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
This commit is contained in:
parent
9f80acd9ba
commit
4d03154e63
|
@ -25,6 +25,8 @@ import analyzer
|
||||||
import acpki
|
import acpki
|
||||||
import drtio_aux_controller
|
import drtio_aux_controller
|
||||||
import zynq_clocking
|
import zynq_clocking
|
||||||
|
import cxp_4r_fmc
|
||||||
|
import cxp
|
||||||
from config import write_csr_file, write_mem_file, write_rustc_cfg_file
|
from config import write_csr_file, write_mem_file, write_rustc_cfg_file
|
||||||
|
|
||||||
class SMAClkinForward(Module):
|
class SMAClkinForward(Module):
|
||||||
|
@ -138,7 +140,7 @@ class ZC706(SoCCore):
|
||||||
platform.add_extension(si5324_fmc33)
|
platform.add_extension(si5324_fmc33)
|
||||||
self.comb += platform.request("si5324_33").rst_n.eq(1)
|
self.comb += platform.request("si5324_33").rst_n.eq(1)
|
||||||
|
|
||||||
cdr_clk = Signal()
|
self.cdr_clk = Signal()
|
||||||
cdr_clk_buf = Signal()
|
cdr_clk_buf = Signal()
|
||||||
si5324_out = platform.request("si5324_clkout")
|
si5324_out = platform.request("si5324_clkout")
|
||||||
platform.add_period_constraint(si5324_out.p, 8.0)
|
platform.add_period_constraint(si5324_out.p, 8.0)
|
||||||
|
@ -146,11 +148,11 @@ class ZC706(SoCCore):
|
||||||
Instance("IBUFDS_GTE2",
|
Instance("IBUFDS_GTE2",
|
||||||
i_CEB=0,
|
i_CEB=0,
|
||||||
i_I=si5324_out.p, i_IB=si5324_out.n,
|
i_I=si5324_out.p, i_IB=si5324_out.n,
|
||||||
o_O=cdr_clk,
|
o_O=self.cdr_clk,
|
||||||
p_CLKCM_CFG="TRUE",
|
p_CLKCM_CFG="TRUE",
|
||||||
p_CLKRCV_TRST="TRUE",
|
p_CLKRCV_TRST="TRUE",
|
||||||
p_CLKSWING_CFG=3),
|
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["HAS_SI5324"] = None
|
||||||
self.config["SI5324_AS_SYNTHESIZER"] = None
|
self.config["SI5324_AS_SYNTHESIZER"] = None
|
||||||
|
@ -652,6 +654,119 @@ class _NIST_QC2_RTIO:
|
||||||
self.add_rtio(rtio_channels)
|
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")
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
# TODO: cdr = ClockDomainsRenamer({"cxp_gtx_rx": "cxp_gtx_rx" + str(i)})
|
||||||
|
|
||||||
|
cxp_interface = cxp.CXP_Interface(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)
|
||||||
|
|
||||||
|
|
||||||
|
tx_mem_name = "cxp_tx" + str(i) + "_mem"
|
||||||
|
tx_mem_size = cxp_interface.get_tx_mem_size()
|
||||||
|
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)
|
||||||
|
cxp_tx_mem_group.append(tx_mem_name)
|
||||||
|
|
||||||
|
rx_mem_name = "cxp_rx" + str(i) + "_mem"
|
||||||
|
rx_mem_size = cxp_interface.get_rx_mem_size()
|
||||||
|
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)
|
||||||
|
cxp_rx_mem_group.append(rx_mem_name)
|
||||||
|
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
rtio_channels = []
|
||||||
|
# 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):
|
class NIST_CLOCK(ZC706, _NIST_CLOCK_RTIO):
|
||||||
def __init__(self, acpki, drtio100mhz):
|
def __init__(self, acpki, drtio100mhz):
|
||||||
ZC706.__init__(self, acpki)
|
ZC706.__init__(self, acpki)
|
||||||
|
@ -684,8 +799,13 @@ class NIST_QC2_Satellite(_SatelliteBase, _NIST_QC2_RTIO):
|
||||||
_SatelliteBase.__init__(self, acpki, drtio100mhz)
|
_SatelliteBase.__init__(self, acpki, drtio100mhz)
|
||||||
_NIST_QC2_RTIO.__init__(self)
|
_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,
|
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():
|
def main():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
|
|
Loading…
Reference in New Issue