mirror of https://github.com/m-labs/artiq.git
drtio: CrossDomainRequest
This commit is contained in:
parent
9790c5d9ed
commit
6a88229e6a
|
@ -2,6 +2,8 @@ from types import SimpleNamespace
|
||||||
|
|
||||||
from migen import *
|
from migen import *
|
||||||
from migen.genlib.fsm import *
|
from migen.genlib.fsm import *
|
||||||
|
from migen.genlib.fifo import AsyncFIFO
|
||||||
|
from migen.genlib.cdc import PulseSynchronizer, NoRetiming
|
||||||
|
|
||||||
|
|
||||||
def layout_len(l):
|
def layout_len(l):
|
||||||
|
@ -311,3 +313,34 @@ class RTPacketSatellite(Module):
|
||||||
tx_dp.stb.eq(1),
|
tx_dp.stb.eq(1),
|
||||||
If(tx_dp.done, NextState("IDLE"))
|
If(tx_dp.done, NextState("IDLE"))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class _CrossDomainRequest(Module):
|
||||||
|
def __init__(self, domain,
|
||||||
|
req_stb, req_ack, req_data,
|
||||||
|
srv_stb, srv_ack, srv_data):
|
||||||
|
dsync = getattr(self.sync, domain)
|
||||||
|
|
||||||
|
request = PulseSynchronizer("sys", domain)
|
||||||
|
reply = PulseSynchronizer(domain, "sys")
|
||||||
|
self.submodules += request, reply
|
||||||
|
|
||||||
|
ongoing = Signal()
|
||||||
|
self.comb += request.i.eq(~ongoing & req_stb)
|
||||||
|
self.sync += [
|
||||||
|
req_ack.eq(reply.o),
|
||||||
|
If(req_stb, ongoing.eq(1)),
|
||||||
|
If(req_ack, ongoing.eq(0))
|
||||||
|
]
|
||||||
|
if req_data is not None:
|
||||||
|
srv_data_r = Signal.like(srv_data)
|
||||||
|
dsync += If(srv_stb & srv_ack, srv_data_r.eq(srv_data))
|
||||||
|
self.specials += NoRetiming(srv_data_r)
|
||||||
|
self.sync += If(reply.o, req_data.eq(srv_data_r))
|
||||||
|
dsync += [
|
||||||
|
If(request.o, srv_stb.eq(1)),
|
||||||
|
If(srv_ack, srv_stb.eq(0))
|
||||||
|
]
|
||||||
|
self.comb += reply.i.eq(srv_stb & srv_ack)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import unittest
|
import unittest
|
||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
|
import random
|
||||||
|
|
||||||
from migen import *
|
from migen import *
|
||||||
|
|
||||||
from artiq.gateware.drtio.rt_packets import *
|
from artiq.gateware.drtio.rt_packets import *
|
||||||
|
from artiq.gateware.drtio.rt_packets import _CrossDomainRequest
|
||||||
|
|
||||||
|
|
||||||
class PacketInterface:
|
class PacketInterface:
|
||||||
|
@ -119,3 +121,50 @@ class TestSatellite(unittest.TestCase):
|
||||||
yield
|
yield
|
||||||
run_simulation(dut, [send(), receive()])
|
run_simulation(dut, [send(), receive()])
|
||||||
self.assertEqual(tx_times, rx_times)
|
self.assertEqual(tx_times, rx_times)
|
||||||
|
|
||||||
|
|
||||||
|
class TestCrossDomainRequest(unittest.TestCase):
|
||||||
|
def test_cross_domain_request(self):
|
||||||
|
for sys_freq in 3, 6, 11:
|
||||||
|
for srv_freq in 3, 6, 11:
|
||||||
|
prng = random.Random(1)
|
||||||
|
|
||||||
|
req_stb = Signal()
|
||||||
|
req_ack = Signal()
|
||||||
|
req_data = Signal(8)
|
||||||
|
srv_stb = Signal()
|
||||||
|
srv_ack = Signal()
|
||||||
|
srv_data = Signal(8)
|
||||||
|
test_seq = [93, 92, 19, 39, 91, 30, 12, 91, 38, 42]
|
||||||
|
received_seq = []
|
||||||
|
|
||||||
|
def requester():
|
||||||
|
for i in range(len(test_seq)):
|
||||||
|
yield req_stb.eq(1)
|
||||||
|
yield
|
||||||
|
while not (yield req_ack):
|
||||||
|
yield
|
||||||
|
received_seq.append((yield req_data))
|
||||||
|
yield req_stb.eq(0)
|
||||||
|
for j in range(prng.randrange(0, 10)):
|
||||||
|
yield
|
||||||
|
|
||||||
|
def server():
|
||||||
|
for data in test_seq:
|
||||||
|
while not (yield srv_stb):
|
||||||
|
yield
|
||||||
|
for j in range(prng.randrange(0, 10)):
|
||||||
|
yield
|
||||||
|
yield srv_data.eq(data)
|
||||||
|
yield srv_ack.eq(1)
|
||||||
|
yield
|
||||||
|
yield srv_ack.eq(0)
|
||||||
|
yield
|
||||||
|
|
||||||
|
dut = _CrossDomainRequest("srv",
|
||||||
|
req_stb, req_ack, req_data,
|
||||||
|
srv_stb, srv_ack, srv_data)
|
||||||
|
run_simulation(dut,
|
||||||
|
{"sys": requester(), "srv": server()},
|
||||||
|
{"sys": sys_freq, "srv": srv_freq})
|
||||||
|
self.assertEqual(test_seq, received_seq)
|
||||||
|
|
Loading…
Reference in New Issue