soc/interconnect/stream: use valid/ready/last signals instead of stb/ack/eop (similar to AXI)

This commit is contained in:
Florent Kermarrec 2016-03-16 20:06:05 +01:00
parent 9032665750
commit 71a719be44
6 changed files with 127 additions and 127 deletions

View File

@ -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)
]

View File

@ -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)
]

View File

@ -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)
)
]

View File

@ -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")
)
)

View File

@ -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):

View File

@ -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)