From 71a719be44639e43b26c9225479ed739795c642c Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 16 Mar 2016 20:06:05 +0100 Subject: [PATCH] soc/interconnect/stream: use valid/ready/last signals instead of stb/ack/eop (similar to AXI) --- litex/soc/cores/uart/core.py | 28 +++--- litex/soc/interconnect/dma_lasmi.py | 16 ++-- litex/soc/interconnect/stream.py | 110 +++++++++++------------ litex/soc/interconnect/stream_packet.py | 62 ++++++------- litex/soc/interconnect/stream_sim.py | 22 ++--- litex/soc/interconnect/wishbonebridge.py | 16 ++-- 6 files changed, 127 insertions(+), 127 deletions(-) diff --git a/litex/soc/cores/uart/core.py b/litex/soc/cores/uart/core.py index a3448aac7..e902dbb78 100644 --- a/litex/soc/cores/uart/core.py +++ b/litex/soc/cores/uart/core.py @@ -22,7 +22,7 @@ class RS232PHYRX(Module): rx_reg = Signal(8) rx_bitcount = Signal(4) rx_busy = Signal() - rx_done = self.source.stb + rx_done = self.source.valid rx_data = self.source.data self.sync += [ rx_done.eq(0), @@ -74,8 +74,8 @@ class RS232PHYTX(Module): tx_bitcount = Signal(4) tx_busy = Signal() self.sync += [ - self.sink.ack.eq(0), - If(self.sink.stb & ~tx_busy & ~self.sink.ack, + self.sink.ready.eq(0), + If(self.sink.valid & ~tx_busy & ~self.sink.ready, tx_reg.eq(self.sink.data), tx_bitcount.eq(0), tx_busy.eq(1), @@ -87,7 +87,7 @@ class RS232PHYTX(Module): ).Elif(tx_bitcount == 9, pads.tx.eq(1), tx_busy.eq(0), - self.sink.ack.eq(1), + self.sink.ready.eq(1), ).Else( pads.tx.eq(tx_reg[0]), tx_reg.eq(Cat(tx_reg[1:], 0)) @@ -117,13 +117,13 @@ class RS232PHYModel(Module): self.source = stream.Endpoint([("data", 8)]) self.comb += [ - pads.source_stb.eq(self.sink.stb), + pads.source_stb.eq(self.sink.valid), pads.source_data.eq(self.sink.data), - self.sink.ack.eq(pads.source_ack), + self.sink.ready.eq(pads.source_ack), - self.source.stb.eq(pads.sink_stb), + self.source.valid.eq(pads.sink_stb), self.source.data.eq(pads.sink_data), - pads.sink_ack.eq(self.source.ack) + pads.sink_ack.eq(self.source.ready) ] @@ -156,12 +156,12 @@ class UART(Module, AutoCSR): self.submodules += tx_fifo self.comb += [ - tx_fifo.sink.stb.eq(self._rxtx.re), + tx_fifo.sink.valid.eq(self._rxtx.re), tx_fifo.sink.data.eq(self._rxtx.r), - self._txfull.status.eq(~tx_fifo.sink.ack), + self._txfull.status.eq(~tx_fifo.sink.ready), tx_fifo.source.connect(phy.sink), # Generate TX IRQ when tx_fifo becomes non-full - self.ev.tx.trigger.eq(~tx_fifo.sink.ack) + self.ev.tx.trigger.eq(~tx_fifo.sink.ready) ] # RX @@ -170,9 +170,9 @@ class UART(Module, AutoCSR): self.comb += [ phy.source.connect(rx_fifo.sink), - self._rxempty.status.eq(~rx_fifo.source.stb), + self._rxempty.status.eq(~rx_fifo.source.valid), self._rxtx.w.eq(rx_fifo.source.data), - rx_fifo.source.ack.eq(self.ev.rx.clear), + rx_fifo.source.ready.eq(self.ev.rx.clear), # Generate RX IRQ when tx_fifo becomes non-empty - self.ev.rx.trigger.eq(~rx_fifo.source.stb) + self.ev.rx.trigger.eq(~rx_fifo.source.valid) ] diff --git a/litex/soc/interconnect/dma_lasmi.py b/litex/soc/interconnect/dma_lasmi.py index a85929629..1857d3cd3 100644 --- a/litex/soc/interconnect/dma_lasmi.py +++ b/litex/soc/interconnect/dma_lasmi.py @@ -20,9 +20,9 @@ class Reader(Module): self.comb += [ lasmim.we.eq(0), - lasmim.stb.eq(self.address.stb & request_enable), + lasmim.stb.eq(self.address.valid & request_enable), lasmim.adr.eq(self.address.a), - self.address.ack.eq(lasmim.req_ack & request_enable), + self.address.ready.eq(lasmim.req_ack & request_enable), request_issued.eq(lasmim.stb & lasmim.req_ack) ] @@ -51,10 +51,10 @@ class Reader(Module): fifo.din.eq(lasmim.dat_r), fifo.we.eq(lasmim.dat_r_ack), - self.data.stb.eq(fifo.readable), - fifo.re.eq(self.data.ack), + self.data.valid.eq(fifo.readable), + fifo.re.eq(self.data.ready), self.data.d.eq(fifo.dout), - data_dequeued.eq(self.data.stb & self.data.ack) + data_dequeued.eq(self.data.valid & self.data.ready) ] @@ -73,10 +73,10 @@ class Writer(Module): self.comb += [ lasmim.we.eq(1), - lasmim.stb.eq(fifo.writable & self.address_data.stb), + lasmim.stb.eq(fifo.writable & self.address_data.valid), lasmim.adr.eq(self.address_data.a), - self.address_data.ack.eq(fifo.writable & lasmim.req_ack), - fifo.we.eq(self.address_data.stb & lasmim.req_ack), + self.address_data.ready.eq(fifo.writable & lasmim.req_ack), + fifo.we.eq(self.address_data.valid & lasmim.req_ack), fifo.din.eq(self.address_data.d) ] diff --git a/litex/soc/interconnect/stream.py b/litex/soc/interconnect/stream.py index 4250d4859..9481248fa 100644 --- a/litex/soc/interconnect/stream.py +++ b/litex/soc/interconnect/stream.py @@ -20,7 +20,7 @@ class EndpointDescription: self.param_layout = param_layout def get_full_layout(self): - reserved = {"stb", "ack", "payload", "param", "eop", "description"} + reserved = {"valid", "ready", "payload", "param", "last", "description"} attributed = set() for f in self.payload_layout + self.param_layout: if f[0] in attributed: @@ -30,9 +30,9 @@ class EndpointDescription: attributed.add(f[0]) full_layout = [ - ("stb", 1, DIR_M_TO_S), - ("ack", 1, DIR_S_TO_M), - ("eop", 1, DIR_M_TO_S), + ("valid", 1, DIR_M_TO_S), + ("ready", 1, DIR_S_TO_M), + ("last", 1, DIR_M_TO_S), ("payload", _make_m2s(self.payload_layout)), ("param", _make_m2s(self.param_layout)) ] @@ -64,7 +64,7 @@ class _FIFOWrapper(Module): description = self.sink.description fifo_layout = [("payload", description.payload_layout), ("param", description.param_layout), - ("eop", 1)] + ("last", 1)] self.submodules.fifo = fifo_class(layout_len(fifo_layout), depth) fifo_in = Record(fifo_layout) @@ -75,17 +75,17 @@ class _FIFOWrapper(Module): ] self.comb += [ - self.sink.ack.eq(self.fifo.writable), - self.fifo.we.eq(self.sink.stb), - fifo_in.eop.eq(self.sink.eop), + self.sink.ready.eq(self.fifo.writable), + self.fifo.we.eq(self.sink.valid), + fifo_in.last.eq(self.sink.last), fifo_in.payload.eq(self.sink.payload), fifo_in.param.eq(self.sink.param), - self.source.stb.eq(self.fifo.readable), - self.source.eop.eq(fifo_out.eop), + self.source.valid.eq(self.fifo.readable), + self.source.last.eq(fifo_out.last), self.source.payload.eq(fifo_out.payload), self.source.param.eq(fifo_out.param), - self.fifo.re.eq(self.source.ack) + self.fifo.re.eq(self.source.ready) ] @@ -153,15 +153,15 @@ class _UpConverter(Module): load_part = Signal() strobe_all = Signal() self.comb += [ - sink.ack.eq(~strobe_all | source.ack), - source.stb.eq(strobe_all), - load_part.eq(sink.stb & sink.ack) + sink.ready.eq(~strobe_all | source.ready), + source.valid.eq(strobe_all), + load_part.eq(sink.valid & sink.ready) ] - demux_last = ((demux == (ratio - 1)) | sink.eop) + demux_last = ((demux == (ratio - 1)) | sink.last) self.sync += [ - If(source.ack, strobe_all.eq(0)), + If(source.ready, strobe_all.eq(0)), If(load_part, If(demux_last, demux.eq(0), @@ -170,10 +170,10 @@ class _UpConverter(Module): demux.eq(demux + 1) ) ), - If(source.stb & source.ack, - source.eop.eq(sink.eop), - ).Elif(sink.stb & sink.ack, - source.eop.eq(sink.eop | source.eop) + If(source.valid & source.ready, + source.last.eq(sink.last), + ).Elif(sink.valid & sink.ready, + source.last.eq(sink.last | source.last) ) ] @@ -202,12 +202,12 @@ class _DownConverter(Module): last = Signal() self.comb += [ last.eq(mux == (ratio-1)), - source.stb.eq(sink.stb), - source.eop.eq(sink.eop & last), - sink.ack.eq(last & source.ack) + source.valid.eq(sink.valid), + source.last.eq(sink.last & last), + sink.ready.eq(last & source.ready) ] self.sync += \ - If(source.stb & source.ack, + If(source.valid & source.ready, If(last, mux.eq(0) ).Else( @@ -294,9 +294,9 @@ class StrideConverter(Module): # cast sink to converter.sink (user fields --> raw bits) self.comb += [ - converter.sink.stb.eq(sink.stb), - converter.sink.eop.eq(sink.eop), - sink.ack.eq(converter.sink.ack) + converter.sink.valid.eq(sink.valid), + converter.sink.last.eq(sink.last), + sink.ready.eq(converter.sink.ready) ] if converter.cls == _DownConverter: ratio = converter.ratio @@ -313,9 +313,9 @@ class StrideConverter(Module): # cast converter.source to source (raw bits --> user fields) self.comb += [ - source.stb.eq(converter.source.stb), - source.eop.eq(converter.source.eop), - converter.source.ack.eq(source.ack) + source.valid.eq(converter.source.valid), + source.last.eq(converter.source.last), + converter.source.ready.eq(source.ready) ] if converter.cls == _UpConverter: ratio = converter.ratio @@ -380,9 +380,9 @@ class BinaryActor(Module): class CombinatorialActor(BinaryActor): def build_binary_control(self, sink, source): self.comb += [ - source.stb.eq(sink.stb), - source.eop.eq(sink.eop), - sink.ack.eq(source.ack), + source.valid.eq(sink.valid), + source.last.eq(sink.last), + sink.ready.eq(source.ready), ] @@ -392,26 +392,26 @@ class PipelinedActor(BinaryActor): BinaryActor.__init__(self, latency) def build_binary_control(self, sink, source, latency): - valid = sink.stb + valid = sink.valid for i in range(latency): valid_n = Signal() self.sync += If(self.pipe_ce, valid_n.eq(valid)) valid = valid_n self.comb += [ - self.pipe_ce.eq(source.ack | ~valid), - sink.ack.eq(self.pipe_ce), - source.stb.eq(valid) + self.pipe_ce.eq(source.ready | ~valid), + sink.ready.eq(self.pipe_ce), + source.valid.eq(valid) ] - eop = sink.stb & sink.eop + last = sink.valid & sink.last for i in range(latency): - eop_n = Signal() + last_n = Signal() self.sync += \ If(self.pipe_ce, - eop_n.eq(eop) + last_n.eq(last) ) - eop = eop_n - self.comb += source.eop.eq(eop) + last = last_n + self.comb += source.last.eq(last) class Buffer(PipelinedActor): @@ -458,11 +458,11 @@ class Unpack(Module): last = Signal() self.comb += [ last.eq(mux == (n-1)), - source.stb.eq(sink.stb), - sink.ack.eq(last & source.ack) + source.valid.eq(sink.valid), + sink.ready.eq(last & source.ready) ] self.sync += [ - If(source.stb & source.ack, + If(source.valid & source.ready, If(last, mux.eq(0) ).Else( @@ -481,7 +481,7 @@ class Unpack(Module): dst = getattr(self.source, f[0]) self.comb += dst.eq(src) - self.comb += source.eop.eq(sink.eop & last) + self.comb += source.last.eq(sink.last & last) class Pack(Module): @@ -502,9 +502,9 @@ class Pack(Module): chunk = n-i-1 if reverse else i cases[i] = [getattr(source.payload, "chunk"+str(chunk)).raw_bits().eq(sink.payload.raw_bits())] self.comb += [ - sink.ack.eq(~strobe_all | source.ack), - source.stb.eq(strobe_all), - load_part.eq(sink.stb & sink.ack) + sink.ready.eq(~strobe_all | source.ready), + source.valid.eq(strobe_all), + load_part.eq(sink.valid & sink.ready) ] for f in description_to.param_layout: @@ -512,10 +512,10 @@ class Pack(Module): dst = getattr(self.source, f[0]) self.sync += If(load_part, dst.eq(src)) - demux_last = ((demux == (n - 1)) | sink.eop) + demux_last = ((demux == (n - 1)) | sink.last) self.sync += [ - If(source.ack, strobe_all.eq(0)), + If(source.ready, strobe_all.eq(0)), If(load_part, Case(demux, cases), If(demux_last, @@ -525,10 +525,10 @@ class Pack(Module): demux.eq(demux + 1) ) ), - If(source.stb & source.ack, - source.eop.eq(sink.eop), - ).Elif(sink.stb & sink.ack, - source.eop.eq(sink.eop | source.eop) + If(source.valid & source.ready, + source.last.eq(sink.last), + ).Elif(sink.valid & sink.ready, + source.last.eq(sink.last | source.last) ) ] diff --git a/litex/soc/interconnect/stream_packet.py b/litex/soc/interconnect/stream_packet.py index 1c16352c5..a41183802 100644 --- a/litex/soc/interconnect/stream_packet.py +++ b/litex/soc/interconnect/stream_packet.py @@ -19,21 +19,21 @@ def reverse_bytes(signal): class Status(Module): def __init__(self, endpoint): self.first = first = Signal(reset=1) - self.eop = eop = Signal() + self.last = last = Signal() self.ongoing = Signal() ongoing = Signal() self.comb += \ - If(endpoint.stb, - eop.eq(endpoint.eop & endpoint.ack) + If(endpoint.valid, + last.eq(endpoint.last & endpoint.ready) ) - self.sync += ongoing.eq((endpoint.stb | ongoing) & ~eop) - self.comb += self.ongoing.eq((endpoint.stb | ongoing) & ~eop) + self.sync += ongoing.eq((endpoint.valid | ongoing) & ~last) + self.comb += self.ongoing.eq((endpoint.valid | ongoing) & ~last) self.sync += [ - If(eop, + If(last, first.eq(1) - ).Elif(endpoint.stb & endpoint.ack, + ).Elif(endpoint.valid & endpoint.ready, first.eq(0) ) ] @@ -95,7 +95,7 @@ class Dispatcher(Module): else: idx = i cases[idx] = [master.connect(slave)] - cases["default"] = [master.ack.eq(1)] + cases["default"] = [master.ready.eq(1)] self.comb += Case(sel, cases) @@ -202,14 +202,14 @@ class Packetizer(Module): idle_next_state = "SEND_HEADER" fsm.act("IDLE", - sink.ack.eq(1), + sink.ready.eq(1), counter_reset.eq(1), - If(sink.stb, - sink.ack.eq(0), - source.stb.eq(1), - source.eop.eq(0), + If(sink.valid, + sink.ready.eq(0), + source.valid.eq(1), + source.last.eq(0), source.data.eq(self.header[:dw]), - If(source.stb & source.ack, + If(source.valid & source.ready, load.eq(1), NextState(idle_next_state) ) @@ -217,10 +217,10 @@ class Packetizer(Module): ) if header_words != 1: fsm.act("SEND_HEADER", - source.stb.eq(1), - source.eop.eq(0), + source.valid.eq(1), + source.last.eq(0), source.data.eq(header_reg[dw:2*dw]), - If(source.stb & source.ack, + If(source.valid & source.ready, shift.eq(1), counter_ce.eq(1), If(counter == header_words-2, @@ -229,13 +229,13 @@ class Packetizer(Module): ) ) fsm.act("COPY", - source.stb.eq(sink.stb), - source.eop.eq(sink.eop), + source.valid.eq(sink.valid), + source.last.eq(sink.last), source.data.eq(sink.data), source.error.eq(sink.error), - If(source.stb & source.ack, - sink.ack.eq(1), - If(source.eop, + If(source.valid & source.ready, + sink.ready.eq(1), + If(source.last, NextState("IDLE") ) ) @@ -285,17 +285,17 @@ class Depacketizer(Module): idle_next_state = "RECEIVE_HEADER" fsm.act("IDLE", - sink.ack.eq(1), + sink.ready.eq(1), counter_reset.eq(1), - If(sink.stb, + If(sink.valid, shift.eq(1), NextState(idle_next_state) ) ) if header_words != 1: fsm.act("RECEIVE_HEADER", - sink.ack.eq(1), - If(sink.stb, + sink.ready.eq(1), + If(sink.valid, counter_ce.eq(1), shift.eq(1), If(counter == header_words-2, @@ -306,20 +306,20 @@ class Depacketizer(Module): no_payload = Signal() self.sync += \ If(fsm.before_entering("COPY"), - no_payload.eq(sink.eop) + no_payload.eq(sink.last) ) if hasattr(sink, "error"): self.comb += source.error.eq(sink.error) self.comb += [ - source.eop.eq(sink.eop | no_payload), + source.last.eq(sink.last | no_payload), source.data.eq(sink.data), header.decode(self.header, source) ] fsm.act("COPY", - sink.ack.eq(source.ack), - source.stb.eq(sink.stb | no_payload), - If(source.stb & source.ack & source.eop, + sink.ready.eq(source.ready), + source.valid.eq(sink.valid | no_payload), + If(source.valid & source.ready & source.last, NextState("IDLE") ) ) diff --git a/litex/soc/interconnect/stream_sim.py b/litex/soc/interconnect/stream_sim.py index 242a7f592..9f7dcb6d0 100644 --- a/litex/soc/interconnect/stream_sim.py +++ b/litex/soc/interconnect/stream_sim.py @@ -119,24 +119,24 @@ class PacketStreamer(Module): if len(self.packets) and self.packet.done: self.packet = self.packets.pop(0) if not self.packet.ongoing and not self.packet.done: - selfp.source.stb = 1 + selfp.source.valid = 1 selfp.source.data = self.packet.pop(0) self.packet.ongoing = True - elif selfp.source.stb == 1 and selfp.source.ack == 1: + elif selfp.source.valid == 1 and selfp.source.ready == 1: if len(self.packet) == 1: - selfp.source.eop = 1 + selfp.source.last = 1 if self.last_be is not None: selfp.source.last_be = self.last_be else: - selfp.source.eop = 0 + selfp.source.last = 0 if self.last_be is not None: selfp.source.last_be = 0 if len(self.packet) > 0: - selfp.source.stb = 1 + selfp.source.valid = 1 selfp.source.data = self.packet.pop(0) else: self.packet.done = True - selfp.source.stb = 0 + selfp.source.valid = 0 class PacketLogger(Module): @@ -154,15 +154,15 @@ class PacketLogger(Module): yield def do_simulation(self, selfp): - selfp.sink.ack = 1 - if selfp.sink.stb: + selfp.sink.ready = 1 + if selfp.sink.valid: if self.first: self.packet = Packet() self.packet.append(selfp.sink.data) self.first = False else: self.packet.append(selfp.sink.data) - if selfp.sink.eop: + if selfp.sink.last: self.packet.done = True self.first = True @@ -180,8 +180,8 @@ class AckRandomizer(Module): If(self.run, self.sink.connect(self.source) ).Else( - self.source.stb.eq(0), - self.sink.ack.eq(0), + self.source.valid.eq(0), + self.sink.ready.eq(0), ) def do_simulation(self, selfp): diff --git a/litex/soc/interconnect/wishbonebridge.py b/litex/soc/interconnect/wishbonebridge.py index b2d0549df..b3be5bd88 100644 --- a/litex/soc/interconnect/wishbonebridge.py +++ b/litex/soc/interconnect/wishbonebridge.py @@ -68,10 +68,10 @@ class WishboneStreamingBridge(Module): self.submodules += fsm, timer self.comb += [ fsm.reset.eq(timer.done), - phy.source.ack.eq(1) + phy.source.ready.eq(1) ] fsm.act("IDLE", - If(phy.source.stb, + If(phy.source.valid, cmd_ce.eq(1), If((phy.source.data == self.cmds["write"]) | (phy.source.data == self.cmds["read"]), @@ -82,13 +82,13 @@ class WishboneStreamingBridge(Module): ) ) fsm.act("RECEIVE_LENGTH", - If(phy.source.stb, + If(phy.source.valid, length_ce.eq(1), NextState("RECEIVE_ADDRESS") ) ) fsm.act("RECEIVE_ADDRESS", - If(phy.source.stb, + If(phy.source.valid, address_ce.eq(1), byte_counter_ce.eq(1), If(byte_counter == 3, @@ -102,7 +102,7 @@ class WishboneStreamingBridge(Module): ) ) fsm.act("RECEIVE_DATA", - If(phy.source.stb, + If(phy.source.valid, rx_data_ce.eq(1), byte_counter_ce.eq(1), If(byte_counter == 3, @@ -141,8 +141,8 @@ class WishboneStreamingBridge(Module): self.comb += \ chooser(data, byte_counter, phy.sink.data, n=4, reverse=True) fsm.act("SEND_DATA", - phy.sink.stb.eq(1), - If(phy.sink.ack, + phy.sink.valid.eq(1), + If(phy.sink.ready, byte_counter_ce.eq(1), If(byte_counter == 3, word_counter_ce.eq(1), @@ -158,7 +158,7 @@ class WishboneStreamingBridge(Module): self.comb += timer.wait.eq(~fsm.ongoing("IDLE")) - self.comb += phy.sink.eop.eq((byte_counter == 3) & (word_counter == length - 1)) + self.comb += phy.sink.last.eq((byte_counter == 3) & (word_counter == length - 1)) if hasattr(phy.sink, "length"): self.comb += phy.sink.length.eq(4*length)