frameline GW: refactor broadcaster

This commit is contained in:
morgan 2025-01-22 16:05:21 +08:00
parent f6b13f271d
commit 624de51ad4

View File

@ -164,20 +164,15 @@ 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)
@ -215,43 +210,40 @@ 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
for key in routing_case:
if key == "default":
fsm.act(
"STORE_BUFFER",
If(no_match,
"DISCARD",
self.sink.ack.eq(1),
).Else(
Case(sel_r, routing),
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),
@ -262,6 +254,7 @@ class Stream_Broadcaster(Module):
NextState("WAIT_HEADER"),
)
),
)
class Frame_Header_Decoder(Module):