forked from M-Labs/artiq-zynq
frameline GW: refactor broadcaster
This commit is contained in:
parent
f6b13f271d
commit
624de51ad4
@ -164,20 +164,15 @@ class CXPCRC32_Checker(Module):
|
|||||||
|
|
||||||
|
|
||||||
class Stream_Broadcaster(Module):
|
class Stream_Broadcaster(Module):
|
||||||
def __init__(self, n_buffer=1, default_id=0):
|
def __init__(self, layout=word_layout_dchar, routing_ids=[0]):
|
||||||
assert n_buffer > 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(layout) for _ in range(n_id)]
|
||||||
|
self.sink = stream.Endpoint(layout)
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
stream_id = Signal(char_width)
|
stream_id = Signal(char_width)
|
||||||
pak_tag = Signal(char_width)
|
pak_tag = Signal(char_width)
|
||||||
@ -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(
|
fsm.act(
|
||||||
"GET_PAK_SIZE_1",
|
"GET_PAK_SIZE_1",
|
||||||
self.sink.ack.eq(1),
|
self.sink.ack.eq(1),
|
||||||
If(
|
If(
|
||||||
self.sink.stb,
|
self.sink.stb,
|
||||||
NextValue(stream_pak_size[:8], self.sink.dchar),
|
NextValue(stream_pak_size[:8], self.sink.dchar),
|
||||||
NextState("STORE_BUFFER"),
|
Case(stream_id, routing_case),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# routing decoder
|
for key in routing_case:
|
||||||
sel = Signal(n_buffer)
|
if key == "default":
|
||||||
no_match = Signal()
|
fsm.act(
|
||||||
self.comb += sel[0].eq(stream_id == default_id)
|
"DISCARD",
|
||||||
for i, id in enumerate(routing_ids_r):
|
self.sink.ack.eq(1),
|
||||||
self.comb += sel[i+1].eq(stream_id == id)
|
If(self.sink.stb,
|
||||||
# DEBUG: disrecard the stream id = 0 rule
|
NextValue(stream_pak_size, stream_pak_size - 1),
|
||||||
# self.comb += source_sel[0].eq(self.stream_id == self.routing_table[0])
|
If(stream_pak_size == 0,
|
||||||
|
NextValue(stream_id, stream_id.reset),
|
||||||
# ensure the lower source has priority when two or more bits of sel are high
|
NextValue(pak_tag, pak_tag.reset),
|
||||||
self.submodules.coder = coder = PriorityEncoder(n_buffer)
|
NextValue(stream_pak_size, stream_pak_size.reset),
|
||||||
sel_r = Signal.like(coder.o)
|
NextState("WAIT_HEADER"),
|
||||||
self.sync += [
|
)
|
||||||
coder.i.eq(sel),
|
),
|
||||||
sel_r.eq(coder.o),
|
)
|
||||||
no_match.eq(coder.n),
|
else:
|
||||||
]
|
fsm.act(
|
||||||
|
f"COPY_TO_BUFFER_{key}",
|
||||||
routing = dict((i, self.sink.connect(s))for i, s in enumerate(self.sources))
|
self.sink.connect(self.sources[key]),
|
||||||
routing["default"] = self.sink.ack.eq(1) # discard if invalid
|
|
||||||
fsm.act(
|
# assume downstream is not blocked
|
||||||
"STORE_BUFFER",
|
If(self.sink.stb,
|
||||||
If(no_match,
|
NextValue(stream_pak_size, stream_pak_size - 1),
|
||||||
self.sink.ack.eq(1),
|
If(stream_pak_size == 0,
|
||||||
).Else(
|
NextValue(stream_id, stream_id.reset),
|
||||||
Case(sel_r, routing),
|
NextValue(pak_tag, pak_tag.reset),
|
||||||
),
|
NextValue(stream_pak_size, stream_pak_size.reset),
|
||||||
# assume downstream is not blocked
|
NextState("WAIT_HEADER"),
|
||||||
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):
|
class Frame_Header_Decoder(Module):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user