From 1e313afe642c6628924d60aad22fb28c73c336f9 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Fri, 21 Oct 2016 22:45:45 +0800 Subject: [PATCH] drtio: CrossDomainNotification --- artiq/gateware/drtio/rt_packets.py | 20 +++++++++ artiq/test/gateware/drtio/test_rt_packets.py | 47 +++++++++++++++++++- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/artiq/gateware/drtio/rt_packets.py b/artiq/gateware/drtio/rt_packets.py index 05a8ae1cf..51123654f 100644 --- a/artiq/gateware/drtio/rt_packets.py +++ b/artiq/gateware/drtio/rt_packets.py @@ -345,3 +345,23 @@ class _CrossDomainRequest(Module): self.comb += reply.i.eq(srv_stb & srv_ack) +class _CrossDomainNotification(Module): + def __init__(self, domain, + emi_stb, emi_data, + rec_stb, rec_ack, rec_data): + emi_data_r = Signal.like(emi_data) + self.specials += NoRetiming(emi_data_r) + dsync = getattr(self.sync, domain) + dsync += If(emi_stb, emi_data_r.eq(emi_data)) + + ps = PulseSynchronizer(domain, "sys") + self.submodules += ps + self.comb += ps.i.eq(emi_stb) + self.sync += [ + If(rec_ack, rec_stb.eq(0)), + If(ps.o, + rec_data.eq(emi_data_r), + rec_stb.eq(1) + ) + ] + diff --git a/artiq/test/gateware/drtio/test_rt_packets.py b/artiq/test/gateware/drtio/test_rt_packets.py index 693176392..72f7531e0 100644 --- a/artiq/test/gateware/drtio/test_rt_packets.py +++ b/artiq/test/gateware/drtio/test_rt_packets.py @@ -5,7 +5,8 @@ import random from migen import * from artiq.gateware.drtio.rt_packets import * -from artiq.gateware.drtio.rt_packets import _CrossDomainRequest +from artiq.gateware.drtio.rt_packets import (_CrossDomainRequest, + _CrossDomainNotification) class PacketInterface: @@ -123,7 +124,7 @@ class TestSatellite(unittest.TestCase): self.assertEqual(tx_times, rx_times) -class TestCrossDomainRequest(unittest.TestCase): +class TestCDC(unittest.TestCase): def test_cross_domain_request(self): prng = random.Random(1) for sys_freq in 3, 6, 11: @@ -167,3 +168,45 @@ class TestCrossDomainRequest(unittest.TestCase): {"sys": requester(), "srv": server()}, {"sys": sys_freq, "srv": srv_freq}) self.assertEqual(test_seq, received_seq) + + def test_cross_domain_notification(self): + prng = random.Random(1) + + emi_stb = Signal() + emi_data = Signal(8) + rec_stb = Signal() + rec_ack = Signal() + rec_data = Signal(8) + + test_seq = [23, 12, 8, 3, 28] + received_seq = [] + + def emitter(): + for data in test_seq: + yield emi_stb.eq(1) + yield emi_data.eq(data) + yield + yield emi_stb.eq(0) + yield + for j in range(prng.randrange(0, 3)): + yield + + def receiver(): + for i in range(len(test_seq)): + while not (yield rec_stb): + yield + received_seq.append((yield rec_data)) + yield rec_ack.eq(1) + yield + yield rec_ack.eq(0) + yield + for j in range(prng.randrange(0, 3)): + yield + + dut = _CrossDomainNotification("emi", + emi_stb, emi_data, + rec_stb, rec_ack, rec_data) + run_simulation(dut, + {"emi": emitter(), "sys": receiver()}, + {"emi": 13, "sys": 3}) + self.assertEqual(test_seq, received_seq)