forked from M-Labs/artiq
drtio: share CDC
This commit is contained in:
parent
078c862618
commit
88b7529d09
|
@ -3,63 +3,12 @@
|
||||||
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.fifo import AsyncFIFO
|
||||||
from migen.genlib.cdc import PulseSynchronizer
|
|
||||||
|
|
||||||
from artiq.gateware.rtio.cdc import GrayCodeTransfer, BlindTransfer
|
from artiq.gateware.rtio.cdc import GrayCodeTransfer, BlindTransfer
|
||||||
|
from artiq.gateware.drtio.cdc import CrossDomainRequest, CrossDomainNotification
|
||||||
from artiq.gateware.drtio.rt_serializer import *
|
from artiq.gateware.drtio.rt_serializer import *
|
||||||
|
|
||||||
|
|
||||||
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:
|
|
||||||
req_data_r = Signal.like(req_data)
|
|
||||||
req_data_r.attr.add("no_retiming")
|
|
||||||
self.sync += If(req_stb, req_data_r.eq(req_data))
|
|
||||||
dsync += [
|
|
||||||
If(request.o, srv_stb.eq(1)),
|
|
||||||
If(srv_ack, srv_stb.eq(0))
|
|
||||||
]
|
|
||||||
if req_data is not None:
|
|
||||||
dsync += If(request.o, srv_data.eq(req_data_r))
|
|
||||||
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(len(emi_data))
|
|
||||||
emi_data_r.attr.add("no_retiming")
|
|
||||||
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)
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class RTPacketMaster(Module):
|
class RTPacketMaster(Module):
|
||||||
def __init__(self, link_layer, sr_fifo_depth=4):
|
def __init__(self, link_layer, sr_fifo_depth=4):
|
||||||
# all interface signals in sys domain unless otherwise specified
|
# all interface signals in sys domain unless otherwise specified
|
||||||
|
@ -206,19 +155,19 @@ class RTPacketMaster(Module):
|
||||||
# CDC
|
# CDC
|
||||||
buffer_space_not = Signal()
|
buffer_space_not = Signal()
|
||||||
buffer_space = Signal(16)
|
buffer_space = Signal(16)
|
||||||
self.submodules += _CrossDomainNotification("rtio_rx",
|
self.submodules += CrossDomainNotification("rtio_rx", "sys",
|
||||||
buffer_space_not, buffer_space,
|
buffer_space_not, buffer_space,
|
||||||
self.buffer_space_not, self.buffer_space_not_ack, self.buffer_space)
|
self.buffer_space_not, self.buffer_space_not_ack, self.buffer_space)
|
||||||
|
|
||||||
set_time_stb = Signal()
|
set_time_stb = Signal()
|
||||||
set_time_ack = Signal()
|
set_time_ack = Signal()
|
||||||
self.submodules += _CrossDomainRequest("rtio",
|
self.submodules += CrossDomainRequest("rtio",
|
||||||
self.set_time_stb, self.set_time_ack, None,
|
self.set_time_stb, self.set_time_ack, None,
|
||||||
set_time_stb, set_time_ack, None)
|
set_time_stb, set_time_ack, None)
|
||||||
|
|
||||||
echo_stb = Signal()
|
echo_stb = Signal()
|
||||||
echo_ack = Signal()
|
echo_ack = Signal()
|
||||||
self.submodules += _CrossDomainRequest("rtio",
|
self.submodules += CrossDomainRequest("rtio",
|
||||||
self.echo_stb, self.echo_ack, None,
|
self.echo_stb, self.echo_ack, None,
|
||||||
echo_stb, echo_ack, None)
|
echo_stb, echo_ack, None)
|
||||||
|
|
||||||
|
@ -227,7 +176,7 @@ class RTPacketMaster(Module):
|
||||||
read_is_overflow = Signal()
|
read_is_overflow = Signal()
|
||||||
read_data = Signal(32)
|
read_data = Signal(32)
|
||||||
read_timestamp = Signal(64)
|
read_timestamp = Signal(64)
|
||||||
self.submodules += _CrossDomainNotification("rtio_rx",
|
self.submodules += CrossDomainNotification("rtio_rx", "sys",
|
||||||
read_not,
|
read_not,
|
||||||
Cat(read_no_event, read_is_overflow, read_data, read_timestamp),
|
Cat(read_no_event, read_is_overflow, read_data, read_timestamp),
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@ import random
|
||||||
|
|
||||||
from migen import *
|
from migen import *
|
||||||
|
|
||||||
from artiq.gateware.drtio.rt_packet_master import (_CrossDomainRequest,
|
from artiq.gateware.drtio.cdc import CrossDomainRequest, CrossDomainNotification
|
||||||
_CrossDomainNotification)
|
|
||||||
|
|
||||||
class TestCDC(unittest.TestCase):
|
class TestCDC(unittest.TestCase):
|
||||||
def test_cross_domain_request(self):
|
def test_cross_domain_request(self):
|
||||||
|
@ -43,7 +43,7 @@ class TestCDC(unittest.TestCase):
|
||||||
yield srv_ack.eq(0)
|
yield srv_ack.eq(0)
|
||||||
yield
|
yield
|
||||||
|
|
||||||
dut = _CrossDomainRequest("srv",
|
dut = CrossDomainRequest("srv",
|
||||||
req_stb, req_ack, req_data,
|
req_stb, req_ack, req_data,
|
||||||
srv_stb, srv_ack, srv_data)
|
srv_stb, srv_ack, srv_data)
|
||||||
run_simulation(dut,
|
run_simulation(dut,
|
||||||
|
@ -85,7 +85,7 @@ class TestCDC(unittest.TestCase):
|
||||||
for j in range(prng.randrange(0, 3)):
|
for j in range(prng.randrange(0, 3)):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
dut = _CrossDomainNotification("emi",
|
dut = CrossDomainNotification("emi", "sys",
|
||||||
emi_stb, emi_data,
|
emi_stb, emi_data,
|
||||||
rec_stb, rec_ack, rec_data)
|
rec_stb, rec_ack, rec_data)
|
||||||
run_simulation(dut,
|
run_simulation(dut,
|
||||||
|
|
Loading…
Reference in New Issue