From b534129d08fbd5879d7db6afcbfb6731b677fc56 Mon Sep 17 00:00:00 2001 From: morgan Date: Mon, 3 Jun 2024 15:58:44 +0800 Subject: [PATCH] zc706: add CXP_DEMO variant zc706: add fmc pads zc706: add constraint to fix comma alignment & setup/hold time issue --- src/gateware/zc706.py | 82 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 4 deletions(-) diff --git a/src/gateware/zc706.py b/src/gateware/zc706.py index 395d6c6..d91c7d7 100755 --- a/src/gateware/zc706.py +++ b/src/gateware/zc706.py @@ -25,6 +25,7 @@ import analyzer import acpki import drtio_aux_controller import zynq_clocking +import cxp_4r_fmc, cxp from config import write_csr_file, write_mem_file, write_rustc_cfg_file class SMAClkinForward(Module): @@ -138,7 +139,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 +147,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 +653,74 @@ 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) + pmod_pads = [platform.request("pmod1_33", i) for i in range(8)] + + clk_freq = 125e6 + + gtx_pads = [platform.request("CXP_HS", i) for i in range(4)] + + self.submodules.cxp = cxp.CXP( + refclk=self.cdr_clk, + downconn_pads=gtx_pads, + upconn_pads=platform.request("CXP_LS", 0), + sys_clk_freq=clk_freq, + debug_sma=platform.request("user_sma_clock_33"), + pmod_pads = pmod_pads + ) + self.csr_devices.append("cxp") + + # 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 gtx in self.cxp.downconn.gtxs: + platform.add_period_constraint(gtx.cd_cxp_gtx_tx.clk, 3.2) + platform.add_period_constraint(gtx.cd_cxp_gtx_rx.clk, 3.2) + # constraint the CLK path + platform.add_false_path_constraints(self.sys_crg.cd_sys.clk, gtx.cd_cxp_gtx_tx.clk, 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): def __init__(self, acpki, drtio100mhz): ZC706.__init__(self, acpki) @@ -684,8 +753,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(