forked from M-Labs/artiq-zynq
frameline GW: refactor broadcaster
This commit is contained in:
parent
f6b13f271d
commit
624de51ad4
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user