From ef9d633e9b6aa4e379a494b8983fa4ade168d231 Mon Sep 17 00:00:00 2001 From: morgan Date: Tue, 14 Jan 2025 11:36:59 +0800 Subject: [PATCH] frameline GW: add reg for arbiter & broadcaster --- src/gateware/cxp_frame_pipeline.py | 42 ++++++++++++++++-------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/gateware/cxp_frame_pipeline.py b/src/gateware/cxp_frame_pipeline.py index 82116f3..f08469f 100644 --- a/src/gateware/cxp_frame_pipeline.py +++ b/src/gateware/cxp_frame_pipeline.py @@ -78,9 +78,11 @@ class Stream_Arbiter(Module): # When Multiple connections are active, stream packets are transmitted in # ascending order of Connection ID (which we currently only support ch1->2->3->4). # And one connection shall be transmitting data at a time. + n_ext_active_r = Signal.like(self.n_ext_active) + self.sync += n_ext_active_r.eq(self.n_ext_active) fsm.act( "SWITCH_SOURCE", - If(read_mask == self.n_ext_active, + If(read_mask == n_ext_active_r, NextValue(read_mask, read_mask.reset), ).Else( NextValue(read_mask, read_mask + 1), @@ -159,31 +161,33 @@ class Stream_Broadcaster(Module): def __init__(self, n_buffer, default_id=0): assert n_buffer > 0 - self.routing_table = [Signal(char_width) for _ in range(1, n_buffer)] + 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) # # # - + 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) - self.stream_id = Signal(char_width) - self.pak_tag = Signal(char_width) - self.stream_pak_size = Signal(char_width * 2) + stream_id = Signal(char_width) + pak_tag = Signal(char_width) + stream_pak_size = Signal(char_width * 2) self.submodules.fsm = fsm = FSM(reset_state="WAIT_HEADER") fsm.act( "WAIT_HEADER", - NextValue(self.stream_id, self.stream_id.reset), - NextValue(self.pak_tag, self.pak_tag.reset), - NextValue(self.stream_pak_size, self.stream_pak_size.reset), + NextValue(stream_id, stream_id.reset), + NextValue(pak_tag, pak_tag.reset), + NextValue(stream_pak_size, stream_pak_size.reset), self.sink.ack.eq(1), If( self.sink.stb, - NextValue(self.stream_id, self.sink.dchar), + NextValue(stream_id, self.sink.dchar), NextState("GET_PAK_TAG"), ), ) @@ -193,7 +197,7 @@ class Stream_Broadcaster(Module): self.sink.ack.eq(1), If( self.sink.stb, - NextValue(self.pak_tag, self.sink.dchar), + NextValue(pak_tag, self.sink.dchar), NextState("GET_PAK_SIZE_0"), ), ) @@ -203,7 +207,7 @@ class Stream_Broadcaster(Module): self.sink.ack.eq(1), If( self.sink.stb, - NextValue(self.stream_pak_size[8:], self.sink.dchar), + NextValue(stream_pak_size[8:], self.sink.dchar), NextState("GET_PAK_SIZE_1"), ), ) @@ -213,7 +217,7 @@ class Stream_Broadcaster(Module): self.sink.ack.eq(1), If( self.sink.stb, - NextValue(self.stream_pak_size[:8], self.sink.dchar), + NextValue(stream_pak_size[:8], self.sink.dchar), NextState("STORE_BUFFER"), ), ) @@ -221,9 +225,9 @@ class Stream_Broadcaster(Module): # routing decoder sel = Signal(n_buffer) no_match = Signal() - self.comb += sel[0].eq(self.stream_id == default_id) - for i, routing_id in enumerate(self.routing_table): - self.comb += sel[i+1].eq(self.stream_id == routing_id) + 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]) @@ -247,8 +251,8 @@ class Stream_Broadcaster(Module): ), # assume downstream is not blocked If(self.sink.stb, - NextValue(self.stream_pak_size, self.stream_pak_size - 1), - If(self.stream_pak_size == 0, + NextValue(stream_pak_size, stream_pak_size - 1), + If(stream_pak_size == 0, NextState("WAIT_HEADER"), ) ), @@ -628,7 +632,7 @@ class Frame_Packet_Router(Module): self.submodules.broadcaster = broadcaster = Stream_Broadcaster(n_buffer) for i, s in enumerate(self.routing_table): - self.sync += broadcaster.routing_table[i].eq(s) + self.sync += broadcaster.routing_ids[i].eq(s) for i, d in enumerate(downconns): # Assume downconns pipeline already marks the eop