eth: Add gearbox delay compensation for BASE-R TX

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich
2026-08-24 16:02:47 -07:00
parent 2f2fe72848
commit f19a6a8439
26 changed files with 1110 additions and 620 deletions

View File

@@ -25,67 +25,71 @@ module taxi_axis_baser_tx_32 #
parameter logic DIC_EN = 1'b1,
parameter logic PTP_TS_EN = 1'b0,
parameter PTP_TS_W = 96,
parameter logic PTP_TS_COR_EN = PTP_TS_EN && GBX_IF_EN,
parameter PTP_TS_COR_W = 16+4,
parameter logic TX_CPL_CTRL_IN_TUSER = 1'b1
)
(
input wire logic clk,
input wire logic rst,
input wire logic clk,
input wire logic rst,
/*
* Transmit interface (AXI stream)
*/
taxi_axis_if.snk s_axis_tx,
taxi_axis_if.src m_axis_tx_cpl,
taxi_axis_if.snk s_axis_tx,
taxi_axis_if.src m_axis_tx_cpl,
/*
* 10GBASE-R encoded interface
*/
output wire logic [DATA_W-1:0] encoded_tx_data,
output wire logic encoded_tx_data_valid,
output wire logic [HDR_W-1:0] encoded_tx_hdr,
output wire logic encoded_tx_hdr_valid,
input wire logic [GBX_CNT-1:0] tx_gbx_req_sync = '0,
input wire logic tx_gbx_req_stall = '0,
output wire logic [GBX_CNT-1:0] tx_gbx_sync,
output wire logic [DATA_W-1:0] encoded_tx_data,
output wire logic encoded_tx_data_valid,
output wire logic [HDR_W-1:0] encoded_tx_hdr,
output wire logic encoded_tx_hdr_valid,
input wire logic [GBX_CNT-1:0] tx_gbx_req_sync = '0,
input wire logic tx_gbx_req_stall = '0,
output wire logic [GBX_CNT-1:0] tx_gbx_sync,
/*
* Ordered sets
*/
input wire logic [23:0] tx_os = '0,
input wire logic tx_os_sig = 1'b0,
input wire logic tx_os_valid = 1'b0,
output wire logic tx_os_ready,
input wire logic [23:0] tx_os = '0,
input wire logic tx_os_sig = 1'b0,
input wire logic tx_os_valid = 1'b0,
output wire logic tx_os_ready,
/*
* PTP
*/
input wire logic [PTP_TS_W-1:0] ptp_ts,
input wire logic [PTP_TS_W-1:0] ptp_ts,
output wire logic ptp_ts_cor_sync,
input wire logic [PTP_TS_COR_W-1:0] ptp_ts_cor_val = '0,
/*
* Configuration
*/
input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1,
input wire logic [7:0] cfg_tx_ifg = 8'd12,
input wire logic cfg_tx_enable,
input wire logic cfg_tx_usxgmii_en = 1'b1,
input wire logic cfg_tx_usxgmii_5g = 1'b0,
input wire logic [2:0] cfg_tx_usxgmii_speed = 3'b011,
input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1,
input wire logic [7:0] cfg_tx_ifg = 8'd12,
input wire logic cfg_tx_enable,
input wire logic cfg_tx_usxgmii_en = 1'b1,
input wire logic cfg_tx_usxgmii_5g = 1'b0,
input wire logic [2:0] cfg_tx_usxgmii_speed = 3'b011,
/*
* Status
*/
output wire logic tx_start_packet,
output wire logic [2:0] stat_tx_byte,
output wire logic [15:0] stat_tx_pkt_len,
output wire logic stat_tx_pkt_ucast,
output wire logic stat_tx_pkt_mcast,
output wire logic stat_tx_pkt_bcast,
output wire logic stat_tx_pkt_vlan,
output wire logic stat_tx_pkt_good,
output wire logic stat_tx_pkt_bad,
output wire logic stat_tx_err_oversize,
output wire logic stat_tx_err_user,
output wire logic stat_tx_err_underflow
output wire logic tx_start_packet,
output wire logic [2:0] stat_tx_byte,
output wire logic [15:0] stat_tx_pkt_len,
output wire logic stat_tx_pkt_ucast,
output wire logic stat_tx_pkt_mcast,
output wire logic stat_tx_pkt_bcast,
output wire logic stat_tx_pkt_vlan,
output wire logic stat_tx_pkt_good,
output wire logic stat_tx_pkt_bad,
output wire logic stat_tx_err_oversize,
output wire logic stat_tx_err_user,
output wire logic stat_tx_err_underflow
);
// extract parameters
@@ -210,9 +214,9 @@ logic rep_stall_reg = 1'b0;
logic s_axis_tx_tready_reg = 1'b0, s_axis_tx_tready_next;
logic [PTP_TS_W-1:0] m_axis_tx_cpl_ts_reg = '0, m_axis_tx_cpl_ts_next;
logic [PTP_TS_W-1:0] m_axis_tx_cpl_ts_reg = '0;
logic [TX_TAG_W-1:0] m_axis_tx_cpl_tag_reg = '0, m_axis_tx_cpl_tag_next;
logic m_axis_tx_cpl_valid_reg = 1'b0, m_axis_tx_cpl_valid_next;
logic m_axis_tx_cpl_valid_reg = 1'b0;
logic tx_os_ready_reg = 1'b0;
@@ -243,6 +247,10 @@ logic stat_tx_err_oversize_reg = 1'b0, stat_tx_err_oversize_next;
logic stat_tx_err_user_reg = 1'b0, stat_tx_err_user_next;
logic stat_tx_err_underflow_reg = 1'b0, stat_tx_err_underflow_next;
logic [4+16-1:0] last_ts_reg = '0;
logic [4+16-1:0] ts_inc_reg = '0;
logic gbx_en_reg = 1'b0;
assign s_axis_tx.tready = s_axis_tx_tready_reg && (!GBX_IF_EN || !tx_gbx_req_stall) && (!USXGMII_EN || !rep_stall_reg);
assign encoded_tx_data = encoded_tx_data_reg;
@@ -262,6 +270,8 @@ assign m_axis_tx_cpl.tuser = '0;
assign tx_os_ready = tx_os_ready_reg;
assign ptp_ts_cor_sync = (GBX_IF_EN && PTP_TS_COR_EN) ? tx_gbx_req_sync : 1'b0;
assign tx_start_packet = start_packet_reg;
assign stat_tx_byte = stat_tx_byte_reg;
@@ -371,20 +381,7 @@ always_comb begin
crc_data_next = crc_data_reg;
m_axis_tx_cpl_ts_next = m_axis_tx_cpl_ts_reg;
m_axis_tx_cpl_tag_next = m_axis_tx_cpl_tag_reg;
m_axis_tx_cpl_valid_next = 1'b0;
if (start_packet_reg) begin
if (PTP_TS_EN) begin
m_axis_tx_cpl_ts_next = ptp_ts;
end
if (TX_CPL_CTRL_IN_TUSER) begin
m_axis_tx_cpl_valid_next = (s_axis_tx.tuser >> 1) == 0;
end else begin
m_axis_tx_cpl_valid_next = 1'b1;
end
end
output_data_next = output_data_reg;
output_type_next = output_type_reg;
@@ -733,14 +730,15 @@ always_ff @(posedge clk) begin
s_axis_tx_tready_reg <= s_axis_tx_tready_next;
m_axis_tx_cpl_ts_reg <= m_axis_tx_cpl_ts_next;
m_axis_tx_cpl_tag_reg <= m_axis_tx_cpl_tag_next;
m_axis_tx_cpl_valid_reg <= m_axis_tx_cpl_valid_next;
m_axis_tx_cpl_valid_reg <= 1'b0;
tx_os_ready_reg <= 1'b0;
start_packet_int_reg <= start_packet_int_next;
start_packet_reg <= 1'b0;
stat_tx_byte_reg <= stat_tx_byte_next;
stat_tx_pkt_len_reg <= stat_tx_pkt_len_next;
stat_tx_pkt_ucast_reg <= stat_tx_pkt_ucast_next;
@@ -763,7 +761,17 @@ always_ff @(posedge clk) begin
output_start_packet_reg <= output_start_packet_next;
output_data_d1_reg <= output_data_reg;
start_packet_reg <= output_start_packet_reg;
if (output_start_packet_reg) begin
start_packet_reg <= 1'b1;
if (PTP_TS_EN) begin
m_axis_tx_cpl_ts_reg <= ptp_ts + (PTP_TS_COR_EN ? PTP_TS_W'(ptp_ts_cor_val) + (GBX_IF_EN && gbx_en_reg && phase_reg == 1 ? PTP_TS_W'(ts_inc_reg >> 5) : '0) : '0);
end
if (TX_CPL_CTRL_IN_TUSER) begin
m_axis_tx_cpl_valid_reg <= (s_axis_tx.tuser >> 1) == 0;
end else begin
m_axis_tx_cpl_valid_reg <= 1'b1;
end
end
if (phase_reg == 0) begin
case ({output_type_reg, output_type_next})
@@ -920,6 +928,13 @@ always_ff @(posedge clk) begin
tx_gbx_sync_reg <= tx_gbx_req_sync;
last_ts_reg <= (4+16)'(ptp_ts);
ts_inc_reg <= (4+16)'(ptp_ts) - last_ts_reg;
if (tx_gbx_req_sync || tx_gbx_req_stall) begin
gbx_en_reg <= 1'b1;
end
if (rst) begin
state_reg <= STATE_IDLE;
@@ -942,6 +957,8 @@ always_ff @(posedge clk) begin
phase_reg <= 1'b0;
tx_gbx_sync_reg <= '0;
gbx_en_reg <= 1'b0;
output_type_reg <= OUT_TYPE_IDLE;
output_start_packet_reg <= 1'b0;

View File

@@ -26,67 +26,71 @@ module taxi_axis_baser_tx_64 #
parameter logic PTP_TS_EN = 1'b0,
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter logic PTP_TS_COR_EN = PTP_TS_EN && GBX_IF_EN,
parameter PTP_TS_COR_W = 16+4,
parameter logic TX_CPL_CTRL_IN_TUSER = 1'b1
)
(
input wire logic clk,
input wire logic rst,
input wire logic clk,
input wire logic rst,
/*
* Transmit interface (AXI stream)
*/
taxi_axis_if.snk s_axis_tx,
taxi_axis_if.src m_axis_tx_cpl,
taxi_axis_if.snk s_axis_tx,
taxi_axis_if.src m_axis_tx_cpl,
/*
* 10GBASE-R encoded interface
*/
output wire logic [DATA_W-1:0] encoded_tx_data,
output wire logic encoded_tx_data_valid,
output wire logic [HDR_W-1:0] encoded_tx_hdr,
output wire logic encoded_tx_hdr_valid,
input wire logic [GBX_CNT-1:0] tx_gbx_req_sync = '0,
input wire logic tx_gbx_req_stall = '0,
output wire logic [GBX_CNT-1:0] tx_gbx_sync,
output wire logic [DATA_W-1:0] encoded_tx_data,
output wire logic encoded_tx_data_valid,
output wire logic [HDR_W-1:0] encoded_tx_hdr,
output wire logic encoded_tx_hdr_valid,
input wire logic [GBX_CNT-1:0] tx_gbx_req_sync = '0,
input wire logic tx_gbx_req_stall = '0,
output wire logic [GBX_CNT-1:0] tx_gbx_sync,
/*
* Ordered sets
*/
input wire logic [23:0] tx_os = '0,
input wire logic tx_os_sig = 1'b0,
input wire logic tx_os_valid = 1'b0,
output wire logic tx_os_ready,
input wire logic [23:0] tx_os = '0,
input wire logic tx_os_sig = 1'b0,
input wire logic tx_os_valid = 1'b0,
output wire logic tx_os_ready,
/*
* PTP
*/
input wire logic [PTP_TS_W-1:0] ptp_ts,
input wire logic [PTP_TS_W-1:0] ptp_ts,
output wire logic ptp_ts_cor_sync,
input wire logic [PTP_TS_COR_W-1:0] ptp_ts_cor_val = '0,
/*
* Configuration
*/
input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1,
input wire logic [7:0] cfg_tx_ifg = 8'd12,
input wire logic cfg_tx_enable,
input wire logic cfg_tx_usxgmii_en = 1'b1,
input wire logic cfg_tx_usxgmii_5g = 1'b0,
input wire logic [2:0] cfg_tx_usxgmii_speed = 3'b011,
input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1,
input wire logic [7:0] cfg_tx_ifg = 8'd12,
input wire logic cfg_tx_enable,
input wire logic cfg_tx_usxgmii_en = 1'b1,
input wire logic cfg_tx_usxgmii_5g = 1'b0,
input wire logic [2:0] cfg_tx_usxgmii_speed = 3'b011,
/*
* Status
*/
output wire logic [1:0] tx_start_packet,
output wire logic [3:0] stat_tx_byte,
output wire logic [15:0] stat_tx_pkt_len,
output wire logic stat_tx_pkt_ucast,
output wire logic stat_tx_pkt_mcast,
output wire logic stat_tx_pkt_bcast,
output wire logic stat_tx_pkt_vlan,
output wire logic stat_tx_pkt_good,
output wire logic stat_tx_pkt_bad,
output wire logic stat_tx_err_oversize,
output wire logic stat_tx_err_user,
output wire logic stat_tx_err_underflow
output wire logic [1:0] tx_start_packet,
output wire logic [3:0] stat_tx_byte,
output wire logic [15:0] stat_tx_pkt_len,
output wire logic stat_tx_pkt_ucast,
output wire logic stat_tx_pkt_mcast,
output wire logic stat_tx_pkt_bcast,
output wire logic stat_tx_pkt_vlan,
output wire logic stat_tx_pkt_good,
output wire logic stat_tx_pkt_bad,
output wire logic stat_tx_err_oversize,
output wire logic stat_tx_err_user,
output wire logic stat_tx_err_underflow
);
// extract parameters
@@ -260,6 +264,8 @@ logic stat_tx_err_underflow_reg = 1'b0, stat_tx_err_underflow_next;
logic [4+16-1:0] last_ts_reg = '0;
logic [4+16-1:0] ts_inc_reg = '0;
logic [4+16-1:0] ts_offs_reg = '0;
logic gbx_en_reg = 1'b0;
assign s_axis_tx.tready = s_axis_tx_tready_reg && (!GBX_IF_EN || !tx_gbx_req_stall) && (!USXGMII_EN || !rep_stall_reg);
@@ -280,6 +286,8 @@ assign m_axis_tx_cpl.tuser = '0;
assign tx_os_ready = tx_os_ready_reg;
assign ptp_ts_cor_sync = (GBX_IF_EN && PTP_TS_COR_EN) ? tx_gbx_req_sync : 1'b0;
assign tx_start_packet = start_packet_reg;
assign stat_tx_byte = stat_tx_byte_reg;
@@ -1073,16 +1081,16 @@ always_ff @(posedge clk) 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] + (GBX_IF_EN ? 46'(ts_offs_reg) : 46'(ts_inc_reg >> 1)) + (PTP_TS_COR_EN ? 46'(ptp_ts_cor_val) : '0);
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);
m_axis_tx_cpl_ts_reg <= ptp_ts + (GBX_IF_EN ? PTP_TS_W'(ts_offs_reg) : PTP_TS_W'(ts_inc_reg >> 1)) + (PTP_TS_COR_EN ? PTP_TS_W'(ptp_ts_cor_val) : '0);
end
end
end else if (output_start_packet_remap[0]) begin
if (PTP_TS_EN) begin
m_axis_tx_cpl_ts_reg <= ptp_ts;
m_axis_tx_cpl_ts_reg <= ptp_ts + (PTP_TS_COR_EN ? PTP_TS_W'(ptp_ts_cor_val) : '0);
end
end
if (output_start_packet_remap != 0) begin
@@ -1176,6 +1184,11 @@ always_ff @(posedge clk) begin
last_ts_reg <= (4+16)'(ptp_ts);
ts_inc_reg <= (4+16)'(ptp_ts) - last_ts_reg;
ts_offs_reg <= (ts_inc_reg >> 1) + (gbx_en_reg ? ts_inc_reg >> 6 : '0);
if (tx_gbx_req_sync || tx_gbx_req_stall) begin
gbx_en_reg <= 1'b1;
end
if (rst) begin
state_reg <= STATE_IDLE;
@@ -1205,6 +1218,8 @@ always_ff @(posedge clk) begin
encoded_tx_hdr_valid_reg <= 1'b0;
tx_gbx_sync_reg <= '0;
gbx_en_reg <= 1'b0;
output_data_reg <= '0;
output_type_reg <= OUT_TYPE_IDLE;
output_start_packet_reg <= 1'b0;

View File

@@ -28,6 +28,8 @@ module taxi_eth_mac_phy_10g #
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_FNS_W = 16,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter logic PTP_TS_COR_EN = PTP_TS_EN && (TX_GBX_IF_EN || RX_GBX_IF_EN),
parameter PTP_TS_COR_W = PTP_TS_FNS_W+4,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter logic BIT_REVERSE = 1'b0,
parameter logic SCRAMBLER_DISABLE = 1'b0,
@@ -48,207 +50,211 @@ module taxi_eth_mac_phy_10g #
parameter logic [8*8-1:0] STAT_PREFIX_STR = "MAC"
)
(
input wire logic rx_clk,
input wire logic rx_rst,
input wire logic tx_clk,
input wire logic tx_rst,
input wire logic rx_clk,
input wire logic rx_rst,
input wire logic tx_clk,
input wire logic tx_rst,
/*
* Transmit interface (AXI stream)
*/
taxi_axis_if.snk s_axis_tx,
taxi_axis_if.src m_axis_tx_cpl,
taxi_axis_if.snk s_axis_tx,
taxi_axis_if.src m_axis_tx_cpl,
/*
* Receive interface (AXI stream)
*/
taxi_axis_if.src m_axis_rx,
taxi_axis_if.src m_axis_rx,
/*
* SERDES interface
*/
output wire logic [DATA_W-1:0] serdes_tx_data,
output wire logic serdes_tx_data_valid,
output wire logic [HDR_W-1:0] serdes_tx_hdr,
output wire logic serdes_tx_hdr_valid,
input wire logic serdes_tx_gbx_req_sync = 1'b0,
input wire logic serdes_tx_gbx_req_stall = 1'b0,
output wire logic serdes_tx_gbx_sync,
input wire logic [DATA_W-1:0] serdes_rx_data,
input wire logic serdes_rx_data_valid = 1'b1,
input wire logic [HDR_W-1:0] serdes_rx_hdr,
input wire logic serdes_rx_hdr_valid = 1'b1,
output wire logic serdes_rx_bitslip,
output wire logic serdes_rx_reset_req,
output wire logic [DATA_W-1:0] serdes_tx_data,
output wire logic serdes_tx_data_valid,
output wire logic [HDR_W-1:0] serdes_tx_hdr,
output wire logic serdes_tx_hdr_valid,
input wire logic serdes_tx_gbx_req_sync = 1'b0,
input wire logic serdes_tx_gbx_req_stall = 1'b0,
output wire logic serdes_tx_gbx_sync,
input wire logic [DATA_W-1:0] serdes_rx_data,
input wire logic serdes_rx_data_valid = 1'b1,
input wire logic [HDR_W-1:0] serdes_rx_hdr,
input wire logic serdes_rx_hdr_valid = 1'b1,
output wire logic serdes_rx_bitslip,
output wire logic serdes_rx_reset_req,
/*
* USXGMII autonegotiation
*/
input wire logic an_en = 1'b1,
input wire logic an_restart = 1'b0,
input wire logic an_speedup = 1'b0,
input wire logic an_timeout_en = 1'b1,
input wire logic an_usxgmii_en = 1'b0,
input wire logic an_usxgmii_auto = 1'b1,
input wire logic an_usxgmii_5g = 1'b0,
output wire logic an_intr,
output wire logic an_running,
output wire logic an_complete,
output wire logic an_timeout,
output wire logic an_usxgmii_mode,
input wire logic [15:0] an_adv_ability_usxgmii = 16'h1601,
output wire logic [15:0] an_lp_adv_ability,
output wire logic an_lp_usxgmii_link,
output wire logic [2:0] an_lp_usxgmii_speed,
output wire logic an_res_full_duplex,
input wire logic an_en = 1'b1,
input wire logic an_restart = 1'b0,
input wire logic an_speedup = 1'b0,
input wire logic an_timeout_en = 1'b1,
input wire logic an_usxgmii_en = 1'b0,
input wire logic an_usxgmii_auto = 1'b1,
input wire logic an_usxgmii_5g = 1'b0,
output wire logic an_intr,
output wire logic an_running,
output wire logic an_complete,
output wire logic an_timeout,
output wire logic an_usxgmii_mode,
input wire logic [15:0] an_adv_ability_usxgmii = 16'h1601,
output wire logic [15:0] an_lp_adv_ability,
output wire logic an_lp_usxgmii_link,
output wire logic [2:0] an_lp_usxgmii_speed,
output wire logic an_res_full_duplex,
/*
* 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,
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,
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,
output wire logic tx_ptp_ts_cor_sync,
input wire logic [PTP_TS_COR_W-1:0] tx_ptp_ts_cor_val = '0,
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,
output wire logic rx_ptp_ts_cor_sync,
input wire logic [PTP_TS_COR_W-1:0] rx_ptp_ts_cor_val = '0,
/*
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
*/
input wire logic tx_lfc_req = 1'b0,
input wire logic tx_lfc_resend = 1'b0,
input wire logic rx_lfc_en = 1'b0,
output wire logic rx_lfc_req,
input wire logic rx_lfc_ack = 1'b0,
input wire logic tx_lfc_req = 1'b0,
input wire logic tx_lfc_resend = 1'b0,
input wire logic rx_lfc_en = 1'b0,
output wire logic rx_lfc_req,
input wire logic rx_lfc_ack = 1'b0,
/*
* Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC)
*/
input wire logic [7:0] tx_pfc_req = '0,
input wire logic tx_pfc_resend = 1'b0,
input wire logic [7:0] rx_pfc_en = '0,
output wire logic [7:0] rx_pfc_req,
input wire logic [7:0] rx_pfc_ack = '0,
input wire logic [7:0] tx_pfc_req = '0,
input wire logic tx_pfc_resend = 1'b0,
input wire logic [7:0] rx_pfc_en = '0,
output wire logic [7:0] rx_pfc_req,
input wire logic [7:0] rx_pfc_ack = '0,
/*
* Pause interface
*/
input wire logic tx_lfc_pause_en = 1'b0,
input wire logic tx_pause_req = 1'b0,
output wire logic tx_pause_ack,
input wire logic tx_lfc_pause_en = 1'b0,
input wire logic tx_pause_req = 1'b0,
output wire logic tx_pause_ack,
/*
* Statistics
*/
input wire logic stat_clk,
input wire logic stat_rst,
taxi_axis_if.src m_axis_stat,
input wire logic stat_clk,
input wire logic stat_rst,
taxi_axis_if.src m_axis_stat,
/*
* Status
*/
output wire logic [1:0] tx_start_packet,
output wire logic [3:0] stat_tx_byte,
output wire logic [15:0] stat_tx_pkt_len,
output wire logic stat_tx_pkt_ucast,
output wire logic stat_tx_pkt_mcast,
output wire logic stat_tx_pkt_bcast,
output wire logic stat_tx_pkt_vlan,
output wire logic stat_tx_pkt_good,
output wire logic stat_tx_pkt_bad,
output wire logic stat_tx_pad_frame,
output wire logic stat_tx_err_oversize,
output wire logic stat_tx_err_user,
output wire logic stat_tx_err_underflow,
output wire logic [1:0] rx_start_packet,
output wire logic [6:0] rx_error_count,
output wire logic rx_block_lock,
output wire logic rx_high_ber,
output wire logic rx_status,
output wire logic [3:0] stat_rx_byte,
output wire logic [15:0] stat_rx_pkt_len,
output wire logic stat_rx_pkt_fragment,
output wire logic stat_rx_pkt_jabber,
output wire logic stat_rx_pkt_ucast,
output wire logic stat_rx_pkt_mcast,
output wire logic stat_rx_pkt_bcast,
output wire logic stat_rx_pkt_vlan,
output wire logic stat_rx_pkt_good,
output wire logic stat_rx_pkt_bad,
output wire logic stat_rx_err_oversize,
output wire logic stat_rx_err_bad_fcs,
output wire logic stat_rx_err_bad_block,
output wire logic stat_rx_err_framing,
output wire logic stat_rx_err_preamble,
input wire logic stat_rx_fifo_drop = 1'b0,
output wire logic stat_tx_mcf,
output wire logic stat_rx_mcf,
output wire logic stat_tx_lfc_pkt,
output wire logic stat_tx_lfc_xon,
output wire logic stat_tx_lfc_xoff,
output wire logic stat_tx_lfc_paused,
output wire logic stat_tx_pfc_pkt,
output wire logic [7:0] stat_tx_pfc_xon,
output wire logic [7:0] stat_tx_pfc_xoff,
output wire logic [7:0] stat_tx_pfc_paused,
output wire logic stat_rx_lfc_pkt,
output wire logic stat_rx_lfc_xon,
output wire logic stat_rx_lfc_xoff,
output wire logic stat_rx_lfc_paused,
output wire logic stat_rx_pfc_pkt,
output wire logic [7:0] stat_rx_pfc_xon,
output wire logic [7:0] stat_rx_pfc_xoff,
output wire logic [7:0] stat_rx_pfc_paused,
output wire logic [1:0] tx_start_packet,
output wire logic [3:0] stat_tx_byte,
output wire logic [15:0] stat_tx_pkt_len,
output wire logic stat_tx_pkt_ucast,
output wire logic stat_tx_pkt_mcast,
output wire logic stat_tx_pkt_bcast,
output wire logic stat_tx_pkt_vlan,
output wire logic stat_tx_pkt_good,
output wire logic stat_tx_pkt_bad,
output wire logic stat_tx_pad_frame,
output wire logic stat_tx_err_oversize,
output wire logic stat_tx_err_user,
output wire logic stat_tx_err_underflow,
output wire logic [1:0] rx_start_packet,
output wire logic [6:0] rx_error_count,
output wire logic rx_block_lock,
output wire logic rx_high_ber,
output wire logic rx_status,
output wire logic [3:0] stat_rx_byte,
output wire logic [15:0] stat_rx_pkt_len,
output wire logic stat_rx_pkt_fragment,
output wire logic stat_rx_pkt_jabber,
output wire logic stat_rx_pkt_ucast,
output wire logic stat_rx_pkt_mcast,
output wire logic stat_rx_pkt_bcast,
output wire logic stat_rx_pkt_vlan,
output wire logic stat_rx_pkt_good,
output wire logic stat_rx_pkt_bad,
output wire logic stat_rx_err_oversize,
output wire logic stat_rx_err_bad_fcs,
output wire logic stat_rx_err_bad_block,
output wire logic stat_rx_err_framing,
output wire logic stat_rx_err_preamble,
input wire logic stat_rx_fifo_drop = 1'b0,
output wire logic stat_tx_mcf,
output wire logic stat_rx_mcf,
output wire logic stat_tx_lfc_pkt,
output wire logic stat_tx_lfc_xon,
output wire logic stat_tx_lfc_xoff,
output wire logic stat_tx_lfc_paused,
output wire logic stat_tx_pfc_pkt,
output wire logic [7:0] stat_tx_pfc_xon,
output wire logic [7:0] stat_tx_pfc_xoff,
output wire logic [7:0] stat_tx_pfc_paused,
output wire logic stat_rx_lfc_pkt,
output wire logic stat_rx_lfc_xon,
output wire logic stat_rx_lfc_xoff,
output wire logic stat_rx_lfc_paused,
output wire logic stat_rx_pfc_pkt,
output wire logic [7:0] stat_rx_pfc_xon,
output wire logic [7:0] stat_rx_pfc_xoff,
output wire logic [7:0] stat_rx_pfc_paused,
/*
* Configuration
*/
input wire logic cfg_tx_pad_en = 1'b1,
input wire logic [7:0] cfg_tx_min_pkt_len = 8'd60-1,
input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1,
input wire logic [7:0] cfg_tx_ifg = 8'd12,
input wire logic cfg_tx_enable = 1'b1,
input wire logic [15:0] cfg_rx_max_pkt_len = 16'd1518-1,
input wire logic cfg_rx_enable = 1'b1,
input wire logic cfg_tx_prbs31_enable = 1'b0,
input wire logic cfg_rx_prbs31_enable = 1'b0,
input wire logic [47:0] cfg_mcf_rx_eth_dst_mcast = 48'h01_80_C2_00_00_01,
input wire logic cfg_mcf_rx_check_eth_dst_mcast = 1'b1,
input wire logic [47:0] cfg_mcf_rx_eth_dst_ucast = 48'd0,
input wire logic cfg_mcf_rx_check_eth_dst_ucast = 1'b0,
input wire logic [47:0] cfg_mcf_rx_eth_src = 48'd0,
input wire logic cfg_mcf_rx_check_eth_src = 1'b0,
input wire logic [15:0] cfg_mcf_rx_eth_type = 16'h8808,
input wire logic [15:0] cfg_mcf_rx_opcode_lfc = 16'h0001,
input wire logic cfg_mcf_rx_check_opcode_lfc = 1'b1,
input wire logic [15:0] cfg_mcf_rx_opcode_pfc = 16'h0101,
input wire logic cfg_mcf_rx_check_opcode_pfc = 1'b1,
input wire logic cfg_mcf_rx_forward = 1'b0,
input wire logic cfg_mcf_rx_enable = 1'b0,
input wire logic [47:0] cfg_tx_lfc_eth_dst = 48'h01_80_C2_00_00_01,
input wire logic [47:0] cfg_tx_lfc_eth_src = 48'h80_23_31_43_54_4C,
input wire logic [15:0] cfg_tx_lfc_eth_type = 16'h8808,
input wire logic [15:0] cfg_tx_lfc_opcode = 16'h0001,
input wire logic cfg_tx_lfc_en = 1'b0,
input wire logic [15:0] cfg_tx_lfc_quanta = 16'hffff,
input wire logic [15:0] cfg_tx_lfc_refresh = 16'h7fff,
input wire logic [47:0] cfg_tx_pfc_eth_dst = 48'h01_80_C2_00_00_01,
input wire logic [47:0] cfg_tx_pfc_eth_src = 48'h80_23_31_43_54_4C,
input wire logic [15:0] cfg_tx_pfc_eth_type = 16'h8808,
input wire logic [15:0] cfg_tx_pfc_opcode = 16'h0101,
input wire logic cfg_tx_pfc_en = 1'b0,
input wire logic [15:0] cfg_tx_pfc_quanta[8] = '{8{16'hffff}},
input wire logic [15:0] cfg_tx_pfc_refresh[8] = '{8{16'h7fff}},
input wire logic [15:0] cfg_rx_lfc_opcode = 16'h0001,
input wire logic cfg_rx_lfc_en = 1'b0,
input wire logic [15:0] cfg_rx_pfc_opcode = 16'h0101,
input wire logic cfg_rx_pfc_en = 1'b0
input wire logic cfg_tx_pad_en = 1'b1,
input wire logic [7:0] cfg_tx_min_pkt_len = 8'd60-1,
input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1,
input wire logic [7:0] cfg_tx_ifg = 8'd12,
input wire logic cfg_tx_enable = 1'b1,
input wire logic [15:0] cfg_rx_max_pkt_len = 16'd1518-1,
input wire logic cfg_rx_enable = 1'b1,
input wire logic cfg_tx_prbs31_enable = 1'b0,
input wire logic cfg_rx_prbs31_enable = 1'b0,
input wire logic [47:0] cfg_mcf_rx_eth_dst_mcast = 48'h01_80_C2_00_00_01,
input wire logic cfg_mcf_rx_check_eth_dst_mcast = 1'b1,
input wire logic [47:0] cfg_mcf_rx_eth_dst_ucast = 48'd0,
input wire logic cfg_mcf_rx_check_eth_dst_ucast = 1'b0,
input wire logic [47:0] cfg_mcf_rx_eth_src = 48'd0,
input wire logic cfg_mcf_rx_check_eth_src = 1'b0,
input wire logic [15:0] cfg_mcf_rx_eth_type = 16'h8808,
input wire logic [15:0] cfg_mcf_rx_opcode_lfc = 16'h0001,
input wire logic cfg_mcf_rx_check_opcode_lfc = 1'b1,
input wire logic [15:0] cfg_mcf_rx_opcode_pfc = 16'h0101,
input wire logic cfg_mcf_rx_check_opcode_pfc = 1'b1,
input wire logic cfg_mcf_rx_forward = 1'b0,
input wire logic cfg_mcf_rx_enable = 1'b0,
input wire logic [47:0] cfg_tx_lfc_eth_dst = 48'h01_80_C2_00_00_01,
input wire logic [47:0] cfg_tx_lfc_eth_src = 48'h80_23_31_43_54_4C,
input wire logic [15:0] cfg_tx_lfc_eth_type = 16'h8808,
input wire logic [15:0] cfg_tx_lfc_opcode = 16'h0001,
input wire logic cfg_tx_lfc_en = 1'b0,
input wire logic [15:0] cfg_tx_lfc_quanta = 16'hffff,
input wire logic [15:0] cfg_tx_lfc_refresh = 16'h7fff,
input wire logic [47:0] cfg_tx_pfc_eth_dst = 48'h01_80_C2_00_00_01,
input wire logic [47:0] cfg_tx_pfc_eth_src = 48'h80_23_31_43_54_4C,
input wire logic [15:0] cfg_tx_pfc_eth_type = 16'h8808,
input wire logic [15:0] cfg_tx_pfc_opcode = 16'h0101,
input wire logic cfg_tx_pfc_en = 1'b0,
input wire logic [15:0] cfg_tx_pfc_quanta[8] = '{8{16'hffff}},
input wire logic [15:0] cfg_tx_pfc_refresh[8] = '{8{16'h7fff}},
input wire logic [15:0] cfg_rx_lfc_opcode = 16'h0001,
input wire logic cfg_rx_lfc_en = 1'b0,
input wire logic [15:0] cfg_rx_pfc_opcode = 16'h0101,
input wire logic cfg_rx_pfc_en = 1'b0
);
localparam KEEP_W = s_axis_tx.KEEP_W;
@@ -525,6 +531,8 @@ taxi_eth_mac_phy_10g_rx #(
.PTP_TS_EN(PTP_TS_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W),
.PTP_TS_COR_EN(PTP_TS_COR_EN),
.PTP_TS_COR_W(PTP_TS_COR_W),
.BIT_REVERSE(BIT_REVERSE),
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE),
.PRBS31_EN(PRBS31_EN),
@@ -565,6 +573,8 @@ eth_mac_phy_10g_rx_inst (
* PTP
*/
.ptp_ts(rx_ptp_ts_out),
.ptp_ts_cor_sync(rx_ptp_ts_cor_sync),
.ptp_ts_cor_val(rx_ptp_ts_cor_val),
/*
* Status
@@ -610,6 +620,8 @@ taxi_eth_mac_phy_10g_tx #(
.PTP_TS_EN(PTP_TS_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W),
.PTP_TS_COR_EN(PTP_TS_COR_EN),
.PTP_TS_COR_W(PTP_TS_COR_W),
.TX_CPL_CTRL_IN_TUSER(MAC_CTRL_EN),
.BIT_REVERSE(BIT_REVERSE),
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE),
@@ -649,6 +661,8 @@ eth_mac_phy_10g_tx_inst (
* PTP
*/
.ptp_ts(tx_ptp_ts_out),
.ptp_ts_cor_sync(tx_ptp_ts_cor_sync),
.ptp_ts_cor_val(tx_ptp_ts_cor_val),
/*
* Status

View File

@@ -28,6 +28,8 @@ module taxi_eth_mac_phy_10g_fifo #
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_FNS_W = 16,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter logic PTP_TS_COR_EN = PTP_TS_EN && (TX_GBX_IF_EN || RX_GBX_IF_EN),
parameter PTP_TS_COR_W = PTP_TS_FNS_W+4,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter logic BIT_REVERSE = 1'b0,
parameter logic SCRAMBLER_DISABLE = 1'b0,
@@ -59,115 +61,119 @@ module taxi_eth_mac_phy_10g_fifo #
parameter logic RX_DROP_WHEN_FULL = RX_DROP_OVERSIZE_FRAME
)
(
input wire logic rx_clk,
input wire logic rx_rst,
input wire logic tx_clk,
input wire logic tx_rst,
input wire logic logic_clk,
input wire logic logic_rst,
input wire logic rx_clk,
input wire logic rx_rst,
input wire logic tx_clk,
input wire logic tx_rst,
input wire logic logic_clk,
input wire logic logic_rst,
/*
* Transmit interface (AXI stream)
*/
taxi_axis_if.snk s_axis_tx,
taxi_axis_if.src m_axis_tx_cpl,
taxi_axis_if.snk s_axis_tx,
taxi_axis_if.src m_axis_tx_cpl,
/*
* Receive interface (AXI stream)
*/
taxi_axis_if.src m_axis_rx,
taxi_axis_if.src m_axis_rx,
/*
* SERDES interface
*/
output wire logic [DATA_W-1:0] serdes_tx_data,
output wire logic serdes_tx_data_valid,
output wire logic [HDR_W-1:0] serdes_tx_hdr,
output wire logic serdes_tx_hdr_valid,
input wire logic serdes_tx_gbx_req_sync = 1'b0,
input wire logic serdes_tx_gbx_req_stall = 1'b0,
output wire logic serdes_tx_gbx_sync,
input wire logic [DATA_W-1:0] serdes_rx_data,
input wire logic serdes_rx_data_valid = 1'b1,
input wire logic [HDR_W-1:0] serdes_rx_hdr,
input wire logic serdes_rx_hdr_valid = 1'b1,
output wire logic serdes_rx_bitslip,
output wire logic serdes_rx_reset_req,
output wire logic [DATA_W-1:0] serdes_tx_data,
output wire logic serdes_tx_data_valid,
output wire logic [HDR_W-1:0] serdes_tx_hdr,
output wire logic serdes_tx_hdr_valid,
input wire logic serdes_tx_gbx_req_sync = 1'b0,
input wire logic serdes_tx_gbx_req_stall = 1'b0,
output wire logic serdes_tx_gbx_sync,
input wire logic [DATA_W-1:0] serdes_rx_data,
input wire logic serdes_rx_data_valid = 1'b1,
input wire logic [HDR_W-1:0] serdes_rx_hdr,
input wire logic serdes_rx_hdr_valid = 1'b1,
output wire logic serdes_rx_bitslip,
output wire logic serdes_rx_reset_req,
/*
* USXGMII autonegotiation
*/
input wire logic an_en = 1'b1,
input wire logic an_restart = 1'b0,
input wire logic an_speedup = 1'b0,
input wire logic an_timeout_en = 1'b1,
input wire logic an_usxgmii_en = 1'b0,
input wire logic an_usxgmii_auto = 1'b1,
input wire logic an_usxgmii_5g = 1'b0,
output wire logic an_intr,
output wire logic an_running,
output wire logic an_complete,
output wire logic an_timeout,
output wire logic an_usxgmii_mode,
input wire logic [15:0] an_adv_ability_usxgmii = 16'h1601,
output wire logic [15:0] an_lp_adv_ability,
output wire logic an_lp_usxgmii_link,
output wire logic [2:0] an_lp_usxgmii_speed,
output wire logic an_res_full_duplex,
input wire logic an_en = 1'b1,
input wire logic an_restart = 1'b0,
input wire logic an_speedup = 1'b0,
input wire logic an_timeout_en = 1'b1,
input wire logic an_usxgmii_en = 1'b0,
input wire logic an_usxgmii_auto = 1'b1,
input wire logic an_usxgmii_5g = 1'b0,
output wire logic an_intr,
output wire logic an_running,
output wire logic an_complete,
output wire logic an_timeout,
output wire logic an_usxgmii_mode,
input wire logic [15:0] an_adv_ability_usxgmii = 16'h1601,
output wire logic [15:0] an_lp_adv_ability,
output wire logic an_lp_usxgmii_link,
output wire logic [2:0] an_lp_usxgmii_speed,
output wire logic an_res_full_duplex,
/*
* PTP clock
*/
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,
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 tx_ptp_ts_cor_sync,
input wire logic [PTP_TS_COR_W-1:0] tx_ptp_ts_cor_val = '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,
output wire logic rx_ptp_ts_cor_sync,
input wire logic [PTP_TS_COR_W-1:0] rx_ptp_ts_cor_val = '0,
/*
* Statistics
*/
input wire logic stat_clk,
input wire logic stat_rst,
taxi_axis_if.src m_axis_stat,
input wire logic stat_clk,
input wire logic stat_rst,
taxi_axis_if.src m_axis_stat,
/*
* Status
*/
output wire logic tx_error_underflow,
output wire logic tx_fifo_overflow,
output wire logic tx_fifo_bad_frame,
output wire logic tx_fifo_good_frame,
output wire logic rx_error_bad_frame,
output wire logic rx_error_bad_fcs,
output wire logic rx_bad_block,
output wire logic rx_sequence_error,
output wire logic rx_block_lock,
output wire logic rx_high_ber,
output wire logic rx_status,
output wire logic rx_fifo_overflow,
output wire logic rx_fifo_bad_frame,
output wire logic rx_fifo_good_frame,
output wire logic tx_error_underflow,
output wire logic tx_fifo_overflow,
output wire logic tx_fifo_bad_frame,
output wire logic tx_fifo_good_frame,
output wire logic rx_error_bad_frame,
output wire logic rx_error_bad_fcs,
output wire logic rx_bad_block,
output wire logic rx_sequence_error,
output wire logic rx_block_lock,
output wire logic rx_high_ber,
output wire logic rx_status,
output wire logic rx_fifo_overflow,
output wire logic rx_fifo_bad_frame,
output wire logic rx_fifo_good_frame,
/*
* Configuration
*/
input wire logic cfg_tx_pad_en = 1'b1,
input wire logic [7:0] cfg_tx_min_pkt_len = 8'd60-1,
input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1,
input wire logic [7:0] cfg_tx_ifg = 8'd12,
input wire logic cfg_tx_enable = 1'b1,
input wire logic [15:0] cfg_rx_max_pkt_len = 16'd1518-1,
input wire logic cfg_rx_enable = 1'b1,
input wire logic cfg_tx_prbs31_enable = 1'b0,
input wire logic cfg_rx_prbs31_enable = 1'b0
input wire logic cfg_tx_pad_en = 1'b1,
input wire logic [7:0] cfg_tx_min_pkt_len = 8'd60-1,
input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1,
input wire logic [7:0] cfg_tx_ifg = 8'd12,
input wire logic cfg_tx_enable = 1'b1,
input wire logic [15:0] cfg_rx_max_pkt_len = 16'd1518-1,
input wire logic cfg_rx_enable = 1'b1,
input wire logic cfg_tx_prbs31_enable = 1'b0,
input wire logic cfg_rx_prbs31_enable = 1'b0
);
localparam KEEP_W = DATA_W/8;
@@ -330,6 +336,8 @@ taxi_eth_mac_phy_10g #(
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_FNS_W(PTP_TS_FNS_W),
.PTP_TS_W(PTP_TS_W),
.PTP_TS_COR_EN(PTP_TS_COR_EN),
.PTP_TS_COR_W(PTP_TS_COR_W),
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
.BIT_REVERSE(BIT_REVERSE),
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE),
@@ -413,10 +421,14 @@ eth_mac_phy_10g_inst (
.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),
.tx_ptp_ts_cor_sync(tx_ptp_ts_cor_sync),
.tx_ptp_ts_cor_val(tx_ptp_ts_cor_val),
.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),
.rx_ptp_ts_cor_sync(rx_ptp_ts_cor_sync),
.rx_ptp_ts_cor_val(rx_ptp_ts_cor_val),
/*
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)

View File

@@ -24,6 +24,8 @@ module taxi_eth_mac_phy_10g_rx #
parameter logic PTP_TS_EN = 1'b0,
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter logic PTP_TS_COR_EN = PTP_TS_EN && GBX_IF_EN,
parameter PTP_TS_COR_W = 16+4,
parameter logic BIT_REVERSE = 1'b0,
parameter logic SCRAMBLER_DISABLE = 1'b0,
parameter logic PRBS31_EN = 1'b0,
@@ -33,71 +35,73 @@ module taxi_eth_mac_phy_10g_rx #
parameter COUNT_125US = 125000/6.4
)
(
input wire logic clk,
input wire logic rst,
input wire logic clk,
input wire logic rst,
/*
* Receive interface (AXI stream)
*/
taxi_axis_if.src m_axis_rx,
taxi_axis_if.src m_axis_rx,
/*
* SERDES interface
*/
input wire logic [DATA_W-1:0] serdes_rx_data,
input wire logic serdes_rx_data_valid = 1'b1,
input wire logic [HDR_W-1:0] serdes_rx_hdr,
input wire logic serdes_rx_hdr_valid = 1'b1,
output wire logic serdes_rx_bitslip,
output wire logic serdes_rx_reset_req,
input wire logic [DATA_W-1:0] serdes_rx_data,
input wire logic serdes_rx_data_valid = 1'b1,
input wire logic [HDR_W-1:0] serdes_rx_hdr,
input wire logic serdes_rx_hdr_valid = 1'b1,
output wire logic serdes_rx_bitslip,
output wire logic serdes_rx_reset_req,
/*
* Ordered sets
*/
output wire logic [23:0] rx_os,
output wire logic rx_os_sig,
output wire logic rx_os_valid,
output wire logic rx_os_match,
output wire logic rx_idle_match,
output wire logic [23:0] rx_os,
output wire logic rx_os_sig,
output wire logic rx_os_valid,
output wire logic rx_os_match,
output wire logic rx_idle_match,
/*
* PTP
*/
input wire logic [PTP_TS_W-1:0] ptp_ts,
input wire logic [PTP_TS_W-1:0] ptp_ts,
output wire logic ptp_ts_cor_sync,
input wire logic [PTP_TS_COR_W-1:0] ptp_ts_cor_val = '0,
/*
* Status
*/
output wire logic [1:0] rx_start_packet,
output wire logic [6:0] rx_error_count,
output wire logic rx_block_lock,
output wire logic rx_high_ber,
output wire logic rx_status,
output wire logic [3:0] stat_rx_byte,
output wire logic [15:0] stat_rx_pkt_len,
output wire logic stat_rx_pkt_fragment,
output wire logic stat_rx_pkt_jabber,
output wire logic stat_rx_pkt_ucast,
output wire logic stat_rx_pkt_mcast,
output wire logic stat_rx_pkt_bcast,
output wire logic stat_rx_pkt_vlan,
output wire logic stat_rx_pkt_good,
output wire logic stat_rx_pkt_bad,
output wire logic stat_rx_err_oversize,
output wire logic stat_rx_err_bad_fcs,
output wire logic stat_rx_err_bad_block,
output wire logic stat_rx_err_framing,
output wire logic stat_rx_err_preamble,
output wire logic [1:0] rx_start_packet,
output wire logic [6:0] rx_error_count,
output wire logic rx_block_lock,
output wire logic rx_high_ber,
output wire logic rx_status,
output wire logic [3:0] stat_rx_byte,
output wire logic [15:0] stat_rx_pkt_len,
output wire logic stat_rx_pkt_fragment,
output wire logic stat_rx_pkt_jabber,
output wire logic stat_rx_pkt_ucast,
output wire logic stat_rx_pkt_mcast,
output wire logic stat_rx_pkt_bcast,
output wire logic stat_rx_pkt_vlan,
output wire logic stat_rx_pkt_good,
output wire logic stat_rx_pkt_bad,
output wire logic stat_rx_err_oversize,
output wire logic stat_rx_err_bad_fcs,
output wire logic stat_rx_err_bad_block,
output wire logic stat_rx_err_framing,
output wire logic stat_rx_err_preamble,
/*
* Configuration
*/
input wire logic [15:0] cfg_rx_max_pkt_len = 16'd1518-1,
input wire logic cfg_rx_enable,
input wire logic cfg_rx_usxgmii_en = 1'b1,
input wire logic cfg_rx_usxgmii_5g = 1'b0,
input wire logic [2:0] cfg_rx_usxgmii_speed = 3'b011,
input wire logic cfg_rx_prbs31_enable
input wire logic [15:0] cfg_rx_max_pkt_len = 16'd1518-1,
input wire logic cfg_rx_enable,
input wire logic cfg_rx_usxgmii_en = 1'b1,
input wire logic cfg_rx_usxgmii_5g = 1'b0,
input wire logic [2:0] cfg_rx_usxgmii_speed = 3'b011,
input wire logic cfg_rx_prbs31_enable
);
wire [DATA_W-1:0] encoded_rx_data;

View File

@@ -25,6 +25,8 @@ module taxi_eth_mac_phy_10g_tx #
parameter logic PTP_TS_EN = 1'b0,
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter logic PTP_TS_COR_EN = PTP_TS_EN && GBX_IF_EN,
parameter PTP_TS_COR_W = 16+4,
parameter logic TX_CPL_CTRL_IN_TUSER = 1'b0,
parameter logic BIT_REVERSE = 1'b0,
parameter logic SCRAMBLER_DISABLE = 1'b0,
@@ -32,68 +34,70 @@ module taxi_eth_mac_phy_10g_tx #
parameter SERDES_PIPELINE = 0
)
(
input wire logic clk,
input wire logic rst,
input wire logic clk,
input wire logic rst,
/*
* Transmit interface (AXI stream)
*/
taxi_axis_if.snk s_axis_tx,
taxi_axis_if.src m_axis_tx_cpl,
taxi_axis_if.snk s_axis_tx,
taxi_axis_if.src m_axis_tx_cpl,
/*
* SERDES interface
*/
output wire logic [DATA_W-1:0] serdes_tx_data,
output wire logic serdes_tx_data_valid,
output wire logic [HDR_W-1:0] serdes_tx_hdr,
output wire logic serdes_tx_hdr_valid,
input wire logic serdes_tx_gbx_req_sync = 1'b0,
input wire logic serdes_tx_gbx_req_stall = 1'b0,
output wire logic serdes_tx_gbx_sync,
output wire logic [DATA_W-1:0] serdes_tx_data,
output wire logic serdes_tx_data_valid,
output wire logic [HDR_W-1:0] serdes_tx_hdr,
output wire logic serdes_tx_hdr_valid,
input wire logic serdes_tx_gbx_req_sync = 1'b0,
input wire logic serdes_tx_gbx_req_stall = 1'b0,
output wire logic serdes_tx_gbx_sync,
/*
* Ordered sets
*/
input wire logic [23:0] tx_os = '0,
input wire logic tx_os_sig = 1'b0,
input wire logic tx_os_valid = 1'b0,
output wire logic tx_os_ready,
input wire logic [23:0] tx_os = '0,
input wire logic tx_os_sig = 1'b0,
input wire logic tx_os_valid = 1'b0,
output wire logic tx_os_ready,
/*
* PTP
*/
input wire logic [PTP_TS_W-1:0] ptp_ts,
input wire logic [PTP_TS_W-1:0] ptp_ts,
output wire logic ptp_ts_cor_sync,
input wire logic [PTP_TS_COR_W-1:0] ptp_ts_cor_val = '0,
/*
* Status
*/
output wire logic [1:0] tx_start_packet,
output wire logic [3:0] stat_tx_byte,
output wire logic [15:0] stat_tx_pkt_len,
output wire logic stat_tx_pkt_ucast,
output wire logic stat_tx_pkt_mcast,
output wire logic stat_tx_pkt_bcast,
output wire logic stat_tx_pkt_vlan,
output wire logic stat_tx_pkt_good,
output wire logic stat_tx_pkt_bad,
output wire logic stat_tx_pad_frame,
output wire logic stat_tx_err_oversize,
output wire logic stat_tx_err_user,
output wire logic stat_tx_err_underflow,
output wire logic [1:0] tx_start_packet,
output wire logic [3:0] stat_tx_byte,
output wire logic [15:0] stat_tx_pkt_len,
output wire logic stat_tx_pkt_ucast,
output wire logic stat_tx_pkt_mcast,
output wire logic stat_tx_pkt_bcast,
output wire logic stat_tx_pkt_vlan,
output wire logic stat_tx_pkt_good,
output wire logic stat_tx_pkt_bad,
output wire logic stat_tx_pad_frame,
output wire logic stat_tx_err_oversize,
output wire logic stat_tx_err_user,
output wire logic stat_tx_err_underflow,
/*
* Configuration
*/
input wire logic cfg_tx_pad_en = 1'b1,
input wire logic [7:0] cfg_tx_min_pkt_len = 8'd60-1,
input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1,
input wire logic [7:0] cfg_tx_ifg = 8'd12,
input wire logic cfg_tx_enable,
input wire logic cfg_tx_usxgmii_en = 1'b1,
input wire logic cfg_tx_usxgmii_5g = 1'b0,
input wire logic [2:0] cfg_tx_usxgmii_speed = 3'b011,
input wire logic cfg_tx_prbs31_enable
input wire logic cfg_tx_pad_en = 1'b1,
input wire logic [7:0] cfg_tx_min_pkt_len = 8'd60-1,
input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1,
input wire logic [7:0] cfg_tx_ifg = 8'd12,
input wire logic cfg_tx_enable,
input wire logic cfg_tx_usxgmii_en = 1'b1,
input wire logic cfg_tx_usxgmii_5g = 1'b0,
input wire logic [2:0] cfg_tx_usxgmii_speed = 3'b011,
input wire logic cfg_tx_prbs31_enable
);
localparam TX_USER_W = s_axis_tx.USER_W;
@@ -157,6 +161,8 @@ if (DATA_W == 64) begin
.PTP_TS_EN(PTP_TS_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W),
.PTP_TS_COR_EN(PTP_TS_COR_EN),
.PTP_TS_COR_W(PTP_TS_COR_W),
.TX_CPL_CTRL_IN_TUSER(TX_CPL_CTRL_IN_TUSER)
)
axis_baser_tx_inst (
@@ -192,6 +198,8 @@ if (DATA_W == 64) begin
* PTP
*/
.ptp_ts(ptp_ts),
.ptp_ts_cor_sync(ptp_ts_cor_sync),
.ptp_ts_cor_val(ptp_ts_cor_val),
/*
* Configuration
@@ -231,6 +239,8 @@ end else begin
.DIC_EN(DIC_EN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TS_W(PTP_TS_W),
.PTP_TS_COR_EN(PTP_TS_COR_EN),
.PTP_TS_COR_W(PTP_TS_COR_W),
.TX_CPL_CTRL_IN_TUSER(TX_CPL_CTRL_IN_TUSER)
)
axis_baser_tx_inst (
@@ -266,6 +276,8 @@ end else begin
* PTP
*/
.ptp_ts(ptp_ts),
.ptp_ts_cor_sync(ptp_ts_cor_sync),
.ptp_ts_cor_val(ptp_ts_cor_val),
/*
* Configuration

View File

@@ -61,6 +61,7 @@ module taxi_eth_mac_25g_us #
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_FNS_W = 16,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter logic PTP_TS_COR_EN = PTP_TS_EN && CFG_LOW_LATENCY,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter logic PRBS31_EN = 1'b0,
parameter TX_SERDES_PIPELINE = 1,
@@ -455,6 +456,7 @@ for (genvar n = 0; n < CNT; n = n + 1) begin : ch
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_FNS_W(PTP_TS_FNS_W),
.PTP_TS_W(PTP_TS_W),
.PTP_TS_COR_EN(PTP_TS_COR_EN),
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
.PRBS31_EN(PRBS31_EN),
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),

View File

@@ -60,6 +60,7 @@ module taxi_eth_mac_25g_us_ch #
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_FNS_W = 16,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter logic PTP_TS_COR_EN = PTP_TS_EN && CFG_LOW_LATENCY,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter logic PRBS31_EN = 1'b0,
parameter TX_SERDES_PIPELINE = 1,
@@ -322,6 +323,8 @@ localparam GBX_EN = CFG_LOW_LATENCY || GT_7;
localparam HDR_W = 2;
localparam PTP_TS_COR_W = PTP_TS_FNS_W+4;
wire rx_reset_req;
wire [DATA_W-1:0] serdes_tx_data;
@@ -337,6 +340,11 @@ wire [HDR_W-1:0] serdes_rx_hdr;
wire serdes_rx_hdr_valid;
wire serdes_rx_bitslip;
wire tx_ptp_ts_cor_sync;
wire [PTP_TS_COR_W-1:0] tx_ptp_ts_cor_val;
wire rx_ptp_ts_cor_sync;
wire [PTP_TS_COR_W-1:0] rx_ptp_ts_cor_val;
if (GT_7) begin : gt
taxi_eth_phy_10g_7_gt #(
@@ -438,6 +446,9 @@ if (GT_7) begin : gt
assign xcvr_qpll1clk_out = 1'b0;
assign xcvr_qpll1refclk_out = 1'b0;
assign tx_ptp_ts_cor_val = '0;
assign rx_ptp_ts_cor_val = '0;
end else if (DATA_W == 64 && CFG_LOW_LATENCY) begin : gt
taxi_eth_phy_25g_us_gt_ll #(
@@ -473,7 +484,9 @@ end else if (DATA_W == 64 && CFG_LOW_LATENCY) begin : gt
// MAC/PHY parameters
.DATA_W(DATA_W),
.HDR_W(HDR_W)
.HDR_W(HDR_W),
.TS_FNS_W(PTP_TS_FNS_W),
.TS_COR_W(PTP_TS_COR_W)
)
gt_inst (
.xcvr_ctrl_clk(xcvr_ctrl_clk),
@@ -549,7 +562,17 @@ end else if (DATA_W == 64 && CFG_LOW_LATENCY) begin : gt
.serdes_rx_data_valid(serdes_rx_data_valid),
.serdes_rx_hdr(serdes_rx_hdr),
.serdes_rx_hdr_valid(serdes_rx_hdr_valid),
.serdes_rx_bitslip(serdes_rx_bitslip)
.serdes_rx_bitslip(serdes_rx_bitslip),
/*
* Timestamp correction
*/
.tx_ts_cor_sync(tx_ptp_ts_cor_sync),
.tx_ts_inc(20'h27b80), // TODO
.tx_ts_cor_val(tx_ptp_ts_cor_val),
.rx_ts_cor_sync(rx_ptp_ts_cor_sync),
.rx_ts_inc(20'h27b80), // TODO
.rx_ts_cor_val(rx_ptp_ts_cor_val)
);
end else if (DATA_W == 64 && !CFG_LOW_LATENCY) begin : gt
@@ -666,6 +689,9 @@ end else if (DATA_W == 64 && !CFG_LOW_LATENCY) begin : gt
.serdes_rx_bitslip(serdes_rx_bitslip)
);
assign tx_ptp_ts_cor_val = '0;
assign rx_ptp_ts_cor_val = '0;
end else if (DATA_W == 32 && CFG_LOW_LATENCY) begin : gt
taxi_eth_phy_10g_us_gt_ll #(
@@ -701,7 +727,9 @@ end else if (DATA_W == 32 && CFG_LOW_LATENCY) begin : gt
// MAC/PHY parameters
.DATA_W(DATA_W),
.HDR_W(HDR_W)
.HDR_W(HDR_W),
.TS_FNS_W(PTP_TS_FNS_W),
.TS_COR_W(PTP_TS_COR_W)
)
gt_inst (
.xcvr_ctrl_clk(xcvr_ctrl_clk),
@@ -777,7 +805,17 @@ end else if (DATA_W == 32 && CFG_LOW_LATENCY) begin : gt
.serdes_rx_data_valid(serdes_rx_data_valid),
.serdes_rx_hdr(serdes_rx_hdr),
.serdes_rx_hdr_valid(serdes_rx_hdr_valid),
.serdes_rx_bitslip(serdes_rx_bitslip)
.serdes_rx_bitslip(serdes_rx_bitslip),
/*
* Timestamp correction
*/
.tx_ts_cor_sync(tx_ptp_ts_cor_sync),
.tx_ts_inc(20'h31a60), // TODO
.tx_ts_cor_val(tx_ptp_ts_cor_val),
.rx_ts_cor_sync(rx_ptp_ts_cor_sync),
.rx_ts_inc(20'h31a60), // TODO
.rx_ts_cor_val(rx_ptp_ts_cor_val)
);
end else if (DATA_W == 32 && !CFG_LOW_LATENCY) begin : gt
@@ -894,6 +932,9 @@ end else if (DATA_W == 32 && !CFG_LOW_LATENCY) begin : gt
.serdes_rx_bitslip(serdes_rx_bitslip)
);
assign tx_ptp_ts_cor_val = '0;
assign rx_ptp_ts_cor_val = '0;
end else begin
$fatal(0, "Error: invalid configuration (%m)");
@@ -914,6 +955,8 @@ if (COMBINED_MAC_PCS) begin : mac
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_FNS_W(PTP_TS_FNS_W),
.PTP_TS_W(PTP_TS_W),
.PTP_TS_COR_EN(PTP_TS_COR_EN),
.PTP_TS_COR_W(PTP_TS_COR_W),
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
.BIT_REVERSE(1'b1),
.SCRAMBLER_DISABLE(1'b0),
@@ -999,10 +1042,14 @@ if (COMBINED_MAC_PCS) begin : mac
.tx_ptp_ts_out(tx_ptp_ts_out),
.tx_ptp_ts_step_out(tx_ptp_ts_step_out),
.tx_ptp_locked(tx_ptp_locked),
.tx_ptp_ts_cor_sync(tx_ptp_ts_cor_sync),
.tx_ptp_ts_cor_val(tx_ptp_ts_cor_val),
.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),
.rx_ptp_ts_cor_sync(rx_ptp_ts_cor_sync),
.rx_ptp_ts_cor_val(rx_ptp_ts_cor_val),
/*
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)

View File

@@ -49,83 +49,95 @@ module taxi_eth_phy_10g_us_gt_ll #
// MAC/PHY parameters
parameter DATA_W = 32,
parameter HDR_W = 2
parameter HDR_W = 2,
parameter TS_FNS_W = 16,
parameter TS_COR_W = TS_FNS_W+4
)
(
input wire logic xcvr_ctrl_clk,
input wire logic xcvr_ctrl_rst,
input wire logic xcvr_ctrl_clk,
input wire logic xcvr_ctrl_rst,
/*
* Transceiver control
*/
taxi_apb_if.slv s_apb_ctrl,
taxi_apb_if.slv s_apb_ctrl,
/*
* Common
*/
output wire logic xcvr_gtpowergood_out,
output wire logic xcvr_gtpowergood_out,
/*
* PLL out
*/
input wire logic xcvr_gtrefclk00_in = 1'b0,
input wire logic xcvr_qpll0pd_in = 1'b0,
input wire logic xcvr_qpll0reset_in = 1'b0,
input wire logic [2:0] xcvr_qpll0pcierate_in = 3'd0,
output wire logic xcvr_qpll0lock_out,
output wire logic xcvr_qpll0clk_out,
output wire logic xcvr_qpll0refclk_out,
input wire logic xcvr_gtrefclk01_in = 1'b0,
input wire logic xcvr_qpll1pd_in = 1'b0,
input wire logic xcvr_qpll1reset_in = 1'b0,
input wire logic [2:0] xcvr_qpll1pcierate_in = 3'd0,
output wire logic xcvr_qpll1lock_out,
output wire logic xcvr_qpll1clk_out,
output wire logic xcvr_qpll1refclk_out,
input wire logic xcvr_gtrefclk00_in = 1'b0,
input wire logic xcvr_qpll0pd_in = 1'b0,
input wire logic xcvr_qpll0reset_in = 1'b0,
input wire logic [2:0] xcvr_qpll0pcierate_in = 3'd0,
output wire logic xcvr_qpll0lock_out,
output wire logic xcvr_qpll0clk_out,
output wire logic xcvr_qpll0refclk_out,
input wire logic xcvr_gtrefclk01_in = 1'b0,
input wire logic xcvr_qpll1pd_in = 1'b0,
input wire logic xcvr_qpll1reset_in = 1'b0,
input wire logic [2:0] xcvr_qpll1pcierate_in = 3'd0,
output wire logic xcvr_qpll1lock_out,
output wire logic xcvr_qpll1clk_out,
output wire logic xcvr_qpll1refclk_out,
/*
* PLL in
*/
input wire logic xcvr_qpll0lock_in = 1'b0,
input wire logic xcvr_qpll0clk_in = 1'b0,
input wire logic xcvr_qpll0refclk_in = 1'b0,
input wire logic xcvr_qpll1lock_in = 1'b0,
input wire logic xcvr_qpll1clk_in = 1'b0,
input wire logic xcvr_qpll1refclk_in = 1'b0,
input wire logic xcvr_qpll0lock_in = 1'b0,
input wire logic xcvr_qpll0clk_in = 1'b0,
input wire logic xcvr_qpll0refclk_in = 1'b0,
input wire logic xcvr_qpll1lock_in = 1'b0,
input wire logic xcvr_qpll1clk_in = 1'b0,
input wire logic xcvr_qpll1refclk_in = 1'b0,
/*
* Serial data
*/
output wire logic xcvr_txp,
output wire logic xcvr_txn,
input wire logic xcvr_rxp,
input wire logic xcvr_rxn,
output wire logic xcvr_txp,
output wire logic xcvr_txn,
input wire logic xcvr_rxp,
input wire logic xcvr_rxn,
/*
* GT user clocks
*/
output wire logic rx_clk,
input wire logic rx_rst_in = 1'b0,
output wire logic rx_rst_out,
output wire logic tx_clk,
input wire logic tx_rst_in = 1'b0,
output wire logic tx_rst_out,
output wire logic rx_clk,
input wire logic rx_rst_in = 1'b0,
output wire logic rx_rst_out,
output wire logic tx_clk,
input wire logic tx_rst_in = 1'b0,
output wire logic tx_rst_out,
/*
* Serdes interface
*/
input wire logic [DATA_W-1:0] serdes_tx_data,
input wire logic serdes_tx_data_valid,
input wire logic [HDR_W-1:0] serdes_tx_hdr,
input wire logic serdes_tx_hdr_valid,
output wire logic serdes_tx_gbx_req_sync,
output wire logic serdes_tx_gbx_req_stall,
input wire logic serdes_tx_gbx_sync,
output wire logic [DATA_W-1:0] serdes_rx_data,
output wire logic serdes_rx_data_valid,
output wire logic [HDR_W-1:0] serdes_rx_hdr,
output wire logic serdes_rx_hdr_valid,
input wire logic serdes_rx_bitslip
input wire logic [DATA_W-1:0] serdes_tx_data,
input wire logic serdes_tx_data_valid,
input wire logic [HDR_W-1:0] serdes_tx_hdr,
input wire logic serdes_tx_hdr_valid,
output wire logic serdes_tx_gbx_req_sync,
output wire logic serdes_tx_gbx_req_stall,
input wire logic serdes_tx_gbx_sync,
output wire logic [DATA_W-1:0] serdes_rx_data,
output wire logic serdes_rx_data_valid,
output wire logic [HDR_W-1:0] serdes_rx_hdr,
output wire logic serdes_rx_hdr_valid,
input wire logic serdes_rx_bitslip,
/*
* Timestamp correction
*/
input wire logic tx_ts_cor_sync = 1'b0,
input wire logic [TS_COR_W-1:0] tx_ts_inc = 20'h31a60,
output wire logic [TS_COR_W-1:0] tx_ts_cor_val,
input wire logic rx_ts_cor_sync = 1'b0,
input wire logic [TS_COR_W-1:0] rx_ts_inc = 20'h31a60,
output wire logic [TS_COR_W-1:0] rx_ts_cor_val
);
localparam GT_USP = FAMILY == "kintexuplus" || FAMILY == "virtexuplus" || FAMILY == "virtexuplusHBM"
@@ -586,6 +598,46 @@ always_ff @(posedge tx_clk) begin
end
end
// Generate TX timestamp correction
logic [6:0] tx_ts_cor_seq_reg = '0;
logic [TS_COR_W-1:0] tx_ts_cor_val_reg = '0;
assign tx_ts_cor_val = tx_ts_cor_val_reg;
always_ff @(posedge tx_clk) begin
tx_ts_cor_seq_reg <= tx_ts_cor_seq_reg + 1;
if (tx_ts_cor_seq_reg[0]) begin
tx_ts_cor_val_reg <= tx_ts_cor_val_reg + (tx_ts_inc >> 4);
end
if (tx_ts_cor_seq_reg == 65) begin
tx_ts_cor_seq_reg <= '0;
tx_ts_cor_val_reg <= '0;
end
if (tx_ts_cor_sync) begin
tx_ts_cor_seq_reg <= 1;
end
end
// Generate RX timestamp correction
logic [6:0] rx_ts_cor_seq_reg = '0;
logic [TS_COR_W-1:0] rx_ts_cor_val_reg = '0;
assign rx_ts_cor_val = rx_ts_cor_val_reg;
always_ff @(posedge rx_clk) begin
rx_ts_cor_seq_reg <= rx_ts_cor_seq_reg + 1;
if (rx_ts_cor_seq_reg[0]) begin
rx_ts_cor_val_reg <= rx_ts_cor_val_reg - (tx_ts_inc >> 4);
end
if (rx_ts_cor_seq_reg == 65) begin
rx_ts_cor_seq_reg <= '0;
rx_ts_cor_val_reg <= rx_ts_inc << 1; // TODO odd offset
end
if (rx_ts_cor_sync) begin
rx_ts_cor_seq_reg <= 1;
end
end
if (SIM) begin : xcvr
// simulation (no GT core)

View File

@@ -49,83 +49,95 @@ module taxi_eth_phy_25g_us_gt_ll #
// MAC/PHY parameters
parameter DATA_W = 64,
parameter HDR_W = 2
parameter HDR_W = 2,
parameter TS_FNS_W = 16,
parameter TS_COR_W = TS_FNS_W+4
)
(
input wire logic xcvr_ctrl_clk,
input wire logic xcvr_ctrl_rst,
input wire logic xcvr_ctrl_clk,
input wire logic xcvr_ctrl_rst,
/*
* Transceiver control
*/
taxi_apb_if.slv s_apb_ctrl,
taxi_apb_if.slv s_apb_ctrl,
/*
* Common
*/
output wire logic xcvr_gtpowergood_out,
output wire logic xcvr_gtpowergood_out,
/*
* PLL out
*/
input wire logic xcvr_gtrefclk00_in = 1'b0,
input wire logic xcvr_qpll0pd_in = 1'b0,
input wire logic xcvr_qpll0reset_in = 1'b0,
input wire logic [2:0] xcvr_qpll0pcierate_in = 3'd0,
output wire logic xcvr_qpll0lock_out,
output wire logic xcvr_qpll0clk_out,
output wire logic xcvr_qpll0refclk_out,
input wire logic xcvr_gtrefclk01_in = 1'b0,
input wire logic xcvr_qpll1pd_in = 1'b0,
input wire logic xcvr_qpll1reset_in = 1'b0,
input wire logic [2:0] xcvr_qpll1pcierate_in = 3'd0,
output wire logic xcvr_qpll1lock_out,
output wire logic xcvr_qpll1clk_out,
output wire logic xcvr_qpll1refclk_out,
input wire logic xcvr_gtrefclk00_in = 1'b0,
input wire logic xcvr_qpll0pd_in = 1'b0,
input wire logic xcvr_qpll0reset_in = 1'b0,
input wire logic [2:0] xcvr_qpll0pcierate_in = 3'd0,
output wire logic xcvr_qpll0lock_out,
output wire logic xcvr_qpll0clk_out,
output wire logic xcvr_qpll0refclk_out,
input wire logic xcvr_gtrefclk01_in = 1'b0,
input wire logic xcvr_qpll1pd_in = 1'b0,
input wire logic xcvr_qpll1reset_in = 1'b0,
input wire logic [2:0] xcvr_qpll1pcierate_in = 3'd0,
output wire logic xcvr_qpll1lock_out,
output wire logic xcvr_qpll1clk_out,
output wire logic xcvr_qpll1refclk_out,
/*
* PLL in
*/
input wire logic xcvr_qpll0lock_in = 1'b0,
input wire logic xcvr_qpll0clk_in = 1'b0,
input wire logic xcvr_qpll0refclk_in = 1'b0,
input wire logic xcvr_qpll1lock_in = 1'b0,
input wire logic xcvr_qpll1clk_in = 1'b0,
input wire logic xcvr_qpll1refclk_in = 1'b0,
input wire logic xcvr_qpll0lock_in = 1'b0,
input wire logic xcvr_qpll0clk_in = 1'b0,
input wire logic xcvr_qpll0refclk_in = 1'b0,
input wire logic xcvr_qpll1lock_in = 1'b0,
input wire logic xcvr_qpll1clk_in = 1'b0,
input wire logic xcvr_qpll1refclk_in = 1'b0,
/*
* Serial data
*/
output wire logic xcvr_txp,
output wire logic xcvr_txn,
input wire logic xcvr_rxp,
input wire logic xcvr_rxn,
output wire logic xcvr_txp,
output wire logic xcvr_txn,
input wire logic xcvr_rxp,
input wire logic xcvr_rxn,
/*
* GT user clocks
*/
output wire logic rx_clk,
input wire logic rx_rst_in = 1'b0,
output wire logic rx_rst_out,
output wire logic tx_clk,
input wire logic tx_rst_in = 1'b0,
output wire logic tx_rst_out,
output wire logic rx_clk,
input wire logic rx_rst_in = 1'b0,
output wire logic rx_rst_out,
output wire logic tx_clk,
input wire logic tx_rst_in = 1'b0,
output wire logic tx_rst_out,
/*
* Serdes interface
*/
input wire logic [DATA_W-1:0] serdes_tx_data,
input wire logic serdes_tx_data_valid,
input wire logic [HDR_W-1:0] serdes_tx_hdr,
input wire logic serdes_tx_hdr_valid,
output wire logic serdes_tx_gbx_req_sync,
output wire logic serdes_tx_gbx_req_stall,
input wire logic serdes_tx_gbx_sync,
output wire logic [DATA_W-1:0] serdes_rx_data,
output wire logic serdes_rx_data_valid,
output wire logic [HDR_W-1:0] serdes_rx_hdr,
output wire logic serdes_rx_hdr_valid,
input wire logic serdes_rx_bitslip
input wire logic [DATA_W-1:0] serdes_tx_data,
input wire logic serdes_tx_data_valid,
input wire logic [HDR_W-1:0] serdes_tx_hdr,
input wire logic serdes_tx_hdr_valid,
output wire logic serdes_tx_gbx_req_sync,
output wire logic serdes_tx_gbx_req_stall,
input wire logic serdes_tx_gbx_sync,
output wire logic [DATA_W-1:0] serdes_rx_data,
output wire logic serdes_rx_data_valid,
output wire logic [HDR_W-1:0] serdes_rx_hdr,
output wire logic serdes_rx_hdr_valid,
input wire logic serdes_rx_bitslip,
/*
* Timestamp correction
*/
input wire logic tx_ts_cor_sync = 1'b0,
input wire logic [TS_COR_W-1:0] tx_ts_inc = 20'h27b80,
output wire logic [TS_COR_W-1:0] tx_ts_cor_val,
input wire logic rx_ts_cor_sync = 1'b0,
input wire logic [TS_COR_W-1:0] rx_ts_inc = 20'h27b80,
output wire logic [TS_COR_W-1:0] rx_ts_cor_val
);
localparam GT_USP = FAMILY == "kintexuplus" || FAMILY == "virtexuplus" || FAMILY == "virtexuplusHBM"
@@ -587,6 +599,42 @@ if (GT_TYPE == "GTY") begin : tx_seq
end
end
// Generate TX timestamp correction
logic [6:0] tx_ts_cor_seq_reg = '0;
logic [TS_COR_W-1:0] tx_ts_cor_val_reg = '0;
assign tx_ts_cor_val = tx_ts_cor_val_reg;
always_ff @(posedge tx_clk) begin
tx_ts_cor_seq_reg <= tx_ts_cor_seq_reg + 1;
tx_ts_cor_val_reg <= tx_ts_cor_val_reg + (tx_ts_inc >> 5);
if (tx_ts_cor_seq_reg == 65) begin
tx_ts_cor_seq_reg <= '0;
tx_ts_cor_val_reg <= '0;
end
if (tx_ts_cor_sync) begin
tx_ts_cor_seq_reg <= 1;
end
end
// Generate RX timestamp correction
logic [6:0] rx_ts_cor_seq_reg = '0;
logic [TS_COR_W-1:0] rx_ts_cor_val_reg = '0;
assign rx_ts_cor_val = rx_ts_cor_val_reg;
always_ff @(posedge rx_clk) begin
rx_ts_cor_seq_reg <= rx_ts_cor_seq_reg + 1;
rx_ts_cor_val_reg <= rx_ts_cor_val_reg - (tx_ts_inc >> 5);
if (rx_ts_cor_seq_reg == 65) begin
rx_ts_cor_seq_reg <= '0;
rx_ts_cor_val_reg <= rx_ts_inc << 1; // TODO odd offset
end
if (rx_ts_cor_sync) begin
rx_ts_cor_seq_reg <= 1;
end
end
end else begin : tx_seq
// 33 clock cycle sequence for GTH, with one stall on cycle 32
// 32-bit internal, 64-bit external datapath width
@@ -628,6 +676,42 @@ end else begin : tx_seq
end
end
// Generate TX timestamp correction
logic [5:0] tx_ts_cor_seq_reg = '0;
logic [TS_COR_W-1:0] tx_ts_cor_val_reg = '0;
assign tx_ts_cor_val = tx_ts_cor_val_reg;
always_ff @(posedge tx_clk) begin
tx_ts_cor_seq_reg <= tx_ts_cor_seq_reg + 1;
tx_ts_cor_val_reg <= tx_ts_cor_val_reg + (tx_ts_inc >> 5);
if (tx_ts_cor_seq_reg == 32) begin
tx_ts_cor_seq_reg <= '0;
tx_ts_cor_val_reg <= '0;
end
if (tx_ts_cor_sync) begin
tx_ts_cor_seq_reg <= 1;
end
end
// Generate RX timestamp correction
logic [5:0] rx_ts_cor_seq_reg = '0;
logic [TS_COR_W-1:0] rx_ts_cor_val_reg = '0;
assign rx_ts_cor_val = rx_ts_cor_val_reg;
always_ff @(posedge rx_clk) begin
rx_ts_cor_seq_reg <= rx_ts_cor_seq_reg + 1;
rx_ts_cor_val_reg <= rx_ts_cor_val_reg - (rx_ts_inc >> 5);
if (rx_ts_cor_seq_reg == 32) begin
rx_ts_cor_seq_reg <= '0;
rx_ts_cor_val_reg <= rx_ts_inc; // TODO odd offset
end
if (rx_ts_cor_sync) begin
rx_ts_cor_seq_reg <= 1;
end
end
end
if (SIM) begin : xcvr

View File

@@ -631,16 +631,16 @@ class BaseRSerdesSink:
self.log.info(" Sequence length: %d cycles", seq_len)
self.log.info(" Stall cycles: %s", seq_stall)
in_bits = 66
in_bits = self.width
out_cycles = seq_len
in_cycles = out_cycles - len(seq_stall)
out_bits = (in_bits * in_cycles) // out_cycles
out_bits = int(((in_bits + 2/self.pack_cnt) * in_cycles) / out_cycles)
self.log.info(" Input: %d bits (%d cycles)", in_bits, in_cycles)
self.log.info(" Input: %d+2 bits (%d cycles)", in_bits, in_cycles)
self.log.info(" Output: %d bits (%d cycles)", out_bits, out_cycles)
self.log.info(" Gearbox ratio: %d:%d", in_bits, out_bits)
self.log.info(" Gearbox ratio: %d+2:%d", in_bits, out_bits)
assert in_cycles*in_bits == out_cycles*out_bits
assert in_cycles*(in_bits + 2/self.pack_cnt) == out_cycles*out_bits
self.gbx_seq = 0
self.gbx_seq_gen = 0
@@ -723,6 +723,8 @@ class BaseRSerdesSink:
clock_edge_event = RisingEdge(self.clock)
clk_period = 0
symb_period = 0
symb_start = 0
last_clk = 0
gbx_delay = 0
sync_bad = True
@@ -746,6 +748,8 @@ class BaseRSerdesSink:
# gearbox sequence
if self.gbx_seq_len:
symb_period = (clk_period * (self.pack_cnt*self.gbx_in_bits + 2)) // self.gbx_out_bits
# generation
self.gbx_seq_gen = (self.gbx_seq_gen + 1) % self.gbx_seq_len
@@ -763,14 +767,23 @@ class BaseRSerdesSink:
if int(self.gbx_sync.value):
self.gbx_seq = 0
if self.gbx_seq == 0:
self.gbx_bit_cnt = 0
gbx_delay = (self.gbx_bit_cnt * clk_period) // self.gbx_out_bits
stall = self.gbx_seq in self.gbx_seq_stall
if not stall:
self.gbx_bit_cnt += self.gbx_in_bits
if self.pack_cnt == 1 or self.pack_seq == 0:
self.gbx_bit_cnt += 2
self.gbx_bit_cnt = max(self.gbx_bit_cnt - self.gbx_out_bits, 0)
if self.gbx_seq in self.gbx_seq_stall:
if stall:
continue
self.gbx_bit_cnt += self.gbx_in_bits
gbx_delay = (self.gbx_bit_cnt * clk_period) // self.gbx_out_bits
else:
symb_period = clk_period * self.pack_cnt
self.gbx_seq = 0
self.gbx_seq_gen = 0
self.gbx_bit_cnt = 0
@@ -799,6 +812,9 @@ class BaseRSerdesSink:
if self.pack_cnt > 1:
# pack input data
if self.pack_seq == 0:
symb_start = sim_time + gbx_delay
if self.hdr_valid is not None:
if self.hdr_valid.value:
data = data_in
@@ -807,13 +823,14 @@ class BaseRSerdesSink:
continue
data |= data_in << (self.width*self.pack_seq)
self.pack_seq = self.pack_seq+1
self.pack_seq += 1
if self.pack_seq < self.pack_cnt:
continue
self.pack_seq = 0
else:
symb_start = sim_time + gbx_delay
data = data_in
hdr = hdr_in
@@ -1004,7 +1021,7 @@ class BaseRSerdesSink:
if c_val and d_val == XgmiiCtrl.START:
# start
frame = XgmiiFrame(bytearray([EthPre.PRE]), [0])
frame.sim_time_start = sim_time + (clk_period // self.byte_lanes * k) + gbx_delay
frame.sim_time_start = symb_start + ((symb_period * k) // 8)
frame.start_lane = k
in_pre = True
else:
@@ -1016,7 +1033,7 @@ class BaseRSerdesSink:
frame.ctrl.append(c_val)
frame.compact()
frame.sim_time_end = sim_time + (clk_period // self.byte_lanes * k) + gbx_delay
frame.sim_time_end = symb_start + ((symb_period * k) // 8)
self.log.info("RX frame: %s", frame)
self.queue_occupancy_bytes += len(frame)
@@ -1028,7 +1045,7 @@ class BaseRSerdesSink:
frame = None
else:
if frame.sim_time_sfd is None and not in_pre:
frame.sim_time_sfd = sim_time + (clk_period // self.byte_lanes * k) + gbx_delay
frame.sim_time_sfd = symb_start + ((symb_period * k) // 8)
if d_val == EthPre.SFD:
in_pre = False

View File

@@ -11,7 +11,7 @@ SIM ?= verilator
WAVES ?= 0
COCOTB_HDL_TIMEUNIT = 1ns
COCOTB_HDL_TIMEPRECISION = 1ps
COCOTB_HDL_TIMEPRECISION = 1fs
RTL_DIR = ../../rtl
LIB_DIR = ../../lib
@@ -43,6 +43,8 @@ export PARAM_DIC_EN := 1
export PARAM_PTP_TS_EN := 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_COR_EN := 1
export PARAM_PTP_TS_COR_W := 20
export PARAM_TX_TAG_W := 16
export PARAM_TX_CPL_CTRL_IN_TUSER := 1

View File

@@ -14,13 +14,12 @@ import logging
import os
import sys
import cocotb_test.simulator
import pytest
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge
from cocotb.utils import get_time_from_sim_steps
from cocotb_tools.runner import get_runner
from cocotbext.eth import PtpClockSimTime
from cocotbext.axi import AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiStreamFrame
@@ -44,7 +43,7 @@ class TB:
self.log.setLevel(logging.DEBUG)
if gbx_cfg:
self.clk_period = 3.102
self.clk_period = 3.103102
else:
self.clk_period = 3.2
@@ -71,6 +70,8 @@ class TB:
dut.tx_os_sig.setimmediatevalue(0)
dut.tx_os_valid.setimmediatevalue(0)
dut.ptp_ts_cor_val.setimmediatevalue(0)
dut.cfg_tx_max_pkt_len.setimmediatevalue(0)
dut.cfg_tx_ifg.setimmediatevalue(0)
dut.cfg_tx_enable.setimmediatevalue(0)
@@ -124,6 +125,8 @@ class TB:
self.stats["stat_tx_err_underflow"] = 0
cocotb.start_soon(self._run_stats_counters())
if gbx_cfg:
cocotb.start_soon(self._run_ts_cor())
async def reset(self):
self.dut.rst.setimmediatevalue(0)
@@ -148,6 +151,24 @@ class TB:
for stat in self.stats:
self.stats[stat] += int(getattr(self.dut, stat).value)
async def _run_ts_cor(self):
seq_len = self.sink.gbx_seq_len
seq = 0
val = 0
ui = self.clk_period / self.sink.width
step = int(ui*2*65536+0.5)
while True:
await RisingEdge(self.dut.clk)
seq += 1
if seq % 2 == 0:
val += step
if seq >= seq_len:
seq = 0
val = 0
self.dut.ptp_ts_cor_val.value = val
if int(self.dut.ptp_ts_cor_sync.value):
seq = 1
def size_list():
return list(range(16, 128)) + [512, 1514, 9214] + [60]*10 + [i for i in range(64, 73) for k in range(8)]
@@ -214,8 +235,7 @@ async def run_test(dut, gbx_cfg=None, usxgmii_speed=None, payload_lengths=None,
assert rx_frame.get_payload() == test_data
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*1) < 0.01
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*1) < 0.01
assert tb.sink.empty()
@@ -522,14 +542,14 @@ def test_taxi_axis_baser_tx_32(request, gbx_en, dic_en):
module = os.path.splitext(os.path.basename(__file__))[0]
toplevel = module
verilog_sources = [
sources = [
os.path.join(tests_dir, f"{toplevel}.sv"),
os.path.join(rtl_dir, f"{dut}.sv"),
os.path.join(taxi_src_dir, "lfsr", "rtl", "taxi_lfsr.sv"),
os.path.join(taxi_src_dir, "axis", "rtl", "taxi_axis_if.sv"),
]
verilog_sources = process_f_files(verilog_sources)
sources = process_f_files(sources)
parameters = {}
@@ -542,6 +562,8 @@ def test_taxi_axis_baser_tx_32(request, gbx_en, dic_en):
parameters['PTP_TS_EN'] = 1
parameters['PTP_TS_FMT_TOD'] = 1
parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64
parameters['PTP_TS_COR_EN'] = 1
parameters['PTP_TS_COR_W'] = 16+4
parameters['TX_TAG_W'] = 16
parameters['TX_CPL_CTRL_IN_TUSER'] = 1
@@ -550,13 +572,28 @@ def test_taxi_axis_baser_tx_32(request, gbx_en, dic_en):
sim_build = os.path.join(tests_dir, "sim_build",
request.node.name.replace('[', '-').replace(']', ''))
cocotb_test.simulator.run(
simulator="verilator",
python_search=[tests_dir],
verilog_sources=verilog_sources,
toplevel=toplevel,
module=module,
timescale = ("1ns", "1fs")
sim = os.getenv("SIM", "verilator")
waves = bool(int(os.getenv("WAVES", 0)))
sys.path.append(tests_dir)
runner = get_runner(sim)
runner.build(
sources=sources,
hdl_toplevel=toplevel,
parameters=parameters,
sim_build=sim_build,
extra_env=extra_env,
always=True,
build_dir=sim_build,
timescale=timescale,
waves=waves,
)
runner.test(
hdl_toplevel=toplevel,
test_module=module,
parameters=parameters,
extra_env=extra_env,
build_dir=sim_build,
timescale=timescale,
waves=waves,
)

View File

@@ -9,7 +9,7 @@ Authors:
*/
`resetall
`timescale 1ns / 1ps
`timescale 1ns / 1fs
`default_nettype none
/*
@@ -27,6 +27,8 @@ module test_taxi_axis_baser_tx_32 #
parameter logic PTP_TS_EN = 1'b0,
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter logic PTP_TS_COR_EN = PTP_TS_EN && GBX_IF_EN,
parameter PTP_TS_COR_W = 16+4,
parameter TX_TAG_W = 16,
parameter logic TX_CPL_CTRL_IN_TUSER = 1'b0
/* verilator lint_on WIDTHTRUNC */
@@ -55,6 +57,8 @@ logic tx_os_valid;
logic tx_os_ready;
logic [PTP_TS_W-1:0] ptp_ts;
logic ptp_ts_cor_sync;
logic [PTP_TS_COR_W-1:0] ptp_ts_cor_val;
logic [15:0] cfg_tx_max_pkt_len;
logic [7:0] cfg_tx_ifg;
@@ -85,6 +89,8 @@ taxi_axis_baser_tx_32 #(
.DIC_EN(DIC_EN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TS_W(PTP_TS_W),
.PTP_TS_COR_EN(PTP_TS_COR_EN),
.PTP_TS_COR_W(PTP_TS_COR_W),
.TX_CPL_CTRL_IN_TUSER(TX_CPL_CTRL_IN_TUSER)
)
uut (
@@ -120,6 +126,8 @@ uut (
* PTP
*/
.ptp_ts(ptp_ts),
.ptp_ts_cor_sync(ptp_ts_cor_sync),
.ptp_ts_cor_val(ptp_ts_cor_val),
/*
* Configuration

View File

@@ -11,7 +11,7 @@ SIM ?= verilator
WAVES ?= 0
COCOTB_HDL_TIMEUNIT = 1ns
COCOTB_HDL_TIMEPRECISION = 1ps
COCOTB_HDL_TIMEPRECISION = 1fs
RTL_DIR = ../../rtl
LIB_DIR = ../../lib
@@ -43,6 +43,8 @@ export PARAM_DIC_EN := 1
export PARAM_PTP_TS_EN := 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_COR_EN := 1
export PARAM_PTP_TS_COR_W := 20
export PARAM_TX_TAG_W := 16
export PARAM_TX_CPL_CTRL_IN_TUSER := 1

View File

@@ -14,13 +14,12 @@ import logging
import os
import sys
import cocotb_test.simulator
import pytest
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge
from cocotb.utils import get_time_from_sim_steps
from cocotb_tools.runner import get_runner
from cocotbext.eth import PtpClockSimTime
from cocotbext.axi import AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiStreamFrame
@@ -44,7 +43,7 @@ class TB:
self.log.setLevel(logging.DEBUG)
if gbx_cfg:
self.clk_period = 6.206
self.clk_period = 6.206206
else:
self.clk_period = 6.4
@@ -71,6 +70,8 @@ class TB:
dut.tx_os_sig.setimmediatevalue(0)
dut.tx_os_valid.setimmediatevalue(0)
dut.ptp_ts_cor_val.setimmediatevalue(0)
dut.cfg_tx_max_pkt_len.setimmediatevalue(0)
dut.cfg_tx_ifg.setimmediatevalue(0)
dut.cfg_tx_enable.setimmediatevalue(0)
@@ -124,6 +125,8 @@ class TB:
self.stats["stat_tx_err_underflow"] = 0
cocotb.start_soon(self._run_stats_counters())
if gbx_cfg:
cocotb.start_soon(self._run_ts_cor())
async def reset(self):
self.dut.rst.setimmediatevalue(0)
@@ -148,6 +151,23 @@ class TB:
for stat in self.stats:
self.stats[stat] += int(getattr(self.dut, stat).value)
async def _run_ts_cor(self):
seq_len = self.sink.gbx_seq_len
seq = 0
val = 0
ui = self.clk_period / self.sink.width
step = int(ui*2*65536+0.5)
while True:
await RisingEdge(self.dut.clk)
seq += 1
val += step
if seq >= seq_len:
seq = 0
val = 0
self.dut.ptp_ts_cor_val.value = val
if int(self.dut.ptp_ts_cor_sync.value):
seq = 1
def size_list():
return list(range(16, 128)) + [512, 1514, 9214] + [60]*10 + [i for i in range(64, 73) for k in range(8)]
@@ -214,8 +234,7 @@ async def run_test(dut, gbx_cfg=None, usxgmii_speed=None, payload_lengths=None,
assert rx_frame.get_payload() == test_data
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*1) < 0.01
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*1) < 0.001
assert tb.sink.empty()
@@ -294,8 +313,7 @@ async def run_test_alignment(dut, gbx_cfg=None, usxgmii_speed=None, payload_data
assert rx_frame.get_payload() == test_data
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*1) < 0.01
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*1) < 0.001
start_lane.append(rx_frame.start_lane)
@@ -638,14 +656,14 @@ def test_taxi_axis_baser_tx_64(request, gbx_en, dic_en):
module = os.path.splitext(os.path.basename(__file__))[0]
toplevel = module
verilog_sources = [
sources = [
os.path.join(tests_dir, f"{toplevel}.sv"),
os.path.join(rtl_dir, f"{dut}.sv"),
os.path.join(taxi_src_dir, "lfsr", "rtl", "taxi_lfsr.sv"),
os.path.join(taxi_src_dir, "axis", "rtl", "taxi_axis_if.sv"),
]
verilog_sources = process_f_files(verilog_sources)
sources = process_f_files(sources)
parameters = {}
@@ -658,6 +676,8 @@ def test_taxi_axis_baser_tx_64(request, gbx_en, dic_en):
parameters['PTP_TS_EN'] = 1
parameters['PTP_TS_FMT_TOD'] = 1
parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64
parameters['PTP_TS_COR_EN'] = 1
parameters['PTP_TS_COR_W'] = 16+4
parameters['TX_TAG_W'] = 16
parameters['TX_CPL_CTRL_IN_TUSER'] = 1
@@ -666,13 +686,28 @@ def test_taxi_axis_baser_tx_64(request, gbx_en, dic_en):
sim_build = os.path.join(tests_dir, "sim_build",
request.node.name.replace('[', '-').replace(']', ''))
cocotb_test.simulator.run(
simulator="verilator",
python_search=[tests_dir],
verilog_sources=verilog_sources,
toplevel=toplevel,
module=module,
timescale = ("1ns", "1fs")
sim = os.getenv("SIM", "verilator")
waves = bool(int(os.getenv("WAVES", 0)))
sys.path.append(tests_dir)
runner = get_runner(sim)
runner.build(
sources=sources,
hdl_toplevel=toplevel,
parameters=parameters,
sim_build=sim_build,
extra_env=extra_env,
always=True,
build_dir=sim_build,
timescale=timescale,
waves=waves,
)
runner.test(
hdl_toplevel=toplevel,
test_module=module,
parameters=parameters,
extra_env=extra_env,
build_dir=sim_build,
timescale=timescale,
waves=waves,
)

View File

@@ -9,7 +9,7 @@ Authors:
*/
`resetall
`timescale 1ns / 1ps
`timescale 1ns / 1fs
`default_nettype none
/*
@@ -27,6 +27,8 @@ module test_taxi_axis_baser_tx_64 #
parameter logic PTP_TS_EN = 1'b0,
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter logic PTP_TS_COR_EN = PTP_TS_EN && GBX_IF_EN,
parameter PTP_TS_COR_W = 16+4,
parameter TX_TAG_W = 16,
parameter logic TX_CPL_CTRL_IN_TUSER = 1'b0
/* verilator lint_on WIDTHTRUNC */
@@ -55,6 +57,8 @@ logic tx_os_valid;
logic tx_os_ready;
logic [PTP_TS_W-1:0] ptp_ts;
logic ptp_ts_cor_sync;
logic [PTP_TS_COR_W-1:0] ptp_ts_cor_val;
logic [15:0] cfg_tx_max_pkt_len;
logic [7:0] cfg_tx_ifg;
@@ -85,6 +89,8 @@ taxi_axis_baser_tx_64 #(
.DIC_EN(DIC_EN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TS_W(PTP_TS_W),
.PTP_TS_COR_EN(PTP_TS_COR_EN),
.PTP_TS_COR_W(PTP_TS_COR_W),
.TX_CPL_CTRL_IN_TUSER(TX_CPL_CTRL_IN_TUSER)
)
uut (
@@ -120,6 +126,8 @@ uut (
* PTP
*/
.ptp_ts(ptp_ts),
.ptp_ts_cor_sync(ptp_ts_cor_sync),
.ptp_ts_cor_val(ptp_ts_cor_val),
/*
* Configuration

View File

@@ -11,7 +11,7 @@ SIM ?= verilator
WAVES ?= 0
COCOTB_HDL_TIMEUNIT = 1ns
COCOTB_HDL_TIMEPRECISION = 1ps
COCOTB_HDL_TIMEPRECISION = 1fs
RTL_DIR = ../../rtl
LIB_DIR = ../../lib
@@ -51,6 +51,7 @@ export PARAM_PTP_TD_EN := $(PARAM_PTP_TS_EN)
export PARAM_PTP_TS_FMT_TOD := 1
export PARAM_PTP_TS_FNS_W := 16
export PARAM_PTP_TS_W := $(if $(filter-out 1,$(PARAM_PTP_TS_FMT_TOD)),64,96)
export PARAM_PTP_TS_COR_EN := 1
export PARAM_PTP_TD_SDI_PIPELINE := 2
export PARAM_TX_TAG_W := 16
export PARAM_PRBS31_EN := 1

View File

@@ -18,12 +18,11 @@ import sys
from scapy.layers.l2 import Ether
import pytest
import cocotb_test.simulator
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge, Timer
from cocotb.utils import get_time_from_sim_steps
from cocotb_tools.runner import get_runner
from cocotbext.eth import XgmiiFrame, PtpClockSimTime
from cocotbext.axi import AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiStreamFrame
@@ -51,7 +50,7 @@ class TB:
cocotb.start_soon(Clock(dut.xcvr_ctrl_clk, 8, units="ns").start())
cocotb.start_soon(Clock(dut.stat_clk, 8, units="ns").start())
cocotb.start_soon(Clock(dut.xcvr_gtrefclk00_in, 6.206, units="ns").start())
cocotb.start_soon(Clock(dut.xcvr_gtrefclk00_in, 6.206206, units="ns").start())
self.apb_ctrl = ApbMaster(ApbBus.from_entity(dut.s_apb_ctrl), dut.xcvr_ctrl_clk, dut.xcvr_ctrl_rst)
@@ -65,14 +64,14 @@ class TB:
if ch.ch_inst.DATA_W.value == 64:
if ch.ch_inst.CFG_LOW_LATENCY.value:
clk = 2.482
clk = 2.482482
gbx_cfg = (66, [64, 65])
else:
clk = 2.56
gbx_cfg = None
else:
if ch.ch_inst.CFG_LOW_LATENCY.value:
clk = 3.102
clk = 3.103102
gbx_cfg = (66, [64, 65])
else:
clk = 3.2
@@ -399,7 +398,7 @@ async def run_test_tx(dut, port=0, payload_lengths=None, payload_data=None, ifg=
assert rx_frame.get_payload() == test_data
assert rx_frame.check_fcs()
assert rx_frame.ctrl is None
if not tb.serdes_sinks[port].gbx_seq_len:
if not tb.serdes_sinks[port].gbx_seq_len or dut.COMBINED_MAC_PCS.value:
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:
@@ -485,7 +484,7 @@ async def run_test_tx_alignment(dut, port=0, payload_data=None, ifg=12):
assert rx_frame.get_payload() == test_data
assert rx_frame.check_fcs()
assert rx_frame.ctrl is None
if not tb.serdes_sinks[port].gbx_seq_len:
if not tb.serdes_sinks[port].gbx_seq_len or dut.COMBINED_MAC_PCS.value:
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:
@@ -1200,12 +1199,12 @@ def test_taxi_eth_mac_25g_us(request, data_w, combined_mac_pcs, low_latency, dic
module = os.path.splitext(os.path.basename(__file__))[0]
toplevel = module
verilog_sources = [
sources = [
os.path.join(tests_dir, f"{toplevel}.sv"),
os.path.join(rtl_dir, "us", f"{dut}.f"),
]
verilog_sources = process_f_files(verilog_sources)
sources = process_f_files(sources)
parameters = {}
@@ -1228,6 +1227,7 @@ def test_taxi_eth_mac_25g_us(request, data_w, combined_mac_pcs, low_latency, dic
parameters['PTP_TS_FMT_TOD'] = 1
parameters['PTP_TS_FNS_W'] = 16
parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64
parameters['PTP_TS_COR_EN'] = 1
parameters['PTP_TD_SDI_PIPELINE'] = 2
parameters['TX_TAG_W'] = 16
parameters['PRBS31_EN'] = 1
@@ -1250,13 +1250,28 @@ def test_taxi_eth_mac_25g_us(request, data_w, combined_mac_pcs, low_latency, dic
sim_build = os.path.join(tests_dir, "sim_build",
request.node.name.replace('[', '-').replace(']', ''))
cocotb_test.simulator.run(
simulator="verilator",
python_search=[tests_dir],
verilog_sources=verilog_sources,
toplevel=toplevel,
module=module,
timescale = ("1ns", "1fs")
sim = os.getenv("SIM", "verilator")
waves = bool(int(os.getenv("WAVES", 0)))
sys.path.append(tests_dir)
runner = get_runner(sim)
runner.build(
sources=sources,
hdl_toplevel=toplevel,
parameters=parameters,
sim_build=sim_build,
extra_env=extra_env,
always=True,
build_dir=sim_build,
timescale=timescale,
waves=waves,
)
runner.test(
hdl_toplevel=toplevel,
test_module=module,
parameters=parameters,
extra_env=extra_env,
build_dir=sim_build,
timescale=timescale,
waves=waves,
)

View File

@@ -9,7 +9,7 @@ Authors:
*/
`resetall
`timescale 1ns / 1ps
`timescale 1ns / 1fs
`default_nettype none
/*
@@ -50,6 +50,7 @@ module test_taxi_eth_mac_25g_us #
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_FNS_W = 16,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter logic PTP_TS_COR_EN = PTP_TS_EN && CFG_LOW_LATENCY,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter TX_TAG_W = 16,
parameter logic PRBS31_EN = 1'b0,
@@ -292,6 +293,7 @@ taxi_eth_mac_25g_us #(
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_FNS_W(PTP_TS_FNS_W),
.PTP_TS_W(PTP_TS_W),
.PTP_TS_COR_EN(PTP_TS_COR_EN),
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
.PRBS31_EN(PRBS31_EN),
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),

View File

@@ -11,7 +11,7 @@ SIM ?= verilator
WAVES ?= 0
COCOTB_HDL_TIMEUNIT = 1ns
COCOTB_HDL_TIMEPRECISION = 1ps
COCOTB_HDL_TIMEPRECISION = 1fs
RTL_DIR = ../../rtl
LIB_DIR = ../../lib
@@ -43,6 +43,8 @@ export PARAM_PTP_TD_EN := $(PARAM_PTP_TS_EN)
export PARAM_PTP_TS_FMT_TOD := 1
export PARAM_PTP_TS_FNS_W := 16
export PARAM_PTP_TS_W := $(if $(filter-out 1,$(PARAM_PTP_TS_FMT_TOD)),64,96)
export PARAM_PTP_TS_COR_EN := 1
export PARAM_PTP_TS_COR_W := 20
export PARAM_PTP_TD_SDI_PIPELINE := 2
export PARAM_TX_TAG_W := 16
export PARAM_BIT_REVERSE := 0

View File

@@ -18,12 +18,11 @@ import sys
from scapy.layers.l2 import Ether
import pytest
import cocotb_test.simulator
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge, Timer
from cocotb.utils import get_time_from_sim_steps
from cocotb_tools.runner import get_runner
from cocotbext.eth import XgmiiFrame, PtpClockSimTime
from cocotbext.axi import AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiStreamFrame
@@ -50,12 +49,12 @@ class TB:
if len(dut.serdes_tx_data) == 64:
if gbx_cfg:
self.clk_period = 6.206
self.clk_period = 6.206206
else:
self.clk_period = 6.4
else:
if gbx_cfg:
self.clk_period = 3.102
self.clk_period = 3.103102
else:
self.clk_period = 3.2
@@ -114,6 +113,9 @@ class TB:
dut.an_usxgmii_5g.setimmediatevalue(0)
dut.an_adv_ability_usxgmii.setimmediatevalue(0x1601)
dut.tx_ptp_ts_cor_val.setimmediatevalue(0)
dut.rx_ptp_ts_cor_val.setimmediatevalue(0)
dut.stat_rx_fifo_drop.setimmediatevalue(0)
dut.cfg_tx_pad_en.setimmediatevalue(0)
@@ -157,6 +159,9 @@ class TB:
dut.cfg_rx_pfc_opcode.setimmediatevalue(0)
dut.cfg_rx_pfc_en.setimmediatevalue(0)
if gbx_cfg:
cocotb.start_soon(self._run_tx_ts_cor())
async def reset(self):
self.dut.rx_rst.setimmediatevalue(0)
self.dut.tx_rst.setimmediatevalue(0)
@@ -180,6 +185,24 @@ class TB:
self.ptp_td_source.set_ts_tod_sim_time()
self.ptp_td_source.set_ts_rel_sim_time()
async def _run_tx_ts_cor(self):
seq_len = self.serdes_sink.gbx_seq_len
seq = 0
val = 0
ui = self.clk_period / self.serdes_sink.width
step = int(ui*2*65536+0.5)
while True:
await RisingEdge(self.dut.tx_clk)
seq += 1
if self.serdes_sink.width == 64 or seq % 2 == 0:
val += step
if seq >= seq_len:
seq = 0
val = 0
self.dut.tx_ptp_ts_cor_val.value = val
if int(self.dut.tx_ptp_ts_cor_sync.value):
seq = 1
def size_list():
return list(range(60, 128)) + [512, 1514, 9214] + [60]*10
@@ -339,11 +362,10 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
assert rx_frame.get_payload() == test_data
assert rx_frame.check_fcs()
assert rx_frame.ctrl is None
if gbx_cfg is None:
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
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.001
assert tb.serdes_sink.empty()
@@ -418,11 +440,10 @@ async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12):
assert rx_frame.get_payload() == test_data
assert rx_frame.check_fcs()
assert rx_frame.ctrl is None
if gbx_cfg is None:
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
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.001
start_lane.append(rx_frame.start_lane)
@@ -1103,12 +1124,12 @@ def test_taxi_eth_mac_phy_10g(request, data_w, ptp_td_en, gbx_en, dic_en, pfc_en
module = os.path.splitext(os.path.basename(__file__))[0]
toplevel = module
verilog_sources = [
sources = [
os.path.join(tests_dir, f"{toplevel}.sv"),
os.path.join(rtl_dir, f"{dut}.f"),
]
verilog_sources = process_f_files(verilog_sources)
sources = process_f_files(sources)
parameters = {}
@@ -1123,6 +1144,8 @@ def test_taxi_eth_mac_phy_10g(request, data_w, ptp_td_en, gbx_en, dic_en, pfc_en
parameters['PTP_TS_FMT_TOD'] = 1
parameters['PTP_TS_FNS_W'] = 16
parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64
parameters['PTP_TS_COR_EN'] = 1
parameters['PTP_TS_COR_W'] = parameters['PTP_TS_FNS_W']+4
parameters['PTP_TD_SDI_PIPELINE'] = 2
parameters['TX_TAG_W'] = 16
parameters['BIT_REVERSE'] = 0
@@ -1148,13 +1171,28 @@ def test_taxi_eth_mac_phy_10g(request, data_w, ptp_td_en, gbx_en, dic_en, pfc_en
sim_build = os.path.join(tests_dir, "sim_build",
request.node.name.replace('[', '-').replace(']', ''))
cocotb_test.simulator.run(
simulator="verilator",
python_search=[tests_dir],
verilog_sources=verilog_sources,
toplevel=toplevel,
module=module,
timescale = ("1ns", "1fs")
sim = os.getenv("SIM", "verilator")
waves = bool(int(os.getenv("WAVES", 0)))
sys.path.append(tests_dir)
runner = get_runner(sim)
runner.build(
sources=sources,
hdl_toplevel=toplevel,
parameters=parameters,
sim_build=sim_build,
extra_env=extra_env,
always=True,
build_dir=sim_build,
timescale=timescale,
waves=waves,
)
runner.test(
hdl_toplevel=toplevel,
test_module=module,
parameters=parameters,
extra_env=extra_env,
build_dir=sim_build,
timescale=timescale,
waves=waves,
)

View File

@@ -9,7 +9,7 @@ Authors:
*/
`resetall
`timescale 1ns / 1ps
`timescale 1ns / 1fs
`default_nettype none
/*
@@ -29,6 +29,8 @@ module test_taxi_eth_mac_phy_10g #
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_FNS_W = 16,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter logic PTP_TS_COR_EN = PTP_TS_EN && (TX_GBX_IF_EN || RX_GBX_IF_EN),
parameter PTP_TS_COR_W = PTP_TS_FNS_W+4,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter TX_TAG_W = 16,
parameter logic BIT_REVERSE = 1'b0,
@@ -104,10 +106,14 @@ 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 tx_ptp_ts_cor_sync;
logic [PTP_TS_COR_W-1:0] tx_ptp_ts_cor_val;
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 rx_ptp_ts_cor_sync;
logic [PTP_TS_COR_W-1:0] rx_ptp_ts_cor_val;
logic tx_lfc_req;
logic tx_lfc_resend;
@@ -235,6 +241,8 @@ taxi_eth_mac_phy_10g #(
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_FNS_W(PTP_TS_FNS_W),
.PTP_TS_W(PTP_TS_W),
.PTP_TS_COR_EN(PTP_TS_COR_EN),
.PTP_TS_COR_W(PTP_TS_COR_W),
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
.BIT_REVERSE(BIT_REVERSE),
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE),
@@ -320,10 +328,14 @@ uut (
.tx_ptp_ts_out(tx_ptp_ts_out),
.tx_ptp_ts_step_out(tx_ptp_ts_step_out),
.tx_ptp_locked(tx_ptp_locked),
.tx_ptp_ts_cor_sync(tx_ptp_ts_cor_sync),
.tx_ptp_ts_cor_val(tx_ptp_ts_cor_val),
.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),
.rx_ptp_ts_cor_sync(rx_ptp_ts_cor_sync),
.rx_ptp_ts_cor_val(rx_ptp_ts_cor_val),
/*
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)

View File

@@ -11,7 +11,7 @@ SIM ?= verilator
WAVES ?= 0
COCOTB_HDL_TIMEUNIT = 1ns
COCOTB_HDL_TIMEPRECISION = 1ps
COCOTB_HDL_TIMEPRECISION = 1fs
RTL_DIR = ../../rtl
LIB_DIR = ../../lib
@@ -44,6 +44,8 @@ export PARAM_PTP_TD_EN := $(PARAM_PTP_TS_EN)
export PARAM_PTP_TS_FMT_TOD := 1
export PARAM_PTP_TS_FNS_W := 16
export PARAM_PTP_TS_W := $(if $(filter-out 1,$(PARAM_PTP_TS_FMT_TOD)),64,96)
export PARAM_PTP_TS_COR_EN := 1
export PARAM_PTP_TS_COR_W := 20
export PARAM_PTP_TD_SDI_PIPELINE := 2
export PARAM_TX_TAG_W := 16
export PARAM_BIT_REVERSE := 0

View File

@@ -15,12 +15,11 @@ import os
import sys
import pytest
import cocotb_test.simulator
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge, Timer
from cocotb.utils import get_time_from_sim_steps
from cocotb_tools.runner import get_runner
from cocotbext.eth import XgmiiFrame, PtpClockSimTime
from cocotbext.axi import AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiStreamFrame
@@ -47,12 +46,12 @@ class TB:
if len(dut.serdes_tx_data) == 64:
if gbx_cfg:
self.clk_period = 6.206
self.clk_period = 6.206206
else:
self.clk_period = 6.4
else:
if gbx_cfg:
self.clk_period = 3.102
self.clk_period = 3.103102
else:
self.clk_period = 3.2
@@ -112,6 +111,9 @@ class TB:
dut.an_usxgmii_5g.setimmediatevalue(0)
dut.an_adv_ability_usxgmii.setimmediatevalue(0x1601)
dut.tx_ptp_ts_cor_val.setimmediatevalue(0)
dut.rx_ptp_ts_cor_val.setimmediatevalue(0)
dut.cfg_tx_pad_en.setimmediatevalue(0)
dut.cfg_tx_min_pkt_len.setimmediatevalue(0)
dut.cfg_tx_max_pkt_len.setimmediatevalue(0)
@@ -122,6 +124,9 @@ class TB:
dut.cfg_tx_prbs31_enable.setimmediatevalue(0)
dut.cfg_rx_prbs31_enable.setimmediatevalue(0)
if gbx_cfg:
cocotb.start_soon(self._run_tx_ts_cor())
async def reset(self):
self.dut.logic_rst.setimmediatevalue(0)
self.dut.rx_rst.setimmediatevalue(0)
@@ -148,6 +153,24 @@ class TB:
self.ptp_td_source.set_ts_tod_sim_time()
self.ptp_td_source.set_ts_rel_sim_time()
async def _run_tx_ts_cor(self):
seq_len = self.serdes_sink.gbx_seq_len
seq = 0
val = 0
ui = self.clk_period / self.serdes_sink.width
step = int(ui*2*65536+0.5)
while True:
await RisingEdge(self.dut.tx_clk)
seq += 1
if self.serdes_sink.width == 64 or seq % 2 == 0:
val += step
if seq >= seq_len:
seq = 0
val = 0
self.dut.tx_ptp_ts_cor_val.value = val
if int(self.dut.tx_ptp_ts_cor_sync.value):
seq = 1
def size_list():
return list(range(60, 128)) + [512, 1514, 9214] + [60]*10
@@ -296,11 +319,10 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
assert rx_frame.get_payload() == test_data
assert rx_frame.check_fcs()
assert rx_frame.ctrl is None
if gbx_cfg is None:
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
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()
@@ -371,11 +393,10 @@ async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12):
assert rx_frame.get_payload() == test_data
assert rx_frame.check_fcs()
assert rx_frame.ctrl is None
if gbx_cfg is None:
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
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)
@@ -640,12 +661,12 @@ def test_taxi_eth_mac_phy_10g_fifo(request, data_w, gbx_en, dic_en):
module = os.path.splitext(os.path.basename(__file__))[0]
toplevel = module
verilog_sources = [
sources = [
os.path.join(tests_dir, f"{toplevel}.sv"),
os.path.join(rtl_dir, f"{dut}.f"),
]
verilog_sources = process_f_files(verilog_sources)
sources = process_f_files(sources)
parameters = {}
@@ -661,6 +682,8 @@ def test_taxi_eth_mac_phy_10g_fifo(request, data_w, gbx_en, dic_en):
parameters['PTP_TS_FMT_TOD'] = 1
parameters['PTP_TS_FNS_W'] = 16
parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64
parameters['PTP_TS_COR_EN'] = 1
parameters['PTP_TS_COR_W'] = parameters['PTP_TS_FNS_W']+4
parameters['PTP_TD_SDI_PIPELINE'] = 2
parameters['TX_TAG_W'] = 16
parameters['BIT_REVERSE'] = 0
@@ -697,13 +720,28 @@ def test_taxi_eth_mac_phy_10g_fifo(request, data_w, gbx_en, dic_en):
sim_build = os.path.join(tests_dir, "sim_build",
request.node.name.replace('[', '-').replace(']', ''))
cocotb_test.simulator.run(
simulator="verilator",
python_search=[tests_dir],
verilog_sources=verilog_sources,
toplevel=toplevel,
module=module,
timescale = ("1ns", "1fs")
sim = os.getenv("SIM", "verilator")
waves = bool(int(os.getenv("WAVES", 0)))
sys.path.append(tests_dir)
runner = get_runner(sim)
runner.build(
sources=sources,
hdl_toplevel=toplevel,
parameters=parameters,
sim_build=sim_build,
extra_env=extra_env,
always=True,
build_dir=sim_build,
timescale=timescale,
waves=waves,
)
runner.test(
hdl_toplevel=toplevel,
test_module=module,
parameters=parameters,
extra_env=extra_env,
build_dir=sim_build,
timescale=timescale,
waves=waves,
)

View File

@@ -9,7 +9,7 @@ Authors:
*/
`resetall
`timescale 1ns / 1ps
`timescale 1ns / 1fs
`default_nettype none
/*
@@ -30,6 +30,8 @@ module test_taxi_eth_mac_phy_10g_fifo #
parameter logic PTP_TS_FMT_TOD = 1'b1,
parameter PTP_TS_FNS_W = 16,
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64,
parameter logic PTP_TS_COR_EN = PTP_TS_EN && (TX_GBX_IF_EN || RX_GBX_IF_EN),
parameter PTP_TS_COR_W = PTP_TS_FNS_W+4,
parameter PTP_TD_SDI_PIPELINE = 2,
parameter TX_TAG_W = 16,
parameter logic BIT_REVERSE = 1'b0,
@@ -119,9 +121,13 @@ 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 tx_ptp_ts_cor_sync;
logic [PTP_TS_COR_W-1:0] tx_ptp_ts_cor_val;
logic [PTP_TS_W-1:0] rx_ptp_ts_out;
logic rx_ptp_ts_step_out;
logic rx_ptp_locked;
logic rx_ptp_ts_cor_sync;
logic [PTP_TS_COR_W-1:0] rx_ptp_ts_cor_val;
logic stat_clk;
logic stat_rst;
@@ -164,6 +170,8 @@ taxi_eth_mac_phy_10g_fifo #(
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_FNS_W(PTP_TS_FNS_W),
.PTP_TS_W(PTP_TS_W),
.PTP_TS_COR_EN(PTP_TS_COR_EN),
.PTP_TS_COR_W(PTP_TS_COR_W),
.PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE),
.BIT_REVERSE(BIT_REVERSE),
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE),
@@ -263,9 +271,13 @@ uut (
.tx_ptp_ts_out(tx_ptp_ts_out),
.tx_ptp_ts_step_out(tx_ptp_ts_step_out),
.tx_ptp_locked(tx_ptp_locked),
.tx_ptp_ts_cor_sync(tx_ptp_ts_cor_sync),
.tx_ptp_ts_cor_val(tx_ptp_ts_cor_val),
.rx_ptp_ts_out(rx_ptp_ts_out),
.rx_ptp_ts_step_out(rx_ptp_ts_step_out),
.rx_ptp_locked(rx_ptp_locked),
.rx_ptp_ts_cor_sync(rx_ptp_ts_cor_sync),
.rx_ptp_ts_cor_val(rx_ptp_ts_cor_val),
/*
* Statistics