eth: Integrate PTP TD leaf clock into MACs

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich
2026-02-13 21:54:11 -08:00
parent 380e2d521a
commit 31553f5734
30 changed files with 880 additions and 155 deletions

View File

@@ -584,10 +584,13 @@ always_ff @(posedge clk) begin
if (PTP_TS_EN && PTP_TS_FMT_TOD) begin
// 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_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[95:48] <= ptp_ts_reg[95:48] + 1;
/* verilator lint_on SELRANGE */
end
// lane swapping and termination character detection
@@ -807,8 +810,11 @@ always_ff @(posedge clk) begin
if (input_start_swap_reg) begin
start_packet_reg <= 2'b10;
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[95:48] <= ptp_ts[95:48];
/* verilator lint_on SELRANGE */
end else begin
ptp_ts_reg <= ptp_ts + PTP_TS_W'(ts_inc_reg >> 1);
end

View File

@@ -788,10 +788,13 @@ always_ff @(posedge clk) begin
if (PTP_TS_EN && PTP_TS_FMT_TOD) begin
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_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[95:48] <= m_axis_tx_cpl_ts_reg[95:48] + 1;
/* verilator lint_on SELRANGE */
end
if (GBX_IF_EN && tx_gbx_req_stall) begin
@@ -810,8 +813,11 @@ always_ff @(posedge clk) begin
if (swap_lanes_reg) begin
if (PTP_TS_EN) 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[95:48] <= ptp_ts[95:48];
/* verilator lint_on SELRANGE */
end else begin
m_axis_tx_cpl_ts_reg <= ptp_ts + PTP_TS_W'(ts_inc_reg >> 1);
end

View File

@@ -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_null_src.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

View File

@@ -26,8 +26,10 @@ module taxi_eth_mac_10g #
parameter logic DIC_EN = 1'b1,
parameter MIN_FRAME_LEN = 64,
parameter logic PTP_TS_EN = 1'b0,
parameter logic PTP_TD_EN = PTP_TS_EN,
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter logic PFC_EN = 1'b0,
parameter logic PAUSE_EN = PFC_EN,
parameter logic STAT_EN = 1'b0,
@@ -71,8 +73,18 @@ module taxi_eth_mac_10g #
/*
* PTP
*/
input wire logic [PTP_TS_W-1:0] tx_ptp_ts = '0,
input wire logic [PTP_TS_W-1:0] rx_ptp_ts = '0,
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,
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)
@@ -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(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
taxi_axis_xgmii_rx_64 #(
@@ -245,7 +374,7 @@ if (DATA_W == 64) begin
/*
* PTP
*/
.ptp_ts(rx_ptp_ts),
.ptp_ts(rx_ptp_ts_out),
/*
* Configuration
@@ -310,7 +439,7 @@ if (DATA_W == 64) begin
/*
* PTP
*/
.ptp_ts(tx_ptp_ts),
.ptp_ts(tx_ptp_ts_out),
/*
* Configuration
@@ -364,7 +493,7 @@ end else if (DATA_W == 32) begin
/*
* PTP
*/
.ptp_ts(rx_ptp_ts),
.ptp_ts(rx_ptp_ts_out),
/*
* Configuration
@@ -431,7 +560,7 @@ end else if (DATA_W == 32) begin
/*
* PTP
*/
.ptp_ts(tx_ptp_ts),
.ptp_ts(tx_ptp_ts_out),
/*
* Configuration

View File

@@ -26,8 +26,10 @@ module taxi_eth_mac_10g_fifo #
parameter logic DIC_EN = 1'b1,
parameter MIN_FRAME_LEN = 64,
parameter logic PTP_TS_EN = 1'b0,
parameter logic PTP_TD_EN = PTP_TS_EN,
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter logic STAT_EN = 1'b0,
parameter STAT_TX_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 logic_clk,
input wire logic logic_rst,
input wire logic ptp_sample_clk,
/*
* AXI4-Stream input (sink)
@@ -85,8 +86,18 @@ module taxi_eth_mac_10g_fifo #
/*
* PTP clock
*/
input wire logic [PTP_TS_W-1:0] ptp_ts = '0,
input wire logic ptp_ts_step = 1'b0,
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,
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
@@ -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(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
wire tx_error_underflow_int;
@@ -195,7 +200,14 @@ always_ff @(posedge logic_clk or posedge logic_rst) begin
end
// 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 #(
.TS_W(PTP_TS_W),
@@ -207,10 +219,10 @@ if (PTP_TS_EN) begin : ptp
.output_clk(tx_clk),
.output_rst(tx_rst),
.sample_clk(ptp_sample_clk),
.input_ts(ptp_ts),
.input_ts_step(ptp_ts_step),
.output_ts(tx_ptp_ts),
.output_ts_step(),
.input_ts(ptp_ts_in),
.input_ts_step(ptp_ts_step_in),
.output_ts(tx_ptp_ts_int),
.output_ts_step(tx_ptp_ts_step_out),
.output_pps(),
.output_pps_str(),
.locked(tx_ptp_locked)
@@ -226,10 +238,10 @@ if (PTP_TS_EN) begin : ptp
.output_clk(rx_clk),
.output_rst(rx_rst),
.sample_clk(ptp_sample_clk),
.input_ts(ptp_ts),
.input_ts_step(ptp_ts_step),
.output_ts(rx_ptp_ts),
.output_ts_step(),
.input_ts(ptp_ts_in),
.input_ts_step(ptp_ts_step_in),
.output_ts(rx_ptp_ts_int),
.output_ts_step(rx_ptp_ts_step_out),
.output_pps(),
.output_pps_str(),
.locked(rx_ptp_locked)
@@ -237,11 +249,13 @@ if (PTP_TS_EN) begin : ptp
end else begin
assign tx_ptp_ts = '0;
assign rx_ptp_ts = '0;
assign tx_ptp_ts_int = '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 rx_ptp_locked = 1'b0;
assign tx_ptp_locked = tx_ptp_locked_int;
assign rx_ptp_locked = rx_ptp_locked_int;
end
@@ -257,8 +271,10 @@ taxi_eth_mac_10g #(
.DIC_EN(DIC_EN),
.MIN_FRAME_LEN(MIN_FRAME_LEN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TD_EN(PTP_TD_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W),
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
.PFC_EN(1'b0),
.PAUSE_EN(1'b0),
.STAT_EN(STAT_EN),
@@ -302,8 +318,18 @@ eth_mac_10g_inst (
/*
* PTP
*/
.tx_ptp_ts(tx_ptp_ts),
.rx_ptp_ts(rx_ptp_ts),
.ptp_clk(ptp_clk),
.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)

View File

@@ -8,4 +8,5 @@ taxi_mac_pause_ctrl_tx.sv
taxi_mac_pause_ctrl_rx.sv
../lib/taxi/src/axis/rtl/taxi_axis_null_src.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

View File

@@ -25,8 +25,10 @@ module taxi_eth_mac_phy_10g #
parameter logic DIC_EN = 1'b1,
parameter MIN_FRAME_LEN = 64,
parameter logic PTP_TS_EN = 1'b0,
parameter logic PTP_TD_EN = PTP_TS_EN,
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter logic BIT_REVERSE = 1'b0,
parameter logic SCRAMBLER_DISABLE = 1'b0,
parameter logic PRBS31_EN = 1'b0,
@@ -82,8 +84,18 @@ module taxi_eth_mac_phy_10g #
/*
* PTP
*/
input wire logic [PTP_TS_W-1:0] tx_ptp_ts,
input wire logic [PTP_TS_W-1:0] rx_ptp_ts,
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,
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)
@@ -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(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 #(
.DATA_W(DATA_W),
.HDR_W(HDR_W),
@@ -263,7 +392,7 @@ eth_mac_phy_10g_rx_inst (
/*
* PTP
*/
.ptp_ts(rx_ptp_ts),
.ptp_ts(rx_ptp_ts_out),
/*
* Status
@@ -337,7 +466,7 @@ eth_mac_phy_10g_tx_inst (
/*
* PTP
*/
.ptp_ts(tx_ptp_ts),
.ptp_ts(tx_ptp_ts_out),
/*
* Status

View File

@@ -25,8 +25,10 @@ module taxi_eth_mac_phy_10g_fifo #
parameter logic DIC_EN = 1'b1,
parameter MIN_FRAME_LEN = 64,
parameter logic PTP_TS_EN = 1'b0,
parameter logic PTP_TD_EN = PTP_TS_EN,
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter logic BIT_REVERSE = 1'b0,
parameter logic SCRAMBLER_DISABLE = 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 logic_clk,
input wire logic logic_rst,
input wire logic ptp_sample_clk,
/*
* Transmit interface (AXI stream)
@@ -96,8 +97,18 @@ module taxi_eth_mac_phy_10g_fifo #
/*
* PTP clock
*/
input wire logic [PTP_TS_W-1:0] ptp_ts = '0,
input wire logic ptp_ts_step = 1'b0,
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,
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
@@ -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(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
wire tx_error_underflow_int;
@@ -229,8 +234,15 @@ always_ff @(posedge logic_clk or posedge logic_rst) begin
end
// 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 #(
.TS_W(PTP_TS_W),
.NS_W(6)
@@ -241,10 +253,10 @@ if (PTP_TS_EN) begin : ptp
.output_clk(tx_clk),
.output_rst(tx_rst),
.sample_clk(ptp_sample_clk),
.input_ts(ptp_ts),
.input_ts_step(ptp_ts_step),
.output_ts(tx_ptp_ts),
.output_ts_step(),
.input_ts(ptp_ts_in),
.input_ts_step(ptp_ts_step_in),
.output_ts(tx_ptp_ts_int),
.output_ts_step(tx_ptp_ts_step_out),
.output_pps(),
.output_pps_str(),
.locked(tx_ptp_locked)
@@ -260,10 +272,10 @@ if (PTP_TS_EN) begin : ptp
.output_clk(rx_clk),
.output_rst(rx_rst),
.sample_clk(ptp_sample_clk),
.input_ts(ptp_ts),
.input_ts_step(ptp_ts_step),
.output_ts(rx_ptp_ts),
.output_ts_step(),
.input_ts(ptp_ts_in),
.input_ts_step(ptp_ts_step_in),
.output_ts(rx_ptp_ts_int),
.output_ts_step(rx_ptp_ts_step_out),
.output_pps(),
.output_pps_str(),
.locked(rx_ptp_locked)
@@ -271,11 +283,13 @@ if (PTP_TS_EN) begin : ptp
end else begin
assign tx_ptp_ts = '0;
assign rx_ptp_ts = '0;
assign tx_ptp_ts_int = '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 rx_ptp_locked = 1'b0;
assign tx_ptp_locked = tx_ptp_locked_int;
assign rx_ptp_locked = rx_ptp_locked_int;
end
@@ -290,8 +304,10 @@ taxi_eth_mac_phy_10g #(
.DIC_EN(DIC_EN),
.MIN_FRAME_LEN(MIN_FRAME_LEN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TD_EN(PTP_TD_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W),
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
.BIT_REVERSE(BIT_REVERSE),
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE),
.PRBS31_EN(PRBS31_EN),
@@ -345,8 +361,18 @@ eth_mac_phy_10g_inst (
/*
* PTP
*/
.tx_ptp_ts(tx_ptp_ts),
.rx_ptp_ts(rx_ptp_ts),
.ptp_clk(ptp_clk),
.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)

View File

@@ -58,8 +58,10 @@ module taxi_eth_mac_25g_us #
parameter logic DIC_EN = 1'b1,
parameter MIN_FRAME_LEN = 64,
parameter logic PTP_TS_EN = 1'b0,
parameter logic PTP_TD_EN = PTP_TS_EN,
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter logic PRBS31_EN = 1'b0,
parameter TX_SERDES_PIPELINE = 1,
parameter RX_SERDES_PIPELINE = 1,
@@ -121,7 +123,6 @@ module taxi_eth_mac_25g_us #
output wire logic tx_clk[CNT],
input wire logic tx_rst_in[CNT] = '{CNT{1'b0}},
output wire logic tx_rst_out[CNT],
input wire logic ptp_sample_clk[CNT] = '{CNT{1'b0}},
/*
* Transmit interface (AXI stream)
@@ -137,10 +138,18 @@ module taxi_eth_mac_25g_us #
/*
* PTP clock
*/
input wire logic [PTP_TS_W-1:0] tx_ptp_ts[CNT] = '{CNT{'0}},
input wire logic tx_ptp_ts_step[CNT] = '{CNT{1'b0}},
input wire logic [PTP_TS_W-1:0] rx_ptp_ts[CNT] = '{CNT{'0}},
input wire logic rx_ptp_ts_step[CNT] = '{CNT{1'b0}},
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,
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)
@@ -420,8 +429,10 @@ for (genvar n = 0; n < CNT; n = n + 1) begin : ch
.DIC_EN(DIC_EN),
.MIN_FRAME_LEN(MIN_FRAME_LEN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TD_EN(PTP_TD_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W),
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
.PRBS31_EN(PRBS31_EN),
.TX_SERDES_PIPELINE(TX_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_rst_in(tx_rst_in[n]),
.tx_rst_out(tx_rst_out[n]),
.ptp_sample_clk(ptp_sample_clk[n]),
/*
* Transmit interface (AXI stream)
@@ -513,10 +523,18 @@ for (genvar n = 0; n < CNT; n = n + 1) begin : ch
/*
* PTP clock
*/
.tx_ptp_ts(tx_ptp_ts[n]),
.tx_ptp_ts_step(tx_ptp_ts_step[n]),
.rx_ptp_ts(rx_ptp_ts[n]),
.rx_ptp_ts_step(rx_ptp_ts_step[n]),
.ptp_clk(ptp_clk),
.ptp_rst(ptp_rst),
.ptp_sample_clk(ptp_sample_clk),
.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)

View File

@@ -57,8 +57,10 @@ module taxi_eth_mac_25g_us_ch #
parameter logic DIC_EN = 1'b1,
parameter MIN_FRAME_LEN = 64,
parameter logic PTP_TS_EN = 1'b0,
parameter logic PTP_TD_EN = PTP_TS_EN,
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter logic PRBS31_EN = 1'b0,
parameter TX_SERDES_PIPELINE = 1,
parameter RX_SERDES_PIPELINE = 1,
@@ -134,7 +136,6 @@ module taxi_eth_mac_25g_us_ch #
output wire logic tx_clk,
input wire logic tx_rst_in = 1'b0,
output wire logic tx_rst_out,
input wire logic ptp_sample_clk = 1'b0,
/*
* Transmit interface (AXI stream)
@@ -150,10 +151,18 @@ module taxi_eth_mac_25g_us_ch #
/*
* PTP clock
*/
input wire logic [PTP_TS_W-1:0] tx_ptp_ts = '0,
input wire logic tx_ptp_ts_step = 1'b0,
input wire logic [PTP_TS_W-1:0] rx_ptp_ts = '0,
input wire logic rx_ptp_ts_step = 1'b0,
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,
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)
@@ -878,8 +887,10 @@ if (COMBINED_MAC_PCS) begin : mac
.DIC_EN(DIC_EN),
.MIN_FRAME_LEN(MIN_FRAME_LEN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TD_EN(PTP_TD_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W),
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
.BIT_REVERSE(1'b1),
.SCRAMBLER_DISABLE(1'b0),
.PRBS31_EN(PRBS31_EN),
@@ -935,8 +946,18 @@ if (COMBINED_MAC_PCS) begin : mac
/*
* PTP
*/
.tx_ptp_ts(tx_ptp_ts),
.rx_ptp_ts(rx_ptp_ts),
.ptp_clk(ptp_clk),
.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)
@@ -1160,8 +1181,10 @@ end else begin : mac
.DIC_EN(DIC_EN),
.MIN_FRAME_LEN(MIN_FRAME_LEN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TD_EN(PTP_TD_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W),
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
.PFC_EN(PFC_EN),
.PAUSE_EN(PAUSE_EN),
.STAT_EN(STAT_EN),
@@ -1205,8 +1228,18 @@ end else begin : mac
/*
* PTP
*/
.tx_ptp_ts(tx_ptp_ts),
.rx_ptp_ts(rx_ptp_ts),
.ptp_clk(ptp_clk),
.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)

View File

@@ -40,8 +40,10 @@ export PARAM_PADDING_EN := 1
export PARAM_DIC_EN := 1
export PARAM_MIN_FRAME_LEN := 64
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_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_PFC_EN := 1
export PARAM_PAUSE_EN := $(PARAM_PFC_EN)

View File

@@ -0,0 +1 @@
../../lib/taxi/src/ptp/tb/ptp_td.py

View File

@@ -13,6 +13,7 @@ import itertools
import logging
import os
import struct
import sys
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.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:
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.rx_ptp_clock = PtpClockSimTime(ts_tod=dut.rx_ptp_ts, clock=dut.rx_clk)
self.tx_ptp_clock = PtpClockSimTime(ts_tod=dut.tx_ptp_ts, clock=dut.tx_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_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_resend.setimmediatevalue(0)
@@ -112,20 +135,26 @@ class TB:
async def reset(self):
self.dut.rx_rst.setimmediatevalue(0)
self.dut.tx_rst.setimmediatevalue(0)
self.dut.ptp_rst.setimmediatevalue(0)
self.dut.stat_rst.setimmediatevalue(0)
await RisingEdge(self.dut.rx_clk)
await RisingEdge(self.dut.rx_clk)
self.dut.rx_rst.value = 1
self.dut.tx_rst.value = 1
self.dut.ptp_rst.value = 1
self.dut.stat_rst.value = 1
await RisingEdge(self.dut.rx_clk)
await RisingEdge(self.dut.rx_clk)
self.dut.rx_rst.value = 0
self.dut.tx_rst.value = 0
self.dut.ptp_rst.value = 0
self.dut.stat_rst.value = 0
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):
@@ -138,6 +167,13 @@ async def run_test_rx(dut, payload_lengths=None, payload_data=None, ifg=12):
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()]
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 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()
@@ -184,6 +223,13 @@ async def run_test_tx(dut, payload_lengths=None, payload_data=None, ifg=12):
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()]
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.check_fcs()
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()
@@ -231,6 +280,13 @@ async def run_test_tx_alignment(dut, payload_data=None, ifg=12):
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 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.check_fcs()
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)
@@ -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("ptp_td_en", [1, 0])
@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"
module = os.path.splitext(os.path.basename(__file__))[0]
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['MIN_FRAME_LEN'] = 64
parameters['PTP_TS_EN'] = 1
parameters['PTP_TD_EN'] = ptp_td_en
parameters['PTP_TS_FMT_TOD'] = 1
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['PFC_EN'] = pfc_en
parameters['PAUSE_EN'] = parameters['PFC_EN']

View File

@@ -26,8 +26,10 @@ module test_taxi_eth_mac_10g #
parameter logic DIC_EN = 1'b1,
parameter MIN_FRAME_LEN = 64,
parameter logic PTP_TS_EN = 1'b0,
parameter logic PTP_TD_EN = PTP_TS_EN,
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter TX_TAG_W = 16,
parameter logic PFC_EN = 1'b0,
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 [GBX_CNT-1:0] tx_gbx_sync;
logic [PTP_TS_W-1:0] tx_ptp_ts;
logic [PTP_TS_W-1:0] rx_ptp_ts;
logic ptp_clk;
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_resend;
@@ -183,8 +195,10 @@ taxi_eth_mac_10g #(
.DIC_EN(DIC_EN),
.MIN_FRAME_LEN(MIN_FRAME_LEN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TD_EN(PTP_TD_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W),
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
.PFC_EN(PFC_EN),
.PAUSE_EN(PAUSE_EN),
.STAT_EN(STAT_EN),
@@ -228,8 +242,18 @@ uut (
/*
* PTP
*/
.tx_ptp_ts(tx_ptp_ts),
.rx_ptp_ts(rx_ptp_ts),
.ptp_clk(ptp_clk),
.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)

View File

@@ -41,8 +41,10 @@ export PARAM_PADDING_EN := 1
export PARAM_DIC_EN := 1
export PARAM_MIN_FRAME_LEN := 64
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_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_STAT_EN := 1
export PARAM_STAT_TX_LEVEL := 2

View File

@@ -0,0 +1 @@
../../lib/taxi/src/ptp/tb/ptp_td.py

View File

@@ -12,6 +12,7 @@ Authors:
import itertools
import logging
import os
import sys
import pytest
import cocotb_test.simulator
@@ -25,6 +26,16 @@ from cocotb.regression import TestFactory
from cocotbext.eth import XgmiiFrame, XgmiiSource, XgmiiSink, PtpClockSimTime
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:
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.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.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_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.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_ifg.setimmediatevalue(0)
@@ -67,22 +88,28 @@ class TB:
self.dut.logic_rst.setimmediatevalue(0)
self.dut.rx_rst.setimmediatevalue(0)
self.dut.tx_rst.setimmediatevalue(0)
self.dut.ptp_rst.setimmediatevalue(0)
self.dut.stat_rst.setimmediatevalue(0)
await RisingEdge(self.dut.logic_clk)
await RisingEdge(self.dut.logic_clk)
self.dut.logic_rst.value = 1
self.dut.rx_rst.value = 1
self.dut.tx_rst.value = 1
self.dut.ptp_rst.value = 1
self.dut.stat_rst.value = 1
await RisingEdge(self.dut.logic_clk)
await RisingEdge(self.dut.logic_clk)
self.dut.logic_rst.value = 0
self.dut.rx_rst.value = 0
self.dut.tx_rst.value = 0
self.dut.ptp_rst.value = 0
self.dut.stat_rst.value = 0
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):
@@ -96,9 +123,9 @@ async def run_test_rx(dut, payload_lengths=None, payload_data=None, ifg=12):
await tb.reset()
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)
for k in range(1000):
for k in range(2000):
await RisingEdge(dut.rx_clk)
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 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()
@@ -148,9 +178,9 @@ async def run_test_tx(dut, payload_lengths=None, payload_data=None, ifg=12):
await tb.reset()
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)
for k in range(1000):
for k in range(2000):
await RisingEdge(dut.tx_clk)
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.check_fcs()
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()
@@ -201,9 +234,9 @@ async def run_test_tx_alignment(dut, payload_data=None, ifg=12):
await tb.reset()
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)
for k in range(1000):
for k in range(2000):
await RisingEdge(dut.tx_clk)
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.check_fcs()
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)
@@ -354,8 +390,10 @@ def test_taxi_eth_mac_10g_fifo(request, data_w, dic_en):
parameters['DIC_EN'] = dic_en
parameters['MIN_FRAME_LEN'] = 64
parameters['PTP_TS_EN'] = 1
parameters['PTP_TD_EN'] = parameters['PTP_TS_EN']
parameters['PTP_TS_FMT_TOD'] = 1
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['STAT_EN'] = 1
parameters['STAT_TX_LEVEL'] = 2

View File

@@ -27,8 +27,10 @@ module test_taxi_eth_mac_10g_fifo #
parameter logic DIC_EN = 1'b1,
parameter MIN_FRAME_LEN = 64,
parameter logic PTP_TS_EN = 1'b0,
parameter logic PTP_TD_EN = PTP_TS_EN,
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter TX_TAG_W = 16,
parameter logic STAT_EN = 1'b0,
parameter STAT_TX_LEVEL = 1,
@@ -64,7 +66,6 @@ logic tx_clk;
logic tx_rst;
logic logic_clk;
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(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 [GBX_CNT-1:0] tx_gbx_sync;
logic [PTP_TS_W-1:0] ptp_ts;
logic ptp_ts_step;
logic ptp_clk;
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_rst;
@@ -113,8 +124,10 @@ taxi_eth_mac_10g_fifo #(
.DIC_EN(DIC_EN),
.MIN_FRAME_LEN(MIN_FRAME_LEN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TD_EN(PTP_TD_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W),
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
.STAT_EN(STAT_EN),
.STAT_TX_LEVEL(STAT_TX_LEVEL),
.STAT_RX_LEVEL(STAT_RX_LEVEL),
@@ -143,7 +156,6 @@ uut (
.tx_rst(tx_rst),
.logic_clk(logic_clk),
.logic_rst(logic_rst),
.ptp_sample_clk(ptp_sample_clk),
/*
* Transmit interface (AXI stream)
@@ -172,8 +184,18 @@ uut (
/*
* PTP clock
*/
.ptp_ts(ptp_ts),
.ptp_ts_step(ptp_ts_step),
.ptp_clk(ptp_clk),
.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

View File

@@ -48,8 +48,10 @@ export PARAM_PADDING_EN := 1
export PARAM_DIC_EN := 1
export PARAM_MIN_FRAME_LEN := 64
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_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_PRBS31_EN := 1
export PARAM_TX_SERDES_PIPELINE := 2

View File

@@ -0,0 +1 @@
../../lib/taxi/src/ptp/tb/ptp_td.py

View File

@@ -32,11 +32,13 @@ from cocotbext.axi import ApbBus, ApbMaster
try:
from baser import BaseRSerdesSource, BaseRSerdesSink
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 baser import BaseRSerdesSource, BaseRSerdesSink
from ptp_td import PtpTdSource
finally:
del sys.path[0]
@@ -118,8 +120,20 @@ class TB:
self.tx_ptp_clocks = []
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.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.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_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.tx_rst_in.setimmediatevalue([0]*4)
@@ -169,18 +183,24 @@ class TB:
async def reset(self):
self.dut.xcvr_ctrl_rst.setimmediatevalue(0)
self.dut.ptp_rst.setimmediatevalue(0)
self.dut.stat_rst.setimmediatevalue(0)
await RisingEdge(self.dut.xcvr_ctrl_clk)
await RisingEdge(self.dut.xcvr_ctrl_clk)
self.dut.xcvr_ctrl_rst.value = 1
self.dut.ptp_rst.value = 1
self.dut.stat_rst.value = 1
await RisingEdge(self.dut.xcvr_ctrl_clk)
await RisingEdge(self.dut.xcvr_ctrl_clk)
self.dut.xcvr_ctrl_rst.value = 0
self.dut.ptp_rst.value = 0
self.dut.stat_rst.value = 0
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):
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):
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
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 frame_error == 0
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()
@@ -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):
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)
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.ctrl is None
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()
@@ -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):
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)
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.ctrl is None
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)
@@ -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['MIN_FRAME_LEN'] = 64
parameters['PTP_TS_EN'] = 1
parameters['PTP_TD_EN'] = parameters['PTP_TS_EN']
parameters['PTP_TS_FMT_TOD'] = 1
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['PRBS31_EN'] = 1
parameters['TX_SERDES_PIPELINE'] = 2

View File

@@ -47,8 +47,10 @@ module test_taxi_eth_mac_25g_us #
parameter logic DIC_EN = 1'b1,
parameter MIN_FRAME_LEN = 64,
parameter logic PTP_TS_EN = 1'b0,
parameter logic PTP_TD_EN = PTP_TS_EN,
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter TX_TAG_W = 16,
parameter logic PRBS31_EN = 1'b0,
parameter TX_SERDES_PIPELINE = 1,
@@ -108,16 +110,23 @@ logic rx_rst_out[CNT];
logic tx_clk[CNT];
logic tx_rst_in[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(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]();
logic [PTP_TS_W-1:0] tx_ptp_ts[CNT];
logic tx_ptp_ts_step[CNT];
logic [PTP_TS_W-1:0] rx_ptp_ts[CNT];
logic rx_ptp_ts_step[CNT];
logic ptp_clk;
logic ptp_rst;
logic ptp_sample_clk;
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_resend[CNT];
@@ -260,8 +269,10 @@ taxi_eth_mac_25g_us #(
.DIC_EN(DIC_EN),
.MIN_FRAME_LEN(MIN_FRAME_LEN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TD_EN(PTP_TD_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W),
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
.PRBS31_EN(PRBS31_EN),
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),
.RX_SERDES_PIPELINE(RX_SERDES_PIPELINE),
@@ -323,7 +334,6 @@ uut (
.tx_clk(tx_clk),
.tx_rst_in(tx_rst_in),
.tx_rst_out(tx_rst_out),
.ptp_sample_clk(ptp_sample_clk),
/*
* Transmit interface (AXI stream)
@@ -339,10 +349,18 @@ uut (
/*
* PTP
*/
.tx_ptp_ts(tx_ptp_ts),
.tx_ptp_ts_step(tx_ptp_ts_step),
.rx_ptp_ts(rx_ptp_ts),
.rx_ptp_ts_step(rx_ptp_ts_step),
.ptp_clk(ptp_clk),
.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)

View File

@@ -40,8 +40,10 @@ export PARAM_PADDING_EN := 1
export PARAM_DIC_EN := 1
export PARAM_MIN_FRAME_LEN := 64
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_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_BIT_REVERSE := 0
export PARAM_SCRAMBLER_DISABLE := 0

View File

@@ -0,0 +1 @@
../../lib/taxi/src/ptp/tb/ptp_td.py

View File

@@ -31,11 +31,13 @@ from cocotbext.axi import AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiStrea
try:
from baser import BaseRSerdesSource, BaseRSerdesSink
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 baser import BaseRSerdesSource, BaseRSerdesSink
from ptp_td import PtpTdSource
finally:
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.rx_ptp_clock = PtpClockSimTime(ts_tod=dut.rx_ptp_ts, clock=dut.rx_clk)
self.tx_ptp_clock = PtpClockSimTime(ts_tod=dut.tx_ptp_ts, clock=dut.tx_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_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)
@@ -136,20 +150,26 @@ class TB:
async def reset(self):
self.dut.rx_rst.setimmediatevalue(0)
self.dut.tx_rst.setimmediatevalue(0)
self.dut.ptp_rst.setimmediatevalue(0)
self.dut.stat_rst.setimmediatevalue(0)
await RisingEdge(self.dut.rx_clk)
await RisingEdge(self.dut.rx_clk)
self.dut.rx_rst.value = 1
self.dut.tx_rst.value = 1
self.dut.ptp_rst.value = 1
self.dut.stat_rst.value = 1
await RisingEdge(self.dut.rx_clk)
await RisingEdge(self.dut.rx_clk)
self.dut.rx_rst.value = 0
self.dut.tx_rst.value = 0
self.dut.ptp_rst.value = 0
self.dut.stat_rst.value = 0
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):
@@ -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):
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
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 frame_error == 0
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()
@@ -231,8 +261,15 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
await tb.reset()
for k in range(100):
await RisingEdge(dut.tx_clk)
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)
else:
for k in range(100):
await RisingEdge(dut.tx_clk)
tb.dut.cfg_tx_enable.value = 1
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.ctrl 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()
@@ -293,8 +333,15 @@ async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12):
await tb.reset()
for k in range(100):
await RisingEdge(dut.tx_clk)
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)
else:
for k in range(100):
await RisingEdge(dut.tx_clk)
tb.dut.cfg_tx_enable.value = 1
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.ctrl 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)
@@ -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("gbx_en", [1, 0])
@pytest.mark.parametrize("ptp_td_en", [1, 0])
@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"
module = os.path.splitext(os.path.basename(__file__))[0]
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['MIN_FRAME_LEN'] = 64
parameters['PTP_TS_EN'] = 1
parameters['PTP_TD_EN'] = ptp_td_en
parameters['PTP_TS_FMT_TOD'] = 1
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['BIT_REVERSE'] = 0
parameters['SCRAMBLER_DISABLE'] = 0

View File

@@ -26,8 +26,10 @@ module test_taxi_eth_mac_phy_10g #
parameter logic DIC_EN = 1'b1,
parameter MIN_FRAME_LEN = 64,
parameter logic PTP_TS_EN = 1'b0,
parameter logic PTP_TD_EN = PTP_TS_EN,
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter TX_TAG_W = 16,
parameter logic BIT_REVERSE = 1'b0,
parameter logic SCRAMBLER_DISABLE = 1'b0,
@@ -76,8 +78,18 @@ logic serdes_rx_hdr_valid;
logic serdes_rx_bitslip;
logic serdes_rx_reset_req;
logic [PTP_TS_W-1:0] tx_ptp_ts;
logic [PTP_TS_W-1:0] rx_ptp_ts;
logic ptp_clk;
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_resend;
@@ -199,8 +211,10 @@ taxi_eth_mac_phy_10g #(
.DIC_EN(DIC_EN),
.MIN_FRAME_LEN(MIN_FRAME_LEN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TD_EN(PTP_TD_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W),
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
.BIT_REVERSE(BIT_REVERSE),
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE),
.PRBS31_EN(PRBS31_EN),
@@ -256,8 +270,18 @@ uut (
/*
* PTP
*/
.tx_ptp_ts(tx_ptp_ts),
.rx_ptp_ts(rx_ptp_ts),
.ptp_clk(ptp_clk),
.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)

View File

@@ -41,8 +41,10 @@ export PARAM_PADDING_EN := 1
export PARAM_DIC_EN := 1
export PARAM_MIN_FRAME_LEN := 64
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_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_BIT_REVERSE := 0
export PARAM_SCRAMBLER_DISABLE := 0

View File

@@ -0,0 +1 @@
../../lib/taxi/src/ptp/tb/ptp_td.py

View File

@@ -28,11 +28,13 @@ from cocotbext.axi import AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiStrea
try:
from baser import BaseRSerdesSource, BaseRSerdesSink
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 baser import BaseRSerdesSource, BaseRSerdesSink
from ptp_td import PtpTdSource
finally:
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.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.ptp_sample_clk, 9.9, units="ns").start())
self.serdes_source = BaseRSerdesSource(
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.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_ifg.setimmediatevalue(0)
@@ -104,22 +116,28 @@ class TB:
self.dut.logic_rst.setimmediatevalue(0)
self.dut.rx_rst.setimmediatevalue(0)
self.dut.tx_rst.setimmediatevalue(0)
self.dut.ptp_rst.setimmediatevalue(0)
self.dut.stat_rst.setimmediatevalue(0)
await RisingEdge(self.dut.logic_clk)
await RisingEdge(self.dut.logic_clk)
self.dut.logic_rst.value = 1
self.dut.rx_rst.value = 1
self.dut.tx_rst.value = 1
self.dut.ptp_rst.value = 1
self.dut.stat_rst.value = 1
await RisingEdge(self.dut.logic_clk)
await RisingEdge(self.dut.logic_clk)
self.dut.logic_rst.value = 0
self.dut.rx_rst.value = 0
self.dut.tx_rst.value = 0
self.dut.ptp_rst.value = 0
self.dut.stat_rst.value = 0
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):
@@ -142,9 +160,9 @@ async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
await RisingEdge(dut.rx_clk)
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)
for k in range(1000):
for k in range(2000):
await RisingEdge(dut.rx_clk)
# 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 frame_error == 0
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()
@@ -205,9 +226,9 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
await tb.reset()
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)
for k in range(1000):
for k in range(2000):
await RisingEdge(dut.tx_clk)
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.ctrl 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()
@@ -269,9 +293,9 @@ async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12):
await tb.reset()
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)
for k in range(1000):
for k in range(2000):
await RisingEdge(dut.tx_clk)
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.ctrl 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)
@@ -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['MIN_FRAME_LEN'] = 64
parameters['PTP_TS_EN'] = 1
parameters['PTP_TD_EN'] = parameters['PTP_TS_EN']
parameters['PTP_TS_FMT_TOD'] = 1
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['BIT_REVERSE'] = 0
parameters['SCRAMBLER_DISABLE'] = 0

View File

@@ -27,8 +27,10 @@ module test_taxi_eth_mac_phy_10g_fifo #
parameter logic DIC_EN = 1'b1,
parameter MIN_FRAME_LEN = 64,
parameter logic PTP_TS_EN = 1'b0,
parameter logic PTP_TD_EN = PTP_TS_EN,
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter TX_TAG_W = 16,
parameter logic BIT_REVERSE = 1'b0,
parameter logic SCRAMBLER_DISABLE = 1'b0,
@@ -71,7 +73,6 @@ logic tx_clk;
logic tx_rst;
logic logic_clk;
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(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_reset_req;
logic [PTP_TS_W-1:0] ptp_ts;
logic ptp_ts_step;
logic ptp_clk;
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_rst;
@@ -130,8 +141,10 @@ taxi_eth_mac_phy_10g_fifo #(
.DIC_EN(DIC_EN),
.MIN_FRAME_LEN(MIN_FRAME_LEN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TD_EN(PTP_TD_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W),
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
.BIT_REVERSE(BIT_REVERSE),
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE),
.PRBS31_EN(PRBS31_EN),
@@ -168,7 +181,6 @@ uut (
.tx_rst(tx_rst),
.logic_clk(logic_clk),
.logic_rst(logic_rst),
.ptp_sample_clk(ptp_sample_clk),
/*
* Transmit interface (AXI stream)
@@ -201,8 +213,18 @@ uut (
/*
* PTP clock
*/
.ptp_ts(ptp_ts),
.ptp_ts_step(ptp_ts_step),
.ptp_clk(ptp_clk),
.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