1
0
mirror of https://github.com/corundum/corundum.git synced 2025-01-16 08:12:53 +08:00

fpga/mqnic/Nexus_K3P_S: Switch Cisco Nexus K3P-S designs to use 10 MHz TCXO for PTP reference clock

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich 2022-12-06 14:33:32 -08:00
parent a0aa614362
commit 59911c5ba7
3 changed files with 106 additions and 7 deletions

View File

@ -13,8 +13,11 @@ set_property CONFIG_MODE BPI16 [current_design]
set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design]
# 10 MHz TXCO
#set_property -dict {LOC D14 IOSTANDARD LVCMOS33} [get_ports clk_10mhz]
#create_clock -period 100 -name clk_100mhz [get_ports clk_10mhz]
set_property -dict {LOC D14 IOSTANDARD LVCMOS33} [get_ports clk_10mhz]
create_clock -period 100.000 -name clk_10mhz [get_ports clk_10mhz]
# D14 cannot directly drive MMCM, so need to set CLOCK_DEDICATED_ROUTE to satisfy DRC
set_property CLOCK_DEDICATED_ROUTE ANY_CMT_COLUMN [get_nets clk_10mhz_bufg]
# LEDs
set_property -dict {LOC J12 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sfp_1_led[0]}]

View File

@ -161,6 +161,11 @@ module fpga #
parameter STAT_ID_WIDTH = 12
)
(
/*
* Clock
*/
input wire clk_10mhz,
/*
* GPIO
*/
@ -226,8 +231,8 @@ module fpga #
);
// PTP configuration
parameter PTP_CLK_PERIOD_NS_NUM = 1024;
parameter PTP_CLK_PERIOD_NS_DENOM = 165;
parameter PTP_CLK_PERIOD_NS_NUM = 4;
parameter PTP_CLK_PERIOD_NS_DENOM = 1;
parameter PTP_TS_WIDTH = 96;
parameter PTP_USE_SAMPLE_CLOCK = 1;
parameter IF_PTP_PERIOD_NS = 6'h2;
@ -347,6 +352,97 @@ sync_reset_125mhz_inst (
.out(rst_125mhz_int)
);
// Internal 250 MHz high-stability clock
wire clk_10mhz_bufg;
BUFG
init_clk_bufg_inst (
.I(clk_10mhz),
.O(clk_10mhz_bufg)
);
wire clk_250mhz_mmcm_out;
wire clk_250mhz_int;
wire rst_250mhz_int;
wire mmcm_250mhz_rst = rst_125mhz_int;
wire mmcm_250mhz_locked;
wire mmcm_250mhz_clkfb;
// MMCM instance
// 10 MHz in, 250 MHz out
// PFD range: 10 MHz to 500 MHz
// VCO range: 800 MHz to 1600 MHz
// M = 100, D = 1 sets Fvco = 1000 MHz
// Divide by 4 to get output frequency of 250 MHz
MMCME4_BASE #(
.BANDWIDTH("OPTIMIZED"),
.CLKOUT0_DIVIDE_F(4),
.CLKOUT0_DUTY_CYCLE(0.5),
.CLKOUT0_PHASE(0),
.CLKOUT1_DIVIDE(1),
.CLKOUT1_DUTY_CYCLE(0.5),
.CLKOUT1_PHASE(0),
.CLKOUT2_DIVIDE(1),
.CLKOUT2_DUTY_CYCLE(0.5),
.CLKOUT2_PHASE(0),
.CLKOUT3_DIVIDE(1),
.CLKOUT3_DUTY_CYCLE(0.5),
.CLKOUT3_PHASE(0),
.CLKOUT4_DIVIDE(1),
.CLKOUT4_DUTY_CYCLE(0.5),
.CLKOUT4_PHASE(0),
.CLKOUT5_DIVIDE(1),
.CLKOUT5_DUTY_CYCLE(0.5),
.CLKOUT5_PHASE(0),
.CLKOUT6_DIVIDE(1),
.CLKOUT6_DUTY_CYCLE(0.5),
.CLKOUT6_PHASE(0),
.CLKFBOUT_MULT_F(100),
.CLKFBOUT_PHASE(0),
.DIVCLK_DIVIDE(1),
.REF_JITTER1(0.010),
.CLKIN1_PERIOD(100.000),
.STARTUP_WAIT("FALSE"),
.CLKOUT4_CASCADE("FALSE")
)
clk_250mhz_mmcm_inst (
.CLKIN1(clk_10mhz_bufg),
.CLKFBIN(mmcm_250mhz_clkfb),
.RST(mmcm_250mhz_rst),
.PWRDWN(1'b0),
.CLKOUT0(clk_250mhz_mmcm_out),
.CLKOUT0B(),
.CLKOUT1(),
.CLKOUT1B(),
.CLKOUT2(),
.CLKOUT2B(),
.CLKOUT3(),
.CLKOUT3B(),
.CLKOUT4(),
.CLKOUT5(),
.CLKOUT6(),
.CLKFBOUT(mmcm_250mhz_clkfb),
.CLKFBOUTB(),
.LOCKED(mmcm_250mhz_locked)
);
BUFG
clk_250mhz_bufg_inst (
.I(clk_250mhz_mmcm_out),
.O(clk_250mhz_int)
);
sync_reset #(
.N(4)
)
sync_reset_250mhz_inst (
.clk(clk_250mhz_int),
.rst(~mmcm_250mhz_locked),
.out(rst_250mhz_int)
);
// GPIO
wire sfp_1_npres_int;
wire sfp_2_npres_int;
@ -1039,8 +1135,8 @@ wire ptp_clk;
wire ptp_rst;
wire ptp_sample_clk;
assign ptp_clk = sfp_mgt_refclk_bufg;
assign ptp_rst = sfp_rst;
assign ptp_clk = clk_250mhz_int;
assign ptp_rst = rst_250mhz_int;
assign ptp_sample_clk = clk_125mhz_int;
assign sfp_1_led[0] = sfp_1_rx_status;

View File

@ -301,7 +301,7 @@ class TB(object):
if hasattr(dut.core_inst.core_pcie_inst, 'pcie_app_ctrl'):
self.dev.functions[0].configure_bar(2, 2**len(dut.core_inst.core_pcie_inst.axil_app_ctrl_araddr), ext=True, prefetch=True)
cocotb.start_soon(Clock(dut.ptp_clk, 6.206, units="ns").start())
cocotb.start_soon(Clock(dut.ptp_clk, 4, units="ns").start())
dut.ptp_rst.setimmediatevalue(0)
cocotb.start_soon(Clock(dut.ptp_sample_clk, 8, units="ns").start())