forked from M-Labs/artiq-zynq
zc706: add CXP_DEMO variant
zc706: add fmc pads zc706: add constraint to fix comma alignment & setup/hold time issue zc706: add csr & mem group for cxp zc706: add CXP to rtio_channel
This commit is contained in:
parent
4f5dbf05a4
commit
e9750d1848
|
@ -25,6 +25,8 @@ import analyzer
|
|||
import acpki
|
||||
import drtio_aux_controller
|
||||
import zynq_clocking
|
||||
import cxp_4r_fmc
|
||||
import cxp
|
||||
from config import write_csr_file, write_mem_file, write_rustc_cfg_file
|
||||
|
||||
class SMAClkinForward(Module):
|
||||
|
@ -138,7 +140,7 @@ class ZC706(SoCCore):
|
|||
platform.add_extension(si5324_fmc33)
|
||||
self.comb += platform.request("si5324_33").rst_n.eq(1)
|
||||
|
||||
cdr_clk = Signal()
|
||||
self.cdr_clk = Signal()
|
||||
cdr_clk_buf = Signal()
|
||||
si5324_out = platform.request("si5324_clkout")
|
||||
platform.add_period_constraint(si5324_out.p, 8.0)
|
||||
|
@ -146,11 +148,11 @@ class ZC706(SoCCore):
|
|||
Instance("IBUFDS_GTE2",
|
||||
i_CEB=0,
|
||||
i_I=si5324_out.p, i_IB=si5324_out.n,
|
||||
o_O=cdr_clk,
|
||||
o_O=self.cdr_clk,
|
||||
p_CLKCM_CFG="TRUE",
|
||||
p_CLKRCV_TRST="TRUE",
|
||||
p_CLKSWING_CFG=3),
|
||||
Instance("BUFG", i_I=cdr_clk, o_O=cdr_clk_buf)
|
||||
Instance("BUFG", i_I=self.cdr_clk, o_O=cdr_clk_buf)
|
||||
]
|
||||
self.config["HAS_SI5324"] = None
|
||||
self.config["SI5324_AS_SYNTHESIZER"] = None
|
||||
|
@ -652,6 +654,129 @@ class _NIST_QC2_RTIO:
|
|||
self.add_rtio(rtio_channels)
|
||||
|
||||
|
||||
class CXP_FMC():
|
||||
"""
|
||||
CoaXpress FMC with 4 CXP channel and 1 SMA trigger
|
||||
"""
|
||||
def __init__(self):
|
||||
platform = self.platform
|
||||
platform.add_extension(cxp_4r_fmc.fmc_adapter_io)
|
||||
platform.add_extension(leds_fmc33)
|
||||
|
||||
debug_sma = [
|
||||
("user_sma_clock_33", 0,
|
||||
Subsignal("p_tx", Pins("AD18"), IOStandard("LVCMOS33")),
|
||||
Subsignal("n_rx", Pins("AD19"), IOStandard("LVCMOS33")),
|
||||
),
|
||||
]
|
||||
|
||||
pmod1_33 = [
|
||||
("pmod1_33", 0, Pins("AJ21"), IOStandard("LVCMOS33")),
|
||||
("pmod1_33", 1, Pins("AK21"), IOStandard("LVCMOS33")),
|
||||
("pmod1_33", 2, Pins("AB21"), IOStandard("LVCMOS33")),
|
||||
("pmod1_33", 3, Pins("AB16"), IOStandard("LVCMOS33")),
|
||||
("pmod1_33", 4, Pins("Y20"), IOStandard("LVCMOS33")),
|
||||
("pmod1_33", 5, Pins("AA20"), IOStandard("LVCMOS33")),
|
||||
("pmod1_33", 6, Pins("AC18"), IOStandard("LVCMOS33")),
|
||||
("pmod1_33", 7, Pins("AC19"), IOStandard("LVCMOS33")),
|
||||
]
|
||||
|
||||
platform.add_extension(debug_sma)
|
||||
platform.add_extension(pmod1_33)
|
||||
debug_sma_pad = platform.request("user_sma_clock_33")
|
||||
pmod_pads = [platform.request("pmod1_33", i) for i in range(8)]
|
||||
|
||||
clk_freq = 125e6
|
||||
|
||||
links = 1
|
||||
cxp_downconn_pads = [platform.request("CXP_HS", i) for i in range(links)]
|
||||
cxp_upconn_pads = [platform.request("CXP_LS", i) for i in range(links)]
|
||||
|
||||
|
||||
self.submodules.cxp_phys = cxp_phys = cxp.CXP_PHYS(
|
||||
refclk=self.cdr_clk,
|
||||
upconn_pads=cxp_upconn_pads,
|
||||
downconn_pads=cxp_downconn_pads,
|
||||
sys_clk_freq=clk_freq,
|
||||
debug_sma=debug_sma_pad,
|
||||
pmod_pads = pmod_pads
|
||||
)
|
||||
self.csr_devices.append("cxp_phys")
|
||||
|
||||
|
||||
rtio_channels = []
|
||||
cxp_csr_group = []
|
||||
cxp_tx_mem_group = []
|
||||
cxp_rx_mem_group = []
|
||||
cxp_loopback_mem_group = []
|
||||
for i, (tx, rx) in enumerate(zip(cxp_phys.upconn.tx_phys, cxp_phys.downconn.rx_phys)):
|
||||
cxp_name = "cxp" + str(i)
|
||||
|
||||
cdr = ClockDomainsRenamer({"cxp_gtx_rx": "cxp_gtx_rx" + str(i)})
|
||||
|
||||
if i == 0:
|
||||
cxp_interface = cdr(cxp.CXP_Master(tx, rx, debug_sma_pad, pmod_pads))
|
||||
|
||||
# Add rtlink for Master Connection only
|
||||
print("CoaXPress at RTIO channel 0x{:06x}".format(len(rtio_channels)))
|
||||
rtio_channels.append(rtio.Channel.from_phy(cxp_interface))
|
||||
|
||||
else:
|
||||
cxp_interface = cdr(cxp.CXP_Extension(tx, rx, debug_sma_pad, pmod_pads))
|
||||
|
||||
setattr(self.submodules, cxp_name, cxp_interface)
|
||||
self.csr_devices.append(cxp_name)
|
||||
cxp_csr_group.append(cxp_name)
|
||||
|
||||
|
||||
|
||||
# Add memory group
|
||||
rx_mem_name = "cxp_rx" + str(i) + "_mem"
|
||||
rx_mem_size = cxp_interface.get_rx_mem_size()
|
||||
cxp_rx_mem_group.append(rx_mem_name)
|
||||
memory_address = self.axi2csr.register_port(cxp_interface.get_rx_port(), rx_mem_size)
|
||||
self.add_memory_region(rx_mem_name, self.mem_map["csr"] + memory_address, rx_mem_size)
|
||||
|
||||
tx_mem_name = "cxp_tx" + str(i) + "_mem"
|
||||
tx_mem_size = cxp_interface.get_tx_mem_size()
|
||||
cxp_tx_mem_group.append(tx_mem_name)
|
||||
memory_address = self.axi2csr.register_port(cxp_interface.get_tx_port(), tx_mem_size)
|
||||
self.add_memory_region(tx_mem_name, self.mem_map["csr"] + memory_address, tx_mem_size)
|
||||
|
||||
# DEBUG loopback tx memory
|
||||
loopback_mem_name = "cxp_loopback_tx" + str(i) + "_mem"
|
||||
loopback_mem_size = cxp_interface.get_loopback_tx_mem_size()
|
||||
cxp_loopback_mem_group.append(loopback_mem_name)
|
||||
memory_address = self.axi2csr.register_port(cxp_interface.get_loopback_tx_port(), loopback_mem_size)
|
||||
self.add_memory_region(loopback_mem_name, self.mem_map["csr"] + memory_address, loopback_mem_size)
|
||||
|
||||
self.add_memory_group("cxp_tx_mem", cxp_tx_mem_group)
|
||||
self.add_memory_group("cxp_rx_mem", cxp_rx_mem_group)
|
||||
self.add_memory_group("cxp_loopback_mem", cxp_loopback_mem_group)
|
||||
self.add_csr_group("cxp", cxp_csr_group)
|
||||
|
||||
# max freq of cxp_gtx_rx = linerate/internal_datawidth = 12.5Gbps/40 = 312.5MHz
|
||||
# zc706 use speed grade 2 which only support up to 10.3125Gbps (4ns)
|
||||
# pushing to 12.5Gbps (3.2ns) will result in Pulse width violation but setup/hold times are met
|
||||
for rx in cxp_phys.downconn.rx_phys :
|
||||
platform.add_period_constraint(rx.gtx.cd_cxp_gtx_tx.clk, 3.2)
|
||||
platform.add_period_constraint(rx.gtx.cd_cxp_gtx_rx.clk, 3.2)
|
||||
# constraint the CLK path
|
||||
platform.add_false_path_constraints(self.sys_crg.cd_sys.clk, rx.gtx.cd_cxp_gtx_tx.clk, rx.gtx.cd_cxp_gtx_rx.clk)
|
||||
|
||||
# FIXME remove this placeholder RTIO channel
|
||||
# There are too few RTIO channels and cannot be compiled (adr width issue of the lane distributor)
|
||||
# see https://github.com/m-labs/artiq/pull/2158 for similar issue
|
||||
print("USER LED at RTIO channel 0x{:06x}".format(len(rtio_channels)))
|
||||
phy = ttl_simple.Output(self.platform.request("user_led_33", 0))
|
||||
self.submodules += phy
|
||||
rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||
self.config["HAS_RTIO_LOG"] = None
|
||||
rtio_channels.append(rtio.LogChannel())
|
||||
|
||||
self.config["RTIO_LOG_CHANNEL"] = len(rtio_channels)
|
||||
self.add_rtio(rtio_channels)
|
||||
|
||||
class NIST_CLOCK(ZC706, _NIST_CLOCK_RTIO):
|
||||
def __init__(self, acpki, drtio100mhz):
|
||||
ZC706.__init__(self, acpki)
|
||||
|
@ -684,8 +809,13 @@ class NIST_QC2_Satellite(_SatelliteBase, _NIST_QC2_RTIO):
|
|||
_SatelliteBase.__init__(self, acpki, drtio100mhz)
|
||||
_NIST_QC2_RTIO.__init__(self)
|
||||
|
||||
class CXP_Demo(ZC706, CXP_FMC):
|
||||
def __init__(self, acpki, drtio100mhz):
|
||||
ZC706.__init__(self, acpki)
|
||||
CXP_FMC.__init__(self)
|
||||
|
||||
VARIANTS = {cls.__name__.lower(): cls for cls in [NIST_CLOCK, NIST_CLOCK_Master, NIST_CLOCK_Satellite,
|
||||
NIST_QC2, NIST_QC2_Master, NIST_QC2_Satellite]}
|
||||
NIST_QC2, NIST_QC2_Master, NIST_QC2_Satellite, CXP_Demo]}
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
|
|
Loading…
Reference in New Issue