rtio: remove NOP suppression capability

Back when RTIO was driving TTLs, this functionality made it simpler to use by removing some irrelevant underflows.

The same technique is not applicable to DDS and SPI, so the user will have to deal with such underflows.

This patch makes the behavior of RTIO more consistent and the code simpler.
This commit is contained in:
Sebastien Bourdeauducq 2016-03-10 09:47:29 +08:00
parent 2e39802a61
commit 542a375305
4 changed files with 8 additions and 31 deletions

View File

@ -95,7 +95,7 @@ class _OutputManager(Module):
ev_layout.append(("address", address_width)) ev_layout.append(("address", address_width))
ev_layout.append(("timestamp", counter.width + fine_ts_width)) ev_layout.append(("timestamp", counter.width + fine_ts_width))
# ev must be valid 1 cycle before we to account for the latency in # ev must be valid 1 cycle before we to account for the latency in
# generating replace, sequence_error and nop # generating replace, sequence_error and collision
self.ev = Record(ev_layout) self.ev = Record(ev_layout)
self.writable = Signal() self.writable = Signal()
@ -128,7 +128,6 @@ class _OutputManager(Module):
sequence_error = Signal() sequence_error = Signal()
collision = Signal() collision = Signal()
any_error = Signal() any_error = Signal()
nop = Signal()
if interface.enable_replace: if interface.enable_replace:
# Note: replace may be asserted at the same time as collision # Note: replace may be asserted at the same time as collision
# when addresses are different. In that case, it is a collision. # when addresses are different. In that case, it is a collision.
@ -151,25 +150,8 @@ class _OutputManager(Module):
else: else:
self.sync.rsys += collision.eq( self.sync.rsys += collision.eq(
self.ev.timestamp[fine_ts_width:] == buf.timestamp[fine_ts_width:]) self.ev.timestamp[fine_ts_width:] == buf.timestamp[fine_ts_width:])
self.comb += any_error.eq(sequence_error | collision)
if interface.suppress_nop:
# disable NOP at reset: do not suppress a first write with all 0s
nop_en = Signal(reset=0)
addresses_equal = [getattr(self.ev, a) == getattr(buf, a)
for a in ("data", "address")
if hasattr(self.ev, a)]
if addresses_equal:
self.sync.rsys += nop.eq(
nop_en & reduce(and_, addresses_equal))
else:
self.comb.eq(nop.eq(0))
self.sync.rsys += [
# buf now contains valid data. enable NOP.
If(self.we & ~any_error, nop_en.eq(1)),
# underflows cancel the write. allow it to be retried.
If(self.underflow, nop_en.eq(0))
]
self.comb += [ self.comb += [
any_error.eq(sequence_error | collision),
self.sequence_error.eq(self.we & sequence_error), self.sequence_error.eq(self.we & sequence_error),
self.collision.eq(self.we & collision) self.collision.eq(self.we & collision)
] ]
@ -190,7 +172,7 @@ class _OutputManager(Module):
fifo.we.eq(1) fifo.we.eq(1)
) )
), ),
If(self.we & ~replace & ~nop & ~any_error, If(self.we & ~replace & ~any_error,
fifo.we.eq(1) fifo.we.eq(1)
) )
) )
@ -199,7 +181,7 @@ class _OutputManager(Module):
# Must come after read to handle concurrent read+write properly # Must come after read to handle concurrent read+write properly
self.sync.rsys += [ self.sync.rsys += [
buf_just_written.eq(0), buf_just_written.eq(0),
If(self.we & ~nop & ~any_error, If(self.we & ~any_error,
buf_just_written.eq(1), buf_just_written.eq(1),
buf_pending.eq(1), buf_pending.eq(1),
buf.eq(self.ev) buf.eq(self.ev)
@ -321,8 +303,7 @@ class Channel:
class LogChannel: class LogChannel:
"""A degenerate channel used to log messages into the analyzer.""" """A degenerate channel used to log messages into the analyzer."""
def __init__(self): def __init__(self):
self.interface = rtlink.Interface( self.interface = rtlink.Interface(rtlink.OInterface(32))
rtlink.OInterface(32, suppress_nop=False))
self.probes = [] self.probes = []
self.overrides = [] self.overrides = []

View File

@ -79,8 +79,7 @@ class Inout(Module):
class ClockGen(Module): class ClockGen(Module):
def __init__(self, pad, ftw_width=24): def __init__(self, pad, ftw_width=24):
self.rtlink = rtlink.Interface( self.rtlink = rtlink.Interface(rtlink.OInterface(ftw_width))
rtlink.OInterface(ftw_width, suppress_nop=False))
# # # # # #

View File

@ -13,7 +13,6 @@ class RT2WB(Module):
rtlink.OInterface( rtlink.OInterface(
len(wb.dat_w), len(wb.dat_w),
address_width + 1, address_width + 1,
suppress_nop=False,
enable_replace=rtio_enable_replace), enable_replace=rtio_enable_replace),
rtlink.IInterface( rtlink.IInterface(
len(wb.dat_r), len(wb.dat_r),

View File

@ -3,8 +3,7 @@ from migen import *
class OInterface: class OInterface:
def __init__(self, data_width, address_width=0, def __init__(self, data_width, address_width=0,
fine_ts_width=0, suppress_nop=True, fine_ts_width=0, enable_replace=True):
enable_replace=True):
self.stb = Signal() self.stb = Signal()
self.busy = Signal() self.busy = Signal()
@ -15,7 +14,6 @@ class OInterface:
if fine_ts_width: if fine_ts_width:
self.fine_ts = Signal(fine_ts_width) self.fine_ts = Signal(fine_ts_width)
self.suppress_nop = suppress_nop
self.enable_replace = enable_replace self.enable_replace = enable_replace
@classmethod @classmethod
@ -23,7 +21,7 @@ class OInterface:
return cls(get_data_width(other), return cls(get_data_width(other),
get_address_width(other), get_address_width(other),
get_fine_ts_width(other), get_fine_ts_width(other),
other.suppress_nop) other.enable_replace)
class IInterface: class IInterface: