mirror of
https://github.com/fpganinja/taxi.git
synced 2026-04-09 05:18:44 -07:00
Compare commits
17 Commits
62da198a76
...
51e0909327
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51e0909327 | ||
|
|
88310fd348 | ||
|
|
eb289eb045 | ||
|
|
2ef9481d00 | ||
|
|
31553f5734 | ||
|
|
380e2d521a | ||
|
|
ce8147f174 | ||
|
|
8b6fb5fdb2 | ||
|
|
0461953bcc | ||
|
|
9c51c6e275 | ||
|
|
c247b3fc7a | ||
|
|
86202e5263 | ||
|
|
1ad0b99952 | ||
|
|
43e46044f6 | ||
|
|
7606ca328b | ||
|
|
20a5166f96 | ||
|
|
ddac834e99 |
@@ -47,13 +47,13 @@ Note that Zircon is still under active development and may not ready for product
|
|||||||
|
|
||||||
## Ethernet MAC and PHY
|
## Ethernet MAC and PHY
|
||||||
|
|
||||||
The Taxi transport library contains several Ethernet MAC and PCS variants, covering link rates from 10 Mbps to 25 Gbps. The MAC modules support LFC and PFC pause frames, PTP timestamping, frame length enforcement, FCS computation and verification, and statistics reporting. Wrappers for low-speed operation support MII, GMII, and RGMII PHY-attach protocols for use with an external PHY chip. Wrappers for 10G/25G include device-specific transceiver instances for a fully-integrated solution. Logic is available for a 10G/25G MAC, 10G/25G PCS, and 10G/25G "fused" MAC+PCS, with reduced latency and resource consumption.
|
The Taxi transport library contains several Ethernet MAC and PCS variants, covering link rates from 10 Mbps to 25 Gbps. The MAC modules support LFC and PFC pause frames, PTP timestamping, frame length enforcement, FCS computation and verification, and statistics reporting. PTP TD leaf clocks and statistics collection components are also integrated, configurable via instance parameters. Wrappers for low-speed operation support MII, GMII, and RGMII PHY-attach protocols for use with an external PHY chip. Wrappers for 10G/25G include device-specific transceiver instances for a fully-integrated solution. Logic is available for a 10G/25G MAC, 10G/25G PCS, and 10G/25G "fused" MAC+PCS, with reduced latency and resource consumption.
|
||||||
|
|
||||||
The 10G/25G MAC/PHY/GT wrapper for 7-series/UltraScale/UltraScale+ supports GTX, GTH, and GTY transceivers. On UltraScale and UltraScale+ devices, it can be configured for either a 32-bit or 64-bit datapath via the DATA_W parameter. The 32-bit datapath supports 10G only, while the 64-bit datapath can be used for either 10G or 25G. TCL scripts for generating the GT cores are provided for both 10G and 25G and for several common reference clocks. The core supports operation in either a normal latency mode or a low latency mode via the CFG_LOW_LATENCY paremter, which affects the clock frequency and transceiver configuration (async gearbox vs. sync gearbox and buffer bypass). The low latency mode has a slightly higher clock frequency and resource consumption, so it is not recommended unless you really need to shave off a new nanoseconds of latency, or you need highest possible time sync precision. On 7-series, the core only supports 32-bit low-latency mode. The wrapper also provides an APB interface for configuring the transceivers and QPLLs.
|
The 10G/25G MAC/PHY/GT wrapper for 7-series/UltraScale/UltraScale+ supports GTX, GTH, and GTY transceivers. On UltraScale and UltraScale+ devices, it can be configured for either a 32-bit or 64-bit datapath via the DATA_W parameter. The 32-bit datapath supports 10G only, while the 64-bit datapath can be used for either 10G or 25G. TCL scripts for generating the GT cores are provided for both 10G and 25G and for several common reference clocks. The core supports operation in either a normal latency mode or a low latency mode via the CFG_LOW_LATENCY paremter, which affects the clock frequency and transceiver configuration (async gearbox vs. sync gearbox and buffer bypass). The low latency mode has a slightly higher clock frequency and resource consumption, so it is not recommended unless you really need to shave off a new nanoseconds of latency, or you need highest possible time sync precision. On 7-series, the core only supports 32-bit low-latency mode. The wrapper also provides an APB interface for configuring the transceivers and QPLLs.
|
||||||
|
|
||||||
The 10G/25G MAC and PCS logic is also highly optimized for both size and timing performance, with 60 instances fitting comfortably on an XCVU9P -2 on the HTG9200 board, fully utilizing 15 QSFP28 (9 on the board plus 6 via FMC+, 60 lanes total). With the low-latency MACs, statistics collection, loopback FIFOs, and XFCP, the footprint is about 15% of the device LUTs at 25G (about 3000 LUTs and 2500 FFs per channel) and about 10% of the device LUTs at 10G (about 2000 LUTs and 2100 FFs per channel). The 10G configuration closes timing on the KC705 (single SFP+, 1 lane total) with an XC7K325T -2 at 322.265625 MHz, and the 25G configuration closes timing on the XUSP3S (quad QSFP38, 16 lanes total) with an XCVU095 -2 at 402.83203125 MHz.
|
The 10G/25G MAC and PCS logic is also highly optimized for both size and timing performance, with 60 instances fitting comfortably on an XCVU9P -2 on the HTG9200 board, fully utilizing 15 QSFP28 (9 on the board plus 6 via FMC+, 60 lanes total). With the low-latency MACs, statistics collection, loopback FIFOs, and XFCP, the footprint is about 15% of the device LUTs at 25G (about 3000 LUTs and 2500 FFs per channel) and about 10% of the device LUTs at 10G (about 2000 LUTs and 2100 FFs per channel). The 10G configuration closes timing on the KC705 (single SFP+, 1 lane total) with an XC7K325T -2 at 322.265625 MHz, and the 25G configuration closes timing on the XUSP3S (quad QSFP38, 16 lanes total) with an XCVU095 -2 at 402.83203125 MHz.
|
||||||
|
|
||||||
Planned features include 1000BASE-X, SGMII, USXGMII, dynamic rate switching, AN, integrated PTP TD logic, better integration of the PTP TD subsystem, and white rabbit/IEEE 1588 HA support.
|
Planned features include 1000BASE-X, SGMII, USXGMII, dynamic rate switching, AN, better integration of the PTP TD subsystem, and white rabbit/IEEE 1588 HA support.
|
||||||
|
|
||||||
## Statistics collection subsystem
|
## Statistics collection subsystem
|
||||||
|
|
||||||
@@ -191,6 +191,8 @@ The Taxi transport library contains many smaller components that can be composed
|
|||||||
* PTP period output
|
* PTP period output
|
||||||
* PTP TD leaf clock
|
* PTP TD leaf clock
|
||||||
* PTP TD PHC
|
* PTP TD PHC
|
||||||
|
* PTP TD PHC wrapper with APB register interface
|
||||||
|
* PTP TD PHC wrapper with AXI lite register interface
|
||||||
* PTP TD relative-to-ToD converter
|
* PTP TD relative-to-ToD converter
|
||||||
* Statistics collection subsystem
|
* Statistics collection subsystem
|
||||||
* Statistics collector
|
* Statistics collector
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
|
|||||||
XDC_FILES = ../fpga.xdc
|
XDC_FILES = ../fpga.xdc
|
||||||
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
|
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
|
||||||
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
|
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
|
||||||
|
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
|
||||||
|
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
|
||||||
|
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
|
||||||
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
|
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
|
||||||
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
|
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
|
|||||||
XDC_FILES = ../fpga.xdc
|
XDC_FILES = ../fpga.xdc
|
||||||
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
|
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
|
||||||
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
|
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
|
||||||
|
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
|
||||||
|
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
|
||||||
|
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
|
||||||
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
|
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
|
||||||
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
|
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ module fpga #
|
|||||||
parameter string VENDOR = "XILINX",
|
parameter string VENDOR = "XILINX",
|
||||||
// device family
|
// device family
|
||||||
parameter string FAMILY = "kintexuplus",
|
parameter string FAMILY = "kintexuplus",
|
||||||
|
// PTP configuration
|
||||||
|
parameter logic PTP_TS_EN = 1'b1,
|
||||||
// 10G/25G MAC configuration
|
// 10G/25G MAC configuration
|
||||||
parameter logic CFG_LOW_LATENCY = 1'b1,
|
parameter logic CFG_LOW_LATENCY = 1'b1,
|
||||||
parameter logic COMBINED_MAC_PCS = 1'b1,
|
parameter logic COMBINED_MAC_PCS = 1'b1,
|
||||||
@@ -491,6 +493,7 @@ fpga_core #(
|
|||||||
.SIM(SIM),
|
.SIM(SIM),
|
||||||
.VENDOR(VENDOR),
|
.VENDOR(VENDOR),
|
||||||
.FAMILY(FAMILY),
|
.FAMILY(FAMILY),
|
||||||
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
|
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
|
||||||
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
|
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
|
||||||
.MAC_DATA_W(MAC_DATA_W)
|
.MAC_DATA_W(MAC_DATA_W)
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ module fpga_core #
|
|||||||
// device family
|
// device family
|
||||||
parameter string FAMILY = "kintexuplus",
|
parameter string FAMILY = "kintexuplus",
|
||||||
parameter RQ_SEQ_NUM_W = 6,
|
parameter RQ_SEQ_NUM_W = 6,
|
||||||
|
// PTP configuration
|
||||||
|
parameter logic PTP_TS_EN = 1'b1,
|
||||||
// 10G/25G MAC configuration
|
// 10G/25G MAC configuration
|
||||||
parameter logic CFG_LOW_LATENCY = 1'b1,
|
parameter logic CFG_LOW_LATENCY = 1'b1,
|
||||||
parameter logic COMBINED_MAC_PCS = 1'b1,
|
parameter logic COMBINED_MAC_PCS = 1'b1,
|
||||||
@@ -114,6 +116,9 @@ module fpga_core #
|
|||||||
output wire [7:0] cfg_interrupt_msi_function_number
|
output wire [7:0] cfg_interrupt_msi_function_number
|
||||||
);
|
);
|
||||||
|
|
||||||
|
localparam logic PTP_TS_FMT_TOD = 1'b0;
|
||||||
|
localparam PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 48;
|
||||||
|
|
||||||
// SFP+
|
// SFP+
|
||||||
wire sfp_tx_clk[2];
|
wire sfp_tx_clk[2];
|
||||||
wire sfp_tx_rst[2];
|
wire sfp_tx_rst[2];
|
||||||
@@ -126,7 +131,7 @@ assign sfp_led[0] = !sfp_rx_status[0];
|
|||||||
assign sfp_led[1] = !sfp_rx_status[1];
|
assign sfp_led[1] = !sfp_rx_status[1];
|
||||||
assign led = '1;
|
assign led = '1;
|
||||||
assign led_r = 1'b1;
|
assign led_r = 1'b1;
|
||||||
assign led_g = 1'b1;
|
// assign led_g = 1'b1;
|
||||||
|
|
||||||
localparam HB_COUNT = 62500000;
|
localparam HB_COUNT = 62500000;
|
||||||
localparam CL_HB_COUNT = $clog2(HB_COUNT);
|
localparam CL_HB_COUNT = $clog2(HB_COUNT);
|
||||||
@@ -160,8 +165,8 @@ assign sfp_mgt_refclk_out = sfp_mgt_refclk_bufg;
|
|||||||
wire sfp_rst;
|
wire sfp_rst;
|
||||||
|
|
||||||
taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1)) axis_sfp_tx[2]();
|
taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1)) axis_sfp_tx[2]();
|
||||||
taxi_axis_if #(.DATA_W(96), .KEEP_W(1), .ID_W(8)) axis_sfp_tx_cpl[2]();
|
taxi_axis_if #(.DATA_W(PTP_TS_W), .KEEP_W(1), .ID_W(8)) axis_sfp_tx_cpl[2]();
|
||||||
taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1)) axis_sfp_rx[2]();
|
taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1+PTP_TS_W)) axis_sfp_rx[2]();
|
||||||
taxi_axis_if #(.DATA_W(16), .KEEP_W(1), .KEEP_EN(0), .LAST_EN(0), .USER_EN(1), .USER_W(1), .ID_EN(1), .ID_W(8)) axis_sfp_stat();
|
taxi_axis_if #(.DATA_W(16), .KEEP_W(1), .KEEP_EN(0), .LAST_EN(0), .USER_EN(1), .USER_W(1), .ID_EN(1), .ID_W(8)) axis_sfp_stat();
|
||||||
|
|
||||||
if (SIM) begin
|
if (SIM) begin
|
||||||
@@ -207,6 +212,15 @@ taxi_apb_if #(
|
|||||||
)
|
)
|
||||||
gt_apb_ctrl();
|
gt_apb_ctrl();
|
||||||
|
|
||||||
|
wire ptp_clk = sfp_mgt_refclk_bufg;
|
||||||
|
wire ptp_rst = sfp_rst;
|
||||||
|
wire ptp_sample_clk = clk_125mhz;
|
||||||
|
wire ptp_td_sd;
|
||||||
|
wire ptp_pps;
|
||||||
|
wire ptp_pps_str;
|
||||||
|
|
||||||
|
assign led_g = ptp_pps_str;
|
||||||
|
|
||||||
taxi_eth_mac_25g_us #(
|
taxi_eth_mac_25g_us #(
|
||||||
.SIM(SIM),
|
.SIM(SIM),
|
||||||
.VENDOR(VENDOR),
|
.VENDOR(VENDOR),
|
||||||
@@ -230,9 +244,11 @@ taxi_eth_mac_25g_us #(
|
|||||||
.PADDING_EN(1'b1),
|
.PADDING_EN(1'b1),
|
||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TD_EN(PTP_TS_EN),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
||||||
|
.PTP_TS_W(PTP_TS_W),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -284,7 +300,6 @@ sfp_mac_inst (
|
|||||||
.tx_clk(sfp_tx_clk),
|
.tx_clk(sfp_tx_clk),
|
||||||
.tx_rst_in('{2{1'b0}}),
|
.tx_rst_in('{2{1'b0}}),
|
||||||
.tx_rst_out(sfp_tx_rst),
|
.tx_rst_out(sfp_tx_rst),
|
||||||
.ptp_sample_clk('{2{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -300,10 +315,18 @@ sfp_mac_inst (
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{2{'0}}),
|
.ptp_clk(ptp_clk),
|
||||||
.tx_ptp_ts_step('{2{1'b0}}),
|
.ptp_rst(ptp_rst),
|
||||||
.rx_ptp_ts('{2{'0}}),
|
.ptp_sample_clk(ptp_sample_clk),
|
||||||
.rx_ptp_ts_step('{2{1'b0}}),
|
.ptp_td_sdi(ptp_td_sd),
|
||||||
|
.tx_ptp_ts_in('{2{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{2{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
@@ -440,6 +463,9 @@ cndm_micro_pcie_us #(
|
|||||||
.VENDOR(VENDOR),
|
.VENDOR(VENDOR),
|
||||||
.FAMILY(FAMILY),
|
.FAMILY(FAMILY),
|
||||||
.PORTS(2),
|
.PORTS(2),
|
||||||
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
|
.PTP_CLK_PER_NS_NUM(32),
|
||||||
|
.PTP_CLK_PER_NS_DENOM(5),
|
||||||
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
|
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
|
||||||
.BAR0_APERTURE(24)
|
.BAR0_APERTURE(24)
|
||||||
)
|
)
|
||||||
@@ -497,6 +523,23 @@ cndm_inst (
|
|||||||
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
|
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
|
||||||
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
|
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP
|
||||||
|
*/
|
||||||
|
.ptp_clk(ptp_clk),
|
||||||
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_sample_clk(ptp_sample_clk),
|
||||||
|
.ptp_td_sdo(ptp_td_sd),
|
||||||
|
.ptp_pps(ptp_pps),
|
||||||
|
.ptp_pps_str(ptp_pps_str),
|
||||||
|
.ptp_sync_locked(),
|
||||||
|
.ptp_sync_ts_rel(),
|
||||||
|
.ptp_sync_ts_rel_step(),
|
||||||
|
.ptp_sync_ts_tod(),
|
||||||
|
.ptp_sync_ts_tod_step(),
|
||||||
|
.ptp_sync_pps(),
|
||||||
|
.ptp_sync_pps_str(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ethernet
|
* Ethernet
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ VERILOG_SOURCES := $(call uniq_base,$(call process_f_files,$(VERILOG_SOURCES)))
|
|||||||
export PARAM_SIM := "1'b1"
|
export PARAM_SIM := "1'b1"
|
||||||
export PARAM_VENDOR := "\"XILINX\""
|
export PARAM_VENDOR := "\"XILINX\""
|
||||||
export PARAM_FAMILY := "\"kintexuplus\""
|
export PARAM_FAMILY := "\"kintexuplus\""
|
||||||
|
export PARAM_PTP_TS_EN := "1'b1"
|
||||||
export PARAM_CFG_LOW_LATENCY := "1'b1"
|
export PARAM_CFG_LOW_LATENCY := "1'b1"
|
||||||
export PARAM_COMBINED_MAC_PCS := "1'b1"
|
export PARAM_COMBINED_MAC_PCS := "1'b1"
|
||||||
export PARAM_MAC_DATA_W := "64"
|
export PARAM_MAC_DATA_W := "64"
|
||||||
|
|||||||
@@ -142,14 +142,14 @@ class TB:
|
|||||||
# pcie_tfc_npd_av=dut.pcie_tfc_npd_av,
|
# pcie_tfc_npd_av=dut.pcie_tfc_npd_av,
|
||||||
|
|
||||||
# Configuration Management Interface
|
# Configuration Management Interface
|
||||||
# cfg_mgmt_addr=dut.cfg_mgmt_addr,
|
cfg_mgmt_addr=dut.cfg_mgmt_addr,
|
||||||
# cfg_mgmt_function_number=dut.cfg_mgmt_function_number,
|
cfg_mgmt_function_number=dut.cfg_mgmt_function_number,
|
||||||
# cfg_mgmt_write=dut.cfg_mgmt_write,
|
cfg_mgmt_write=dut.cfg_mgmt_write,
|
||||||
# cfg_mgmt_write_data=dut.cfg_mgmt_write_data,
|
cfg_mgmt_write_data=dut.cfg_mgmt_write_data,
|
||||||
# cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable,
|
cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable,
|
||||||
# cfg_mgmt_read=dut.cfg_mgmt_read,
|
cfg_mgmt_read=dut.cfg_mgmt_read,
|
||||||
# cfg_mgmt_read_data=dut.cfg_mgmt_read_data,
|
cfg_mgmt_read_data=dut.cfg_mgmt_read_data,
|
||||||
# cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done,
|
cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done,
|
||||||
# cfg_mgmt_debug_access
|
# cfg_mgmt_debug_access
|
||||||
|
|
||||||
# Configuration Status Interface
|
# Configuration Status Interface
|
||||||
@@ -486,6 +486,7 @@ def test_fpga_core(request, mac_data_w):
|
|||||||
parameters['SIM'] = "1'b1"
|
parameters['SIM'] = "1'b1"
|
||||||
parameters['VENDOR'] = "\"XILINX\""
|
parameters['VENDOR'] = "\"XILINX\""
|
||||||
parameters['FAMILY'] = "\"kintexuplus\""
|
parameters['FAMILY'] = "\"kintexuplus\""
|
||||||
|
parameters['PTP_TS_EN'] = "1'b1"
|
||||||
parameters['CFG_LOW_LATENCY'] = "1'b1"
|
parameters['CFG_LOW_LATENCY'] = "1'b1"
|
||||||
parameters['COMBINED_MAC_PCS'] = "1'b1"
|
parameters['COMBINED_MAC_PCS'] = "1'b1"
|
||||||
parameters['MAC_DATA_W'] = mac_data_w
|
parameters['MAC_DATA_W'] = mac_data_w
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ module test_fpga_core #
|
|||||||
parameter AXIS_PCIE_RQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 62 : 137,
|
parameter AXIS_PCIE_RQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 62 : 137,
|
||||||
parameter AXIS_PCIE_CQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 85 : 183,
|
parameter AXIS_PCIE_CQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 85 : 183,
|
||||||
parameter AXIS_PCIE_CC_USER_W = AXIS_PCIE_DATA_W < 512 ? 33 : 81,
|
parameter AXIS_PCIE_CC_USER_W = AXIS_PCIE_DATA_W < 512 ? 33 : 81,
|
||||||
|
// PTP configuration
|
||||||
|
parameter logic PTP_TS_EN = 1'b1,
|
||||||
// 10G/25G MAC configuration
|
// 10G/25G MAC configuration
|
||||||
parameter logic CFG_LOW_LATENCY = 1'b1,
|
parameter logic CFG_LOW_LATENCY = 1'b1,
|
||||||
parameter logic COMBINED_MAC_PCS = 1'b1,
|
parameter logic COMBINED_MAC_PCS = 1'b1,
|
||||||
@@ -137,6 +139,8 @@ fpga_core #(
|
|||||||
.VENDOR(VENDOR),
|
.VENDOR(VENDOR),
|
||||||
.FAMILY(FAMILY),
|
.FAMILY(FAMILY),
|
||||||
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
|
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
|
||||||
|
// PTP configuration
|
||||||
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
// 10G/25G MAC configuration
|
// 10G/25G MAC configuration
|
||||||
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
|
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
|
||||||
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
|
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ cndm-y += cndm_irq.o
|
|||||||
cndm-y += cndm_dev.o
|
cndm-y += cndm_dev.o
|
||||||
cndm-y += cndm_netdev.o
|
cndm-y += cndm_netdev.o
|
||||||
cndm-y += cndm_ethtool.o
|
cndm-y += cndm_ethtool.o
|
||||||
|
cndm-y += cndm_ptp.o
|
||||||
cndm-y += cndm_tx.o
|
cndm-y += cndm_tx.o
|
||||||
cndm-y += cndm_rx.o
|
cndm-y += cndm_rx.o
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ Authors:
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/miscdevice.h>
|
#include <linux/miscdevice.h>
|
||||||
|
#include <linux/net_tstamp.h>
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
#include <linux/ptp_clock_kernel.h>
|
#include <linux/ptp_clock_kernel.h>
|
||||||
@@ -52,7 +53,7 @@ struct cndm_dev {
|
|||||||
u32 port_offset;
|
u32 port_offset;
|
||||||
u32 port_stride;
|
u32 port_stride;
|
||||||
|
|
||||||
void __iomem *ptp_regs;
|
void __iomem *phc_regs;
|
||||||
struct ptp_clock *ptp_clock;
|
struct ptp_clock *ptp_clock;
|
||||||
struct ptp_clock_info ptp_clock_info;
|
struct ptp_clock_info ptp_clock_info;
|
||||||
};
|
};
|
||||||
@@ -61,6 +62,7 @@ struct cndm_tx_info {
|
|||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
dma_addr_t dma_addr;
|
dma_addr_t dma_addr;
|
||||||
u32 len;
|
u32 len;
|
||||||
|
int ts_requested;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cndm_rx_info {
|
struct cndm_rx_info {
|
||||||
@@ -86,6 +88,10 @@ struct cndm_priv {
|
|||||||
struct cndm_irq *irq;
|
struct cndm_irq *irq;
|
||||||
struct notifier_block irq_nb;
|
struct notifier_block irq_nb;
|
||||||
|
|
||||||
|
struct hwtstamp_config hwts_config;
|
||||||
|
u64 ts_s;
|
||||||
|
u8 ts_valid;
|
||||||
|
|
||||||
struct cndm_tx_info *tx_info;
|
struct cndm_tx_info *tx_info;
|
||||||
struct cndm_rx_info *rx_info;
|
struct cndm_rx_info *rx_info;
|
||||||
|
|
||||||
@@ -140,7 +146,9 @@ struct cndm_desc {
|
|||||||
struct cndm_cpl {
|
struct cndm_cpl {
|
||||||
__u8 rsvd[4];
|
__u8 rsvd[4];
|
||||||
__le32 len;
|
__le32 len;
|
||||||
__u8 rsvd2[7];
|
__le32 ts_ns;
|
||||||
|
__le16 ts_fns;
|
||||||
|
__u8 ts_s;
|
||||||
__u8 phase;
|
__u8 phase;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -162,6 +170,11 @@ extern const struct file_operations cndm_fops;
|
|||||||
// cndm_ethtool.c
|
// cndm_ethtool.c
|
||||||
extern const struct ethtool_ops cndm_ethtool_ops;
|
extern const struct ethtool_ops cndm_ethtool_ops;
|
||||||
|
|
||||||
|
// cndm_ptp.c
|
||||||
|
ktime_t cndm_read_cpl_ts(struct cndm_priv *priv, const struct cndm_cpl *cpl);
|
||||||
|
void cndm_register_phc(struct cndm_dev *cdev);
|
||||||
|
void cndm_unregister_phc(struct cndm_dev *cdev);
|
||||||
|
|
||||||
// cndm_tx.c
|
// cndm_tx.c
|
||||||
int cndm_free_tx_buf(struct cndm_priv *priv);
|
int cndm_free_tx_buf(struct cndm_priv *priv);
|
||||||
int cndm_poll_tx_cq(struct napi_struct *napi, int budget);
|
int cndm_poll_tx_cq(struct napi_struct *napi, int budget);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ Authors:
|
|||||||
#include "cndm.h"
|
#include "cndm.h"
|
||||||
|
|
||||||
#include <linux/ethtool.h>
|
#include <linux/ethtool.h>
|
||||||
|
#include <linux/version.h>
|
||||||
|
|
||||||
static void cndm_get_drvinfo(struct net_device *ndev,
|
static void cndm_get_drvinfo(struct net_device *ndev,
|
||||||
struct ethtool_drvinfo *drvinfo)
|
struct ethtool_drvinfo *drvinfo)
|
||||||
@@ -24,6 +25,37 @@ static void cndm_get_drvinfo(struct net_device *ndev,
|
|||||||
strscpy(drvinfo->bus_info, dev_name(cdev->dev), sizeof(drvinfo->bus_info));
|
strscpy(drvinfo->bus_info, dev_name(cdev->dev), sizeof(drvinfo->bus_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0)
|
||||||
|
static int cndm_get_ts_info(struct net_device *ndev,
|
||||||
|
struct kernel_ethtool_ts_info *info)
|
||||||
|
#else
|
||||||
|
static int cndm_get_ts_info(struct net_device *ndev,
|
||||||
|
struct ethtool_ts_info *info)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
struct cndm_priv *priv = netdev_priv(ndev);
|
||||||
|
struct cndm_dev *cdev = priv->cdev;
|
||||||
|
|
||||||
|
ethtool_op_get_ts_info(ndev, info);
|
||||||
|
|
||||||
|
if (cdev->ptp_clock)
|
||||||
|
info->phc_index = ptp_clock_index(cdev->ptp_clock);
|
||||||
|
|
||||||
|
// if (!(priv->if_features & cndm_IF_FEATURE_PTP_TS) || !cdev->ptp_clock)
|
||||||
|
// return 0;
|
||||||
|
|
||||||
|
info->so_timestamping |= SOF_TIMESTAMPING_TX_HARDWARE |
|
||||||
|
SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE;
|
||||||
|
|
||||||
|
info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);
|
||||||
|
|
||||||
|
info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const struct ethtool_ops cndm_ethtool_ops = {
|
const struct ethtool_ops cndm_ethtool_ops = {
|
||||||
.get_drvinfo = cndm_get_drvinfo,
|
.get_drvinfo = cndm_get_drvinfo,
|
||||||
|
.get_link = ethtool_op_get_link,
|
||||||
|
.get_ts_info = cndm_get_ts_info,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ static int cndm_common_probe(struct cndm_dev *cdev)
|
|||||||
if (cdev->port_count > ARRAY_SIZE(cdev->ndev))
|
if (cdev->port_count > ARRAY_SIZE(cdev->ndev))
|
||||||
cdev->port_count = ARRAY_SIZE(cdev->ndev);
|
cdev->port_count = ARRAY_SIZE(cdev->ndev);
|
||||||
|
|
||||||
|
cndm_register_phc(cdev);
|
||||||
|
|
||||||
for (k = 0; k < cdev->port_count; k++) {
|
for (k = 0; k < cdev->port_count; k++) {
|
||||||
struct net_device *ndev;
|
struct net_device *ndev;
|
||||||
|
|
||||||
@@ -113,6 +115,8 @@ static void cndm_common_remove(struct cndm_dev *cdev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cndm_unregister_phc(cdev);
|
||||||
|
|
||||||
devlink_unregister(devlink);
|
devlink_unregister(devlink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,67 @@ static int cndm_close(struct net_device *ndev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cndm_hwtstamp_set(struct net_device *ndev, struct ifreq *ifr)
|
||||||
|
{
|
||||||
|
struct cndm_priv *priv = netdev_priv(ndev);
|
||||||
|
struct hwtstamp_config hwts_config;
|
||||||
|
|
||||||
|
if (copy_from_user(&hwts_config, ifr->ifr_data, sizeof(hwts_config)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
if (hwts_config.flags)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
switch (hwts_config.tx_type) {
|
||||||
|
case HWTSTAMP_TX_OFF:
|
||||||
|
case HWTSTAMP_TX_ON:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -ERANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (hwts_config.rx_filter) {
|
||||||
|
case HWTSTAMP_FILTER_NONE:
|
||||||
|
break;
|
||||||
|
case HWTSTAMP_FILTER_ALL:
|
||||||
|
case HWTSTAMP_FILTER_SOME:
|
||||||
|
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
|
||||||
|
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
|
||||||
|
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
|
||||||
|
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
|
||||||
|
case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
|
||||||
|
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
|
||||||
|
case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
|
||||||
|
case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
|
||||||
|
case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
|
||||||
|
case HWTSTAMP_FILTER_PTP_V2_EVENT:
|
||||||
|
case HWTSTAMP_FILTER_PTP_V2_SYNC:
|
||||||
|
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
|
||||||
|
case HWTSTAMP_FILTER_NTP_ALL:
|
||||||
|
hwts_config.rx_filter = HWTSTAMP_FILTER_ALL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -ERANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&priv->hwts_config, &hwts_config, sizeof(hwts_config));
|
||||||
|
|
||||||
|
if (copy_to_user(ifr->ifr_data, &hwts_config, sizeof(hwts_config)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cndm_hwtstamp_get(struct net_device *ndev, struct ifreq *ifr)
|
||||||
|
{
|
||||||
|
struct cndm_priv *priv = netdev_priv(ndev);
|
||||||
|
|
||||||
|
if (copy_to_user(ifr->ifr_data, &priv->hwts_config, sizeof(priv->hwts_config)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int cndm_set_mac(struct net_device *ndev, void *addr)
|
static int cndm_set_mac(struct net_device *ndev, void *addr)
|
||||||
{
|
{
|
||||||
struct sockaddr *saddr = addr;
|
struct sockaddr *saddr = addr;
|
||||||
@@ -70,12 +131,29 @@ static int cndm_set_mac(struct net_device *ndev, void *addr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cndm_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
|
||||||
|
{
|
||||||
|
switch (cmd) {
|
||||||
|
case SIOCSHWTSTAMP:
|
||||||
|
return cndm_hwtstamp_set(ndev, ifr);
|
||||||
|
case SIOCGHWTSTAMP:
|
||||||
|
return cndm_hwtstamp_get(ndev, ifr);
|
||||||
|
default:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const struct net_device_ops cndm_netdev_ops = {
|
static const struct net_device_ops cndm_netdev_ops = {
|
||||||
.ndo_open = cndm_open,
|
.ndo_open = cndm_open,
|
||||||
.ndo_stop = cndm_close,
|
.ndo_stop = cndm_close,
|
||||||
.ndo_start_xmit = cndm_start_xmit,
|
.ndo_start_xmit = cndm_start_xmit,
|
||||||
.ndo_validate_addr = eth_validate_addr,
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
.ndo_set_mac_address = cndm_set_mac,
|
.ndo_set_mac_address = cndm_set_mac,
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
|
||||||
|
.ndo_eth_ioctl = cndm_ioctl,
|
||||||
|
#else
|
||||||
|
.ndo_do_ioctl = cndm_ioctl,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static int cndm_netdev_irq(struct notifier_block *nb, unsigned long action, void *data)
|
static int cndm_netdev_irq(struct notifier_block *nb, unsigned long action, void *data)
|
||||||
@@ -124,6 +202,10 @@ struct net_device *cndm_create_netdev(struct cndm_dev *cdev, int port, void __io
|
|||||||
|
|
||||||
eth_hw_addr_random(ndev);
|
eth_hw_addr_random(ndev);
|
||||||
|
|
||||||
|
priv->hwts_config.flags = 0;
|
||||||
|
priv->hwts_config.tx_type = HWTSTAMP_TX_OFF;
|
||||||
|
priv->hwts_config.rx_filter = HWTSTAMP_FILTER_NONE;
|
||||||
|
|
||||||
ndev->netdev_ops = &cndm_netdev_ops;
|
ndev->netdev_ops = &cndm_netdev_ops;
|
||||||
ndev->ethtool_ops = &cndm_ethtool_ops;
|
ndev->ethtool_ops = &cndm_ethtool_ops;
|
||||||
|
|
||||||
|
|||||||
192
src/cndm/modules/cndm/cndm_ptp.c
Normal file
192
src/cndm/modules/cndm/cndm_ptp.c
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
// SPDX-License-Identifier: GPL
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2025 FPGA Ninja, LLC
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
- Alex Forencich
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cndm.h"
|
||||||
|
#include <linux/version.h>
|
||||||
|
|
||||||
|
ktime_t cndm_read_cpl_ts(struct cndm_priv *priv, const struct cndm_cpl *cpl)
|
||||||
|
{
|
||||||
|
struct cndm_dev *cdev = priv->cdev;
|
||||||
|
|
||||||
|
// u64 ts_s = le16_to_cpu(cpl->ts_s);
|
||||||
|
u64 ts_s = cpl->ts_s;
|
||||||
|
u32 ts_ns = le32_to_cpu(cpl->ts_ns);
|
||||||
|
|
||||||
|
if (unlikely(!priv->ts_valid || (priv->ts_s ^ ts_s) & 0xf0)) {
|
||||||
|
// seconds MSBs do not match, update cached timestamp
|
||||||
|
if (cdev->phc_regs) {
|
||||||
|
priv->ts_s = ioread32(cdev->phc_regs + 0x18);
|
||||||
|
priv->ts_s |= (u64) ioread32(cdev->phc_regs + 0x1C) << 32;
|
||||||
|
priv->ts_valid = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ts_s |= priv->ts_s & 0xfffffffffffffff0;
|
||||||
|
|
||||||
|
return ktime_set(ts_s, ts_ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cndm_phc_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||||
|
{
|
||||||
|
struct cndm_dev *cdev = container_of(ptp, struct cndm_dev, ptp_clock_info);
|
||||||
|
|
||||||
|
bool neg = false;
|
||||||
|
u64 nom_per_fns, adj;
|
||||||
|
|
||||||
|
dev_dbg(cdev->dev, "%s: scaled_ppm: %ld", __func__, scaled_ppm);
|
||||||
|
|
||||||
|
if (scaled_ppm < 0) {
|
||||||
|
neg = true;
|
||||||
|
scaled_ppm = -scaled_ppm;
|
||||||
|
}
|
||||||
|
|
||||||
|
nom_per_fns = ioread32(cdev->phc_regs + 0x70);
|
||||||
|
nom_per_fns |= (u64) ioread32(cdev->phc_regs + 0x74) << 32;
|
||||||
|
|
||||||
|
if (nom_per_fns == 0)
|
||||||
|
nom_per_fns = 0x4ULL << 32;
|
||||||
|
|
||||||
|
adj = div_u64(((nom_per_fns >> 16) * scaled_ppm) + 500000, 1000000);
|
||||||
|
|
||||||
|
if (neg)
|
||||||
|
adj = nom_per_fns - adj;
|
||||||
|
else
|
||||||
|
adj = nom_per_fns + adj;
|
||||||
|
|
||||||
|
iowrite32(adj & 0xffffffff, cdev->phc_regs + 0x78);
|
||||||
|
iowrite32(adj >> 32, cdev->phc_regs + 0x7C);
|
||||||
|
|
||||||
|
dev_dbg(cdev->dev, "%s adj: 0x%llx", __func__, adj);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cndm_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
|
||||||
|
{
|
||||||
|
struct cndm_dev *cdev = container_of(ptp, struct cndm_dev, ptp_clock_info);
|
||||||
|
|
||||||
|
ioread32(cdev->phc_regs + 0x30);
|
||||||
|
ts->tv_nsec = ioread32(cdev->phc_regs + 0x34);
|
||||||
|
ts->tv_sec = ioread32(cdev->phc_regs + 0x38);
|
||||||
|
ts->tv_sec |= (u64) ioread32(cdev->phc_regs + 0x3C) << 32;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
|
static int cndm_phc_gettimex(struct ptp_clock_info *ptp, struct timespec64 *ts, struct ptp_system_timestamp *sts)
|
||||||
|
{
|
||||||
|
struct cndm_dev *cdev = container_of(ptp, struct cndm_dev, ptp_clock_info);
|
||||||
|
|
||||||
|
ptp_read_system_prets(sts);
|
||||||
|
ioread32(cdev->phc_regs + 0x30);
|
||||||
|
ptp_read_system_postts(sts);
|
||||||
|
ts->tv_nsec = ioread32(cdev->phc_regs + 0x34);
|
||||||
|
ts->tv_sec = ioread32(cdev->phc_regs + 0x38);
|
||||||
|
ts->tv_sec |= (u64) ioread32(cdev->phc_regs + 0x3C) << 32;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int cndm_phc_settime(struct ptp_clock_info *ptp, const struct timespec64 *ts)
|
||||||
|
{
|
||||||
|
struct cndm_dev *cdev = container_of(ptp, struct cndm_dev, ptp_clock_info);
|
||||||
|
|
||||||
|
iowrite32(ts->tv_nsec, cdev->phc_regs + 0x54);
|
||||||
|
iowrite32(ts->tv_sec & 0xffffffff, cdev->phc_regs + 0x58);
|
||||||
|
iowrite32(ts->tv_sec >> 32, cdev->phc_regs + 0x5C);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cndm_phc_adjtime(struct ptp_clock_info *ptp, s64 delta)
|
||||||
|
{
|
||||||
|
struct cndm_dev *cdev = container_of(ptp, struct cndm_dev, ptp_clock_info);
|
||||||
|
struct timespec64 ts;
|
||||||
|
|
||||||
|
dev_dbg(cdev->dev, "%s: delta: %lld", __func__, delta);
|
||||||
|
|
||||||
|
if (delta > 536000000 || delta < -536000000) {
|
||||||
|
// for a large delta, perform a non-precision step
|
||||||
|
cndm_phc_gettime(ptp, &ts);
|
||||||
|
ts = timespec64_add(ts, ns_to_timespec64(delta));
|
||||||
|
cndm_phc_settime(ptp, &ts);
|
||||||
|
} else {
|
||||||
|
// for a small delta, perform a precision atomic offset
|
||||||
|
iowrite32(delta & 0xffffffff, cdev->phc_regs + 0x50);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cndm_phc_set_from_system_clock(struct ptp_clock_info *ptp)
|
||||||
|
{
|
||||||
|
struct timespec64 ts;
|
||||||
|
|
||||||
|
#ifdef ktime_get_clocktai_ts64
|
||||||
|
ktime_get_clocktai_ts64(&ts);
|
||||||
|
#else
|
||||||
|
ts = ktime_to_timespec64(ktime_get_clocktai());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cndm_phc_settime(ptp, &ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cndm_register_phc(struct cndm_dev *cdev)
|
||||||
|
{
|
||||||
|
if (cdev->ptp_clock) {
|
||||||
|
dev_warn(cdev->dev, "PTP clock already registered");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
if (cdev->port_offset == 0x10000) {
|
||||||
|
dev_info(cdev->dev, "PTP clock not present");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cdev->phc_regs = cdev->hw_addr + 0x10000; // TODO
|
||||||
|
|
||||||
|
cdev->ptp_clock_info.owner = THIS_MODULE;
|
||||||
|
snprintf(cdev->ptp_clock_info.name, sizeof(cdev->ptp_clock_info.name), "%s_phc", cdev->name);
|
||||||
|
cdev->ptp_clock_info.max_adj = 1000000000;
|
||||||
|
cdev->ptp_clock_info.n_alarm = 0;
|
||||||
|
cdev->ptp_clock_info.n_ext_ts = 0;
|
||||||
|
cdev->ptp_clock_info.n_per_out = 0;
|
||||||
|
cdev->ptp_clock_info.n_pins = 0;
|
||||||
|
cdev->ptp_clock_info.pps = 0;
|
||||||
|
cdev->ptp_clock_info.adjfine = cndm_phc_adjfine;
|
||||||
|
cdev->ptp_clock_info.adjtime = cndm_phc_adjtime;
|
||||||
|
cdev->ptp_clock_info.gettime64 = cndm_phc_gettime;
|
||||||
|
cdev->ptp_clock_info.gettimex64 = cndm_phc_gettimex;
|
||||||
|
cdev->ptp_clock_info.settime64 = cndm_phc_settime;
|
||||||
|
|
||||||
|
cdev->ptp_clock = ptp_clock_register(&cdev->ptp_clock_info, cdev->dev);
|
||||||
|
|
||||||
|
if (IS_ERR(cdev->ptp_clock)) {
|
||||||
|
dev_err(cdev->dev, "failed to register PHC");
|
||||||
|
cdev->ptp_clock = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_info(cdev->dev, "registered PHC (index %d)", ptp_clock_index(cdev->ptp_clock));
|
||||||
|
|
||||||
|
cndm_phc_set_from_system_clock(&cdev->ptp_clock_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cndm_unregister_phc(struct cndm_dev *cdev)
|
||||||
|
{
|
||||||
|
if (cdev->ptp_clock) {
|
||||||
|
ptp_clock_unregister(cdev->ptp_clock);
|
||||||
|
cdev->ptp_clock = NULL;
|
||||||
|
dev_info(cdev->dev, "unregistered PHC");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -143,15 +143,20 @@ static int cndm_process_rx_cq(struct net_device *ndev, int napi_budget)
|
|||||||
|
|
||||||
if (len < ETH_HLEN) {
|
if (len < ETH_HLEN) {
|
||||||
netdev_warn(priv->ndev, "Dropping short frame (len %d)", len);
|
netdev_warn(priv->ndev, "Dropping short frame (len %d)", len);
|
||||||
|
__free_pages(page, 0);
|
||||||
goto rx_drop;
|
goto rx_drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
skb = napi_get_frags(&priv->rx_napi);
|
skb = napi_get_frags(&priv->rx_napi);
|
||||||
if (!skb) {
|
if (!skb) {
|
||||||
netdev_err(priv->ndev, "Failed to allocate skb %d", index);
|
netdev_err(priv->ndev, "Failed to allocate skb %d", index);
|
||||||
break;
|
__free_pages(page, 0);
|
||||||
|
goto rx_drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RX hardware timestamp
|
||||||
|
skb_hwtstamps(skb)->hwtstamp = cndm_read_cpl_ts(priv, cpl);
|
||||||
|
|
||||||
__skb_fill_page_desc(skb, 0, page, 0, len);
|
__skb_fill_page_desc(skb, 0, page, 0, len);
|
||||||
|
|
||||||
skb_shinfo(skb)->nr_frags = 1;
|
skb_shinfo(skb)->nr_frags = 1;
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ int cndm_free_tx_buf(struct cndm_priv *priv)
|
|||||||
static int cndm_process_tx_cq(struct net_device *ndev, int napi_budget)
|
static int cndm_process_tx_cq(struct net_device *ndev, int napi_budget)
|
||||||
{
|
{
|
||||||
struct cndm_priv *priv = netdev_priv(ndev);
|
struct cndm_priv *priv = netdev_priv(ndev);
|
||||||
|
struct cndm_tx_info *tx_info;
|
||||||
struct cndm_cpl *cpl;
|
struct cndm_cpl *cpl;
|
||||||
|
struct skb_shared_hwtstamps hwts;
|
||||||
int done = 0;
|
int done = 0;
|
||||||
|
|
||||||
u32 cq_cons_ptr;
|
u32 cq_cons_ptr;
|
||||||
@@ -64,6 +66,14 @@ static int cndm_process_tx_cq(struct net_device *ndev, int napi_budget)
|
|||||||
dma_rmb();
|
dma_rmb();
|
||||||
|
|
||||||
index = cons_ptr & priv->txq_mask;
|
index = cons_ptr & priv->txq_mask;
|
||||||
|
tx_info = &priv->tx_info[index];
|
||||||
|
|
||||||
|
// TX hardware timestamp
|
||||||
|
if (unlikely(tx_info->ts_requested)) {
|
||||||
|
netdev_dbg(priv->ndev, "%s: TX TS requested", __func__);
|
||||||
|
hwts.hwtstamp = cndm_read_cpl_ts(priv, cpl);
|
||||||
|
skb_tstamp_tx(tx_info->skb, &hwts);
|
||||||
|
}
|
||||||
|
|
||||||
cndm_free_tx_desc(priv, index, napi_budget);
|
cndm_free_tx_desc(priv, index, napi_budget);
|
||||||
|
|
||||||
@@ -100,6 +110,7 @@ int cndm_poll_tx_cq(struct napi_struct *napi, int budget)
|
|||||||
|
|
||||||
int cndm_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
int cndm_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||||
{
|
{
|
||||||
|
struct skb_shared_info *shinfo = skb_shinfo(skb);
|
||||||
struct cndm_priv *priv = netdev_priv(ndev);
|
struct cndm_priv *priv = netdev_priv(ndev);
|
||||||
struct device *dev = priv->dev;
|
struct device *dev = priv->dev;
|
||||||
u32 index;
|
u32 index;
|
||||||
@@ -123,6 +134,14 @@ int cndm_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
|||||||
tx_desc = (struct cndm_desc *)(priv->txq_region + index*16);
|
tx_desc = (struct cndm_desc *)(priv->txq_region + index*16);
|
||||||
tx_info = &priv->tx_info[index];
|
tx_info = &priv->tx_info[index];
|
||||||
|
|
||||||
|
// TX hardware timestamp
|
||||||
|
tx_info->ts_requested = 0;
|
||||||
|
if (unlikely(shinfo->tx_flags & SKBTX_HW_TSTAMP)) {
|
||||||
|
netdev_dbg(ndev, "%s: TX TS requested", __func__);
|
||||||
|
shinfo->tx_flags |= SKBTX_IN_PROGRESS;
|
||||||
|
tx_info->ts_requested = 1;
|
||||||
|
}
|
||||||
|
|
||||||
len = skb_headlen(skb);
|
len = skb_headlen(skb);
|
||||||
|
|
||||||
dma_addr = dma_map_single(dev, skb->data, len, DMA_TO_DEVICE);
|
dma_addr = dma_map_single(dev, skb->data, len, DMA_TO_DEVICE);
|
||||||
@@ -143,6 +162,8 @@ int cndm_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
|||||||
|
|
||||||
priv->txq_prod++;
|
priv->txq_prod++;
|
||||||
|
|
||||||
|
skb_tx_timestamp(skb);
|
||||||
|
|
||||||
if (priv->txq_prod - priv->txq_cons >= 128) {
|
if (priv->txq_prod - priv->txq_cons >= 128) {
|
||||||
netdev_dbg(ndev, "TX ring full");
|
netdev_dbg(ndev, "TX ring full");
|
||||||
netif_tx_stop_queue(priv->tx_queue);
|
netif_tx_stop_queue(priv->tx_queue);
|
||||||
|
|||||||
@@ -12,5 +12,5 @@ cndm_micro_cpl_wr.sv
|
|||||||
../lib/taxi/src/axis/rtl/taxi_axis_async_fifo.f
|
../lib/taxi/src/axis/rtl/taxi_axis_async_fifo.f
|
||||||
../lib/taxi/src/axis/rtl/taxi_axis_arb_mux.f
|
../lib/taxi/src/axis/rtl/taxi_axis_arb_mux.f
|
||||||
../lib/taxi/src/axis/rtl/taxi_axis_demux.sv
|
../lib/taxi/src/axis/rtl/taxi_axis_demux.sv
|
||||||
../lib/taxi/src/ptp/rtl/taxi_ptp_td_phc.sv
|
../lib/taxi/src/ptp/rtl/taxi_ptp_td_phc_axil.f
|
||||||
../lib/taxi/src/ptp/rtl/taxi_ptp_td_leaf.sv
|
../lib/taxi/src/ptp/rtl/taxi_ptp_td_rel2tod.sv
|
||||||
|
|||||||
@@ -16,10 +16,11 @@ Authors:
|
|||||||
* Corundum-micro core logic
|
* Corundum-micro core logic
|
||||||
*/
|
*/
|
||||||
module cndm_micro_core #(
|
module cndm_micro_core #(
|
||||||
parameter PORTS = 2//,
|
parameter PORTS = 2,
|
||||||
// parameter logic PTP_TS_EN = 1'b1,
|
parameter logic PTP_TS_EN = 1'b1,
|
||||||
// parameter PTP_CLK_PER_NS_NUM = 512,
|
parameter logic PTP_TS_FMT_TOD = 1'b0,
|
||||||
// parameter PTP_CLK_PER_NS_DENOM = 165
|
parameter PTP_CLK_PER_NS_NUM = 512,
|
||||||
|
parameter PTP_CLK_PER_NS_DENOM = 165
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input wire logic clk,
|
input wire logic clk,
|
||||||
@@ -46,19 +47,20 @@ module cndm_micro_core #(
|
|||||||
/*
|
/*
|
||||||
* PTP
|
* PTP
|
||||||
*/
|
*/
|
||||||
// input wire logic ptp_clk = 1'b0,
|
input wire logic ptp_clk = 1'b0,
|
||||||
// input wire logic ptp_rst = 1'b0,
|
input wire logic ptp_rst = 1'b0,
|
||||||
// input wire logic ptp_sample_clk = 1'b0,
|
input wire logic ptp_sample_clk = 1'b0,
|
||||||
// output wire logic ptp_td_sdo,
|
input wire logic ptp_td_sdi = 1'b0,
|
||||||
// output wire logic ptp_pps,
|
output wire logic ptp_td_sdo,
|
||||||
// output wire logic ptp_pps_str,
|
output wire logic ptp_pps,
|
||||||
// output wire logic ptp_sync_locked,
|
output wire logic ptp_pps_str,
|
||||||
// output wire logic [63:0] ptp_sync_ts_rel,
|
output wire logic ptp_sync_locked,
|
||||||
// output wire logic ptp_sync_ts_rel_step,
|
output wire logic [63:0] ptp_sync_ts_rel,
|
||||||
// output wire logic [95:0] ptp_sync_ts_tod,
|
output wire logic ptp_sync_ts_rel_step,
|
||||||
// output wire logic ptp_sync_ts_tod_step,
|
output wire logic [95:0] ptp_sync_ts_tod,
|
||||||
// output wire logic ptp_sync_pps,
|
output wire logic ptp_sync_ts_tod_step,
|
||||||
// output wire logic ptp_sync_pps_str,
|
output wire logic ptp_sync_pps,
|
||||||
|
output wire logic ptp_sync_pps_str,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ethernet
|
* Ethernet
|
||||||
@@ -84,8 +86,7 @@ localparam RAM_SEG_DATA_W = dma_ram_wr.SEG_DATA_W;
|
|||||||
localparam RAM_SEG_BE_W = dma_ram_wr.SEG_BE_W;
|
localparam RAM_SEG_BE_W = dma_ram_wr.SEG_BE_W;
|
||||||
localparam RAM_SEL_W = dma_ram_wr.SEL_W;
|
localparam RAM_SEL_W = dma_ram_wr.SEL_W;
|
||||||
|
|
||||||
localparam PORT_OFFSET = 1;
|
localparam PORT_OFFSET = PTP_TS_EN ? 2 : 1;
|
||||||
// localparam PORT_OFFSET = PTP_TS_EN ? 2 : 1;
|
|
||||||
|
|
||||||
taxi_axil_if #(
|
taxi_axil_if #(
|
||||||
.DATA_W(s_axil_wr.DATA_W),
|
.DATA_W(s_axil_wr.DATA_W),
|
||||||
@@ -182,8 +183,7 @@ always_ff @(posedge clk) begin
|
|||||||
|
|
||||||
case ({s_axil_ctrl[0].araddr[15:2], 2'b00})
|
case ({s_axil_ctrl[0].araddr[15:2], 2'b00})
|
||||||
16'h0100: s_axil_rdata_reg <= PORTS; // port count
|
16'h0100: s_axil_rdata_reg <= PORTS; // port count
|
||||||
16'h0104: s_axil_rdata_reg <= 32'h00010000; // port offset
|
16'h0104: s_axil_rdata_reg <= PTP_TS_EN ? 32'h00020000 : 32'h00010000; // port offset
|
||||||
// 16'h0104: s_axil_rdata_reg <= PTP_TS_EN ? 32'h00020000 : 32'h00010000; // port offset
|
|
||||||
16'h0108: s_axil_rdata_reg <= 32'h00010000; // port stride
|
16'h0108: s_axil_rdata_reg <= 32'h00010000; // port stride
|
||||||
default: begin end
|
default: begin end
|
||||||
endcase
|
endcase
|
||||||
@@ -199,47 +199,54 @@ always_ff @(posedge clk) begin
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// if (PTP_TS_EN) begin : ptp
|
if (PTP_TS_EN) begin : ptp
|
||||||
|
|
||||||
// cndm_micro_ptp #(
|
taxi_ptp_td_phc_axil #(
|
||||||
// .PTP_CLK_PER_NS_NUM(PTP_CLK_PER_NS_NUM),
|
.PTP_CLK_PER_NS_NUM(PTP_CLK_PER_NS_NUM),
|
||||||
// .PTP_CLK_PER_NS_DENOM(PTP_CLK_PER_NS_DENOM)
|
.PTP_CLK_PER_NS_DENOM(PTP_CLK_PER_NS_DENOM)
|
||||||
// )
|
)
|
||||||
// ptp_inst (
|
ptp_inst (
|
||||||
// .clk(clk),
|
.clk(clk),
|
||||||
// .rst(rst),
|
.rst(rst),
|
||||||
|
|
||||||
// /*
|
/*
|
||||||
// * Control register interface
|
* Control register interface
|
||||||
// */
|
*/
|
||||||
// .s_axil_wr(s_axil_ctrl[1]),
|
.s_axil_wr(s_axil_ctrl[1]),
|
||||||
// .s_axil_rd(s_axil_ctrl[1]),
|
.s_axil_rd(s_axil_ctrl[1]),
|
||||||
|
|
||||||
// /*
|
/*
|
||||||
// * PTP
|
* PTP
|
||||||
// */
|
*/
|
||||||
// .ptp_clk(ptp_clk),
|
.ptp_clk(ptp_clk),
|
||||||
// .ptp_rst(ptp_rst),
|
.ptp_rst(ptp_rst),
|
||||||
// .ptp_sample_clk(ptp_sample_clk),
|
.ptp_sample_clk(ptp_sample_clk),
|
||||||
// .ptp_td_sdo(ptp_td_sdo),
|
.ptp_td_sdo(ptp_td_sdo),
|
||||||
// .ptp_pps(ptp_pps),
|
.ptp_pps(ptp_pps),
|
||||||
// .ptp_pps_str(ptp_pps_str),
|
.ptp_pps_str(ptp_pps_str),
|
||||||
// .ptp_sync_locked(ptp_sync_locked),
|
.ptp_sync_locked(ptp_sync_locked),
|
||||||
// .ptp_sync_ts_rel(ptp_sync_ts_rel),
|
.ptp_sync_ts_rel(ptp_sync_ts_rel),
|
||||||
// .ptp_sync_ts_rel_step(ptp_sync_ts_rel_step),
|
.ptp_sync_ts_rel_step(ptp_sync_ts_rel_step),
|
||||||
// .ptp_sync_ts_tod(ptp_sync_ts_tod),
|
.ptp_sync_ts_tod(ptp_sync_ts_tod),
|
||||||
// .ptp_sync_ts_tod_step(ptp_sync_ts_tod_step),
|
.ptp_sync_ts_tod_step(ptp_sync_ts_tod_step),
|
||||||
// .ptp_sync_pps(ptp_sync_pps),
|
.ptp_sync_pps(ptp_sync_pps),
|
||||||
// .ptp_sync_pps_str(ptp_sync_pps_str)
|
.ptp_sync_pps_str(ptp_sync_pps_str)
|
||||||
// );
|
);
|
||||||
|
|
||||||
// end else begin : ptp
|
end else begin : ptp
|
||||||
|
|
||||||
// assign ptp_td_sdo = 1'b0;
|
assign ptp_td_sdo = 1'b0;
|
||||||
// assign ptp_pps = 1'b0;
|
assign ptp_pps = 1'b0;
|
||||||
// assign ptp_pps_str = 1'b0;
|
assign ptp_pps_str = 1'b0;
|
||||||
|
assign ptp_sync_locked = 1'b0;
|
||||||
|
assign ptp_sync_ts_rel = '0;
|
||||||
|
assign ptp_sync_ts_rel_step = 1'b0;
|
||||||
|
assign ptp_sync_ts_tod = '0;
|
||||||
|
assign ptp_sync_ts_tod_step = 1'b0;
|
||||||
|
assign ptp_sync_pps = 1'b0;
|
||||||
|
assign ptp_sync_pps_str = 1'b0;
|
||||||
|
|
||||||
// end
|
end
|
||||||
|
|
||||||
taxi_dma_desc_if #(
|
taxi_dma_desc_if #(
|
||||||
.SRC_ADDR_W(dma_rd_desc_req.SRC_ADDR_W),
|
.SRC_ADDR_W(dma_rd_desc_req.SRC_ADDR_W),
|
||||||
@@ -325,7 +332,8 @@ dma_mux_inst (
|
|||||||
for (genvar p = 0; p < PORTS; p = p + 1) begin : port
|
for (genvar p = 0; p < PORTS; p = p + 1) begin : port
|
||||||
|
|
||||||
cndm_micro_port #(
|
cndm_micro_port #(
|
||||||
// .PTP_TS_EN(PTP_TS_EN)
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD)
|
||||||
)
|
)
|
||||||
port_inst (
|
port_inst (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
@@ -349,6 +357,13 @@ for (genvar p = 0; p < PORTS; p = p + 1) begin : port
|
|||||||
|
|
||||||
.irq(irq[p]),
|
.irq(irq[p]),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP
|
||||||
|
*/
|
||||||
|
.ptp_clk(ptp_clk),
|
||||||
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_td_sdi(ptp_td_sdo),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ethernet
|
* Ethernet
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2,4 +2,5 @@ cndm_micro_pcie_us.sv
|
|||||||
cndm_micro_core.f
|
cndm_micro_core.f
|
||||||
../lib/taxi/src/pcie/rtl/taxi_pcie_us_axil_master.sv
|
../lib/taxi/src/pcie/rtl/taxi_pcie_us_axil_master.sv
|
||||||
../lib/taxi/src/pcie/rtl/taxi_pcie_us_msi.sv
|
../lib/taxi/src/pcie/rtl/taxi_pcie_us_msi.sv
|
||||||
|
../lib/taxi/src/pcie/rtl/taxi_pcie_us_cfg.sv
|
||||||
../lib/taxi/src/dma/rtl/taxi_dma_if_pcie_us.f
|
../lib/taxi/src/dma/rtl/taxi_dma_if_pcie_us.f
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ module cndm_micro_pcie_us #(
|
|||||||
// device family
|
// device family
|
||||||
parameter string FAMILY = "virtexuplus",
|
parameter string FAMILY = "virtexuplus",
|
||||||
parameter PORTS = 2,
|
parameter PORTS = 2,
|
||||||
|
parameter logic PTP_TS_EN = 1'b1,
|
||||||
|
parameter logic PTP_TS_FMT_TOD = 1'b0,
|
||||||
|
parameter PTP_CLK_PER_NS_NUM = 512,
|
||||||
|
parameter PTP_CLK_PER_NS_DENOM = 165,
|
||||||
parameter RQ_SEQ_NUM_W = 6,
|
parameter RQ_SEQ_NUM_W = 6,
|
||||||
parameter BAR0_APERTURE = 24
|
parameter BAR0_APERTURE = 24
|
||||||
)
|
)
|
||||||
@@ -80,6 +84,24 @@ module cndm_micro_pcie_us #(
|
|||||||
output wire [7:0] cfg_interrupt_msi_tph_st_tag,
|
output wire [7:0] cfg_interrupt_msi_tph_st_tag,
|
||||||
output wire [7:0] cfg_interrupt_msi_function_number,
|
output wire [7:0] cfg_interrupt_msi_function_number,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP
|
||||||
|
*/
|
||||||
|
input wire logic ptp_clk = 1'b0,
|
||||||
|
input wire logic ptp_rst = 1'b0,
|
||||||
|
input wire logic ptp_sample_clk = 1'b0,
|
||||||
|
input wire logic ptp_td_sdi = 1'b0,
|
||||||
|
output wire logic ptp_td_sdo,
|
||||||
|
output wire logic ptp_pps,
|
||||||
|
output wire logic ptp_pps_str,
|
||||||
|
output wire logic ptp_sync_locked,
|
||||||
|
output wire logic [63:0] ptp_sync_ts_rel,
|
||||||
|
output wire logic ptp_sync_ts_rel_step,
|
||||||
|
output wire logic [95:0] ptp_sync_ts_tod,
|
||||||
|
output wire logic ptp_sync_ts_tod_step,
|
||||||
|
output wire logic ptp_sync_pps,
|
||||||
|
output wire logic ptp_sync_pps_str,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ethernet
|
* Ethernet
|
||||||
*/
|
*/
|
||||||
@@ -175,6 +197,8 @@ logic [7:0] pcie_tx_fc_nph_av;
|
|||||||
logic [7:0] pcie_tx_fc_ph_av;
|
logic [7:0] pcie_tx_fc_ph_av;
|
||||||
logic [11:0] pcie_tx_fc_pd_av;
|
logic [11:0] pcie_tx_fc_pd_av;
|
||||||
|
|
||||||
|
logic ext_tag_en;
|
||||||
|
|
||||||
assign cfg_fc_sel = 3'b100;
|
assign cfg_fc_sel = 3'b100;
|
||||||
|
|
||||||
taxi_dma_desc_if #(
|
taxi_dma_desc_if #(
|
||||||
@@ -333,7 +357,7 @@ dma_if_inst (
|
|||||||
*/
|
*/
|
||||||
.read_enable(1'b1),
|
.read_enable(1'b1),
|
||||||
.write_enable(1'b1),
|
.write_enable(1'b1),
|
||||||
.ext_tag_en(1'b0), // TODO
|
.ext_tag_en(ext_tag_en),
|
||||||
.rcb_128b(cfg_rcb_status[0]),
|
.rcb_128b(cfg_rcb_status[0]),
|
||||||
.requester_id('0),
|
.requester_id('0),
|
||||||
.requester_id_en(1'b0),
|
.requester_id_en(1'b0),
|
||||||
@@ -383,6 +407,36 @@ dma_if_inst (
|
|||||||
.stat_wr_tx_stall(stat_wr_tx_stall)
|
.stat_wr_tx_stall(stat_wr_tx_stall)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
taxi_pcie_us_cfg #(
|
||||||
|
.PF_COUNT(1),
|
||||||
|
.VF_COUNT(0),
|
||||||
|
.VF_OFFSET(m_axis_pcie_rq.USER_W == 60 ? 64 : 4),
|
||||||
|
.PCIE_CAP_OFFSET(m_axis_pcie_rq.USER_W == 60 ? 12'h0C0 : 12'h070)
|
||||||
|
)
|
||||||
|
cfg_inst (
|
||||||
|
.clk(pcie_clk),
|
||||||
|
.rst(pcie_rst),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configuration outputs
|
||||||
|
*/
|
||||||
|
.ext_tag_en(ext_tag_en),
|
||||||
|
.max_read_req_size(),
|
||||||
|
.max_payload_size(),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interface to Ultrascale PCIe IP core
|
||||||
|
*/
|
||||||
|
.cfg_mgmt_addr(cfg_mgmt_addr),
|
||||||
|
.cfg_mgmt_function_number(cfg_mgmt_function_number),
|
||||||
|
.cfg_mgmt_write(cfg_mgmt_write),
|
||||||
|
.cfg_mgmt_write_data(cfg_mgmt_write_data),
|
||||||
|
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
|
||||||
|
.cfg_mgmt_read(cfg_mgmt_read),
|
||||||
|
.cfg_mgmt_read_data(cfg_mgmt_read_data),
|
||||||
|
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done)
|
||||||
|
);
|
||||||
|
|
||||||
wire [PORTS-1:0] irq;
|
wire [PORTS-1:0] irq;
|
||||||
wire [31:0] msi_irq = 32'(irq);
|
wire [31:0] msi_irq = 32'(irq);
|
||||||
|
|
||||||
@@ -423,7 +477,11 @@ msi_inst (
|
|||||||
);
|
);
|
||||||
|
|
||||||
cndm_micro_core #(
|
cndm_micro_core #(
|
||||||
.PORTS(PORTS)
|
.PORTS(PORTS),
|
||||||
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
||||||
|
.PTP_CLK_PER_NS_NUM(PTP_CLK_PER_NS_NUM),
|
||||||
|
.PTP_CLK_PER_NS_DENOM(PTP_CLK_PER_NS_DENOM)
|
||||||
)
|
)
|
||||||
core_inst (
|
core_inst (
|
||||||
.clk(pcie_clk),
|
.clk(pcie_clk),
|
||||||
@@ -447,6 +505,24 @@ core_inst (
|
|||||||
|
|
||||||
.irq(irq),
|
.irq(irq),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP
|
||||||
|
*/
|
||||||
|
.ptp_clk(ptp_clk),
|
||||||
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_sample_clk(ptp_sample_clk),
|
||||||
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
.ptp_td_sdo(ptp_td_sdo),
|
||||||
|
.ptp_pps(ptp_pps),
|
||||||
|
.ptp_pps_str(ptp_pps_str),
|
||||||
|
.ptp_sync_locked(ptp_sync_locked),
|
||||||
|
.ptp_sync_ts_rel(ptp_sync_ts_rel),
|
||||||
|
.ptp_sync_ts_rel_step(ptp_sync_ts_rel_step),
|
||||||
|
.ptp_sync_ts_tod(ptp_sync_ts_tod),
|
||||||
|
.ptp_sync_ts_tod_step(ptp_sync_ts_tod_step),
|
||||||
|
.ptp_sync_pps(ptp_sync_pps),
|
||||||
|
.ptp_sync_pps_str(ptp_sync_pps_str),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ethernet
|
* Ethernet
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ Authors:
|
|||||||
* Corundum-micro port module
|
* Corundum-micro port module
|
||||||
*/
|
*/
|
||||||
module cndm_micro_port #(
|
module cndm_micro_port #(
|
||||||
parameter logic PTP_TS_EN = 1'b1
|
parameter logic PTP_TS_EN = 1'b1,
|
||||||
|
parameter logic PTP_TS_FMT_TOD = 1'b0
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input wire logic clk,
|
input wire logic clk,
|
||||||
@@ -40,6 +41,13 @@ module cndm_micro_port #(
|
|||||||
|
|
||||||
output wire logic irq,
|
output wire logic irq,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP
|
||||||
|
*/
|
||||||
|
input wire logic ptp_clk = 1'b0,
|
||||||
|
input wire logic ptp_rst = 1'b0,
|
||||||
|
input wire logic ptp_td_sdi = 1'b0,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ethernet
|
* Ethernet
|
||||||
*/
|
*/
|
||||||
@@ -454,7 +462,7 @@ taxi_axis_if #(
|
|||||||
.KEEP_EN(mac_axis_tx_cpl.KEEP_EN),
|
.KEEP_EN(mac_axis_tx_cpl.KEEP_EN),
|
||||||
.KEEP_W(mac_axis_tx_cpl.KEEP_W),
|
.KEEP_W(mac_axis_tx_cpl.KEEP_W),
|
||||||
.USER_EN(1),
|
.USER_EN(1),
|
||||||
.USER_W(1)
|
.USER_W(mac_axis_tx_cpl.USER_W)
|
||||||
)
|
)
|
||||||
mac_tx_cpl_int();
|
mac_tx_cpl_int();
|
||||||
|
|
||||||
@@ -507,12 +515,20 @@ tx_cpl_fifo (
|
|||||||
);
|
);
|
||||||
|
|
||||||
cndm_micro_tx #(
|
cndm_micro_tx #(
|
||||||
.PTP_TS_EN(PTP_TS_EN)
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD)
|
||||||
)
|
)
|
||||||
tx_inst (
|
tx_inst (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP
|
||||||
|
*/
|
||||||
|
.ptp_clk(ptp_clk),
|
||||||
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DMA
|
* DMA
|
||||||
*/
|
*/
|
||||||
@@ -530,7 +546,7 @@ tx_inst (
|
|||||||
taxi_axis_if #(
|
taxi_axis_if #(
|
||||||
.DATA_W(mac_axis_rx.DATA_W),
|
.DATA_W(mac_axis_rx.DATA_W),
|
||||||
.USER_EN(1),
|
.USER_EN(1),
|
||||||
.USER_W(1)
|
.USER_W(mac_axis_rx.USER_W)
|
||||||
) mac_rx_int();
|
) mac_rx_int();
|
||||||
|
|
||||||
taxi_axis_async_fifo #(
|
taxi_axis_async_fifo #(
|
||||||
@@ -582,12 +598,20 @@ rx_fifo (
|
|||||||
);
|
);
|
||||||
|
|
||||||
cndm_micro_rx #(
|
cndm_micro_rx #(
|
||||||
.PTP_TS_EN(PTP_TS_EN)
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD)
|
||||||
)
|
)
|
||||||
rx_inst (
|
rx_inst (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP
|
||||||
|
*/
|
||||||
|
.ptp_clk(ptp_clk),
|
||||||
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DMA
|
* DMA
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -16,12 +16,20 @@ Authors:
|
|||||||
* Corundum-micro receive datapath
|
* Corundum-micro receive datapath
|
||||||
*/
|
*/
|
||||||
module cndm_micro_rx #(
|
module cndm_micro_rx #(
|
||||||
parameter logic PTP_TS_EN = 1'b1
|
parameter logic PTP_TS_EN = 1'b1,
|
||||||
|
parameter logic PTP_TS_FMT_TOD = 1'b0
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input wire logic clk,
|
input wire logic clk,
|
||||||
input wire logic rst,
|
input wire logic rst,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP
|
||||||
|
*/
|
||||||
|
input wire logic ptp_clk = 1'b0,
|
||||||
|
input wire logic ptp_rst = 1'b0,
|
||||||
|
input wire logic ptp_td_sdi = 1'b0,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DMA
|
* DMA
|
||||||
*/
|
*/
|
||||||
@@ -50,7 +58,7 @@ taxi_dma_desc_if #(
|
|||||||
.ID_EN(0),
|
.ID_EN(0),
|
||||||
.DEST_EN(0),
|
.DEST_EN(0),
|
||||||
.USER_EN(1),
|
.USER_EN(1),
|
||||||
.USER_W(1)
|
.USER_W(rx_data.USER_W)
|
||||||
) dma_desc();
|
) dma_desc();
|
||||||
|
|
||||||
localparam [2:0]
|
localparam [2:0]
|
||||||
@@ -65,6 +73,84 @@ logic desc_req_reg = 1'b0;
|
|||||||
|
|
||||||
assign desc_req = desc_req_reg;
|
assign desc_req = desc_req_reg;
|
||||||
|
|
||||||
|
wire [95:0] rx_ptp_ts;
|
||||||
|
wire rx_ptp_ts_valid;
|
||||||
|
|
||||||
|
if (PTP_TS_EN) begin
|
||||||
|
|
||||||
|
if (PTP_TS_FMT_TOD) begin
|
||||||
|
|
||||||
|
assign rx_ptp_ts = dma_desc.sts_user[dma_desc.USER_W-1:1];
|
||||||
|
assign rx_ptp_ts_valid = dma_desc.sts_valid;
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
taxi_axis_if #(
|
||||||
|
.DATA_W(48),
|
||||||
|
.KEEP_EN(0),
|
||||||
|
.KEEP_W(1),
|
||||||
|
.STRB_EN(0),
|
||||||
|
.LAST_EN(0),
|
||||||
|
.ID_EN(0),
|
||||||
|
.DEST_EN(0),
|
||||||
|
.USER_EN(1),
|
||||||
|
.USER_W(1)
|
||||||
|
) ptp_ts_rel();
|
||||||
|
|
||||||
|
assign ptp_ts_rel.tdata = dma_desc.sts_user[dma_desc.USER_W-1:1];
|
||||||
|
assign ptp_ts_rel.tuser = dma_desc.sts_user[0];
|
||||||
|
assign ptp_ts_rel.tvalid = dma_desc.sts_valid;
|
||||||
|
|
||||||
|
taxi_axis_if #(
|
||||||
|
.DATA_W(96),
|
||||||
|
.KEEP_EN(0),
|
||||||
|
.KEEP_W(1),
|
||||||
|
.STRB_EN(0),
|
||||||
|
.LAST_EN(0),
|
||||||
|
.ID_EN(0),
|
||||||
|
.DEST_EN(0),
|
||||||
|
.USER_EN(1),
|
||||||
|
.USER_W(1)
|
||||||
|
) ptp_ts_tod();
|
||||||
|
|
||||||
|
assign rx_ptp_ts = ptp_ts_tod.tdata;
|
||||||
|
assign rx_ptp_ts_valid = ptp_ts_tod.tvalid;
|
||||||
|
|
||||||
|
taxi_ptp_td_rel2tod #(
|
||||||
|
.TS_FNS_W(16),
|
||||||
|
.TS_REL_NS_W(ptp_ts_rel.DATA_W-16),
|
||||||
|
.TS_TOD_S_W(48),
|
||||||
|
.TS_REL_W(ptp_ts_rel.DATA_W),
|
||||||
|
.TS_TOD_W(96),
|
||||||
|
.TD_SDI_PIPELINE(2)
|
||||||
|
)
|
||||||
|
rel2tod_inst (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP clock interface
|
||||||
|
*/
|
||||||
|
.ptp_clk(ptp_clk),
|
||||||
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timestamp conversion
|
||||||
|
*/
|
||||||
|
.s_axis_ts_rel(ptp_ts_rel),
|
||||||
|
.m_axis_ts_tod(ptp_ts_tod)
|
||||||
|
);
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
assign rx_ptp_ts = '0;
|
||||||
|
assign rx_ptp_ts_valid = 1'b0;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
desc_req_reg <= 1'b0;
|
desc_req_reg <= 1'b0;
|
||||||
|
|
||||||
@@ -104,6 +190,12 @@ always_ff @(posedge clk) begin
|
|||||||
axis_cpl.tlast <= 1'b1;
|
axis_cpl.tlast <= 1'b1;
|
||||||
axis_cpl.tvalid <= axis_cpl.tvalid && !axis_cpl.tready;
|
axis_cpl.tvalid <= axis_cpl.tvalid && !axis_cpl.tready;
|
||||||
|
|
||||||
|
if (rx_ptp_ts_valid) begin
|
||||||
|
axis_cpl.tdata[127:112] <= rx_ptp_ts[63:48]; // sec
|
||||||
|
axis_cpl.tdata[95:64] <= rx_ptp_ts[47:16]; // ns
|
||||||
|
axis_cpl.tdata[111:96] <= rx_ptp_ts[15:0]; // fns
|
||||||
|
end
|
||||||
|
|
||||||
case (state_reg)
|
case (state_reg)
|
||||||
STATE_IDLE: begin
|
STATE_IDLE: begin
|
||||||
dma_desc.req_valid <= 1'b1;
|
dma_desc.req_valid <= 1'b1;
|
||||||
|
|||||||
@@ -16,12 +16,20 @@ Authors:
|
|||||||
* Corundum-micro transmit datapath
|
* Corundum-micro transmit datapath
|
||||||
*/
|
*/
|
||||||
module cndm_micro_tx #(
|
module cndm_micro_tx #(
|
||||||
parameter logic PTP_TS_EN = 1'b1
|
parameter logic PTP_TS_EN = 1'b1,
|
||||||
|
parameter logic PTP_TS_FMT_TOD = 1'b0
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input wire logic clk,
|
input wire logic clk,
|
||||||
input wire logic rst,
|
input wire logic rst,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP
|
||||||
|
*/
|
||||||
|
input wire logic ptp_clk = 1'b0,
|
||||||
|
input wire logic ptp_rst = 1'b0,
|
||||||
|
input wire logic ptp_td_sdi = 1'b0,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DMA
|
* DMA
|
||||||
*/
|
*/
|
||||||
@@ -66,6 +74,68 @@ logic desc_req_reg = 1'b0;
|
|||||||
|
|
||||||
assign desc_req = desc_req_reg;
|
assign desc_req = desc_req_reg;
|
||||||
|
|
||||||
|
wire [95:0] tx_cpl_ptp_ts;
|
||||||
|
wire tx_cpl_valid;
|
||||||
|
|
||||||
|
if (PTP_TS_EN) begin
|
||||||
|
|
||||||
|
if (PTP_TS_FMT_TOD) begin
|
||||||
|
|
||||||
|
assign tx_cpl_ptp_ts = tx_cpl.tdata;
|
||||||
|
assign tx_cpl_valid = tx_cpl.tvalid;
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
taxi_axis_if #(
|
||||||
|
.DATA_W(96),
|
||||||
|
.KEEP_EN(0),
|
||||||
|
.KEEP_W(1),
|
||||||
|
.STRB_EN(0),
|
||||||
|
.LAST_EN(0),
|
||||||
|
.ID_EN(0),
|
||||||
|
.DEST_EN(0),
|
||||||
|
.USER_EN(1),
|
||||||
|
.USER_W(1)
|
||||||
|
) tx_cpl_tod();
|
||||||
|
|
||||||
|
assign tx_cpl_ptp_ts = tx_cpl_tod.tdata;
|
||||||
|
assign tx_cpl_valid = tx_cpl_tod.tvalid;
|
||||||
|
|
||||||
|
taxi_ptp_td_rel2tod #(
|
||||||
|
.TS_FNS_W(16),
|
||||||
|
.TS_REL_NS_W(tx_cpl.DATA_W-16),
|
||||||
|
.TS_TOD_S_W(48),
|
||||||
|
.TS_REL_W(tx_cpl.DATA_W),
|
||||||
|
.TS_TOD_W(96),
|
||||||
|
.TD_SDI_PIPELINE(2)
|
||||||
|
)
|
||||||
|
rel2tod_inst (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP clock interface
|
||||||
|
*/
|
||||||
|
.ptp_clk(ptp_clk),
|
||||||
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timestamp conversion
|
||||||
|
*/
|
||||||
|
.s_axis_ts_rel(tx_cpl),
|
||||||
|
.m_axis_ts_tod(tx_cpl_tod)
|
||||||
|
);
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
assign tx_cpl_ptp_ts = '0;
|
||||||
|
assign tx_cpl_valid = tx_cpl.tvalid;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
desc_req_reg <= 1'b0;
|
desc_req_reg <= 1'b0;
|
||||||
|
|
||||||
@@ -118,6 +188,8 @@ always_ff @(posedge clk) begin
|
|||||||
dma_desc.req_src_addr <= '0;
|
dma_desc.req_src_addr <= '0;
|
||||||
dma_desc.req_len <= axis_desc.tdata[47:32];
|
dma_desc.req_len <= axis_desc.tdata[47:32];
|
||||||
|
|
||||||
|
axis_cpl.tdata[47:32] <= axis_desc.tdata[47:32];
|
||||||
|
|
||||||
if (axis_desc.tvalid && axis_desc.tready) begin
|
if (axis_desc.tvalid && axis_desc.tready) begin
|
||||||
if (axis_desc.tuser) begin
|
if (axis_desc.tuser) begin
|
||||||
// failed to read desc
|
// failed to read desc
|
||||||
@@ -135,7 +207,10 @@ always_ff @(posedge clk) begin
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
STATE_TX_DATA: begin
|
STATE_TX_DATA: begin
|
||||||
if (dma_desc.sts_valid) begin
|
axis_cpl.tdata[127:112] <= tx_cpl_ptp_ts[63:48]; // sec
|
||||||
|
axis_cpl.tdata[95:64] <= tx_cpl_ptp_ts[47:16]; // ns
|
||||||
|
axis_cpl.tdata[111:96] <= tx_cpl_ptp_ts[15:0]; // fns
|
||||||
|
if (tx_cpl_valid) begin
|
||||||
axis_cpl.tvalid <= 1'b1;
|
axis_cpl.tvalid <= 1'b1;
|
||||||
state_reg <= STATE_IDLE;
|
state_reg <= STATE_IDLE;
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -39,6 +39,10 @@ export PARAM_SIM := "1'b1"
|
|||||||
export PARAM_VENDOR := "\"XILINX\""
|
export PARAM_VENDOR := "\"XILINX\""
|
||||||
export PARAM_FAMILY := "\"virtexuplus\""
|
export PARAM_FAMILY := "\"virtexuplus\""
|
||||||
export PARAM_PORTS := 2
|
export PARAM_PORTS := 2
|
||||||
|
export PARAM_PTP_TS_EN := 1
|
||||||
|
export PARAM_PTP_TS_FMT_TOD := 0
|
||||||
|
export PARAM_PTP_CLK_PER_NS_NUM := 512
|
||||||
|
export PARAM_PTP_CLK_PER_NS_DENOM := 165
|
||||||
export PARAM_MAC_DATA_W := 32
|
export PARAM_MAC_DATA_W := 32
|
||||||
export PARAM_AXIS_PCIE_DATA_W := 256
|
export PARAM_AXIS_PCIE_DATA_W := 256
|
||||||
export PARAM_BAR0_APERTURE := 24
|
export PARAM_BAR0_APERTURE := 24
|
||||||
|
|||||||
@@ -140,14 +140,14 @@ class TB:
|
|||||||
# pcie_tfc_npd_av=dut.pcie_tfc_npd_av,
|
# pcie_tfc_npd_av=dut.pcie_tfc_npd_av,
|
||||||
|
|
||||||
# Configuration Management Interface
|
# Configuration Management Interface
|
||||||
# cfg_mgmt_addr=dut.cfg_mgmt_addr,
|
cfg_mgmt_addr=dut.cfg_mgmt_addr,
|
||||||
# cfg_mgmt_function_number=dut.cfg_mgmt_function_number,
|
cfg_mgmt_function_number=dut.cfg_mgmt_function_number,
|
||||||
# cfg_mgmt_write=dut.cfg_mgmt_write,
|
cfg_mgmt_write=dut.cfg_mgmt_write,
|
||||||
# cfg_mgmt_write_data=dut.cfg_mgmt_write_data,
|
cfg_mgmt_write_data=dut.cfg_mgmt_write_data,
|
||||||
# cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable,
|
cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable,
|
||||||
# cfg_mgmt_read=dut.cfg_mgmt_read,
|
cfg_mgmt_read=dut.cfg_mgmt_read,
|
||||||
# cfg_mgmt_read_data=dut.cfg_mgmt_read_data,
|
cfg_mgmt_read_data=dut.cfg_mgmt_read_data,
|
||||||
# cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done,
|
cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done,
|
||||||
# cfg_mgmt_debug_access
|
# cfg_mgmt_debug_access
|
||||||
|
|
||||||
# Configuration Status Interface
|
# Configuration Status Interface
|
||||||
@@ -271,6 +271,10 @@ class TB:
|
|||||||
|
|
||||||
self.dev.functions[0].configure_bar(0, 2**int(dut.uut.axil_ctrl_bar.ADDR_W))
|
self.dev.functions[0].configure_bar(0, 2**int(dut.uut.axil_ctrl_bar.ADDR_W))
|
||||||
|
|
||||||
|
# PTP
|
||||||
|
cocotb.start_soon(Clock(dut.ptp_clk, 3.102, units="ns").start())
|
||||||
|
cocotb.start_soon(Clock(dut.ptp_sample_clk, 8, units="ns").start())
|
||||||
|
|
||||||
# Ethernet
|
# Ethernet
|
||||||
self.port_mac = []
|
self.port_mac = []
|
||||||
|
|
||||||
@@ -291,6 +295,9 @@ class TB:
|
|||||||
rx_clk=dut.mac_rx_clk[k],
|
rx_clk=dut.mac_rx_clk[k],
|
||||||
rx_rst=dut.mac_rx_rst[k],
|
rx_rst=dut.mac_rx_rst[k],
|
||||||
rx_bus=AxiStreamBus.from_entity(dut.mac_axis_rx[k]),
|
rx_bus=AxiStreamBus.from_entity(dut.mac_axis_rx[k]),
|
||||||
|
tx_ptp_time=dut.mac_axis_tx[k].tid, # TODO
|
||||||
|
tx_ptp_ts=dut.mac_axis_tx_cpl[k].tdata, # TODO
|
||||||
|
tx_ptp_ts_valid=dut.mac_axis_tx_cpl[k].tvalid, # TODO
|
||||||
ifg=12, speed=eth_speed
|
ifg=12, speed=eth_speed
|
||||||
)
|
)
|
||||||
self.port_mac.append(mac)
|
self.port_mac.append(mac)
|
||||||
@@ -347,6 +354,8 @@ class TB:
|
|||||||
|
|
||||||
async def init(self):
|
async def init(self):
|
||||||
|
|
||||||
|
self.dut.ptp_rst.setimmediatevalue(0)
|
||||||
|
|
||||||
for mac in self.port_mac:
|
for mac in self.port_mac:
|
||||||
mac.rx.reset.setimmediatevalue(0)
|
mac.rx.reset.setimmediatevalue(0)
|
||||||
mac.tx.reset.setimmediatevalue(0)
|
mac.tx.reset.setimmediatevalue(0)
|
||||||
@@ -357,6 +366,8 @@ class TB:
|
|||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.pcie_clk)
|
await RisingEdge(self.dut.pcie_clk)
|
||||||
|
|
||||||
|
self.dut.ptp_rst.value = 1
|
||||||
|
|
||||||
for mac in self.port_mac:
|
for mac in self.port_mac:
|
||||||
mac.rx.reset.value = 1
|
mac.rx.reset.value = 1
|
||||||
mac.tx.reset.value = 1
|
mac.tx.reset.value = 1
|
||||||
@@ -364,6 +375,8 @@ class TB:
|
|||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.pcie_clk)
|
await RisingEdge(self.dut.pcie_clk)
|
||||||
|
|
||||||
|
self.dut.ptp_rst.value = 0
|
||||||
|
|
||||||
for mac in self.port_mac:
|
for mac in self.port_mac:
|
||||||
mac.rx.reset.value = 0
|
mac.rx.reset.value = 0
|
||||||
mac.tx.reset.value = 0
|
mac.tx.reset.value = 0
|
||||||
@@ -499,6 +512,10 @@ def test_cndm_micro_pcie_us(request, mac_data_w):
|
|||||||
parameters['VENDOR'] = "\"XILINX\""
|
parameters['VENDOR'] = "\"XILINX\""
|
||||||
parameters['FAMILY'] = "\"virtexuplus\""
|
parameters['FAMILY'] = "\"virtexuplus\""
|
||||||
parameters['PORTS'] = 2
|
parameters['PORTS'] = 2
|
||||||
|
parameters["PTP_TS_EN"] = 1
|
||||||
|
parameters["PTP_TS_FMT_TOD"] = 0
|
||||||
|
parameters["PTP_CLK_PER_NS_NUM"] = 512
|
||||||
|
parameters["PTP_CLK_PER_NS_DENOM"] = 165
|
||||||
parameters['MAC_DATA_W'] = mac_data_w
|
parameters['MAC_DATA_W'] = mac_data_w
|
||||||
parameters['AXIS_PCIE_DATA_W'] = 256
|
parameters['AXIS_PCIE_DATA_W'] = 256
|
||||||
parameters['BAR0_APERTURE'] = 24
|
parameters['BAR0_APERTURE'] = 24
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ module test_cndm_micro_pcie_us #
|
|||||||
parameter string VENDOR = "XILINX",
|
parameter string VENDOR = "XILINX",
|
||||||
parameter string FAMILY = "virtexuplus",
|
parameter string FAMILY = "virtexuplus",
|
||||||
parameter PORTS = 2,
|
parameter PORTS = 2,
|
||||||
|
parameter logic PTP_TS_EN = 1'b1,
|
||||||
|
parameter logic PTP_TS_FMT_TOD = 1'b0,
|
||||||
|
parameter PTP_CLK_PER_NS_NUM = 512,
|
||||||
|
parameter PTP_CLK_PER_NS_DENOM = 165,
|
||||||
parameter MAC_DATA_W = 32,
|
parameter MAC_DATA_W = 32,
|
||||||
parameter AXIS_PCIE_DATA_W = 256,
|
parameter AXIS_PCIE_DATA_W = 256,
|
||||||
parameter AXIS_PCIE_RC_USER_W = AXIS_PCIE_DATA_W < 512 ? 75 : 161,
|
parameter AXIS_PCIE_RC_USER_W = AXIS_PCIE_DATA_W < 512 ? 75 : 161,
|
||||||
@@ -33,6 +37,8 @@ module test_cndm_micro_pcie_us #
|
|||||||
)
|
)
|
||||||
();
|
();
|
||||||
|
|
||||||
|
localparam PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 48;
|
||||||
|
|
||||||
localparam AXIS_PCIE_KEEP_W = (AXIS_PCIE_DATA_W/32);
|
localparam AXIS_PCIE_KEEP_W = (AXIS_PCIE_DATA_W/32);
|
||||||
localparam RQ_SEQ_NUM_W = AXIS_PCIE_RQ_USER_W == 60 ? 4 : 6;
|
localparam RQ_SEQ_NUM_W = AXIS_PCIE_RQ_USER_W == 60 ? 4 : 6;
|
||||||
|
|
||||||
@@ -122,6 +128,20 @@ logic [1:0] cfg_interrupt_msi_tph_type;
|
|||||||
logic [7:0] cfg_interrupt_msi_tph_st_tag;
|
logic [7:0] cfg_interrupt_msi_tph_st_tag;
|
||||||
logic [7:0] cfg_interrupt_msi_function_number;
|
logic [7:0] cfg_interrupt_msi_function_number;
|
||||||
|
|
||||||
|
logic ptp_rst;
|
||||||
|
logic ptp_clk;
|
||||||
|
logic ptp_sample_clk;
|
||||||
|
logic ptp_td_sdo;
|
||||||
|
logic ptp_pps;
|
||||||
|
logic ptp_pps_str;
|
||||||
|
logic ptp_sync_locked;
|
||||||
|
logic [63:0] ptp_sync_ts_rel;
|
||||||
|
logic ptp_sync_ts_rel_step;
|
||||||
|
logic [95:0] ptp_sync_ts_tod;
|
||||||
|
logic ptp_sync_ts_tod_step;
|
||||||
|
logic ptp_sync_pps;
|
||||||
|
logic ptp_sync_pps_str;
|
||||||
|
|
||||||
logic mac_tx_clk[PORTS];
|
logic mac_tx_clk[PORTS];
|
||||||
logic mac_tx_rst[PORTS];
|
logic mac_tx_rst[PORTS];
|
||||||
|
|
||||||
@@ -136,7 +156,7 @@ logic mac_rx_clk[PORTS];
|
|||||||
logic mac_rx_rst[PORTS];
|
logic mac_rx_rst[PORTS];
|
||||||
|
|
||||||
taxi_axis_if #(
|
taxi_axis_if #(
|
||||||
.DATA_W(96),
|
.DATA_W(PTP_TS_W),
|
||||||
.KEEP_W(1),
|
.KEEP_W(1),
|
||||||
.ID_W(8)
|
.ID_W(8)
|
||||||
) mac_axis_tx_cpl[PORTS]();
|
) mac_axis_tx_cpl[PORTS]();
|
||||||
@@ -145,7 +165,7 @@ taxi_axis_if #(
|
|||||||
.DATA_W(MAC_DATA_W),
|
.DATA_W(MAC_DATA_W),
|
||||||
.ID_W(8),
|
.ID_W(8),
|
||||||
.USER_EN(1),
|
.USER_EN(1),
|
||||||
.USER_W(1)
|
.USER_W(PTP_TS_W+1)
|
||||||
) mac_axis_rx[PORTS]();
|
) mac_axis_rx[PORTS]();
|
||||||
|
|
||||||
cndm_micro_pcie_us #(
|
cndm_micro_pcie_us #(
|
||||||
@@ -153,6 +173,9 @@ cndm_micro_pcie_us #(
|
|||||||
.VENDOR(VENDOR),
|
.VENDOR(VENDOR),
|
||||||
.FAMILY(FAMILY),
|
.FAMILY(FAMILY),
|
||||||
.PORTS(PORTS),
|
.PORTS(PORTS),
|
||||||
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
|
.PTP_CLK_PER_NS_NUM(PTP_CLK_PER_NS_NUM),
|
||||||
|
.PTP_CLK_PER_NS_DENOM(PTP_CLK_PER_NS_DENOM),
|
||||||
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
|
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
|
||||||
.BAR0_APERTURE(BAR0_APERTURE)
|
.BAR0_APERTURE(BAR0_APERTURE)
|
||||||
)
|
)
|
||||||
@@ -210,6 +233,23 @@ uut (
|
|||||||
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
|
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
|
||||||
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
|
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP
|
||||||
|
*/
|
||||||
|
.ptp_clk(ptp_clk),
|
||||||
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_sample_clk(ptp_sample_clk),
|
||||||
|
.ptp_td_sdo(ptp_td_sdo),
|
||||||
|
.ptp_pps(ptp_pps),
|
||||||
|
.ptp_pps_str(ptp_pps_str),
|
||||||
|
.ptp_sync_locked(ptp_sync_locked),
|
||||||
|
.ptp_sync_ts_rel(ptp_sync_ts_rel),
|
||||||
|
.ptp_sync_ts_rel_step(ptp_sync_ts_rel_step),
|
||||||
|
.ptp_sync_ts_tod(ptp_sync_ts_tod),
|
||||||
|
.ptp_sync_ts_tod_step(ptp_sync_ts_tod_step),
|
||||||
|
.ptp_sync_pps(ptp_sync_pps),
|
||||||
|
.ptp_sync_pps_str(ptp_sync_pps_str),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ethernet: SFP+
|
* Ethernet: SFP+
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -231,8 +231,10 @@ taxi_eth_mac_25g_us #(
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -284,7 +286,6 @@ sfp_mac_inst (
|
|||||||
.tx_clk(sfp_tx_clk),
|
.tx_clk(sfp_tx_clk),
|
||||||
.tx_rst_in('{2{1'b0}}),
|
.tx_rst_in('{2{1'b0}}),
|
||||||
.tx_rst_out(sfp_tx_rst),
|
.tx_rst_out(sfp_tx_rst),
|
||||||
.ptp_sample_clk('{2{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -300,10 +301,18 @@ sfp_mac_inst (
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{2{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{2{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{2{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{2{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{2{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{2{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -142,14 +142,14 @@ class TB:
|
|||||||
# pcie_tfc_npd_av=dut.pcie_tfc_npd_av,
|
# pcie_tfc_npd_av=dut.pcie_tfc_npd_av,
|
||||||
|
|
||||||
# Configuration Management Interface
|
# Configuration Management Interface
|
||||||
# cfg_mgmt_addr=dut.cfg_mgmt_addr,
|
cfg_mgmt_addr=dut.cfg_mgmt_addr,
|
||||||
# cfg_mgmt_function_number=dut.cfg_mgmt_function_number,
|
cfg_mgmt_function_number=dut.cfg_mgmt_function_number,
|
||||||
# cfg_mgmt_write=dut.cfg_mgmt_write,
|
cfg_mgmt_write=dut.cfg_mgmt_write,
|
||||||
# cfg_mgmt_write_data=dut.cfg_mgmt_write_data,
|
cfg_mgmt_write_data=dut.cfg_mgmt_write_data,
|
||||||
# cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable,
|
cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable,
|
||||||
# cfg_mgmt_read=dut.cfg_mgmt_read,
|
cfg_mgmt_read=dut.cfg_mgmt_read,
|
||||||
# cfg_mgmt_read_data=dut.cfg_mgmt_read_data,
|
cfg_mgmt_read_data=dut.cfg_mgmt_read_data,
|
||||||
# cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done,
|
cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done,
|
||||||
# cfg_mgmt_debug_access
|
# cfg_mgmt_debug_access
|
||||||
|
|
||||||
# Configuration Status Interface
|
# Configuration Status Interface
|
||||||
|
|||||||
@@ -2,4 +2,5 @@ cndm_proto_pcie_us.sv
|
|||||||
cndm_proto_core.f
|
cndm_proto_core.f
|
||||||
../lib/taxi/src/pcie/rtl/taxi_pcie_us_axil_master.sv
|
../lib/taxi/src/pcie/rtl/taxi_pcie_us_axil_master.sv
|
||||||
../lib/taxi/src/pcie/rtl/taxi_pcie_us_msi.sv
|
../lib/taxi/src/pcie/rtl/taxi_pcie_us_msi.sv
|
||||||
|
../lib/taxi/src/pcie/rtl/taxi_pcie_us_cfg.sv
|
||||||
../lib/taxi/src/dma/rtl/taxi_dma_if_pcie_us.f
|
../lib/taxi/src/dma/rtl/taxi_dma_if_pcie_us.f
|
||||||
|
|||||||
@@ -177,6 +177,8 @@ logic [7:0] pcie_tx_fc_nph_av;
|
|||||||
logic [7:0] pcie_tx_fc_ph_av;
|
logic [7:0] pcie_tx_fc_ph_av;
|
||||||
logic [11:0] pcie_tx_fc_pd_av;
|
logic [11:0] pcie_tx_fc_pd_av;
|
||||||
|
|
||||||
|
logic ext_tag_en;
|
||||||
|
|
||||||
assign cfg_fc_sel = 3'b100;
|
assign cfg_fc_sel = 3'b100;
|
||||||
|
|
||||||
taxi_dma_desc_if #(
|
taxi_dma_desc_if #(
|
||||||
@@ -335,7 +337,7 @@ dma_if_inst (
|
|||||||
*/
|
*/
|
||||||
.read_enable(1'b1),
|
.read_enable(1'b1),
|
||||||
.write_enable(1'b1),
|
.write_enable(1'b1),
|
||||||
.ext_tag_en(1'b0), // TODO
|
.ext_tag_en(ext_tag_en),
|
||||||
.rcb_128b(cfg_rcb_status[0]),
|
.rcb_128b(cfg_rcb_status[0]),
|
||||||
.requester_id('0),
|
.requester_id('0),
|
||||||
.requester_id_en(1'b0),
|
.requester_id_en(1'b0),
|
||||||
@@ -385,6 +387,36 @@ dma_if_inst (
|
|||||||
.stat_wr_tx_stall(stat_wr_tx_stall)
|
.stat_wr_tx_stall(stat_wr_tx_stall)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
taxi_pcie_us_cfg #(
|
||||||
|
.PF_COUNT(1),
|
||||||
|
.VF_COUNT(0),
|
||||||
|
.VF_OFFSET(m_axis_pcie_rq.USER_W == 60 ? 64 : 4),
|
||||||
|
.PCIE_CAP_OFFSET(m_axis_pcie_rq.USER_W == 60 ? 12'h0C0 : 12'h070)
|
||||||
|
)
|
||||||
|
cfg_inst (
|
||||||
|
.clk(pcie_clk),
|
||||||
|
.rst(pcie_rst),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configuration outputs
|
||||||
|
*/
|
||||||
|
.ext_tag_en(ext_tag_en),
|
||||||
|
.max_read_req_size(),
|
||||||
|
.max_payload_size(),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interface to Ultrascale PCIe IP core
|
||||||
|
*/
|
||||||
|
.cfg_mgmt_addr(cfg_mgmt_addr),
|
||||||
|
.cfg_mgmt_function_number(cfg_mgmt_function_number),
|
||||||
|
.cfg_mgmt_write(cfg_mgmt_write),
|
||||||
|
.cfg_mgmt_write_data(cfg_mgmt_write_data),
|
||||||
|
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
|
||||||
|
.cfg_mgmt_read(cfg_mgmt_read),
|
||||||
|
.cfg_mgmt_read_data(cfg_mgmt_read_data),
|
||||||
|
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done)
|
||||||
|
);
|
||||||
|
|
||||||
// MSI interrupts
|
// MSI interrupts
|
||||||
wire [PORTS-1:0] irq;
|
wire [PORTS-1:0] irq;
|
||||||
wire [31:0] msi_irq = 32'(irq);
|
wire [31:0] msi_irq = 32'(irq);
|
||||||
|
|||||||
@@ -140,14 +140,14 @@ class TB:
|
|||||||
# pcie_tfc_npd_av=dut.pcie_tfc_npd_av,
|
# pcie_tfc_npd_av=dut.pcie_tfc_npd_av,
|
||||||
|
|
||||||
# Configuration Management Interface
|
# Configuration Management Interface
|
||||||
# cfg_mgmt_addr=dut.cfg_mgmt_addr,
|
cfg_mgmt_addr=dut.cfg_mgmt_addr,
|
||||||
# cfg_mgmt_function_number=dut.cfg_mgmt_function_number,
|
cfg_mgmt_function_number=dut.cfg_mgmt_function_number,
|
||||||
# cfg_mgmt_write=dut.cfg_mgmt_write,
|
cfg_mgmt_write=dut.cfg_mgmt_write,
|
||||||
# cfg_mgmt_write_data=dut.cfg_mgmt_write_data,
|
cfg_mgmt_write_data=dut.cfg_mgmt_write_data,
|
||||||
# cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable,
|
cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable,
|
||||||
# cfg_mgmt_read=dut.cfg_mgmt_read,
|
cfg_mgmt_read=dut.cfg_mgmt_read,
|
||||||
# cfg_mgmt_read_data=dut.cfg_mgmt_read_data,
|
cfg_mgmt_read_data=dut.cfg_mgmt_read_data,
|
||||||
# cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done,
|
cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done,
|
||||||
# cfg_mgmt_debug_access
|
# cfg_mgmt_debug_access
|
||||||
|
|
||||||
# Configuration Status Interface
|
# Configuration Status Interface
|
||||||
|
|||||||
@@ -684,7 +684,7 @@ always_comb begin
|
|||||||
|
|
||||||
if (status_fifo_rd_ptr_reg != status_fifo_wr_ptr_reg) begin
|
if (status_fifo_rd_ptr_reg != status_fifo_wr_ptr_reg) begin
|
||||||
// status FIFO not empty
|
// status FIFO not empty
|
||||||
if (m_axi.bready && m_axi.bvalid) begin
|
if (m_axi_wr.bready && m_axi_wr.bvalid) begin
|
||||||
// got write completion, pop and return status
|
// got write completion, pop and return status
|
||||||
wr_desc_sts_len_next = status_fifo_len[status_fifo_rd_ptr_reg[STATUS_FIFO_AW-1:0]];
|
wr_desc_sts_len_next = status_fifo_len[status_fifo_rd_ptr_reg[STATUS_FIFO_AW-1:0]];
|
||||||
wr_desc_sts_tag_next = status_fifo_tag[status_fifo_rd_ptr_reg[STATUS_FIFO_AW-1:0]];
|
wr_desc_sts_tag_next = status_fifo_tag[status_fifo_rd_ptr_reg[STATUS_FIFO_AW-1:0]];
|
||||||
|
|||||||
@@ -176,8 +176,10 @@ for (genvar n = 0; n < 2; n = n + 1) begin : gty_quad
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -229,7 +231,6 @@ for (genvar n = 0; n < 2; n = n + 1) begin : gty_quad
|
|||||||
.tx_clk(qsfp_tx_clk[n*CNT +: CNT]),
|
.tx_clk(qsfp_tx_clk[n*CNT +: CNT]),
|
||||||
.tx_rst_in('{CNT{1'b0}}),
|
.tx_rst_in('{CNT{1'b0}}),
|
||||||
.tx_rst_out(qsfp_tx_rst[n*CNT +: CNT]),
|
.tx_rst_out(qsfp_tx_rst[n*CNT +: CNT]),
|
||||||
.ptp_sample_clk('{CNT{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -245,10 +246,18 @@ for (genvar n = 0; n < 2; n = n + 1) begin : gty_quad
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{CNT{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{CNT{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{CNT{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{CNT{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{CNT{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{CNT{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -177,8 +177,10 @@ taxi_eth_mac_25g_us #(
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -230,7 +232,6 @@ sfp_mac_inst (
|
|||||||
.tx_clk(sfp_tx_clk),
|
.tx_clk(sfp_tx_clk),
|
||||||
.tx_rst_in('{2{1'b0}}),
|
.tx_rst_in('{2{1'b0}}),
|
||||||
.tx_rst_out(sfp_tx_rst),
|
.tx_rst_out(sfp_tx_rst),
|
||||||
.ptp_sample_clk('{2{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -246,10 +247,18 @@ sfp_mac_inst (
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{2{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{2{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{2{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{2{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{2{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{2{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -347,8 +347,10 @@ for (genvar n = 0; n < GTY_QUAD_CNT; n = n + 1) begin : gty_quad
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -406,7 +408,6 @@ for (genvar n = 0; n < GTY_QUAD_CNT; n = n + 1) begin : gty_quad
|
|||||||
.tx_clk(eth_gty_tx_clk[n*CNT +: CNT]),
|
.tx_clk(eth_gty_tx_clk[n*CNT +: CNT]),
|
||||||
.tx_rst_in('{CNT{1'b0}}),
|
.tx_rst_in('{CNT{1'b0}}),
|
||||||
.tx_rst_out(eth_gty_tx_rst[n*CNT +: CNT]),
|
.tx_rst_out(eth_gty_tx_rst[n*CNT +: CNT]),
|
||||||
.ptp_sample_clk('{CNT{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -422,10 +423,18 @@ for (genvar n = 0; n < GTY_QUAD_CNT; n = n + 1) begin : gty_quad
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{CNT{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{CNT{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{CNT{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{CNT{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{CNT{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{CNT{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -428,8 +428,10 @@ for (genvar n = 0; n < GTY_QUAD_CNT; n = n + 1) begin : gty_quad
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -503,7 +505,6 @@ for (genvar n = 0; n < GTY_QUAD_CNT; n = n + 1) begin : gty_quad
|
|||||||
.tx_clk(eth_gty_tx_clk[n*CNT +: CNT]),
|
.tx_clk(eth_gty_tx_clk[n*CNT +: CNT]),
|
||||||
.tx_rst_in('{CNT{1'b0}}),
|
.tx_rst_in('{CNT{1'b0}}),
|
||||||
.tx_rst_out(eth_gty_tx_rst[n*CNT +: CNT]),
|
.tx_rst_out(eth_gty_tx_rst[n*CNT +: CNT]),
|
||||||
.ptp_sample_clk('{CNT{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -519,10 +520,18 @@ for (genvar n = 0; n < GTY_QUAD_CNT; n = n + 1) begin : gty_quad
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{CNT{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{CNT{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{CNT{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{CNT{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{CNT{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{CNT{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -372,8 +372,10 @@ for (genvar n = 0; n < GTY_QUAD_CNT; n = n + 1) begin : gty_quad
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -434,7 +436,6 @@ for (genvar n = 0; n < GTY_QUAD_CNT; n = n + 1) begin : gty_quad
|
|||||||
.tx_clk(eth_gty_tx_clk[n*CNT +: CNT]),
|
.tx_clk(eth_gty_tx_clk[n*CNT +: CNT]),
|
||||||
.tx_rst_in('{CNT{1'b0}}),
|
.tx_rst_in('{CNT{1'b0}}),
|
||||||
.tx_rst_out(eth_gty_tx_rst[n*CNT +: CNT]),
|
.tx_rst_out(eth_gty_tx_rst[n*CNT +: CNT]),
|
||||||
.ptp_sample_clk('{CNT{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -450,10 +451,18 @@ for (genvar n = 0; n < GTY_QUAD_CNT; n = n + 1) begin : gty_quad
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{CNT{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{CNT{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{CNT{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{CNT{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{CNT{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{CNT{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -519,8 +519,10 @@ taxi_eth_mac_25g_us #(
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -582,7 +584,6 @@ sfp_mac_inst (
|
|||||||
.tx_clk(sfp_tx_clk),
|
.tx_clk(sfp_tx_clk),
|
||||||
.tx_rst_in('{1{1'b0}}),
|
.tx_rst_in('{1{1'b0}}),
|
||||||
.tx_rst_out(sfp_tx_rst),
|
.tx_rst_out(sfp_tx_rst),
|
||||||
.ptp_sample_clk('{1{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -598,10 +599,18 @@ sfp_mac_inst (
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{1{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{1{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{1{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{1{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{1{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{1{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -606,8 +606,10 @@ end else begin : sfp_mac
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -666,7 +668,6 @@ end else begin : sfp_mac
|
|||||||
.tx_clk(sfp_tx_clk),
|
.tx_clk(sfp_tx_clk),
|
||||||
.tx_rst_in('{2{1'b0}}),
|
.tx_rst_in('{2{1'b0}}),
|
||||||
.tx_rst_out(sfp_tx_rst),
|
.tx_rst_out(sfp_tx_rst),
|
||||||
.ptp_sample_clk('{2{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -682,10 +683,18 @@ end else begin : sfp_mac
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{2{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{2{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{2{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{2{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{2{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{2{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -420,8 +420,10 @@ end else begin : sfp_mac
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -473,7 +475,6 @@ end else begin : sfp_mac
|
|||||||
.tx_clk(sfp_tx_clk),
|
.tx_clk(sfp_tx_clk),
|
||||||
.tx_rst_in('{1{1'b0}}),
|
.tx_rst_in('{1{1'b0}}),
|
||||||
.tx_rst_out(sfp_tx_rst),
|
.tx_rst_out(sfp_tx_rst),
|
||||||
.ptp_sample_clk('{1{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -489,10 +490,18 @@ end else begin : sfp_mac
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{1{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{1{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{1{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{1{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{1{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{1{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -309,8 +309,10 @@ taxi_eth_mac_25g_us #(
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -368,7 +370,6 @@ sfp_mac_inst (
|
|||||||
.tx_clk(sfp_tx_clk),
|
.tx_clk(sfp_tx_clk),
|
||||||
.tx_rst_in('{4{1'b0}}),
|
.tx_rst_in('{4{1'b0}}),
|
||||||
.tx_rst_out(sfp_tx_rst),
|
.tx_rst_out(sfp_tx_rst),
|
||||||
.ptp_sample_clk('{4{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -384,10 +385,18 @@ sfp_mac_inst (
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{4{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{4{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{4{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{4{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{4{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{4{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -195,8 +195,10 @@ for (genvar n = 0; n < 2; n = n + 1) begin : gty_quad
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -248,7 +250,6 @@ for (genvar n = 0; n < 2; n = n + 1) begin : gty_quad
|
|||||||
.tx_clk(qsfp_tx_clk[n*CNT +: CNT]),
|
.tx_clk(qsfp_tx_clk[n*CNT +: CNT]),
|
||||||
.tx_rst_in('{CNT{1'b0}}),
|
.tx_rst_in('{CNT{1'b0}}),
|
||||||
.tx_rst_out(qsfp_tx_rst[n*CNT +: CNT]),
|
.tx_rst_out(qsfp_tx_rst[n*CNT +: CNT]),
|
||||||
.ptp_sample_clk('{CNT{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -264,10 +265,18 @@ for (genvar n = 0; n < 2; n = n + 1) begin : gty_quad
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{CNT{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{CNT{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{CNT{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{CNT{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{CNT{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{CNT{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -171,8 +171,10 @@ taxi_eth_mac_25g_us #(
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -224,7 +226,6 @@ sfp_mac_inst (
|
|||||||
.tx_clk(sfp_tx_clk),
|
.tx_clk(sfp_tx_clk),
|
||||||
.tx_rst_in('{2{1'b0}}),
|
.tx_rst_in('{2{1'b0}}),
|
||||||
.tx_rst_out(sfp_tx_rst),
|
.tx_rst_out(sfp_tx_rst),
|
||||||
.ptp_sample_clk('{2{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -240,10 +241,18 @@ sfp_mac_inst (
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{2{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{2{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{2{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{2{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{2{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{2{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -314,8 +314,10 @@ taxi_eth_mac_25g_us #(
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -373,7 +375,6 @@ sfp_mac_inst (
|
|||||||
.tx_clk(sfp_tx_clk),
|
.tx_clk(sfp_tx_clk),
|
||||||
.tx_rst_in('{4{1'b0}}),
|
.tx_rst_in('{4{1'b0}}),
|
||||||
.tx_rst_out(sfp_tx_rst),
|
.tx_rst_out(sfp_tx_rst),
|
||||||
.ptp_sample_clk('{4{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -389,10 +390,18 @@ sfp_mac_inst (
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{4{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{4{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{4{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{4{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{4{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{4{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -402,8 +402,10 @@ taxi_eth_mac_25g_us #(
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -461,7 +463,6 @@ qsfp_mac_inst (
|
|||||||
.tx_clk(qsfp_tx_clk),
|
.tx_clk(qsfp_tx_clk),
|
||||||
.tx_rst_in('{4{1'b0}}),
|
.tx_rst_in('{4{1'b0}}),
|
||||||
.tx_rst_out(qsfp_tx_rst),
|
.tx_rst_out(qsfp_tx_rst),
|
||||||
.ptp_sample_clk('{4{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -477,10 +478,18 @@ qsfp_mac_inst (
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{4{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{4{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{4{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{4{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{4{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{4{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -599,8 +599,10 @@ for (genvar n = 0; n < 2; n = n + 1) begin : gty_quad
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -658,7 +660,6 @@ for (genvar n = 0; n < 2; n = n + 1) begin : gty_quad
|
|||||||
.tx_clk(qsfp_tx_clk[n*CNT +: CNT]),
|
.tx_clk(qsfp_tx_clk[n*CNT +: CNT]),
|
||||||
.tx_rst_in('{CNT{1'b0}}),
|
.tx_rst_in('{CNT{1'b0}}),
|
||||||
.tx_rst_out(qsfp_tx_rst[n*CNT +: CNT]),
|
.tx_rst_out(qsfp_tx_rst[n*CNT +: CNT]),
|
||||||
.ptp_sample_clk('{CNT{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -674,10 +675,18 @@ for (genvar n = 0; n < 2; n = n + 1) begin : gty_quad
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{CNT{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{CNT{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{CNT{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{CNT{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{CNT{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{CNT{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -326,8 +326,10 @@ for (genvar n = 0; n < GTY_QUAD_CNT; n = n + 1) begin : gty_quad
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -387,7 +389,6 @@ for (genvar n = 0; n < GTY_QUAD_CNT; n = n + 1) begin : gty_quad
|
|||||||
.tx_clk(eth_gty_tx_clk[n*CNT +: CNT]),
|
.tx_clk(eth_gty_tx_clk[n*CNT +: CNT]),
|
||||||
.tx_rst_in('{CNT{1'b0}}),
|
.tx_rst_in('{CNT{1'b0}}),
|
||||||
.tx_rst_out(eth_gty_tx_rst[n*CNT +: CNT]),
|
.tx_rst_out(eth_gty_tx_rst[n*CNT +: CNT]),
|
||||||
.ptp_sample_clk('{CNT{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -403,10 +404,18 @@ for (genvar n = 0; n < GTY_QUAD_CNT; n = n + 1) begin : gty_quad
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{CNT{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{CNT{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{CNT{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{CNT{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{CNT{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{CNT{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -661,8 +661,10 @@ end else begin : sfp_mac
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -720,7 +722,6 @@ end else begin : sfp_mac
|
|||||||
.tx_clk(sfp_tx_clk),
|
.tx_clk(sfp_tx_clk),
|
||||||
.tx_rst_in('{4{1'b0}}),
|
.tx_rst_in('{4{1'b0}}),
|
||||||
.tx_rst_out(sfp_tx_rst),
|
.tx_rst_out(sfp_tx_rst),
|
||||||
.ptp_sample_clk('{4{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -736,10 +737,18 @@ end else begin : sfp_mac
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{4{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{4{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{4{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{4{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{4{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{4{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -476,8 +476,10 @@ end else begin : sfp_mac
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -536,7 +538,6 @@ end else begin : sfp_mac
|
|||||||
.tx_clk(sfp_tx_clk),
|
.tx_clk(sfp_tx_clk),
|
||||||
.tx_rst_in('{2{1'b0}}),
|
.tx_rst_in('{2{1'b0}}),
|
||||||
.tx_rst_out(sfp_tx_rst),
|
.tx_rst_out(sfp_tx_rst),
|
||||||
.ptp_sample_clk('{2{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -552,10 +553,18 @@ end else begin : sfp_mac
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{2{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{2{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{2{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{2{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{2{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{2{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -383,8 +383,10 @@ taxi_eth_mac_25g_us #(
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -442,7 +444,6 @@ sfp_mac_inst (
|
|||||||
.tx_clk(sfp_tx_clk),
|
.tx_clk(sfp_tx_clk),
|
||||||
.tx_rst_in('{4{1'b0}}),
|
.tx_rst_in('{4{1'b0}}),
|
||||||
.tx_rst_out(sfp_tx_rst),
|
.tx_rst_out(sfp_tx_rst),
|
||||||
.ptp_sample_clk('{4{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -458,10 +459,18 @@ sfp_mac_inst (
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{4{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{4{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{4{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{4{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{4{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{4{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -223,8 +223,10 @@ for (genvar n = 0; n < 2; n = n + 1) begin : gty_quad
|
|||||||
.DIC_EN(1'b1),
|
.DIC_EN(1'b1),
|
||||||
.MIN_FRAME_LEN(64),
|
.MIN_FRAME_LEN(64),
|
||||||
.PTP_TS_EN(1'b0),
|
.PTP_TS_EN(1'b0),
|
||||||
|
.PTP_TD_EN(1'b0),
|
||||||
.PTP_TS_FMT_TOD(1'b1),
|
.PTP_TS_FMT_TOD(1'b1),
|
||||||
.PTP_TS_W(96),
|
.PTP_TS_W(96),
|
||||||
|
.PTP_TD_SDI_PIPELINE(2),
|
||||||
.PRBS31_EN(1'b0),
|
.PRBS31_EN(1'b0),
|
||||||
.TX_SERDES_PIPELINE(1),
|
.TX_SERDES_PIPELINE(1),
|
||||||
.RX_SERDES_PIPELINE(1),
|
.RX_SERDES_PIPELINE(1),
|
||||||
@@ -276,7 +278,6 @@ for (genvar n = 0; n < 2; n = n + 1) begin : gty_quad
|
|||||||
.tx_clk(qsfp_tx_clk[n*CNT +: CNT]),
|
.tx_clk(qsfp_tx_clk[n*CNT +: CNT]),
|
||||||
.tx_rst_in('{CNT{1'b0}}),
|
.tx_rst_in('{CNT{1'b0}}),
|
||||||
.tx_rst_out(qsfp_tx_rst[n*CNT +: CNT]),
|
.tx_rst_out(qsfp_tx_rst[n*CNT +: CNT]),
|
||||||
.ptp_sample_clk('{CNT{1'b0}}),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -292,10 +293,18 @@ for (genvar n = 0; n < 2; n = n + 1) begin : gty_quad
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts('{CNT{'0}}),
|
.ptp_clk(1'b0),
|
||||||
.tx_ptp_ts_step('{CNT{1'b0}}),
|
.ptp_rst(1'b0),
|
||||||
.rx_ptp_ts('{CNT{'0}}),
|
.ptp_sample_clk(1'b0),
|
||||||
.rx_ptp_ts_step('{CNT{1'b0}}),
|
.ptp_td_sdi(1'b0),
|
||||||
|
.tx_ptp_ts_in('{CNT{'0}}),
|
||||||
|
.tx_ptp_ts_out(),
|
||||||
|
.tx_ptp_ts_step_out(),
|
||||||
|
.tx_ptp_locked(),
|
||||||
|
.rx_ptp_ts_in('{CNT{'0}}),
|
||||||
|
.rx_ptp_ts_out(),
|
||||||
|
.rx_ptp_ts_step_out(),
|
||||||
|
.rx_ptp_locked(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -584,10 +584,13 @@ always_ff @(posedge clk) begin
|
|||||||
|
|
||||||
if (PTP_TS_EN && PTP_TS_FMT_TOD) begin
|
if (PTP_TS_EN && PTP_TS_FMT_TOD) begin
|
||||||
// ns field rollover
|
// ns field rollover
|
||||||
|
// workaround for verilator lint bug: unreachable by parameter value
|
||||||
|
/* verilator lint_off SELRANGE */
|
||||||
ptp_ts_adj_reg[15:0] <= ptp_ts_reg[15:0];
|
ptp_ts_adj_reg[15:0] <= ptp_ts_reg[15:0];
|
||||||
{ptp_ts_borrow_reg, ptp_ts_adj_reg[45:16]} <= $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000);
|
{ptp_ts_borrow_reg, ptp_ts_adj_reg[45:16]} <= $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000);
|
||||||
ptp_ts_adj_reg[47:46] <= 0;
|
ptp_ts_adj_reg[47:46] <= 0;
|
||||||
ptp_ts_adj_reg[95:48] <= ptp_ts_reg[95:48] + 1;
|
ptp_ts_adj_reg[95:48] <= ptp_ts_reg[95:48] + 1;
|
||||||
|
/* verilator lint_on SELRANGE */
|
||||||
end
|
end
|
||||||
|
|
||||||
// lane swapping and termination character detection
|
// lane swapping and termination character detection
|
||||||
@@ -807,8 +810,11 @@ always_ff @(posedge clk) begin
|
|||||||
if (input_start_swap_reg) begin
|
if (input_start_swap_reg) begin
|
||||||
start_packet_reg <= 2'b10;
|
start_packet_reg <= 2'b10;
|
||||||
if (PTP_TS_FMT_TOD) begin
|
if (PTP_TS_FMT_TOD) begin
|
||||||
|
// workaround for verilator lint bug: unreachable by parameter value
|
||||||
|
/* verilator lint_off SELRANGE */
|
||||||
ptp_ts_reg[45:0] <= ptp_ts[45:0] + 46'(ts_inc_reg >> 1);
|
ptp_ts_reg[45:0] <= ptp_ts[45:0] + 46'(ts_inc_reg >> 1);
|
||||||
ptp_ts_reg[95:48] <= ptp_ts[95:48];
|
ptp_ts_reg[95:48] <= ptp_ts[95:48];
|
||||||
|
/* verilator lint_on SELRANGE */
|
||||||
end else begin
|
end else begin
|
||||||
ptp_ts_reg <= ptp_ts + PTP_TS_W'(ts_inc_reg >> 1);
|
ptp_ts_reg <= ptp_ts + PTP_TS_W'(ts_inc_reg >> 1);
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -788,10 +788,13 @@ always_ff @(posedge clk) begin
|
|||||||
|
|
||||||
if (PTP_TS_EN && PTP_TS_FMT_TOD) begin
|
if (PTP_TS_EN && PTP_TS_FMT_TOD) begin
|
||||||
m_axis_tx_cpl_valid_reg <= m_axis_tx_cpl_valid_int_reg;
|
m_axis_tx_cpl_valid_reg <= m_axis_tx_cpl_valid_int_reg;
|
||||||
|
// workaround for verilator lint bug: unreachable by parameter value
|
||||||
|
/* verilator lint_off SELRANGE */
|
||||||
m_axis_tx_cpl_ts_adj_reg[15:0] <= m_axis_tx_cpl_ts_reg[15:0];
|
m_axis_tx_cpl_ts_adj_reg[15:0] <= m_axis_tx_cpl_ts_reg[15:0];
|
||||||
{m_axis_tx_cpl_ts_borrow_reg, m_axis_tx_cpl_ts_adj_reg[45:16]} <= $signed({1'b0, m_axis_tx_cpl_ts_reg[45:16]}) - $signed(31'd1000000000);
|
{m_axis_tx_cpl_ts_borrow_reg, m_axis_tx_cpl_ts_adj_reg[45:16]} <= $signed({1'b0, m_axis_tx_cpl_ts_reg[45:16]}) - $signed(31'd1000000000);
|
||||||
m_axis_tx_cpl_ts_adj_reg[47:46] <= 0;
|
m_axis_tx_cpl_ts_adj_reg[47:46] <= 0;
|
||||||
m_axis_tx_cpl_ts_adj_reg[95:48] <= m_axis_tx_cpl_ts_reg[95:48] + 1;
|
m_axis_tx_cpl_ts_adj_reg[95:48] <= m_axis_tx_cpl_ts_reg[95:48] + 1;
|
||||||
|
/* verilator lint_on SELRANGE */
|
||||||
end
|
end
|
||||||
|
|
||||||
if (GBX_IF_EN && tx_gbx_req_stall) begin
|
if (GBX_IF_EN && tx_gbx_req_stall) begin
|
||||||
@@ -810,8 +813,11 @@ always_ff @(posedge clk) begin
|
|||||||
if (swap_lanes_reg) begin
|
if (swap_lanes_reg) begin
|
||||||
if (PTP_TS_EN) begin
|
if (PTP_TS_EN) begin
|
||||||
if (PTP_TS_FMT_TOD) begin
|
if (PTP_TS_FMT_TOD) begin
|
||||||
|
// workaround for verilator lint bug: unreachable by parameter value
|
||||||
|
/* verilator lint_off SELRANGE */
|
||||||
m_axis_tx_cpl_ts_reg[45:0] <= ptp_ts[45:0] + 46'(ts_inc_reg >> 1);
|
m_axis_tx_cpl_ts_reg[45:0] <= ptp_ts[45:0] + 46'(ts_inc_reg >> 1);
|
||||||
m_axis_tx_cpl_ts_reg[95:48] <= ptp_ts[95:48];
|
m_axis_tx_cpl_ts_reg[95:48] <= ptp_ts[95:48];
|
||||||
|
/* verilator lint_on SELRANGE */
|
||||||
end else begin
|
end else begin
|
||||||
m_axis_tx_cpl_ts_reg <= ptp_ts + PTP_TS_W'(ts_inc_reg >> 1);
|
m_axis_tx_cpl_ts_reg <= ptp_ts + PTP_TS_W'(ts_inc_reg >> 1);
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -12,4 +12,5 @@ taxi_mac_pause_ctrl_rx.sv
|
|||||||
../lib/taxi/src/axis/rtl/taxi_axis_if.sv
|
../lib/taxi/src/axis/rtl/taxi_axis_if.sv
|
||||||
../lib/taxi/src/axis/rtl/taxi_axis_null_src.sv
|
../lib/taxi/src/axis/rtl/taxi_axis_null_src.sv
|
||||||
../lib/taxi/src/axis/rtl/taxi_axis_tie.sv
|
../lib/taxi/src/axis/rtl/taxi_axis_tie.sv
|
||||||
|
../lib/taxi/src/ptp/rtl/taxi_ptp_td_leaf.sv
|
||||||
../lib/taxi/src/sync/rtl/taxi_sync_signal.sv
|
../lib/taxi/src/sync/rtl/taxi_sync_signal.sv
|
||||||
|
|||||||
@@ -26,8 +26,10 @@ module taxi_eth_mac_10g #
|
|||||||
parameter logic DIC_EN = 1'b1,
|
parameter logic DIC_EN = 1'b1,
|
||||||
parameter MIN_FRAME_LEN = 64,
|
parameter MIN_FRAME_LEN = 64,
|
||||||
parameter logic PTP_TS_EN = 1'b0,
|
parameter logic PTP_TS_EN = 1'b0,
|
||||||
|
parameter logic PTP_TD_EN = PTP_TS_EN,
|
||||||
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
||||||
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
||||||
|
parameter PTP_TD_SDI_PIPELINE = 2,
|
||||||
parameter logic PFC_EN = 1'b0,
|
parameter logic PFC_EN = 1'b0,
|
||||||
parameter logic PAUSE_EN = PFC_EN,
|
parameter logic PAUSE_EN = PFC_EN,
|
||||||
parameter logic STAT_EN = 1'b0,
|
parameter logic STAT_EN = 1'b0,
|
||||||
@@ -71,8 +73,18 @@ module taxi_eth_mac_10g #
|
|||||||
/*
|
/*
|
||||||
* PTP
|
* PTP
|
||||||
*/
|
*/
|
||||||
input wire logic [PTP_TS_W-1:0] tx_ptp_ts = '0,
|
input wire logic ptp_clk = 1'b0,
|
||||||
input wire logic [PTP_TS_W-1:0] rx_ptp_ts = '0,
|
input wire logic ptp_rst = 1'b0,
|
||||||
|
input wire logic ptp_sample_clk = 1'b0,
|
||||||
|
input wire logic ptp_td_sdi = 1'b0,
|
||||||
|
input wire logic [PTP_TS_W-1:0] tx_ptp_ts_in = '0,
|
||||||
|
output wire logic [PTP_TS_W-1:0] tx_ptp_ts_out,
|
||||||
|
output wire logic tx_ptp_ts_step_out,
|
||||||
|
output wire logic tx_ptp_locked,
|
||||||
|
input wire logic [PTP_TS_W-1:0] rx_ptp_ts_in = '0,
|
||||||
|
output wire logic [PTP_TS_W-1:0] rx_ptp_ts_out,
|
||||||
|
output wire logic rx_ptp_ts_step_out,
|
||||||
|
output wire logic rx_ptp_locked,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
@@ -216,6 +228,123 @@ if (KEEP_W*8 != DATA_W || CTRL_W*8 != DATA_W)
|
|||||||
taxi_axis_if #(.DATA_W(DATA_W), .KEEP_W(KEEP_W), .USER_EN(1), .USER_W(TX_USER_W_INT), .ID_EN(1), .ID_W(TX_TAG_W)) axis_tx_int();
|
taxi_axis_if #(.DATA_W(DATA_W), .KEEP_W(KEEP_W), .USER_EN(1), .USER_W(TX_USER_W_INT), .ID_EN(1), .ID_W(TX_TAG_W)) axis_tx_int();
|
||||||
taxi_axis_if #(.DATA_W(DATA_W), .KEEP_W(KEEP_W), .USER_EN(1), .USER_W(RX_USER_W)) axis_rx_int();
|
taxi_axis_if #(.DATA_W(DATA_W), .KEEP_W(KEEP_W), .USER_EN(1), .USER_W(RX_USER_W)) axis_rx_int();
|
||||||
|
|
||||||
|
// PTP timestamping
|
||||||
|
if (PTP_TS_EN && PTP_TD_EN) begin : ptp
|
||||||
|
|
||||||
|
// TX
|
||||||
|
wire [PTP_TS_W-1:0] tx_ptp_ts_rel;
|
||||||
|
wire tx_ptp_ts_rel_step;
|
||||||
|
wire [PTP_TS_W-1:0] tx_ptp_ts_tod;
|
||||||
|
wire tx_ptp_ts_tod_step;
|
||||||
|
|
||||||
|
taxi_ptp_td_leaf #(
|
||||||
|
.TS_REL_EN(!PTP_TS_FMT_TOD),
|
||||||
|
.TS_TOD_EN(PTP_TS_FMT_TOD),
|
||||||
|
.TS_FNS_W(16),
|
||||||
|
.TS_REL_NS_W(PTP_TS_FMT_TOD ? 48 : PTP_TS_W-16),
|
||||||
|
.TS_TOD_S_W(PTP_TS_FMT_TOD ? PTP_TS_W-32-16 : 48),
|
||||||
|
.TS_REL_W(PTP_TS_W),
|
||||||
|
.TS_TOD_W(PTP_TS_W),
|
||||||
|
.TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE)
|
||||||
|
)
|
||||||
|
tx_leaf_inst (
|
||||||
|
.clk(tx_clk),
|
||||||
|
.rst(tx_rst),
|
||||||
|
.sample_clk(ptp_sample_clk),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP clock interface
|
||||||
|
*/
|
||||||
|
.ptp_clk(ptp_clk),
|
||||||
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timestamp output
|
||||||
|
*/
|
||||||
|
.output_ts_rel(tx_ptp_ts_rel),
|
||||||
|
.output_ts_rel_step(tx_ptp_ts_rel_step),
|
||||||
|
.output_ts_tod(tx_ptp_ts_tod),
|
||||||
|
.output_ts_tod_step(tx_ptp_ts_tod_step),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PPS output (ToD format only)
|
||||||
|
*/
|
||||||
|
.output_pps(),
|
||||||
|
.output_pps_str(),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Status
|
||||||
|
*/
|
||||||
|
.locked(tx_ptp_locked)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign tx_ptp_ts_out = PTP_TS_FMT_TOD ? tx_ptp_ts_tod : tx_ptp_ts_rel;
|
||||||
|
assign tx_ptp_ts_step_out = PTP_TS_FMT_TOD ? tx_ptp_ts_tod_step : tx_ptp_ts_rel_step;
|
||||||
|
|
||||||
|
// RX
|
||||||
|
wire [PTP_TS_W-1:0] rx_ptp_ts_rel;
|
||||||
|
wire rx_ptp_ts_rel_step;
|
||||||
|
wire [PTP_TS_W-1:0] rx_ptp_ts_tod;
|
||||||
|
wire rx_ptp_ts_tod_step;
|
||||||
|
|
||||||
|
taxi_ptp_td_leaf #(
|
||||||
|
.TS_REL_EN(!PTP_TS_FMT_TOD),
|
||||||
|
.TS_TOD_EN(PTP_TS_FMT_TOD),
|
||||||
|
.TS_FNS_W(16),
|
||||||
|
.TS_REL_NS_W(PTP_TS_FMT_TOD ? 48 : PTP_TS_W-16),
|
||||||
|
.TS_TOD_S_W(PTP_TS_FMT_TOD ? PTP_TS_W-32-16 : 48),
|
||||||
|
.TS_REL_W(PTP_TS_W),
|
||||||
|
.TS_TOD_W(PTP_TS_W),
|
||||||
|
.TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE)
|
||||||
|
)
|
||||||
|
rx_leaf_inst (
|
||||||
|
.clk(rx_clk),
|
||||||
|
.rst(rx_rst),
|
||||||
|
.sample_clk(ptp_sample_clk),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP clock interface
|
||||||
|
*/
|
||||||
|
.ptp_clk(ptp_clk),
|
||||||
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timestamp output
|
||||||
|
*/
|
||||||
|
.output_ts_rel(rx_ptp_ts_rel),
|
||||||
|
.output_ts_rel_step(rx_ptp_ts_rel_step),
|
||||||
|
.output_ts_tod(rx_ptp_ts_tod),
|
||||||
|
.output_ts_tod_step(rx_ptp_ts_tod_step),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PPS output (ToD format only)
|
||||||
|
*/
|
||||||
|
.output_pps(),
|
||||||
|
.output_pps_str(),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Status
|
||||||
|
*/
|
||||||
|
.locked(rx_ptp_locked)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign rx_ptp_ts_out = PTP_TS_FMT_TOD ? rx_ptp_ts_tod : rx_ptp_ts_rel;
|
||||||
|
assign rx_ptp_ts_step_out = PTP_TS_FMT_TOD ? rx_ptp_ts_tod_step : rx_ptp_ts_rel_step;
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
assign tx_ptp_ts_out = tx_ptp_ts_in;
|
||||||
|
assign tx_ptp_ts_step_out = 1'b0;
|
||||||
|
assign rx_ptp_ts_out = rx_ptp_ts_in;
|
||||||
|
assign rx_ptp_ts_step_out = 1'b0;
|
||||||
|
|
||||||
|
assign tx_ptp_locked = 1'b0;
|
||||||
|
assign rx_ptp_locked = 1'b0;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
if (DATA_W == 64) begin
|
if (DATA_W == 64) begin
|
||||||
|
|
||||||
taxi_axis_xgmii_rx_64 #(
|
taxi_axis_xgmii_rx_64 #(
|
||||||
@@ -245,7 +374,7 @@ if (DATA_W == 64) begin
|
|||||||
/*
|
/*
|
||||||
* PTP
|
* PTP
|
||||||
*/
|
*/
|
||||||
.ptp_ts(rx_ptp_ts),
|
.ptp_ts(rx_ptp_ts_out),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configuration
|
* Configuration
|
||||||
@@ -310,7 +439,7 @@ if (DATA_W == 64) begin
|
|||||||
/*
|
/*
|
||||||
* PTP
|
* PTP
|
||||||
*/
|
*/
|
||||||
.ptp_ts(tx_ptp_ts),
|
.ptp_ts(tx_ptp_ts_out),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configuration
|
* Configuration
|
||||||
@@ -364,7 +493,7 @@ end else if (DATA_W == 32) begin
|
|||||||
/*
|
/*
|
||||||
* PTP
|
* PTP
|
||||||
*/
|
*/
|
||||||
.ptp_ts(rx_ptp_ts),
|
.ptp_ts(rx_ptp_ts_out),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configuration
|
* Configuration
|
||||||
@@ -431,7 +560,7 @@ end else if (DATA_W == 32) begin
|
|||||||
/*
|
/*
|
||||||
* PTP
|
* PTP
|
||||||
*/
|
*/
|
||||||
.ptp_ts(tx_ptp_ts),
|
.ptp_ts(tx_ptp_ts_out),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configuration
|
* Configuration
|
||||||
|
|||||||
@@ -26,8 +26,10 @@ module taxi_eth_mac_10g_fifo #
|
|||||||
parameter logic DIC_EN = 1'b1,
|
parameter logic DIC_EN = 1'b1,
|
||||||
parameter MIN_FRAME_LEN = 64,
|
parameter MIN_FRAME_LEN = 64,
|
||||||
parameter logic PTP_TS_EN = 1'b0,
|
parameter logic PTP_TS_EN = 1'b0,
|
||||||
|
parameter logic PTP_TD_EN = PTP_TS_EN,
|
||||||
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
||||||
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
||||||
|
parameter PTP_TD_SDI_PIPELINE = 2,
|
||||||
parameter logic STAT_EN = 1'b0,
|
parameter logic STAT_EN = 1'b0,
|
||||||
parameter STAT_TX_LEVEL = 1,
|
parameter STAT_TX_LEVEL = 1,
|
||||||
parameter STAT_RX_LEVEL = 1,
|
parameter STAT_RX_LEVEL = 1,
|
||||||
@@ -56,7 +58,6 @@ module taxi_eth_mac_10g_fifo #
|
|||||||
input wire logic tx_rst,
|
input wire logic tx_rst,
|
||||||
input wire logic logic_clk,
|
input wire logic logic_clk,
|
||||||
input wire logic logic_rst,
|
input wire logic logic_rst,
|
||||||
input wire logic ptp_sample_clk,
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AXI4-Stream input (sink)
|
* AXI4-Stream input (sink)
|
||||||
@@ -85,8 +86,18 @@ module taxi_eth_mac_10g_fifo #
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
input wire logic [PTP_TS_W-1:0] ptp_ts = '0,
|
input wire logic ptp_clk = 1'b0,
|
||||||
input wire logic ptp_ts_step = 1'b0,
|
input wire logic ptp_rst = 1'b0,
|
||||||
|
input wire logic ptp_sample_clk = 1'b0,
|
||||||
|
input wire logic ptp_td_sdi = 1'b0,
|
||||||
|
input wire logic [PTP_TS_W-1:0] ptp_ts_in = '0,
|
||||||
|
input wire logic ptp_ts_step_in = 1'b0,
|
||||||
|
output wire logic [PTP_TS_W-1:0] tx_ptp_ts_out,
|
||||||
|
output wire logic tx_ptp_ts_step_out,
|
||||||
|
output wire logic tx_ptp_locked,
|
||||||
|
output wire logic [PTP_TS_W-1:0] rx_ptp_ts_out,
|
||||||
|
output wire logic rx_ptp_ts_step_out,
|
||||||
|
output wire logic rx_ptp_locked,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Statistics
|
* Statistics
|
||||||
@@ -127,12 +138,6 @@ taxi_axis_if #(.DATA_W(DATA_W), .KEEP_W(KEEP_W), .USER_EN(1), .USER_W(TX_USER_W)
|
|||||||
taxi_axis_if #(.DATA_W(PTP_TS_W), .KEEP_W(1), .ID_EN(1), .ID_W(TX_TAG_W)) axis_tx_cpl_int();
|
taxi_axis_if #(.DATA_W(PTP_TS_W), .KEEP_W(1), .ID_EN(1), .ID_W(TX_TAG_W)) axis_tx_cpl_int();
|
||||||
taxi_axis_if #(.DATA_W(DATA_W), .KEEP_W(KEEP_W), .USER_EN(1), .USER_W(RX_USER_W)) axis_rx_int();
|
taxi_axis_if #(.DATA_W(DATA_W), .KEEP_W(KEEP_W), .USER_EN(1), .USER_W(RX_USER_W)) axis_rx_int();
|
||||||
|
|
||||||
wire [PTP_TS_W-1:0] tx_ptp_ts;
|
|
||||||
wire [PTP_TS_W-1:0] rx_ptp_ts;
|
|
||||||
|
|
||||||
wire tx_ptp_locked;
|
|
||||||
wire rx_ptp_locked;
|
|
||||||
|
|
||||||
// synchronize MAC status signals into logic clock domain
|
// synchronize MAC status signals into logic clock domain
|
||||||
wire tx_error_underflow_int;
|
wire tx_error_underflow_int;
|
||||||
|
|
||||||
@@ -195,7 +200,14 @@ always_ff @(posedge logic_clk or posedge logic_rst) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
// PTP timestamping
|
// PTP timestamping
|
||||||
if (PTP_TS_EN) begin : ptp
|
wire [PTP_TS_W-1:0] tx_ptp_ts_int;
|
||||||
|
wire tx_ptp_ts_step_int;
|
||||||
|
wire tx_ptp_locked_int;
|
||||||
|
wire [PTP_TS_W-1:0] rx_ptp_ts_int;
|
||||||
|
wire rx_ptp_ts_step_int;
|
||||||
|
wire rx_ptp_locked_int;
|
||||||
|
|
||||||
|
if (PTP_TS_EN && !PTP_TD_EN) begin : ptp
|
||||||
|
|
||||||
taxi_ptp_clock_cdc #(
|
taxi_ptp_clock_cdc #(
|
||||||
.TS_W(PTP_TS_W),
|
.TS_W(PTP_TS_W),
|
||||||
@@ -207,10 +219,10 @@ if (PTP_TS_EN) begin : ptp
|
|||||||
.output_clk(tx_clk),
|
.output_clk(tx_clk),
|
||||||
.output_rst(tx_rst),
|
.output_rst(tx_rst),
|
||||||
.sample_clk(ptp_sample_clk),
|
.sample_clk(ptp_sample_clk),
|
||||||
.input_ts(ptp_ts),
|
.input_ts(ptp_ts_in),
|
||||||
.input_ts_step(ptp_ts_step),
|
.input_ts_step(ptp_ts_step_in),
|
||||||
.output_ts(tx_ptp_ts),
|
.output_ts(tx_ptp_ts_int),
|
||||||
.output_ts_step(),
|
.output_ts_step(tx_ptp_ts_step_out),
|
||||||
.output_pps(),
|
.output_pps(),
|
||||||
.output_pps_str(),
|
.output_pps_str(),
|
||||||
.locked(tx_ptp_locked)
|
.locked(tx_ptp_locked)
|
||||||
@@ -226,10 +238,10 @@ if (PTP_TS_EN) begin : ptp
|
|||||||
.output_clk(rx_clk),
|
.output_clk(rx_clk),
|
||||||
.output_rst(rx_rst),
|
.output_rst(rx_rst),
|
||||||
.sample_clk(ptp_sample_clk),
|
.sample_clk(ptp_sample_clk),
|
||||||
.input_ts(ptp_ts),
|
.input_ts(ptp_ts_in),
|
||||||
.input_ts_step(ptp_ts_step),
|
.input_ts_step(ptp_ts_step_in),
|
||||||
.output_ts(rx_ptp_ts),
|
.output_ts(rx_ptp_ts_int),
|
||||||
.output_ts_step(),
|
.output_ts_step(rx_ptp_ts_step_out),
|
||||||
.output_pps(),
|
.output_pps(),
|
||||||
.output_pps_str(),
|
.output_pps_str(),
|
||||||
.locked(rx_ptp_locked)
|
.locked(rx_ptp_locked)
|
||||||
@@ -237,11 +249,13 @@ if (PTP_TS_EN) begin : ptp
|
|||||||
|
|
||||||
end else begin
|
end else begin
|
||||||
|
|
||||||
assign tx_ptp_ts = '0;
|
assign tx_ptp_ts_int = '0;
|
||||||
assign rx_ptp_ts = '0;
|
assign tx_ptp_ts_step_out = tx_ptp_ts_step_int;
|
||||||
|
assign rx_ptp_ts_int = '0;
|
||||||
|
assign rx_ptp_ts_step_out = rx_ptp_ts_step_int;
|
||||||
|
|
||||||
assign tx_ptp_locked = 1'b0;
|
assign tx_ptp_locked = tx_ptp_locked_int;
|
||||||
assign rx_ptp_locked = 1'b0;
|
assign rx_ptp_locked = rx_ptp_locked_int;
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -257,8 +271,10 @@ taxi_eth_mac_10g #(
|
|||||||
.DIC_EN(DIC_EN),
|
.DIC_EN(DIC_EN),
|
||||||
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
||||||
.PTP_TS_EN(PTP_TS_EN),
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
|
.PTP_TD_EN(PTP_TD_EN),
|
||||||
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
||||||
.PTP_TS_W(PTP_TS_W),
|
.PTP_TS_W(PTP_TS_W),
|
||||||
|
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
|
||||||
.PFC_EN(1'b0),
|
.PFC_EN(1'b0),
|
||||||
.PAUSE_EN(1'b0),
|
.PAUSE_EN(1'b0),
|
||||||
.STAT_EN(STAT_EN),
|
.STAT_EN(STAT_EN),
|
||||||
@@ -302,8 +318,18 @@ eth_mac_10g_inst (
|
|||||||
/*
|
/*
|
||||||
* PTP
|
* PTP
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts(tx_ptp_ts),
|
.ptp_clk(ptp_clk),
|
||||||
.rx_ptp_ts(rx_ptp_ts),
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_sample_clk(ptp_sample_clk),
|
||||||
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
.tx_ptp_ts_in(tx_ptp_ts_int),
|
||||||
|
.tx_ptp_ts_out(tx_ptp_ts_out),
|
||||||
|
.tx_ptp_ts_step_out(tx_ptp_ts_step_int),
|
||||||
|
.tx_ptp_locked(tx_ptp_locked_int),
|
||||||
|
.rx_ptp_ts_in(rx_ptp_ts_int),
|
||||||
|
.rx_ptp_ts_out(rx_ptp_ts_out),
|
||||||
|
.rx_ptp_ts_step_out(rx_ptp_ts_step_int),
|
||||||
|
.rx_ptp_locked(rx_ptp_locked_int),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ taxi_mac_pause_ctrl_tx.sv
|
|||||||
taxi_mac_pause_ctrl_rx.sv
|
taxi_mac_pause_ctrl_rx.sv
|
||||||
../lib/taxi/src/axis/rtl/taxi_axis_null_src.sv
|
../lib/taxi/src/axis/rtl/taxi_axis_null_src.sv
|
||||||
../lib/taxi/src/axis/rtl/taxi_axis_tie.sv
|
../lib/taxi/src/axis/rtl/taxi_axis_tie.sv
|
||||||
|
../lib/taxi/src/ptp/rtl/taxi_ptp_td_leaf.sv
|
||||||
../lib/taxi/src/sync/rtl/taxi_sync_signal.sv
|
../lib/taxi/src/sync/rtl/taxi_sync_signal.sv
|
||||||
|
|||||||
@@ -25,8 +25,10 @@ module taxi_eth_mac_phy_10g #
|
|||||||
parameter logic DIC_EN = 1'b1,
|
parameter logic DIC_EN = 1'b1,
|
||||||
parameter MIN_FRAME_LEN = 64,
|
parameter MIN_FRAME_LEN = 64,
|
||||||
parameter logic PTP_TS_EN = 1'b0,
|
parameter logic PTP_TS_EN = 1'b0,
|
||||||
|
parameter logic PTP_TD_EN = PTP_TS_EN,
|
||||||
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
||||||
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
||||||
|
parameter PTP_TD_SDI_PIPELINE = 2,
|
||||||
parameter logic BIT_REVERSE = 1'b0,
|
parameter logic BIT_REVERSE = 1'b0,
|
||||||
parameter logic SCRAMBLER_DISABLE = 1'b0,
|
parameter logic SCRAMBLER_DISABLE = 1'b0,
|
||||||
parameter logic PRBS31_EN = 1'b0,
|
parameter logic PRBS31_EN = 1'b0,
|
||||||
@@ -82,8 +84,18 @@ module taxi_eth_mac_phy_10g #
|
|||||||
/*
|
/*
|
||||||
* PTP
|
* PTP
|
||||||
*/
|
*/
|
||||||
input wire logic [PTP_TS_W-1:0] tx_ptp_ts,
|
input wire logic ptp_clk = 1'b0,
|
||||||
input wire logic [PTP_TS_W-1:0] rx_ptp_ts,
|
input wire logic ptp_rst = 1'b0,
|
||||||
|
input wire logic ptp_sample_clk = 1'b0,
|
||||||
|
input wire logic ptp_td_sdi = 1'b0,
|
||||||
|
input wire logic [PTP_TS_W-1:0] tx_ptp_ts_in = '0,
|
||||||
|
output wire logic [PTP_TS_W-1:0] tx_ptp_ts_out,
|
||||||
|
output wire logic tx_ptp_ts_step_out,
|
||||||
|
output wire logic tx_ptp_locked,
|
||||||
|
input wire logic [PTP_TS_W-1:0] rx_ptp_ts_in = '0,
|
||||||
|
output wire logic [PTP_TS_W-1:0] rx_ptp_ts_out,
|
||||||
|
output wire logic rx_ptp_ts_step_out,
|
||||||
|
output wire logic rx_ptp_locked,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
@@ -226,6 +238,123 @@ localparam TX_USER_W_INT = (MAC_CTRL_EN ? 1 : 0) + TX_USER_W;
|
|||||||
taxi_axis_if #(.DATA_W(DATA_W), .USER_EN(1), .USER_W(TX_USER_W_INT), .ID_EN(1), .ID_W(TX_TAG_W)) axis_tx_int();
|
taxi_axis_if #(.DATA_W(DATA_W), .USER_EN(1), .USER_W(TX_USER_W_INT), .ID_EN(1), .ID_W(TX_TAG_W)) axis_tx_int();
|
||||||
taxi_axis_if #(.DATA_W(DATA_W), .USER_EN(1), .USER_W(RX_USER_W)) axis_rx_int();
|
taxi_axis_if #(.DATA_W(DATA_W), .USER_EN(1), .USER_W(RX_USER_W)) axis_rx_int();
|
||||||
|
|
||||||
|
// PTP timestamping
|
||||||
|
if (PTP_TS_EN && PTP_TD_EN) begin : ptp
|
||||||
|
|
||||||
|
// TX
|
||||||
|
wire [PTP_TS_W-1:0] tx_ptp_ts_rel;
|
||||||
|
wire tx_ptp_ts_rel_step;
|
||||||
|
wire [PTP_TS_W-1:0] tx_ptp_ts_tod;
|
||||||
|
wire tx_ptp_ts_tod_step;
|
||||||
|
|
||||||
|
taxi_ptp_td_leaf #(
|
||||||
|
.TS_REL_EN(!PTP_TS_FMT_TOD),
|
||||||
|
.TS_TOD_EN(PTP_TS_FMT_TOD),
|
||||||
|
.TS_FNS_W(16),
|
||||||
|
.TS_REL_NS_W(PTP_TS_FMT_TOD ? 48 : PTP_TS_W-16),
|
||||||
|
.TS_TOD_S_W(PTP_TS_FMT_TOD ? PTP_TS_W-32-16 : 48),
|
||||||
|
.TS_REL_W(PTP_TS_W),
|
||||||
|
.TS_TOD_W(PTP_TS_W),
|
||||||
|
.TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE)
|
||||||
|
)
|
||||||
|
tx_leaf_inst (
|
||||||
|
.clk(tx_clk),
|
||||||
|
.rst(tx_rst),
|
||||||
|
.sample_clk(ptp_sample_clk),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP clock interface
|
||||||
|
*/
|
||||||
|
.ptp_clk(ptp_clk),
|
||||||
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timestamp output
|
||||||
|
*/
|
||||||
|
.output_ts_rel(tx_ptp_ts_rel),
|
||||||
|
.output_ts_rel_step(tx_ptp_ts_rel_step),
|
||||||
|
.output_ts_tod(tx_ptp_ts_tod),
|
||||||
|
.output_ts_tod_step(tx_ptp_ts_tod_step),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PPS output (ToD format only)
|
||||||
|
*/
|
||||||
|
.output_pps(),
|
||||||
|
.output_pps_str(),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Status
|
||||||
|
*/
|
||||||
|
.locked(tx_ptp_locked)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign tx_ptp_ts_out = PTP_TS_FMT_TOD ? tx_ptp_ts_tod : tx_ptp_ts_rel;
|
||||||
|
assign tx_ptp_ts_step_out = PTP_TS_FMT_TOD ? tx_ptp_ts_tod_step : tx_ptp_ts_rel_step;
|
||||||
|
|
||||||
|
// RX
|
||||||
|
wire [PTP_TS_W-1:0] rx_ptp_ts_rel;
|
||||||
|
wire rx_ptp_ts_rel_step;
|
||||||
|
wire [PTP_TS_W-1:0] rx_ptp_ts_tod;
|
||||||
|
wire rx_ptp_ts_tod_step;
|
||||||
|
|
||||||
|
taxi_ptp_td_leaf #(
|
||||||
|
.TS_REL_EN(!PTP_TS_FMT_TOD),
|
||||||
|
.TS_TOD_EN(PTP_TS_FMT_TOD),
|
||||||
|
.TS_FNS_W(16),
|
||||||
|
.TS_REL_NS_W(PTP_TS_FMT_TOD ? 48 : PTP_TS_W-16),
|
||||||
|
.TS_TOD_S_W(PTP_TS_FMT_TOD ? PTP_TS_W-32-16 : 48),
|
||||||
|
.TS_REL_W(PTP_TS_W),
|
||||||
|
.TS_TOD_W(PTP_TS_W),
|
||||||
|
.TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE)
|
||||||
|
)
|
||||||
|
rx_leaf_inst (
|
||||||
|
.clk(rx_clk),
|
||||||
|
.rst(rx_rst),
|
||||||
|
.sample_clk(ptp_sample_clk),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP clock interface
|
||||||
|
*/
|
||||||
|
.ptp_clk(ptp_clk),
|
||||||
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timestamp output
|
||||||
|
*/
|
||||||
|
.output_ts_rel(rx_ptp_ts_rel),
|
||||||
|
.output_ts_rel_step(rx_ptp_ts_rel_step),
|
||||||
|
.output_ts_tod(rx_ptp_ts_tod),
|
||||||
|
.output_ts_tod_step(rx_ptp_ts_tod_step),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PPS output (ToD format only)
|
||||||
|
*/
|
||||||
|
.output_pps(),
|
||||||
|
.output_pps_str(),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Status
|
||||||
|
*/
|
||||||
|
.locked(rx_ptp_locked)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign rx_ptp_ts_out = PTP_TS_FMT_TOD ? rx_ptp_ts_tod : rx_ptp_ts_rel;
|
||||||
|
assign rx_ptp_ts_step_out = PTP_TS_FMT_TOD ? rx_ptp_ts_tod_step : rx_ptp_ts_rel_step;
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
assign tx_ptp_ts_out = tx_ptp_ts_in;
|
||||||
|
assign tx_ptp_ts_step_out = 1'b0;
|
||||||
|
assign rx_ptp_ts_out = rx_ptp_ts_in;
|
||||||
|
assign rx_ptp_ts_step_out = 1'b0;
|
||||||
|
|
||||||
|
assign tx_ptp_locked = 1'b0;
|
||||||
|
assign rx_ptp_locked = 1'b0;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
taxi_eth_mac_phy_10g_rx #(
|
taxi_eth_mac_phy_10g_rx #(
|
||||||
.DATA_W(DATA_W),
|
.DATA_W(DATA_W),
|
||||||
.HDR_W(HDR_W),
|
.HDR_W(HDR_W),
|
||||||
@@ -263,7 +392,7 @@ eth_mac_phy_10g_rx_inst (
|
|||||||
/*
|
/*
|
||||||
* PTP
|
* PTP
|
||||||
*/
|
*/
|
||||||
.ptp_ts(rx_ptp_ts),
|
.ptp_ts(rx_ptp_ts_out),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Status
|
* Status
|
||||||
@@ -337,7 +466,7 @@ eth_mac_phy_10g_tx_inst (
|
|||||||
/*
|
/*
|
||||||
* PTP
|
* PTP
|
||||||
*/
|
*/
|
||||||
.ptp_ts(tx_ptp_ts),
|
.ptp_ts(tx_ptp_ts_out),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Status
|
* Status
|
||||||
|
|||||||
@@ -25,8 +25,10 @@ module taxi_eth_mac_phy_10g_fifo #
|
|||||||
parameter logic DIC_EN = 1'b1,
|
parameter logic DIC_EN = 1'b1,
|
||||||
parameter MIN_FRAME_LEN = 64,
|
parameter MIN_FRAME_LEN = 64,
|
||||||
parameter logic PTP_TS_EN = 1'b0,
|
parameter logic PTP_TS_EN = 1'b0,
|
||||||
|
parameter logic PTP_TD_EN = PTP_TS_EN,
|
||||||
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
||||||
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
||||||
|
parameter PTP_TD_SDI_PIPELINE = 2,
|
||||||
parameter logic BIT_REVERSE = 1'b0,
|
parameter logic BIT_REVERSE = 1'b0,
|
||||||
parameter logic SCRAMBLER_DISABLE = 1'b0,
|
parameter logic SCRAMBLER_DISABLE = 1'b0,
|
||||||
parameter logic PRBS31_EN = 1'b0,
|
parameter logic PRBS31_EN = 1'b0,
|
||||||
@@ -63,7 +65,6 @@ module taxi_eth_mac_phy_10g_fifo #
|
|||||||
input wire logic tx_rst,
|
input wire logic tx_rst,
|
||||||
input wire logic logic_clk,
|
input wire logic logic_clk,
|
||||||
input wire logic logic_rst,
|
input wire logic logic_rst,
|
||||||
input wire logic ptp_sample_clk,
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -96,8 +97,18 @@ module taxi_eth_mac_phy_10g_fifo #
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
input wire logic [PTP_TS_W-1:0] ptp_ts = '0,
|
input wire logic ptp_clk = 1'b0,
|
||||||
input wire logic ptp_ts_step = 1'b0,
|
input wire logic ptp_rst = 1'b0,
|
||||||
|
input wire logic ptp_sample_clk = 1'b0,
|
||||||
|
input wire logic ptp_td_sdi = 1'b0,
|
||||||
|
input wire logic [PTP_TS_W-1:0] ptp_ts_in = '0,
|
||||||
|
input wire logic ptp_ts_step_in = 1'b0,
|
||||||
|
output wire logic [PTP_TS_W-1:0] tx_ptp_ts_out,
|
||||||
|
output wire logic tx_ptp_ts_step_out,
|
||||||
|
output wire logic tx_ptp_locked,
|
||||||
|
output wire logic [PTP_TS_W-1:0] rx_ptp_ts_out,
|
||||||
|
output wire logic rx_ptp_ts_step_out,
|
||||||
|
output wire logic rx_ptp_locked,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Statistics
|
* Statistics
|
||||||
@@ -145,12 +156,6 @@ taxi_axis_if #(.DATA_W(DATA_W), .KEEP_W(KEEP_W), .USER_EN(1), .USER_W(TX_USER_W)
|
|||||||
taxi_axis_if #(.DATA_W(PTP_TS_W), .KEEP_W(1), .ID_EN(1), .ID_W(TX_TAG_W)) axis_tx_cpl_int();
|
taxi_axis_if #(.DATA_W(PTP_TS_W), .KEEP_W(1), .ID_EN(1), .ID_W(TX_TAG_W)) axis_tx_cpl_int();
|
||||||
taxi_axis_if #(.DATA_W(DATA_W), .KEEP_W(KEEP_W), .USER_EN(1), .USER_W(RX_USER_W)) axis_rx_int();
|
taxi_axis_if #(.DATA_W(DATA_W), .KEEP_W(KEEP_W), .USER_EN(1), .USER_W(RX_USER_W)) axis_rx_int();
|
||||||
|
|
||||||
wire [PTP_TS_W-1:0] tx_ptp_ts;
|
|
||||||
wire [PTP_TS_W-1:0] rx_ptp_ts;
|
|
||||||
|
|
||||||
wire tx_ptp_locked;
|
|
||||||
wire rx_ptp_locked;
|
|
||||||
|
|
||||||
// synchronize MAC status signals into logic clock domain
|
// synchronize MAC status signals into logic clock domain
|
||||||
wire tx_error_underflow_int;
|
wire tx_error_underflow_int;
|
||||||
|
|
||||||
@@ -229,7 +234,14 @@ always_ff @(posedge logic_clk or posedge logic_rst) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
// PTP timestamping
|
// PTP timestamping
|
||||||
if (PTP_TS_EN) begin : ptp
|
wire [PTP_TS_W-1:0] tx_ptp_ts_int;
|
||||||
|
wire tx_ptp_ts_step_int;
|
||||||
|
wire tx_ptp_locked_int;
|
||||||
|
wire [PTP_TS_W-1:0] rx_ptp_ts_int;
|
||||||
|
wire rx_ptp_ts_step_int;
|
||||||
|
wire rx_ptp_locked_int;
|
||||||
|
|
||||||
|
if (PTP_TS_EN && !PTP_TD_EN) begin : ptp
|
||||||
|
|
||||||
taxi_ptp_clock_cdc #(
|
taxi_ptp_clock_cdc #(
|
||||||
.TS_W(PTP_TS_W),
|
.TS_W(PTP_TS_W),
|
||||||
@@ -241,10 +253,10 @@ if (PTP_TS_EN) begin : ptp
|
|||||||
.output_clk(tx_clk),
|
.output_clk(tx_clk),
|
||||||
.output_rst(tx_rst),
|
.output_rst(tx_rst),
|
||||||
.sample_clk(ptp_sample_clk),
|
.sample_clk(ptp_sample_clk),
|
||||||
.input_ts(ptp_ts),
|
.input_ts(ptp_ts_in),
|
||||||
.input_ts_step(ptp_ts_step),
|
.input_ts_step(ptp_ts_step_in),
|
||||||
.output_ts(tx_ptp_ts),
|
.output_ts(tx_ptp_ts_int),
|
||||||
.output_ts_step(),
|
.output_ts_step(tx_ptp_ts_step_out),
|
||||||
.output_pps(),
|
.output_pps(),
|
||||||
.output_pps_str(),
|
.output_pps_str(),
|
||||||
.locked(tx_ptp_locked)
|
.locked(tx_ptp_locked)
|
||||||
@@ -260,10 +272,10 @@ if (PTP_TS_EN) begin : ptp
|
|||||||
.output_clk(rx_clk),
|
.output_clk(rx_clk),
|
||||||
.output_rst(rx_rst),
|
.output_rst(rx_rst),
|
||||||
.sample_clk(ptp_sample_clk),
|
.sample_clk(ptp_sample_clk),
|
||||||
.input_ts(ptp_ts),
|
.input_ts(ptp_ts_in),
|
||||||
.input_ts_step(ptp_ts_step),
|
.input_ts_step(ptp_ts_step_in),
|
||||||
.output_ts(rx_ptp_ts),
|
.output_ts(rx_ptp_ts_int),
|
||||||
.output_ts_step(),
|
.output_ts_step(rx_ptp_ts_step_out),
|
||||||
.output_pps(),
|
.output_pps(),
|
||||||
.output_pps_str(),
|
.output_pps_str(),
|
||||||
.locked(rx_ptp_locked)
|
.locked(rx_ptp_locked)
|
||||||
@@ -271,11 +283,13 @@ if (PTP_TS_EN) begin : ptp
|
|||||||
|
|
||||||
end else begin
|
end else begin
|
||||||
|
|
||||||
assign tx_ptp_ts = '0;
|
assign tx_ptp_ts_int = '0;
|
||||||
assign rx_ptp_ts = '0;
|
assign tx_ptp_ts_step_out = tx_ptp_ts_step_int;
|
||||||
|
assign rx_ptp_ts_int = '0;
|
||||||
|
assign rx_ptp_ts_step_out = rx_ptp_ts_step_int;
|
||||||
|
|
||||||
assign tx_ptp_locked = 1'b0;
|
assign tx_ptp_locked = tx_ptp_locked_int;
|
||||||
assign rx_ptp_locked = 1'b0;
|
assign rx_ptp_locked = rx_ptp_locked_int;
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -290,8 +304,10 @@ taxi_eth_mac_phy_10g #(
|
|||||||
.DIC_EN(DIC_EN),
|
.DIC_EN(DIC_EN),
|
||||||
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
||||||
.PTP_TS_EN(PTP_TS_EN),
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
|
.PTP_TD_EN(PTP_TD_EN),
|
||||||
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
||||||
.PTP_TS_W(PTP_TS_W),
|
.PTP_TS_W(PTP_TS_W),
|
||||||
|
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
|
||||||
.BIT_REVERSE(BIT_REVERSE),
|
.BIT_REVERSE(BIT_REVERSE),
|
||||||
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE),
|
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE),
|
||||||
.PRBS31_EN(PRBS31_EN),
|
.PRBS31_EN(PRBS31_EN),
|
||||||
@@ -345,8 +361,18 @@ eth_mac_phy_10g_inst (
|
|||||||
/*
|
/*
|
||||||
* PTP
|
* PTP
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts(tx_ptp_ts),
|
.ptp_clk(ptp_clk),
|
||||||
.rx_ptp_ts(rx_ptp_ts),
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_sample_clk(ptp_sample_clk),
|
||||||
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
.tx_ptp_ts_in(tx_ptp_ts_int),
|
||||||
|
.tx_ptp_ts_out(tx_ptp_ts_out),
|
||||||
|
.tx_ptp_ts_step_out(tx_ptp_ts_step_int),
|
||||||
|
.tx_ptp_locked(tx_ptp_locked_int),
|
||||||
|
.rx_ptp_ts_in(rx_ptp_ts_int),
|
||||||
|
.rx_ptp_ts_out(rx_ptp_ts_out),
|
||||||
|
.rx_ptp_ts_step_out(rx_ptp_ts_step_int),
|
||||||
|
.rx_ptp_locked(rx_ptp_locked_int),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -58,8 +58,10 @@ module taxi_eth_mac_25g_us #
|
|||||||
parameter logic DIC_EN = 1'b1,
|
parameter logic DIC_EN = 1'b1,
|
||||||
parameter MIN_FRAME_LEN = 64,
|
parameter MIN_FRAME_LEN = 64,
|
||||||
parameter logic PTP_TS_EN = 1'b0,
|
parameter logic PTP_TS_EN = 1'b0,
|
||||||
|
parameter logic PTP_TD_EN = PTP_TS_EN,
|
||||||
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
||||||
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
||||||
|
parameter PTP_TD_SDI_PIPELINE = 2,
|
||||||
parameter logic PRBS31_EN = 1'b0,
|
parameter logic PRBS31_EN = 1'b0,
|
||||||
parameter TX_SERDES_PIPELINE = 1,
|
parameter TX_SERDES_PIPELINE = 1,
|
||||||
parameter RX_SERDES_PIPELINE = 1,
|
parameter RX_SERDES_PIPELINE = 1,
|
||||||
@@ -121,7 +123,6 @@ module taxi_eth_mac_25g_us #
|
|||||||
output wire logic tx_clk[CNT],
|
output wire logic tx_clk[CNT],
|
||||||
input wire logic tx_rst_in[CNT] = '{CNT{1'b0}},
|
input wire logic tx_rst_in[CNT] = '{CNT{1'b0}},
|
||||||
output wire logic tx_rst_out[CNT],
|
output wire logic tx_rst_out[CNT],
|
||||||
input wire logic ptp_sample_clk[CNT] = '{CNT{1'b0}},
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -137,10 +138,18 @@ module taxi_eth_mac_25g_us #
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
input wire logic [PTP_TS_W-1:0] tx_ptp_ts[CNT] = '{CNT{'0}},
|
input wire logic ptp_clk = 1'b0,
|
||||||
input wire logic tx_ptp_ts_step[CNT] = '{CNT{1'b0}},
|
input wire logic ptp_rst = 1'b0,
|
||||||
input wire logic [PTP_TS_W-1:0] rx_ptp_ts[CNT] = '{CNT{'0}},
|
input wire logic ptp_sample_clk = 1'b0,
|
||||||
input wire logic rx_ptp_ts_step[CNT] = '{CNT{1'b0}},
|
input wire logic ptp_td_sdi = 1'b0,
|
||||||
|
input wire logic [PTP_TS_W-1:0] tx_ptp_ts_in[CNT] = '{CNT{'0}},
|
||||||
|
output wire logic [PTP_TS_W-1:0] tx_ptp_ts_out[CNT],
|
||||||
|
output wire logic tx_ptp_ts_step_out[CNT],
|
||||||
|
output wire logic tx_ptp_locked[CNT],
|
||||||
|
input wire logic [PTP_TS_W-1:0] rx_ptp_ts_in[CNT] = '{CNT{'0}},
|
||||||
|
output wire logic [PTP_TS_W-1:0] rx_ptp_ts_out[CNT],
|
||||||
|
output wire logic rx_ptp_ts_step_out[CNT],
|
||||||
|
output wire logic rx_ptp_locked[CNT],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
@@ -420,8 +429,10 @@ for (genvar n = 0; n < CNT; n = n + 1) begin : ch
|
|||||||
.DIC_EN(DIC_EN),
|
.DIC_EN(DIC_EN),
|
||||||
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
||||||
.PTP_TS_EN(PTP_TS_EN),
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
|
.PTP_TD_EN(PTP_TD_EN),
|
||||||
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
||||||
.PTP_TS_W(PTP_TS_W),
|
.PTP_TS_W(PTP_TS_W),
|
||||||
|
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
|
||||||
.PRBS31_EN(PRBS31_EN),
|
.PRBS31_EN(PRBS31_EN),
|
||||||
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),
|
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),
|
||||||
.RX_SERDES_PIPELINE(RX_SERDES_PIPELINE),
|
.RX_SERDES_PIPELINE(RX_SERDES_PIPELINE),
|
||||||
@@ -497,7 +508,6 @@ for (genvar n = 0; n < CNT; n = n + 1) begin : ch
|
|||||||
.tx_clk(tx_clk[n]),
|
.tx_clk(tx_clk[n]),
|
||||||
.tx_rst_in(tx_rst_in[n]),
|
.tx_rst_in(tx_rst_in[n]),
|
||||||
.tx_rst_out(tx_rst_out[n]),
|
.tx_rst_out(tx_rst_out[n]),
|
||||||
.ptp_sample_clk(ptp_sample_clk[n]),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -513,10 +523,18 @@ for (genvar n = 0; n < CNT; n = n + 1) begin : ch
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts(tx_ptp_ts[n]),
|
.ptp_clk(ptp_clk),
|
||||||
.tx_ptp_ts_step(tx_ptp_ts_step[n]),
|
.ptp_rst(ptp_rst),
|
||||||
.rx_ptp_ts(rx_ptp_ts[n]),
|
.ptp_sample_clk(ptp_sample_clk),
|
||||||
.rx_ptp_ts_step(rx_ptp_ts_step[n]),
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
.tx_ptp_ts_in(tx_ptp_ts_in[n]),
|
||||||
|
.tx_ptp_ts_out(tx_ptp_ts_out[n]),
|
||||||
|
.tx_ptp_ts_step_out(tx_ptp_ts_step_out[n]),
|
||||||
|
.tx_ptp_locked(tx_ptp_locked[n]),
|
||||||
|
.rx_ptp_ts_in(rx_ptp_ts_in[n]),
|
||||||
|
.rx_ptp_ts_out(rx_ptp_ts_out[n]),
|
||||||
|
.rx_ptp_ts_step_out(rx_ptp_ts_step_out[n]),
|
||||||
|
.rx_ptp_locked(rx_ptp_locked[n]),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -57,8 +57,10 @@ module taxi_eth_mac_25g_us_ch #
|
|||||||
parameter logic DIC_EN = 1'b1,
|
parameter logic DIC_EN = 1'b1,
|
||||||
parameter MIN_FRAME_LEN = 64,
|
parameter MIN_FRAME_LEN = 64,
|
||||||
parameter logic PTP_TS_EN = 1'b0,
|
parameter logic PTP_TS_EN = 1'b0,
|
||||||
|
parameter logic PTP_TD_EN = PTP_TS_EN,
|
||||||
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
||||||
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
||||||
|
parameter PTP_TD_SDI_PIPELINE = 2,
|
||||||
parameter logic PRBS31_EN = 1'b0,
|
parameter logic PRBS31_EN = 1'b0,
|
||||||
parameter TX_SERDES_PIPELINE = 1,
|
parameter TX_SERDES_PIPELINE = 1,
|
||||||
parameter RX_SERDES_PIPELINE = 1,
|
parameter RX_SERDES_PIPELINE = 1,
|
||||||
@@ -134,7 +136,6 @@ module taxi_eth_mac_25g_us_ch #
|
|||||||
output wire logic tx_clk,
|
output wire logic tx_clk,
|
||||||
input wire logic tx_rst_in = 1'b0,
|
input wire logic tx_rst_in = 1'b0,
|
||||||
output wire logic tx_rst_out,
|
output wire logic tx_rst_out,
|
||||||
input wire logic ptp_sample_clk = 1'b0,
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -150,10 +151,18 @@ module taxi_eth_mac_25g_us_ch #
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
input wire logic [PTP_TS_W-1:0] tx_ptp_ts = '0,
|
input wire logic ptp_clk = 1'b0,
|
||||||
input wire logic tx_ptp_ts_step = 1'b0,
|
input wire logic ptp_rst = 1'b0,
|
||||||
input wire logic [PTP_TS_W-1:0] rx_ptp_ts = '0,
|
input wire logic ptp_sample_clk = 1'b0,
|
||||||
input wire logic rx_ptp_ts_step = 1'b0,
|
input wire logic ptp_td_sdi = 1'b0,
|
||||||
|
input wire logic [PTP_TS_W-1:0] tx_ptp_ts_in = '0,
|
||||||
|
output wire logic [PTP_TS_W-1:0] tx_ptp_ts_out,
|
||||||
|
output wire logic tx_ptp_ts_step_out,
|
||||||
|
output wire logic tx_ptp_locked,
|
||||||
|
input wire logic [PTP_TS_W-1:0] rx_ptp_ts_in = '0,
|
||||||
|
output wire logic [PTP_TS_W-1:0] rx_ptp_ts_out,
|
||||||
|
output wire logic rx_ptp_ts_step_out,
|
||||||
|
output wire logic rx_ptp_locked,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
@@ -878,8 +887,10 @@ if (COMBINED_MAC_PCS) begin : mac
|
|||||||
.DIC_EN(DIC_EN),
|
.DIC_EN(DIC_EN),
|
||||||
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
||||||
.PTP_TS_EN(PTP_TS_EN),
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
|
.PTP_TD_EN(PTP_TD_EN),
|
||||||
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
||||||
.PTP_TS_W(PTP_TS_W),
|
.PTP_TS_W(PTP_TS_W),
|
||||||
|
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
|
||||||
.BIT_REVERSE(1'b1),
|
.BIT_REVERSE(1'b1),
|
||||||
.SCRAMBLER_DISABLE(1'b0),
|
.SCRAMBLER_DISABLE(1'b0),
|
||||||
.PRBS31_EN(PRBS31_EN),
|
.PRBS31_EN(PRBS31_EN),
|
||||||
@@ -935,8 +946,18 @@ if (COMBINED_MAC_PCS) begin : mac
|
|||||||
/*
|
/*
|
||||||
* PTP
|
* PTP
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts(tx_ptp_ts),
|
.ptp_clk(ptp_clk),
|
||||||
.rx_ptp_ts(rx_ptp_ts),
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_sample_clk(ptp_sample_clk),
|
||||||
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
.tx_ptp_ts_in(tx_ptp_ts_in),
|
||||||
|
.tx_ptp_ts_out(tx_ptp_ts_out),
|
||||||
|
.tx_ptp_ts_step_out(tx_ptp_ts_step_out),
|
||||||
|
.tx_ptp_locked(tx_ptp_locked),
|
||||||
|
.rx_ptp_ts_in(rx_ptp_ts_in),
|
||||||
|
.rx_ptp_ts_out(rx_ptp_ts_out),
|
||||||
|
.rx_ptp_ts_step_out(rx_ptp_ts_step_out),
|
||||||
|
.rx_ptp_locked(rx_ptp_locked),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
@@ -1160,8 +1181,10 @@ end else begin : mac
|
|||||||
.DIC_EN(DIC_EN),
|
.DIC_EN(DIC_EN),
|
||||||
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
||||||
.PTP_TS_EN(PTP_TS_EN),
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
|
.PTP_TD_EN(PTP_TD_EN),
|
||||||
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
||||||
.PTP_TS_W(PTP_TS_W),
|
.PTP_TS_W(PTP_TS_W),
|
||||||
|
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
|
||||||
.PFC_EN(PFC_EN),
|
.PFC_EN(PFC_EN),
|
||||||
.PAUSE_EN(PAUSE_EN),
|
.PAUSE_EN(PAUSE_EN),
|
||||||
.STAT_EN(STAT_EN),
|
.STAT_EN(STAT_EN),
|
||||||
@@ -1205,8 +1228,18 @@ end else begin : mac
|
|||||||
/*
|
/*
|
||||||
* PTP
|
* PTP
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts(tx_ptp_ts),
|
.ptp_clk(ptp_clk),
|
||||||
.rx_ptp_ts(rx_ptp_ts),
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_sample_clk(ptp_sample_clk),
|
||||||
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
.tx_ptp_ts_in(tx_ptp_ts_in),
|
||||||
|
.tx_ptp_ts_out(tx_ptp_ts_out),
|
||||||
|
.tx_ptp_ts_step_out(tx_ptp_ts_step_out),
|
||||||
|
.tx_ptp_locked(tx_ptp_locked),
|
||||||
|
.rx_ptp_ts_in(rx_ptp_ts_in),
|
||||||
|
.rx_ptp_ts_out(rx_ptp_ts_out),
|
||||||
|
.rx_ptp_ts_step_out(rx_ptp_ts_step_out),
|
||||||
|
.rx_ptp_locked(rx_ptp_locked),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -40,8 +40,10 @@ export PARAM_PADDING_EN := 1
|
|||||||
export PARAM_DIC_EN := 1
|
export PARAM_DIC_EN := 1
|
||||||
export PARAM_MIN_FRAME_LEN := 64
|
export PARAM_MIN_FRAME_LEN := 64
|
||||||
export PARAM_PTP_TS_EN := 1
|
export PARAM_PTP_TS_EN := 1
|
||||||
|
export PARAM_PTP_TD_EN := $(PARAM_PTP_TS_EN)
|
||||||
export PARAM_PTP_TS_FMT_TOD := 1
|
export PARAM_PTP_TS_FMT_TOD := 1
|
||||||
export PARAM_PTP_TS_W := $(if $(filter-out 1,$(PARAM_PTP_TS_FMT_TOD)),64,96)
|
export PARAM_PTP_TS_W := $(if $(filter-out 1,$(PARAM_PTP_TS_FMT_TOD)),64,96)
|
||||||
|
export PARAM_PTP_TD_SDI_PIPELINE := 2
|
||||||
export PARAM_TX_TAG_W := 16
|
export PARAM_TX_TAG_W := 16
|
||||||
export PARAM_PFC_EN := 1
|
export PARAM_PFC_EN := 1
|
||||||
export PARAM_PAUSE_EN := $(PARAM_PFC_EN)
|
export PARAM_PAUSE_EN := $(PARAM_PFC_EN)
|
||||||
|
|||||||
1
src/eth/tb/taxi_eth_mac_10g/ptp_td.py
Symbolic link
1
src/eth/tb/taxi_eth_mac_10g/ptp_td.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../lib/taxi/src/ptp/tb/ptp_td.py
|
||||||
@@ -13,6 +13,7 @@ import itertools
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import struct
|
import struct
|
||||||
|
import sys
|
||||||
|
|
||||||
from scapy.layers.l2 import Ether
|
from scapy.layers.l2 import Ether
|
||||||
|
|
||||||
@@ -28,6 +29,16 @@ from cocotb.regression import TestFactory
|
|||||||
from cocotbext.eth import XgmiiFrame, XgmiiSource, XgmiiSink, PtpClockSimTime
|
from cocotbext.eth import XgmiiFrame, XgmiiSource, XgmiiSink, PtpClockSimTime
|
||||||
from cocotbext.axi import AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiStreamFrame
|
from cocotbext.axi import AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiStreamFrame
|
||||||
|
|
||||||
|
try:
|
||||||
|
from ptp_td import PtpTdSource
|
||||||
|
except ImportError:
|
||||||
|
# attempt import from current directory
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__)))
|
||||||
|
try:
|
||||||
|
from ptp_td import PtpTdSource
|
||||||
|
finally:
|
||||||
|
del sys.path[0]
|
||||||
|
|
||||||
|
|
||||||
class TB:
|
class TB:
|
||||||
def __init__(self, dut):
|
def __init__(self, dut):
|
||||||
@@ -54,8 +65,20 @@ class TB:
|
|||||||
|
|
||||||
self.stat_sink = AxiStreamSink(AxiStreamBus.from_entity(dut.m_axis_stat), dut.stat_clk, dut.stat_rst)
|
self.stat_sink = AxiStreamSink(AxiStreamBus.from_entity(dut.m_axis_stat), dut.stat_clk, dut.stat_rst)
|
||||||
|
|
||||||
self.rx_ptp_clock = PtpClockSimTime(ts_tod=dut.rx_ptp_ts, clock=dut.rx_clk)
|
self.rx_ptp_clock = PtpClockSimTime(ts_tod=dut.rx_ptp_ts_in, clock=dut.rx_clk)
|
||||||
self.tx_ptp_clock = PtpClockSimTime(ts_tod=dut.tx_ptp_ts, clock=dut.tx_clk)
|
self.tx_ptp_clock = PtpClockSimTime(ts_tod=dut.tx_ptp_ts_in, clock=dut.tx_clk)
|
||||||
|
|
||||||
|
self.ptp_clk_period = self.clk_period
|
||||||
|
|
||||||
|
cocotb.start_soon(Clock(dut.ptp_clk, self.ptp_clk_period, units="ns").start())
|
||||||
|
cocotb.start_soon(Clock(dut.ptp_sample_clk, 8, units="ns").start())
|
||||||
|
|
||||||
|
self.ptp_td_source = PtpTdSource(
|
||||||
|
data=dut.ptp_td_sdi,
|
||||||
|
clock=dut.ptp_clk,
|
||||||
|
reset=dut.ptp_rst,
|
||||||
|
period_ns=self.ptp_clk_period
|
||||||
|
)
|
||||||
|
|
||||||
dut.tx_lfc_req.setimmediatevalue(0)
|
dut.tx_lfc_req.setimmediatevalue(0)
|
||||||
dut.tx_lfc_resend.setimmediatevalue(0)
|
dut.tx_lfc_resend.setimmediatevalue(0)
|
||||||
@@ -112,20 +135,26 @@ class TB:
|
|||||||
async def reset(self):
|
async def reset(self):
|
||||||
self.dut.rx_rst.setimmediatevalue(0)
|
self.dut.rx_rst.setimmediatevalue(0)
|
||||||
self.dut.tx_rst.setimmediatevalue(0)
|
self.dut.tx_rst.setimmediatevalue(0)
|
||||||
|
self.dut.ptp_rst.setimmediatevalue(0)
|
||||||
self.dut.stat_rst.setimmediatevalue(0)
|
self.dut.stat_rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.rx_clk)
|
await RisingEdge(self.dut.rx_clk)
|
||||||
await RisingEdge(self.dut.rx_clk)
|
await RisingEdge(self.dut.rx_clk)
|
||||||
self.dut.rx_rst.value = 1
|
self.dut.rx_rst.value = 1
|
||||||
self.dut.tx_rst.value = 1
|
self.dut.tx_rst.value = 1
|
||||||
|
self.dut.ptp_rst.value = 1
|
||||||
self.dut.stat_rst.value = 1
|
self.dut.stat_rst.value = 1
|
||||||
await RisingEdge(self.dut.rx_clk)
|
await RisingEdge(self.dut.rx_clk)
|
||||||
await RisingEdge(self.dut.rx_clk)
|
await RisingEdge(self.dut.rx_clk)
|
||||||
self.dut.rx_rst.value = 0
|
self.dut.rx_rst.value = 0
|
||||||
self.dut.tx_rst.value = 0
|
self.dut.tx_rst.value = 0
|
||||||
|
self.dut.ptp_rst.value = 0
|
||||||
self.dut.stat_rst.value = 0
|
self.dut.stat_rst.value = 0
|
||||||
await RisingEdge(self.dut.rx_clk)
|
await RisingEdge(self.dut.rx_clk)
|
||||||
await RisingEdge(self.dut.rx_clk)
|
await RisingEdge(self.dut.rx_clk)
|
||||||
|
|
||||||
|
self.ptp_td_source.set_ts_tod_sim_time()
|
||||||
|
self.ptp_td_source.set_ts_rel_sim_time()
|
||||||
|
|
||||||
|
|
||||||
async def run_test_rx(dut, payload_lengths=None, payload_data=None, ifg=12):
|
async def run_test_rx(dut, payload_lengths=None, payload_data=None, ifg=12):
|
||||||
|
|
||||||
@@ -138,6 +167,13 @@ async def run_test_rx(dut, payload_lengths=None, payload_data=None, ifg=12):
|
|||||||
|
|
||||||
await tb.reset()
|
await tb.reset()
|
||||||
|
|
||||||
|
if dut.PTP_TD_EN.value:
|
||||||
|
tb.log.info("Wait for PTP CDC lock")
|
||||||
|
while not int(dut.rx_ptp_locked.value):
|
||||||
|
await RisingEdge(dut.rx_clk)
|
||||||
|
for k in range(2000):
|
||||||
|
await RisingEdge(dut.rx_clk)
|
||||||
|
|
||||||
test_frames = [payload_data(x) for x in payload_lengths()]
|
test_frames = [payload_data(x) for x in payload_lengths()]
|
||||||
tx_frames = []
|
tx_frames = []
|
||||||
|
|
||||||
@@ -165,7 +201,10 @@ async def run_test_rx(dut, payload_lengths=None, payload_data=None, ifg=12):
|
|||||||
|
|
||||||
assert rx_frame.tdata == test_data
|
assert rx_frame.tdata == test_data
|
||||||
assert frame_error == 0
|
assert frame_error == 0
|
||||||
assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period) < 0.01
|
if dut.PTP_TD_EN.value:
|
||||||
|
assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period) < tb.clk_period*5
|
||||||
|
else:
|
||||||
|
assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period) < 0.01
|
||||||
|
|
||||||
assert tb.axis_sink.empty()
|
assert tb.axis_sink.empty()
|
||||||
|
|
||||||
@@ -184,6 +223,13 @@ async def run_test_tx(dut, payload_lengths=None, payload_data=None, ifg=12):
|
|||||||
|
|
||||||
await tb.reset()
|
await tb.reset()
|
||||||
|
|
||||||
|
if dut.PTP_TD_EN.value:
|
||||||
|
tb.log.info("Wait for PTP CDC lock")
|
||||||
|
while not int(dut.tx_ptp_locked.value):
|
||||||
|
await RisingEdge(dut.tx_clk)
|
||||||
|
for k in range(2000):
|
||||||
|
await RisingEdge(dut.tx_clk)
|
||||||
|
|
||||||
test_frames = [payload_data(x) for x in payload_lengths()]
|
test_frames = [payload_data(x) for x in payload_lengths()]
|
||||||
|
|
||||||
for test_data in test_frames:
|
for test_data in test_frames:
|
||||||
@@ -208,7 +254,10 @@ async def run_test_tx(dut, payload_lengths=None, payload_data=None, ifg=12):
|
|||||||
assert rx_frame.get_payload() == test_data
|
assert rx_frame.get_payload() == test_data
|
||||||
assert rx_frame.check_fcs()
|
assert rx_frame.check_fcs()
|
||||||
assert rx_frame.ctrl is None
|
assert rx_frame.ctrl is None
|
||||||
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period) < 0.01
|
if dut.PTP_TD_EN.value:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period) < tb.clk_period*5
|
||||||
|
else:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period) < 0.01
|
||||||
|
|
||||||
assert tb.xgmii_sink.empty()
|
assert tb.xgmii_sink.empty()
|
||||||
|
|
||||||
@@ -231,6 +280,13 @@ async def run_test_tx_alignment(dut, payload_data=None, ifg=12):
|
|||||||
|
|
||||||
await tb.reset()
|
await tb.reset()
|
||||||
|
|
||||||
|
if dut.PTP_TD_EN.value:
|
||||||
|
tb.log.info("Wait for PTP CDC lock")
|
||||||
|
while not int(dut.tx_ptp_locked.value):
|
||||||
|
await RisingEdge(dut.tx_clk)
|
||||||
|
for k in range(2000):
|
||||||
|
await RisingEdge(dut.tx_clk)
|
||||||
|
|
||||||
for length in range(60, 92):
|
for length in range(60, 92):
|
||||||
|
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
@@ -261,7 +317,10 @@ async def run_test_tx_alignment(dut, payload_data=None, ifg=12):
|
|||||||
assert rx_frame.get_payload() == test_data
|
assert rx_frame.get_payload() == test_data
|
||||||
assert rx_frame.check_fcs()
|
assert rx_frame.check_fcs()
|
||||||
assert rx_frame.ctrl is None
|
assert rx_frame.ctrl is None
|
||||||
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period) < 0.01
|
if dut.PTP_TD_EN.value:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period) < tb.clk_period*5
|
||||||
|
else:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period) < 0.01
|
||||||
|
|
||||||
start_lane.append(rx_frame.start_lane)
|
start_lane.append(rx_frame.start_lane)
|
||||||
|
|
||||||
@@ -731,8 +790,9 @@ def process_f_files(files):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(("dic_en", "pfc_en"), [(1, 1), (1, 0), (0, 0)])
|
@pytest.mark.parametrize(("dic_en", "pfc_en"), [(1, 1), (1, 0), (0, 0)])
|
||||||
|
@pytest.mark.parametrize("ptp_td_en", [1, 0])
|
||||||
@pytest.mark.parametrize("data_w", [32, 64])
|
@pytest.mark.parametrize("data_w", [32, 64])
|
||||||
def test_taxi_eth_mac_10g(request, data_w, dic_en, pfc_en):
|
def test_taxi_eth_mac_10g(request, data_w, ptp_td_en, dic_en, pfc_en):
|
||||||
dut = "taxi_eth_mac_10g"
|
dut = "taxi_eth_mac_10g"
|
||||||
module = os.path.splitext(os.path.basename(__file__))[0]
|
module = os.path.splitext(os.path.basename(__file__))[0]
|
||||||
toplevel = module
|
toplevel = module
|
||||||
@@ -754,8 +814,10 @@ def test_taxi_eth_mac_10g(request, data_w, dic_en, pfc_en):
|
|||||||
parameters['DIC_EN'] = dic_en
|
parameters['DIC_EN'] = dic_en
|
||||||
parameters['MIN_FRAME_LEN'] = 64
|
parameters['MIN_FRAME_LEN'] = 64
|
||||||
parameters['PTP_TS_EN'] = 1
|
parameters['PTP_TS_EN'] = 1
|
||||||
|
parameters['PTP_TD_EN'] = ptp_td_en
|
||||||
parameters['PTP_TS_FMT_TOD'] = 1
|
parameters['PTP_TS_FMT_TOD'] = 1
|
||||||
parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64
|
parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64
|
||||||
|
parameters['PTP_TD_SDI_PIPELINE'] = 2
|
||||||
parameters['TX_TAG_W'] = 16
|
parameters['TX_TAG_W'] = 16
|
||||||
parameters['PFC_EN'] = pfc_en
|
parameters['PFC_EN'] = pfc_en
|
||||||
parameters['PAUSE_EN'] = parameters['PFC_EN']
|
parameters['PAUSE_EN'] = parameters['PFC_EN']
|
||||||
|
|||||||
@@ -26,8 +26,10 @@ module test_taxi_eth_mac_10g #
|
|||||||
parameter logic DIC_EN = 1'b1,
|
parameter logic DIC_EN = 1'b1,
|
||||||
parameter MIN_FRAME_LEN = 64,
|
parameter MIN_FRAME_LEN = 64,
|
||||||
parameter logic PTP_TS_EN = 1'b0,
|
parameter logic PTP_TS_EN = 1'b0,
|
||||||
|
parameter logic PTP_TD_EN = PTP_TS_EN,
|
||||||
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
||||||
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
||||||
|
parameter PTP_TD_SDI_PIPELINE = 2,
|
||||||
parameter TX_TAG_W = 16,
|
parameter TX_TAG_W = 16,
|
||||||
parameter logic PFC_EN = 1'b0,
|
parameter logic PFC_EN = 1'b0,
|
||||||
parameter logic PAUSE_EN = PFC_EN,
|
parameter logic PAUSE_EN = PFC_EN,
|
||||||
@@ -65,8 +67,18 @@ logic [GBX_CNT-1:0] tx_gbx_req_sync;
|
|||||||
logic tx_gbx_req_stall;
|
logic tx_gbx_req_stall;
|
||||||
logic [GBX_CNT-1:0] tx_gbx_sync;
|
logic [GBX_CNT-1:0] tx_gbx_sync;
|
||||||
|
|
||||||
logic [PTP_TS_W-1:0] tx_ptp_ts;
|
logic ptp_clk;
|
||||||
logic [PTP_TS_W-1:0] rx_ptp_ts;
|
logic ptp_rst;
|
||||||
|
logic ptp_sample_clk;
|
||||||
|
logic ptp_td_sdi;
|
||||||
|
logic [PTP_TS_W-1:0] tx_ptp_ts_in;
|
||||||
|
logic [PTP_TS_W-1:0] tx_ptp_ts_out;
|
||||||
|
logic tx_ptp_ts_step_out;
|
||||||
|
logic tx_ptp_locked;
|
||||||
|
logic [PTP_TS_W-1:0] rx_ptp_ts_in;
|
||||||
|
logic [PTP_TS_W-1:0] rx_ptp_ts_out;
|
||||||
|
logic rx_ptp_ts_step_out;
|
||||||
|
logic rx_ptp_locked;
|
||||||
|
|
||||||
logic tx_lfc_req;
|
logic tx_lfc_req;
|
||||||
logic tx_lfc_resend;
|
logic tx_lfc_resend;
|
||||||
@@ -183,8 +195,10 @@ taxi_eth_mac_10g #(
|
|||||||
.DIC_EN(DIC_EN),
|
.DIC_EN(DIC_EN),
|
||||||
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
||||||
.PTP_TS_EN(PTP_TS_EN),
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
|
.PTP_TD_EN(PTP_TD_EN),
|
||||||
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
||||||
.PTP_TS_W(PTP_TS_W),
|
.PTP_TS_W(PTP_TS_W),
|
||||||
|
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
|
||||||
.PFC_EN(PFC_EN),
|
.PFC_EN(PFC_EN),
|
||||||
.PAUSE_EN(PAUSE_EN),
|
.PAUSE_EN(PAUSE_EN),
|
||||||
.STAT_EN(STAT_EN),
|
.STAT_EN(STAT_EN),
|
||||||
@@ -228,8 +242,18 @@ uut (
|
|||||||
/*
|
/*
|
||||||
* PTP
|
* PTP
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts(tx_ptp_ts),
|
.ptp_clk(ptp_clk),
|
||||||
.rx_ptp_ts(rx_ptp_ts),
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_sample_clk(ptp_sample_clk),
|
||||||
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
.tx_ptp_ts_in(tx_ptp_ts_in),
|
||||||
|
.tx_ptp_ts_out(tx_ptp_ts_out),
|
||||||
|
.tx_ptp_ts_step_out(tx_ptp_ts_step_out),
|
||||||
|
.tx_ptp_locked(tx_ptp_locked),
|
||||||
|
.rx_ptp_ts_in(rx_ptp_ts_in),
|
||||||
|
.rx_ptp_ts_out(rx_ptp_ts_out),
|
||||||
|
.rx_ptp_ts_step_out(rx_ptp_ts_step_out),
|
||||||
|
.rx_ptp_locked(rx_ptp_locked),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -41,8 +41,10 @@ export PARAM_PADDING_EN := 1
|
|||||||
export PARAM_DIC_EN := 1
|
export PARAM_DIC_EN := 1
|
||||||
export PARAM_MIN_FRAME_LEN := 64
|
export PARAM_MIN_FRAME_LEN := 64
|
||||||
export PARAM_PTP_TS_EN := 1
|
export PARAM_PTP_TS_EN := 1
|
||||||
|
export PARAM_PTP_TD_EN := $(PARAM_PTP_TS_EN)
|
||||||
export PARAM_PTP_TS_FMT_TOD := 1
|
export PARAM_PTP_TS_FMT_TOD := 1
|
||||||
export PARAM_PTP_TS_W := $(if $(filter-out 1,$(PARAM_PTP_TS_FMT_TOD)),64,96)
|
export PARAM_PTP_TS_W := $(if $(filter-out 1,$(PARAM_PTP_TS_FMT_TOD)),64,96)
|
||||||
|
export PARAM_PTP_TD_SDI_PIPELINE := 2
|
||||||
export PARAM_TX_TAG_W := 16
|
export PARAM_TX_TAG_W := 16
|
||||||
export PARAM_STAT_EN := 1
|
export PARAM_STAT_EN := 1
|
||||||
export PARAM_STAT_TX_LEVEL := 2
|
export PARAM_STAT_TX_LEVEL := 2
|
||||||
|
|||||||
1
src/eth/tb/taxi_eth_mac_10g_fifo/ptp_td.py
Symbolic link
1
src/eth/tb/taxi_eth_mac_10g_fifo/ptp_td.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../lib/taxi/src/ptp/tb/ptp_td.py
|
||||||
@@ -12,6 +12,7 @@ Authors:
|
|||||||
import itertools
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import cocotb_test.simulator
|
import cocotb_test.simulator
|
||||||
@@ -25,6 +26,16 @@ from cocotb.regression import TestFactory
|
|||||||
from cocotbext.eth import XgmiiFrame, XgmiiSource, XgmiiSink, PtpClockSimTime
|
from cocotbext.eth import XgmiiFrame, XgmiiSource, XgmiiSink, PtpClockSimTime
|
||||||
from cocotbext.axi import AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiStreamFrame
|
from cocotbext.axi import AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiStreamFrame
|
||||||
|
|
||||||
|
try:
|
||||||
|
from ptp_td import PtpTdSource
|
||||||
|
except ImportError:
|
||||||
|
# attempt import from current directory
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__)))
|
||||||
|
try:
|
||||||
|
from ptp_td import PtpTdSource
|
||||||
|
finally:
|
||||||
|
del sys.path[0]
|
||||||
|
|
||||||
|
|
||||||
class TB:
|
class TB:
|
||||||
def __init__(self, dut):
|
def __init__(self, dut):
|
||||||
@@ -42,7 +53,6 @@ class TB:
|
|||||||
cocotb.start_soon(Clock(dut.rx_clk, self.clk_period, units="ns").start())
|
cocotb.start_soon(Clock(dut.rx_clk, self.clk_period, units="ns").start())
|
||||||
cocotb.start_soon(Clock(dut.tx_clk, self.clk_period, units="ns").start())
|
cocotb.start_soon(Clock(dut.tx_clk, self.clk_period, units="ns").start())
|
||||||
cocotb.start_soon(Clock(dut.stat_clk, self.clk_period, units="ns").start())
|
cocotb.start_soon(Clock(dut.stat_clk, self.clk_period, units="ns").start())
|
||||||
cocotb.start_soon(Clock(dut.ptp_sample_clk, 9.9, units="ns").start())
|
|
||||||
|
|
||||||
self.xgmii_source = XgmiiSource(dut.xgmii_rxd, dut.xgmii_rxc, dut.rx_clk, dut.rx_rst)
|
self.xgmii_source = XgmiiSource(dut.xgmii_rxd, dut.xgmii_rxc, dut.rx_clk, dut.rx_rst)
|
||||||
self.xgmii_sink = XgmiiSink(dut.xgmii_txd, dut.xgmii_txc, dut.tx_clk, dut.tx_rst)
|
self.xgmii_sink = XgmiiSink(dut.xgmii_txd, dut.xgmii_txc, dut.tx_clk, dut.tx_rst)
|
||||||
@@ -53,9 +63,20 @@ class TB:
|
|||||||
|
|
||||||
self.stat_sink = AxiStreamSink(AxiStreamBus.from_entity(dut.m_axis_stat), dut.stat_clk, dut.stat_rst)
|
self.stat_sink = AxiStreamSink(AxiStreamBus.from_entity(dut.m_axis_stat), dut.stat_clk, dut.stat_rst)
|
||||||
|
|
||||||
self.ptp_clock = PtpClockSimTime(ts_tod=dut.ptp_ts, clock=dut.logic_clk)
|
self.ptp_clock = PtpClockSimTime(ts_tod=dut.ptp_ts_in, clock=dut.logic_clk)
|
||||||
|
dut.ptp_ts_step_in.setimmediatevalue(0)
|
||||||
|
|
||||||
dut.ptp_ts_step.setimmediatevalue(0)
|
self.ptp_clk_period = self.clk_period
|
||||||
|
|
||||||
|
cocotb.start_soon(Clock(dut.ptp_clk, self.ptp_clk_period, units="ns").start())
|
||||||
|
cocotb.start_soon(Clock(dut.ptp_sample_clk, 8, units="ns").start())
|
||||||
|
|
||||||
|
self.ptp_td_source = PtpTdSource(
|
||||||
|
data=dut.ptp_td_sdi,
|
||||||
|
clock=dut.ptp_clk,
|
||||||
|
reset=dut.ptp_rst,
|
||||||
|
period_ns=self.ptp_clk_period
|
||||||
|
)
|
||||||
|
|
||||||
dut.cfg_tx_max_pkt_len.setimmediatevalue(0)
|
dut.cfg_tx_max_pkt_len.setimmediatevalue(0)
|
||||||
dut.cfg_tx_ifg.setimmediatevalue(0)
|
dut.cfg_tx_ifg.setimmediatevalue(0)
|
||||||
@@ -67,22 +88,28 @@ class TB:
|
|||||||
self.dut.logic_rst.setimmediatevalue(0)
|
self.dut.logic_rst.setimmediatevalue(0)
|
||||||
self.dut.rx_rst.setimmediatevalue(0)
|
self.dut.rx_rst.setimmediatevalue(0)
|
||||||
self.dut.tx_rst.setimmediatevalue(0)
|
self.dut.tx_rst.setimmediatevalue(0)
|
||||||
|
self.dut.ptp_rst.setimmediatevalue(0)
|
||||||
self.dut.stat_rst.setimmediatevalue(0)
|
self.dut.stat_rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.logic_clk)
|
await RisingEdge(self.dut.logic_clk)
|
||||||
await RisingEdge(self.dut.logic_clk)
|
await RisingEdge(self.dut.logic_clk)
|
||||||
self.dut.logic_rst.value = 1
|
self.dut.logic_rst.value = 1
|
||||||
self.dut.rx_rst.value = 1
|
self.dut.rx_rst.value = 1
|
||||||
self.dut.tx_rst.value = 1
|
self.dut.tx_rst.value = 1
|
||||||
|
self.dut.ptp_rst.value = 1
|
||||||
self.dut.stat_rst.value = 1
|
self.dut.stat_rst.value = 1
|
||||||
await RisingEdge(self.dut.logic_clk)
|
await RisingEdge(self.dut.logic_clk)
|
||||||
await RisingEdge(self.dut.logic_clk)
|
await RisingEdge(self.dut.logic_clk)
|
||||||
self.dut.logic_rst.value = 0
|
self.dut.logic_rst.value = 0
|
||||||
self.dut.rx_rst.value = 0
|
self.dut.rx_rst.value = 0
|
||||||
self.dut.tx_rst.value = 0
|
self.dut.tx_rst.value = 0
|
||||||
|
self.dut.ptp_rst.value = 0
|
||||||
self.dut.stat_rst.value = 0
|
self.dut.stat_rst.value = 0
|
||||||
await RisingEdge(self.dut.logic_clk)
|
await RisingEdge(self.dut.logic_clk)
|
||||||
await RisingEdge(self.dut.logic_clk)
|
await RisingEdge(self.dut.logic_clk)
|
||||||
|
|
||||||
|
self.ptp_td_source.set_ts_tod_sim_time()
|
||||||
|
self.ptp_td_source.set_ts_rel_sim_time()
|
||||||
|
|
||||||
|
|
||||||
async def run_test_rx(dut, payload_lengths=None, payload_data=None, ifg=12):
|
async def run_test_rx(dut, payload_lengths=None, payload_data=None, ifg=12):
|
||||||
|
|
||||||
@@ -96,9 +123,9 @@ async def run_test_rx(dut, payload_lengths=None, payload_data=None, ifg=12):
|
|||||||
await tb.reset()
|
await tb.reset()
|
||||||
|
|
||||||
tb.log.info("Wait for PTP CDC lock")
|
tb.log.info("Wait for PTP CDC lock")
|
||||||
while not int(dut.uut.rx_ptp_locked.value):
|
while not int(dut.rx_ptp_locked.value):
|
||||||
await RisingEdge(dut.rx_clk)
|
await RisingEdge(dut.rx_clk)
|
||||||
for k in range(1000):
|
for k in range(2000):
|
||||||
await RisingEdge(dut.rx_clk)
|
await RisingEdge(dut.rx_clk)
|
||||||
|
|
||||||
test_frames = [payload_data(x) for x in payload_lengths()]
|
test_frames = [payload_data(x) for x in payload_lengths()]
|
||||||
@@ -128,7 +155,10 @@ async def run_test_rx(dut, payload_lengths=None, payload_data=None, ifg=12):
|
|||||||
|
|
||||||
assert rx_frame.tdata == test_data
|
assert rx_frame.tdata == test_data
|
||||||
assert frame_error == 0
|
assert frame_error == 0
|
||||||
assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period) < tb.clk_period*2
|
if dut.PTP_TD_EN.value:
|
||||||
|
assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period) < tb.clk_period*4
|
||||||
|
else:
|
||||||
|
assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period) < tb.clk_period*2
|
||||||
|
|
||||||
assert tb.axis_sink.empty()
|
assert tb.axis_sink.empty()
|
||||||
|
|
||||||
@@ -148,9 +178,9 @@ async def run_test_tx(dut, payload_lengths=None, payload_data=None, ifg=12):
|
|||||||
await tb.reset()
|
await tb.reset()
|
||||||
|
|
||||||
tb.log.info("Wait for PTP CDC lock")
|
tb.log.info("Wait for PTP CDC lock")
|
||||||
while not int(dut.uut.tx_ptp_locked.value):
|
while not int(dut.tx_ptp_locked.value):
|
||||||
await RisingEdge(dut.tx_clk)
|
await RisingEdge(dut.tx_clk)
|
||||||
for k in range(1000):
|
for k in range(2000):
|
||||||
await RisingEdge(dut.tx_clk)
|
await RisingEdge(dut.tx_clk)
|
||||||
|
|
||||||
test_frames = [payload_data(x) for x in payload_lengths()]
|
test_frames = [payload_data(x) for x in payload_lengths()]
|
||||||
@@ -177,7 +207,10 @@ async def run_test_tx(dut, payload_lengths=None, payload_data=None, ifg=12):
|
|||||||
assert rx_frame.get_payload() == test_data
|
assert rx_frame.get_payload() == test_data
|
||||||
assert rx_frame.check_fcs()
|
assert rx_frame.check_fcs()
|
||||||
assert rx_frame.ctrl is None
|
assert rx_frame.ctrl is None
|
||||||
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period) < tb.clk_period*2
|
if dut.PTP_TD_EN.value:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period) < tb.clk_period*4
|
||||||
|
else:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period) < tb.clk_period*2
|
||||||
|
|
||||||
assert tb.xgmii_sink.empty()
|
assert tb.xgmii_sink.empty()
|
||||||
|
|
||||||
@@ -201,9 +234,9 @@ async def run_test_tx_alignment(dut, payload_data=None, ifg=12):
|
|||||||
await tb.reset()
|
await tb.reset()
|
||||||
|
|
||||||
tb.log.info("Wait for PTP CDC lock")
|
tb.log.info("Wait for PTP CDC lock")
|
||||||
while not int(dut.uut.tx_ptp_locked.value):
|
while not int(dut.tx_ptp_locked.value):
|
||||||
await RisingEdge(dut.tx_clk)
|
await RisingEdge(dut.tx_clk)
|
||||||
for k in range(1000):
|
for k in range(2000):
|
||||||
await RisingEdge(dut.tx_clk)
|
await RisingEdge(dut.tx_clk)
|
||||||
|
|
||||||
for length in range(60, 92):
|
for length in range(60, 92):
|
||||||
@@ -236,7 +269,10 @@ async def run_test_tx_alignment(dut, payload_data=None, ifg=12):
|
|||||||
assert rx_frame.get_payload() == test_data
|
assert rx_frame.get_payload() == test_data
|
||||||
assert rx_frame.check_fcs()
|
assert rx_frame.check_fcs()
|
||||||
assert rx_frame.ctrl is None
|
assert rx_frame.ctrl is None
|
||||||
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period) < tb.clk_period*2
|
if dut.PTP_TD_EN.value:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period) < tb.clk_period*4
|
||||||
|
else:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period) < tb.clk_period*2
|
||||||
|
|
||||||
start_lane.append(rx_frame.start_lane)
|
start_lane.append(rx_frame.start_lane)
|
||||||
|
|
||||||
@@ -354,8 +390,10 @@ def test_taxi_eth_mac_10g_fifo(request, data_w, dic_en):
|
|||||||
parameters['DIC_EN'] = dic_en
|
parameters['DIC_EN'] = dic_en
|
||||||
parameters['MIN_FRAME_LEN'] = 64
|
parameters['MIN_FRAME_LEN'] = 64
|
||||||
parameters['PTP_TS_EN'] = 1
|
parameters['PTP_TS_EN'] = 1
|
||||||
|
parameters['PTP_TD_EN'] = parameters['PTP_TS_EN']
|
||||||
parameters['PTP_TS_FMT_TOD'] = 1
|
parameters['PTP_TS_FMT_TOD'] = 1
|
||||||
parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64
|
parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64
|
||||||
|
parameters['PTP_TD_SDI_PIPELINE'] = 2
|
||||||
parameters['TX_TAG_W'] = 16
|
parameters['TX_TAG_W'] = 16
|
||||||
parameters['STAT_EN'] = 1
|
parameters['STAT_EN'] = 1
|
||||||
parameters['STAT_TX_LEVEL'] = 2
|
parameters['STAT_TX_LEVEL'] = 2
|
||||||
|
|||||||
@@ -27,8 +27,10 @@ module test_taxi_eth_mac_10g_fifo #
|
|||||||
parameter logic DIC_EN = 1'b1,
|
parameter logic DIC_EN = 1'b1,
|
||||||
parameter MIN_FRAME_LEN = 64,
|
parameter MIN_FRAME_LEN = 64,
|
||||||
parameter logic PTP_TS_EN = 1'b0,
|
parameter logic PTP_TS_EN = 1'b0,
|
||||||
|
parameter logic PTP_TD_EN = PTP_TS_EN,
|
||||||
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
||||||
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
||||||
|
parameter PTP_TD_SDI_PIPELINE = 2,
|
||||||
parameter TX_TAG_W = 16,
|
parameter TX_TAG_W = 16,
|
||||||
parameter logic STAT_EN = 1'b0,
|
parameter logic STAT_EN = 1'b0,
|
||||||
parameter STAT_TX_LEVEL = 1,
|
parameter STAT_TX_LEVEL = 1,
|
||||||
@@ -64,7 +66,6 @@ logic tx_clk;
|
|||||||
logic tx_rst;
|
logic tx_rst;
|
||||||
logic logic_clk;
|
logic logic_clk;
|
||||||
logic logic_rst;
|
logic logic_rst;
|
||||||
logic ptp_sample_clk;
|
|
||||||
|
|
||||||
taxi_axis_if #(.DATA_W(AXIS_DATA_W), .USER_EN(1), .USER_W(TX_USER_W), .ID_EN(1), .ID_W(TX_TAG_W)) s_axis_tx();
|
taxi_axis_if #(.DATA_W(AXIS_DATA_W), .USER_EN(1), .USER_W(TX_USER_W), .ID_EN(1), .ID_W(TX_TAG_W)) s_axis_tx();
|
||||||
taxi_axis_if #(.DATA_W(96), .KEEP_W(1), .ID_EN(1), .ID_W(TX_TAG_W)) m_axis_tx_cpl();
|
taxi_axis_if #(.DATA_W(96), .KEEP_W(1), .ID_EN(1), .ID_W(TX_TAG_W)) m_axis_tx_cpl();
|
||||||
@@ -80,8 +81,18 @@ logic [GBX_CNT-1:0] tx_gbx_req_sync;
|
|||||||
logic tx_gbx_req_stall;
|
logic tx_gbx_req_stall;
|
||||||
logic [GBX_CNT-1:0] tx_gbx_sync;
|
logic [GBX_CNT-1:0] tx_gbx_sync;
|
||||||
|
|
||||||
logic [PTP_TS_W-1:0] ptp_ts;
|
logic ptp_clk;
|
||||||
logic ptp_ts_step;
|
logic ptp_rst;
|
||||||
|
logic ptp_sample_clk;
|
||||||
|
logic ptp_td_sdi;
|
||||||
|
logic [PTP_TS_W-1:0] ptp_ts_in;
|
||||||
|
logic ptp_ts_step_in;
|
||||||
|
logic [PTP_TS_W-1:0] tx_ptp_ts_out;
|
||||||
|
logic tx_ptp_ts_step_out;
|
||||||
|
logic tx_ptp_locked;
|
||||||
|
logic [PTP_TS_W-1:0] rx_ptp_ts_out;
|
||||||
|
logic rx_ptp_ts_step_out;
|
||||||
|
logic rx_ptp_locked;
|
||||||
|
|
||||||
logic stat_clk;
|
logic stat_clk;
|
||||||
logic stat_rst;
|
logic stat_rst;
|
||||||
@@ -113,8 +124,10 @@ taxi_eth_mac_10g_fifo #(
|
|||||||
.DIC_EN(DIC_EN),
|
.DIC_EN(DIC_EN),
|
||||||
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
||||||
.PTP_TS_EN(PTP_TS_EN),
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
|
.PTP_TD_EN(PTP_TD_EN),
|
||||||
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
||||||
.PTP_TS_W(PTP_TS_W),
|
.PTP_TS_W(PTP_TS_W),
|
||||||
|
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
|
||||||
.STAT_EN(STAT_EN),
|
.STAT_EN(STAT_EN),
|
||||||
.STAT_TX_LEVEL(STAT_TX_LEVEL),
|
.STAT_TX_LEVEL(STAT_TX_LEVEL),
|
||||||
.STAT_RX_LEVEL(STAT_RX_LEVEL),
|
.STAT_RX_LEVEL(STAT_RX_LEVEL),
|
||||||
@@ -143,7 +156,6 @@ uut (
|
|||||||
.tx_rst(tx_rst),
|
.tx_rst(tx_rst),
|
||||||
.logic_clk(logic_clk),
|
.logic_clk(logic_clk),
|
||||||
.logic_rst(logic_rst),
|
.logic_rst(logic_rst),
|
||||||
.ptp_sample_clk(ptp_sample_clk),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -172,8 +184,18 @@ uut (
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.ptp_ts(ptp_ts),
|
.ptp_clk(ptp_clk),
|
||||||
.ptp_ts_step(ptp_ts_step),
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_sample_clk(ptp_sample_clk),
|
||||||
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
.ptp_ts_in(ptp_ts_in),
|
||||||
|
.ptp_ts_step_in(ptp_ts_step_in),
|
||||||
|
.tx_ptp_ts_out(tx_ptp_ts_out),
|
||||||
|
.tx_ptp_ts_step_out(tx_ptp_ts_step_out),
|
||||||
|
.tx_ptp_locked(tx_ptp_locked),
|
||||||
|
.rx_ptp_ts_out(rx_ptp_ts_out),
|
||||||
|
.rx_ptp_ts_step_out(rx_ptp_ts_step_out),
|
||||||
|
.rx_ptp_locked(rx_ptp_locked),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Statistics
|
* Statistics
|
||||||
|
|||||||
@@ -48,8 +48,10 @@ export PARAM_PADDING_EN := 1
|
|||||||
export PARAM_DIC_EN := 1
|
export PARAM_DIC_EN := 1
|
||||||
export PARAM_MIN_FRAME_LEN := 64
|
export PARAM_MIN_FRAME_LEN := 64
|
||||||
export PARAM_PTP_TS_EN := 1
|
export PARAM_PTP_TS_EN := 1
|
||||||
|
export PARAM_PTP_TD_EN := $(PARAM_PTP_TS_EN)
|
||||||
export PARAM_PTP_TS_FMT_TOD := 1
|
export PARAM_PTP_TS_FMT_TOD := 1
|
||||||
export PARAM_PTP_TS_W := $(if $(filter-out 1,$(PARAM_PTP_TS_FMT_TOD)),64,96)
|
export PARAM_PTP_TS_W := $(if $(filter-out 1,$(PARAM_PTP_TS_FMT_TOD)),64,96)
|
||||||
|
export PARAM_PTP_TD_SDI_PIPELINE := 2
|
||||||
export PARAM_TX_TAG_W := 16
|
export PARAM_TX_TAG_W := 16
|
||||||
export PARAM_PRBS31_EN := 1
|
export PARAM_PRBS31_EN := 1
|
||||||
export PARAM_TX_SERDES_PIPELINE := 2
|
export PARAM_TX_SERDES_PIPELINE := 2
|
||||||
|
|||||||
1
src/eth/tb/taxi_eth_mac_25g_us/ptp_td.py
Symbolic link
1
src/eth/tb/taxi_eth_mac_25g_us/ptp_td.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../lib/taxi/src/ptp/tb/ptp_td.py
|
||||||
@@ -32,11 +32,13 @@ from cocotbext.axi import ApbBus, ApbMaster
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
from baser import BaseRSerdesSource, BaseRSerdesSink
|
from baser import BaseRSerdesSource, BaseRSerdesSink
|
||||||
|
from ptp_td import PtpTdSource
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# attempt import from current directory
|
# attempt import from current directory
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__)))
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__)))
|
||||||
try:
|
try:
|
||||||
from baser import BaseRSerdesSource, BaseRSerdesSink
|
from baser import BaseRSerdesSource, BaseRSerdesSink
|
||||||
|
from ptp_td import PtpTdSource
|
||||||
finally:
|
finally:
|
||||||
del sys.path[0]
|
del sys.path[0]
|
||||||
|
|
||||||
@@ -118,8 +120,20 @@ class TB:
|
|||||||
self.tx_ptp_clocks = []
|
self.tx_ptp_clocks = []
|
||||||
|
|
||||||
for k in range(4):
|
for k in range(4):
|
||||||
self.rx_ptp_clocks.append(PtpClockSimTime(ts_tod=dut.rx_ptp_ts[k], clock=dut.uut.ch[k].ch_inst.gt.gt_inst.rx_clk))
|
self.rx_ptp_clocks.append(PtpClockSimTime(ts_tod=dut.rx_ptp_ts_in[k], clock=dut.uut.ch[k].ch_inst.gt.gt_inst.rx_clk))
|
||||||
self.tx_ptp_clocks.append(PtpClockSimTime(ts_tod=dut.tx_ptp_ts[k], clock=dut.uut.ch[k].ch_inst.gt.gt_inst.tx_clk))
|
self.tx_ptp_clocks.append(PtpClockSimTime(ts_tod=dut.tx_ptp_ts_in[k], clock=dut.uut.ch[k].ch_inst.gt.gt_inst.tx_clk))
|
||||||
|
|
||||||
|
self.ptp_clk_period = self.clk_period[0]
|
||||||
|
|
||||||
|
cocotb.start_soon(Clock(dut.ptp_clk, self.ptp_clk_period, units="ns").start())
|
||||||
|
cocotb.start_soon(Clock(dut.ptp_sample_clk, 8, units="ns").start())
|
||||||
|
|
||||||
|
self.ptp_td_source = PtpTdSource(
|
||||||
|
data=dut.ptp_td_sdi,
|
||||||
|
clock=dut.ptp_clk,
|
||||||
|
reset=dut.ptp_rst,
|
||||||
|
period_ns=self.ptp_clk_period
|
||||||
|
)
|
||||||
|
|
||||||
dut.rx_rst_in.setimmediatevalue([0]*4)
|
dut.rx_rst_in.setimmediatevalue([0]*4)
|
||||||
dut.tx_rst_in.setimmediatevalue([0]*4)
|
dut.tx_rst_in.setimmediatevalue([0]*4)
|
||||||
@@ -169,18 +183,24 @@ class TB:
|
|||||||
|
|
||||||
async def reset(self):
|
async def reset(self):
|
||||||
self.dut.xcvr_ctrl_rst.setimmediatevalue(0)
|
self.dut.xcvr_ctrl_rst.setimmediatevalue(0)
|
||||||
|
self.dut.ptp_rst.setimmediatevalue(0)
|
||||||
self.dut.stat_rst.setimmediatevalue(0)
|
self.dut.stat_rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.xcvr_ctrl_clk)
|
await RisingEdge(self.dut.xcvr_ctrl_clk)
|
||||||
await RisingEdge(self.dut.xcvr_ctrl_clk)
|
await RisingEdge(self.dut.xcvr_ctrl_clk)
|
||||||
self.dut.xcvr_ctrl_rst.value = 1
|
self.dut.xcvr_ctrl_rst.value = 1
|
||||||
|
self.dut.ptp_rst.value = 1
|
||||||
self.dut.stat_rst.value = 1
|
self.dut.stat_rst.value = 1
|
||||||
await RisingEdge(self.dut.xcvr_ctrl_clk)
|
await RisingEdge(self.dut.xcvr_ctrl_clk)
|
||||||
await RisingEdge(self.dut.xcvr_ctrl_clk)
|
await RisingEdge(self.dut.xcvr_ctrl_clk)
|
||||||
self.dut.xcvr_ctrl_rst.value = 0
|
self.dut.xcvr_ctrl_rst.value = 0
|
||||||
|
self.dut.ptp_rst.value = 0
|
||||||
self.dut.stat_rst.value = 0
|
self.dut.stat_rst.value = 0
|
||||||
await RisingEdge(self.dut.xcvr_ctrl_clk)
|
await RisingEdge(self.dut.xcvr_ctrl_clk)
|
||||||
await RisingEdge(self.dut.xcvr_ctrl_clk)
|
await RisingEdge(self.dut.xcvr_ctrl_clk)
|
||||||
|
|
||||||
|
self.ptp_td_source.set_ts_tod_sim_time()
|
||||||
|
self.ptp_td_source.set_ts_rel_sim_time()
|
||||||
|
|
||||||
|
|
||||||
async def run_test_regs(dut):
|
async def run_test_regs(dut):
|
||||||
tb = TB(dut)
|
tb = TB(dut)
|
||||||
@@ -231,6 +251,12 @@ async def run_test_rx(dut, port=0, payload_lengths=None, payload_data=None, ifg=
|
|||||||
while not int(dut.rx_block_lock[port].value):
|
while not int(dut.rx_block_lock[port].value):
|
||||||
await RisingEdge(dut.xcvr_ctrl_clk)
|
await RisingEdge(dut.xcvr_ctrl_clk)
|
||||||
|
|
||||||
|
tb.log.info("Wait for PTP CDC lock")
|
||||||
|
while not int(dut.rx_ptp_locked[port].value):
|
||||||
|
await RisingEdge(dut.xcvr_ctrl_clk)
|
||||||
|
for k in range(2000):
|
||||||
|
await RisingEdge(dut.xcvr_ctrl_clk)
|
||||||
|
|
||||||
tb.dut.cfg_rx_enable[port].value = 1
|
tb.dut.cfg_rx_enable[port].value = 1
|
||||||
|
|
||||||
test_frames = [payload_data(x) for x in payload_lengths()]
|
test_frames = [payload_data(x) for x in payload_lengths()]
|
||||||
@@ -267,7 +293,10 @@ async def run_test_rx(dut, port=0, payload_lengths=None, payload_data=None, ifg=
|
|||||||
assert rx_frame.tdata == test_data
|
assert rx_frame.tdata == test_data
|
||||||
assert frame_error == 0
|
assert frame_error == 0
|
||||||
if not tb.serdes_sources[port].gbx_seq_len:
|
if not tb.serdes_sources[port].gbx_seq_len:
|
||||||
assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period[port]*pipe_delay) < 0.01
|
if dut.PTP_TD_EN.value:
|
||||||
|
assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period[port]*pipe_delay) < tb.clk_period[port]*3
|
||||||
|
else:
|
||||||
|
assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period[port]*pipe_delay) < 0.01
|
||||||
|
|
||||||
assert tb.axis_sinks[port].empty()
|
assert tb.axis_sinks[port].empty()
|
||||||
|
|
||||||
@@ -300,7 +329,10 @@ async def run_test_tx(dut, port=0, payload_lengths=None, payload_data=None, ifg=
|
|||||||
while int(dut.tx_rst_out[port].value):
|
while int(dut.tx_rst_out[port].value):
|
||||||
await RisingEdge(dut.xcvr_ctrl_clk)
|
await RisingEdge(dut.xcvr_ctrl_clk)
|
||||||
|
|
||||||
for k in range(100):
|
tb.log.info("Wait for PTP CDC lock")
|
||||||
|
while not int(dut.tx_ptp_locked[port].value):
|
||||||
|
await RisingEdge(dut.xcvr_ctrl_clk)
|
||||||
|
for k in range(2000):
|
||||||
await RisingEdge(dut.xcvr_ctrl_clk)
|
await RisingEdge(dut.xcvr_ctrl_clk)
|
||||||
|
|
||||||
tb.dut.cfg_tx_enable[port].value = 1
|
tb.dut.cfg_tx_enable[port].value = 1
|
||||||
@@ -337,7 +369,10 @@ async def run_test_tx(dut, port=0, payload_lengths=None, payload_data=None, ifg=
|
|||||||
assert rx_frame.check_fcs()
|
assert rx_frame.check_fcs()
|
||||||
assert rx_frame.ctrl is None
|
assert rx_frame.ctrl is None
|
||||||
if not tb.serdes_sinks[port].gbx_seq_len:
|
if not tb.serdes_sinks[port].gbx_seq_len:
|
||||||
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period[port]*pipe_delay) < 0.01
|
if dut.PTP_TD_EN.value:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period[port]*pipe_delay) < tb.clk_period[port]*3
|
||||||
|
else:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period[port]*pipe_delay) < 0.01
|
||||||
|
|
||||||
assert tb.serdes_sinks[port].empty()
|
assert tb.serdes_sinks[port].empty()
|
||||||
|
|
||||||
@@ -374,7 +409,10 @@ async def run_test_tx_alignment(dut, port=0, payload_data=None, ifg=12):
|
|||||||
while int(dut.tx_rst_out[port].value):
|
while int(dut.tx_rst_out[port].value):
|
||||||
await RisingEdge(dut.xcvr_ctrl_clk)
|
await RisingEdge(dut.xcvr_ctrl_clk)
|
||||||
|
|
||||||
for k in range(100):
|
tb.log.info("Wait for PTP CDC lock")
|
||||||
|
while not int(dut.tx_ptp_locked[port].value):
|
||||||
|
await RisingEdge(dut.xcvr_ctrl_clk)
|
||||||
|
for k in range(2000):
|
||||||
await RisingEdge(dut.xcvr_ctrl_clk)
|
await RisingEdge(dut.xcvr_ctrl_clk)
|
||||||
|
|
||||||
tb.dut.cfg_tx_enable[port].value = 1
|
tb.dut.cfg_tx_enable[port].value = 1
|
||||||
@@ -416,7 +454,10 @@ async def run_test_tx_alignment(dut, port=0, payload_data=None, ifg=12):
|
|||||||
assert rx_frame.check_fcs()
|
assert rx_frame.check_fcs()
|
||||||
assert rx_frame.ctrl is None
|
assert rx_frame.ctrl is None
|
||||||
if not tb.serdes_sinks[port].gbx_seq_len:
|
if not tb.serdes_sinks[port].gbx_seq_len:
|
||||||
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period[port]*pipe_delay) < 0.01
|
if dut.PTP_TD_EN.value:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period[port]*pipe_delay) < tb.clk_period[port]*3
|
||||||
|
else:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period[port]*pipe_delay) < 0.01
|
||||||
|
|
||||||
start_lane.append(rx_frame.start_lane)
|
start_lane.append(rx_frame.start_lane)
|
||||||
|
|
||||||
@@ -1024,8 +1065,10 @@ def test_taxi_eth_mac_25g_us(request, data_w, combined_mac_pcs, low_latency, dic
|
|||||||
parameters['DIC_EN'] = dic_en
|
parameters['DIC_EN'] = dic_en
|
||||||
parameters['MIN_FRAME_LEN'] = 64
|
parameters['MIN_FRAME_LEN'] = 64
|
||||||
parameters['PTP_TS_EN'] = 1
|
parameters['PTP_TS_EN'] = 1
|
||||||
|
parameters['PTP_TD_EN'] = parameters['PTP_TS_EN']
|
||||||
parameters['PTP_TS_FMT_TOD'] = 1
|
parameters['PTP_TS_FMT_TOD'] = 1
|
||||||
parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64
|
parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64
|
||||||
|
parameters['PTP_TD_SDI_PIPELINE'] = 2
|
||||||
parameters['TX_TAG_W'] = 16
|
parameters['TX_TAG_W'] = 16
|
||||||
parameters['PRBS31_EN'] = 1
|
parameters['PRBS31_EN'] = 1
|
||||||
parameters['TX_SERDES_PIPELINE'] = 2
|
parameters['TX_SERDES_PIPELINE'] = 2
|
||||||
|
|||||||
@@ -47,8 +47,10 @@ module test_taxi_eth_mac_25g_us #
|
|||||||
parameter logic DIC_EN = 1'b1,
|
parameter logic DIC_EN = 1'b1,
|
||||||
parameter MIN_FRAME_LEN = 64,
|
parameter MIN_FRAME_LEN = 64,
|
||||||
parameter logic PTP_TS_EN = 1'b0,
|
parameter logic PTP_TS_EN = 1'b0,
|
||||||
|
parameter logic PTP_TD_EN = PTP_TS_EN,
|
||||||
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
||||||
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
||||||
|
parameter PTP_TD_SDI_PIPELINE = 2,
|
||||||
parameter TX_TAG_W = 16,
|
parameter TX_TAG_W = 16,
|
||||||
parameter logic PRBS31_EN = 1'b0,
|
parameter logic PRBS31_EN = 1'b0,
|
||||||
parameter TX_SERDES_PIPELINE = 1,
|
parameter TX_SERDES_PIPELINE = 1,
|
||||||
@@ -108,16 +110,23 @@ logic rx_rst_out[CNT];
|
|||||||
logic tx_clk[CNT];
|
logic tx_clk[CNT];
|
||||||
logic tx_rst_in[CNT];
|
logic tx_rst_in[CNT];
|
||||||
logic tx_rst_out[CNT];
|
logic tx_rst_out[CNT];
|
||||||
logic ptp_sample_clk[CNT];
|
|
||||||
|
|
||||||
taxi_axis_if #(.DATA_W(DATA_W), .USER_EN(1), .USER_W(TX_USER_W), .ID_EN(1), .ID_W(TX_TAG_W)) s_axis_tx[CNT]();
|
taxi_axis_if #(.DATA_W(DATA_W), .USER_EN(1), .USER_W(TX_USER_W), .ID_EN(1), .ID_W(TX_TAG_W)) s_axis_tx[CNT]();
|
||||||
taxi_axis_if #(.DATA_W(PTP_TS_W), .KEEP_W(1), .ID_EN(1), .ID_W(TX_TAG_W)) m_axis_tx_cpl[CNT]();
|
taxi_axis_if #(.DATA_W(PTP_TS_W), .KEEP_W(1), .ID_EN(1), .ID_W(TX_TAG_W)) m_axis_tx_cpl[CNT]();
|
||||||
taxi_axis_if #(.DATA_W(DATA_W), .USER_EN(1), .USER_W(RX_USER_W)) m_axis_rx[CNT]();
|
taxi_axis_if #(.DATA_W(DATA_W), .USER_EN(1), .USER_W(RX_USER_W)) m_axis_rx[CNT]();
|
||||||
|
|
||||||
logic [PTP_TS_W-1:0] tx_ptp_ts[CNT];
|
logic ptp_clk;
|
||||||
logic tx_ptp_ts_step[CNT];
|
logic ptp_rst;
|
||||||
logic [PTP_TS_W-1:0] rx_ptp_ts[CNT];
|
logic ptp_sample_clk;
|
||||||
logic rx_ptp_ts_step[CNT];
|
logic ptp_td_sdi;
|
||||||
|
logic [PTP_TS_W-1:0] tx_ptp_ts_in[CNT];
|
||||||
|
logic [PTP_TS_W-1:0] tx_ptp_ts_out[CNT];
|
||||||
|
logic tx_ptp_ts_step_out[CNT];
|
||||||
|
logic tx_ptp_locked[CNT];
|
||||||
|
logic [PTP_TS_W-1:0] rx_ptp_ts_in[CNT];
|
||||||
|
logic [PTP_TS_W-1:0] rx_ptp_ts_out[CNT];
|
||||||
|
logic rx_ptp_ts_step_out[CNT];
|
||||||
|
logic rx_ptp_locked[CNT];
|
||||||
|
|
||||||
logic tx_lfc_req[CNT];
|
logic tx_lfc_req[CNT];
|
||||||
logic tx_lfc_resend[CNT];
|
logic tx_lfc_resend[CNT];
|
||||||
@@ -260,8 +269,10 @@ taxi_eth_mac_25g_us #(
|
|||||||
.DIC_EN(DIC_EN),
|
.DIC_EN(DIC_EN),
|
||||||
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
||||||
.PTP_TS_EN(PTP_TS_EN),
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
|
.PTP_TD_EN(PTP_TD_EN),
|
||||||
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
||||||
.PTP_TS_W(PTP_TS_W),
|
.PTP_TS_W(PTP_TS_W),
|
||||||
|
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
|
||||||
.PRBS31_EN(PRBS31_EN),
|
.PRBS31_EN(PRBS31_EN),
|
||||||
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),
|
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),
|
||||||
.RX_SERDES_PIPELINE(RX_SERDES_PIPELINE),
|
.RX_SERDES_PIPELINE(RX_SERDES_PIPELINE),
|
||||||
@@ -323,7 +334,6 @@ uut (
|
|||||||
.tx_clk(tx_clk),
|
.tx_clk(tx_clk),
|
||||||
.tx_rst_in(tx_rst_in),
|
.tx_rst_in(tx_rst_in),
|
||||||
.tx_rst_out(tx_rst_out),
|
.tx_rst_out(tx_rst_out),
|
||||||
.ptp_sample_clk(ptp_sample_clk),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -339,10 +349,18 @@ uut (
|
|||||||
/*
|
/*
|
||||||
* PTP
|
* PTP
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts(tx_ptp_ts),
|
.ptp_clk(ptp_clk),
|
||||||
.tx_ptp_ts_step(tx_ptp_ts_step),
|
.ptp_rst(ptp_rst),
|
||||||
.rx_ptp_ts(rx_ptp_ts),
|
.ptp_sample_clk(ptp_sample_clk),
|
||||||
.rx_ptp_ts_step(rx_ptp_ts_step),
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
.tx_ptp_ts_in(tx_ptp_ts_in),
|
||||||
|
.tx_ptp_ts_out(tx_ptp_ts_out),
|
||||||
|
.tx_ptp_ts_step_out(tx_ptp_ts_step_out),
|
||||||
|
.tx_ptp_locked(tx_ptp_locked),
|
||||||
|
.rx_ptp_ts_in(rx_ptp_ts_in),
|
||||||
|
.rx_ptp_ts_out(rx_ptp_ts_out),
|
||||||
|
.rx_ptp_ts_step_out(rx_ptp_ts_step_out),
|
||||||
|
.rx_ptp_locked(rx_ptp_locked),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -40,8 +40,10 @@ export PARAM_PADDING_EN := 1
|
|||||||
export PARAM_DIC_EN := 1
|
export PARAM_DIC_EN := 1
|
||||||
export PARAM_MIN_FRAME_LEN := 64
|
export PARAM_MIN_FRAME_LEN := 64
|
||||||
export PARAM_PTP_TS_EN := 1
|
export PARAM_PTP_TS_EN := 1
|
||||||
|
export PARAM_PTP_TD_EN := $(PARAM_PTP_TS_EN)
|
||||||
export PARAM_PTP_TS_FMT_TOD := 1
|
export PARAM_PTP_TS_FMT_TOD := 1
|
||||||
export PARAM_PTP_TS_W := $(if $(filter-out 1,$(PARAM_PTP_TS_FMT_TOD)),64,96)
|
export PARAM_PTP_TS_W := $(if $(filter-out 1,$(PARAM_PTP_TS_FMT_TOD)),64,96)
|
||||||
|
export PARAM_PTP_TD_SDI_PIPELINE := 2
|
||||||
export PARAM_TX_TAG_W := 16
|
export PARAM_TX_TAG_W := 16
|
||||||
export PARAM_BIT_REVERSE := 0
|
export PARAM_BIT_REVERSE := 0
|
||||||
export PARAM_SCRAMBLER_DISABLE := 0
|
export PARAM_SCRAMBLER_DISABLE := 0
|
||||||
|
|||||||
1
src/eth/tb/taxi_eth_mac_phy_10g/ptp_td.py
Symbolic link
1
src/eth/tb/taxi_eth_mac_phy_10g/ptp_td.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../lib/taxi/src/ptp/tb/ptp_td.py
|
||||||
@@ -31,11 +31,13 @@ from cocotbext.axi import AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiStrea
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
from baser import BaseRSerdesSource, BaseRSerdesSink
|
from baser import BaseRSerdesSource, BaseRSerdesSink
|
||||||
|
from ptp_td import PtpTdSource
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# attempt import from current directory
|
# attempt import from current directory
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__)))
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__)))
|
||||||
try:
|
try:
|
||||||
from baser import BaseRSerdesSource, BaseRSerdesSink
|
from baser import BaseRSerdesSource, BaseRSerdesSink
|
||||||
|
from ptp_td import PtpTdSource
|
||||||
finally:
|
finally:
|
||||||
del sys.path[0]
|
del sys.path[0]
|
||||||
|
|
||||||
@@ -89,8 +91,20 @@ class TB:
|
|||||||
|
|
||||||
self.stat_sink = AxiStreamSink(AxiStreamBus.from_entity(dut.m_axis_stat), dut.stat_clk, dut.stat_rst)
|
self.stat_sink = AxiStreamSink(AxiStreamBus.from_entity(dut.m_axis_stat), dut.stat_clk, dut.stat_rst)
|
||||||
|
|
||||||
self.rx_ptp_clock = PtpClockSimTime(ts_tod=dut.rx_ptp_ts, clock=dut.rx_clk)
|
self.rx_ptp_clock = PtpClockSimTime(ts_tod=dut.rx_ptp_ts_in, clock=dut.rx_clk)
|
||||||
self.tx_ptp_clock = PtpClockSimTime(ts_tod=dut.tx_ptp_ts, clock=dut.tx_clk)
|
self.tx_ptp_clock = PtpClockSimTime(ts_tod=dut.tx_ptp_ts_in, clock=dut.tx_clk)
|
||||||
|
|
||||||
|
self.ptp_clk_period = self.clk_period
|
||||||
|
|
||||||
|
cocotb.start_soon(Clock(dut.ptp_clk, self.ptp_clk_period, units="ns").start())
|
||||||
|
cocotb.start_soon(Clock(dut.ptp_sample_clk, 8, units="ns").start())
|
||||||
|
|
||||||
|
self.ptp_td_source = PtpTdSource(
|
||||||
|
data=dut.ptp_td_sdi,
|
||||||
|
clock=dut.ptp_clk,
|
||||||
|
reset=dut.ptp_rst,
|
||||||
|
period_ns=self.ptp_clk_period
|
||||||
|
)
|
||||||
|
|
||||||
dut.stat_rx_fifo_drop.setimmediatevalue(0)
|
dut.stat_rx_fifo_drop.setimmediatevalue(0)
|
||||||
|
|
||||||
@@ -136,20 +150,26 @@ class TB:
|
|||||||
async def reset(self):
|
async def reset(self):
|
||||||
self.dut.rx_rst.setimmediatevalue(0)
|
self.dut.rx_rst.setimmediatevalue(0)
|
||||||
self.dut.tx_rst.setimmediatevalue(0)
|
self.dut.tx_rst.setimmediatevalue(0)
|
||||||
|
self.dut.ptp_rst.setimmediatevalue(0)
|
||||||
self.dut.stat_rst.setimmediatevalue(0)
|
self.dut.stat_rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.rx_clk)
|
await RisingEdge(self.dut.rx_clk)
|
||||||
await RisingEdge(self.dut.rx_clk)
|
await RisingEdge(self.dut.rx_clk)
|
||||||
self.dut.rx_rst.value = 1
|
self.dut.rx_rst.value = 1
|
||||||
self.dut.tx_rst.value = 1
|
self.dut.tx_rst.value = 1
|
||||||
|
self.dut.ptp_rst.value = 1
|
||||||
self.dut.stat_rst.value = 1
|
self.dut.stat_rst.value = 1
|
||||||
await RisingEdge(self.dut.rx_clk)
|
await RisingEdge(self.dut.rx_clk)
|
||||||
await RisingEdge(self.dut.rx_clk)
|
await RisingEdge(self.dut.rx_clk)
|
||||||
self.dut.rx_rst.value = 0
|
self.dut.rx_rst.value = 0
|
||||||
self.dut.tx_rst.value = 0
|
self.dut.tx_rst.value = 0
|
||||||
|
self.dut.ptp_rst.value = 0
|
||||||
self.dut.stat_rst.value = 0
|
self.dut.stat_rst.value = 0
|
||||||
await RisingEdge(self.dut.rx_clk)
|
await RisingEdge(self.dut.rx_clk)
|
||||||
await RisingEdge(self.dut.rx_clk)
|
await RisingEdge(self.dut.rx_clk)
|
||||||
|
|
||||||
|
self.ptp_td_source.set_ts_tod_sim_time()
|
||||||
|
self.ptp_td_source.set_ts_rel_sim_time()
|
||||||
|
|
||||||
|
|
||||||
async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, ifg=12):
|
async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, ifg=12):
|
||||||
|
|
||||||
@@ -172,6 +192,13 @@ async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
|
|||||||
while not int(dut.rx_block_lock.value):
|
while not int(dut.rx_block_lock.value):
|
||||||
await RisingEdge(dut.rx_clk)
|
await RisingEdge(dut.rx_clk)
|
||||||
|
|
||||||
|
if dut.PTP_TD_EN.value:
|
||||||
|
tb.log.info("Wait for PTP CDC lock")
|
||||||
|
while not int(dut.rx_ptp_locked.value):
|
||||||
|
await RisingEdge(dut.rx_clk)
|
||||||
|
for k in range(2000):
|
||||||
|
await RisingEdge(dut.rx_clk)
|
||||||
|
|
||||||
tb.dut.cfg_rx_enable.value = 1
|
tb.dut.cfg_rx_enable.value = 1
|
||||||
|
|
||||||
test_frames = [payload_data(x) for x in payload_lengths()]
|
test_frames = [payload_data(x) for x in payload_lengths()]
|
||||||
@@ -208,7 +235,10 @@ async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
|
|||||||
assert rx_frame.tdata == test_data
|
assert rx_frame.tdata == test_data
|
||||||
assert frame_error == 0
|
assert frame_error == 0
|
||||||
if gbx_cfg is None:
|
if gbx_cfg is None:
|
||||||
assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < 0.01
|
if dut.PTP_TD_EN.value:
|
||||||
|
assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < tb.clk_period*5
|
||||||
|
else:
|
||||||
|
assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < 0.01
|
||||||
|
|
||||||
assert tb.axis_sink.empty()
|
assert tb.axis_sink.empty()
|
||||||
|
|
||||||
@@ -231,8 +261,15 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
|
|||||||
|
|
||||||
await tb.reset()
|
await tb.reset()
|
||||||
|
|
||||||
for k in range(100):
|
if dut.PTP_TD_EN.value:
|
||||||
await RisingEdge(dut.tx_clk)
|
tb.log.info("Wait for PTP CDC lock")
|
||||||
|
while not int(dut.tx_ptp_locked.value):
|
||||||
|
await RisingEdge(dut.tx_clk)
|
||||||
|
for k in range(2000):
|
||||||
|
await RisingEdge(dut.tx_clk)
|
||||||
|
else:
|
||||||
|
for k in range(100):
|
||||||
|
await RisingEdge(dut.tx_clk)
|
||||||
|
|
||||||
tb.dut.cfg_tx_enable.value = 1
|
tb.dut.cfg_tx_enable.value = 1
|
||||||
tb.serdes_sink.clear()
|
tb.serdes_sink.clear()
|
||||||
@@ -266,7 +303,10 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
|
|||||||
assert rx_frame.check_fcs()
|
assert rx_frame.check_fcs()
|
||||||
assert rx_frame.ctrl is None
|
assert rx_frame.ctrl is None
|
||||||
if gbx_cfg is None:
|
if gbx_cfg is None:
|
||||||
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < 0.01
|
if dut.PTP_TD_EN.value:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*5
|
||||||
|
else:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < 0.01
|
||||||
|
|
||||||
assert tb.serdes_sink.empty()
|
assert tb.serdes_sink.empty()
|
||||||
|
|
||||||
@@ -293,8 +333,15 @@ async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12):
|
|||||||
|
|
||||||
await tb.reset()
|
await tb.reset()
|
||||||
|
|
||||||
for k in range(100):
|
if dut.PTP_TD_EN.value:
|
||||||
await RisingEdge(dut.tx_clk)
|
tb.log.info("Wait for PTP CDC lock")
|
||||||
|
while not int(dut.tx_ptp_locked.value):
|
||||||
|
await RisingEdge(dut.tx_clk)
|
||||||
|
for k in range(2000):
|
||||||
|
await RisingEdge(dut.tx_clk)
|
||||||
|
else:
|
||||||
|
for k in range(100):
|
||||||
|
await RisingEdge(dut.tx_clk)
|
||||||
|
|
||||||
tb.dut.cfg_tx_enable.value = 1
|
tb.dut.cfg_tx_enable.value = 1
|
||||||
tb.serdes_sink.clear()
|
tb.serdes_sink.clear()
|
||||||
@@ -333,7 +380,10 @@ async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12):
|
|||||||
assert rx_frame.check_fcs()
|
assert rx_frame.check_fcs()
|
||||||
assert rx_frame.ctrl is None
|
assert rx_frame.ctrl is None
|
||||||
if gbx_cfg is None:
|
if gbx_cfg is None:
|
||||||
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < 0.01
|
if dut.PTP_TD_EN.value:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*5
|
||||||
|
else:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < 0.01
|
||||||
|
|
||||||
start_lane.append(rx_frame.start_lane)
|
start_lane.append(rx_frame.start_lane)
|
||||||
|
|
||||||
@@ -885,8 +935,9 @@ def process_f_files(files):
|
|||||||
|
|
||||||
@pytest.mark.parametrize(("dic_en", "pfc_en"), [(1, 1), (1, 0), (0, 0)])
|
@pytest.mark.parametrize(("dic_en", "pfc_en"), [(1, 1), (1, 0), (0, 0)])
|
||||||
@pytest.mark.parametrize("gbx_en", [1, 0])
|
@pytest.mark.parametrize("gbx_en", [1, 0])
|
||||||
|
@pytest.mark.parametrize("ptp_td_en", [1, 0])
|
||||||
@pytest.mark.parametrize("data_w", [32, 64])
|
@pytest.mark.parametrize("data_w", [32, 64])
|
||||||
def test_taxi_eth_mac_phy_10g(request, data_w, gbx_en, dic_en, pfc_en):
|
def test_taxi_eth_mac_phy_10g(request, data_w, ptp_td_en, gbx_en, dic_en, pfc_en):
|
||||||
dut = "taxi_eth_mac_phy_10g"
|
dut = "taxi_eth_mac_phy_10g"
|
||||||
module = os.path.splitext(os.path.basename(__file__))[0]
|
module = os.path.splitext(os.path.basename(__file__))[0]
|
||||||
toplevel = module
|
toplevel = module
|
||||||
@@ -908,8 +959,10 @@ def test_taxi_eth_mac_phy_10g(request, data_w, gbx_en, dic_en, pfc_en):
|
|||||||
parameters['DIC_EN'] = dic_en
|
parameters['DIC_EN'] = dic_en
|
||||||
parameters['MIN_FRAME_LEN'] = 64
|
parameters['MIN_FRAME_LEN'] = 64
|
||||||
parameters['PTP_TS_EN'] = 1
|
parameters['PTP_TS_EN'] = 1
|
||||||
|
parameters['PTP_TD_EN'] = ptp_td_en
|
||||||
parameters['PTP_TS_FMT_TOD'] = 1
|
parameters['PTP_TS_FMT_TOD'] = 1
|
||||||
parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64
|
parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64
|
||||||
|
parameters['PTP_TD_SDI_PIPELINE'] = 2
|
||||||
parameters['TX_TAG_W'] = 16
|
parameters['TX_TAG_W'] = 16
|
||||||
parameters['BIT_REVERSE'] = 0
|
parameters['BIT_REVERSE'] = 0
|
||||||
parameters['SCRAMBLER_DISABLE'] = 0
|
parameters['SCRAMBLER_DISABLE'] = 0
|
||||||
|
|||||||
@@ -26,8 +26,10 @@ module test_taxi_eth_mac_phy_10g #
|
|||||||
parameter logic DIC_EN = 1'b1,
|
parameter logic DIC_EN = 1'b1,
|
||||||
parameter MIN_FRAME_LEN = 64,
|
parameter MIN_FRAME_LEN = 64,
|
||||||
parameter logic PTP_TS_EN = 1'b0,
|
parameter logic PTP_TS_EN = 1'b0,
|
||||||
|
parameter logic PTP_TD_EN = PTP_TS_EN,
|
||||||
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
||||||
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
||||||
|
parameter PTP_TD_SDI_PIPELINE = 2,
|
||||||
parameter TX_TAG_W = 16,
|
parameter TX_TAG_W = 16,
|
||||||
parameter logic BIT_REVERSE = 1'b0,
|
parameter logic BIT_REVERSE = 1'b0,
|
||||||
parameter logic SCRAMBLER_DISABLE = 1'b0,
|
parameter logic SCRAMBLER_DISABLE = 1'b0,
|
||||||
@@ -76,8 +78,18 @@ logic serdes_rx_hdr_valid;
|
|||||||
logic serdes_rx_bitslip;
|
logic serdes_rx_bitslip;
|
||||||
logic serdes_rx_reset_req;
|
logic serdes_rx_reset_req;
|
||||||
|
|
||||||
logic [PTP_TS_W-1:0] tx_ptp_ts;
|
logic ptp_clk;
|
||||||
logic [PTP_TS_W-1:0] rx_ptp_ts;
|
logic ptp_rst;
|
||||||
|
logic ptp_sample_clk;
|
||||||
|
logic ptp_td_sdi;
|
||||||
|
logic [PTP_TS_W-1:0] tx_ptp_ts_in;
|
||||||
|
logic [PTP_TS_W-1:0] tx_ptp_ts_out;
|
||||||
|
logic tx_ptp_ts_step_out;
|
||||||
|
logic tx_ptp_locked;
|
||||||
|
logic [PTP_TS_W-1:0] rx_ptp_ts_in;
|
||||||
|
logic [PTP_TS_W-1:0] rx_ptp_ts_out;
|
||||||
|
logic rx_ptp_ts_step_out;
|
||||||
|
logic rx_ptp_locked;
|
||||||
|
|
||||||
logic tx_lfc_req;
|
logic tx_lfc_req;
|
||||||
logic tx_lfc_resend;
|
logic tx_lfc_resend;
|
||||||
@@ -199,8 +211,10 @@ taxi_eth_mac_phy_10g #(
|
|||||||
.DIC_EN(DIC_EN),
|
.DIC_EN(DIC_EN),
|
||||||
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
||||||
.PTP_TS_EN(PTP_TS_EN),
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
|
.PTP_TD_EN(PTP_TD_EN),
|
||||||
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
||||||
.PTP_TS_W(PTP_TS_W),
|
.PTP_TS_W(PTP_TS_W),
|
||||||
|
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
|
||||||
.BIT_REVERSE(BIT_REVERSE),
|
.BIT_REVERSE(BIT_REVERSE),
|
||||||
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE),
|
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE),
|
||||||
.PRBS31_EN(PRBS31_EN),
|
.PRBS31_EN(PRBS31_EN),
|
||||||
@@ -256,8 +270,18 @@ uut (
|
|||||||
/*
|
/*
|
||||||
* PTP
|
* PTP
|
||||||
*/
|
*/
|
||||||
.tx_ptp_ts(tx_ptp_ts),
|
.ptp_clk(ptp_clk),
|
||||||
.rx_ptp_ts(rx_ptp_ts),
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_sample_clk(ptp_sample_clk),
|
||||||
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
.tx_ptp_ts_in(tx_ptp_ts_in),
|
||||||
|
.tx_ptp_ts_out(tx_ptp_ts_out),
|
||||||
|
.tx_ptp_ts_step_out(tx_ptp_ts_step_out),
|
||||||
|
.tx_ptp_locked(tx_ptp_locked),
|
||||||
|
.rx_ptp_ts_in(rx_ptp_ts_in),
|
||||||
|
.rx_ptp_ts_out(rx_ptp_ts_out),
|
||||||
|
.rx_ptp_ts_step_out(rx_ptp_ts_step_out),
|
||||||
|
.rx_ptp_locked(rx_ptp_locked),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||||
|
|||||||
@@ -41,8 +41,10 @@ export PARAM_PADDING_EN := 1
|
|||||||
export PARAM_DIC_EN := 1
|
export PARAM_DIC_EN := 1
|
||||||
export PARAM_MIN_FRAME_LEN := 64
|
export PARAM_MIN_FRAME_LEN := 64
|
||||||
export PARAM_PTP_TS_EN := 1
|
export PARAM_PTP_TS_EN := 1
|
||||||
|
export PARAM_PTP_TD_EN := $(PARAM_PTP_TS_EN)
|
||||||
export PARAM_PTP_TS_FMT_TOD := 1
|
export PARAM_PTP_TS_FMT_TOD := 1
|
||||||
export PARAM_PTP_TS_W := $(if $(filter-out 1,$(PARAM_PTP_TS_FMT_TOD)),64,96)
|
export PARAM_PTP_TS_W := $(if $(filter-out 1,$(PARAM_PTP_TS_FMT_TOD)),64,96)
|
||||||
|
export PARAM_PTP_TD_SDI_PIPELINE := 2
|
||||||
export PARAM_TX_TAG_W := 16
|
export PARAM_TX_TAG_W := 16
|
||||||
export PARAM_BIT_REVERSE := 0
|
export PARAM_BIT_REVERSE := 0
|
||||||
export PARAM_SCRAMBLER_DISABLE := 0
|
export PARAM_SCRAMBLER_DISABLE := 0
|
||||||
|
|||||||
1
src/eth/tb/taxi_eth_mac_phy_10g_fifo/ptp_td.py
Symbolic link
1
src/eth/tb/taxi_eth_mac_phy_10g_fifo/ptp_td.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../lib/taxi/src/ptp/tb/ptp_td.py
|
||||||
@@ -28,11 +28,13 @@ from cocotbext.axi import AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiStrea
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
from baser import BaseRSerdesSource, BaseRSerdesSink
|
from baser import BaseRSerdesSource, BaseRSerdesSink
|
||||||
|
from ptp_td import PtpTdSource
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# attempt import from current directory
|
# attempt import from current directory
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__)))
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__)))
|
||||||
try:
|
try:
|
||||||
from baser import BaseRSerdesSource, BaseRSerdesSink
|
from baser import BaseRSerdesSource, BaseRSerdesSink
|
||||||
|
from ptp_td import PtpTdSource
|
||||||
finally:
|
finally:
|
||||||
del sys.path[0]
|
del sys.path[0]
|
||||||
|
|
||||||
@@ -59,7 +61,6 @@ class TB:
|
|||||||
cocotb.start_soon(Clock(dut.rx_clk, self.clk_period, units="ns").start())
|
cocotb.start_soon(Clock(dut.rx_clk, self.clk_period, units="ns").start())
|
||||||
cocotb.start_soon(Clock(dut.tx_clk, self.clk_period, units="ns").start())
|
cocotb.start_soon(Clock(dut.tx_clk, self.clk_period, units="ns").start())
|
||||||
cocotb.start_soon(Clock(dut.stat_clk, self.clk_period, units="ns").start())
|
cocotb.start_soon(Clock(dut.stat_clk, self.clk_period, units="ns").start())
|
||||||
cocotb.start_soon(Clock(dut.ptp_sample_clk, 9.9, units="ns").start())
|
|
||||||
|
|
||||||
self.serdes_source = BaseRSerdesSource(
|
self.serdes_source = BaseRSerdesSource(
|
||||||
data=dut.serdes_rx_data,
|
data=dut.serdes_rx_data,
|
||||||
@@ -88,9 +89,20 @@ class TB:
|
|||||||
|
|
||||||
self.stat_sink = AxiStreamSink(AxiStreamBus.from_entity(dut.m_axis_stat), dut.stat_clk, dut.stat_rst)
|
self.stat_sink = AxiStreamSink(AxiStreamBus.from_entity(dut.m_axis_stat), dut.stat_clk, dut.stat_rst)
|
||||||
|
|
||||||
self.ptp_clock = PtpClockSimTime(ts_tod=dut.ptp_ts, clock=dut.logic_clk)
|
self.ptp_clock = PtpClockSimTime(ts_tod=dut.ptp_ts_in, clock=dut.logic_clk)
|
||||||
|
dut.ptp_ts_step_in.setimmediatevalue(0)
|
||||||
|
|
||||||
dut.ptp_ts_step.setimmediatevalue(0)
|
self.ptp_clk_period = self.clk_period
|
||||||
|
|
||||||
|
cocotb.start_soon(Clock(dut.ptp_clk, self.ptp_clk_period, units="ns").start())
|
||||||
|
cocotb.start_soon(Clock(dut.ptp_sample_clk, 8, units="ns").start())
|
||||||
|
|
||||||
|
self.ptp_td_source = PtpTdSource(
|
||||||
|
data=dut.ptp_td_sdi,
|
||||||
|
clock=dut.ptp_clk,
|
||||||
|
reset=dut.ptp_rst,
|
||||||
|
period_ns=self.ptp_clk_period
|
||||||
|
)
|
||||||
|
|
||||||
dut.cfg_tx_max_pkt_len.setimmediatevalue(0)
|
dut.cfg_tx_max_pkt_len.setimmediatevalue(0)
|
||||||
dut.cfg_tx_ifg.setimmediatevalue(0)
|
dut.cfg_tx_ifg.setimmediatevalue(0)
|
||||||
@@ -104,22 +116,28 @@ class TB:
|
|||||||
self.dut.logic_rst.setimmediatevalue(0)
|
self.dut.logic_rst.setimmediatevalue(0)
|
||||||
self.dut.rx_rst.setimmediatevalue(0)
|
self.dut.rx_rst.setimmediatevalue(0)
|
||||||
self.dut.tx_rst.setimmediatevalue(0)
|
self.dut.tx_rst.setimmediatevalue(0)
|
||||||
|
self.dut.ptp_rst.setimmediatevalue(0)
|
||||||
self.dut.stat_rst.setimmediatevalue(0)
|
self.dut.stat_rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.logic_clk)
|
await RisingEdge(self.dut.logic_clk)
|
||||||
await RisingEdge(self.dut.logic_clk)
|
await RisingEdge(self.dut.logic_clk)
|
||||||
self.dut.logic_rst.value = 1
|
self.dut.logic_rst.value = 1
|
||||||
self.dut.rx_rst.value = 1
|
self.dut.rx_rst.value = 1
|
||||||
self.dut.tx_rst.value = 1
|
self.dut.tx_rst.value = 1
|
||||||
|
self.dut.ptp_rst.value = 1
|
||||||
self.dut.stat_rst.value = 1
|
self.dut.stat_rst.value = 1
|
||||||
await RisingEdge(self.dut.logic_clk)
|
await RisingEdge(self.dut.logic_clk)
|
||||||
await RisingEdge(self.dut.logic_clk)
|
await RisingEdge(self.dut.logic_clk)
|
||||||
self.dut.logic_rst.value = 0
|
self.dut.logic_rst.value = 0
|
||||||
self.dut.rx_rst.value = 0
|
self.dut.rx_rst.value = 0
|
||||||
self.dut.tx_rst.value = 0
|
self.dut.tx_rst.value = 0
|
||||||
|
self.dut.ptp_rst.value = 0
|
||||||
self.dut.stat_rst.value = 0
|
self.dut.stat_rst.value = 0
|
||||||
await RisingEdge(self.dut.logic_clk)
|
await RisingEdge(self.dut.logic_clk)
|
||||||
await RisingEdge(self.dut.logic_clk)
|
await RisingEdge(self.dut.logic_clk)
|
||||||
|
|
||||||
|
self.ptp_td_source.set_ts_tod_sim_time()
|
||||||
|
self.ptp_td_source.set_ts_rel_sim_time()
|
||||||
|
|
||||||
|
|
||||||
async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, ifg=12):
|
async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, ifg=12):
|
||||||
|
|
||||||
@@ -142,9 +160,9 @@ async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
|
|||||||
await RisingEdge(dut.rx_clk)
|
await RisingEdge(dut.rx_clk)
|
||||||
|
|
||||||
tb.log.info("Wait for PTP CDC lock")
|
tb.log.info("Wait for PTP CDC lock")
|
||||||
while not int(dut.uut.rx_ptp_locked.value):
|
while not int(dut.rx_ptp_locked.value):
|
||||||
await RisingEdge(dut.rx_clk)
|
await RisingEdge(dut.rx_clk)
|
||||||
for k in range(1000):
|
for k in range(2000):
|
||||||
await RisingEdge(dut.rx_clk)
|
await RisingEdge(dut.rx_clk)
|
||||||
|
|
||||||
# clear out sink buffer
|
# clear out sink buffer
|
||||||
@@ -181,7 +199,10 @@ async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
|
|||||||
assert rx_frame.tdata == test_data
|
assert rx_frame.tdata == test_data
|
||||||
assert frame_error == 0
|
assert frame_error == 0
|
||||||
if gbx_cfg is None:
|
if gbx_cfg is None:
|
||||||
assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < tb.clk_period*2
|
if dut.PTP_TD_EN.value:
|
||||||
|
assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < tb.clk_period*5
|
||||||
|
else:
|
||||||
|
assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < tb.clk_period*2
|
||||||
|
|
||||||
assert tb.axis_sink.empty()
|
assert tb.axis_sink.empty()
|
||||||
|
|
||||||
@@ -205,9 +226,9 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
|
|||||||
await tb.reset()
|
await tb.reset()
|
||||||
|
|
||||||
tb.log.info("Wait for PTP CDC lock")
|
tb.log.info("Wait for PTP CDC lock")
|
||||||
while not int(dut.uut.tx_ptp_locked.value):
|
while not int(dut.tx_ptp_locked.value):
|
||||||
await RisingEdge(dut.tx_clk)
|
await RisingEdge(dut.tx_clk)
|
||||||
for k in range(1000):
|
for k in range(2000):
|
||||||
await RisingEdge(dut.tx_clk)
|
await RisingEdge(dut.tx_clk)
|
||||||
|
|
||||||
tb.dut.cfg_tx_enable.value = 1
|
tb.dut.cfg_tx_enable.value = 1
|
||||||
@@ -241,7 +262,10 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
|
|||||||
assert rx_frame.check_fcs()
|
assert rx_frame.check_fcs()
|
||||||
assert rx_frame.ctrl is None
|
assert rx_frame.ctrl is None
|
||||||
if gbx_cfg is None:
|
if gbx_cfg is None:
|
||||||
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*2
|
if dut.PTP_TD_EN.value:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*5
|
||||||
|
else:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*2
|
||||||
|
|
||||||
assert tb.serdes_sink.empty()
|
assert tb.serdes_sink.empty()
|
||||||
|
|
||||||
@@ -269,9 +293,9 @@ async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12):
|
|||||||
await tb.reset()
|
await tb.reset()
|
||||||
|
|
||||||
tb.log.info("Wait for PTP CDC lock")
|
tb.log.info("Wait for PTP CDC lock")
|
||||||
while not int(dut.uut.tx_ptp_locked.value):
|
while not int(dut.tx_ptp_locked.value):
|
||||||
await RisingEdge(dut.tx_clk)
|
await RisingEdge(dut.tx_clk)
|
||||||
for k in range(1000):
|
for k in range(2000):
|
||||||
await RisingEdge(dut.tx_clk)
|
await RisingEdge(dut.tx_clk)
|
||||||
|
|
||||||
tb.dut.cfg_tx_enable.value = 1
|
tb.dut.cfg_tx_enable.value = 1
|
||||||
@@ -311,7 +335,10 @@ async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12):
|
|||||||
assert rx_frame.check_fcs()
|
assert rx_frame.check_fcs()
|
||||||
assert rx_frame.ctrl is None
|
assert rx_frame.ctrl is None
|
||||||
if gbx_cfg is None:
|
if gbx_cfg is None:
|
||||||
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*2
|
if dut.PTP_TD_EN.value:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*5
|
||||||
|
else:
|
||||||
|
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*2
|
||||||
|
|
||||||
start_lane.append(rx_frame.start_lane)
|
start_lane.append(rx_frame.start_lane)
|
||||||
|
|
||||||
@@ -481,8 +508,10 @@ def test_taxi_eth_mac_phy_10g_fifo(request, data_w, gbx_en, dic_en):
|
|||||||
parameters['DIC_EN'] = dic_en
|
parameters['DIC_EN'] = dic_en
|
||||||
parameters['MIN_FRAME_LEN'] = 64
|
parameters['MIN_FRAME_LEN'] = 64
|
||||||
parameters['PTP_TS_EN'] = 1
|
parameters['PTP_TS_EN'] = 1
|
||||||
|
parameters['PTP_TD_EN'] = parameters['PTP_TS_EN']
|
||||||
parameters['PTP_TS_FMT_TOD'] = 1
|
parameters['PTP_TS_FMT_TOD'] = 1
|
||||||
parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64
|
parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64
|
||||||
|
parameters['PTP_TD_SDI_PIPELINE'] = 2
|
||||||
parameters['TX_TAG_W'] = 16
|
parameters['TX_TAG_W'] = 16
|
||||||
parameters['BIT_REVERSE'] = 0
|
parameters['BIT_REVERSE'] = 0
|
||||||
parameters['SCRAMBLER_DISABLE'] = 0
|
parameters['SCRAMBLER_DISABLE'] = 0
|
||||||
|
|||||||
@@ -27,8 +27,10 @@ module test_taxi_eth_mac_phy_10g_fifo #
|
|||||||
parameter logic DIC_EN = 1'b1,
|
parameter logic DIC_EN = 1'b1,
|
||||||
parameter MIN_FRAME_LEN = 64,
|
parameter MIN_FRAME_LEN = 64,
|
||||||
parameter logic PTP_TS_EN = 1'b0,
|
parameter logic PTP_TS_EN = 1'b0,
|
||||||
|
parameter logic PTP_TD_EN = PTP_TS_EN,
|
||||||
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
||||||
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
|
||||||
|
parameter PTP_TD_SDI_PIPELINE = 2,
|
||||||
parameter TX_TAG_W = 16,
|
parameter TX_TAG_W = 16,
|
||||||
parameter logic BIT_REVERSE = 1'b0,
|
parameter logic BIT_REVERSE = 1'b0,
|
||||||
parameter logic SCRAMBLER_DISABLE = 1'b0,
|
parameter logic SCRAMBLER_DISABLE = 1'b0,
|
||||||
@@ -71,7 +73,6 @@ logic tx_clk;
|
|||||||
logic tx_rst;
|
logic tx_rst;
|
||||||
logic logic_clk;
|
logic logic_clk;
|
||||||
logic logic_rst;
|
logic logic_rst;
|
||||||
logic ptp_sample_clk;
|
|
||||||
|
|
||||||
taxi_axis_if #(.DATA_W(AXIS_DATA_W), .USER_EN(1), .USER_W(TX_USER_W), .ID_EN(1), .ID_W(TX_TAG_W)) s_axis_tx();
|
taxi_axis_if #(.DATA_W(AXIS_DATA_W), .USER_EN(1), .USER_W(TX_USER_W), .ID_EN(1), .ID_W(TX_TAG_W)) s_axis_tx();
|
||||||
taxi_axis_if #(.DATA_W(96), .KEEP_W(1), .ID_EN(1), .ID_W(TX_TAG_W)) m_axis_tx_cpl();
|
taxi_axis_if #(.DATA_W(96), .KEEP_W(1), .ID_EN(1), .ID_W(TX_TAG_W)) m_axis_tx_cpl();
|
||||||
@@ -91,8 +92,18 @@ logic serdes_rx_hdr_valid;
|
|||||||
logic serdes_rx_bitslip;
|
logic serdes_rx_bitslip;
|
||||||
logic serdes_rx_reset_req;
|
logic serdes_rx_reset_req;
|
||||||
|
|
||||||
logic [PTP_TS_W-1:0] ptp_ts;
|
logic ptp_clk;
|
||||||
logic ptp_ts_step;
|
logic ptp_rst;
|
||||||
|
logic ptp_sample_clk;
|
||||||
|
logic ptp_td_sdi;
|
||||||
|
logic [PTP_TS_W-1:0] ptp_ts_in;
|
||||||
|
logic ptp_ts_step_in;
|
||||||
|
logic [PTP_TS_W-1:0] tx_ptp_ts_out;
|
||||||
|
logic tx_ptp_ts_step_out;
|
||||||
|
logic tx_ptp_locked;
|
||||||
|
logic [PTP_TS_W-1:0] rx_ptp_ts_out;
|
||||||
|
logic rx_ptp_ts_step_out;
|
||||||
|
logic rx_ptp_locked;
|
||||||
|
|
||||||
logic stat_clk;
|
logic stat_clk;
|
||||||
logic stat_rst;
|
logic stat_rst;
|
||||||
@@ -130,8 +141,10 @@ taxi_eth_mac_phy_10g_fifo #(
|
|||||||
.DIC_EN(DIC_EN),
|
.DIC_EN(DIC_EN),
|
||||||
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
||||||
.PTP_TS_EN(PTP_TS_EN),
|
.PTP_TS_EN(PTP_TS_EN),
|
||||||
|
.PTP_TD_EN(PTP_TD_EN),
|
||||||
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
||||||
.PTP_TS_W(PTP_TS_W),
|
.PTP_TS_W(PTP_TS_W),
|
||||||
|
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
|
||||||
.BIT_REVERSE(BIT_REVERSE),
|
.BIT_REVERSE(BIT_REVERSE),
|
||||||
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE),
|
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE),
|
||||||
.PRBS31_EN(PRBS31_EN),
|
.PRBS31_EN(PRBS31_EN),
|
||||||
@@ -168,7 +181,6 @@ uut (
|
|||||||
.tx_rst(tx_rst),
|
.tx_rst(tx_rst),
|
||||||
.logic_clk(logic_clk),
|
.logic_clk(logic_clk),
|
||||||
.logic_rst(logic_rst),
|
.logic_rst(logic_rst),
|
||||||
.ptp_sample_clk(ptp_sample_clk),
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit interface (AXI stream)
|
* Transmit interface (AXI stream)
|
||||||
@@ -201,8 +213,18 @@ uut (
|
|||||||
/*
|
/*
|
||||||
* PTP clock
|
* PTP clock
|
||||||
*/
|
*/
|
||||||
.ptp_ts(ptp_ts),
|
.ptp_clk(ptp_clk),
|
||||||
.ptp_ts_step(ptp_ts_step),
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_sample_clk(ptp_sample_clk),
|
||||||
|
.ptp_td_sdi(ptp_td_sdi),
|
||||||
|
.ptp_ts_in(ptp_ts_in),
|
||||||
|
.ptp_ts_step_in(ptp_ts_step_in),
|
||||||
|
.tx_ptp_ts_out(tx_ptp_ts_out),
|
||||||
|
.tx_ptp_ts_step_out(tx_ptp_ts_step_out),
|
||||||
|
.tx_ptp_locked(tx_ptp_locked),
|
||||||
|
.rx_ptp_ts_out(rx_ptp_ts_out),
|
||||||
|
.rx_ptp_ts_step_out(rx_ptp_ts_step_out),
|
||||||
|
.rx_ptp_locked(rx_ptp_locked),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Statistics
|
* Statistics
|
||||||
|
|||||||
164
src/pcie/rtl/taxi_pcie_us_cfg.sv
Normal file
164
src/pcie/rtl/taxi_pcie_us_cfg.sv
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
// SPDX-License-Identifier: CERN-OHL-S-2.0
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2018-2025 FPGA Ninja, LLC
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
- Alex Forencich
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
`resetall
|
||||||
|
`timescale 1ns / 1ps
|
||||||
|
`default_nettype none
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UltraScale PCIe configuration shim
|
||||||
|
*/
|
||||||
|
module taxi_pcie_us_cfg #
|
||||||
|
(
|
||||||
|
parameter PF_COUNT = 1,
|
||||||
|
parameter VF_COUNT = 0,
|
||||||
|
parameter VF_OFFSET = 64,
|
||||||
|
parameter F_COUNT = PF_COUNT+VF_COUNT,
|
||||||
|
parameter logic READ_EXT_TAG_ENABLE = 1'b1,
|
||||||
|
parameter logic READ_MAX_READ_REQ_SIZE = 1'b1,
|
||||||
|
parameter logic READ_MAX_PAYLOAD_SIZE = 1'b1,
|
||||||
|
parameter PCIE_CAP_OFFSET = 12'h0C0
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input wire logic clk,
|
||||||
|
input wire logic rst,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configuration outputs
|
||||||
|
*/
|
||||||
|
output wire logic [F_COUNT-1:0] ext_tag_en,
|
||||||
|
output wire logic [F_COUNT*3-1:0] max_read_req_size,
|
||||||
|
output wire logic [F_COUNT*3-1:0] max_payload_size,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interface to Ultrascale PCIe IP core
|
||||||
|
*/
|
||||||
|
output wire logic [9:0] cfg_mgmt_addr,
|
||||||
|
output wire logic [7:0] cfg_mgmt_function_number,
|
||||||
|
output wire logic cfg_mgmt_write,
|
||||||
|
output wire logic [31:0] cfg_mgmt_write_data,
|
||||||
|
output wire logic [3:0] cfg_mgmt_byte_enable,
|
||||||
|
output wire logic cfg_mgmt_read,
|
||||||
|
input wire logic [31:0] cfg_mgmt_read_data,
|
||||||
|
input wire logic cfg_mgmt_read_write_done
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam CL_F_COUNT = F_COUNT > 1 ? $clog2(F_COUNT) : 1;
|
||||||
|
|
||||||
|
localparam READ_REV_CTRL = READ_EXT_TAG_ENABLE || READ_MAX_READ_REQ_SIZE || READ_MAX_PAYLOAD_SIZE;
|
||||||
|
|
||||||
|
localparam DEV_CTRL_OFFSET = PCIE_CAP_OFFSET + 12'h008;
|
||||||
|
|
||||||
|
logic [F_COUNT-1:0] ext_tag_en_reg = '0, ext_tag_en_next;
|
||||||
|
logic [F_COUNT*3-1:0] max_read_req_size_reg = '0, max_read_req_size_next;
|
||||||
|
logic [F_COUNT*3-1:0] max_payload_size_reg = '0, max_payload_size_next;
|
||||||
|
|
||||||
|
logic [9:0] cfg_mgmt_addr_reg = '0, cfg_mgmt_addr_next;
|
||||||
|
logic [7:0] cfg_mgmt_function_number_reg = '0, cfg_mgmt_function_number_next;
|
||||||
|
logic cfg_mgmt_write_reg = 1'b0, cfg_mgmt_write_next;
|
||||||
|
logic [31:0] cfg_mgmt_write_data_reg = '0, cfg_mgmt_write_data_next;
|
||||||
|
logic [3:0] cfg_mgmt_byte_enable_reg = '0, cfg_mgmt_byte_enable_next;
|
||||||
|
logic cfg_mgmt_read_reg = 1'b0, cfg_mgmt_read_next;
|
||||||
|
logic [31:0] cfg_mgmt_read_data_reg = '0;
|
||||||
|
logic cfg_mgmt_read_write_done_reg = 1'b0;
|
||||||
|
|
||||||
|
logic [7:0] delay_reg = 8'hff, delay_next;
|
||||||
|
logic [CL_F_COUNT-1:0] func_cnt_reg = '0, func_cnt_next;
|
||||||
|
|
||||||
|
assign ext_tag_en = ext_tag_en_reg;
|
||||||
|
assign max_read_req_size = max_read_req_size_reg;
|
||||||
|
assign max_payload_size = max_payload_size_reg;
|
||||||
|
|
||||||
|
assign cfg_mgmt_addr = cfg_mgmt_addr_reg;
|
||||||
|
assign cfg_mgmt_function_number = cfg_mgmt_function_number_reg;
|
||||||
|
assign cfg_mgmt_write = cfg_mgmt_write_reg;
|
||||||
|
assign cfg_mgmt_write_data = cfg_mgmt_write_data_reg;
|
||||||
|
assign cfg_mgmt_byte_enable = cfg_mgmt_byte_enable_reg;
|
||||||
|
assign cfg_mgmt_read = cfg_mgmt_read_reg;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
ext_tag_en_next = ext_tag_en_reg;
|
||||||
|
max_read_req_size_next = max_read_req_size_reg;
|
||||||
|
max_payload_size_next = max_payload_size_reg;
|
||||||
|
|
||||||
|
cfg_mgmt_addr_next = cfg_mgmt_addr_reg;
|
||||||
|
cfg_mgmt_function_number_next = cfg_mgmt_function_number_reg;
|
||||||
|
cfg_mgmt_write_next = cfg_mgmt_write_reg && !cfg_mgmt_read_write_done;
|
||||||
|
cfg_mgmt_write_data_next = cfg_mgmt_write_data_reg;
|
||||||
|
cfg_mgmt_byte_enable_next = cfg_mgmt_byte_enable_reg;
|
||||||
|
cfg_mgmt_read_next = cfg_mgmt_read_reg && !cfg_mgmt_read_write_done;
|
||||||
|
|
||||||
|
delay_next = delay_reg;
|
||||||
|
func_cnt_next = func_cnt_reg;
|
||||||
|
|
||||||
|
if (delay_reg > 0) begin
|
||||||
|
delay_next = delay_reg - 1;
|
||||||
|
end else begin
|
||||||
|
cfg_mgmt_addr_next = 10'(DEV_CTRL_OFFSET >> 2);
|
||||||
|
cfg_mgmt_read_next = 1'b1;
|
||||||
|
if (cfg_mgmt_read_write_done_reg) begin
|
||||||
|
cfg_mgmt_read_next = 1'b0;
|
||||||
|
|
||||||
|
ext_tag_en_next[func_cnt_reg] = cfg_mgmt_read_data_reg[8];
|
||||||
|
max_read_req_size_next[func_cnt_reg*3 +: 3] = cfg_mgmt_read_data_reg[14:12];
|
||||||
|
max_payload_size_next[func_cnt_reg*3 +: 3] = cfg_mgmt_read_data_reg[7:5];
|
||||||
|
|
||||||
|
if (func_cnt_reg == F_COUNT-1) begin
|
||||||
|
func_cnt_next = 0;
|
||||||
|
cfg_mgmt_function_number_next = 0;
|
||||||
|
end else if (func_cnt_reg == PF_COUNT-1) begin
|
||||||
|
func_cnt_next = func_cnt_reg + 1;
|
||||||
|
cfg_mgmt_function_number_next = VF_OFFSET;
|
||||||
|
end else begin
|
||||||
|
func_cnt_next = func_cnt_reg + 1;
|
||||||
|
cfg_mgmt_function_number_next = cfg_mgmt_function_number_reg + 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
delay_next = 8'hff;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge clk) begin
|
||||||
|
ext_tag_en_reg <= ext_tag_en_next;
|
||||||
|
max_read_req_size_reg <= max_read_req_size_next;
|
||||||
|
max_payload_size_reg <= max_payload_size_next;
|
||||||
|
|
||||||
|
cfg_mgmt_addr_reg <= cfg_mgmt_addr_next;
|
||||||
|
cfg_mgmt_function_number_reg <= cfg_mgmt_function_number_next;
|
||||||
|
cfg_mgmt_write_reg <= cfg_mgmt_write_next;
|
||||||
|
cfg_mgmt_write_data_reg <= cfg_mgmt_write_data_next;
|
||||||
|
cfg_mgmt_byte_enable_reg <= cfg_mgmt_byte_enable_next;
|
||||||
|
cfg_mgmt_read_reg <= cfg_mgmt_read_next;
|
||||||
|
cfg_mgmt_read_data_reg <= cfg_mgmt_read_data;
|
||||||
|
cfg_mgmt_read_write_done_reg <= cfg_mgmt_read_write_done;
|
||||||
|
|
||||||
|
delay_reg <= delay_next;
|
||||||
|
func_cnt_reg <= func_cnt_next;
|
||||||
|
|
||||||
|
if (rst) begin
|
||||||
|
ext_tag_en_reg <= '0;
|
||||||
|
max_read_req_size_reg <= '0;
|
||||||
|
max_payload_size_reg <= '0;
|
||||||
|
|
||||||
|
cfg_mgmt_addr_reg <= '0;
|
||||||
|
cfg_mgmt_function_number_reg <= '0;
|
||||||
|
cfg_mgmt_write_reg <= 1'b0;
|
||||||
|
cfg_mgmt_read_reg <= 1'b0;
|
||||||
|
cfg_mgmt_read_write_done_reg <= 1'b0;
|
||||||
|
|
||||||
|
delay_reg <= 8'hff;
|
||||||
|
func_cnt_reg <= '0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`resetall
|
||||||
@@ -420,9 +420,9 @@ always_comb begin
|
|||||||
endcase
|
endcase
|
||||||
|
|
||||||
// time integral of error
|
// time integral of error
|
||||||
case (dst_gain_sel_reg)
|
case (dst_gain_sel_reg && !dst_sync_locked_reg)
|
||||||
1'd0: {dst_ovf, dst_err_int_next} = $signed({1'b0, dst_err_int_reg}) + (PHASE_ACC_W+2)'($signed(sample_acc_sync_reg));
|
1'd0: {dst_ovf, dst_err_int_next} = $signed({1'b0, dst_err_int_reg}) + (PHASE_ACC_W+2)'($signed(sample_acc_sync_reg));
|
||||||
1'd1: {dst_ovf, dst_err_int_next} = $signed({1'b0, dst_err_int_reg}) + (PHASE_ACC_W+2)'($signed(sample_acc_sync_reg) * 2**7);
|
1'd1: {dst_ovf, dst_err_int_next} = $signed({1'b0, dst_err_int_reg}) + (PHASE_ACC_W+2)'($signed(sample_acc_sync_reg) * 2**5);
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
// saturate
|
// saturate
|
||||||
@@ -435,9 +435,9 @@ always_comb begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
// compute output
|
// compute output
|
||||||
case (dst_gain_sel_reg)
|
case (dst_gain_sel_reg && !dst_sync_locked_reg)
|
||||||
1'd0: {dst_ovf, dst_phase_inc_next} = $signed({1'b0, dst_err_int_reg}) + ($signed(sample_acc_sync_reg) * 2**4);
|
1'd0: {dst_ovf, dst_phase_inc_next} = $signed({1'b0, dst_err_int_reg}) + ($signed(sample_acc_sync_reg) * 2**5);
|
||||||
1'd1: {dst_ovf, dst_phase_inc_next} = $signed({1'b0, dst_err_int_reg}) + ($signed(sample_acc_sync_reg) * 2**11);
|
1'd1: {dst_ovf, dst_phase_inc_next} = $signed({1'b0, dst_err_int_reg}) + ($signed(sample_acc_sync_reg) * 2**9);
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
// saturate
|
// saturate
|
||||||
@@ -741,7 +741,7 @@ always_comb begin
|
|||||||
ts_rel_ns_next[TS_REL_NS_W-1:9] = ts_rel_ns_reg[TS_REL_NS_W-1:9] + 1;
|
ts_rel_ns_next[TS_REL_NS_W-1:9] = ts_rel_ns_reg[TS_REL_NS_W-1:9] + 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (dst_update_reg && !dst_sync_reg && dst_rel_shadow_valid_reg && (dst_load_cnt_reg == 0)) begin
|
if (dst_rel_shadow_valid_reg && dst_rel_ns_shadow_reg[8] == ts_rel_ns_reg[8] && (dst_load_cnt_reg == 0)) begin
|
||||||
// check timestamp MSBs
|
// check timestamp MSBs
|
||||||
if (dst_rel_step_shadow_reg || ts_rel_load_ts_reg) begin
|
if (dst_rel_step_shadow_reg || ts_rel_load_ts_reg) begin
|
||||||
// input stepped
|
// input stepped
|
||||||
@@ -789,7 +789,7 @@ always_comb begin
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if (dst_update_reg && !dst_sync_reg && dst_tod_shadow_valid_reg && (dst_load_cnt_reg == 0)) begin
|
if (dst_tod_shadow_valid_reg && dst_tod_ns_shadow_reg[8] == ts_tod_ns_reg[8] && (dst_load_cnt_reg == 0)) begin
|
||||||
// check timestamp MSBs
|
// check timestamp MSBs
|
||||||
if (dst_tod_step_shadow_reg || ts_tod_load_ts_reg) begin
|
if (dst_tod_step_shadow_reg || ts_tod_load_ts_reg) begin
|
||||||
// input stepped
|
// input stepped
|
||||||
|
|||||||
4
src/ptp/rtl/taxi_ptp_td_phc_apb.f
Normal file
4
src/ptp/rtl/taxi_ptp_td_phc_apb.f
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
taxi_ptp_td_phc_apb.sv
|
||||||
|
taxi_ptp_td_phc.sv
|
||||||
|
taxi_ptp_td_leaf.sv
|
||||||
|
../lib/taxi/src/apb/rtl/taxi_apb_if.sv
|
||||||
533
src/ptp/rtl/taxi_ptp_td_phc_apb.sv
Normal file
533
src/ptp/rtl/taxi_ptp_td_phc_apb.sv
Normal file
@@ -0,0 +1,533 @@
|
|||||||
|
// SPDX-License-Identifier: CERN-OHL-S-2.0
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2026 FPGA Ninja, LLC
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
- Alex Forencich
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
`resetall
|
||||||
|
`timescale 1ns / 1ps
|
||||||
|
`default_nettype none
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP time distribution PHC with APB register interface
|
||||||
|
*/
|
||||||
|
module taxi_ptp_td_phc_apb #
|
||||||
|
(
|
||||||
|
parameter PTP_CLK_PER_NS_NUM = 512,
|
||||||
|
parameter PTP_CLK_PER_NS_DENOM = 165,
|
||||||
|
parameter PTP_CLOCK_CDC_PIPELINE = 0
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input wire logic clk,
|
||||||
|
input wire logic rst,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Control register interface
|
||||||
|
*/
|
||||||
|
taxi_apb_if.slv s_apb,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP clock
|
||||||
|
*/
|
||||||
|
input wire logic ptp_clk,
|
||||||
|
input wire logic ptp_rst,
|
||||||
|
input wire logic ptp_sample_clk,
|
||||||
|
output wire logic ptp_td_sdo,
|
||||||
|
output wire logic ptp_pps,
|
||||||
|
output wire logic ptp_pps_str,
|
||||||
|
output wire logic ptp_sync_locked,
|
||||||
|
output wire logic [63:0] ptp_sync_ts_rel,
|
||||||
|
output wire logic ptp_sync_ts_rel_step,
|
||||||
|
output wire logic [95:0] ptp_sync_ts_tod,
|
||||||
|
output wire logic ptp_sync_ts_tod_step,
|
||||||
|
output wire logic ptp_sync_pps,
|
||||||
|
output wire logic ptp_sync_pps_str
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam APB_DATA_W = s_apb.DATA_W;
|
||||||
|
localparam APB_ADDR_W = s_apb.ADDR_W;
|
||||||
|
localparam APB_STRB_W = s_apb.STRB_W;
|
||||||
|
|
||||||
|
localparam PTP_NS_W = 8;
|
||||||
|
localparam PTP_FNS_W = 32;
|
||||||
|
|
||||||
|
localparam PTP_CLK_PER_NS = PTP_CLK_PER_NS_NUM / PTP_CLK_PER_NS_DENOM;
|
||||||
|
localparam PTP_CLK_PER_NS_REM = PTP_CLK_PER_NS_NUM - PTP_CLK_PER_NS*PTP_CLK_PER_NS_DENOM;
|
||||||
|
localparam PTP_CLK_PER_FNS = (PTP_CLK_PER_NS_REM * {32'd1, {PTP_FNS_W{1'b0}}}) / (32+PTP_FNS_W)'(PTP_CLK_PER_NS_DENOM);
|
||||||
|
localparam PTP_CLK_PER_FNS_REM = (PTP_CLK_PER_NS_REM * {32'd1, {PTP_FNS_W{1'b0}}}) - PTP_CLK_PER_FNS*PTP_CLK_PER_NS_DENOM;
|
||||||
|
|
||||||
|
// check configuration
|
||||||
|
if (APB_DATA_W != 32)
|
||||||
|
$fatal(0, "Error: Register interface width must be 32 (instance %m)");
|
||||||
|
|
||||||
|
if (APB_STRB_W * 8 != APB_DATA_W)
|
||||||
|
$fatal(0, "Error: Register interface requires byte (8-bit) granularity (instance %m)");
|
||||||
|
|
||||||
|
if (APB_ADDR_W < 7)
|
||||||
|
$fatal(0, "Error: Register address width too narrow (instance %m)");
|
||||||
|
|
||||||
|
logic [95:0] get_ptp_ts_tod_reg = '0;
|
||||||
|
logic [29:0] set_ptp_ts_tod_ns_reg = '0;
|
||||||
|
logic [47:0] set_ptp_ts_tod_s_reg = '0;
|
||||||
|
|
||||||
|
logic set_ptp_ts_tod_req_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic set_ptp_ts_tod_req_sync1_reg = 1'b0, set_ptp_ts_tod_req_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic set_ptp_ts_tod_ack_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic set_ptp_ts_tod_ack_sync1_reg = 1'b0, set_ptp_ts_tod_ack_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic set_ptp_ts_tod_valid_reg = 1'b0;
|
||||||
|
wire set_ptp_ts_tod_ready;
|
||||||
|
|
||||||
|
logic [29:0] offset_ptp_ts_tod_ns_reg = '0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_tod_req_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic offset_ptp_ts_tod_req_sync1_reg = 1'b0, offset_ptp_ts_tod_req_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_tod_ack_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic offset_ptp_ts_tod_ack_sync1_reg = 1'b0, offset_ptp_ts_tod_ack_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_tod_valid_reg = 1'b0;
|
||||||
|
wire offset_ptp_ts_tod_ready;
|
||||||
|
|
||||||
|
logic [63:0] get_ptp_ts_rel_reg = '0;
|
||||||
|
logic [47:0] set_ptp_ts_rel_ns_reg = '0;
|
||||||
|
|
||||||
|
logic set_ptp_ts_rel_req_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic set_ptp_ts_rel_req_sync1_reg = 1'b0, set_ptp_ts_rel_req_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic set_ptp_ts_rel_ack_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic set_ptp_ts_rel_ack_sync1_reg = 1'b0, set_ptp_ts_rel_ack_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic set_ptp_ts_rel_valid_reg = 1'b0;
|
||||||
|
wire set_ptp_ts_rel_ready;
|
||||||
|
|
||||||
|
logic [31:0] offset_ptp_ts_rel_ns_reg = '0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_rel_req_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic offset_ptp_ts_rel_req_sync1_reg = 1'b0, offset_ptp_ts_rel_req_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_rel_ack_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic offset_ptp_ts_rel_ack_sync1_reg = 1'b0, offset_ptp_ts_rel_ack_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_rel_valid_reg = 1'b0;
|
||||||
|
wire offset_ptp_ts_rel_ready;
|
||||||
|
|
||||||
|
logic [PTP_NS_W-1:0] set_ptp_period_ns_reg = PTP_NS_W'(PTP_CLK_PER_NS);
|
||||||
|
logic [PTP_FNS_W-1:0] set_ptp_period_fns_reg = PTP_FNS_W'(PTP_CLK_PER_FNS);
|
||||||
|
|
||||||
|
logic set_ptp_period_req_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic set_ptp_period_req_sync1_reg = 1'b0, set_ptp_period_req_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic set_ptp_period_ack_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic set_ptp_period_ack_sync1_reg = 1'b0, set_ptp_period_ack_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic set_ptp_period_valid_reg = 1'b0;
|
||||||
|
wire set_ptp_period_ready;
|
||||||
|
|
||||||
|
logic [31:0] offset_ptp_ts_fns_reg = '0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_req_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic offset_ptp_ts_req_sync1_reg = 1'b0, offset_ptp_ts_req_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_ack_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic offset_ptp_ts_ack_sync1_reg = 1'b0, offset_ptp_ts_ack_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_valid_reg = 1'b0;
|
||||||
|
wire offset_ptp_ts_ready;
|
||||||
|
|
||||||
|
always_ff @(posedge ptp_clk) begin
|
||||||
|
set_ptp_ts_tod_req_sync1_reg <= set_ptp_ts_tod_req_reg;
|
||||||
|
set_ptp_ts_tod_req_sync2_reg <= set_ptp_ts_tod_req_sync1_reg;
|
||||||
|
offset_ptp_ts_tod_req_sync1_reg <= offset_ptp_ts_tod_req_reg;
|
||||||
|
offset_ptp_ts_tod_req_sync2_reg <= offset_ptp_ts_tod_req_sync1_reg;
|
||||||
|
set_ptp_ts_rel_req_sync1_reg <= set_ptp_ts_rel_req_reg;
|
||||||
|
set_ptp_ts_rel_req_sync2_reg <= set_ptp_ts_rel_req_sync1_reg;
|
||||||
|
offset_ptp_ts_rel_req_sync1_reg <= offset_ptp_ts_rel_req_reg;
|
||||||
|
offset_ptp_ts_rel_req_sync2_reg <= offset_ptp_ts_rel_req_sync1_reg;
|
||||||
|
set_ptp_period_req_sync1_reg <= set_ptp_period_req_reg;
|
||||||
|
set_ptp_period_req_sync2_reg <= set_ptp_period_req_sync1_reg;
|
||||||
|
offset_ptp_ts_req_sync1_reg <= offset_ptp_ts_req_reg;
|
||||||
|
offset_ptp_ts_req_sync2_reg <= offset_ptp_ts_req_sync1_reg;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge clk) begin
|
||||||
|
set_ptp_ts_tod_ack_sync1_reg <= set_ptp_ts_tod_ack_reg;
|
||||||
|
set_ptp_ts_tod_ack_sync2_reg <= set_ptp_ts_tod_ack_sync1_reg;
|
||||||
|
offset_ptp_ts_tod_ack_sync1_reg <= offset_ptp_ts_tod_ack_reg;
|
||||||
|
offset_ptp_ts_tod_ack_sync2_reg <= offset_ptp_ts_tod_ack_sync1_reg;
|
||||||
|
set_ptp_ts_rel_ack_sync1_reg <= set_ptp_ts_rel_ack_reg;
|
||||||
|
set_ptp_ts_rel_ack_sync2_reg <= set_ptp_ts_rel_ack_sync1_reg;
|
||||||
|
offset_ptp_ts_rel_ack_sync1_reg <= offset_ptp_ts_rel_ack_reg;
|
||||||
|
offset_ptp_ts_rel_ack_sync2_reg <= offset_ptp_ts_rel_ack_sync1_reg;
|
||||||
|
set_ptp_period_ack_sync1_reg <= set_ptp_period_ack_reg;
|
||||||
|
set_ptp_period_ack_sync2_reg <= set_ptp_period_ack_sync1_reg;
|
||||||
|
offset_ptp_ts_ack_sync1_reg <= offset_ptp_ts_ack_reg;
|
||||||
|
offset_ptp_ts_ack_sync2_reg <= offset_ptp_ts_ack_sync1_reg;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge ptp_clk) begin
|
||||||
|
if (set_ptp_ts_tod_ack_reg) begin
|
||||||
|
set_ptp_ts_tod_ack_reg <= set_ptp_ts_tod_req_sync2_reg;
|
||||||
|
end else begin
|
||||||
|
if (set_ptp_ts_tod_valid_reg && set_ptp_ts_tod_ready) begin
|
||||||
|
set_ptp_ts_tod_valid_reg <= 1'b0;
|
||||||
|
set_ptp_ts_tod_ack_reg <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
set_ptp_ts_tod_valid_reg <= set_ptp_ts_tod_req_sync2_reg;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (offset_ptp_ts_tod_ack_reg) begin
|
||||||
|
offset_ptp_ts_tod_ack_reg <= offset_ptp_ts_tod_req_sync2_reg;
|
||||||
|
end else begin
|
||||||
|
if (offset_ptp_ts_tod_valid_reg && offset_ptp_ts_tod_ready) begin
|
||||||
|
offset_ptp_ts_tod_valid_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_tod_ack_reg <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
offset_ptp_ts_tod_valid_reg <= offset_ptp_ts_tod_req_sync2_reg;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (set_ptp_ts_rel_ack_reg) begin
|
||||||
|
set_ptp_ts_rel_ack_reg <= set_ptp_ts_rel_req_sync2_reg;
|
||||||
|
end else begin
|
||||||
|
if (set_ptp_ts_rel_valid_reg && set_ptp_ts_rel_ready) begin
|
||||||
|
set_ptp_ts_rel_valid_reg <= 1'b0;
|
||||||
|
set_ptp_ts_rel_ack_reg <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
set_ptp_ts_rel_valid_reg <= set_ptp_ts_rel_req_sync2_reg;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (offset_ptp_ts_rel_ack_reg) begin
|
||||||
|
offset_ptp_ts_rel_ack_reg <= offset_ptp_ts_rel_req_sync2_reg;
|
||||||
|
end else begin
|
||||||
|
if (offset_ptp_ts_rel_valid_reg && offset_ptp_ts_rel_ready) begin
|
||||||
|
offset_ptp_ts_rel_valid_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_rel_ack_reg <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
offset_ptp_ts_rel_valid_reg <= offset_ptp_ts_rel_req_sync2_reg;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (set_ptp_period_ack_reg) begin
|
||||||
|
set_ptp_period_ack_reg <= set_ptp_period_req_sync2_reg;
|
||||||
|
end else begin
|
||||||
|
if (set_ptp_period_valid_reg && set_ptp_period_ready) begin
|
||||||
|
set_ptp_period_valid_reg <= 1'b0;
|
||||||
|
set_ptp_period_ack_reg <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
set_ptp_period_valid_reg <= set_ptp_period_req_sync2_reg;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (offset_ptp_ts_ack_reg) begin
|
||||||
|
offset_ptp_ts_ack_reg <= offset_ptp_ts_req_sync2_reg;
|
||||||
|
end else begin
|
||||||
|
if (offset_ptp_ts_valid_reg && offset_ptp_ts_ready) begin
|
||||||
|
offset_ptp_ts_valid_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_ack_reg <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
offset_ptp_ts_valid_reg <= offset_ptp_ts_req_sync2_reg;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (ptp_rst) begin
|
||||||
|
set_ptp_ts_tod_ack_reg <= 1'b0;
|
||||||
|
set_ptp_ts_tod_valid_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_tod_ack_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_tod_valid_reg <= 1'b0;
|
||||||
|
set_ptp_ts_rel_ack_reg <= 1'b0;
|
||||||
|
set_ptp_ts_rel_valid_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_rel_ack_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_rel_valid_reg <= 1'b0;
|
||||||
|
set_ptp_period_ack_reg <= 1'b0;
|
||||||
|
set_ptp_period_valid_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_ack_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_valid_reg <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
logic s_apb_pready_reg = 1'b0;
|
||||||
|
logic [AXIL_DATA_W-1:0] s_apb_prdata_reg = '0;
|
||||||
|
|
||||||
|
assign s_apb.pready = s_apb_pready_reg;
|
||||||
|
assign s_apb.prdata = s_apb_prdata_reg;
|
||||||
|
assign s_apb.pslverr = 1'b0;
|
||||||
|
assign s_apb.prresp = '0;
|
||||||
|
assign s_apb.pbuser = '0;
|
||||||
|
|
||||||
|
always_ff @(posedge clk) begin
|
||||||
|
s_apb_pready_reg <= 1'b0;
|
||||||
|
|
||||||
|
set_ptp_ts_tod_req_reg <= set_ptp_ts_tod_req_reg && !set_ptp_ts_tod_ack_sync2_reg;
|
||||||
|
offset_ptp_ts_tod_req_reg <= offset_ptp_ts_tod_req_reg && !offset_ptp_ts_tod_ack_sync2_reg;
|
||||||
|
set_ptp_ts_rel_req_reg <= set_ptp_ts_rel_req_reg && !set_ptp_ts_rel_ack_sync2_reg;
|
||||||
|
offset_ptp_ts_rel_req_reg <= offset_ptp_ts_rel_req_reg && !offset_ptp_ts_rel_ack_sync2_reg;
|
||||||
|
offset_ptp_ts_req_reg <= offset_ptp_ts_req_reg && !offset_ptp_ts_ack_sync2_reg;
|
||||||
|
set_ptp_period_req_reg <= set_ptp_period_req_reg && !set_ptp_period_ack_sync2_reg;
|
||||||
|
|
||||||
|
if (s_apb.penable && s_apb.psel && !s_apb_pready_reg) begin
|
||||||
|
s_apb_pready_reg <= 1'b1;
|
||||||
|
|
||||||
|
if (s_apb.pwrite) begin
|
||||||
|
case (7'({s_apb.paddr >> 2, 2'b00}))
|
||||||
|
// PHC
|
||||||
|
7'h50: begin
|
||||||
|
// PTP offset ToD
|
||||||
|
if (!offset_ptp_ts_tod_req_reg || offset_ptp_ts_tod_ack_sync2_reg) begin
|
||||||
|
offset_ptp_ts_tod_ns_reg <= 30'(s_apb.pwdata);
|
||||||
|
offset_ptp_ts_tod_req_reg <= s_apb.pwdata != 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h54: begin
|
||||||
|
// PTP set ToD ns
|
||||||
|
if (!set_ptp_ts_tod_req_reg || set_ptp_ts_tod_ack_sync2_reg) begin
|
||||||
|
set_ptp_ts_tod_ns_reg <= 30'(s_apb.pwdata);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h58: begin
|
||||||
|
// PTP set ToD sec l
|
||||||
|
if (!set_ptp_ts_tod_req_reg || set_ptp_ts_tod_ack_sync2_reg) begin
|
||||||
|
set_ptp_ts_tod_s_reg[31:0] <= s_apb.pwdata;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h5C: begin
|
||||||
|
// PTP set ToD sec h
|
||||||
|
if (!set_ptp_ts_tod_req_reg || set_ptp_ts_tod_ack_sync2_reg) begin
|
||||||
|
set_ptp_ts_tod_s_reg[47:32] <= 16'(s_apb.pwdata);
|
||||||
|
set_ptp_ts_tod_req_reg <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h60: begin
|
||||||
|
// PTP set rel ns l
|
||||||
|
if (!set_ptp_ts_rel_req_reg || set_ptp_ts_rel_ack_sync2_reg) begin
|
||||||
|
set_ptp_ts_rel_ns_reg[31:0] <= s_apb.pwdata;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h64: begin
|
||||||
|
// PTP set rel ns h
|
||||||
|
if (!set_ptp_ts_rel_req_reg || set_ptp_ts_rel_ack_sync2_reg) begin
|
||||||
|
set_ptp_ts_rel_ns_reg[47:32] <= 16'(s_apb.pwdata);
|
||||||
|
set_ptp_ts_rel_req_reg <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h68: begin
|
||||||
|
// PTP offset rel
|
||||||
|
if (!offset_ptp_ts_rel_req_reg || offset_ptp_ts_rel_ack_sync2_reg) begin
|
||||||
|
offset_ptp_ts_rel_ns_reg <= s_apb.pwdata;
|
||||||
|
offset_ptp_ts_rel_req_reg <= s_apb.pwdata != 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h6C: begin
|
||||||
|
// PTP offset FNS
|
||||||
|
if (!offset_ptp_ts_req_reg || offset_ptp_ts_ack_sync2_reg) begin
|
||||||
|
offset_ptp_ts_fns_reg <= s_apb.pwdata;
|
||||||
|
offset_ptp_ts_req_reg <= s_apb.pwdata != 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h78: begin
|
||||||
|
// PTP period fns
|
||||||
|
if (!set_ptp_period_req_reg || set_ptp_period_ack_sync2_reg) begin
|
||||||
|
set_ptp_period_fns_reg <= PTP_FNS_W'(s_apb.pwdata);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h7C: begin
|
||||||
|
// PTP period ns
|
||||||
|
if (!set_ptp_period_req_reg || set_ptp_period_ack_sync2_reg) begin
|
||||||
|
set_ptp_period_ns_reg <= PTP_NS_W'(s_apb.pwdata);
|
||||||
|
set_ptp_period_req_reg <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
default: begin end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
case (7'({s_apb.paddr >> 2, 2'b00}))
|
||||||
|
7'h0C: begin
|
||||||
|
// PHC control
|
||||||
|
s_apb_prdata_reg[8] <= ptp_sync_pps_str; // PPS
|
||||||
|
s_apb_prdata_reg[16] <= ptp_sync_locked; // Locked
|
||||||
|
s_apb_prdata_reg[24] <= set_ptp_ts_tod_req_reg || set_ptp_ts_tod_ack_sync2_reg; // ToD set pending
|
||||||
|
s_apb_prdata_reg[25] <= offset_ptp_ts_tod_req_reg || offset_ptp_ts_tod_ack_sync2_reg; // ToD offset pending
|
||||||
|
s_apb_prdata_reg[26] <= set_ptp_ts_rel_req_reg || set_ptp_ts_rel_ack_sync2_reg; // Relative set pending
|
||||||
|
s_apb_prdata_reg[27] <= offset_ptp_ts_rel_req_reg || offset_ptp_ts_rel_ack_sync2_reg; // Relative offset pending
|
||||||
|
s_apb_prdata_reg[28] <= set_ptp_period_req_reg || set_ptp_period_ack_sync2_reg; // Period set pending
|
||||||
|
s_apb_prdata_reg[29] <= offset_ptp_ts_req_reg || offset_ptp_ts_ack_sync2_reg; // FNS offset pending
|
||||||
|
end
|
||||||
|
7'h10: s_apb_prdata_reg <= {ptp_sync_ts_tod[15:0], 16'd0}; // PTP cur fns
|
||||||
|
7'h14: s_apb_prdata_reg <= ptp_sync_ts_tod[47:16]; // PTP cur ToD ns
|
||||||
|
7'h18: s_apb_prdata_reg <= ptp_sync_ts_tod[79:48]; // PTP cur ToD sec l
|
||||||
|
7'h1C: s_apb_prdata_reg <= 32'(ptp_sync_ts_tod[95:80]); // PTP cur ToD sec h
|
||||||
|
7'h20: s_apb_prdata_reg <= ptp_sync_ts_rel[47:16]; // PTP cur rel ns l
|
||||||
|
7'h24: s_apb_prdata_reg <= 32'(ptp_sync_ts_rel[63:48]); // PTP cur rel ns h
|
||||||
|
7'h28: s_apb_prdata_reg <= '0; // PTP cur PTM l
|
||||||
|
7'h2C: s_apb_prdata_reg <= '0; // PTP cur PTM h
|
||||||
|
7'h30: begin
|
||||||
|
// PTP snapshot fns
|
||||||
|
get_ptp_ts_tod_reg <= ptp_sync_ts_tod;
|
||||||
|
get_ptp_ts_rel_reg <= ptp_sync_ts_rel;
|
||||||
|
s_apb_prdata_reg <= {ptp_sync_ts_tod[15:0], 16'd0};
|
||||||
|
end
|
||||||
|
7'h34: s_apb_prdata_reg <= 32'(get_ptp_ts_tod_reg[45:16]); // PTP snapshot ToD ns
|
||||||
|
7'h38: s_apb_prdata_reg <= get_ptp_ts_tod_reg[79:48]; // PTP snapshot ToD sec l
|
||||||
|
7'h3C: s_apb_prdata_reg <= 32'(get_ptp_ts_tod_reg[95:80]); // PTP snapshot ToD sec h
|
||||||
|
7'h40: s_apb_prdata_reg <= get_ptp_ts_rel_reg[47:16]; // PTP snapshot rel ns l
|
||||||
|
7'h44: s_apb_prdata_reg <= 32'(get_ptp_ts_rel_reg[63:48]); // PTP snapshot rel ns h
|
||||||
|
7'h48: s_apb_prdata_reg <= '0; // PTP snapshot PTM l
|
||||||
|
7'h4C: s_apb_prdata_reg <= '0; // PTP snapshot PTM h
|
||||||
|
7'h50: s_apb_prdata_reg <= 32'(offset_ptp_ts_tod_ns_reg); // PTP offset ToD
|
||||||
|
7'h54: s_apb_prdata_reg <= 32'(set_ptp_ts_tod_ns_reg); // PTP set ToD ns
|
||||||
|
7'h58: s_apb_prdata_reg <= set_ptp_ts_tod_s_reg[31:0]; // PTP set ToD sec l
|
||||||
|
7'h5C: s_apb_prdata_reg <= set_ptp_ts_tod_s_reg[47:16]; // PTP set ToD sec h
|
||||||
|
7'h60: s_apb_prdata_reg <= set_ptp_ts_rel_ns_reg[31:0]; // PTP set rel ns l
|
||||||
|
7'h64: s_apb_prdata_reg <= set_ptp_ts_rel_ns_reg[47:16]; // PTP set rel ns h
|
||||||
|
7'h68: s_apb_prdata_reg <= offset_ptp_ts_rel_ns_reg; // PTP offset rel
|
||||||
|
7'h6C: s_apb_prdata_reg <= offset_ptp_ts_fns_reg; // PTP offset FNS
|
||||||
|
7'h70: s_apb_prdata_reg <= 32'(PTP_CLK_PER_FNS); // PTP nom period fns
|
||||||
|
7'h74: s_apb_prdata_reg <= 32'(PTP_CLK_PER_NS); // PTP nom period ns
|
||||||
|
7'h78: s_apb_prdata_reg <= set_ptp_period_fns_reg; // PTP period fns
|
||||||
|
7'h7C: s_apb_prdata_reg <= 32'(set_ptp_period_ns_reg); // PTP period ns
|
||||||
|
default: begin end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
if (rst) begin
|
||||||
|
s_apb_pready_reg <= 1'b0;
|
||||||
|
|
||||||
|
set_ptp_period_ns_reg <= PTP_NS_W'(PTP_CLK_PER_NS);
|
||||||
|
set_ptp_period_fns_reg <= PTP_FNS_W'(PTP_CLK_PER_FNS);
|
||||||
|
|
||||||
|
set_ptp_ts_tod_req_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_tod_req_reg <= 1'b0;
|
||||||
|
set_ptp_ts_rel_req_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_rel_req_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_req_reg <= 1'b0;
|
||||||
|
set_ptp_period_req_reg <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// PTP clock
|
||||||
|
taxi_ptp_td_phc #(
|
||||||
|
.PERIOD_NS_NUM(PTP_CLK_PER_NS_NUM),
|
||||||
|
.PERIOD_NS_DENOM(PTP_CLK_PER_NS_DENOM)
|
||||||
|
)
|
||||||
|
ptp_td_phc_inst (
|
||||||
|
.clk(ptp_clk),
|
||||||
|
.rst(ptp_rst),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ToD timestamp control
|
||||||
|
*/
|
||||||
|
.input_ts_tod_s(set_ptp_ts_tod_s_reg),
|
||||||
|
.input_ts_tod_ns(set_ptp_ts_tod_ns_reg),
|
||||||
|
.input_ts_tod_valid(set_ptp_ts_tod_valid_reg),
|
||||||
|
.input_ts_tod_ready(set_ptp_ts_tod_ready),
|
||||||
|
.input_ts_tod_offset_ns(offset_ptp_ts_tod_ns_reg),
|
||||||
|
.input_ts_tod_offset_valid(offset_ptp_ts_tod_valid_reg),
|
||||||
|
.input_ts_tod_offset_ready(offset_ptp_ts_tod_ready),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Relative timestamp control
|
||||||
|
*/
|
||||||
|
.input_ts_rel_ns(set_ptp_ts_rel_ns_reg),
|
||||||
|
.input_ts_rel_valid(set_ptp_ts_rel_valid_reg),
|
||||||
|
.input_ts_rel_ready(set_ptp_ts_rel_ready),
|
||||||
|
.input_ts_rel_offset_ns(offset_ptp_ts_rel_ns_reg),
|
||||||
|
.input_ts_rel_offset_valid(offset_ptp_ts_rel_valid_reg),
|
||||||
|
.input_ts_rel_offset_ready(offset_ptp_ts_rel_ready),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fractional ns control
|
||||||
|
*/
|
||||||
|
.input_ts_offset_fns(offset_ptp_ts_fns_reg),
|
||||||
|
.input_ts_offset_valid(offset_ptp_ts_valid_reg),
|
||||||
|
.input_ts_offset_ready(offset_ptp_ts_ready),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Period control
|
||||||
|
*/
|
||||||
|
.input_period_ns(set_ptp_period_ns_reg),
|
||||||
|
.input_period_fns(set_ptp_period_fns_reg),
|
||||||
|
.input_period_valid(set_ptp_period_valid_reg),
|
||||||
|
.input_period_ready(set_ptp_period_ready),
|
||||||
|
.input_drift_num('0),
|
||||||
|
.input_drift_denom('0),
|
||||||
|
.input_drift_valid(1'b0),
|
||||||
|
.input_drift_ready(),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Time distribution serial data output
|
||||||
|
*/
|
||||||
|
.ptp_td_sdo(ptp_td_sdo),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PPS output
|
||||||
|
*/
|
||||||
|
.output_pps(ptp_pps),
|
||||||
|
.output_pps_str(ptp_pps_str)
|
||||||
|
);
|
||||||
|
|
||||||
|
// sync to core clock domain
|
||||||
|
taxi_ptp_td_leaf #(
|
||||||
|
.TS_REL_EN(1),
|
||||||
|
.TS_TOD_EN(1),
|
||||||
|
.TS_FNS_W(16),
|
||||||
|
.TS_REL_NS_W(48),
|
||||||
|
.TS_TOD_S_W(48),
|
||||||
|
.TS_REL_W(64),
|
||||||
|
.TS_TOD_W(96),
|
||||||
|
.TD_SDI_PIPELINE(PTP_CLOCK_CDC_PIPELINE)
|
||||||
|
)
|
||||||
|
ptp_td_leaf_inst (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
.sample_clk(ptp_sample_clk),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP clock interface
|
||||||
|
*/
|
||||||
|
.ptp_clk(ptp_clk),
|
||||||
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_td_sdi(ptp_td_sdo),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timestamp output
|
||||||
|
*/
|
||||||
|
.output_ts_rel(ptp_sync_ts_rel),
|
||||||
|
.output_ts_rel_step(ptp_sync_ts_rel_step),
|
||||||
|
.output_ts_tod(ptp_sync_ts_tod),
|
||||||
|
.output_ts_tod_step(ptp_sync_ts_tod_step),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PPS output (ToD format only)
|
||||||
|
*/
|
||||||
|
.output_pps(ptp_sync_pps),
|
||||||
|
.output_pps_str(ptp_sync_pps_str),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Status
|
||||||
|
*/
|
||||||
|
.locked(ptp_sync_locked)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`resetall
|
||||||
4
src/ptp/rtl/taxi_ptp_td_phc_axil.f
Normal file
4
src/ptp/rtl/taxi_ptp_td_phc_axil.f
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
taxi_ptp_td_phc_axil.sv
|
||||||
|
taxi_ptp_td_phc.sv
|
||||||
|
taxi_ptp_td_leaf.sv
|
||||||
|
../lib/taxi/src/axi/rtl/taxi_axil_if.sv
|
||||||
562
src/ptp/rtl/taxi_ptp_td_phc_axil.sv
Normal file
562
src/ptp/rtl/taxi_ptp_td_phc_axil.sv
Normal file
@@ -0,0 +1,562 @@
|
|||||||
|
// SPDX-License-Identifier: CERN-OHL-S-2.0
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2026 FPGA Ninja, LLC
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
- Alex Forencich
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
`resetall
|
||||||
|
`timescale 1ns / 1ps
|
||||||
|
`default_nettype none
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP time distribution PHC with AXI-lite register interface
|
||||||
|
*/
|
||||||
|
module taxi_ptp_td_phc_axil #
|
||||||
|
(
|
||||||
|
parameter PTP_CLK_PER_NS_NUM = 512,
|
||||||
|
parameter PTP_CLK_PER_NS_DENOM = 165,
|
||||||
|
parameter PTP_CLOCK_CDC_PIPELINE = 0
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input wire logic clk,
|
||||||
|
input wire logic rst,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Control register interface
|
||||||
|
*/
|
||||||
|
taxi_axil_if.wr_slv s_axil_wr,
|
||||||
|
taxi_axil_if.rd_slv s_axil_rd,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP clock
|
||||||
|
*/
|
||||||
|
input wire logic ptp_clk,
|
||||||
|
input wire logic ptp_rst,
|
||||||
|
input wire logic ptp_sample_clk,
|
||||||
|
output wire logic ptp_td_sdo,
|
||||||
|
output wire logic ptp_pps,
|
||||||
|
output wire logic ptp_pps_str,
|
||||||
|
output wire logic ptp_sync_locked,
|
||||||
|
output wire logic [63:0] ptp_sync_ts_rel,
|
||||||
|
output wire logic ptp_sync_ts_rel_step,
|
||||||
|
output wire logic [95:0] ptp_sync_ts_tod,
|
||||||
|
output wire logic ptp_sync_ts_tod_step,
|
||||||
|
output wire logic ptp_sync_pps,
|
||||||
|
output wire logic ptp_sync_pps_str
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam AXIL_DATA_W = s_axil_wr.DATA_W;
|
||||||
|
localparam AXIL_ADDR_W = s_axil_wr.ADDR_W;
|
||||||
|
localparam AXIL_STRB_W = s_axil_wr.STRB_W;
|
||||||
|
|
||||||
|
localparam PTP_NS_W = 8;
|
||||||
|
localparam PTP_FNS_W = 32;
|
||||||
|
|
||||||
|
localparam PTP_CLK_PER_NS = PTP_CLK_PER_NS_NUM / PTP_CLK_PER_NS_DENOM;
|
||||||
|
localparam PTP_CLK_PER_NS_REM = PTP_CLK_PER_NS_NUM - PTP_CLK_PER_NS*PTP_CLK_PER_NS_DENOM;
|
||||||
|
localparam PTP_CLK_PER_FNS = (PTP_CLK_PER_NS_REM * {32'd1, {PTP_FNS_W{1'b0}}}) / (32+PTP_FNS_W)'(PTP_CLK_PER_NS_DENOM);
|
||||||
|
localparam PTP_CLK_PER_FNS_REM = (PTP_CLK_PER_NS_REM * {32'd1, {PTP_FNS_W{1'b0}}}) - PTP_CLK_PER_FNS*PTP_CLK_PER_NS_DENOM;
|
||||||
|
|
||||||
|
// check configuration
|
||||||
|
if (AXIL_DATA_W != 32)
|
||||||
|
$fatal(0, "Error: Register interface width must be 32 (instance %m)");
|
||||||
|
|
||||||
|
if (AXIL_STRB_W * 8 != AXIL_DATA_W)
|
||||||
|
$fatal(0, "Error: Register interface requires byte (8-bit) granularity (instance %m)");
|
||||||
|
|
||||||
|
if (AXIL_ADDR_W < 7)
|
||||||
|
$fatal(0, "Error: Register address width too narrow (instance %m)");
|
||||||
|
|
||||||
|
logic [95:0] get_ptp_ts_tod_reg = '0;
|
||||||
|
logic [29:0] set_ptp_ts_tod_ns_reg = '0;
|
||||||
|
logic [47:0] set_ptp_ts_tod_s_reg = '0;
|
||||||
|
|
||||||
|
logic set_ptp_ts_tod_req_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic set_ptp_ts_tod_req_sync1_reg = 1'b0, set_ptp_ts_tod_req_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic set_ptp_ts_tod_ack_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic set_ptp_ts_tod_ack_sync1_reg = 1'b0, set_ptp_ts_tod_ack_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic set_ptp_ts_tod_valid_reg = 1'b0;
|
||||||
|
wire set_ptp_ts_tod_ready;
|
||||||
|
|
||||||
|
logic [29:0] offset_ptp_ts_tod_ns_reg = '0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_tod_req_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic offset_ptp_ts_tod_req_sync1_reg = 1'b0, offset_ptp_ts_tod_req_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_tod_ack_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic offset_ptp_ts_tod_ack_sync1_reg = 1'b0, offset_ptp_ts_tod_ack_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_tod_valid_reg = 1'b0;
|
||||||
|
wire offset_ptp_ts_tod_ready;
|
||||||
|
|
||||||
|
logic [63:0] get_ptp_ts_rel_reg = '0;
|
||||||
|
logic [47:0] set_ptp_ts_rel_ns_reg = '0;
|
||||||
|
|
||||||
|
logic set_ptp_ts_rel_req_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic set_ptp_ts_rel_req_sync1_reg = 1'b0, set_ptp_ts_rel_req_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic set_ptp_ts_rel_ack_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic set_ptp_ts_rel_ack_sync1_reg = 1'b0, set_ptp_ts_rel_ack_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic set_ptp_ts_rel_valid_reg = 1'b0;
|
||||||
|
wire set_ptp_ts_rel_ready;
|
||||||
|
|
||||||
|
logic [31:0] offset_ptp_ts_rel_ns_reg = '0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_rel_req_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic offset_ptp_ts_rel_req_sync1_reg = 1'b0, offset_ptp_ts_rel_req_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_rel_ack_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic offset_ptp_ts_rel_ack_sync1_reg = 1'b0, offset_ptp_ts_rel_ack_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_rel_valid_reg = 1'b0;
|
||||||
|
wire offset_ptp_ts_rel_ready;
|
||||||
|
|
||||||
|
logic [PTP_NS_W-1:0] set_ptp_period_ns_reg = PTP_NS_W'(PTP_CLK_PER_NS);
|
||||||
|
logic [PTP_FNS_W-1:0] set_ptp_period_fns_reg = PTP_FNS_W'(PTP_CLK_PER_FNS);
|
||||||
|
|
||||||
|
logic set_ptp_period_req_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic set_ptp_period_req_sync1_reg = 1'b0, set_ptp_period_req_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic set_ptp_period_ack_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic set_ptp_period_ack_sync1_reg = 1'b0, set_ptp_period_ack_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic set_ptp_period_valid_reg = 1'b0;
|
||||||
|
wire set_ptp_period_ready;
|
||||||
|
|
||||||
|
logic [31:0] offset_ptp_ts_fns_reg = '0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_req_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic offset_ptp_ts_req_sync1_reg = 1'b0, offset_ptp_ts_req_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_ack_reg = 1'b0;
|
||||||
|
(* async_reg = "true", shreg_extract = "no" *)
|
||||||
|
logic offset_ptp_ts_ack_sync1_reg = 1'b0, offset_ptp_ts_ack_sync2_reg = 1'b0;
|
||||||
|
|
||||||
|
logic offset_ptp_ts_valid_reg = 1'b0;
|
||||||
|
wire offset_ptp_ts_ready;
|
||||||
|
|
||||||
|
always_ff @(posedge ptp_clk) begin
|
||||||
|
set_ptp_ts_tod_req_sync1_reg <= set_ptp_ts_tod_req_reg;
|
||||||
|
set_ptp_ts_tod_req_sync2_reg <= set_ptp_ts_tod_req_sync1_reg;
|
||||||
|
offset_ptp_ts_tod_req_sync1_reg <= offset_ptp_ts_tod_req_reg;
|
||||||
|
offset_ptp_ts_tod_req_sync2_reg <= offset_ptp_ts_tod_req_sync1_reg;
|
||||||
|
set_ptp_ts_rel_req_sync1_reg <= set_ptp_ts_rel_req_reg;
|
||||||
|
set_ptp_ts_rel_req_sync2_reg <= set_ptp_ts_rel_req_sync1_reg;
|
||||||
|
offset_ptp_ts_rel_req_sync1_reg <= offset_ptp_ts_rel_req_reg;
|
||||||
|
offset_ptp_ts_rel_req_sync2_reg <= offset_ptp_ts_rel_req_sync1_reg;
|
||||||
|
set_ptp_period_req_sync1_reg <= set_ptp_period_req_reg;
|
||||||
|
set_ptp_period_req_sync2_reg <= set_ptp_period_req_sync1_reg;
|
||||||
|
offset_ptp_ts_req_sync1_reg <= offset_ptp_ts_req_reg;
|
||||||
|
offset_ptp_ts_req_sync2_reg <= offset_ptp_ts_req_sync1_reg;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge clk) begin
|
||||||
|
set_ptp_ts_tod_ack_sync1_reg <= set_ptp_ts_tod_ack_reg;
|
||||||
|
set_ptp_ts_tod_ack_sync2_reg <= set_ptp_ts_tod_ack_sync1_reg;
|
||||||
|
offset_ptp_ts_tod_ack_sync1_reg <= offset_ptp_ts_tod_ack_reg;
|
||||||
|
offset_ptp_ts_tod_ack_sync2_reg <= offset_ptp_ts_tod_ack_sync1_reg;
|
||||||
|
set_ptp_ts_rel_ack_sync1_reg <= set_ptp_ts_rel_ack_reg;
|
||||||
|
set_ptp_ts_rel_ack_sync2_reg <= set_ptp_ts_rel_ack_sync1_reg;
|
||||||
|
offset_ptp_ts_rel_ack_sync1_reg <= offset_ptp_ts_rel_ack_reg;
|
||||||
|
offset_ptp_ts_rel_ack_sync2_reg <= offset_ptp_ts_rel_ack_sync1_reg;
|
||||||
|
set_ptp_period_ack_sync1_reg <= set_ptp_period_ack_reg;
|
||||||
|
set_ptp_period_ack_sync2_reg <= set_ptp_period_ack_sync1_reg;
|
||||||
|
offset_ptp_ts_ack_sync1_reg <= offset_ptp_ts_ack_reg;
|
||||||
|
offset_ptp_ts_ack_sync2_reg <= offset_ptp_ts_ack_sync1_reg;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge ptp_clk) begin
|
||||||
|
if (set_ptp_ts_tod_ack_reg) begin
|
||||||
|
set_ptp_ts_tod_ack_reg <= set_ptp_ts_tod_req_sync2_reg;
|
||||||
|
end else begin
|
||||||
|
if (set_ptp_ts_tod_valid_reg && set_ptp_ts_tod_ready) begin
|
||||||
|
set_ptp_ts_tod_valid_reg <= 1'b0;
|
||||||
|
set_ptp_ts_tod_ack_reg <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
set_ptp_ts_tod_valid_reg <= set_ptp_ts_tod_req_sync2_reg;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (offset_ptp_ts_tod_ack_reg) begin
|
||||||
|
offset_ptp_ts_tod_ack_reg <= offset_ptp_ts_tod_req_sync2_reg;
|
||||||
|
end else begin
|
||||||
|
if (offset_ptp_ts_tod_valid_reg && offset_ptp_ts_tod_ready) begin
|
||||||
|
offset_ptp_ts_tod_valid_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_tod_ack_reg <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
offset_ptp_ts_tod_valid_reg <= offset_ptp_ts_tod_req_sync2_reg;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (set_ptp_ts_rel_ack_reg) begin
|
||||||
|
set_ptp_ts_rel_ack_reg <= set_ptp_ts_rel_req_sync2_reg;
|
||||||
|
end else begin
|
||||||
|
if (set_ptp_ts_rel_valid_reg && set_ptp_ts_rel_ready) begin
|
||||||
|
set_ptp_ts_rel_valid_reg <= 1'b0;
|
||||||
|
set_ptp_ts_rel_ack_reg <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
set_ptp_ts_rel_valid_reg <= set_ptp_ts_rel_req_sync2_reg;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (offset_ptp_ts_rel_ack_reg) begin
|
||||||
|
offset_ptp_ts_rel_ack_reg <= offset_ptp_ts_rel_req_sync2_reg;
|
||||||
|
end else begin
|
||||||
|
if (offset_ptp_ts_rel_valid_reg && offset_ptp_ts_rel_ready) begin
|
||||||
|
offset_ptp_ts_rel_valid_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_rel_ack_reg <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
offset_ptp_ts_rel_valid_reg <= offset_ptp_ts_rel_req_sync2_reg;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (set_ptp_period_ack_reg) begin
|
||||||
|
set_ptp_period_ack_reg <= set_ptp_period_req_sync2_reg;
|
||||||
|
end else begin
|
||||||
|
if (set_ptp_period_valid_reg && set_ptp_period_ready) begin
|
||||||
|
set_ptp_period_valid_reg <= 1'b0;
|
||||||
|
set_ptp_period_ack_reg <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
set_ptp_period_valid_reg <= set_ptp_period_req_sync2_reg;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (offset_ptp_ts_ack_reg) begin
|
||||||
|
offset_ptp_ts_ack_reg <= offset_ptp_ts_req_sync2_reg;
|
||||||
|
end else begin
|
||||||
|
if (offset_ptp_ts_valid_reg && offset_ptp_ts_ready) begin
|
||||||
|
offset_ptp_ts_valid_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_ack_reg <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
offset_ptp_ts_valid_reg <= offset_ptp_ts_req_sync2_reg;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (ptp_rst) begin
|
||||||
|
set_ptp_ts_tod_ack_reg <= 1'b0;
|
||||||
|
set_ptp_ts_tod_valid_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_tod_ack_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_tod_valid_reg <= 1'b0;
|
||||||
|
set_ptp_ts_rel_ack_reg <= 1'b0;
|
||||||
|
set_ptp_ts_rel_valid_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_rel_ack_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_rel_valid_reg <= 1'b0;
|
||||||
|
set_ptp_period_ack_reg <= 1'b0;
|
||||||
|
set_ptp_period_valid_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_ack_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_valid_reg <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
logic s_axil_awready_reg = 1'b0;
|
||||||
|
logic s_axil_wready_reg = 1'b0;
|
||||||
|
logic s_axil_bvalid_reg = 1'b0;
|
||||||
|
|
||||||
|
logic s_axil_arready_reg = 1'b0;
|
||||||
|
logic [AXIL_DATA_W-1:0] s_axil_rdata_reg = '0;
|
||||||
|
logic s_axil_rvalid_reg = 1'b0;
|
||||||
|
|
||||||
|
assign s_axil_wr.awready = s_axil_awready_reg;
|
||||||
|
assign s_axil_wr.wready = s_axil_wready_reg;
|
||||||
|
assign s_axil_wr.bresp = '0;
|
||||||
|
assign s_axil_wr.buser = '0;
|
||||||
|
assign s_axil_wr.bvalid = s_axil_bvalid_reg;
|
||||||
|
|
||||||
|
assign s_axil_rd.arready = s_axil_arready_reg;
|
||||||
|
assign s_axil_rd.rdata = s_axil_rdata_reg;
|
||||||
|
assign s_axil_rd.rresp = '0;
|
||||||
|
assign s_axil_rd.ruser = '0;
|
||||||
|
assign s_axil_rd.rvalid = s_axil_rvalid_reg;
|
||||||
|
|
||||||
|
always_ff @(posedge clk) begin
|
||||||
|
s_axil_awready_reg <= 1'b0;
|
||||||
|
s_axil_wready_reg <= 1'b0;
|
||||||
|
s_axil_bvalid_reg <= s_axil_bvalid_reg && !s_axil_wr.bready;
|
||||||
|
|
||||||
|
s_axil_arready_reg <= 1'b0;
|
||||||
|
s_axil_rvalid_reg <= s_axil_rvalid_reg && !s_axil_rd.rready;
|
||||||
|
|
||||||
|
set_ptp_ts_tod_req_reg <= set_ptp_ts_tod_req_reg && !set_ptp_ts_tod_ack_sync2_reg;
|
||||||
|
offset_ptp_ts_tod_req_reg <= offset_ptp_ts_tod_req_reg && !offset_ptp_ts_tod_ack_sync2_reg;
|
||||||
|
set_ptp_ts_rel_req_reg <= set_ptp_ts_rel_req_reg && !set_ptp_ts_rel_ack_sync2_reg;
|
||||||
|
offset_ptp_ts_rel_req_reg <= offset_ptp_ts_rel_req_reg && !offset_ptp_ts_rel_ack_sync2_reg;
|
||||||
|
offset_ptp_ts_req_reg <= offset_ptp_ts_req_reg && !offset_ptp_ts_ack_sync2_reg;
|
||||||
|
set_ptp_period_req_reg <= set_ptp_period_req_reg && !set_ptp_period_ack_sync2_reg;
|
||||||
|
|
||||||
|
if (s_axil_wr.awvalid && s_axil_wr.wvalid && !s_axil_bvalid_reg) begin
|
||||||
|
s_axil_awready_reg <= 1'b1;
|
||||||
|
s_axil_wready_reg <= 1'b1;
|
||||||
|
s_axil_bvalid_reg <= 1'b1;
|
||||||
|
|
||||||
|
case (7'({s_axil_wr.awaddr >> 2, 2'b00}))
|
||||||
|
// PHC
|
||||||
|
7'h50: begin
|
||||||
|
// PTP offset ToD
|
||||||
|
if (!offset_ptp_ts_tod_req_reg || offset_ptp_ts_tod_ack_sync2_reg) begin
|
||||||
|
offset_ptp_ts_tod_ns_reg <= 30'(s_axil_wr.wdata);
|
||||||
|
offset_ptp_ts_tod_req_reg <= s_axil_wr.wdata != 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h54: begin
|
||||||
|
// PTP set ToD ns
|
||||||
|
if (!set_ptp_ts_tod_req_reg || set_ptp_ts_tod_ack_sync2_reg) begin
|
||||||
|
set_ptp_ts_tod_ns_reg <= 30'(s_axil_wr.wdata);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h58: begin
|
||||||
|
// PTP set ToD sec l
|
||||||
|
if (!set_ptp_ts_tod_req_reg || set_ptp_ts_tod_ack_sync2_reg) begin
|
||||||
|
set_ptp_ts_tod_s_reg[31:0] <= s_axil_wr.wdata;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h5C: begin
|
||||||
|
// PTP set ToD sec h
|
||||||
|
if (!set_ptp_ts_tod_req_reg || set_ptp_ts_tod_ack_sync2_reg) begin
|
||||||
|
set_ptp_ts_tod_s_reg[47:32] <= 16'(s_axil_wr.wdata);
|
||||||
|
set_ptp_ts_tod_req_reg <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h60: begin
|
||||||
|
// PTP set rel ns l
|
||||||
|
if (!set_ptp_ts_rel_req_reg || set_ptp_ts_rel_ack_sync2_reg) begin
|
||||||
|
set_ptp_ts_rel_ns_reg[31:0] <= s_axil_wr.wdata;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h64: begin
|
||||||
|
// PTP set rel ns h
|
||||||
|
if (!set_ptp_ts_rel_req_reg || set_ptp_ts_rel_ack_sync2_reg) begin
|
||||||
|
set_ptp_ts_rel_ns_reg[47:32] <= 16'(s_axil_wr.wdata);
|
||||||
|
set_ptp_ts_rel_req_reg <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h68: begin
|
||||||
|
// PTP offset rel
|
||||||
|
if (!offset_ptp_ts_rel_req_reg || offset_ptp_ts_rel_ack_sync2_reg) begin
|
||||||
|
offset_ptp_ts_rel_ns_reg <= s_axil_wr.wdata;
|
||||||
|
offset_ptp_ts_rel_req_reg <= s_axil_wr.wdata != 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h6C: begin
|
||||||
|
// PTP offset FNS
|
||||||
|
if (!offset_ptp_ts_req_reg || offset_ptp_ts_ack_sync2_reg) begin
|
||||||
|
offset_ptp_ts_fns_reg <= s_axil_wr.wdata;
|
||||||
|
offset_ptp_ts_req_reg <= s_axil_wr.wdata != 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h78: begin
|
||||||
|
// PTP period fns
|
||||||
|
if (!set_ptp_period_req_reg || set_ptp_period_ack_sync2_reg) begin
|
||||||
|
set_ptp_period_fns_reg <= PTP_FNS_W'(s_axil_wr.wdata);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'h7C: begin
|
||||||
|
// PTP period ns
|
||||||
|
if (!set_ptp_period_req_reg || set_ptp_period_ack_sync2_reg) begin
|
||||||
|
set_ptp_period_ns_reg <= PTP_NS_W'(s_axil_wr.wdata);
|
||||||
|
set_ptp_period_req_reg <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
default: begin end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
if (s_axil_rd.arvalid && !s_axil_rvalid_reg) begin
|
||||||
|
s_axil_rdata_reg <= '0;
|
||||||
|
|
||||||
|
s_axil_arready_reg <= 1'b1;
|
||||||
|
s_axil_rvalid_reg <= 1'b1;
|
||||||
|
|
||||||
|
case (7'({s_axil_rd.araddr >> 2, 2'b00}))
|
||||||
|
7'h0C: begin
|
||||||
|
// PHC control
|
||||||
|
s_axil_rdata_reg[8] <= ptp_sync_pps_str; // PPS
|
||||||
|
s_axil_rdata_reg[16] <= ptp_sync_locked; // Locked
|
||||||
|
s_axil_rdata_reg[24] <= set_ptp_ts_tod_req_reg || set_ptp_ts_tod_ack_sync2_reg; // ToD set pending
|
||||||
|
s_axil_rdata_reg[25] <= offset_ptp_ts_tod_req_reg || offset_ptp_ts_tod_ack_sync2_reg; // ToD offset pending
|
||||||
|
s_axil_rdata_reg[26] <= set_ptp_ts_rel_req_reg || set_ptp_ts_rel_ack_sync2_reg; // Relative set pending
|
||||||
|
s_axil_rdata_reg[27] <= offset_ptp_ts_rel_req_reg || offset_ptp_ts_rel_ack_sync2_reg; // Relative offset pending
|
||||||
|
s_axil_rdata_reg[28] <= set_ptp_period_req_reg || set_ptp_period_ack_sync2_reg; // Period set pending
|
||||||
|
s_axil_rdata_reg[29] <= offset_ptp_ts_req_reg || offset_ptp_ts_ack_sync2_reg; // FNS offset pending
|
||||||
|
end
|
||||||
|
7'h10: s_axil_rdata_reg <= {ptp_sync_ts_tod[15:0], 16'd0}; // PTP cur fns
|
||||||
|
7'h14: s_axil_rdata_reg <= ptp_sync_ts_tod[47:16]; // PTP cur ToD ns
|
||||||
|
7'h18: s_axil_rdata_reg <= ptp_sync_ts_tod[79:48]; // PTP cur ToD sec l
|
||||||
|
7'h1C: s_axil_rdata_reg <= 32'(ptp_sync_ts_tod[95:80]); // PTP cur ToD sec h
|
||||||
|
7'h20: s_axil_rdata_reg <= ptp_sync_ts_rel[47:16]; // PTP cur rel ns l
|
||||||
|
7'h24: s_axil_rdata_reg <= 32'(ptp_sync_ts_rel[63:48]); // PTP cur rel ns h
|
||||||
|
7'h28: s_axil_rdata_reg <= '0; // PTP cur PTM l
|
||||||
|
7'h2C: s_axil_rdata_reg <= '0; // PTP cur PTM h
|
||||||
|
7'h30: begin
|
||||||
|
// PTP snapshot fns
|
||||||
|
get_ptp_ts_tod_reg <= ptp_sync_ts_tod;
|
||||||
|
get_ptp_ts_rel_reg <= ptp_sync_ts_rel;
|
||||||
|
s_axil_rdata_reg <= {ptp_sync_ts_tod[15:0], 16'd0};
|
||||||
|
end
|
||||||
|
7'h34: s_axil_rdata_reg <= 32'(get_ptp_ts_tod_reg[45:16]); // PTP snapshot ToD ns
|
||||||
|
7'h38: s_axil_rdata_reg <= get_ptp_ts_tod_reg[79:48]; // PTP snapshot ToD sec l
|
||||||
|
7'h3C: s_axil_rdata_reg <= 32'(get_ptp_ts_tod_reg[95:80]); // PTP snapshot ToD sec h
|
||||||
|
7'h40: s_axil_rdata_reg <= get_ptp_ts_rel_reg[47:16]; // PTP snapshot rel ns l
|
||||||
|
7'h44: s_axil_rdata_reg <= 32'(get_ptp_ts_rel_reg[63:48]); // PTP snapshot rel ns h
|
||||||
|
7'h48: s_axil_rdata_reg <= '0; // PTP snapshot PTM l
|
||||||
|
7'h4C: s_axil_rdata_reg <= '0; // PTP snapshot PTM h
|
||||||
|
7'h50: s_axil_rdata_reg <= 32'(offset_ptp_ts_tod_ns_reg); // PTP offset ToD
|
||||||
|
7'h54: s_axil_rdata_reg <= 32'(set_ptp_ts_tod_ns_reg); // PTP set ToD ns
|
||||||
|
7'h58: s_axil_rdata_reg <= set_ptp_ts_tod_s_reg[31:0]; // PTP set ToD sec l
|
||||||
|
7'h5C: s_axil_rdata_reg <= set_ptp_ts_tod_s_reg[47:16]; // PTP set ToD sec h
|
||||||
|
7'h60: s_axil_rdata_reg <= set_ptp_ts_rel_ns_reg[31:0]; // PTP set rel ns l
|
||||||
|
7'h64: s_axil_rdata_reg <= set_ptp_ts_rel_ns_reg[47:16]; // PTP set rel ns h
|
||||||
|
7'h68: s_axil_rdata_reg <= offset_ptp_ts_rel_ns_reg; // PTP offset rel
|
||||||
|
7'h6C: s_axil_rdata_reg <= offset_ptp_ts_fns_reg; // PTP offset FNS
|
||||||
|
7'h70: s_axil_rdata_reg <= 32'(PTP_CLK_PER_FNS); // PTP nom period fns
|
||||||
|
7'h74: s_axil_rdata_reg <= 32'(PTP_CLK_PER_NS); // PTP nom period ns
|
||||||
|
7'h78: s_axil_rdata_reg <= set_ptp_period_fns_reg; // PTP period fns
|
||||||
|
7'h7C: s_axil_rdata_reg <= 32'(set_ptp_period_ns_reg); // PTP period ns
|
||||||
|
default: begin end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
if (rst) begin
|
||||||
|
s_axil_awready_reg <= 1'b0;
|
||||||
|
s_axil_wready_reg <= 1'b0;
|
||||||
|
s_axil_bvalid_reg <= 1'b0;
|
||||||
|
|
||||||
|
s_axil_arready_reg <= 1'b0;
|
||||||
|
s_axil_rvalid_reg <= 1'b0;
|
||||||
|
|
||||||
|
set_ptp_period_ns_reg <= PTP_NS_W'(PTP_CLK_PER_NS);
|
||||||
|
set_ptp_period_fns_reg <= PTP_FNS_W'(PTP_CLK_PER_FNS);
|
||||||
|
|
||||||
|
set_ptp_ts_tod_req_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_tod_req_reg <= 1'b0;
|
||||||
|
set_ptp_ts_rel_req_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_rel_req_reg <= 1'b0;
|
||||||
|
offset_ptp_ts_req_reg <= 1'b0;
|
||||||
|
set_ptp_period_req_reg <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// PTP clock
|
||||||
|
taxi_ptp_td_phc #(
|
||||||
|
.PERIOD_NS_NUM(PTP_CLK_PER_NS_NUM),
|
||||||
|
.PERIOD_NS_DENOM(PTP_CLK_PER_NS_DENOM)
|
||||||
|
)
|
||||||
|
ptp_td_phc_inst (
|
||||||
|
.clk(ptp_clk),
|
||||||
|
.rst(ptp_rst),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ToD timestamp control
|
||||||
|
*/
|
||||||
|
.input_ts_tod_s(set_ptp_ts_tod_s_reg),
|
||||||
|
.input_ts_tod_ns(set_ptp_ts_tod_ns_reg),
|
||||||
|
.input_ts_tod_valid(set_ptp_ts_tod_valid_reg),
|
||||||
|
.input_ts_tod_ready(set_ptp_ts_tod_ready),
|
||||||
|
.input_ts_tod_offset_ns(offset_ptp_ts_tod_ns_reg),
|
||||||
|
.input_ts_tod_offset_valid(offset_ptp_ts_tod_valid_reg),
|
||||||
|
.input_ts_tod_offset_ready(offset_ptp_ts_tod_ready),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Relative timestamp control
|
||||||
|
*/
|
||||||
|
.input_ts_rel_ns(set_ptp_ts_rel_ns_reg),
|
||||||
|
.input_ts_rel_valid(set_ptp_ts_rel_valid_reg),
|
||||||
|
.input_ts_rel_ready(set_ptp_ts_rel_ready),
|
||||||
|
.input_ts_rel_offset_ns(offset_ptp_ts_rel_ns_reg),
|
||||||
|
.input_ts_rel_offset_valid(offset_ptp_ts_rel_valid_reg),
|
||||||
|
.input_ts_rel_offset_ready(offset_ptp_ts_rel_ready),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fractional ns control
|
||||||
|
*/
|
||||||
|
.input_ts_offset_fns(offset_ptp_ts_fns_reg),
|
||||||
|
.input_ts_offset_valid(offset_ptp_ts_valid_reg),
|
||||||
|
.input_ts_offset_ready(offset_ptp_ts_ready),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Period control
|
||||||
|
*/
|
||||||
|
.input_period_ns(set_ptp_period_ns_reg),
|
||||||
|
.input_period_fns(set_ptp_period_fns_reg),
|
||||||
|
.input_period_valid(set_ptp_period_valid_reg),
|
||||||
|
.input_period_ready(set_ptp_period_ready),
|
||||||
|
.input_drift_num('0),
|
||||||
|
.input_drift_denom('0),
|
||||||
|
.input_drift_valid(1'b0),
|
||||||
|
.input_drift_ready(),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Time distribution serial data output
|
||||||
|
*/
|
||||||
|
.ptp_td_sdo(ptp_td_sdo),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PPS output
|
||||||
|
*/
|
||||||
|
.output_pps(ptp_pps),
|
||||||
|
.output_pps_str(ptp_pps_str)
|
||||||
|
);
|
||||||
|
|
||||||
|
// sync to core clock domain
|
||||||
|
taxi_ptp_td_leaf #(
|
||||||
|
.TS_REL_EN(1),
|
||||||
|
.TS_TOD_EN(1),
|
||||||
|
.TS_FNS_W(16),
|
||||||
|
.TS_REL_NS_W(48),
|
||||||
|
.TS_TOD_S_W(48),
|
||||||
|
.TS_REL_W(64),
|
||||||
|
.TS_TOD_W(96),
|
||||||
|
.TD_SDI_PIPELINE(PTP_CLOCK_CDC_PIPELINE)
|
||||||
|
)
|
||||||
|
ptp_td_leaf_inst (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
.sample_clk(ptp_sample_clk),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTP clock interface
|
||||||
|
*/
|
||||||
|
.ptp_clk(ptp_clk),
|
||||||
|
.ptp_rst(ptp_rst),
|
||||||
|
.ptp_td_sdi(ptp_td_sdo),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timestamp output
|
||||||
|
*/
|
||||||
|
.output_ts_rel(ptp_sync_ts_rel),
|
||||||
|
.output_ts_rel_step(ptp_sync_ts_rel_step),
|
||||||
|
.output_ts_tod(ptp_sync_ts_tod),
|
||||||
|
.output_ts_tod_step(ptp_sync_ts_tod_step),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PPS output (ToD format only)
|
||||||
|
*/
|
||||||
|
.output_pps(ptp_sync_pps),
|
||||||
|
.output_pps_str(ptp_sync_pps_str),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Status
|
||||||
|
*/
|
||||||
|
.locked(ptp_sync_locked)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`resetall
|
||||||
43
src/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
Normal file
43
src/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# SPDX-License-Identifier: CERN-OHL-S-2.0
|
||||||
|
#
|
||||||
|
# Copyright (c) 2019-2026 FPGA Ninja, LLC
|
||||||
|
#
|
||||||
|
# Authors:
|
||||||
|
# - Alex Forencich
|
||||||
|
#
|
||||||
|
|
||||||
|
# PTP time distribution PHC module control registers
|
||||||
|
|
||||||
|
foreach inst [get_cells -hier -filter {(ORIG_REF_NAME == taxi_ptp_td_phc_axil || REF_NAME == taxi_ptp_td_phc_axil || ORIG_REF_NAME == taxi_ptp_td_phc_apb || REF_NAME == taxi_ptp_td_phc_apb)}] {
|
||||||
|
puts "Inserting timing constraints for taxi_ptp_td_phc_axil instance $inst"
|
||||||
|
|
||||||
|
set src_clk [get_clocks -of_objects [get_cells "$inst/set_ptp_period_req_reg_reg"]]
|
||||||
|
|
||||||
|
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 1.0}]
|
||||||
|
|
||||||
|
set_max_delay -from [get_cells "$inst/set_ptp_ts_tod_s_reg_reg[*]"] -to [get_cells "$inst/ptp_td_phc_inst/ts_tod_s_reg_reg[*]"] -datapath_only $src_clk_period
|
||||||
|
set_max_delay -from [get_cells "$inst/set_ptp_ts_tod_ns_reg_reg[*]"] -to [get_cells "$inst/ptp_td_phc_inst/ts_tod_ns_reg_reg[*]"] -datapath_only $src_clk_period
|
||||||
|
set_max_delay -from [get_cells "$inst/set_ptp_ts_tod_req_reg_reg"] -to [get_cells "$inst/set_ptp_ts_tod_req_sync1_reg_reg"] -datapath_only $src_clk_period
|
||||||
|
set_max_delay -from [get_cells "$inst/set_ptp_ts_tod_ack_reg_reg"] -to [get_cells "$inst/set_ptp_ts_tod_ack_sync1_reg_reg"] -datapath_only $src_clk_period
|
||||||
|
|
||||||
|
set_max_delay -from [get_cells "$inst/offset_ptp_ts_tod_ns_reg_reg[*]"] -to [get_cells "$inst/ptp_td_phc_inst/adder_b_reg_reg[*]"] -datapath_only $src_clk_period
|
||||||
|
set_max_delay -from [get_cells "$inst/offset_ptp_ts_tod_req_reg_reg"] -to [get_cells "$inst/offset_ptp_ts_tod_req_sync1_reg_reg"] -datapath_only $src_clk_period
|
||||||
|
set_max_delay -from [get_cells "$inst/offset_ptp_ts_tod_ack_reg_reg"] -to [get_cells "$inst/offset_ptp_ts_tod_ack_sync1_reg_reg"] -datapath_only $src_clk_period
|
||||||
|
|
||||||
|
set_max_delay -from [get_cells "$inst/set_ptp_ts_rel_ns_reg_reg[*]"] -to [get_cells "$inst/ptp_td_phc_inst/ts_rel_ns_reg_reg[*]"] -datapath_only $src_clk_period
|
||||||
|
set_max_delay -from [get_cells "$inst/set_ptp_ts_rel_req_reg_reg"] -to [get_cells "$inst/set_ptp_ts_rel_req_sync1_reg_reg"] -datapath_only $src_clk_period
|
||||||
|
set_max_delay -from [get_cells "$inst/set_ptp_ts_rel_ack_reg_reg"] -to [get_cells "$inst/set_ptp_ts_rel_ack_sync1_reg_reg"] -datapath_only $src_clk_period
|
||||||
|
|
||||||
|
set_max_delay -from [get_cells "$inst/offset_ptp_ts_rel_ns_reg_reg[*]"] -to [get_cells "$inst/ptp_td_phc_inst/adder_b_reg_reg[*]"] -datapath_only $src_clk_period
|
||||||
|
set_max_delay -from [get_cells "$inst/offset_ptp_ts_rel_req_reg_reg"] -to [get_cells "$inst/offset_ptp_ts_rel_req_sync1_reg_reg"] -datapath_only $src_clk_period
|
||||||
|
set_max_delay -from [get_cells "$inst/offset_ptp_ts_rel_ack_reg_reg"] -to [get_cells "$inst/offset_ptp_ts_rel_ack_sync1_reg_reg"] -datapath_only $src_clk_period
|
||||||
|
|
||||||
|
set_max_delay -from [get_cells "$inst/set_ptp_period_ns_reg_reg[*]"] -to [get_cells "$inst/ptp_td_phc_inst/period_ns_reg_reg[*]"] -datapath_only $src_clk_period
|
||||||
|
set_max_delay -from [get_cells "$inst/set_ptp_period_fns_reg_reg[*]"] -to [get_cells "$inst/ptp_td_phc_inst/period_fns_reg_reg[*]"] -datapath_only $src_clk_period
|
||||||
|
set_max_delay -from [get_cells "$inst/set_ptp_period_req_reg_reg"] -to [get_cells "$inst/set_ptp_period_req_sync1_reg_reg"] -datapath_only $src_clk_period
|
||||||
|
set_max_delay -from [get_cells "$inst/set_ptp_period_ack_reg_reg"] -to [get_cells "$inst/set_ptp_period_ack_sync1_reg_reg"] -datapath_only $src_clk_period
|
||||||
|
|
||||||
|
set_max_delay -from [get_cells "$inst/offset_ptp_ts_fns_reg_reg[*]"] -to [get_cells "$inst/ptp_td_phc_inst/adder_b_reg_reg[*]"] -datapath_only $src_clk_period
|
||||||
|
set_max_delay -from [get_cells "$inst/offset_ptp_ts_req_reg_reg"] -to [get_cells "$inst/offset_ptp_ts_req_sync1_reg_reg"] -datapath_only $src_clk_period
|
||||||
|
set_max_delay -from [get_cells "$inst/offset_ptp_ts_ack_reg_reg"] -to [get_cells "$inst/offset_ptp_ts_ack_sync1_reg_reg"] -datapath_only $src_clk_period
|
||||||
|
}
|
||||||
@@ -102,13 +102,19 @@ class PtpTdSource(Reset):
|
|||||||
p += Decimal(self.drift_num) / Decimal(self.drift_denom)
|
p += Decimal(self.drift_num) / Decimal(self.drift_denom)
|
||||||
return p / Decimal(2**32)
|
return p / Decimal(2**32)
|
||||||
|
|
||||||
|
def get_delay_cycles(self):
|
||||||
|
return 14*17+self.td_delay-1
|
||||||
|
|
||||||
|
def get_delay_ns(self):
|
||||||
|
return self.get_delay_cycles() * self.get_period_ns()
|
||||||
|
|
||||||
def set_ts_tod(self, ts_s, ts_ns, ts_fns):
|
def set_ts_tod(self, ts_s, ts_ns, ts_fns):
|
||||||
self.ts_tod_s = int(ts_s)
|
self.ts_tod_s = int(ts_s)
|
||||||
self.ts_tod_ns = int(ts_ns)
|
self.ts_tod_ns = int(ts_ns)
|
||||||
self.ts_fns = int(ts_fns)
|
self.ts_fns = int(ts_fns)
|
||||||
self.ts_tod_updated = True
|
self.ts_tod_updated = True
|
||||||
|
|
||||||
def set_ts_tod_64(self, ts):
|
def set_ts_tod_96(self, ts):
|
||||||
ts = int(ts)
|
ts = int(ts)
|
||||||
self.set_ts_tod(ts >> 48, (ts >> 32) & 0x3fffffff, (ts & 0xffff) << 16)
|
self.set_ts_tod(ts >> 48, (ts >> 32) & 0x3fffffff, (ts & 0xffff) << 16)
|
||||||
|
|
||||||
@@ -123,7 +129,7 @@ class PtpTdSource(Reset):
|
|||||||
self.set_ts_tod_ns(Decimal(t).scaleb(9, self.ctx))
|
self.set_ts_tod_ns(Decimal(t).scaleb(9, self.ctx))
|
||||||
|
|
||||||
def set_ts_tod_sim_time(self):
|
def set_ts_tod_sim_time(self):
|
||||||
self.set_ts_tod_ns(Decimal(get_sim_time('fs')).scaleb(-6))
|
self.set_ts_tod_ns(Decimal(get_sim_time('fs')).scaleb(-6) + self.get_delay_ns())
|
||||||
|
|
||||||
def get_ts_tod(self):
|
def get_ts_tod(self):
|
||||||
ts_tod_s, ts_tod_ns, ts_rel_ns, ts_fns = self.timestamp_delay[0]
|
ts_tod_s, ts_tod_ns, ts_rel_ns, ts_fns = self.timestamp_delay[0]
|
||||||
@@ -161,7 +167,7 @@ class PtpTdSource(Reset):
|
|||||||
self.set_ts_rel_ns(Decimal(t).scaleb(9, self.ctx))
|
self.set_ts_rel_ns(Decimal(t).scaleb(9, self.ctx))
|
||||||
|
|
||||||
def set_ts_rel_sim_time(self):
|
def set_ts_rel_sim_time(self):
|
||||||
self.set_ts_rel_ns(Decimal(get_sim_time('fs')).scaleb(-6))
|
self.set_ts_rel_ns(Decimal(get_sim_time('fs')).scaleb(-6) + self.get_delay_ns())
|
||||||
|
|
||||||
def get_ts_rel(self):
|
def get_ts_rel(self):
|
||||||
ts_tod_s, ts_tod_ns, ts_rel_ns, ts_fns = self.timestamp_delay[0]
|
ts_tod_s, ts_tod_ns, ts_rel_ns, ts_fns = self.timestamp_delay[0]
|
||||||
|
|||||||
Reference in New Issue
Block a user