1
0
Fork 0

sim: add stream pipeline with parser & buffer

This commit is contained in:
morgan 2024-11-08 12:19:49 +08:00
parent 473d44fd82
commit 0da7222262
2 changed files with 31 additions and 31 deletions

View File

@ -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)

View File

@ -11,33 +11,18 @@ 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)
# no backpressure for sim purposes
self.sync += double_buffer.source.ack.eq(1)
self.submodules.crossbar = crossbar = Streams_Crossbar(self.downconns, self.stream_buffers)
# 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)
stream_pipeline = Stream_Pipeline()
setattr(self.submodules, "stream_pipeline"+str(i), stream_pipeline)
self.stream_sinks.append(stream_pipeline)
self.submodules.crossbar = Streams_Crossbar(self.downconn_sources, self.stream_sinks)
class Pipeline(Module):
def __init__(self):
@ -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}"