2
0
mirror of https://github.com/m-labs/artiq.git synced 2024-12-25 11:18:27 +08:00

rtio: when rtlink addresses are different, issue collision not replace (fixes #320)

This commit is contained in:
Sebastien Bourdeauducq 2016-03-08 15:58:25 +08:00
parent 71105fd0d7
commit 2953b069dc
2 changed files with 23 additions and 4 deletions

View File

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

View File

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