soc/interconnect/stream: add first signal to streams (avoid over-complicated code in some cases)

This commit is contained in:
Florent Kermarrec 2017-06-09 19:35:48 +02:00
parent c19c4b711b
commit c44a4b051f
1 changed files with 29 additions and 3 deletions

View File

@ -20,7 +20,7 @@ class EndpointDescription:
self.param_layout = param_layout self.param_layout = param_layout
def get_full_layout(self): def get_full_layout(self):
reserved = {"valid", "ready", "payload", "param", "last", "description"} reserved = {"valid", "ready", "payload", "param", "first", "last", "description"}
attributed = set() attributed = set()
for f in self.payload_layout + self.param_layout: for f in self.payload_layout + self.param_layout:
if f[0] in attributed: if f[0] in attributed:
@ -32,6 +32,7 @@ class EndpointDescription:
full_layout = [ full_layout = [
("valid", 1, DIR_M_TO_S), ("valid", 1, DIR_M_TO_S),
("ready", 1, DIR_S_TO_M), ("ready", 1, DIR_S_TO_M),
("first", 1, DIR_M_TO_S),
("last", 1, DIR_M_TO_S), ("last", 1, DIR_M_TO_S),
("payload", _make_m2s(self.payload_layout)), ("payload", _make_m2s(self.payload_layout)),
("param", _make_m2s(self.param_layout)) ("param", _make_m2s(self.param_layout))
@ -64,6 +65,7 @@ class _FIFOWrapper(Module):
description = self.sink.description description = self.sink.description
fifo_layout = [("payload", description.payload_layout), fifo_layout = [("payload", description.payload_layout),
("param", description.param_layout), ("param", description.param_layout),
("first", 1),
("last", 1)] ("last", 1)]
self.submodules.fifo = fifo_class(layout_len(fifo_layout), depth) self.submodules.fifo = fifo_class(layout_len(fifo_layout), depth)
@ -77,11 +79,13 @@ class _FIFOWrapper(Module):
self.comb += [ self.comb += [
self.sink.ready.eq(self.fifo.writable), self.sink.ready.eq(self.fifo.writable),
self.fifo.we.eq(self.sink.valid), self.fifo.we.eq(self.sink.valid),
fifo_in.first.eq(self.sink.first),
fifo_in.last.eq(self.sink.last), fifo_in.last.eq(self.sink.last),
fifo_in.payload.eq(self.sink.payload), fifo_in.payload.eq(self.sink.payload),
fifo_in.param.eq(self.sink.param), fifo_in.param.eq(self.sink.param),
self.source.valid.eq(self.fifo.readable), self.source.valid.eq(self.fifo.readable),
self.source.first.eq(fifo_out.first),
self.source.last.eq(fifo_out.last), self.source.last.eq(fifo_out.last),
self.source.payload.eq(fifo_out.payload), self.source.payload.eq(fifo_out.payload),
self.source.param.eq(fifo_out.param), self.source.param.eq(fifo_out.param),
@ -171,8 +175,10 @@ class _UpConverter(Module):
) )
), ),
If(source.valid & source.ready, If(source.valid & source.ready,
source.first.eq(sink.first),
source.last.eq(sink.last), source.last.eq(sink.last),
).Elif(sink.valid & sink.ready, ).Elif(sink.valid & sink.ready,
source.first.eq(sink.first | source.first),
source.last.eq(sink.last | source.last) source.last.eq(sink.last | source.last)
) )
] ]
@ -199,10 +205,13 @@ class _DownConverter(Module):
# control path # control path
mux = Signal(max=ratio) mux = Signal(max=ratio)
first = Signal()
last = Signal() last = Signal()
self.comb += [ self.comb += [
first.eq(mux == 0),
last.eq(mux == (ratio-1)), last.eq(mux == (ratio-1)),
source.valid.eq(sink.valid), source.valid.eq(sink.valid),
source.first.eq(sink.first & first),
source.last.eq(sink.last & last), source.last.eq(sink.last & last),
sink.ready.eq(last & source.ready) sink.ready.eq(last & source.ready)
] ]
@ -295,6 +304,7 @@ class StrideConverter(Module):
# cast sink to converter.sink (user fields --> raw bits) # cast sink to converter.sink (user fields --> raw bits)
self.comb += [ self.comb += [
converter.sink.valid.eq(sink.valid), converter.sink.valid.eq(sink.valid),
converter.sink.first.eq(sink.first),
converter.sink.last.eq(sink.last), converter.sink.last.eq(sink.last),
sink.ready.eq(converter.sink.ready) sink.ready.eq(converter.sink.ready)
] ]
@ -314,6 +324,7 @@ class StrideConverter(Module):
# cast converter.source to source (raw bits --> user fields) # cast converter.source to source (raw bits --> user fields)
self.comb += [ self.comb += [
source.valid.eq(converter.source.valid), source.valid.eq(converter.source.valid),
source.first.eq(converter.source.first),
source.last.eq(converter.source.last), source.last.eq(converter.source.last),
converter.source.ready.eq(source.ready) converter.source.ready.eq(source.ready)
] ]
@ -381,6 +392,7 @@ class CombinatorialActor(BinaryActor):
def build_binary_control(self, sink, source): def build_binary_control(self, sink, source):
self.comb += [ self.comb += [
source.valid.eq(sink.valid), source.valid.eq(sink.valid),
source.first.eq(sink.first),
source.last.eq(sink.last), source.last.eq(sink.last),
sink.ready.eq(source.ready), sink.ready.eq(source.ready),
] ]
@ -408,15 +420,22 @@ class PipelinedActor(BinaryActor):
source.valid.eq(valid), source.valid.eq(valid),
self.busy.eq(busy) self.busy.eq(busy)
] ]
first = sink.valid & sink.first
last = sink.valid & sink.last last = sink.valid & sink.last
for i in range(latency): for i in range(latency):
first_n = Signal()
last_n = Signal() last_n = Signal()
self.sync += \ self.sync += \
If(self.pipe_ce, If(self.pipe_ce,
first_n.eq(first),
last_n.eq(last) last_n.eq(last)
) )
first = first_n
last = last_n last = last_n
self.comb += source.last.eq(last) self.comb += [
source.first.eq(first),
source.last.eq(last)
]
class Buffer(PipelinedActor): class Buffer(PipelinedActor):
@ -460,8 +479,10 @@ class Unpack(Module):
# # # # # #
mux = Signal(max=n) mux = Signal(max=n)
first = Signal()
last = Signal() last = Signal()
self.comb += [ self.comb += [
first.eq(mux == 0),
last.eq(mux == (n-1)), last.eq(mux == (n-1)),
source.valid.eq(sink.valid), source.valid.eq(sink.valid),
sink.ready.eq(last & source.ready) sink.ready.eq(last & source.ready)
@ -486,7 +507,10 @@ class Unpack(Module):
dst = getattr(self.source, f[0]) dst = getattr(self.source, f[0])
self.comb += dst.eq(src) self.comb += dst.eq(src)
self.comb += source.last.eq(sink.last & last) self.comb += [
source.first.eq(sink.first & first),
source.last.eq(sink.last & last)
]
class Pack(Module): class Pack(Module):
@ -531,8 +555,10 @@ class Pack(Module):
) )
), ),
If(source.valid & source.ready, If(source.valid & source.ready,
source.first.eq(sink.first),
source.last.eq(sink.last), source.last.eq(sink.last),
).Elif(sink.valid & sink.ready, ).Elif(sink.valid & sink.ready,
source.first.eq(sink.first | source.first),
source.last.eq(sink.last | source.last) source.last.eq(sink.last | source.last)
) )
] ]