diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/rtl/fpga.v b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/rtl/fpga.v index 9fd85fd19..ac8aaaf4b 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/rtl/fpga.v @@ -247,6 +247,7 @@ parameter PTP_FNS_WIDTH = 32; parameter PTP_PERIOD_NS = 4'd4; parameter PTP_PERIOD_FNS = 32'd0; parameter PTP_USE_SAMPLE_CLOCK = 0; +parameter PTP_SEPARATE_RX_CLOCK = 1; // PCIe interface configuration parameter MSI_COUNT = 32; @@ -935,6 +936,8 @@ wire qsfp_0_rx_axis_tvalid_int; wire qsfp_0_rx_axis_tlast_int; wire [80+1-1:0] qsfp_0_rx_axis_tuser_int; +wire qsfp_0_rx_ptp_clk_int; +wire qsfp_0_rx_ptp_rst_int; wire [79:0] qsfp_0_rx_ptp_time_int; wire qsfp_1_tx_clk_int; @@ -968,20 +971,44 @@ wire qsfp_1_rx_axis_tvalid_int; wire qsfp_1_rx_axis_tlast_int; wire [80+1-1:0] qsfp_1_rx_axis_tuser_int; +wire qsfp_1_rx_ptp_clk_int; +wire qsfp_1_rx_ptp_rst_int; wire [79:0] qsfp_1_rx_ptp_time_int; wire qsfp_0_rx_status; wire qsfp_1_rx_status; wire qsfp_0_txuserclk2; +wire qsfp_0_rxuserclk2; assign qsfp_0_tx_clk_int = qsfp_0_txuserclk2; assign qsfp_0_rx_clk_int = qsfp_0_txuserclk2; +assign qsfp_0_rx_ptp_clk_int = qsfp_0_rxuserclk2; wire qsfp_1_txuserclk2; +wire qsfp_1_rxuserclk2; assign qsfp_1_tx_clk_int = qsfp_1_txuserclk2; assign qsfp_1_rx_clk_int = qsfp_1_txuserclk2; +assign qsfp_1_rx_ptp_clk_int = qsfp_1_rxuserclk2; + +sync_reset #( + .N(4) +) +sync_reset_qsfp_0_rx_ptp_rst_inst ( + .clk(qsfp_0_rx_ptp_clk_int), + .rst(qsfp_0_tx_rst_int), + .out(qsfp_0_rx_ptp_rst_int) +); + +sync_reset #( + .N(4) +) +sync_reset_qsfp_1_rx_ptp_rst_inst ( + .clk(qsfp_1_rx_ptp_clk_int), + .rst(qsfp_1_tx_rst_int), + .out(qsfp_1_rx_ptp_rst_int) +); cmac_pad #( .DATA_WIDTH(AXIS_ETH_DATA_WIDTH), @@ -1046,7 +1073,7 @@ qsfp_0_cmac_inst ( .rx_otn_vlmarker(), // output .rx_preambleout(), // output [55:0] .usr_rx_reset(qsfp_0_rx_rst_int), // output - .gt_rxusrclk2(), // output + .gt_rxusrclk2(qsfp_0_rxuserclk2), // output .rx_lane_aligner_fill_0(), // output [6:0] .rx_lane_aligner_fill_1(), // output [6:0] @@ -1070,8 +1097,7 @@ qsfp_0_cmac_inst ( .rx_lane_aligner_fill_9(), // output [6:0] .rx_ptp_tstamp_out(qsfp_0_rx_axis_tuser_int[80:1]), // output [79:0] .rx_ptp_pcslane_out(), // output [4:0] - // RX fed from TX clock, so use same PTP time source - .ctl_rx_systemtimerin(qsfp_0_tx_ptp_time_int), // input [79:0] + .ctl_rx_systemtimerin(qsfp_0_rx_ptp_time_int), // input [79:0] .stat_rx_aligned(), // output .stat_rx_aligned_err(), // output @@ -1367,7 +1393,7 @@ qsfp_1_cmac_inst ( .rx_otn_vlmarker(), // output .rx_preambleout(), // output [55:0] .usr_rx_reset(qsfp_1_rx_rst_int), // output - .gt_rxusrclk2(), // output + .gt_rxusrclk2(qsfp_1_rxuserclk2), // output .rx_lane_aligner_fill_0(), // output [6:0] .rx_lane_aligner_fill_1(), // output [6:0] @@ -1391,8 +1417,7 @@ qsfp_1_cmac_inst ( .rx_lane_aligner_fill_9(), // output [6:0] .rx_ptp_tstamp_out(qsfp_1_rx_axis_tuser_int[80:1]), // output [79:0] .rx_ptp_pcslane_out(), // output [4:0] - // RX fed from TX clock, so use same PTP time source - .ctl_rx_systemtimerin(qsfp_1_tx_ptp_time_int), // input [79:0] + .ctl_rx_systemtimerin(qsfp_1_rx_ptp_time_int), // input [79:0] .stat_rx_aligned(), // output .stat_rx_aligned_err(), // output @@ -1649,6 +1674,7 @@ fpga_core #( .PTP_PERIOD_NS(PTP_PERIOD_NS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), @@ -1871,9 +1897,12 @@ core_inst ( .qsfp_0_rx_axis_tvalid(qsfp_0_rx_axis_tvalid_int), .qsfp_0_rx_axis_tlast(qsfp_0_rx_axis_tlast_int), .qsfp_0_rx_axis_tuser(qsfp_0_rx_axis_tuser_int), + .qsfp_0_rx_ptp_clk(qsfp_0_rx_ptp_clk_int), + .qsfp_0_rx_ptp_rst(qsfp_0_rx_ptp_rst_int), .qsfp_0_rx_ptp_time(qsfp_0_rx_ptp_time_int), .qsfp_0_modprs_l(qsfp_0_modprs_l_int), .qsfp_0_sel_l(qsfp_0_sel_l), + .qsfp_1_tx_clk(qsfp_1_tx_clk_int), .qsfp_1_tx_rst(qsfp_1_tx_rst_int), .qsfp_1_tx_axis_tdata(qsfp_1_tx_axis_tdata_int), @@ -1893,17 +1922,22 @@ core_inst ( .qsfp_1_rx_axis_tvalid(qsfp_1_rx_axis_tvalid_int), .qsfp_1_rx_axis_tlast(qsfp_1_rx_axis_tlast_int), .qsfp_1_rx_axis_tuser(qsfp_1_rx_axis_tuser_int), + .qsfp_1_rx_ptp_clk(qsfp_1_rx_ptp_clk_int), + .qsfp_1_rx_ptp_rst(qsfp_1_rx_ptp_rst_int), .qsfp_1_rx_ptp_time(qsfp_1_rx_ptp_time_int), .qsfp_1_modprs_l(qsfp_1_modprs_l_int), .qsfp_1_sel_l(qsfp_1_sel_l), + .qsfp_reset_l(qsfp_reset_l), .qsfp_int_l(qsfp_int_l_int), + .qsfp_i2c_scl_i(qsfp_i2c_scl_i), .qsfp_i2c_scl_o(qsfp_i2c_scl_o), .qsfp_i2c_scl_t(qsfp_i2c_scl_t), .qsfp_i2c_sda_i(qsfp_i2c_sda_i), .qsfp_i2c_sda_o(qsfp_i2c_sda_o), .qsfp_i2c_sda_t(qsfp_i2c_sda_t), + .eeprom_i2c_scl_i(eeprom_i2c_scl_i), .eeprom_i2c_scl_o(eeprom_i2c_scl_o), .eeprom_i2c_scl_t(eeprom_i2c_scl_t), diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/rtl/fpga_core.v index 36effc722..f69adee32 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/rtl/fpga_core.v @@ -62,6 +62,7 @@ module fpga_core # parameter PTP_PERIOD_NS = 4'd4, parameter PTP_PERIOD_FNS = 32'd0, parameter PTP_USE_SAMPLE_CLOCK = 0, + parameter PTP_SEPARATE_RX_CLOCK = 0, parameter PTP_PEROUT_ENABLE = 0, parameter PTP_PEROUT_COUNT = 1, @@ -289,6 +290,8 @@ module fpga_core # input wire qsfp_0_rx_axis_tlast, input wire [80+1-1:0] qsfp_0_rx_axis_tuser, + input wire qsfp_0_rx_ptp_clk, + input wire qsfp_0_rx_ptp_rst, output wire [79:0] qsfp_0_rx_ptp_time, input wire qsfp_0_modprs_l, @@ -309,6 +312,8 @@ module fpga_core # input wire [15:0] qsfp_1_tx_ptp_ts_tag, input wire qsfp_1_tx_ptp_ts_valid, + input wire qsfp_1_rx_ptp_clk, + input wire qsfp_1_rx_ptp_rst, input wire qsfp_1_rx_clk, input wire qsfp_1_rx_rst, @@ -650,6 +655,8 @@ wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; +wire [PORT_COUNT-1:0] eth_rx_ptp_clk; +wire [PORT_COUNT-1:0] eth_rx_ptp_rst; wire [PORT_COUNT*PTP_TS_WIDTH-1:0] eth_rx_ptp_ts_96; wire [PORT_COUNT-1:0] eth_rx_ptp_ts_step; @@ -696,6 +703,8 @@ generate assign axis_eth_rx_tlast[QSFP_0_IND] = qsfp_0_rx_axis_tlast; assign axis_eth_rx_tuser[QSFP_0_IND*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH] = {qsfp_0_rx_axis_tuser[80:1], 16'd0, qsfp_0_rx_axis_tuser[0]}; + assign eth_rx_ptp_clk[QSFP_0_IND] = qsfp_0_rx_ptp_clk; + assign eth_rx_ptp_rst[QSFP_0_IND] = qsfp_0_rx_ptp_rst; assign qsfp_0_tx_ptp_time = eth_tx_ptp_ts_96[QSFP_0_IND*PTP_TS_WIDTH+16 +: 80]; assign qsfp_0_rx_ptp_time = eth_rx_ptp_ts_96[QSFP_0_IND*PTP_TS_WIDTH+16 +: 80]; end else begin @@ -732,6 +741,8 @@ generate assign axis_eth_rx_tlast[QSFP_1_IND] = qsfp_1_rx_axis_tlast; assign axis_eth_rx_tuser[QSFP_1_IND*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH] = {qsfp_1_rx_axis_tuser[80:1], 16'd0, qsfp_1_rx_axis_tuser[0]}; + assign eth_rx_ptp_clk[QSFP_1_IND] = qsfp_1_rx_ptp_clk; + assign eth_rx_ptp_rst[QSFP_1_IND] = qsfp_1_rx_ptp_rst; assign qsfp_1_tx_ptp_time = eth_tx_ptp_ts_96[QSFP_1_IND*PTP_TS_WIDTH+16 +: 80]; assign qsfp_1_rx_ptp_time = eth_rx_ptp_ts_96[QSFP_1_IND*PTP_TS_WIDTH+16 +: 80]; end else begin @@ -768,6 +779,7 @@ mqnic_core_pcie_us #( .PTP_PERIOD_NS(PTP_PERIOD_NS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), @@ -1060,6 +1072,8 @@ core_inst ( .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), + .eth_rx_ptp_clk(eth_rx_ptp_clk), + .eth_rx_ptp_rst(eth_rx_ptp_rst), .eth_rx_ptp_ts_96(eth_rx_ptp_ts_96), .eth_rx_ptp_ts_step(eth_rx_ptp_ts_step), diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/Makefile index c34567745..0ec3ce1c2 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/Makefile @@ -123,6 +123,7 @@ export PARAM_PORTS_PER_IF ?= 1 # PTP configuration export PARAM_PTP_USE_SAMPLE_CLOCK ?= 0 +export PARAM_PTP_SEPARATE_RX_CLOCK ?= 0 export PARAM_PTP_PEROUT_ENABLE ?= 0 export PARAM_PTP_PEROUT_COUNT ?= 1 @@ -222,6 +223,7 @@ ifeq ($(SIM), icarus) COMPILE_ARGS += -P $(TOPLEVEL).IF_COUNT=$(PARAM_IF_COUNT) COMPILE_ARGS += -P $(TOPLEVEL).PORTS_PER_IF=$(PARAM_PORTS_PER_IF) COMPILE_ARGS += -P $(TOPLEVEL).PTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -P $(TOPLEVEL).PTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_CLOCK) COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE) COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT) COMPILE_ARGS += -P $(TOPLEVEL).EVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE) @@ -301,6 +303,7 @@ else ifeq ($(SIM), verilator) COMPILE_ARGS += -GIF_COUNT=$(PARAM_IF_COUNT) COMPILE_ARGS += -GPORTS_PER_IF=$(PARAM_PORTS_PER_IF) COMPILE_ARGS += -GPTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -GPTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_CLOCK) COMPILE_ARGS += -GPTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE) COMPILE_ARGS += -GPTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT) COMPILE_ARGS += -GEVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE) diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/test_fpga_core.py index e0c306907..ae40b20cb 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -604,6 +604,7 @@ def test_fpga_core(request): # PTP configuration parameters['PTP_USE_SAMPLE_CLOCK'] = 0 + parameters['PTP_SEPARATE_RX_CLOCK'] = 0 parameters['PTP_PEROUT_ENABLE'] = 0 parameters['PTP_PEROUT_COUNT'] = 1 diff --git a/fpga/mqnic/AU200/fpga_100g/rtl/fpga.v b/fpga/mqnic/AU200/fpga_100g/rtl/fpga.v index b7f009f47..6f5f8d386 100644 --- a/fpga/mqnic/AU200/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/AU200/fpga_100g/rtl/fpga.v @@ -249,6 +249,7 @@ parameter PTP_FNS_WIDTH = 32; parameter PTP_PERIOD_NS = 4'd4; parameter PTP_PERIOD_FNS = 32'd0; parameter PTP_USE_SAMPLE_CLOCK = 0; +parameter PTP_SEPARATE_RX_CLOCK = 1; // PCIe interface configuration parameter MSI_COUNT = 32; @@ -1063,6 +1064,8 @@ wire qsfp0_rx_axis_tvalid_int; wire qsfp0_rx_axis_tlast_int; wire [80+1-1:0] qsfp0_rx_axis_tuser_int; +wire qsfp0_rx_ptp_clk_int; +wire qsfp0_rx_ptp_rst_int; wire [79:0] qsfp0_rx_ptp_time_int; assign qsfp1_refclk_reset = qsfp_refclk_reset_reg; @@ -1099,20 +1102,44 @@ wire qsfp1_rx_axis_tvalid_int; wire qsfp1_rx_axis_tlast_int; wire [80+1-1:0] qsfp1_rx_axis_tuser_int; +wire qsfp1_rx_ptp_clk_int; +wire qsfp1_rx_ptp_rst_int; wire [79:0] qsfp1_rx_ptp_time_int; wire qsfp0_rx_status; wire qsfp1_rx_status; wire qsfp0_txuserclk2; +wire qsfp0_rxuserclk2; assign qsfp0_tx_clk_int = qsfp0_txuserclk2; assign qsfp0_rx_clk_int = qsfp0_txuserclk2; +assign qsfp0_rx_ptp_clk_int = qsfp0_rxuserclk2; wire qsfp1_txuserclk2; +wire qsfp1_rxuserclk2; assign qsfp1_tx_clk_int = qsfp1_txuserclk2; assign qsfp1_rx_clk_int = qsfp1_txuserclk2; +assign qsfp1_rx_ptp_clk_int = qsfp1_rxuserclk2; + +sync_reset #( + .N(4) +) +sync_reset_qsfp0_rx_ptp_rst_inst ( + .clk(qsfp0_rx_ptp_clk_int), + .rst(qsfp0_tx_rst_int), + .out(qsfp0_rx_ptp_rst_int) +); + +sync_reset #( + .N(4) +) +sync_reset_qsfp1_rx_ptp_rst_inst ( + .clk(qsfp1_rx_ptp_clk_int), + .rst(qsfp1_tx_rst_int), + .out(qsfp1_rx_ptp_rst_int) +); cmac_pad #( .DATA_WIDTH(AXIS_ETH_DATA_WIDTH), @@ -1177,7 +1204,7 @@ qsfp0_cmac_inst ( .rx_otn_vlmarker(), // output .rx_preambleout(), // output [55:0] .usr_rx_reset(qsfp0_rx_rst_int), // output - .gt_rxusrclk2(), // output + .gt_rxusrclk2(qsfp0_rxuserclk2), // output .rx_lane_aligner_fill_0(), // output [6:0] .rx_lane_aligner_fill_1(), // output [6:0] @@ -1201,8 +1228,7 @@ qsfp0_cmac_inst ( .rx_lane_aligner_fill_9(), // output [6:0] .rx_ptp_tstamp_out(qsfp0_rx_axis_tuser_int[80:1]), // output [79:0] .rx_ptp_pcslane_out(), // output [4:0] - // RX fed from TX clock, so use same PTP time source - .ctl_rx_systemtimerin(qsfp0_tx_ptp_time_int), // input [79:0] + .ctl_rx_systemtimerin(qsfp0_rx_ptp_time_int), // input [79:0] .stat_rx_aligned(), // output .stat_rx_aligned_err(), // output @@ -1498,7 +1524,7 @@ qsfp1_cmac_inst ( .rx_otn_vlmarker(), // output .rx_preambleout(), // output [55:0] .usr_rx_reset(qsfp1_rx_rst_int), // output - .gt_rxusrclk2(), // output + .gt_rxusrclk2(qsfp1_rxuserclk2), // output .rx_lane_aligner_fill_0(), // output [6:0] .rx_lane_aligner_fill_1(), // output [6:0] @@ -1522,8 +1548,7 @@ qsfp1_cmac_inst ( .rx_lane_aligner_fill_9(), // output [6:0] .rx_ptp_tstamp_out(qsfp1_rx_axis_tuser_int[80:1]), // output [79:0] .rx_ptp_pcslane_out(), // output [4:0] - // RX fed from TX clock, so use same PTP time source - .ctl_rx_systemtimerin(qsfp1_tx_ptp_time_int), // input [79:0] + .ctl_rx_systemtimerin(qsfp1_rx_ptp_time_int), // input [79:0] .stat_rx_aligned(), // output .stat_rx_aligned_err(), // output @@ -1783,6 +1808,7 @@ fpga_core #( .PTP_PERIOD_NS(PTP_PERIOD_NS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), @@ -2013,6 +2039,8 @@ core_inst ( .qsfp0_rx_axis_tvalid(qsfp0_rx_axis_tvalid_int), .qsfp0_rx_axis_tlast(qsfp0_rx_axis_tlast_int), .qsfp0_rx_axis_tuser(qsfp0_rx_axis_tuser_int), + .qsfp0_rx_ptp_clk(qsfp0_rx_ptp_clk_int), + .qsfp0_rx_ptp_rst(qsfp0_rx_ptp_rst_int), .qsfp0_rx_ptp_time(qsfp0_rx_ptp_time_int), .qsfp1_tx_clk(qsfp1_tx_clk_int), @@ -2034,6 +2062,8 @@ core_inst ( .qsfp1_rx_axis_tvalid(qsfp1_rx_axis_tvalid_int), .qsfp1_rx_axis_tlast(qsfp1_rx_axis_tlast_int), .qsfp1_rx_axis_tuser(qsfp1_rx_axis_tuser_int), + .qsfp1_rx_ptp_clk(qsfp1_rx_ptp_clk_int), + .qsfp1_rx_ptp_rst(qsfp1_rx_ptp_rst_int), .qsfp1_rx_ptp_time(qsfp1_rx_ptp_time_int), /* diff --git a/fpga/mqnic/AU200/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/AU200/fpga_100g/rtl/fpga_core.v index 8359904d8..cd0d2cc94 100644 --- a/fpga/mqnic/AU200/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/AU200/fpga_100g/rtl/fpga_core.v @@ -62,6 +62,7 @@ module fpga_core # parameter PTP_PERIOD_NS = 4'd4, parameter PTP_PERIOD_FNS = 32'd0, parameter PTP_USE_SAMPLE_CLOCK = 0, + parameter PTP_SEPARATE_RX_CLOCK = 0, parameter PTP_PEROUT_ENABLE = 0, parameter PTP_PEROUT_COUNT = 1, @@ -297,6 +298,8 @@ module fpga_core # input wire qsfp0_rx_axis_tlast, input wire [80+1-1:0] qsfp0_rx_axis_tuser, + input wire qsfp0_rx_ptp_clk, + input wire qsfp0_rx_ptp_rst, output wire [79:0] qsfp0_rx_ptp_time, output wire qsfp0_modsell, @@ -329,6 +332,8 @@ module fpga_core # input wire qsfp1_rx_axis_tlast, input wire [80+1-1:0] qsfp1_rx_axis_tuser, + input wire qsfp1_rx_ptp_clk, + input wire qsfp1_rx_ptp_rst, output wire [79:0] qsfp1_rx_ptp_time, output wire qsfp1_modsell, @@ -658,6 +663,8 @@ wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; +wire [PORT_COUNT-1:0] eth_rx_ptp_clk; +wire [PORT_COUNT-1:0] eth_rx_ptp_rst; wire [PORT_COUNT*PTP_TS_WIDTH-1:0] eth_rx_ptp_ts_96; wire [PORT_COUNT-1:0] eth_rx_ptp_ts_step; @@ -704,6 +711,8 @@ generate assign axis_eth_rx_tlast[QSFP0_IND] = qsfp0_rx_axis_tlast; assign axis_eth_rx_tuser[QSFP0_IND*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH] = {qsfp0_rx_axis_tuser[80:1], 16'd0, qsfp0_rx_axis_tuser[0]}; + assign eth_rx_ptp_clk[QSFP0_IND] = qsfp0_rx_ptp_clk; + assign eth_rx_ptp_rst[QSFP0_IND] = qsfp0_rx_ptp_rst; assign qsfp0_tx_ptp_time = eth_tx_ptp_ts_96[QSFP0_IND*PTP_TS_WIDTH+16 +: 80]; assign qsfp0_rx_ptp_time = eth_rx_ptp_ts_96[QSFP0_IND*PTP_TS_WIDTH+16 +: 80]; end else begin @@ -740,6 +749,8 @@ generate assign axis_eth_rx_tlast[QSFP1_IND] = qsfp1_rx_axis_tlast; assign axis_eth_rx_tuser[QSFP1_IND*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH] = {qsfp1_rx_axis_tuser[80:1], 16'd0, qsfp1_rx_axis_tuser[0]}; + assign eth_rx_ptp_clk[QSFP1_IND] = qsfp1_rx_ptp_clk; + assign eth_rx_ptp_rst[QSFP1_IND] = qsfp1_rx_ptp_rst; assign qsfp1_tx_ptp_time = eth_tx_ptp_ts_96[QSFP1_IND*PTP_TS_WIDTH+16 +: 80]; assign qsfp1_rx_ptp_time = eth_rx_ptp_ts_96[QSFP1_IND*PTP_TS_WIDTH+16 +: 80]; end else begin @@ -776,6 +787,7 @@ mqnic_core_pcie_us #( .PTP_PERIOD_NS(PTP_PERIOD_NS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), @@ -1068,6 +1080,8 @@ core_inst ( .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), + .eth_rx_ptp_clk(eth_rx_ptp_clk), + .eth_rx_ptp_rst(eth_rx_ptp_rst), .eth_rx_ptp_ts_96(eth_rx_ptp_ts_96), .eth_rx_ptp_ts_step(eth_rx_ptp_ts_step), diff --git a/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/Makefile index 5edd4f293..d418b9605 100644 --- a/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/Makefile @@ -123,6 +123,7 @@ export PARAM_PORTS_PER_IF ?= 1 # PTP configuration export PARAM_PTP_USE_SAMPLE_CLOCK ?= 0 +export PARAM_PTP_SEPARATE_RX_CLOCK ?= 0 export PARAM_PTP_PEROUT_ENABLE ?= 0 export PARAM_PTP_PEROUT_COUNT ?= 1 @@ -222,6 +223,7 @@ ifeq ($(SIM), icarus) COMPILE_ARGS += -P $(TOPLEVEL).IF_COUNT=$(PARAM_IF_COUNT) COMPILE_ARGS += -P $(TOPLEVEL).PORTS_PER_IF=$(PARAM_PORTS_PER_IF) COMPILE_ARGS += -P $(TOPLEVEL).PTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -P $(TOPLEVEL).PTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_CLOCK) COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE) COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT) COMPILE_ARGS += -P $(TOPLEVEL).EVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE) @@ -301,6 +303,7 @@ else ifeq ($(SIM), verilator) COMPILE_ARGS += -GIF_COUNT=$(PARAM_IF_COUNT) COMPILE_ARGS += -GPORTS_PER_IF=$(PARAM_PORTS_PER_IF) COMPILE_ARGS += -GPTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -GPTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_CLOCK) COMPILE_ARGS += -GPTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE) COMPILE_ARGS += -GPTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT) COMPILE_ARGS += -GEVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE) diff --git a/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/test_fpga_core.py index bdc2524f8..1427cf113 100644 --- a/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -604,6 +604,7 @@ def test_fpga_core(request): # PTP configuration parameters['PTP_USE_SAMPLE_CLOCK'] = 0 + parameters['PTP_SEPARATE_RX_CLOCK'] = 0 parameters['PTP_PEROUT_ENABLE'] = 0 parameters['PTP_PEROUT_COUNT'] = 1 diff --git a/fpga/mqnic/AU250/fpga_100g/rtl/fpga.v b/fpga/mqnic/AU250/fpga_100g/rtl/fpga.v index 5dc27ecd1..8e60b3168 100644 --- a/fpga/mqnic/AU250/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/AU250/fpga_100g/rtl/fpga.v @@ -249,6 +249,7 @@ parameter PTP_FNS_WIDTH = 32; parameter PTP_PERIOD_NS = 4'd4; parameter PTP_PERIOD_FNS = 32'd0; parameter PTP_USE_SAMPLE_CLOCK = 0; +parameter PTP_SEPARATE_RX_CLOCK = 1; // PCIe interface configuration parameter MSI_COUNT = 32; @@ -1063,6 +1064,8 @@ wire qsfp0_rx_axis_tvalid_int; wire qsfp0_rx_axis_tlast_int; wire [80+1-1:0] qsfp0_rx_axis_tuser_int; +wire qsfp0_rx_ptp_clk_int; +wire qsfp0_rx_ptp_rst_int; wire [79:0] qsfp0_rx_ptp_time_int; assign qsfp1_refclk_reset = qsfp_refclk_reset_reg; @@ -1099,20 +1102,44 @@ wire qsfp1_rx_axis_tvalid_int; wire qsfp1_rx_axis_tlast_int; wire [80+1-1:0] qsfp1_rx_axis_tuser_int; +wire qsfp1_rx_ptp_clk_int; +wire qsfp1_rx_ptp_rst_int; wire [79:0] qsfp1_rx_ptp_time_int; wire qsfp0_rx_status; wire qsfp1_rx_status; wire qsfp0_txuserclk2; +wire qsfp0_rxuserclk2; assign qsfp0_tx_clk_int = qsfp0_txuserclk2; assign qsfp0_rx_clk_int = qsfp0_txuserclk2; +assign qsfp0_rx_ptp_clk_int = qsfp0_rxuserclk2; wire qsfp1_txuserclk2; +wire qsfp1_rxuserclk2; assign qsfp1_tx_clk_int = qsfp1_txuserclk2; assign qsfp1_rx_clk_int = qsfp1_txuserclk2; +assign qsfp1_rx_ptp_clk_int = qsfp1_rxuserclk2; + +sync_reset #( + .N(4) +) +sync_reset_qsfp0_rx_ptp_rst_inst ( + .clk(qsfp0_rx_ptp_clk_int), + .rst(qsfp0_tx_rst_int), + .out(qsfp0_rx_ptp_rst_int) +); + +sync_reset #( + .N(4) +) +sync_reset_qsfp1_rx_ptp_rst_inst ( + .clk(qsfp1_rx_ptp_clk_int), + .rst(qsfp1_tx_rst_int), + .out(qsfp1_rx_ptp_rst_int) +); cmac_pad #( .DATA_WIDTH(AXIS_ETH_DATA_WIDTH), @@ -1177,7 +1204,7 @@ qsfp0_cmac_inst ( .rx_otn_vlmarker(), // output .rx_preambleout(), // output [55:0] .usr_rx_reset(qsfp0_rx_rst_int), // output - .gt_rxusrclk2(), // output + .gt_rxusrclk2(qsfp0_rxuserclk2), // output .rx_lane_aligner_fill_0(), // output [6:0] .rx_lane_aligner_fill_1(), // output [6:0] @@ -1201,8 +1228,7 @@ qsfp0_cmac_inst ( .rx_lane_aligner_fill_9(), // output [6:0] .rx_ptp_tstamp_out(qsfp0_rx_axis_tuser_int[80:1]), // output [79:0] .rx_ptp_pcslane_out(), // output [4:0] - // RX fed from TX clock, so use same PTP time source - .ctl_rx_systemtimerin(qsfp0_tx_ptp_time_int), // input [79:0] + .ctl_rx_systemtimerin(qsfp0_rx_ptp_time_int), // input [79:0] .stat_rx_aligned(), // output .stat_rx_aligned_err(), // output @@ -1498,7 +1524,7 @@ qsfp1_cmac_inst ( .rx_otn_vlmarker(), // output .rx_preambleout(), // output [55:0] .usr_rx_reset(qsfp1_rx_rst_int), // output - .gt_rxusrclk2(), // output + .gt_rxusrclk2(qsfp1_rxuserclk2), // output .rx_lane_aligner_fill_0(), // output [6:0] .rx_lane_aligner_fill_1(), // output [6:0] @@ -1522,8 +1548,7 @@ qsfp1_cmac_inst ( .rx_lane_aligner_fill_9(), // output [6:0] .rx_ptp_tstamp_out(qsfp1_rx_axis_tuser_int[80:1]), // output [79:0] .rx_ptp_pcslane_out(), // output [4:0] - // RX fed from TX clock, so use same PTP time source - .ctl_rx_systemtimerin(qsfp1_tx_ptp_time_int), // input [79:0] + .ctl_rx_systemtimerin(qsfp1_rx_ptp_time_int), // input [79:0] .stat_rx_aligned(), // output .stat_rx_aligned_err(), // output @@ -1783,6 +1808,7 @@ fpga_core #( .PTP_PERIOD_NS(PTP_PERIOD_NS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), @@ -2013,6 +2039,8 @@ core_inst ( .qsfp0_rx_axis_tvalid(qsfp0_rx_axis_tvalid_int), .qsfp0_rx_axis_tlast(qsfp0_rx_axis_tlast_int), .qsfp0_rx_axis_tuser(qsfp0_rx_axis_tuser_int), + .qsfp0_rx_ptp_clk(qsfp0_rx_ptp_clk_int), + .qsfp0_rx_ptp_rst(qsfp0_rx_ptp_rst_int), .qsfp0_rx_ptp_time(qsfp0_rx_ptp_time_int), .qsfp1_tx_clk(qsfp1_tx_clk_int), @@ -2034,6 +2062,8 @@ core_inst ( .qsfp1_rx_axis_tvalid(qsfp1_rx_axis_tvalid_int), .qsfp1_rx_axis_tlast(qsfp1_rx_axis_tlast_int), .qsfp1_rx_axis_tuser(qsfp1_rx_axis_tuser_int), + .qsfp1_rx_ptp_clk(qsfp1_rx_ptp_clk_int), + .qsfp1_rx_ptp_rst(qsfp1_rx_ptp_rst_int), .qsfp1_rx_ptp_time(qsfp1_rx_ptp_time_int), /* diff --git a/fpga/mqnic/AU250/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/AU250/fpga_100g/rtl/fpga_core.v index 1ebfcb0cb..7b10116c0 100644 --- a/fpga/mqnic/AU250/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/AU250/fpga_100g/rtl/fpga_core.v @@ -62,6 +62,7 @@ module fpga_core # parameter PTP_PERIOD_NS = 4'd4, parameter PTP_PERIOD_FNS = 32'd0, parameter PTP_USE_SAMPLE_CLOCK = 0, + parameter PTP_SEPARATE_RX_CLOCK = 0, parameter PTP_PEROUT_ENABLE = 0, parameter PTP_PEROUT_COUNT = 1, @@ -297,6 +298,8 @@ module fpga_core # input wire qsfp0_rx_axis_tlast, input wire [80+1-1:0] qsfp0_rx_axis_tuser, + input wire qsfp0_rx_ptp_clk, + input wire qsfp0_rx_ptp_rst, output wire [79:0] qsfp0_rx_ptp_time, output wire qsfp0_modsell, @@ -329,6 +332,8 @@ module fpga_core # input wire qsfp1_rx_axis_tlast, input wire [80+1-1:0] qsfp1_rx_axis_tuser, + input wire qsfp1_rx_ptp_clk, + input wire qsfp1_rx_ptp_rst, output wire [79:0] qsfp1_rx_ptp_time, output wire qsfp1_modsell, @@ -658,6 +663,8 @@ wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; +wire [PORT_COUNT-1:0] eth_rx_ptp_clk; +wire [PORT_COUNT-1:0] eth_rx_ptp_rst; wire [PORT_COUNT*PTP_TS_WIDTH-1:0] eth_rx_ptp_ts_96; wire [PORT_COUNT-1:0] eth_rx_ptp_ts_step; @@ -704,6 +711,8 @@ generate assign axis_eth_rx_tlast[QSFP0_IND] = qsfp0_rx_axis_tlast; assign axis_eth_rx_tuser[QSFP0_IND*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH] = {qsfp0_rx_axis_tuser[80:1], 16'd0, qsfp0_rx_axis_tuser[0]}; + assign eth_rx_ptp_clk[QSFP0_IND] = qsfp0_rx_ptp_clk; + assign eth_rx_ptp_rst[QSFP0_IND] = qsfp0_rx_ptp_rst; assign qsfp0_tx_ptp_time = eth_tx_ptp_ts_96[QSFP0_IND*PTP_TS_WIDTH+16 +: 80]; assign qsfp0_rx_ptp_time = eth_rx_ptp_ts_96[QSFP0_IND*PTP_TS_WIDTH+16 +: 80]; end else begin @@ -740,6 +749,8 @@ generate assign axis_eth_rx_tlast[QSFP1_IND] = qsfp1_rx_axis_tlast; assign axis_eth_rx_tuser[QSFP1_IND*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH] = {qsfp1_rx_axis_tuser[80:1], 16'd0, qsfp1_rx_axis_tuser[0]}; + assign eth_rx_ptp_clk[QSFP1_IND] = qsfp1_rx_ptp_clk; + assign eth_rx_ptp_rst[QSFP1_IND] = qsfp1_rx_ptp_rst; assign qsfp1_tx_ptp_time = eth_tx_ptp_ts_96[QSFP1_IND*PTP_TS_WIDTH+16 +: 80]; assign qsfp1_rx_ptp_time = eth_rx_ptp_ts_96[QSFP1_IND*PTP_TS_WIDTH+16 +: 80]; end else begin @@ -776,6 +787,7 @@ mqnic_core_pcie_us #( .PTP_PERIOD_NS(PTP_PERIOD_NS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), @@ -1068,6 +1080,8 @@ core_inst ( .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), + .eth_rx_ptp_clk(eth_rx_ptp_clk), + .eth_rx_ptp_rst(eth_rx_ptp_rst), .eth_rx_ptp_ts_96(eth_rx_ptp_ts_96), .eth_rx_ptp_ts_step(eth_rx_ptp_ts_step), diff --git a/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/Makefile index 5edd4f293..d418b9605 100644 --- a/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/Makefile @@ -123,6 +123,7 @@ export PARAM_PORTS_PER_IF ?= 1 # PTP configuration export PARAM_PTP_USE_SAMPLE_CLOCK ?= 0 +export PARAM_PTP_SEPARATE_RX_CLOCK ?= 0 export PARAM_PTP_PEROUT_ENABLE ?= 0 export PARAM_PTP_PEROUT_COUNT ?= 1 @@ -222,6 +223,7 @@ ifeq ($(SIM), icarus) COMPILE_ARGS += -P $(TOPLEVEL).IF_COUNT=$(PARAM_IF_COUNT) COMPILE_ARGS += -P $(TOPLEVEL).PORTS_PER_IF=$(PARAM_PORTS_PER_IF) COMPILE_ARGS += -P $(TOPLEVEL).PTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -P $(TOPLEVEL).PTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_CLOCK) COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE) COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT) COMPILE_ARGS += -P $(TOPLEVEL).EVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE) @@ -301,6 +303,7 @@ else ifeq ($(SIM), verilator) COMPILE_ARGS += -GIF_COUNT=$(PARAM_IF_COUNT) COMPILE_ARGS += -GPORTS_PER_IF=$(PARAM_PORTS_PER_IF) COMPILE_ARGS += -GPTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -GPTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_CLOCK) COMPILE_ARGS += -GPTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE) COMPILE_ARGS += -GPTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT) COMPILE_ARGS += -GEVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE) diff --git a/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/test_fpga_core.py index bdc2524f8..1427cf113 100644 --- a/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -604,6 +604,7 @@ def test_fpga_core(request): # PTP configuration parameters['PTP_USE_SAMPLE_CLOCK'] = 0 + parameters['PTP_SEPARATE_RX_CLOCK'] = 0 parameters['PTP_PEROUT_ENABLE'] = 0 parameters['PTP_PEROUT_COUNT'] = 1 diff --git a/fpga/mqnic/AU280/fpga_100g/rtl/fpga.v b/fpga/mqnic/AU280/fpga_100g/rtl/fpga.v index ea8eb7e86..8f57843a0 100644 --- a/fpga/mqnic/AU280/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/AU280/fpga_100g/rtl/fpga.v @@ -232,6 +232,7 @@ parameter PTP_FNS_WIDTH = 32; parameter PTP_PERIOD_NS = 4'd4; parameter PTP_PERIOD_FNS = 32'd0; parameter PTP_USE_SAMPLE_CLOCK = 0; +parameter PTP_SEPARATE_RX_CLOCK = 1; // PCIe interface configuration parameter MSI_COUNT = 32; @@ -966,6 +967,8 @@ wire qsfp0_rx_axis_tvalid_int; wire qsfp0_rx_axis_tlast_int; wire [80+1-1:0] qsfp0_rx_axis_tuser_int; +wire qsfp0_rx_ptp_clk_int; +wire qsfp0_rx_ptp_rst_int; wire [79:0] qsfp0_rx_ptp_time_int; assign qsfp1_refclk_oe_b = 1'b0; @@ -1002,20 +1005,44 @@ wire qsfp1_rx_axis_tvalid_int; wire qsfp1_rx_axis_tlast_int; wire [80+1-1:0] qsfp1_rx_axis_tuser_int; +wire qsfp1_rx_ptp_clk_int; +wire qsfp1_rx_ptp_rst_int; wire [79:0] qsfp1_rx_ptp_time_int; wire qsfp0_rx_status; wire qsfp1_rx_status; wire qsfp0_txuserclk2; +wire qsfp0_rxuserclk2; assign qsfp0_tx_clk_int = qsfp0_txuserclk2; assign qsfp0_rx_clk_int = qsfp0_txuserclk2; +assign qsfp0_rx_ptp_clk_int = qsfp0_rxuserclk2; wire qsfp1_txuserclk2; +wire qsfp1_rxuserclk2; assign qsfp1_tx_clk_int = qsfp1_txuserclk2; assign qsfp1_rx_clk_int = qsfp1_txuserclk2; +assign qsfp1_rx_ptp_clk_int = qsfp1_rxuserclk2; + +sync_reset #( + .N(4) +) +sync_reset_qsfp0_rx_ptp_rst_inst ( + .clk(qsfp0_rx_ptp_clk_int), + .rst(qsfp0_tx_rst_int), + .out(qsfp0_rx_ptp_rst_int) +); + +sync_reset #( + .N(4) +) +sync_reset_qsfp1_rx_ptp_rst_inst ( + .clk(qsfp1_rx_ptp_clk_int), + .rst(qsfp1_tx_rst_int), + .out(qsfp1_rx_ptp_rst_int) +); cmac_pad #( .DATA_WIDTH(AXIS_ETH_DATA_WIDTH), @@ -1080,7 +1107,7 @@ qsfp0_cmac_inst ( .rx_otn_vlmarker(), // output .rx_preambleout(), // output [55:0] .usr_rx_reset(qsfp0_rx_rst_int), // output - .gt_rxusrclk2(), // output + .gt_rxusrclk2(qsfp0_rxuserclk2), // output .rx_lane_aligner_fill_0(), // output [6:0] .rx_lane_aligner_fill_1(), // output [6:0] @@ -1104,8 +1131,7 @@ qsfp0_cmac_inst ( .rx_lane_aligner_fill_9(), // output [6:0] .rx_ptp_tstamp_out(qsfp0_rx_axis_tuser_int[80:1]), // output [79:0] .rx_ptp_pcslane_out(), // output [4:0] - // RX fed from TX clock, so use same PTP time source - .ctl_rx_systemtimerin(qsfp0_tx_ptp_time_int), // input [79:0] + .ctl_rx_systemtimerin(qsfp0_rx_ptp_time_int), // input [79:0] .stat_rx_aligned(), // output .stat_rx_aligned_err(), // output @@ -1401,7 +1427,7 @@ qsfp1_cmac_inst ( .rx_otn_vlmarker(), // output .rx_preambleout(), // output [55:0] .usr_rx_reset(qsfp1_rx_rst_int), // output - .gt_rxusrclk2(), // output + .gt_rxusrclk2(qsfp1_rxuserclk2), // output .rx_lane_aligner_fill_0(), // output [6:0] .rx_lane_aligner_fill_1(), // output [6:0] @@ -1425,8 +1451,7 @@ qsfp1_cmac_inst ( .rx_lane_aligner_fill_9(), // output [6:0] .rx_ptp_tstamp_out(qsfp1_rx_axis_tuser_int[80:1]), // output [79:0] .rx_ptp_pcslane_out(), // output [4:0] - // RX fed from TX clock, so use same PTP time source - .ctl_rx_systemtimerin(qsfp1_tx_ptp_time_int), // input [79:0] + .ctl_rx_systemtimerin(qsfp1_rx_ptp_time_int), // input [79:0] .stat_rx_aligned(), // output .stat_rx_aligned_err(), // output @@ -1680,6 +1705,7 @@ fpga_core #( .PTP_PERIOD_NS(PTP_PERIOD_NS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), @@ -1894,6 +1920,8 @@ core_inst ( .qsfp0_rx_axis_tvalid(qsfp0_rx_axis_tvalid_int), .qsfp0_rx_axis_tlast(qsfp0_rx_axis_tlast_int), .qsfp0_rx_axis_tuser(qsfp0_rx_axis_tuser_int), + .qsfp0_rx_ptp_clk(qsfp0_rx_ptp_clk_int), + .qsfp0_rx_ptp_rst(qsfp0_rx_ptp_rst_int), .qsfp0_rx_ptp_time(qsfp0_rx_ptp_time_int), .qsfp1_tx_clk(qsfp1_tx_clk_int), @@ -1915,6 +1943,8 @@ core_inst ( .qsfp1_rx_axis_tvalid(qsfp1_rx_axis_tvalid_int), .qsfp1_rx_axis_tlast(qsfp1_rx_axis_tlast_int), .qsfp1_rx_axis_tuser(qsfp1_rx_axis_tuser_int), + .qsfp1_rx_ptp_clk(qsfp1_rx_ptp_clk_int), + .qsfp1_rx_ptp_rst(qsfp1_rx_ptp_rst_int), .qsfp1_rx_ptp_time(qsfp1_rx_ptp_time_int), /* diff --git a/fpga/mqnic/AU280/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/AU280/fpga_100g/rtl/fpga_core.v index a43a384c9..7f759b46e 100644 --- a/fpga/mqnic/AU280/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/AU280/fpga_100g/rtl/fpga_core.v @@ -62,6 +62,7 @@ module fpga_core # parameter PTP_PERIOD_NS = 4'd4, parameter PTP_PERIOD_FNS = 32'd0, parameter PTP_USE_SAMPLE_CLOCK = 0, + parameter PTP_SEPARATE_RX_CLOCK = 0, parameter PTP_PEROUT_ENABLE = 0, parameter PTP_PEROUT_COUNT = 1, @@ -281,6 +282,8 @@ module fpga_core # input wire qsfp0_rx_axis_tlast, input wire [80+1-1:0] qsfp0_rx_axis_tuser, + input wire qsfp0_rx_ptp_clk, + input wire qsfp0_rx_ptp_rst, output wire [79:0] qsfp0_rx_ptp_time, input wire qsfp1_tx_clk, @@ -298,6 +301,8 @@ module fpga_core # input wire [15:0] qsfp1_tx_ptp_ts_tag, input wire qsfp1_tx_ptp_ts_valid, + input wire qsfp1_rx_ptp_clk, + input wire qsfp1_rx_ptp_rst, input wire qsfp1_rx_clk, input wire qsfp1_rx_rst, @@ -542,6 +547,8 @@ wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; +wire [PORT_COUNT-1:0] eth_rx_ptp_clk; +wire [PORT_COUNT-1:0] eth_rx_ptp_rst; wire [PORT_COUNT*PTP_TS_WIDTH-1:0] eth_rx_ptp_ts_96; wire [PORT_COUNT-1:0] eth_rx_ptp_ts_step; @@ -588,6 +595,8 @@ generate assign axis_eth_rx_tlast[QSFP0_IND] = qsfp0_rx_axis_tlast; assign axis_eth_rx_tuser[QSFP0_IND*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH] = {qsfp0_rx_axis_tuser[80:1], 16'd0, qsfp0_rx_axis_tuser[0]}; + assign eth_rx_ptp_clk[QSFP0_IND] = qsfp0_rx_ptp_clk; + assign eth_rx_ptp_rst[QSFP0_IND] = qsfp0_rx_ptp_rst; assign qsfp0_tx_ptp_time = eth_tx_ptp_ts_96[QSFP0_IND*PTP_TS_WIDTH+16 +: 80]; assign qsfp0_rx_ptp_time = eth_rx_ptp_ts_96[QSFP0_IND*PTP_TS_WIDTH+16 +: 80]; end else begin @@ -624,6 +633,8 @@ generate assign axis_eth_rx_tlast[QSFP1_IND] = qsfp1_rx_axis_tlast; assign axis_eth_rx_tuser[QSFP1_IND*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH] = {qsfp1_rx_axis_tuser[80:1], 16'd0, qsfp1_rx_axis_tuser[0]}; + assign eth_rx_ptp_clk[QSFP1_IND] = qsfp1_rx_ptp_clk; + assign eth_rx_ptp_rst[QSFP1_IND] = qsfp1_rx_ptp_rst; assign qsfp1_tx_ptp_time = eth_tx_ptp_ts_96[QSFP1_IND*PTP_TS_WIDTH+16 +: 80]; assign qsfp1_rx_ptp_time = eth_rx_ptp_ts_96[QSFP1_IND*PTP_TS_WIDTH+16 +: 80]; end else begin @@ -660,6 +671,7 @@ mqnic_core_pcie_us #( .PTP_PERIOD_NS(PTP_PERIOD_NS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), @@ -952,6 +964,8 @@ core_inst ( .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), + .eth_rx_ptp_clk(eth_rx_ptp_clk), + .eth_rx_ptp_rst(eth_rx_ptp_rst), .eth_rx_ptp_ts_96(eth_rx_ptp_ts_96), .eth_rx_ptp_ts_step(eth_rx_ptp_ts_step), diff --git a/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/Makefile index 5edd4f293..d418b9605 100644 --- a/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/Makefile @@ -123,6 +123,7 @@ export PARAM_PORTS_PER_IF ?= 1 # PTP configuration export PARAM_PTP_USE_SAMPLE_CLOCK ?= 0 +export PARAM_PTP_SEPARATE_RX_CLOCK ?= 0 export PARAM_PTP_PEROUT_ENABLE ?= 0 export PARAM_PTP_PEROUT_COUNT ?= 1 @@ -222,6 +223,7 @@ ifeq ($(SIM), icarus) COMPILE_ARGS += -P $(TOPLEVEL).IF_COUNT=$(PARAM_IF_COUNT) COMPILE_ARGS += -P $(TOPLEVEL).PORTS_PER_IF=$(PARAM_PORTS_PER_IF) COMPILE_ARGS += -P $(TOPLEVEL).PTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -P $(TOPLEVEL).PTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_CLOCK) COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE) COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT) COMPILE_ARGS += -P $(TOPLEVEL).EVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE) @@ -301,6 +303,7 @@ else ifeq ($(SIM), verilator) COMPILE_ARGS += -GIF_COUNT=$(PARAM_IF_COUNT) COMPILE_ARGS += -GPORTS_PER_IF=$(PARAM_PORTS_PER_IF) COMPILE_ARGS += -GPTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -GPTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_CLOCK) COMPILE_ARGS += -GPTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE) COMPILE_ARGS += -GPTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT) COMPILE_ARGS += -GEVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE) diff --git a/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/test_fpga_core.py index fdfa9a24d..b18020795 100644 --- a/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -593,6 +593,7 @@ def test_fpga_core(request): # PTP configuration parameters['PTP_USE_SAMPLE_CLOCK'] = 0 + parameters['PTP_SEPARATE_RX_CLOCK'] = 0 parameters['PTP_PEROUT_ENABLE'] = 0 parameters['PTP_PEROUT_COUNT'] = 1 diff --git a/fpga/mqnic/AU50/fpga_100g/rtl/fpga.v b/fpga/mqnic/AU50/fpga_100g/rtl/fpga.v index 0a1141b8d..5fd77adcc 100644 --- a/fpga/mqnic/AU50/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/AU50/fpga_100g/rtl/fpga.v @@ -210,6 +210,7 @@ parameter PTP_FNS_WIDTH = 32; parameter PTP_PERIOD_NS = 4'd4; parameter PTP_PERIOD_FNS = 32'd0; parameter PTP_USE_SAMPLE_CLOCK = 0; +parameter PTP_SEPARATE_RX_CLOCK = 1; // PCIe interface configuration parameter MSI_COUNT = 32; @@ -941,14 +942,27 @@ wire qsfp_rx_axis_tvalid_int; wire qsfp_rx_axis_tlast_int; wire [80+1-1:0] qsfp_rx_axis_tuser_int; +wire qsfp_rx_ptp_clk_int; +wire qsfp_rx_ptp_rst_int; wire [79:0] qsfp_rx_ptp_time_int; wire qsfp_rx_status; wire qsfp_txuserclk2; +wire qsfp_rxuserclk2; assign qsfp_tx_clk_int = qsfp_txuserclk2; assign qsfp_rx_clk_int = qsfp_txuserclk2; +assign qsfp_rx_ptp_clk_int = qsfp_rxuserclk2; + +sync_reset #( + .N(4) +) +sync_reset_qsfp_rx_ptp_rst_inst ( + .clk(qsfp_rx_ptp_clk_int), + .rst(qsfp_tx_rst_int), + .out(qsfp_rx_ptp_rst_int) +); cmac_pad #( .DATA_WIDTH(AXIS_ETH_DATA_WIDTH), @@ -1013,7 +1027,7 @@ qsfp_cmac_inst ( .rx_otn_vlmarker(), // output .rx_preambleout(), // output [55:0] .usr_rx_reset(qsfp_rx_rst_int), // output - .gt_rxusrclk2(), // output + .gt_rxusrclk2(qsfp_rxuserclk2), // output .rx_lane_aligner_fill_0(), // output [6:0] .rx_lane_aligner_fill_1(), // output [6:0] @@ -1037,8 +1051,7 @@ qsfp_cmac_inst ( .rx_lane_aligner_fill_9(), // output [6:0] .rx_ptp_tstamp_out(qsfp_rx_axis_tuser_int[80:1]), // output [79:0] .rx_ptp_pcslane_out(), // output [4:0] - // RX fed from TX clock, so use same PTP time source - .ctl_rx_systemtimerin(qsfp_tx_ptp_time_int), // input [79:0] + .ctl_rx_systemtimerin(qsfp_rx_ptp_time_int), // input [79:0] .stat_rx_aligned(), // output .stat_rx_aligned_err(), // output @@ -1294,6 +1307,7 @@ fpga_core #( .PTP_PERIOD_NS(PTP_PERIOD_NS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), @@ -1515,6 +1529,8 @@ core_inst ( .qsfp_rx_axis_tvalid(qsfp_rx_axis_tvalid_int), .qsfp_rx_axis_tlast(qsfp_rx_axis_tlast_int), .qsfp_rx_axis_tuser(qsfp_rx_axis_tuser_int), + .qsfp_rx_ptp_clk(qsfp_rx_ptp_clk_int), + .qsfp_rx_ptp_rst(qsfp_rx_ptp_rst_int), .qsfp_rx_ptp_time(qsfp_rx_ptp_time_int), /* diff --git a/fpga/mqnic/AU50/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/AU50/fpga_100g/rtl/fpga_core.v index 768ad6f26..88689df8c 100644 --- a/fpga/mqnic/AU50/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/AU50/fpga_100g/rtl/fpga_core.v @@ -62,6 +62,7 @@ module fpga_core # parameter PTP_PERIOD_NS = 4'd4, parameter PTP_PERIOD_FNS = 32'd0, parameter PTP_USE_SAMPLE_CLOCK = 0, + parameter PTP_SEPARATE_RX_CLOCK = 0, parameter PTP_PEROUT_ENABLE = 0, parameter PTP_PEROUT_COUNT = 1, @@ -288,6 +289,8 @@ module fpga_core # input wire qsfp_rx_axis_tlast, input wire [80+1-1:0] qsfp_rx_axis_tuser, + input wire qsfp_rx_ptp_clk, + input wire qsfp_rx_ptp_rst, output wire [79:0] qsfp_rx_ptp_time, /* @@ -540,6 +543,8 @@ wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; +wire [PORT_COUNT-1:0] eth_rx_ptp_clk; +wire [PORT_COUNT-1:0] eth_rx_ptp_rst; wire [PORT_COUNT*PTP_TS_WIDTH-1:0] eth_rx_ptp_ts_96; wire [PORT_COUNT-1:0] eth_rx_ptp_ts_step; @@ -583,6 +588,8 @@ generate assign axis_eth_rx_tlast[QSFP_IND] = qsfp_rx_axis_tlast; assign axis_eth_rx_tuser[QSFP_IND*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH] = {qsfp_rx_axis_tuser[80:1], 16'd0, qsfp_rx_axis_tuser[0]}; + assign eth_rx_ptp_clk[QSFP_IND] = qsfp_rx_ptp_clk; + assign eth_rx_ptp_rst[QSFP_IND] = qsfp_rx_ptp_rst; assign qsfp_tx_ptp_time = eth_tx_ptp_ts_96[QSFP_IND*PTP_TS_WIDTH+16 +: 80]; assign qsfp_rx_ptp_time = eth_rx_ptp_ts_96[QSFP_IND*PTP_TS_WIDTH+16 +: 80]; end else begin @@ -619,6 +626,7 @@ mqnic_core_pcie_us #( .PTP_PERIOD_NS(PTP_PERIOD_NS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), @@ -911,6 +919,8 @@ core_inst ( .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), + .eth_rx_ptp_clk(eth_rx_ptp_clk), + .eth_rx_ptp_rst(eth_rx_ptp_rst), .eth_rx_ptp_ts_96(eth_rx_ptp_ts_96), .eth_rx_ptp_ts_step(eth_rx_ptp_ts_step), diff --git a/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/Makefile index e2cf53457..a96fb3b3c 100644 --- a/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/Makefile @@ -123,6 +123,7 @@ export PARAM_PORTS_PER_IF ?= 1 # PTP configuration export PARAM_PTP_USE_SAMPLE_CLOCK ?= 0 +export PARAM_PTP_SEPARATE_RX_CLOCK ?= 0 export PARAM_PTP_PEROUT_ENABLE ?= 0 export PARAM_PTP_PEROUT_COUNT ?= 1 @@ -222,6 +223,7 @@ ifeq ($(SIM), icarus) COMPILE_ARGS += -P $(TOPLEVEL).IF_COUNT=$(PARAM_IF_COUNT) COMPILE_ARGS += -P $(TOPLEVEL).PORTS_PER_IF=$(PARAM_PORTS_PER_IF) COMPILE_ARGS += -P $(TOPLEVEL).PTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -P $(TOPLEVEL).PTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_CLOCK) COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE) COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT) COMPILE_ARGS += -P $(TOPLEVEL).EVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE) @@ -301,6 +303,7 @@ else ifeq ($(SIM), verilator) COMPILE_ARGS += -GIF_COUNT=$(PARAM_IF_COUNT) COMPILE_ARGS += -GPORTS_PER_IF=$(PARAM_PORTS_PER_IF) COMPILE_ARGS += -GPTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -GPTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_CLOCK) COMPILE_ARGS += -GPTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE) COMPILE_ARGS += -GPTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT) COMPILE_ARGS += -GEVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE) diff --git a/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/test_fpga_core.py index 6d26ac782..4473c519c 100644 --- a/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -554,6 +554,7 @@ def test_fpga_core(request): # PTP configuration parameters['PTP_USE_SAMPLE_CLOCK'] = 0 + parameters['PTP_SEPARATE_RX_CLOCK'] = 0 parameters['PTP_PEROUT_ENABLE'] = 0 parameters['PTP_PEROUT_COUNT'] = 1 diff --git a/fpga/mqnic/VCU118/fpga_100g/rtl/fpga.v b/fpga/mqnic/VCU118/fpga_100g/rtl/fpga.v index d5b9b4d6f..f7abcc11c 100644 --- a/fpga/mqnic/VCU118/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/VCU118/fpga_100g/rtl/fpga.v @@ -264,6 +264,7 @@ parameter PTP_FNS_WIDTH = 32; parameter PTP_PERIOD_NS = 4'd4; parameter PTP_PERIOD_FNS = 32'd0; parameter PTP_USE_SAMPLE_CLOCK = 0; +parameter PTP_SEPARATE_RX_CLOCK = 1; // PCIe interface configuration parameter MSI_COUNT = 32; @@ -926,6 +927,8 @@ wire qsfp1_rx_axis_tvalid_int; wire qsfp1_rx_axis_tlast_int; wire [80+1-1:0] qsfp1_rx_axis_tuser_int; +wire qsfp1_rx_ptp_clk_int; +wire qsfp1_rx_ptp_rst_int; wire [79:0] qsfp1_rx_ptp_time_int; wire qsfp2_tx_clk_int; @@ -959,20 +962,44 @@ wire qsfp2_rx_axis_tvalid_int; wire qsfp2_rx_axis_tlast_int; wire [80+1-1:0] qsfp2_rx_axis_tuser_int; +wire qsfp2_rx_ptp_clk_int; +wire qsfp2_rx_ptp_rst_int; wire [79:0] qsfp2_rx_ptp_time_int; wire qsfp1_rx_status; wire qsfp2_rx_status; wire qsfp1_txuserclk2; +wire qsfp1_rxuserclk2; assign qsfp1_tx_clk_int = qsfp1_txuserclk2; assign qsfp1_rx_clk_int = qsfp1_txuserclk2; +assign qsfp1_rx_ptp_clk_int = qsfp1_rxuserclk2; wire qsfp2_txuserclk2; +wire qsfp2_rxuserclk2; assign qsfp2_tx_clk_int = qsfp2_txuserclk2; assign qsfp2_rx_clk_int = qsfp2_txuserclk2; +assign qsfp2_rx_ptp_clk_int = qsfp2_rxuserclk2; + +sync_reset #( + .N(4) +) +sync_reset_qsfp1_rx_ptp_rst_inst ( + .clk(qsfp1_rx_ptp_clk_int), + .rst(qsfp1_tx_rst_int), + .out(qsfp1_rx_ptp_rst_int) +); + +sync_reset #( + .N(4) +) +sync_reset_qsfp2_rx_ptp_rst_inst ( + .clk(qsfp2_rx_ptp_clk_int), + .rst(qsfp2_tx_rst_int), + .out(qsfp2_rx_ptp_rst_int) +); cmac_pad #( .DATA_WIDTH(AXIS_ETH_DATA_WIDTH), @@ -1037,7 +1064,7 @@ qsfp1_cmac_inst ( .rx_otn_vlmarker(), // output .rx_preambleout(), // output [55:0] .usr_rx_reset(qsfp1_rx_rst_int), // output - .gt_rxusrclk2(), // output + .gt_rxusrclk2(qsfp1_rxuserclk2), // output .rx_lane_aligner_fill_0(), // output [6:0] .rx_lane_aligner_fill_1(), // output [6:0] @@ -1061,8 +1088,7 @@ qsfp1_cmac_inst ( .rx_lane_aligner_fill_9(), // output [6:0] .rx_ptp_tstamp_out(qsfp1_rx_axis_tuser_int[80:1]), // output [79:0] .rx_ptp_pcslane_out(), // output [4:0] - // RX fed from TX clock, so use same PTP time source - .ctl_rx_systemtimerin(qsfp1_tx_ptp_time_int), // input [79:0] + .ctl_rx_systemtimerin(qsfp1_rx_ptp_time_int), // input [79:0] .stat_rx_aligned(), // output .stat_rx_aligned_err(), // output @@ -1358,7 +1384,7 @@ qsfp2_cmac_inst ( .rx_otn_vlmarker(), // output .rx_preambleout(), // output [55:0] .usr_rx_reset(qsfp2_rx_rst_int), // output - .gt_rxusrclk2(), // output + .gt_rxusrclk2(qsfp2_rxuserclk2), // output .rx_lane_aligner_fill_0(), // output [6:0] .rx_lane_aligner_fill_1(), // output [6:0] @@ -1382,8 +1408,7 @@ qsfp2_cmac_inst ( .rx_lane_aligner_fill_9(), // output [6:0] .rx_ptp_tstamp_out(qsfp2_rx_axis_tuser_int[80:1]), // output [79:0] .rx_ptp_pcslane_out(), // output [4:0] - // RX fed from TX clock, so use same PTP time source - .ctl_rx_systemtimerin(qsfp2_tx_ptp_time_int), // input [79:0] + .ctl_rx_systemtimerin(qsfp2_rx_ptp_time_int), // input [79:0] .stat_rx_aligned(), // output .stat_rx_aligned_err(), // output @@ -1643,6 +1668,7 @@ fpga_core #( .PTP_PERIOD_NS(PTP_PERIOD_NS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), @@ -1880,6 +1906,8 @@ core_inst ( .qsfp1_rx_axis_tvalid(qsfp1_rx_axis_tvalid_int), .qsfp1_rx_axis_tlast(qsfp1_rx_axis_tlast_int), .qsfp1_rx_axis_tuser(qsfp1_rx_axis_tuser_int), + .qsfp1_rx_ptp_clk(qsfp1_rx_ptp_clk_int), + .qsfp1_rx_ptp_rst(qsfp1_rx_ptp_rst_int), .qsfp1_rx_ptp_time(qsfp1_rx_ptp_time_int), .qsfp1_modprsl(qsfp1_modprsl_int), .qsfp1_modsell(qsfp1_modsell), @@ -1906,6 +1934,8 @@ core_inst ( .qsfp2_rx_axis_tvalid(qsfp2_rx_axis_tvalid_int), .qsfp2_rx_axis_tlast(qsfp2_rx_axis_tlast_int), .qsfp2_rx_axis_tuser(qsfp2_rx_axis_tuser_int), + .qsfp2_rx_ptp_clk(qsfp2_rx_ptp_clk_int), + .qsfp2_rx_ptp_rst(qsfp2_rx_ptp_rst_int), .qsfp2_rx_ptp_time(qsfp2_rx_ptp_time_int), .qsfp2_modprsl(qsfp2_modprsl_int), .qsfp2_modsell(qsfp2_modsell), diff --git a/fpga/mqnic/VCU118/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/VCU118/fpga_100g/rtl/fpga_core.v index 7389d340a..274b6940d 100644 --- a/fpga/mqnic/VCU118/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/VCU118/fpga_100g/rtl/fpga_core.v @@ -62,6 +62,7 @@ module fpga_core # parameter PTP_PERIOD_NS = 4'd4, parameter PTP_PERIOD_FNS = 32'd0, parameter PTP_USE_SAMPLE_CLOCK = 0, + parameter PTP_SEPARATE_RX_CLOCK = 0, parameter PTP_PEROUT_ENABLE = 1, parameter PTP_PEROUT_COUNT = 1, @@ -304,6 +305,8 @@ module fpga_core # input wire qsfp1_rx_axis_tlast, input wire [80+1-1:0] qsfp1_rx_axis_tuser, + input wire qsfp1_rx_ptp_clk, + input wire qsfp1_rx_ptp_rst, output wire [79:0] qsfp1_rx_ptp_time, output wire qsfp1_modsell, @@ -336,6 +339,8 @@ module fpga_core # input wire qsfp2_rx_axis_tlast, input wire [80+1-1:0] qsfp2_rx_axis_tuser, + input wire qsfp2_rx_ptp_clk, + input wire qsfp2_rx_ptp_rst, output wire [79:0] qsfp2_rx_ptp_time, output wire qsfp2_modsell, @@ -631,6 +636,8 @@ wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; +wire [PORT_COUNT-1:0] eth_rx_ptp_clk; +wire [PORT_COUNT-1:0] eth_rx_ptp_rst; wire [PORT_COUNT*PTP_TS_WIDTH-1:0] eth_rx_ptp_ts_96; wire [PORT_COUNT-1:0] eth_rx_ptp_ts_step; @@ -677,6 +684,8 @@ generate assign axis_eth_rx_tlast[QSFP1_IND] = qsfp1_rx_axis_tlast; assign axis_eth_rx_tuser[QSFP1_IND*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH] = {qsfp1_rx_axis_tuser[80:1], 16'd0, qsfp1_rx_axis_tuser[0]}; + assign eth_rx_ptp_clk[QSFP1_IND] = qsfp1_rx_ptp_clk; + assign eth_rx_ptp_rst[QSFP1_IND] = qsfp1_rx_ptp_rst; assign qsfp1_tx_ptp_time = eth_tx_ptp_ts_96[QSFP1_IND*PTP_TS_WIDTH+16 +: 80]; assign qsfp1_rx_ptp_time = eth_rx_ptp_ts_96[QSFP1_IND*PTP_TS_WIDTH+16 +: 80]; end else begin @@ -713,6 +722,8 @@ generate assign axis_eth_rx_tlast[QSFP2_IND] = qsfp2_rx_axis_tlast; assign axis_eth_rx_tuser[QSFP2_IND*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH] = {qsfp2_rx_axis_tuser[80:1], 16'd0, qsfp2_rx_axis_tuser[0]}; + assign eth_rx_ptp_clk[QSFP2_IND] = qsfp2_rx_ptp_clk; + assign eth_rx_ptp_rst[QSFP2_IND] = qsfp2_rx_ptp_rst; assign qsfp2_tx_ptp_time = eth_tx_ptp_ts_96[QSFP2_IND*PTP_TS_WIDTH+16 +: 80]; assign qsfp2_rx_ptp_time = eth_rx_ptp_ts_96[QSFP2_IND*PTP_TS_WIDTH+16 +: 80]; end else begin @@ -749,6 +760,7 @@ mqnic_core_pcie_us #( .PTP_PERIOD_NS(PTP_PERIOD_NS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), @@ -1041,6 +1053,8 @@ core_inst ( .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), + .eth_rx_ptp_clk(eth_rx_ptp_clk), + .eth_rx_ptp_rst(eth_rx_ptp_rst), .eth_rx_ptp_ts_96(eth_rx_ptp_ts_96), .eth_rx_ptp_ts_step(eth_rx_ptp_ts_step), diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/Makefile index fc1af6ec1..3a1294dee 100644 --- a/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/Makefile @@ -123,6 +123,7 @@ export PARAM_PORTS_PER_IF ?= 1 # PTP configuration export PARAM_PTP_USE_SAMPLE_CLOCK ?= 0 +export PARAM_PTP_SEPARATE_RX_CLOCK ?= 0 export PARAM_PTP_PEROUT_ENABLE ?= 1 export PARAM_PTP_PEROUT_COUNT ?= 1 @@ -222,6 +223,7 @@ ifeq ($(SIM), icarus) COMPILE_ARGS += -P $(TOPLEVEL).IF_COUNT=$(PARAM_IF_COUNT) COMPILE_ARGS += -P $(TOPLEVEL).PORTS_PER_IF=$(PARAM_PORTS_PER_IF) COMPILE_ARGS += -P $(TOPLEVEL).PTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -P $(TOPLEVEL).PTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_CLOCK) COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE) COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT) COMPILE_ARGS += -P $(TOPLEVEL).EVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE) @@ -301,6 +303,7 @@ else ifeq ($(SIM), verilator) COMPILE_ARGS += -GIF_COUNT=$(PARAM_IF_COUNT) COMPILE_ARGS += -GPORTS_PER_IF=$(PARAM_PORTS_PER_IF) COMPILE_ARGS += -GPTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -GPTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_CLOCK) COMPILE_ARGS += -GPTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE) COMPILE_ARGS += -GPTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT) COMPILE_ARGS += -GEVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE) diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/test_fpga_core.py index 909c13f5d..d53ccadd4 100644 --- a/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -608,6 +608,7 @@ def test_fpga_core(request): # PTP configuration parameters['PTP_USE_SAMPLE_CLOCK'] = 0 + parameters['PTP_SEPARATE_RX_CLOCK'] = 0 parameters['PTP_PEROUT_ENABLE'] = 1 parameters['PTP_PEROUT_COUNT'] = 1 diff --git a/fpga/mqnic/VCU1525/fpga_100g/rtl/fpga.v b/fpga/mqnic/VCU1525/fpga_100g/rtl/fpga.v index ea98ace20..94fca3701 100644 --- a/fpga/mqnic/VCU1525/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/VCU1525/fpga_100g/rtl/fpga.v @@ -246,6 +246,7 @@ parameter PTP_FNS_WIDTH = 32; parameter PTP_PERIOD_NS = 4'd4; parameter PTP_PERIOD_FNS = 32'd0; parameter PTP_USE_SAMPLE_CLOCK = 0; +parameter PTP_SEPARATE_RX_CLOCK = 1; // PCIe interface configuration parameter MSI_COUNT = 32; @@ -912,6 +913,8 @@ wire qsfp0_rx_axis_tvalid_int; wire qsfp0_rx_axis_tlast_int; wire [80+1-1:0] qsfp0_rx_axis_tuser_int; +wire qsfp0_rx_ptp_clk_int; +wire qsfp0_rx_ptp_rst_int; wire [79:0] qsfp0_rx_ptp_time_int; assign qsfp1_refclk_reset = qsfp_refclk_reset_reg; @@ -948,20 +951,44 @@ wire qsfp1_rx_axis_tvalid_int; wire qsfp1_rx_axis_tlast_int; wire [80+1-1:0] qsfp1_rx_axis_tuser_int; +wire qsfp1_rx_ptp_clk_int; +wire qsfp1_rx_ptp_rst_int; wire [79:0] qsfp1_rx_ptp_time_int; wire qsfp0_rx_status; wire qsfp1_rx_status; wire qsfp0_txuserclk2; +wire qsfp0_rxuserclk2; assign qsfp0_tx_clk_int = qsfp0_txuserclk2; assign qsfp0_rx_clk_int = qsfp0_txuserclk2; +assign qsfp0_rx_ptp_clk_int = qsfp0_rxuserclk2; wire qsfp1_txuserclk2; +wire qsfp1_rxuserclk2; assign qsfp1_tx_clk_int = qsfp1_txuserclk2; assign qsfp1_rx_clk_int = qsfp1_txuserclk2; +assign qsfp1_rx_ptp_clk_int = qsfp1_rxuserclk2; + +sync_reset #( + .N(4) +) +sync_reset_qsfp0_rx_ptp_rst_inst ( + .clk(qsfp0_rx_ptp_clk_int), + .rst(qsfp0_tx_rst_int), + .out(qsfp0_rx_ptp_rst_int) +); + +sync_reset #( + .N(4) +) +sync_reset_qsfp1_rx_ptp_rst_inst ( + .clk(qsfp1_rx_ptp_clk_int), + .rst(qsfp1_tx_rst_int), + .out(qsfp1_rx_ptp_rst_int) +); cmac_pad #( .DATA_WIDTH(AXIS_ETH_DATA_WIDTH), @@ -1026,7 +1053,7 @@ qsfp0_cmac_inst ( .rx_otn_vlmarker(), // output .rx_preambleout(), // output [55:0] .usr_rx_reset(qsfp0_rx_rst_int), // output - .gt_rxusrclk2(), // output + .gt_rxusrclk2(qsfp0_rxuserclk2), // output .rx_lane_aligner_fill_0(), // output [6:0] .rx_lane_aligner_fill_1(), // output [6:0] @@ -1050,8 +1077,7 @@ qsfp0_cmac_inst ( .rx_lane_aligner_fill_9(), // output [6:0] .rx_ptp_tstamp_out(qsfp0_rx_axis_tuser_int[80:1]), // output [79:0] .rx_ptp_pcslane_out(), // output [4:0] - // RX fed from TX clock, so use same PTP time source - .ctl_rx_systemtimerin(qsfp0_tx_ptp_time_int), // input [79:0] + .ctl_rx_systemtimerin(qsfp0_rx_ptp_time_int), // input [79:0] .stat_rx_aligned(), // output .stat_rx_aligned_err(), // output @@ -1347,7 +1373,7 @@ qsfp1_cmac_inst ( .rx_otn_vlmarker(), // output .rx_preambleout(), // output [55:0] .usr_rx_reset(qsfp1_rx_rst_int), // output - .gt_rxusrclk2(), // output + .gt_rxusrclk2(qsfp1_rxuserclk2), // output .rx_lane_aligner_fill_0(), // output [6:0] .rx_lane_aligner_fill_1(), // output [6:0] @@ -1371,8 +1397,7 @@ qsfp1_cmac_inst ( .rx_lane_aligner_fill_9(), // output [6:0] .rx_ptp_tstamp_out(qsfp1_rx_axis_tuser_int[80:1]), // output [79:0] .rx_ptp_pcslane_out(), // output [4:0] - // RX fed from TX clock, so use same PTP time source - .ctl_rx_systemtimerin(qsfp1_tx_ptp_time_int), // input [79:0] + .ctl_rx_systemtimerin(qsfp1_rx_ptp_time_int), // input [79:0] .stat_rx_aligned(), // output .stat_rx_aligned_err(), // output @@ -1632,6 +1657,7 @@ fpga_core #( .PTP_PERIOD_NS(PTP_PERIOD_NS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), @@ -1862,6 +1888,8 @@ core_inst ( .qsfp0_rx_axis_tvalid(qsfp0_rx_axis_tvalid_int), .qsfp0_rx_axis_tlast(qsfp0_rx_axis_tlast_int), .qsfp0_rx_axis_tuser(qsfp0_rx_axis_tuser_int), + .qsfp0_rx_ptp_clk(qsfp0_rx_ptp_clk_int), + .qsfp0_rx_ptp_rst(qsfp0_rx_ptp_rst_int), .qsfp0_rx_ptp_time(qsfp0_rx_ptp_time_int), .qsfp0_modprsl(qsfp0_modprsl_int), .qsfp0_modsell(qsfp0_modsell), @@ -1888,6 +1916,8 @@ core_inst ( .qsfp1_rx_axis_tvalid(qsfp1_rx_axis_tvalid_int), .qsfp1_rx_axis_tlast(qsfp1_rx_axis_tlast_int), .qsfp1_rx_axis_tuser(qsfp1_rx_axis_tuser_int), + .qsfp1_rx_ptp_clk(qsfp1_rx_ptp_clk_int), + .qsfp1_rx_ptp_rst(qsfp1_rx_ptp_rst_int), .qsfp1_rx_ptp_time(qsfp1_rx_ptp_time_int), .qsfp1_modprsl(qsfp1_modprsl_int), .qsfp1_modsell(qsfp1_modsell), diff --git a/fpga/mqnic/VCU1525/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/VCU1525/fpga_100g/rtl/fpga_core.v index 53454ee26..ee7728858 100644 --- a/fpga/mqnic/VCU1525/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/VCU1525/fpga_100g/rtl/fpga_core.v @@ -62,6 +62,7 @@ module fpga_core # parameter PTP_PERIOD_NS = 4'd4, parameter PTP_PERIOD_FNS = 32'd0, parameter PTP_USE_SAMPLE_CLOCK = 0, + parameter PTP_SEPARATE_RX_CLOCK = 0, parameter PTP_PEROUT_ENABLE = 0, parameter PTP_PEROUT_COUNT = 1, @@ -297,6 +298,8 @@ module fpga_core # input wire qsfp0_rx_axis_tlast, input wire [80+1-1:0] qsfp0_rx_axis_tuser, + input wire qsfp0_rx_ptp_clk, + input wire qsfp0_rx_ptp_rst, output wire [79:0] qsfp0_rx_ptp_time, output wire qsfp0_modsell, @@ -329,6 +332,8 @@ module fpga_core # input wire qsfp1_rx_axis_tlast, input wire [80+1-1:0] qsfp1_rx_axis_tuser, + input wire qsfp1_rx_ptp_clk, + input wire qsfp1_rx_ptp_rst, output wire [79:0] qsfp1_rx_ptp_time, output wire qsfp1_modsell, @@ -586,6 +591,8 @@ wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; +wire [PORT_COUNT-1:0] eth_rx_ptp_clk; +wire [PORT_COUNT-1:0] eth_rx_ptp_rst; wire [PORT_COUNT*PTP_TS_WIDTH-1:0] eth_rx_ptp_ts_96; wire [PORT_COUNT-1:0] eth_rx_ptp_ts_step; @@ -632,6 +639,8 @@ generate assign axis_eth_rx_tlast[QSFP0_IND] = qsfp0_rx_axis_tlast; assign axis_eth_rx_tuser[QSFP0_IND*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH] = {qsfp0_rx_axis_tuser[80:1], 16'd0, qsfp0_rx_axis_tuser[0]}; + assign eth_rx_ptp_clk[QSFP0_IND] = qsfp0_rx_ptp_clk; + assign eth_rx_ptp_rst[QSFP0_IND] = qsfp0_rx_ptp_rst; assign qsfp0_tx_ptp_time = eth_tx_ptp_ts_96[QSFP0_IND*PTP_TS_WIDTH+16 +: 80]; assign qsfp0_rx_ptp_time = eth_rx_ptp_ts_96[QSFP0_IND*PTP_TS_WIDTH+16 +: 80]; end else begin @@ -668,6 +677,8 @@ generate assign axis_eth_rx_tlast[QSFP1_IND] = qsfp1_rx_axis_tlast; assign axis_eth_rx_tuser[QSFP1_IND*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH] = {qsfp1_rx_axis_tuser[80:1], 16'd0, qsfp1_rx_axis_tuser[0]}; + assign eth_rx_ptp_clk[QSFP1_IND] = qsfp1_rx_ptp_clk; + assign eth_rx_ptp_rst[QSFP1_IND] = qsfp1_rx_ptp_rst; assign qsfp1_tx_ptp_time = eth_tx_ptp_ts_96[QSFP1_IND*PTP_TS_WIDTH+16 +: 80]; assign qsfp1_rx_ptp_time = eth_rx_ptp_ts_96[QSFP1_IND*PTP_TS_WIDTH+16 +: 80]; end else begin @@ -704,6 +715,7 @@ mqnic_core_pcie_us #( .PTP_PERIOD_NS(PTP_PERIOD_NS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), @@ -996,6 +1008,8 @@ core_inst ( .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), + .eth_rx_ptp_clk(eth_rx_ptp_clk), + .eth_rx_ptp_rst(eth_rx_ptp_rst), .eth_rx_ptp_ts_96(eth_rx_ptp_ts_96), .eth_rx_ptp_ts_step(eth_rx_ptp_ts_step), diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/Makefile index 5edd4f293..d418b9605 100644 --- a/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/Makefile @@ -123,6 +123,7 @@ export PARAM_PORTS_PER_IF ?= 1 # PTP configuration export PARAM_PTP_USE_SAMPLE_CLOCK ?= 0 +export PARAM_PTP_SEPARATE_RX_CLOCK ?= 0 export PARAM_PTP_PEROUT_ENABLE ?= 0 export PARAM_PTP_PEROUT_COUNT ?= 1 @@ -222,6 +223,7 @@ ifeq ($(SIM), icarus) COMPILE_ARGS += -P $(TOPLEVEL).IF_COUNT=$(PARAM_IF_COUNT) COMPILE_ARGS += -P $(TOPLEVEL).PORTS_PER_IF=$(PARAM_PORTS_PER_IF) COMPILE_ARGS += -P $(TOPLEVEL).PTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -P $(TOPLEVEL).PTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_CLOCK) COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE) COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT) COMPILE_ARGS += -P $(TOPLEVEL).EVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE) @@ -301,6 +303,7 @@ else ifeq ($(SIM), verilator) COMPILE_ARGS += -GIF_COUNT=$(PARAM_IF_COUNT) COMPILE_ARGS += -GPORTS_PER_IF=$(PARAM_PORTS_PER_IF) COMPILE_ARGS += -GPTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -GPTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_CLOCK) COMPILE_ARGS += -GPTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE) COMPILE_ARGS += -GPTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT) COMPILE_ARGS += -GEVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE) diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/test_fpga_core.py index ea9d95201..e7e615c59 100644 --- a/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -602,6 +602,7 @@ def test_fpga_core(request): # PTP configuration parameters['PTP_USE_SAMPLE_CLOCK'] = 0 + parameters['PTP_SEPARATE_RX_CLOCK'] = 0 parameters['PTP_PEROUT_ENABLE'] = 0 parameters['PTP_PEROUT_COUNT'] = 1 diff --git a/fpga/mqnic/fb2CG/fpga_100g/rtl/fpga.v b/fpga/mqnic/fb2CG/fpga_100g/rtl/fpga.v index 8ec62b6a5..7ff17c5fc 100644 --- a/fpga/mqnic/fb2CG/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/fb2CG/fpga_100g/rtl/fpga.v @@ -261,6 +261,7 @@ parameter PTP_FNS_WIDTH = 32; parameter PTP_PERIOD_NS = 4'd4; parameter PTP_PERIOD_FNS = 32'd0; parameter PTP_USE_SAMPLE_CLOCK = 0; +parameter PTP_SEPARATE_RX_CLOCK = 1; // PCIe interface configuration parameter MSI_COUNT = 32; @@ -956,6 +957,8 @@ wire qsfp_0_rx_axis_tvalid_int; wire qsfp_0_rx_axis_tlast_int; wire [80+1-1:0] qsfp_0_rx_axis_tuser_int; +wire qsfp_0_rx_ptp_clk_int; +wire qsfp_0_rx_ptp_rst_int; wire [79:0] qsfp_0_rx_ptp_time_int; wire qsfp_1_tx_clk_int; @@ -989,20 +992,44 @@ wire qsfp_1_rx_axis_tvalid_int; wire qsfp_1_rx_axis_tlast_int; wire [80+1-1:0] qsfp_1_rx_axis_tuser_int; +wire qsfp_1_rx_ptp_clk_int; +wire qsfp_1_rx_ptp_rst_int; wire [79:0] qsfp_1_rx_ptp_time_int; wire qsfp_0_rx_status; wire qsfp_1_rx_status; wire qsfp_0_txuserclk2; +wire qsfp_0_rxuserclk2; assign qsfp_0_tx_clk_int = qsfp_0_txuserclk2; assign qsfp_0_rx_clk_int = qsfp_0_txuserclk2; +assign qsfp_0_rx_ptp_clk_int = qsfp_0_rxuserclk2; wire qsfp_1_txuserclk2; +wire qsfp_1_rxuserclk2; assign qsfp_1_tx_clk_int = qsfp_1_txuserclk2; assign qsfp_1_rx_clk_int = qsfp_1_txuserclk2; +assign qsfp_1_rx_ptp_clk_int = qsfp_1_rxuserclk2; + +sync_reset #( + .N(4) +) +sync_reset_qsfp_0_rx_ptp_rst_inst ( + .clk(qsfp_0_rx_ptp_clk_int), + .rst(qsfp_0_tx_rst_int), + .out(qsfp_0_rx_ptp_rst_int) +); + +sync_reset #( + .N(4) +) +sync_reset_qsfp_1_rx_ptp_rst_inst ( + .clk(qsfp_1_rx_ptp_clk_int), + .rst(qsfp_1_tx_rst_int), + .out(qsfp_1_rx_ptp_rst_int) +); cmac_pad #( .DATA_WIDTH(AXIS_ETH_DATA_WIDTH), @@ -1067,7 +1094,7 @@ qsfp_0_cmac_inst ( .rx_otn_vlmarker(), // output .rx_preambleout(), // output [55:0] .usr_rx_reset(qsfp_0_rx_rst_int), // output - .gt_rxusrclk2(), // output + .gt_rxusrclk2(qsfp_0_rxuserclk2), // output .rx_lane_aligner_fill_0(), // output [6:0] .rx_lane_aligner_fill_1(), // output [6:0] @@ -1091,8 +1118,7 @@ qsfp_0_cmac_inst ( .rx_lane_aligner_fill_9(), // output [6:0] .rx_ptp_tstamp_out(qsfp_0_rx_axis_tuser_int[80:1]), // output [79:0] .rx_ptp_pcslane_out(), // output [4:0] - // RX fed from TX clock, so use same PTP time source - .ctl_rx_systemtimerin(qsfp_0_tx_ptp_time_int), // input [79:0] + .ctl_rx_systemtimerin(qsfp_0_rx_ptp_time_int), // input [79:0] .stat_rx_aligned(), // output .stat_rx_aligned_err(), // output @@ -1388,7 +1414,7 @@ qsfp_1_cmac_inst ( .rx_otn_vlmarker(), // output .rx_preambleout(), // output [55:0] .usr_rx_reset(qsfp_1_rx_rst_int), // output - .gt_rxusrclk2(), // output + .gt_rxusrclk2(qsfp_1_rxuserclk2), // output .rx_lane_aligner_fill_0(), // output [6:0] .rx_lane_aligner_fill_1(), // output [6:0] @@ -1412,8 +1438,7 @@ qsfp_1_cmac_inst ( .rx_lane_aligner_fill_9(), // output [6:0] .rx_ptp_tstamp_out(qsfp_1_rx_axis_tuser_int[80:1]), // output [79:0] .rx_ptp_pcslane_out(), // output [4:0] - // RX fed from TX clock, so use same PTP time source - .ctl_rx_systemtimerin(qsfp_1_tx_ptp_time_int), // input [79:0] + .ctl_rx_systemtimerin(qsfp_1_rx_ptp_time_int), // input [79:0] .stat_rx_aligned(), // output .stat_rx_aligned_err(), // output @@ -1672,6 +1697,7 @@ fpga_core #( .PTP_PERIOD_NS(PTP_PERIOD_NS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), @@ -1907,6 +1933,8 @@ core_inst ( .qsfp_0_rx_axis_tvalid(qsfp_0_rx_axis_tvalid_int), .qsfp_0_rx_axis_tlast(qsfp_0_rx_axis_tlast_int), .qsfp_0_rx_axis_tuser(qsfp_0_rx_axis_tuser_int), + .qsfp_0_rx_ptp_clk(qsfp_0_rx_ptp_clk_int), + .qsfp_0_rx_ptp_rst(qsfp_0_rx_ptp_rst_int), .qsfp_0_rx_ptp_time(qsfp_0_rx_ptp_time_int), .qsfp_0_mod_prsnt_n(qsfp_0_mod_prsnt_n_int), .qsfp_0_reset_n(qsfp_0_reset_n), @@ -1937,6 +1965,8 @@ core_inst ( .qsfp_1_rx_axis_tvalid(qsfp_1_rx_axis_tvalid_int), .qsfp_1_rx_axis_tlast(qsfp_1_rx_axis_tlast_int), .qsfp_1_rx_axis_tuser(qsfp_1_rx_axis_tuser_int), + .qsfp_1_rx_ptp_clk(qsfp_1_rx_ptp_clk_int), + .qsfp_1_rx_ptp_rst(qsfp_1_rx_ptp_rst_int), .qsfp_1_rx_ptp_time(qsfp_1_rx_ptp_time_int), .qsfp_1_mod_prsnt_n(qsfp_1_mod_prsnt_n_int), .qsfp_1_reset_n(qsfp_1_reset_n), diff --git a/fpga/mqnic/fb2CG/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/fb2CG/fpga_100g/rtl/fpga_core.v index cdb451bd3..5bf9169f0 100644 --- a/fpga/mqnic/fb2CG/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/fb2CG/fpga_100g/rtl/fpga_core.v @@ -62,6 +62,7 @@ module fpga_core # parameter PTP_PERIOD_NS = 4'd4, parameter PTP_PERIOD_FNS = 32'd0, parameter PTP_USE_SAMPLE_CLOCK = 0, + parameter PTP_SEPARATE_RX_CLOCK = 0, parameter PTP_PEROUT_ENABLE = 1, parameter PTP_PEROUT_COUNT = 1, @@ -302,6 +303,8 @@ module fpga_core # input wire qsfp_0_rx_axis_tlast, input wire [80+1-1:0] qsfp_0_rx_axis_tuser, + input wire qsfp_0_rx_ptp_clk, + input wire qsfp_0_rx_ptp_rst, output wire [79:0] qsfp_0_rx_ptp_time, input wire qsfp_0_mod_prsnt_n, @@ -339,6 +342,8 @@ module fpga_core # input wire qsfp_1_rx_axis_tlast, input wire [80+1-1:0] qsfp_1_rx_axis_tuser, + input wire qsfp_1_rx_ptp_clk, + input wire qsfp_1_rx_ptp_rst, output wire [79:0] qsfp_1_rx_ptp_time, input wire qsfp_1_mod_prsnt_n, @@ -678,6 +683,8 @@ wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; +wire [PORT_COUNT-1:0] eth_rx_ptp_clk; +wire [PORT_COUNT-1:0] eth_rx_ptp_rst; wire [PORT_COUNT*PTP_TS_WIDTH-1:0] eth_rx_ptp_ts_96; wire [PORT_COUNT-1:0] eth_rx_ptp_ts_step; @@ -724,6 +731,8 @@ generate assign axis_eth_rx_tlast[QSFP_0_IND] = qsfp_0_rx_axis_tlast; assign axis_eth_rx_tuser[QSFP_0_IND*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH] = {qsfp_0_rx_axis_tuser[80:1], 16'd0, qsfp_0_rx_axis_tuser[0]}; + assign eth_rx_ptp_clk[QSFP_0_IND] = qsfp_0_rx_ptp_clk; + assign eth_rx_ptp_rst[QSFP_0_IND] = qsfp_0_rx_ptp_rst; assign qsfp_0_tx_ptp_time = eth_tx_ptp_ts_96[QSFP_0_IND*PTP_TS_WIDTH+16 +: 80]; assign qsfp_0_rx_ptp_time = eth_rx_ptp_ts_96[QSFP_0_IND*PTP_TS_WIDTH+16 +: 80]; end else begin @@ -760,6 +769,8 @@ generate assign axis_eth_rx_tlast[QSFP_1_IND] = qsfp_1_rx_axis_tlast; assign axis_eth_rx_tuser[QSFP_1_IND*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH] = {qsfp_1_rx_axis_tuser[80:1], 16'd0, qsfp_1_rx_axis_tuser[0]}; + assign eth_rx_ptp_clk[QSFP_1_IND] = qsfp_1_rx_ptp_clk; + assign eth_rx_ptp_rst[QSFP_1_IND] = qsfp_1_rx_ptp_rst; assign qsfp_1_tx_ptp_time = eth_tx_ptp_ts_96[QSFP_1_IND*PTP_TS_WIDTH+16 +: 80]; assign qsfp_1_rx_ptp_time = eth_rx_ptp_ts_96[QSFP_1_IND*PTP_TS_WIDTH+16 +: 80]; end else begin @@ -796,6 +807,7 @@ mqnic_core_pcie_us #( .PTP_PERIOD_NS(PTP_PERIOD_NS), .PTP_PERIOD_FNS(PTP_PERIOD_FNS), .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), @@ -1088,6 +1100,8 @@ core_inst ( .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), + .eth_rx_ptp_clk(eth_rx_ptp_clk), + .eth_rx_ptp_rst(eth_rx_ptp_rst), .eth_rx_ptp_ts_96(eth_rx_ptp_ts_96), .eth_rx_ptp_ts_step(eth_rx_ptp_ts_step), diff --git a/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/Makefile index 429cb94ed..5bbba203f 100644 --- a/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/Makefile @@ -124,6 +124,7 @@ export PARAM_PORTS_PER_IF ?= 1 # PTP configuration export PARAM_PTP_USE_SAMPLE_CLOCK ?= 0 +export PARAM_PTP_SEPARATE_RX_CLOCK ?= 0 export PARAM_PTP_PEROUT_ENABLE ?= 1 export PARAM_PTP_PEROUT_COUNT ?= 1 @@ -223,6 +224,7 @@ ifeq ($(SIM), icarus) COMPILE_ARGS += -P $(TOPLEVEL).IF_COUNT=$(PARAM_IF_COUNT) COMPILE_ARGS += -P $(TOPLEVEL).PORTS_PER_IF=$(PARAM_PORTS_PER_IF) COMPILE_ARGS += -P $(TOPLEVEL).PTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -P $(TOPLEVEL).PTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_CLOCK) COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE) COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT) COMPILE_ARGS += -P $(TOPLEVEL).EVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE) @@ -302,6 +304,7 @@ else ifeq ($(SIM), verilator) COMPILE_ARGS += -GIF_COUNT=$(PARAM_IF_COUNT) COMPILE_ARGS += -GPORTS_PER_IF=$(PARAM_PORTS_PER_IF) COMPILE_ARGS += -GPTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -GPTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_CLOCK) COMPILE_ARGS += -GPTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE) COMPILE_ARGS += -GPTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT) COMPILE_ARGS += -GEVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE) diff --git a/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/test_fpga_core.py index 97a35f708..510079f89 100644 --- a/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -607,6 +607,7 @@ def test_fpga_core(request): # PTP configuration parameters['PTP_USE_SAMPLE_CLOCK'] = 0 + parameters['PTP_SEPARATE_RX_CLOCK'] = 0 parameters['PTP_PEROUT_ENABLE'] = 1 parameters['PTP_PEROUT_COUNT'] = 1