From 0da7222262338eced3702dd62e7bf1c44c335ce4 Mon Sep 17 00:00:00 2001 From: morgan Date: Fri, 8 Nov 2024 12:19:49 +0800 Subject: [PATCH] sim: add stream pipeline with parser & buffer --- sim_pipeline.py | 26 ++++++++++++++++++++------ sim_stream.py | 36 +++++++++++------------------------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/sim_pipeline.py b/sim_pipeline.py index 513fa49..f0f7853 100644 --- a/sim_pipeline.py +++ b/sim_pipeline.py @@ -25,11 +25,11 @@ class EOP_Marker(Module): self.source.eop.eq(~self.sink.stb & last_stb), ] class Streams_Crossbar(Module): - def __init__(self, downconns, streams_buffer): - n_downconn = len(downconns) + def __init__(self, downconn_sources, stream_sinks): + n_downconn = len(downconn_sources) self.submodules.mux = mux = stream.Multiplexer(word_layout_dchar, n_downconn) - for i, c in enumerate(downconns): + for i, c in enumerate(downconn_sources): self.comb += [ c.source.connect(getattr(mux, "sink"+str(i))) ] @@ -37,7 +37,7 @@ class Streams_Crossbar(Module): self.submodules.fsm = fsm = FSM(reset_state="WAIT_HEADER") self.stream_id = Signal(char_width) - case = dict((i, mux.source.connect(b.sink)) for i, b in enumerate(streams_buffer)) + case = dict((i, mux.source.connect(b.sink)) for i, b in enumerate(stream_sinks)) fsm.act( "WAIT_HEADER", NextValue(self.stream_id, mux.source.dchar), @@ -103,8 +103,7 @@ class CXPCRC32(Module): # For verifying crc in stream data packet class Double_Stream_Buffer(Module): - # default size is 2 kBtyes - Section 9.5.2 (CXP-001-2021) - def __init__(self, size=16000): + def __init__(self, size): self.sink = stream.Endpoint(word_layout_dchar) self.submodules.crc = crc = CXPCRC32(word_dw) @@ -276,3 +275,18 @@ class Pixel_Decoder(Module): # TODO: support mono16 for now? +class Stream_Pipeline(Module): + # optimal stream packet size is 2 kBtyes - Section 9.5.2 (CXP-001-2021) + def __init__(self, size=16000): + + self.submodules.double_buffer = double_buffer = Double_Stream_Buffer(size) + self.submodules.parser = parser = Stream_Parser() + + pipeline = [double_buffer, parser] + for s, d in zip(pipeline, pipeline[1:]): + self.comb += s.source.connect(d.sink) + self.sink = pipeline[0].sink + self.source = pipeline[-1].source + + # no backpressure for sim purposes + self.sync += self.source.ack.eq(1) diff --git a/sim_stream.py b/sim_stream.py index 3360320..5da2229 100644 --- a/sim_stream.py +++ b/sim_stream.py @@ -11,34 +11,19 @@ class CXP_Links(Module): # TODO: select the correct buffer to read from # NOTE: although there are double buffer in each connect, the reading must be faster than writing to avoid data loss - self.downconns = [] - self.stream_buffers = [] + self.downconn_sources = [] + self.stream_sinks = [] for i in range(2): downconn = Pipeline() setattr(self.submodules, "cxp_conn"+str(i), downconn) - self.downconns.append(downconn) + self.downconn_sources.append(downconn) - double_buffer = Double_Stream_Buffer() - setattr(self.submodules, "stream_buffer"+str(i), double_buffer) - self.stream_buffers.append(double_buffer) + stream_pipeline = Stream_Pipeline() + setattr(self.submodules, "stream_pipeline"+str(i), stream_pipeline) + self.stream_sinks.append(stream_pipeline) - # no backpressure for sim purposes - self.sync += double_buffer.source.ack.eq(1) - - - self.submodules.crossbar = crossbar = Streams_Crossbar(self.downconns, self.stream_buffers) + self.submodules.crossbar = Streams_Crossbar(self.downconn_sources, self.stream_sinks) - # TODO: add extractor - - # pipeline = [dispatcher, double_buffer] - # for s, d in zip(pipeline, pipeline[1:]): - # self.comb += s.source.connect(d.sink) - # self.source = pipeline[-1].source - - # # no backpressure - # self.sync += self.source.ack.eq(1) - - class Pipeline(Module): def __init__(self): self.submodules.generator = generator = StreamData_Generator() @@ -62,8 +47,8 @@ dut = CXP_Links() def check_case(packet=[]): print("=================TEST========================") - downconns = dut.downconns - stream_buffers = dut.stream_buffers + downconns = dut.downconn_sources + stream_buffers = dut.stream_sinks ch = 0 for i, p in enumerate(packet): @@ -94,7 +79,8 @@ def check_case(packet=[]): # check cycle result yield - source = dut.stream_buffers[0].source + # source = dut.stream_pipeline_sinks[0].source + source = dut.stream_sinks[0].double_buffer.source print( f"\nCYCLE#{i} : source char = {yield source.data:#X} k = {yield source.k:#X} stb = {yield source.stb} ack = {yield source.ack} eop = {yield source.eop}" # f" source dchar = {yield source.dchar:#X} dchar_k = {yield source.dchar_k:#X}"