forked from M-Labs/artiq-zynq
kasli soc: add coaxpress-sfp support to standalone
cxp-sfp: add IBUFDS_GTE2 cxp-sfp: add CXPGrabber with its memory region and CSR cxp-sfp: add `CXPGrabber` rtio interface to self.rtio_channels cxp-sfp: add timing requirement for cd_cxp_gt_rx master/satellite: raise warning when using coaxpress-sfp
This commit is contained in:
parent
04856e66d0
commit
0717003c42
@ -15,7 +15,7 @@ from misoc.cores import virtual_leds
|
||||
from artiq.coredevice import jsondesc
|
||||
from artiq.gateware import rtio, eem_7series
|
||||
from artiq.gateware.rtio.xilinx_clocking import fix_serdes_timing_path
|
||||
from artiq.gateware.rtio.phy import ttl_simple
|
||||
from artiq.gateware.rtio.phy import ttl_simple, cxp_grabber
|
||||
from artiq.gateware.drtio.transceiver import gtx_7series, eem_serdes
|
||||
from artiq.gateware.drtio.siphaser import SiPhaser7Series
|
||||
from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer
|
||||
@ -161,12 +161,20 @@ class GenericStandalone(SoCCore):
|
||||
self.config["HAS_SI5324"] = None
|
||||
self.config["SI5324_SOFT_RESET"] = None
|
||||
|
||||
|
||||
self.rtio_channels = []
|
||||
has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"])
|
||||
if has_grabber:
|
||||
self.grabber_csr_group = []
|
||||
eem_7series.add_peripherals(self, description["peripherals"], iostandard=eem_iostandard)
|
||||
|
||||
has_grabber = False
|
||||
eem_peripherals = []
|
||||
for peripheral in description["peripherals"]:
|
||||
if peripheral["type"] == "coaxpress_sfp":
|
||||
self.add_coaxpress_sfp(clk_freq, peripheral["roi_engine_count"])
|
||||
elif peripheral["type"] == "grabber":
|
||||
has_grabber = True
|
||||
self.grabber_csr_group = []
|
||||
eem_peripherals.append(peripheral)
|
||||
else:
|
||||
eem_peripherals.append(peripheral)
|
||||
eem_7series.add_peripherals(self, eem_peripherals, iostandard=eem_iostandard)
|
||||
for i in (0, 1):
|
||||
print("USER LED at RTIO channel 0x{:06x}".format(len(self.rtio_channels)))
|
||||
user_led = self.platform.request("user_led", i)
|
||||
@ -216,6 +224,46 @@ class GenericStandalone(SoCCore):
|
||||
self.platform.add_false_path_constraints(
|
||||
self.sys_crg.cd_sys.clk, getattr(self, grabber).deserializer.cd_cl.clk)
|
||||
|
||||
def add_coaxpress_sfp(self, clk_freq, roi_engine_count):
|
||||
refclk = Signal()
|
||||
gt_refclk_pad = self.platform.request("clk_gtp")
|
||||
self.platform.add_period_constraint(gt_refclk_pad.p, 8.0)
|
||||
self.specials += Instance("IBUFDS_GTE2",
|
||||
i_CEB=0,
|
||||
i_I=gt_refclk_pad.p,
|
||||
i_IB=gt_refclk_pad.n,
|
||||
o_O=refclk,
|
||||
p_CLKCM_CFG="TRUE",
|
||||
p_CLKRCV_TRST="TRUE",
|
||||
p_CLKSWING_CFG=3
|
||||
)
|
||||
|
||||
sfp_slot = 0
|
||||
self.submodules.cxp_grabber = cxp_grabber.CXPGrabber(
|
||||
refclk=refclk,
|
||||
gt_pads=[self.platform.request("sfp", sfp_slot)],
|
||||
sys_clk_freq=clk_freq,
|
||||
roi_engine_count=roi_engine_count
|
||||
)
|
||||
|
||||
mem_size = self.cxp_grabber.core.get_mem_size()
|
||||
# upper half is tx while lower half is rx
|
||||
memory_address = self.axi2csr.register_port(self.cxp_grabber.core.get_tx_port(), mem_size)
|
||||
self.axi2csr.register_port(self.cxp_grabber.core.get_rx_port(), mem_size)
|
||||
self.add_memory_region("cxp_mem", self.mem_map["csr"] + memory_address, mem_size * 2)
|
||||
self.csr_devices.append("cxp_grabber")
|
||||
|
||||
print("CoaXPress-SFP (SFP{}) at RTIO channel 0x{:06x}".format(sfp_slot, len(self.rtio_channels)))
|
||||
self.rtio_channels += [
|
||||
rtio.Channel(self.cxp_grabber.trigger),
|
||||
rtio.Channel(self.cxp_grabber.config),
|
||||
rtio.Channel(self.cxp_grabber.gate_data),
|
||||
]
|
||||
# max freq of cxp_gt_rx = linerate/internal_datawidth = 12.5Gbps/40 = 312.5MHz
|
||||
rx = self.cxp_grabber.phy.phys[0]
|
||||
self.platform.add_period_constraint(rx.gtx.cd_cxp_gt_rx.clk, 3.2)
|
||||
# constraint the clk path
|
||||
self.platform.add_false_path_constraints(self.sys_crg.cd_sys.clk, rx.gtx.cd_cxp_gt_rx.clk)
|
||||
|
||||
class GenericMaster(SoCCore):
|
||||
def __init__(self, description, acpki=False):
|
||||
@ -690,6 +738,9 @@ def main():
|
||||
args = parser.parse_args()
|
||||
description = jsondesc.load(args.description)
|
||||
|
||||
has_coaxpress_sfp = any(peripheral["type"] == "coaxpress_sfp" for peripheral in description["peripherals"])
|
||||
if has_coaxpress_sfp and description["drtio_role"] != "standalone":
|
||||
raise ValueError("CoaXPress-SFP requires free SFP ports, please switch role to standalone")
|
||||
if description["target"] != "kasli_soc":
|
||||
raise ValueError("Description is for a different target")
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user