From 624de51ad4cef05f8ef55ad5600e805d12f6c8e5 Mon Sep 17 00:00:00 2001 From: morgan Date: Wed, 22 Jan 2025 16:05:21 +0800 Subject: [PATCH] frameline GW: refactor broadcaster --- src/gateware/cxp_frame_pipeline.py | 89 ++++++++++++++---------------- 1 file changed, 41 insertions(+), 48 deletions(-) diff --git a/src/gateware/cxp_frame_pipeline.py b/src/gateware/cxp_frame_pipeline.py index 6790cca..afdfa16 100644 --- a/src/gateware/cxp_frame_pipeline.py +++ b/src/gateware/cxp_frame_pipeline.py @@ -164,21 +164,16 @@ class CXPCRC32_Checker(Module): class Stream_Broadcaster(Module): - def __init__(self, n_buffer=1, default_id=0): - assert n_buffer > 0 + def __init__(self, layout=word_layout_dchar, routing_ids=[0]): + n_id = len(routing_ids) + assert n_id > 0 - self.routing_ids = [Signal(char_width) for _ in range(1, n_buffer)] - - self.sources = [stream.Endpoint(word_layout_dchar) for _ in range(n_buffer)] - self.sink = stream.Endpoint(word_layout_dchar) + self.sources = [stream.Endpoint(layout) for _ in range(n_id)] + self.sink = stream.Endpoint(layout) # # # - routing_ids_r = [Signal(char_width) for _ in range(1, n_buffer)] - for i, id in enumerate(self.routing_ids): - self.sync += routing_ids_r[i].eq(id) - stream_id = Signal(char_width) pak_tag = Signal(char_width) stream_pak_size = Signal(char_width * 2) @@ -215,54 +210,52 @@ class Stream_Broadcaster(Module): ), ) + routing_case = {"default": NextState("DISCARD")} + for id in (routing_ids): + routing_case[id] = [NextState(f"COPY_TO_BUFFER_{id}")] + fsm.act( "GET_PAK_SIZE_1", self.sink.ack.eq(1), If( self.sink.stb, NextValue(stream_pak_size[:8], self.sink.dchar), - NextState("STORE_BUFFER"), + Case(stream_id, routing_case), ), ) - # routing decoder - sel = Signal(n_buffer) - no_match = Signal() - self.comb += sel[0].eq(stream_id == default_id) - for i, id in enumerate(routing_ids_r): - self.comb += sel[i+1].eq(stream_id == id) - # DEBUG: disrecard the stream id = 0 rule - # self.comb += source_sel[0].eq(self.stream_id == self.routing_table[0]) - - # ensure the lower source has priority when two or more bits of sel are high - self.submodules.coder = coder = PriorityEncoder(n_buffer) - sel_r = Signal.like(coder.o) - self.sync += [ - coder.i.eq(sel), - sel_r.eq(coder.o), - no_match.eq(coder.n), - ] - - routing = dict((i, self.sink.connect(s))for i, s in enumerate(self.sources)) - routing["default"] = self.sink.ack.eq(1) # discard if invalid - fsm.act( - "STORE_BUFFER", - If(no_match, - self.sink.ack.eq(1), - ).Else( - Case(sel_r, routing), - ), - # assume downstream is not blocked - If(self.sink.stb, - NextValue(stream_pak_size, stream_pak_size - 1), - If(stream_pak_size == 0, - NextValue(stream_id, stream_id.reset), - NextValue(pak_tag, pak_tag.reset), - NextValue(stream_pak_size, stream_pak_size.reset), - NextState("WAIT_HEADER"), + for key in routing_case: + if key == "default": + fsm.act( + "DISCARD", + self.sink.ack.eq(1), + If(self.sink.stb, + NextValue(stream_pak_size, stream_pak_size - 1), + If(stream_pak_size == 0, + NextValue(stream_id, stream_id.reset), + NextValue(pak_tag, pak_tag.reset), + NextValue(stream_pak_size, stream_pak_size.reset), + NextState("WAIT_HEADER"), + ) + ), + ) + else: + fsm.act( + f"COPY_TO_BUFFER_{key}", + self.sink.connect(self.sources[key]), + + # assume downstream is not blocked + If(self.sink.stb, + NextValue(stream_pak_size, stream_pak_size - 1), + If(stream_pak_size == 0, + NextValue(stream_id, stream_id.reset), + NextValue(pak_tag, pak_tag.reset), + NextValue(stream_pak_size, stream_pak_size.reset), + NextState("WAIT_HEADER"), + ) + ), + ) - ), - ) class Frame_Header_Decoder(Module): def __init__(self):