forked from M-Labs/artiq
rtio: when rtlink addresses are different, issue collision not replace (fixes #320)
This commit is contained in:
parent
71105fd0d7
commit
2953b069dc
|
@ -130,19 +130,23 @@ class _OutputManager(Module):
|
|||
any_error = Signal()
|
||||
nop = Signal()
|
||||
self.sync.rsys += [
|
||||
# Note: replace does not perform any RTLink address checks,
|
||||
# i.e. a write to a different address will be silently replaced
|
||||
# as well.
|
||||
# Note: replace may be asserted at the same time as collision
|
||||
# when addresses are different. In that case, it is a collision.
|
||||
replace.eq(self.ev.timestamp == buf.timestamp),
|
||||
# Detect sequence errors on coarse timestamps only
|
||||
# so that they are mutually exclusive with collision errors.
|
||||
sequence_error.eq(self.ev.timestamp[fine_ts_width:]
|
||||
< buf.timestamp[fine_ts_width:])
|
||||
]
|
||||
if hasattr(self.ev, "a"):
|
||||
different_addresses = self.ev.a != buf.a
|
||||
else:
|
||||
different_addresses = 0
|
||||
if fine_ts_width:
|
||||
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.ev.timestamp[:fine_ts_width] != buf.timestamp[:fine_ts_width])
|
||||
|different_addresses))
|
||||
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
|
||||
|
|
|
@ -163,6 +163,17 @@ class Collision(EnvExperiment):
|
|||
delay_mu(1)
|
||||
|
||||
|
||||
class AddressCollision(EnvExperiment):
|
||||
def build(self):
|
||||
self.setattr_device("core")
|
||||
self.setattr_device("loop_in")
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.loop_in.input()
|
||||
self.loop_in.pulse(10*us)
|
||||
|
||||
|
||||
class TimeKeepsRunning(EnvExperiment):
|
||||
def build(self):
|
||||
self.setattr_device("core")
|
||||
|
@ -224,6 +235,10 @@ class CoredeviceTest(ExperimentCase):
|
|||
with self.assertRaises(RTIOCollision):
|
||||
self.execute(Collision)
|
||||
|
||||
def test_address_collision(self):
|
||||
with self.assertRaises(RTIOCollision):
|
||||
self.execute(AddressCollision)
|
||||
|
||||
def test_watchdog(self):
|
||||
# watchdog only works on the device
|
||||
with self.assertRaises(IOError):
|
||||
|
|
Loading…
Reference in New Issue