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()
|
any_error = Signal()
|
||||||
nop = Signal()
|
nop = Signal()
|
||||||
self.sync.rsys += [
|
self.sync.rsys += [
|
||||||
# Note: replace does not perform any RTLink address checks,
|
# Note: replace may be asserted at the same time as collision
|
||||||
# i.e. a write to a different address will be silently replaced
|
# when addresses are different. In that case, it is a collision.
|
||||||
# as well.
|
|
||||||
replace.eq(self.ev.timestamp == buf.timestamp),
|
replace.eq(self.ev.timestamp == buf.timestamp),
|
||||||
# Detect sequence errors on coarse timestamps only
|
# Detect sequence errors on coarse timestamps only
|
||||||
# so that they are mutually exclusive with collision errors.
|
# so that they are mutually exclusive with collision errors.
|
||||||
sequence_error.eq(self.ev.timestamp[fine_ts_width:]
|
sequence_error.eq(self.ev.timestamp[fine_ts_width:]
|
||||||
< buf.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:
|
if fine_ts_width:
|
||||||
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.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)
|
self.comb += any_error.eq(sequence_error | collision)
|
||||||
if interface.suppress_nop:
|
if interface.suppress_nop:
|
||||||
# disable NOP at reset: do not suppress a first write with all 0s
|
# disable NOP at reset: do not suppress a first write with all 0s
|
||||||
|
|
|
@ -163,6 +163,17 @@ class Collision(EnvExperiment):
|
||||||
delay_mu(1)
|
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):
|
class TimeKeepsRunning(EnvExperiment):
|
||||||
def build(self):
|
def build(self):
|
||||||
self.setattr_device("core")
|
self.setattr_device("core")
|
||||||
|
@ -224,6 +235,10 @@ class CoredeviceTest(ExperimentCase):
|
||||||
with self.assertRaises(RTIOCollision):
|
with self.assertRaises(RTIOCollision):
|
||||||
self.execute(Collision)
|
self.execute(Collision)
|
||||||
|
|
||||||
|
def test_address_collision(self):
|
||||||
|
with self.assertRaises(RTIOCollision):
|
||||||
|
self.execute(AddressCollision)
|
||||||
|
|
||||||
def test_watchdog(self):
|
def test_watchdog(self):
|
||||||
# watchdog only works on the device
|
# watchdog only works on the device
|
||||||
with self.assertRaises(IOError):
|
with self.assertRaises(IOError):
|
||||||
|
|
Loading…
Reference in New Issue