From 82fe5a6bdda2b5c1b1a097b451369e788fd8d636 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 7 Jun 2019 16:38:36 -0700 Subject: [PATCH] Add PTP timestamp capture logic to MACs --- rtl/axis_baser_rx_64.v | 64 ++++++++++++---- rtl/axis_baser_tx_64.v | 93 ++++++++++++++++++---- rtl/axis_gmii_rx.v | 72 +++++++++++------ rtl/axis_gmii_tx.v | 80 ++++++++++++++----- rtl/axis_xgmii_rx_32.v | 87 ++++++++++++++------- rtl/axis_xgmii_rx_64.v | 106 ++++++++++++++++++------- rtl/axis_xgmii_tx_32.v | 121 ++++++++++++++++++++--------- rtl/axis_xgmii_tx_64.v | 149 +++++++++++++++++++++++++++--------- rtl/eth_mac_10g.v | 127 ++++++++++++++++++++++-------- rtl/eth_mac_1g.v | 98 ++++++++++++++++-------- rtl/eth_mac_phy_10g.v | 100 ++++++++++++++++-------- rtl/eth_mac_phy_10g_rx.v | 54 ++++++++----- rtl/eth_mac_phy_10g_tx.v | 56 ++++++++++---- tb/test_axis_baser_rx_64.py | 9 ++- tb/test_axis_baser_rx_64.v | 19 ++++- tb/test_axis_baser_tx_64.py | 17 +++- tb/test_axis_baser_tx_64.v | 30 +++++++- tb/test_axis_gmii_rx.py | 14 +++- tb/test_axis_gmii_rx.v | 21 +++-- tb/test_axis_gmii_tx.py | 21 ++++- tb/test_axis_gmii_tx.v | 32 +++++++- tb/test_axis_xgmii_rx_32.py | 22 ++++-- tb/test_axis_xgmii_rx_32.v | 32 ++++++-- tb/test_axis_xgmii_rx_64.py | 22 ++++-- tb/test_axis_xgmii_rx_64.v | 34 ++++++-- tb/test_axis_xgmii_tx_32.py | 30 ++++++-- tb/test_axis_xgmii_tx_32.v | 44 +++++++++-- tb/test_axis_xgmii_tx_64.py | 30 ++++++-- tb/test_axis_xgmii_tx_64.v | 46 +++++++++-- tb/test_eth_mac_10g_32.py | 23 +++++- tb/test_eth_mac_10g_32.v | 37 ++++++++- tb/test_eth_mac_10g_64.py | 25 +++++- tb/test_eth_mac_10g_64.v | 41 +++++++++- tb/test_eth_mac_1g.py | 32 ++++++-- tb/test_eth_mac_1g.v | 47 ++++++++++-- tb/test_eth_mac_phy_10g.py | 24 +++++- tb/test_eth_mac_phy_10g.v | 39 +++++++++- 37 files changed, 1471 insertions(+), 427 deletions(-) diff --git a/rtl/axis_baser_rx_64.v b/rtl/axis_baser_rx_64.v index 6916911b6..e37b8294c 100644 --- a/rtl/axis_baser_rx_64.v +++ b/rtl/axis_baser_rx_64.v @@ -33,34 +33,44 @@ module axis_baser_rx_64 # ( parameter DATA_WIDTH = 64, parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter HDR_WIDTH = 2 + parameter HDR_WIDTH = 2, + parameter PTP_PERIOD_NS = 4'h6, + parameter PTP_PERIOD_FNS = 16'h6666, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * 10GBASE-R encoded input */ - input wire [DATA_WIDTH-1:0] encoded_rx_data, - input wire [HDR_WIDTH-1:0] encoded_rx_hdr, + input wire [DATA_WIDTH-1:0] encoded_rx_data, + input wire [HDR_WIDTH-1:0] encoded_rx_hdr, /* * AXI output */ - output wire [DATA_WIDTH-1:0] m_axis_tdata, - output wire [KEEP_WIDTH-1:0] m_axis_tkeep, - output wire m_axis_tvalid, - output wire m_axis_tlast, - output wire m_axis_tuser, + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + output wire m_axis_tlast, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, /* * Status */ - output wire [1:0] start_packet, - output wire error_bad_frame, - output wire error_bad_fcs, - output wire rx_bad_block + output wire [1:0] start_packet, + output wire error_bad_frame, + output wire error_bad_fcs, + output wire rx_bad_block ); // bus width assertions @@ -177,6 +187,8 @@ reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; reg rx_bad_block_reg = 1'b0; +reg [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0; + reg [31:0] crc_state = 32'hFFFFFFFF; reg [31:0] crc_state3 = 32'hFFFFFFFF; @@ -198,7 +210,7 @@ assign m_axis_tdata = m_axis_tdata_reg; assign m_axis_tkeep = m_axis_tkeep_reg; assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tlast = m_axis_tlast_reg; -assign m_axis_tuser = m_axis_tuser_reg; +assign m_axis_tuser = PTP_TS_ENABLE ? {ptp_ts_reg, m_axis_tuser_reg} : m_axis_tuser_reg; assign start_packet = start_packet_reg; assign error_bad_frame = error_bad_frame_reg; @@ -518,6 +530,28 @@ always @(posedge clk) begin end end + if (PTP_TS_WIDTH == 96 && $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin + // ns field rollover + ptp_ts_reg[45:16] <= $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000); + ptp_ts_reg[95:48] <= ptp_ts_reg[95:48] + 1; + end + + if (encoded_rx_hdr == SYNC_CTRL && encoded_rx_data[7:0] == BLOCK_TYPE_START_0) begin + if (PTP_TS_WIDTH == 96) begin + ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + ptp_ts_reg[95:48] <= ptp_ts[95:48]; + end else begin + ptp_ts_reg <= ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + end + end else if (encoded_rx_hdr == SYNC_CTRL && (encoded_rx_data[7:0] == BLOCK_TYPE_START_4 || encoded_rx_data[7:0] == BLOCK_TYPE_OS_START)) begin + if (PTP_TS_WIDTH == 96) begin + ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + ptp_ts_reg[95:48] <= ptp_ts[95:48]; + end else begin + ptp_ts_reg <= ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + end + end + m_axis_tdata_reg <= m_axis_tdata_next; m_axis_tkeep_reg <= m_axis_tkeep_next; m_axis_tlast_reg <= m_axis_tlast_next; diff --git a/rtl/axis_baser_tx_64.v b/rtl/axis_baser_tx_64.v index e7a62fa2b..4487053a2 100644 --- a/rtl/axis_baser_tx_64.v +++ b/rtl/axis_baser_tx_64.v @@ -36,38 +36,53 @@ module axis_baser_tx_64 # parameter HDR_WIDTH = 2, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, - parameter MIN_FRAME_LENGTH = 64 + parameter MIN_FRAME_LENGTH = 64, + parameter PTP_PERIOD_NS = 4'h6, + parameter PTP_PERIOD_FNS = 16'h6666, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter PTP_TAG_ENABLE = 0, + parameter PTP_TAG_WIDTH = 16, + parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * AXI input */ - input wire [DATA_WIDTH-1:0] s_axis_tdata, - input wire [KEEP_WIDTH-1:0] s_axis_tkeep, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire s_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [USER_WIDTH-1:0] s_axis_tuser, /* * 10GBASE-R encoded interface */ - output wire [DATA_WIDTH-1:0] encoded_tx_data, - output wire [HDR_WIDTH-1:0] encoded_tx_hdr, + output wire [DATA_WIDTH-1:0] encoded_tx_data, + output wire [HDR_WIDTH-1:0] encoded_tx_hdr, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, + output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts, + output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag, + output wire m_axis_ptp_ts_valid, /* * Configuration */ - input wire [7:0] ifg_delay, + input wire [7:0] ifg_delay, /* * Status */ - output wire [1:0] start_packet, - output wire error_underflow + output wire [1:0] start_packet, + output wire error_underflow ); // bus width assertions @@ -192,6 +207,11 @@ reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next; reg s_axis_tready_reg = 1'b0, s_axis_tready_next; +reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_reg = 0, m_axis_ptp_ts_next; +reg [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag_reg = 0, m_axis_ptp_ts_tag_next; +reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next; +reg m_axis_ptp_ts_valid_int_reg = 1'b0, m_axis_ptp_ts_valid_int_next; + reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next0; @@ -217,6 +237,10 @@ assign s_axis_tready = s_axis_tready_reg; assign encoded_tx_data = encoded_tx_data_reg; assign encoded_tx_hdr = encoded_tx_hdr_reg; +assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0; +assign m_axis_ptp_ts_tag = PTP_TS_ENABLE && PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; +assign m_axis_ptp_ts_valid = PTP_TS_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; + assign start_packet = start_packet_reg; assign error_underflow = error_underflow_reg; @@ -469,12 +493,26 @@ always @* begin s_tdata_next = s_tdata_reg; s_tkeep_next = s_tkeep_reg; + m_axis_ptp_ts_next = m_axis_ptp_ts_reg; + m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg; + m_axis_ptp_ts_valid_next = 1'b0; + m_axis_ptp_ts_valid_int_next = 1'b0; + output_data_next = s_tdata_reg; output_type_next = OUTPUT_TYPE_IDLE; start_packet_next = 2'b00; error_underflow_next = 1'b0; + if (m_axis_ptp_ts_valid_int_reg) begin + m_axis_ptp_ts_valid_next = 1'b1; + if (PTP_TS_WIDTH == 96 && $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin + // ns field rollover + m_axis_ptp_ts_next[45:16] <= $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000); + m_axis_ptp_ts_next[95:48] <= m_axis_ptp_ts_reg[95:48] + 1; + end + end + case (state_reg) STATE_IDLE: begin // idle state - wait for data @@ -493,10 +531,26 @@ always @* begin if (ifg_count_reg > 8'd0) begin // need to send more idles - swap lanes swap_lanes = 1'b1; + if (PTP_TS_WIDTH == 96) begin + m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48]; + end else begin + m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + end + m_axis_ptp_ts_tag_next = s_axis_tuser >> 1; + m_axis_ptp_ts_valid_int_next = 1'b1; start_packet_next = 2'b10; end else begin // no more idles - unswap unswap_lanes = 1'b1; + if (PTP_TS_WIDTH == 96) begin + m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48]; + end else begin + m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + end + m_axis_ptp_ts_tag_next = s_axis_tuser >> 1; + m_axis_ptp_ts_valid_int_next = 1'b1; start_packet_next = 2'b01; end output_data_next = {ETH_SFD, {7{ETH_PRE}}}; @@ -527,7 +581,7 @@ always @* begin if (s_axis_tlast) begin frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep); s_axis_tready_next = 1'b0; - if (s_axis_tuser) begin + if (s_axis_tuser[0]) begin output_type_next = OUTPUT_TYPE_ERROR; frame_ptr_next = 16'd0; ifg_count_next = 8'd8; @@ -721,6 +775,9 @@ always @(posedge clk) begin s_axis_tready_reg <= 1'b0; + m_axis_ptp_ts_valid_reg <= 1'b0; + m_axis_ptp_ts_valid_int_reg <= 1'b0; + encoded_tx_data_reg <= {{8{CTRL_IDLE}}, BLOCK_TYPE_CTRL}; encoded_tx_hdr_reg <= SYNC_CTRL; @@ -745,6 +802,9 @@ always @(posedge clk) begin deficit_idle_count_reg <= deficit_idle_count_next; s_axis_tready_reg <= s_axis_tready_next; + + m_axis_ptp_ts_valid_reg <= m_axis_ptp_ts_valid_next; + m_axis_ptp_ts_valid_int_reg <= m_axis_ptp_ts_valid_int_next; start_packet_reg <= start_packet_next; error_underflow_reg <= error_underflow_next; @@ -845,6 +905,9 @@ always @(posedge clk) begin s_tdata_reg <= s_tdata_next; s_tkeep_reg <= s_tkeep_next; + m_axis_ptp_ts_reg <= m_axis_ptp_ts_next; + m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next; + swap_data <= output_data_next[63:32]; delay_type <= output_type_next ^ 4'd4; diff --git a/rtl/axis_gmii_rx.v b/rtl/axis_gmii_rx.v index c6a52f655..b09240162 100644 --- a/rtl/axis_gmii_rx.v +++ b/rtl/axis_gmii_rx.v @@ -29,40 +29,59 @@ THE SOFTWARE. /* * AXI4-Stream GMII frame receiver (GMII in, AXI out) */ -module axis_gmii_rx +module axis_gmii_rx # ( - input wire clk, - input wire rst, + parameter DATA_WIDTH = 8, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1 +) +( + input wire clk, + input wire rst, /* * GMII input */ - input wire [7:0] gmii_rxd, - input wire gmii_rx_dv, - input wire gmii_rx_er, + input wire [DATA_WIDTH-1:0] gmii_rxd, + input wire gmii_rx_dv, + input wire gmii_rx_er, /* * AXI output */ - output wire [7:0] m_axis_tdata, - output wire m_axis_tvalid, - output wire m_axis_tlast, - output wire m_axis_tuser, + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire m_axis_tvalid, + output wire m_axis_tlast, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, /* * Control */ - input wire clk_enable, - input wire mii_select, + input wire clk_enable, + input wire mii_select, /* * Status */ - output wire start_packet, - output wire error_bad_frame, - output wire error_bad_fcs + output wire start_packet, + output wire error_bad_frame, + output wire error_bad_fcs ); +// bus width assertions +initial begin + if (DATA_WIDTH != 8) begin + $error("Error: Interface width must be 8"); + $finish; + end +end + localparam [7:0] ETH_PRE = 8'h55, ETH_SFD = 8'hD5; @@ -81,11 +100,11 @@ reg update_crc; reg mii_odd = 1'b0; reg mii_locked = 1'b0; -reg [7:0] gmii_rxd_d0 = 8'd0; -reg [7:0] gmii_rxd_d1 = 8'd0; -reg [7:0] gmii_rxd_d2 = 8'd0; -reg [7:0] gmii_rxd_d3 = 8'd0; -reg [7:0] gmii_rxd_d4 = 8'd0; +reg [DATA_WIDTH-1:0] gmii_rxd_d0 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] gmii_rxd_d1 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] gmii_rxd_d2 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] gmii_rxd_d3 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] gmii_rxd_d4 = {DATA_WIDTH{1'b0}}; reg gmii_rx_dv_d0 = 1'b0; reg gmii_rx_dv_d1 = 1'b0; @@ -99,7 +118,7 @@ reg gmii_rx_er_d2 = 1'b0; reg gmii_rx_er_d3 = 1'b0; reg gmii_rx_er_d4 = 1'b0; -reg [7:0] m_axis_tdata_reg = 8'd0, m_axis_tdata_next; +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}, m_axis_tdata_next; reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; @@ -108,13 +127,15 @@ reg start_packet_reg = 1'b0, start_packet_next; reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; +reg [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0, ptp_ts_next; + reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next; assign m_axis_tdata = m_axis_tdata_reg; assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tlast = m_axis_tlast_reg; -assign m_axis_tuser = m_axis_tuser_reg; +assign m_axis_tuser = PTP_TS_ENABLE ? {ptp_ts_reg, m_axis_tuser_reg} : m_axis_tuser_reg; assign start_packet = start_packet_reg; assign error_bad_frame = error_bad_frame_reg; @@ -142,7 +163,7 @@ always @* begin reset_crc = 1'b0; update_crc = 1'b0; - m_axis_tdata_next = 8'd0; + m_axis_tdata_next = {DATA_WIDTH{1'b0}}; m_axis_tvalid_next = 1'b0; m_axis_tlast_next = 1'b0; m_axis_tuser_next = 1'b0; @@ -151,6 +172,8 @@ always @* begin error_bad_frame_next = 1'b0; error_bad_fcs_next = 1'b0; + ptp_ts_next = ptp_ts_reg; + if (!clk_enable) begin // clock disabled - hold state state_next = state_reg; @@ -164,6 +187,7 @@ always @* begin reset_crc = 1'b1; if (gmii_rx_dv_d4 && !gmii_rx_er_d4 && gmii_rxd_d4 == ETH_SFD) begin + ptp_ts_next = ptp_ts; start_packet_next = 1'b1; state_next = STATE_PAYLOAD; end else begin @@ -283,6 +307,8 @@ always @(posedge clk) begin end end + ptp_ts_reg <= ptp_ts_next; + m_axis_tdata_reg <= m_axis_tdata_next; m_axis_tlast_reg <= m_axis_tlast_next; m_axis_tuser_reg <= m_axis_tuser_next; diff --git a/rtl/axis_gmii_tx.v b/rtl/axis_gmii_tx.v index 0acdab337..e16ef2ed8 100644 --- a/rtl/axis_gmii_tx.v +++ b/rtl/axis_gmii_tx.v @@ -31,47 +31,69 @@ THE SOFTWARE. */ module axis_gmii_tx # ( + parameter DATA_WIDTH = 8, parameter ENABLE_PADDING = 1, - parameter MIN_FRAME_LENGTH = 64 + parameter MIN_FRAME_LENGTH = 64, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter PTP_TAG_ENABLE = 0, + parameter PTP_TAG_WIDTH = 16, + parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * AXI input */ - input wire [7:0] s_axis_tdata, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire s_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [USER_WIDTH-1:0] s_axis_tuser, /* * GMII output */ - output wire [7:0] gmii_txd, - output wire gmii_tx_en, - output wire gmii_tx_er, + output wire [DATA_WIDTH-1:0] gmii_txd, + output wire gmii_tx_en, + output wire gmii_tx_er, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, + output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts, + output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag, + output wire m_axis_ptp_ts_valid, /* * Control */ - input wire clk_enable, - input wire mii_select, + input wire clk_enable, + input wire mii_select, /* * Configuration */ - input wire [7:0] ifg_delay, + input wire [7:0] ifg_delay, /* * Status */ - output wire start_packet, - output wire error_underflow + output wire start_packet, + output wire error_underflow ); +// bus width assertions +initial begin + if (DATA_WIDTH != 8) begin + $error("Error: Interface width must be 8"); + $finish; + end +end + localparam [7:0] ETH_PRE = 8'h55, ETH_SFD = 8'hD5; @@ -105,6 +127,10 @@ reg gmii_tx_er_reg = 1'b0, gmii_tx_er_next; reg s_axis_tready_reg = 1'b0, s_axis_tready_next; +reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_reg = 0, m_axis_ptp_ts_next; +reg [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag_reg = 0, m_axis_ptp_ts_tag_next; +reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next; + reg start_packet_reg = 1'b0, start_packet_next; reg error_underflow_reg = 1'b0, error_underflow_next; @@ -117,6 +143,10 @@ assign gmii_txd = gmii_txd_reg; assign gmii_tx_en = gmii_tx_en_reg; assign gmii_tx_er = gmii_tx_er_reg; +assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0; +assign m_axis_ptp_ts_tag = PTP_TS_ENABLE && PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; +assign m_axis_ptp_ts_valid = PTP_TS_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; + assign start_packet = start_packet_reg; assign error_underflow = error_underflow_reg; @@ -151,7 +181,11 @@ always @* begin s_tdata_next = s_tdata_reg; - gmii_txd_next = 8'd0; + m_axis_ptp_ts_next = m_axis_ptp_ts_reg; + m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg; + m_axis_ptp_ts_valid_next = 1'b0; + + gmii_txd_next = {DATA_WIDTH{1'b0}}; gmii_tx_en_next = 1'b0; gmii_tx_er_next = 1'b0; @@ -210,6 +244,9 @@ always @* begin s_tdata_next = s_axis_tdata; end gmii_txd_next = ETH_SFD; + m_axis_ptp_ts_next = ptp_ts; + m_axis_ptp_ts_tag_next = s_axis_tuser >> 1; + m_axis_ptp_ts_valid_next = 1'b1; start_packet_next = 1'b1; state_next = STATE_PAYLOAD; end else begin @@ -233,7 +270,7 @@ always @* begin if (s_axis_tvalid) begin if (s_axis_tlast) begin s_axis_tready_next = !s_axis_tready_reg; - if (s_axis_tuser) begin + if (s_axis_tuser[0]) begin gmii_tx_er_next = 1'b1; frame_ptr_next = 1'b0; state_next = STATE_IFG; @@ -365,6 +402,8 @@ always @(posedge clk) begin s_axis_tready_reg <= 1'b0; + m_axis_ptp_ts_valid_reg <= 1'b0; + gmii_tx_en_reg <= 1'b0; gmii_tx_er_reg <= 1'b0; @@ -378,6 +417,8 @@ always @(posedge clk) begin frame_ptr_reg <= frame_ptr_next; s_axis_tready_reg <= s_axis_tready_next; + + m_axis_ptp_ts_valid_reg <= m_axis_ptp_ts_valid_next; gmii_tx_en_reg <= gmii_tx_en_next; gmii_tx_er_reg <= gmii_tx_er_next; @@ -393,6 +434,9 @@ always @(posedge clk) begin end end + m_axis_ptp_ts_reg <= m_axis_ptp_ts_next; + m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next; + mii_odd_reg <= mii_odd_next; mii_msn_reg <= mii_msn_next; diff --git a/rtl/axis_xgmii_rx_32.v b/rtl/axis_xgmii_rx_32.v index 5710b7d26..65fafe901 100644 --- a/rtl/axis_xgmii_rx_32.v +++ b/rtl/axis_xgmii_rx_32.v @@ -29,34 +29,60 @@ THE SOFTWARE. /* * AXI4-Stream XGMII frame receiver (XGMII in, AXI out) */ -module axis_xgmii_rx_32 +module axis_xgmii_rx_32 # ( - input wire clk, - input wire rst, + parameter DATA_WIDTH = 32, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter CTRL_WIDTH = (DATA_WIDTH/8), + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1 +) +( + input wire clk, + input wire rst, /* * XGMII input */ - input wire [31:0] xgmii_rxd, - input wire [3:0] xgmii_rxc, + input wire [DATA_WIDTH-1:0] xgmii_rxd, + input wire [CTRL_WIDTH-1:0] xgmii_rxc, /* * AXI output */ - output wire [31:0] m_axis_tdata, - output wire [3:0] m_axis_tkeep, - output wire m_axis_tvalid, - output wire m_axis_tlast, - output wire m_axis_tuser, + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + output wire m_axis_tlast, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, /* * Status */ - output wire start_packet, - output wire error_bad_frame, - output wire error_bad_fcs + output wire start_packet, + output wire error_bad_frame, + output wire error_bad_fcs ); +// bus width assertions +initial begin + if (DATA_WIDTH != 32) begin + $error("Error: Interface width must be 32"); + $finish; + end + + if (KEEP_WIDTH * 8 != DATA_WIDTH || CTRL_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: Interface requires byte (8-bit) granularity"); + $finish; + end +end + localparam [7:0] ETH_PRE = 8'h55, ETH_SFD = 8'hD5; @@ -81,16 +107,16 @@ reg update_crc; reg [3:0] last_cycle_tkeep_reg = 4'd0, last_cycle_tkeep_next; -reg [31:0] xgmii_rxd_d0 = 32'd0; -reg [31:0] xgmii_rxd_d1 = 32'd0; -reg [31:0] xgmii_rxd_d2 = 32'd0; +reg [DATA_WIDTH-1:0] xgmii_rxd_d0 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] xgmii_rxd_d1 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] xgmii_rxd_d2 = {DATA_WIDTH{1'b0}}; -reg [3:0] xgmii_rxc_d0 = 4'd0; -reg [3:0] xgmii_rxc_d1 = 4'd0; -reg [3:0] xgmii_rxc_d2 = 4'd0; +reg [CTRL_WIDTH-1:0] xgmii_rxc_d0 = {CTRL_WIDTH{1'b0}}; +reg [CTRL_WIDTH-1:0] xgmii_rxc_d1 = {CTRL_WIDTH{1'b0}}; +reg [CTRL_WIDTH-1:0] xgmii_rxc_d2 = {CTRL_WIDTH{1'b0}}; -reg [31:0] m_axis_tdata_reg = 32'd0, m_axis_tdata_next; -reg [3:0] m_axis_tkeep_reg = 4'd0, m_axis_tkeep_next; +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}, m_axis_tdata_next; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}, m_axis_tkeep_next; reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; @@ -99,6 +125,8 @@ reg start_packet_reg = 1'b0, start_packet_next; reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; +reg [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0, ptp_ts_next; + reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next0; @@ -120,7 +148,7 @@ assign m_axis_tdata = m_axis_tdata_reg; assign m_axis_tkeep = m_axis_tkeep_reg; assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tlast = m_axis_tlast_reg; -assign m_axis_tuser = m_axis_tuser_reg; +assign m_axis_tuser = PTP_TS_ENABLE ? {ptp_ts_reg, m_axis_tuser_reg} : m_axis_tuser_reg; assign start_packet = start_packet_reg; assign error_bad_frame = error_bad_frame_reg; @@ -257,8 +285,8 @@ always @* begin last_cycle_tkeep_next = last_cycle_tkeep_reg; - m_axis_tdata_next = 32'd0; - m_axis_tkeep_next = 4'd0; + m_axis_tdata_next = {DATA_WIDTH{1'b0}}; + m_axis_tkeep_next = {KEEP_WIDTH{1'b0}}; m_axis_tvalid_next = 1'b0; m_axis_tlast_next = 1'b0; m_axis_tuser_next = 1'b0; @@ -267,6 +295,8 @@ always @* begin error_bad_frame_next = 1'b0; error_bad_fcs_next = 1'b0; + ptp_ts_next = ptp_ts_reg; + case (state_reg) STATE_IDLE: begin // idle state - wait for packet @@ -276,7 +306,7 @@ always @* begin // start condition if (control_masked) begin // control or error characters in first data word - m_axis_tdata_next = 32'd0; + m_axis_tdata_next = {DATA_WIDTH{1'b0}}; m_axis_tkeep_next = 4'h1; m_axis_tvalid_next = 1'b1; m_axis_tlast_next = 1'b1; @@ -295,6 +325,7 @@ always @* begin STATE_PREAMBLE: begin // drop preamble update_crc = 1'b1; + ptp_ts_next = ptp_ts; start_packet_next = 1'b1; state_next = STATE_PAYLOAD; end @@ -379,8 +410,8 @@ always @(posedge clk) begin crc_valid2_save <= 1'b0; crc_valid3_save <= 1'b0; - xgmii_rxc_d0 <= 4'd0; - xgmii_rxc_d1 <= 4'd0; + xgmii_rxc_d0 <= {CTRL_WIDTH{1'b0}}; + xgmii_rxc_d1 <= {CTRL_WIDTH{1'b0}}; end else begin state_reg <= state_next; @@ -415,6 +446,8 @@ always @(posedge clk) begin m_axis_tlast_reg <= m_axis_tlast_next; m_axis_tuser_reg <= m_axis_tuser_next; + ptp_ts_reg <= ptp_ts_next; + last_cycle_tkeep_reg <= last_cycle_tkeep_next; detect_term_save <= detect_term; diff --git a/rtl/axis_xgmii_rx_64.v b/rtl/axis_xgmii_rx_64.v index 96e438998..45838e0ee 100644 --- a/rtl/axis_xgmii_rx_64.v +++ b/rtl/axis_xgmii_rx_64.v @@ -29,34 +29,62 @@ THE SOFTWARE. /* * AXI4-Stream XGMII frame receiver (XGMII in, AXI out) */ -module axis_xgmii_rx_64 +module axis_xgmii_rx_64 # ( - input wire clk, - input wire rst, + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter CTRL_WIDTH = (DATA_WIDTH/8), + parameter PTP_PERIOD_NS = 4'h6, + parameter PTP_PERIOD_FNS = 16'h6666, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1 +) +( + input wire clk, + input wire rst, /* * XGMII input */ - input wire [63:0] xgmii_rxd, - input wire [7:0] xgmii_rxc, + input wire [DATA_WIDTH-1:0] xgmii_rxd, + input wire [CTRL_WIDTH-1:0] xgmii_rxc, /* * AXI output */ - output wire [63:0] m_axis_tdata, - output wire [7:0] m_axis_tkeep, - output wire m_axis_tvalid, - output wire m_axis_tlast, - output wire m_axis_tuser, + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + output wire m_axis_tlast, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, /* * Status */ - output wire [1:0] start_packet, - output wire error_bad_frame, - output wire error_bad_fcs + output wire [1:0] start_packet, + output wire error_bad_frame, + output wire error_bad_fcs ); +// bus width assertions +initial begin + if (DATA_WIDTH != 64) begin + $error("Error: Interface width must be 64"); + $finish; + end + + if (KEEP_WIDTH * 8 != DATA_WIDTH || CTRL_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: Interface requires byte (8-bit) granularity"); + $finish; + end +end + localparam [7:0] ETH_PRE = 8'h55, ETH_SFD = 8'hD5; @@ -84,15 +112,15 @@ reg lanes_swapped = 1'b0; reg [31:0] swap_rxd = 32'd0; reg [3:0] swap_rxc = 4'd0; -reg [63:0] xgmii_rxd_d0 = 32'd0; -reg [63:0] xgmii_rxd_d1 = 32'd0; -reg [63:0] xgmii_rxd_crc = 32'd0; +reg [DATA_WIDTH-1:0] xgmii_rxd_d0 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] xgmii_rxd_d1 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] xgmii_rxd_crc = {DATA_WIDTH{1'b0}}; -reg [7:0] xgmii_rxc_d0 = 8'd0; -reg [7:0] xgmii_rxc_d1 = 8'd0; +reg [CTRL_WIDTH-1:0] xgmii_rxc_d0 = {CTRL_WIDTH{1'b0}}; +reg [CTRL_WIDTH-1:0] xgmii_rxc_d1 = {CTRL_WIDTH{1'b0}}; -reg [63:0] m_axis_tdata_reg = 64'd0, m_axis_tdata_next; -reg [7:0] m_axis_tkeep_reg = 8'd0, m_axis_tkeep_next; +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}, m_axis_tdata_next; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}, m_axis_tkeep_next; reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; @@ -101,6 +129,8 @@ reg [1:0] start_packet_reg = 2'b00; reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; +reg [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0; + reg [31:0] crc_state = 32'hFFFFFFFF; reg [31:0] crc_state3 = 32'hFFFFFFFF; @@ -122,7 +152,7 @@ assign m_axis_tdata = m_axis_tdata_reg; assign m_axis_tkeep = m_axis_tkeep_reg; assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tlast = m_axis_tlast_reg; -assign m_axis_tuser = m_axis_tuser_reg; +assign m_axis_tuser = PTP_TS_ENABLE ? {ptp_ts_reg, m_axis_tuser_reg} : m_axis_tuser_reg; assign start_packet = start_packet_reg; assign error_bad_frame = error_bad_frame_reg; @@ -295,8 +325,8 @@ always @* begin last_cycle_tkeep_next = last_cycle_tkeep_reg; - m_axis_tdata_next = 64'd0; - m_axis_tkeep_next = 8'd0; + m_axis_tdata_next = {DATA_WIDTH{1'b0}}; + m_axis_tkeep_next = {KEEP_WIDTH{1'b0}}; m_axis_tvalid_next = 1'b0; m_axis_tlast_next = 1'b0; m_axis_tuser_next = 1'b0; @@ -313,7 +343,7 @@ always @* begin // start condition if (control_masked) begin // control or error characters in first data word - m_axis_tdata_next = 64'd0; + m_axis_tdata_next = {DATA_WIDTH{1'b0}}; m_axis_tkeep_next = 8'h01; m_axis_tvalid_next = 1'b1; m_axis_tlast_next = 1'b1; @@ -397,7 +427,7 @@ always @* begin // start condition if (control_masked) begin // control or error characters in first data word - m_axis_tdata_next = 64'd0; + m_axis_tdata_next = {DATA_WIDTH{1'b0}}; m_axis_tkeep_next = 8'h01; m_axis_tvalid_next = 1'b1; m_axis_tlast_next = 1'b1; @@ -430,8 +460,8 @@ always @(posedge clk) begin crc_state3 <= 32'hFFFFFFFF; crc_valid7_save <= 1'b0; - xgmii_rxc_d0 <= 8'd0; - xgmii_rxc_d1 <= 8'd0; + xgmii_rxc_d0 <= {CTRL_WIDTH{1'b0}}; + xgmii_rxc_d1 <= {CTRL_WIDTH{1'b0}}; lanes_swapped <= 1'b0; end else begin @@ -471,6 +501,28 @@ always @(posedge clk) begin end end + if (PTP_TS_WIDTH == 96 && $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin + // ns field rollover + ptp_ts_reg[45:16] <= $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000); + ptp_ts_reg[95:48] <= ptp_ts_reg[95:48] + 1; + end + + if (xgmii_rxc[0] && xgmii_rxd[7:0] == XGMII_START) begin + if (PTP_TS_WIDTH == 96) begin + ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + ptp_ts_reg[95:48] <= ptp_ts[95:48]; + end else begin + ptp_ts_reg <= ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + end + end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == XGMII_START) begin + if (PTP_TS_WIDTH == 96) begin + ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + ptp_ts_reg[95:48] <= ptp_ts[95:48]; + end else begin + ptp_ts_reg <= ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + end + end + m_axis_tdata_reg <= m_axis_tdata_next; m_axis_tkeep_reg <= m_axis_tkeep_next; m_axis_tlast_reg <= m_axis_tlast_next; diff --git a/rtl/axis_xgmii_tx_32.v b/rtl/axis_xgmii_tx_32.v index ea2ac38fc..0eae6d15e 100644 --- a/rtl/axis_xgmii_tx_32.v +++ b/rtl/axis_xgmii_tx_32.v @@ -31,42 +31,71 @@ THE SOFTWARE. */ module axis_xgmii_tx_32 # ( + parameter DATA_WIDTH = 32, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter CTRL_WIDTH = (DATA_WIDTH/8), parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, - parameter MIN_FRAME_LENGTH = 64 + parameter MIN_FRAME_LENGTH = 64, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter PTP_TAG_ENABLE = 0, + parameter PTP_TAG_WIDTH = 16, + parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * AXI input */ - input wire [31:0] s_axis_tdata, - input wire [3:0] s_axis_tkeep, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire s_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [USER_WIDTH-1:0] s_axis_tuser, /* * XGMII output */ - output wire [31:0] xgmii_txd, - output wire [3:0] xgmii_txc, + output wire [DATA_WIDTH-1:0] xgmii_txd, + output wire [CTRL_WIDTH-1:0] xgmii_txc, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, + output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts, + output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag, + output wire m_axis_ptp_ts_valid, /* * Configuration */ - input wire [7:0] ifg_delay, + input wire [7:0] ifg_delay, /* * Status */ - output wire start_packet, - output wire error_underflow + output wire start_packet, + output wire error_underflow ); +// bus width assertions +initial begin + if (DATA_WIDTH != 32) begin + $error("Error: Interface width must be 32"); + $finish; + end + + if (KEEP_WIDTH * 8 != DATA_WIDTH || CTRL_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: Interface requires byte (8-bit) granularity"); + $finish; + end +end + localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4; localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfffc; localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0003; @@ -98,15 +127,15 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg reset_crc; reg update_crc; -reg [31:0] s_axis_tdata_masked; +reg [DATA_WIDTH-1:0] s_axis_tdata_masked; -reg [31:0] s_tdata_reg = 64'd0, s_tdata_next; -reg [3:0] s_tkeep_reg = 8'd0, s_tkeep_next; +reg [DATA_WIDTH-1:0] s_tdata_reg ={DATA_WIDTH{1'b0}}, s_tdata_next; +reg [KEEP_WIDTH-1:0] s_tkeep_reg = {KEEP_WIDTH{1'b0}}, s_tkeep_next; -reg [31:0] fcs_output_txd_0; -reg [31:0] fcs_output_txd_1; -reg [3:0] fcs_output_txc_0; -reg [3:0] fcs_output_txc_1; +reg [DATA_WIDTH-1:0] fcs_output_txd_0; +reg [DATA_WIDTH-1:0] fcs_output_txd_1; +reg [CTRL_WIDTH-1:0] fcs_output_txc_0; +reg [CTRL_WIDTH-1:0] fcs_output_txc_1; reg [7:0] ifg_offset; @@ -119,6 +148,10 @@ reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next; reg s_axis_tready_reg = 1'b0, s_axis_tready_next; +reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_reg = 0, m_axis_ptp_ts_next; +reg [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag_reg = 0, m_axis_ptp_ts_tag_next; +reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next; + reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next0; @@ -126,8 +159,8 @@ wire [31:0] crc_next1; wire [31:0] crc_next2; wire [31:0] crc_next3; -reg [31:0] xgmii_txd_reg = {4{XGMII_IDLE}}, xgmii_txd_next; -reg [3:0] xgmii_txc_reg = 4'b1111, xgmii_txc_next; +reg [DATA_WIDTH-1:0] xgmii_txd_reg = {CTRL_WIDTH{XGMII_IDLE}}, xgmii_txd_next; +reg [CTRL_WIDTH-1:0] xgmii_txc_reg = {CTRL_WIDTH{1'b1}}, xgmii_txc_next; reg start_packet_reg = 1'b0, start_packet_next; reg error_underflow_reg = 1'b0, error_underflow_next; @@ -137,6 +170,10 @@ assign s_axis_tready = s_axis_tready_reg; assign xgmii_txd = xgmii_txd_reg; assign xgmii_txc = xgmii_txc_reg; +assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0; +assign m_axis_ptp_ts_tag = PTP_TS_ENABLE && PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; +assign m_axis_ptp_ts_valid = PTP_TS_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; + assign start_packet = start_packet_reg; assign error_underflow = error_underflow_reg; @@ -260,10 +297,10 @@ always @* begin extra_cycle = 1'b1; end default: begin - fcs_output_txd_0 = {4{XGMII_ERROR}}; - fcs_output_txd_1 = {4{XGMII_ERROR}}; - fcs_output_txc_0 = 4'b1111; - fcs_output_txc_1 = 4'b1111; + fcs_output_txd_0 = {CTRL_WIDTH{XGMII_ERROR}}; + fcs_output_txd_1 = {CTRL_WIDTH{XGMII_ERROR}}; + fcs_output_txc_0 = {CTRL_WIDTH{1'b1}}; + fcs_output_txc_1 = {CTRL_WIDTH{1'b1}}; ifg_offset = 8'd0; extra_cycle = 1'b0; end @@ -286,9 +323,13 @@ always @* begin s_tdata_next = s_tdata_reg; s_tkeep_next = s_tkeep_reg; + m_axis_ptp_ts_next = m_axis_ptp_ts_reg; + m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg; + m_axis_ptp_ts_valid_next = 1'b0; + // XGMII idle - xgmii_txd_next = {4{XGMII_IDLE}}; - xgmii_txc_next = 4'b1111; + xgmii_txd_next = {CTRL_WIDTH{XGMII_IDLE}}; + xgmii_txc_next = {CTRL_WIDTH{1'b1}}; start_packet_next = 1'b0; error_underflow_next = 1'b0; @@ -300,8 +341,8 @@ always @* begin reset_crc = 1'b1; // XGMII idle - xgmii_txd_next = {4{XGMII_IDLE}}; - xgmii_txc_next = 4'b1111; + xgmii_txd_next = {CTRL_WIDTH{XGMII_IDLE}}; + xgmii_txc_next = {CTRL_WIDTH{1'b1}}; s_tdata_next = s_axis_tdata_masked; s_tkeep_next = s_axis_tkeep; @@ -327,6 +368,9 @@ always @* begin xgmii_txd_next = {ETH_SFD, {3{ETH_PRE}}}; xgmii_txc_next = 4'b0000; s_axis_tready_next = 1'b1; + m_axis_ptp_ts_next = ptp_ts; + m_axis_ptp_ts_tag_next = s_axis_tuser >> 1; + m_axis_ptp_ts_valid_next = 1'b1; start_packet_next = 1'b1; state_next = STATE_PAYLOAD; end @@ -347,7 +391,7 @@ always @* begin if (s_axis_tlast) begin frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep); s_axis_tready_next = 1'b0; - if (s_axis_tuser) begin + if (s_axis_tuser[0]) begin xgmii_txd_next = {XGMII_TERM, {3{XGMII_ERROR}}}; xgmii_txc_next = 4'b1111; frame_ptr_next = 16'd0; @@ -389,7 +433,7 @@ always @* begin s_axis_tready_next = 1'b0; xgmii_txd_next = s_tdata_reg; - xgmii_txc_next = 4'b0000; + xgmii_txc_next = {CTRL_WIDTH{1'b0}}; s_tdata_next = 32'd0; s_tkeep_next = 4'hf; @@ -537,8 +581,10 @@ always @(posedge clk) begin s_axis_tready_reg <= 1'b0; - xgmii_txd_reg <= {4{XGMII_IDLE}}; - xgmii_txc_reg <= 4'b1111; + m_axis_ptp_ts_valid_reg <= 1'b0; + + xgmii_txd_reg <= {CTRL_WIDTH{XGMII_IDLE}}; + xgmii_txc_reg <= {CTRL_WIDTH{1'b1}}; start_packet_reg <= 1'b0; error_underflow_reg <= 1'b0; @@ -553,6 +599,8 @@ always @(posedge clk) begin deficit_idle_count_reg <= deficit_idle_count_next; s_axis_tready_reg <= s_axis_tready_next; + + m_axis_ptp_ts_valid_reg <= m_axis_ptp_ts_valid_next; xgmii_txd_reg <= xgmii_txd_next; xgmii_txc_reg <= xgmii_txc_next; @@ -570,6 +618,9 @@ always @(posedge clk) begin s_tdata_reg <= s_tdata_next; s_tkeep_reg <= s_tkeep_next; + + m_axis_ptp_ts_reg <= m_axis_ptp_ts_next; + m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next; end endmodule diff --git a/rtl/axis_xgmii_tx_64.v b/rtl/axis_xgmii_tx_64.v index fd3001844..67f30ce87 100644 --- a/rtl/axis_xgmii_tx_64.v +++ b/rtl/axis_xgmii_tx_64.v @@ -31,42 +31,73 @@ THE SOFTWARE. */ module axis_xgmii_tx_64 # ( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter CTRL_WIDTH = (DATA_WIDTH/8), parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, - parameter MIN_FRAME_LENGTH = 64 + parameter MIN_FRAME_LENGTH = 64, + parameter PTP_PERIOD_NS = 4'h6, + parameter PTP_PERIOD_FNS = 16'h6666, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter PTP_TAG_ENABLE = 0, + parameter PTP_TAG_WIDTH = 16, + parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * AXI input */ - input wire [63:0] s_axis_tdata, - input wire [7:0] s_axis_tkeep, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire s_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [USER_WIDTH-1:0] s_axis_tuser, /* * XGMII output */ - output wire [63:0] xgmii_txd, - output wire [7:0] xgmii_txc, + output wire [DATA_WIDTH-1:0] xgmii_txd, + output wire [CTRL_WIDTH-1:0] xgmii_txc, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, + output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts, + output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag, + output wire m_axis_ptp_ts_valid, /* * Configuration */ - input wire [7:0] ifg_delay, + input wire [7:0] ifg_delay, /* * Status */ - output wire [1:0] start_packet, - output wire error_underflow + output wire [1:0] start_packet, + output wire error_underflow ); +// bus width assertions +initial begin + if (DATA_WIDTH != 64) begin + $error("Error: Interface width must be 64"); + $finish; + end + + if (KEEP_WIDTH * 8 != DATA_WIDTH || CTRL_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: Interface requires byte (8-bit) granularity"); + $finish; + end +end + localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4; localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfff8; localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0007; @@ -103,15 +134,15 @@ reg lanes_swapped = 1'b0; reg [31:0] swap_txd = 32'd0; reg [3:0] swap_txc = 4'd0; -reg [63:0] s_axis_tdata_masked; +reg [DATA_WIDTH-1:0] s_axis_tdata_masked; -reg [63:0] s_tdata_reg = 64'd0, s_tdata_next; -reg [7:0] s_tkeep_reg = 8'd0, s_tkeep_next; +reg [DATA_WIDTH-1:0] s_tdata_reg = {DATA_WIDTH{1'b0}}, s_tdata_next; +reg [KEEP_WIDTH-1:0] s_tkeep_reg = {KEEP_WIDTH{1'b0}}, s_tkeep_next; -reg [63:0] fcs_output_txd_0; -reg [63:0] fcs_output_txd_1; -reg [7:0] fcs_output_txc_0; -reg [7:0] fcs_output_txc_1; +reg [DATA_WIDTH-1:0] fcs_output_txd_0; +reg [DATA_WIDTH-1:0] fcs_output_txd_1; +reg [CTRL_WIDTH-1:0] fcs_output_txc_0; +reg [CTRL_WIDTH-1:0] fcs_output_txc_1; reg [7:0] ifg_offset; @@ -124,6 +155,11 @@ reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next; reg s_axis_tready_reg = 1'b0, s_axis_tready_next; +reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_reg = 0, m_axis_ptp_ts_next; +reg [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag_reg = 0, m_axis_ptp_ts_tag_next; +reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next; +reg m_axis_ptp_ts_valid_int_reg = 1'b0, m_axis_ptp_ts_valid_int_next; + reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next0; @@ -135,8 +171,8 @@ wire [31:0] crc_next5; wire [31:0] crc_next6; wire [31:0] crc_next7; -reg [63:0] xgmii_txd_reg = {8{XGMII_IDLE}}, xgmii_txd_next; -reg [7:0] xgmii_txc_reg = 8'b11111111, xgmii_txc_next; +reg [DATA_WIDTH-1:0] xgmii_txd_reg = {CTRL_WIDTH{XGMII_IDLE}}, xgmii_txd_next; +reg [CTRL_WIDTH-1:0] xgmii_txc_reg = {CTRL_WIDTH{1'b1}}, xgmii_txc_next; reg start_packet_reg = 2'b00, start_packet_next; reg error_underflow_reg = 1'b0, error_underflow_next; @@ -146,6 +182,10 @@ assign s_axis_tready = s_axis_tready_reg; assign xgmii_txd = xgmii_txd_reg; assign xgmii_txc = xgmii_txc_reg; +assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0; +assign m_axis_ptp_ts_tag = PTP_TS_ENABLE && PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; +assign m_axis_ptp_ts_valid = PTP_TS_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; + assign start_packet = start_packet_reg; assign error_underflow = error_underflow_reg; @@ -369,10 +409,10 @@ always @* begin extra_cycle = 1'b1; end default: begin - fcs_output_txd_0 = {8{XGMII_ERROR}}; - fcs_output_txd_1 = {8{XGMII_ERROR}}; - fcs_output_txc_0 = 8'b11111111; - fcs_output_txc_1 = 8'b11111111; + fcs_output_txd_0 = {CTRL_WIDTH{XGMII_ERROR}}; + fcs_output_txd_1 = {CTRL_WIDTH{XGMII_ERROR}}; + fcs_output_txc_0 = {CTRL_WIDTH{1'b1}}; + fcs_output_txc_1 = {CTRL_WIDTH{1'b1}}; ifg_offset = 8'd0; extra_cycle = 1'b1; end @@ -398,13 +438,27 @@ always @* begin s_tdata_next = s_tdata_reg; s_tkeep_next = s_tkeep_reg; + m_axis_ptp_ts_next = m_axis_ptp_ts_reg; + m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg; + m_axis_ptp_ts_valid_next = 1'b0; + m_axis_ptp_ts_valid_int_next = 1'b0; + // XGMII idle - xgmii_txd_next = {8{XGMII_IDLE}}; - xgmii_txc_next = 8'b11111111; + xgmii_txd_next = {CTRL_WIDTH{XGMII_IDLE}}; + xgmii_txc_next = {CTRL_WIDTH{1'b1}}; start_packet_next = 2'b00; error_underflow_next = 1'b0; + if (m_axis_ptp_ts_valid_int_reg) begin + m_axis_ptp_ts_valid_next = 1'b1; + if (PTP_TS_WIDTH == 96 && $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin + // ns field rollover + m_axis_ptp_ts_next[45:16] <= $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000); + m_axis_ptp_ts_next[95:48] <= m_axis_ptp_ts_reg[95:48] + 1; + end + end + case (state_reg) STATE_IDLE: begin // idle state - wait for data @@ -413,8 +467,8 @@ always @* begin s_axis_tready_next = 1'b1; // XGMII idle - xgmii_txd_next = {8{XGMII_IDLE}}; - xgmii_txc_next = 8'b11111111; + xgmii_txd_next = {CTRL_WIDTH{XGMII_IDLE}}; + xgmii_txc_next = {CTRL_WIDTH{1'b1}}; s_tdata_next = s_axis_tdata_masked; s_tkeep_next = s_axis_tkeep; @@ -424,10 +478,26 @@ always @* begin if (ifg_count_reg > 8'd0) begin // need to send more idles - swap lanes swap_lanes = 1'b1; + if (PTP_TS_WIDTH == 96) begin + m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48]; + end else begin + m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + end + m_axis_ptp_ts_tag_next = s_axis_tuser >> 1; + m_axis_ptp_ts_valid_int_next = 1'b1; start_packet_next = 2'b10; end else begin // no more idles - unswap unswap_lanes = 1'b1; + if (PTP_TS_WIDTH == 96) begin + m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48]; + end else begin + m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + end + m_axis_ptp_ts_tag_next = s_axis_tuser >> 1; + m_axis_ptp_ts_valid_int_next = 1'b1; start_packet_next = 2'b01; end xgmii_txd_next = {ETH_SFD, {6{ETH_PRE}}, XGMII_START}; @@ -458,7 +528,7 @@ always @* begin if (s_axis_tlast) begin frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep); s_axis_tready_next = 1'b0; - if (s_axis_tuser) begin + if (s_axis_tuser[0]) begin xgmii_txd_next = {{3{XGMII_IDLE}}, XGMII_TERM, {4{XGMII_ERROR}}}; xgmii_txc_next = 8'b11111111; frame_ptr_next = 16'd0; @@ -500,7 +570,7 @@ always @* begin s_axis_tready_next = 1'b0; xgmii_txd_next = s_tdata_reg; - xgmii_txc_next = 8'b00000000; + xgmii_txc_next = {CTRL_WIDTH{1'b0}}; s_tdata_next = 64'd0; s_tkeep_next = 8'hff; @@ -654,8 +724,11 @@ always @(posedge clk) begin s_axis_tready_reg <= 1'b0; - xgmii_txd_reg <= {8{XGMII_IDLE}}; - xgmii_txc_reg <= 8'b11111111; + m_axis_ptp_ts_valid_reg <= 1'b0; + m_axis_ptp_ts_valid_int_reg <= 1'b0; + + xgmii_txd_reg <= {CTRL_WIDTH{XGMII_IDLE}}; + xgmii_txc_reg <= {CTRL_WIDTH{1'b1}}; start_packet_reg <= 2'b00; error_underflow_reg <= 1'b0; @@ -672,6 +745,9 @@ always @(posedge clk) begin deficit_idle_count_reg <= deficit_idle_count_next; s_axis_tready_reg <= s_axis_tready_next; + + m_axis_ptp_ts_valid_reg <= m_axis_ptp_ts_valid_next; + m_axis_ptp_ts_valid_int_reg <= m_axis_ptp_ts_valid_int_next; start_packet_reg <= start_packet_next; error_underflow_reg <= error_underflow_next; @@ -697,6 +773,9 @@ always @(posedge clk) begin s_tdata_reg <= s_tdata_next; s_tkeep_reg <= s_tkeep_next; + m_axis_ptp_ts_reg <= m_axis_ptp_ts_next; + m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next; + swap_txd <= xgmii_txd_next[63:32]; swap_txc <= xgmii_txc_next[7:4]; end diff --git a/rtl/eth_mac_10g.v b/rtl/eth_mac_10g.v index dceab9c73..9601a2e13 100644 --- a/rtl/eth_mac_10g.v +++ b/rtl/eth_mac_10g.v @@ -36,54 +36,73 @@ module eth_mac_10g # parameter CTRL_WIDTH = (DATA_WIDTH/8), parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, - parameter MIN_FRAME_LENGTH = 64 + parameter MIN_FRAME_LENGTH = 64, + parameter PTP_PERIOD_NS = 4'h6, + parameter PTP_PERIOD_FNS = 16'h6666, + parameter TX_PTP_TS_ENABLE = 0, + parameter TX_PTP_TS_WIDTH = 96, + parameter TX_PTP_TAG_ENABLE = 0, + parameter TX_PTP_TAG_WIDTH = 16, + parameter RX_PTP_TS_ENABLE = 0, + parameter RX_PTP_TS_WIDTH = 96, + parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1, + parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1 ) ( - input wire rx_clk, - input wire rx_rst, - input wire tx_clk, - input wire tx_rst, + input wire rx_clk, + input wire rx_rst, + input wire tx_clk, + input wire tx_rst, /* * AXI input */ - input wire [DATA_WIDTH-1:0] tx_axis_tdata, - input wire [KEEP_WIDTH-1:0] tx_axis_tkeep, - input wire tx_axis_tvalid, - output wire tx_axis_tready, - input wire tx_axis_tlast, - input wire tx_axis_tuser, + input wire [DATA_WIDTH-1:0] tx_axis_tdata, + input wire [KEEP_WIDTH-1:0] tx_axis_tkeep, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire [TX_USER_WIDTH-1:0] tx_axis_tuser, /* * AXI output */ - output wire [DATA_WIDTH-1:0] rx_axis_tdata, - output wire [KEEP_WIDTH-1:0] rx_axis_tkeep, - output wire rx_axis_tvalid, - output wire rx_axis_tlast, - output wire rx_axis_tuser, + output wire [DATA_WIDTH-1:0] rx_axis_tdata, + output wire [KEEP_WIDTH-1:0] rx_axis_tkeep, + output wire rx_axis_tvalid, + output wire rx_axis_tlast, + output wire [RX_USER_WIDTH-1:0] rx_axis_tuser, /* * XGMII interface */ - input wire [DATA_WIDTH-1:0] xgmii_rxd, - input wire [CTRL_WIDTH-1:0] xgmii_rxc, - output wire [DATA_WIDTH-1:0] xgmii_txd, - output wire [CTRL_WIDTH-1:0] xgmii_txc, + input wire [DATA_WIDTH-1:0] xgmii_rxd, + input wire [CTRL_WIDTH-1:0] xgmii_rxc, + output wire [DATA_WIDTH-1:0] xgmii_txd, + output wire [CTRL_WIDTH-1:0] xgmii_txc, + + /* + * PTP + */ + input wire [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts, + input wire [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts, + output wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts, + output wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag, + output wire tx_axis_ptp_ts_valid, /* * Status */ - output wire [1:0] tx_start_packet, - output wire tx_error_underflow, - output wire [1:0] rx_start_packet, - output wire rx_error_bad_frame, - output wire rx_error_bad_fcs, + output wire [1:0] tx_start_packet, + output wire tx_error_underflow, + output wire [1:0] rx_start_packet, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, /* * Configuration */ - input wire [7:0] ifg_delay + input wire [7:0] ifg_delay ); // bus width assertions @@ -103,7 +122,16 @@ generate if (DATA_WIDTH == 64) begin -axis_xgmii_rx_64 +axis_xgmii_rx_64 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(RX_PTP_TS_ENABLE), + .PTP_TS_WIDTH(RX_PTP_TS_WIDTH), + .USER_WIDTH(RX_USER_WIDTH) +) axis_xgmii_rx_inst ( .clk(rx_clk), .rst(rx_rst), @@ -114,15 +142,26 @@ axis_xgmii_rx_inst ( .m_axis_tvalid(rx_axis_tvalid), .m_axis_tlast(rx_axis_tlast), .m_axis_tuser(rx_axis_tuser), + .ptp_ts(rx_ptp_ts), .start_packet(rx_start_packet), .error_bad_frame(rx_error_bad_frame), .error_bad_fcs(rx_error_bad_fcs) ); axis_xgmii_tx_64 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(TX_PTP_TS_ENABLE), + .PTP_TS_WIDTH(TX_PTP_TS_WIDTH), + .PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), + .USER_WIDTH(TX_USER_WIDTH) ) axis_xgmii_tx_inst ( .clk(tx_clk), @@ -135,6 +174,10 @@ axis_xgmii_tx_inst ( .s_axis_tuser(tx_axis_tuser), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .ptp_ts(tx_ptp_ts), + .m_axis_ptp_ts(tx_axis_ptp_ts), + .m_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), .ifg_delay(ifg_delay), .start_packet(tx_start_packet), .error_underflow(tx_error_underflow) @@ -142,7 +185,14 @@ axis_xgmii_tx_inst ( end else begin -axis_xgmii_rx_32 +axis_xgmii_rx_32 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .PTP_TS_ENABLE(RX_PTP_TS_ENABLE), + .PTP_TS_WIDTH(RX_PTP_TS_WIDTH), + .USER_WIDTH(RX_USER_WIDTH) +) axis_xgmii_rx_inst ( .clk(rx_clk), .rst(rx_rst), @@ -153,7 +203,8 @@ axis_xgmii_rx_inst ( .m_axis_tvalid(rx_axis_tvalid), .m_axis_tlast(rx_axis_tlast), .m_axis_tuser(rx_axis_tuser), - .start_packet(rx_start_packet), + .ptp_ts(rx_ptp_ts), + .start_packet(rx_start_packet[0]), .error_bad_frame(rx_error_bad_frame), .error_bad_fcs(rx_error_bad_fcs) ); @@ -161,9 +212,17 @@ axis_xgmii_rx_inst ( assign rx_start_packet[1] = 1'b0; axis_xgmii_tx_32 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_TS_ENABLE(TX_PTP_TS_ENABLE), + .PTP_TS_WIDTH(TX_PTP_TS_WIDTH), + .PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), + .USER_WIDTH(TX_USER_WIDTH) ) axis_xgmii_tx_inst ( .clk(tx_clk), @@ -176,8 +235,12 @@ axis_xgmii_tx_inst ( .s_axis_tuser(tx_axis_tuser), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .ptp_ts(tx_ptp_ts), + .m_axis_ptp_ts(tx_axis_ptp_ts), + .m_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), .ifg_delay(ifg_delay), - .start_packet(tx_start_packet) + .start_packet(tx_start_packet[0]) ); assign tx_start_packet[1] = 1'b0; diff --git a/rtl/eth_mac_1g.v b/rtl/eth_mac_1g.v index 1a37ff5c8..7eefcdf3f 100644 --- a/rtl/eth_mac_1g.v +++ b/rtl/eth_mac_1g.v @@ -31,66 +31,89 @@ THE SOFTWARE. */ module eth_mac_1g # ( + parameter DATA_WIDTH = 8, parameter ENABLE_PADDING = 1, - parameter MIN_FRAME_LENGTH = 64 + parameter MIN_FRAME_LENGTH = 64, + parameter TX_PTP_TS_ENABLE = 0, + parameter TX_PTP_TS_WIDTH = 96, + parameter TX_PTP_TAG_ENABLE = 0, + parameter TX_PTP_TAG_WIDTH = 16, + parameter RX_PTP_TS_ENABLE = 0, + parameter RX_PTP_TS_WIDTH = 96, + parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1, + parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1 ) ( - input wire rx_clk, - input wire rx_rst, - input wire tx_clk, - input wire tx_rst, + input wire rx_clk, + input wire rx_rst, + input wire tx_clk, + input wire tx_rst, /* * AXI input */ - input wire [7:0] tx_axis_tdata, - input wire tx_axis_tvalid, - output wire tx_axis_tready, - input wire tx_axis_tlast, - input wire tx_axis_tuser, + input wire [DATA_WIDTH-1:0] tx_axis_tdata, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire [TX_USER_WIDTH-1:0] tx_axis_tuser, /* * AXI output */ - output wire [7:0] rx_axis_tdata, - output wire rx_axis_tvalid, - output wire rx_axis_tlast, - output wire rx_axis_tuser, + output wire [DATA_WIDTH-1:0] rx_axis_tdata, + output wire rx_axis_tvalid, + output wire rx_axis_tlast, + output wire [RX_USER_WIDTH-1:0] rx_axis_tuser, /* * GMII interface */ - input wire [7:0] gmii_rxd, - input wire gmii_rx_dv, - input wire gmii_rx_er, - output wire [7:0] gmii_txd, - output wire gmii_tx_en, - output wire gmii_tx_er, + input wire [DATA_WIDTH-1:0] gmii_rxd, + input wire gmii_rx_dv, + input wire gmii_rx_er, + output wire [DATA_WIDTH-1:0] gmii_txd, + output wire gmii_tx_en, + output wire gmii_tx_er, + + /* + * PTP + */ + input wire [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts, + input wire [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts, + output wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts, + output wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag, + output wire tx_axis_ptp_ts_valid, /* * Control */ - input wire rx_clk_enable, - input wire tx_clk_enable, - input wire rx_mii_select, - input wire tx_mii_select, + input wire rx_clk_enable, + input wire tx_clk_enable, + input wire rx_mii_select, + input wire tx_mii_select, /* * Status */ - output wire tx_start_packet, - output wire tx_error_underflow, - output wire rx_start_packet, - output wire rx_error_bad_frame, - output wire rx_error_bad_fcs, + output wire tx_start_packet, + output wire tx_error_underflow, + output wire rx_start_packet, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, /* * Configuration */ - input wire [7:0] ifg_delay + input wire [7:0] ifg_delay ); -axis_gmii_rx +axis_gmii_rx #( + .DATA_WIDTH(DATA_WIDTH), + .PTP_TS_ENABLE(RX_PTP_TS_ENABLE), + .PTP_TS_WIDTH(RX_PTP_TS_WIDTH), + .USER_WIDTH(RX_USER_WIDTH) +) axis_gmii_rx_inst ( .clk(rx_clk), .rst(rx_rst), @@ -101,6 +124,7 @@ axis_gmii_rx_inst ( .m_axis_tvalid(rx_axis_tvalid), .m_axis_tlast(rx_axis_tlast), .m_axis_tuser(rx_axis_tuser), + .ptp_ts(rx_ptp_ts), .clk_enable(rx_clk_enable), .mii_select(rx_mii_select), .start_packet(rx_start_packet), @@ -109,8 +133,14 @@ axis_gmii_rx_inst ( ); axis_gmii_tx #( + .DATA_WIDTH(DATA_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_TS_ENABLE(TX_PTP_TS_ENABLE), + .PTP_TS_WIDTH(TX_PTP_TS_WIDTH), + .PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), + .USER_WIDTH(TX_USER_WIDTH) ) axis_gmii_tx_inst ( .clk(tx_clk), @@ -123,6 +153,10 @@ axis_gmii_tx_inst ( .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), + .ptp_ts(tx_ptp_ts), + .m_axis_ptp_ts(tx_axis_ptp_ts), + .m_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), .clk_enable(tx_clk_enable), .mii_select(tx_mii_select), .ifg_delay(ifg_delay), diff --git a/rtl/eth_mac_phy_10g.v b/rtl/eth_mac_phy_10g.v index d635f3254..a1b16ade1 100644 --- a/rtl/eth_mac_phy_10g.v +++ b/rtl/eth_mac_phy_10g.v @@ -38,6 +38,16 @@ module eth_mac_phy_10g # parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, + parameter PTP_PERIOD_NS = 4'h6, + parameter PTP_PERIOD_FNS = 16'h6666, + parameter TX_PTP_TS_ENABLE = 0, + parameter TX_PTP_TS_WIDTH = 96, + parameter TX_PTP_TAG_ENABLE = 0, + parameter TX_PTP_TAG_WIDTH = 16, + parameter RX_PTP_TS_ENABLE = 0, + parameter RX_PTP_TS_WIDTH = 96, + parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1, + parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1, parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, parameter PRBS31_ENABLE = 0, @@ -45,58 +55,67 @@ module eth_mac_phy_10g # parameter COUNT_125US = 125000/6.4 ) ( - input wire rx_clk, - input wire rx_rst, - input wire tx_clk, - input wire tx_rst, + input wire rx_clk, + input wire rx_rst, + input wire tx_clk, + input wire tx_rst, /* * AXI input */ - input wire [DATA_WIDTH-1:0] tx_axis_tdata, - input wire [KEEP_WIDTH-1:0] tx_axis_tkeep, - input wire tx_axis_tvalid, - output wire tx_axis_tready, - input wire tx_axis_tlast, - input wire tx_axis_tuser, + input wire [DATA_WIDTH-1:0] tx_axis_tdata, + input wire [KEEP_WIDTH-1:0] tx_axis_tkeep, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire [TX_USER_WIDTH-1:0] tx_axis_tuser, /* * AXI output */ - output wire [DATA_WIDTH-1:0] rx_axis_tdata, - output wire [KEEP_WIDTH-1:0] rx_axis_tkeep, - output wire rx_axis_tvalid, - output wire rx_axis_tlast, - output wire rx_axis_tuser, + output wire [DATA_WIDTH-1:0] rx_axis_tdata, + output wire [KEEP_WIDTH-1:0] rx_axis_tkeep, + output wire rx_axis_tvalid, + output wire rx_axis_tlast, + output wire [RX_USER_WIDTH-1:0] rx_axis_tuser, /* * SERDES interface */ - output wire [DATA_WIDTH-1:0] serdes_tx_data, - output wire [HDR_WIDTH-1:0] serdes_tx_hdr, - input wire [DATA_WIDTH-1:0] serdes_rx_data, - input wire [HDR_WIDTH-1:0] serdes_rx_hdr, - output wire serdes_rx_bitslip, + output wire [DATA_WIDTH-1:0] serdes_tx_data, + output wire [HDR_WIDTH-1:0] serdes_tx_hdr, + input wire [DATA_WIDTH-1:0] serdes_rx_data, + input wire [HDR_WIDTH-1:0] serdes_rx_hdr, + output wire serdes_rx_bitslip, + + /* + * PTP + */ + input wire [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts, + input wire [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts, + output wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts, + output wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag, + output wire tx_axis_ptp_ts_valid, /* * Status */ - output wire [1:0] tx_start_packet, - output wire tx_error_underflow, - output wire [1:0] rx_start_packet, - output wire [6:0] rx_error_count, - output wire rx_error_bad_frame, - output wire rx_error_bad_fcs, - output wire rx_bad_block, - output wire rx_block_lock, - output wire rx_high_ber, + output wire [1:0] tx_start_packet, + output wire tx_error_underflow, + output wire [1:0] rx_start_packet, + output wire [6:0] rx_error_count, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + output wire rx_bad_block, + output wire rx_block_lock, + output wire rx_high_ber, /* * Configuration */ - input wire [7:0] ifg_delay, - input wire tx_prbs31_enable, - input wire rx_prbs31_enable + input wire [7:0] ifg_delay, + input wire tx_prbs31_enable, + input wire rx_prbs31_enable ); eth_mac_phy_10g_rx #( @@ -104,6 +123,11 @@ eth_mac_phy_10g_rx #( .KEEP_WIDTH(KEEP_WIDTH), .CTRL_WIDTH(CTRL_WIDTH), .HDR_WIDTH(HDR_WIDTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(RX_PTP_TS_ENABLE), + .PTP_TS_WIDTH(RX_PTP_TS_WIDTH), + .USER_WIDTH(RX_USER_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .PRBS31_ENABLE(PRBS31_ENABLE), @@ -121,6 +145,7 @@ eth_mac_phy_10g_rx_inst ( .serdes_rx_data(serdes_rx_data), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_bitslip(serdes_rx_bitslip), + .ptp_ts(rx_ptp_ts), .rx_start_packet(rx_start_packet), .rx_error_count(rx_error_count), .rx_error_bad_frame(rx_error_bad_frame), @@ -139,6 +164,13 @@ eth_mac_phy_10g_tx #( .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(TX_PTP_TS_ENABLE), + .PTP_TS_WIDTH(TX_PTP_TS_WIDTH), + .PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), + .USER_WIDTH(TX_USER_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .PRBS31_ENABLE(PRBS31_ENABLE) @@ -154,6 +186,10 @@ eth_mac_phy_10g_tx_inst ( .s_axis_tuser(tx_axis_tuser), .serdes_tx_data(serdes_tx_data), .serdes_tx_hdr(serdes_tx_hdr), + .ptp_ts(tx_ptp_ts), + .m_axis_ptp_ts(tx_axis_ptp_ts), + .m_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), .tx_start_packet(tx_start_packet), .tx_error_underflow(tx_error_underflow), .ifg_delay(ifg_delay), diff --git a/rtl/eth_mac_phy_10g_rx.v b/rtl/eth_mac_phy_10g_rx.v index 5c70391fd..44476eef4 100644 --- a/rtl/eth_mac_phy_10g_rx.v +++ b/rtl/eth_mac_phy_10g_rx.v @@ -35,6 +35,11 @@ module eth_mac_phy_10g_rx # parameter KEEP_WIDTH = (DATA_WIDTH/8), parameter CTRL_WIDTH = (DATA_WIDTH/8), parameter HDR_WIDTH = (DATA_WIDTH/32), + parameter PTP_PERIOD_NS = 4'h6, + parameter PTP_PERIOD_FNS = 16'h6666, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1, parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, parameter PRBS31_ENABLE = 0, @@ -42,40 +47,45 @@ module eth_mac_phy_10g_rx # parameter COUNT_125US = 125000/6.4 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * AXI output */ - output wire [DATA_WIDTH-1:0] m_axis_tdata, - output wire [KEEP_WIDTH-1:0] m_axis_tkeep, - output wire m_axis_tvalid, - output wire m_axis_tlast, - output wire m_axis_tuser, + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + output wire m_axis_tlast, + output wire [USER_WIDTH-1:0] m_axis_tuser, /* * SERDES interface */ - input wire [DATA_WIDTH-1:0] serdes_rx_data, - input wire [HDR_WIDTH-1:0] serdes_rx_hdr, - output wire serdes_rx_bitslip, + input wire [DATA_WIDTH-1:0] serdes_rx_data, + input wire [HDR_WIDTH-1:0] serdes_rx_hdr, + output wire serdes_rx_bitslip, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, /* * Status */ - output wire [1:0] rx_start_packet, - output wire [6:0] rx_error_count, - output wire rx_error_bad_frame, - output wire rx_error_bad_fcs, - output wire rx_bad_block, - output wire rx_block_lock, - output wire rx_high_ber, + output wire [1:0] rx_start_packet, + output wire [6:0] rx_error_count, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + output wire rx_bad_block, + output wire rx_block_lock, + output wire rx_high_ber, /* * Configuration */ - input wire rx_prbs31_enable + input wire rx_prbs31_enable ); // bus width assertions @@ -126,7 +136,12 @@ eth_phy_10g_rx_if_inst ( axis_baser_rx_64 #( .DATA_WIDTH(DATA_WIDTH), .KEEP_WIDTH(KEEP_WIDTH), - .HDR_WIDTH(HDR_WIDTH) + .HDR_WIDTH(HDR_WIDTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .USER_WIDTH(USER_WIDTH) ) axis_baser_rx_inst ( .clk(clk), @@ -138,6 +153,7 @@ axis_baser_rx_inst ( .m_axis_tvalid(m_axis_tvalid), .m_axis_tlast(m_axis_tlast), .m_axis_tuser(m_axis_tuser), + .ptp_ts(ptp_ts), .start_packet(rx_start_packet), .error_bad_frame(rx_error_bad_frame), .error_bad_fcs(rx_error_bad_fcs), diff --git a/rtl/eth_mac_phy_10g_tx.v b/rtl/eth_mac_phy_10g_tx.v index 9e795206f..9a497e2d5 100644 --- a/rtl/eth_mac_phy_10g_tx.v +++ b/rtl/eth_mac_phy_10g_tx.v @@ -38,41 +38,56 @@ module eth_mac_phy_10g_tx # parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, + parameter PTP_PERIOD_NS = 4'h6, + parameter PTP_PERIOD_FNS = 16'h6666, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter PTP_TAG_ENABLE = 0, + parameter PTP_TAG_WIDTH = 16, + parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1, parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, parameter PRBS31_ENABLE = 0 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * AXI input */ - input wire [DATA_WIDTH-1:0] s_axis_tdata, - input wire [KEEP_WIDTH-1:0] s_axis_tkeep, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire s_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [USER_WIDTH-1:0] s_axis_tuser, /* * SERDES interface */ - output wire [DATA_WIDTH-1:0] serdes_tx_data, - output wire [HDR_WIDTH-1:0] serdes_tx_hdr, + output wire [DATA_WIDTH-1:0] serdes_tx_data, + output wire [HDR_WIDTH-1:0] serdes_tx_hdr, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, + output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts, + output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag, + output wire m_axis_ptp_ts_valid, /* * Status */ - output wire [1:0] tx_start_packet, - output wire tx_error_underflow, + output wire [1:0] tx_start_packet, + output wire tx_error_underflow, /* * Configuration */ - input wire [7:0] ifg_delay, - input wire tx_prbs31_enable + input wire [7:0] ifg_delay, + input wire tx_prbs31_enable ); // bus width assertions @@ -102,7 +117,14 @@ axis_baser_tx_64 #( .HDR_WIDTH(HDR_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .PTP_TAG_ENABLE(PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(PTP_TAG_WIDTH), + .USER_WIDTH(USER_WIDTH) ) axis_baser_tx_inst ( .clk(clk), @@ -115,6 +137,10 @@ axis_baser_tx_inst ( .s_axis_tuser(s_axis_tuser), .encoded_tx_data(encoded_tx_data), .encoded_tx_hdr(encoded_tx_hdr), + .ptp_ts(ptp_ts), + .m_axis_ptp_ts(m_axis_ptp_ts), + .m_axis_ptp_ts_tag(m_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(m_axis_ptp_ts_valid), .start_packet(tx_start_packet), .error_underflow(tx_error_underflow), .ifg_delay(ifg_delay) diff --git a/tb/test_axis_baser_rx_64.py b/tb/test_axis_baser_rx_64.py index f4313fc18..d13e4993f 100755 --- a/tb/test_axis_baser_rx_64.py +++ b/tb/test_axis_baser_rx_64.py @@ -50,6 +50,11 @@ def bench(): DATA_WIDTH = 64 KEEP_WIDTH = (DATA_WIDTH/8) HDR_WIDTH = 2 + PTP_PERIOD_NS = 0x6 + PTP_PERIOD_FNS = 0x6666 + PTP_TS_ENABLE = 0 + PTP_TS_WIDTH = 96 + USER_WIDTH = (PTP_TS_WIDTH if PTP_TS_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) @@ -58,13 +63,14 @@ def bench(): encoded_rx_data = Signal(intbv(0)[DATA_WIDTH:]) encoded_rx_hdr = Signal(intbv(1)[HDR_WIDTH:]) + ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) # Outputs m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) m_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) m_axis_tvalid = Signal(bool(0)) m_axis_tlast = Signal(bool(0)) - m_axis_tuser = Signal(bool(0)) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) start_packet = Signal(intbv(0)[2:]) error_bad_frame = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) @@ -110,6 +116,7 @@ def bench(): m_axis_tvalid=m_axis_tvalid, m_axis_tlast=m_axis_tlast, m_axis_tuser=m_axis_tuser, + ptp_ts=ptp_ts, start_packet=start_packet, error_bad_frame=error_bad_frame, error_bad_fcs=error_bad_fcs, diff --git a/tb/test_axis_baser_rx_64.v b/tb/test_axis_baser_rx_64.v index cc0b669f8..95eb08067 100644 --- a/tb/test_axis_baser_rx_64.v +++ b/tb/test_axis_baser_rx_64.v @@ -35,6 +35,11 @@ module test_axis_baser_rx_64; parameter DATA_WIDTH = 64; parameter KEEP_WIDTH = (DATA_WIDTH/8); parameter HDR_WIDTH = 2; +parameter PTP_PERIOD_NS = 4'h6; +parameter PTP_PERIOD_FNS = 16'h6666; +parameter PTP_TS_ENABLE = 0; +parameter PTP_TS_WIDTH = 96; +parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1; // Inputs reg clk = 0; @@ -43,13 +48,14 @@ reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] encoded_rx_data = 0; reg [HDR_WIDTH-1:0] encoded_rx_hdr = 1; +reg [PTP_TS_WIDTH-1:0] ptp_ts = 0; // Outputs wire [DATA_WIDTH-1:0] m_axis_tdata; wire [KEEP_WIDTH-1:0] m_axis_tkeep; wire m_axis_tvalid; wire m_axis_tlast; -wire m_axis_tuser; +wire [USER_WIDTH-1:0] m_axis_tuser; wire [1:0] start_packet; wire error_bad_frame; wire error_bad_fcs; @@ -62,7 +68,8 @@ initial begin rst, current_test, encoded_rx_data, - encoded_rx_hdr + encoded_rx_hdr, + ptp_ts ); $to_myhdl( m_axis_tdata, @@ -84,7 +91,12 @@ end axis_baser_rx_64 #( .DATA_WIDTH(DATA_WIDTH), .KEEP_WIDTH(KEEP_WIDTH), - .HDR_WIDTH(HDR_WIDTH) + .HDR_WIDTH(HDR_WIDTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -96,6 +108,7 @@ UUT ( .m_axis_tvalid(m_axis_tvalid), .m_axis_tlast(m_axis_tlast), .m_axis_tuser(m_axis_tuser), + .ptp_ts(ptp_ts), .start_packet(start_packet), .error_bad_frame(error_bad_frame), .error_bad_fcs(error_bad_fcs), diff --git a/tb/test_axis_baser_tx_64.py b/tb/test_axis_baser_tx_64.py index 26afcefc5..f807214ef 100755 --- a/tb/test_axis_baser_tx_64.py +++ b/tb/test_axis_baser_tx_64.py @@ -52,6 +52,13 @@ def bench(): ENABLE_PADDING = 1 ENABLE_DIC = 1 MIN_FRAME_LENGTH = 64 + PTP_PERIOD_NS = 0x6 + PTP_PERIOD_FNS = 0x6666 + PTP_TS_ENABLE = 0 + PTP_TS_WIDTH = 96 + PTP_TAG_ENABLE = 0 + PTP_TAG_WIDTH = 16 + USER_WIDTH = (PTP_TAG_WIDTH if PTP_TS_ENABLE and PTP_TAG_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) @@ -62,13 +69,17 @@ def bench(): s_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) s_axis_tvalid = Signal(bool(0)) s_axis_tlast = Signal(bool(0)) - s_axis_tuser = Signal(bool(0)) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) ifg_delay = Signal(intbv(0)[8:]) # Outputs s_axis_tready = Signal(bool(0)) encoded_tx_data = Signal(intbv(0)[DATA_WIDTH:]) encoded_tx_hdr = Signal(intbv(1)[HDR_WIDTH:]) + m_axis_ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) + m_axis_ptp_ts_tag = Signal(intbv(0)[PTP_TAG_WIDTH:]) + m_axis_ptp_ts_valid = Signal(bool(0)) start_packet = Signal(intbv(0)[2:]) error_underflow = Signal(bool(0)) @@ -117,6 +128,10 @@ def bench(): s_axis_tuser=s_axis_tuser, encoded_tx_data=encoded_tx_data, encoded_tx_hdr=encoded_tx_hdr, + ptp_ts=ptp_ts, + m_axis_ptp_ts=m_axis_ptp_ts, + m_axis_ptp_ts_tag=m_axis_ptp_ts_tag, + m_axis_ptp_ts_valid=m_axis_ptp_ts_valid, ifg_delay=ifg_delay, start_packet=start_packet, error_underflow=error_underflow diff --git a/tb/test_axis_baser_tx_64.v b/tb/test_axis_baser_tx_64.v index aa64db44a..5aac11293 100644 --- a/tb/test_axis_baser_tx_64.v +++ b/tb/test_axis_baser_tx_64.v @@ -38,6 +38,13 @@ parameter HDR_WIDTH = 2; parameter ENABLE_PADDING = 1; parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; +parameter PTP_PERIOD_NS = 4'h6; +parameter PTP_PERIOD_FNS = 16'h6666; +parameter PTP_TS_ENABLE = 0; +parameter PTP_TS_WIDTH = 96; +parameter PTP_TAG_ENABLE = 0; +parameter PTP_TAG_WIDTH = 16; +parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; // Inputs reg clk = 0; @@ -48,13 +55,17 @@ reg [DATA_WIDTH-1:0] s_axis_tdata = 0; reg [KEEP_WIDTH-1:0] s_axis_tkeep = 0; reg s_axis_tvalid = 0; reg s_axis_tlast = 0; -reg s_axis_tuser = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg [PTP_TS_WIDTH-1:0] ptp_ts = 0; reg [7:0] ifg_delay = 0; // Outputs wire s_axis_tready; wire [DATA_WIDTH-1:0] encoded_tx_data; wire [HDR_WIDTH-1:0] encoded_tx_hdr; +wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts; +wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag; +wire m_axis_ptp_ts_valid; wire [1:0] start_packet; wire error_underflow; @@ -69,12 +80,16 @@ initial begin s_axis_tvalid, s_axis_tlast, s_axis_tuser, + ptp_ts, ifg_delay ); $to_myhdl( s_axis_tready, encoded_tx_data, encoded_tx_hdr, + m_axis_ptp_ts, + m_axis_ptp_ts_tag, + m_axis_ptp_ts_valid, start_packet, error_underflow ); @@ -90,7 +105,14 @@ axis_baser_tx_64 #( .HDR_WIDTH(HDR_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .PTP_TAG_ENABLE(PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(PTP_TAG_WIDTH), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -103,6 +125,10 @@ UUT ( .s_axis_tuser(s_axis_tuser), .encoded_tx_data(encoded_tx_data), .encoded_tx_hdr(encoded_tx_hdr), + .ptp_ts(ptp_ts), + .m_axis_ptp_ts(m_axis_ptp_ts), + .m_axis_ptp_ts_tag(m_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(m_axis_ptp_ts_valid), .ifg_delay(ifg_delay), .start_packet(start_packet), .error_underflow(error_underflow) diff --git a/tb/test_axis_gmii_rx.py b/tb/test_axis_gmii_rx.py index dbf93f16b..237909385 100755 --- a/tb/test_axis_gmii_rx.py +++ b/tb/test_axis_gmii_rx.py @@ -46,24 +46,28 @@ def bench(): # Parameters - + DATA_WIDTH = 8 + PTP_TS_ENABLE = 0 + PTP_TS_WIDTH = 96 + USER_WIDTH = (PTP_TS_WIDTH if PTP_TS_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - gmii_rxd = Signal(intbv(0)[8:]) + gmii_rxd = Signal(intbv(0)[DATA_WIDTH:]) gmii_rx_dv = Signal(bool(0)) gmii_rx_er = Signal(bool(0)) + ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) clk_enable = Signal(bool(1)) mii_select = Signal(bool(0)) # Outputs - m_axis_tdata = Signal(intbv(0)[8:]) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) m_axis_tvalid = Signal(bool(0)) m_axis_tlast = Signal(bool(0)) - m_axis_tuser = Signal(bool(0)) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) start_packet = Signal(bool(0)) error_bad_frame = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) @@ -113,6 +117,8 @@ def bench(): m_axis_tlast=m_axis_tlast, m_axis_tuser=m_axis_tuser, + ptp_ts=ptp_ts, + clk_enable=clk_enable, mii_select=mii_select, diff --git a/tb/test_axis_gmii_rx.v b/tb/test_axis_gmii_rx.v index af28a9a77..452fdcbe1 100644 --- a/tb/test_axis_gmii_rx.v +++ b/tb/test_axis_gmii_rx.v @@ -32,24 +32,28 @@ THE SOFTWARE. module test_axis_gmii_rx; // Parameters +parameter DATA_WIDTH = 8; +parameter PTP_TS_ENABLE = 0; +parameter PTP_TS_WIDTH = 96; +parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1; // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] gmii_rxd = 0; +reg [DATA_WIDTH-1:0] gmii_rxd = 0; reg gmii_rx_dv = 0; reg gmii_rx_er = 0; - +reg [PTP_TS_WIDTH-1:0] ptp_ts = 0; reg clk_enable = 1; reg mii_select = 0; // Outputs -wire [7:0] m_axis_tdata; +wire [DATA_WIDTH-1:0] m_axis_tdata; wire m_axis_tvalid; wire m_axis_tlast; -wire m_axis_tuser; +wire [USER_WIDTH-1:0] m_axis_tuser; wire start_packet; wire error_bad_frame; wire error_bad_fcs; @@ -63,6 +67,7 @@ initial begin gmii_rxd, gmii_rx_dv, gmii_rx_er, + ptp_ts, clk_enable, mii_select ); @@ -81,7 +86,12 @@ initial begin $dumpvars(0, test_axis_gmii_rx); end -axis_gmii_rx +axis_gmii_rx #( + .DATA_WIDTH(DATA_WIDTH), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), @@ -92,6 +102,7 @@ UUT ( .m_axis_tvalid(m_axis_tvalid), .m_axis_tlast(m_axis_tlast), .m_axis_tuser(m_axis_tuser), + .ptp_ts(ptp_ts), .clk_enable(clk_enable), .mii_select(mii_select), .start_packet(start_packet), diff --git a/tb/test_axis_gmii_tx.py b/tb/test_axis_gmii_tx.py index f0cd1b5b6..041fef7d0 100755 --- a/tb/test_axis_gmii_tx.py +++ b/tb/test_axis_gmii_tx.py @@ -46,27 +46,37 @@ def bench(): # Parameters + DATA_WIDTH = 8 ENABLE_PADDING = 1 MIN_FRAME_LENGTH = 64 + PTP_TS_ENABLE = 0 + PTP_TS_WIDTH = 96 + PTP_TAG_ENABLE = 0 + PTP_TAG_WIDTH = 16 + USER_WIDTH = (PTP_TAG_WIDTH if PTP_TS_ENABLE and PTP_TAG_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - s_axis_tdata = Signal(intbv(0)[8:]) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) s_axis_tvalid = Signal(bool(0)) s_axis_tlast = Signal(bool(0)) - s_axis_tuser = Signal(bool(0)) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) clk_enable = Signal(bool(1)) mii_select = Signal(bool(0)) ifg_delay = Signal(intbv(0)[8:]) # Outputs s_axis_tready = Signal(bool(0)) - gmii_txd = Signal(intbv(0)[8:]) + gmii_txd = Signal(intbv(0)[DATA_WIDTH:]) gmii_tx_en = Signal(bool(0)) gmii_tx_er = Signal(bool(0)) + m_axis_ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) + m_axis_ptp_ts_tag = Signal(intbv(0)[PTP_TAG_WIDTH:]) + m_axis_ptp_ts_valid = Signal(bool(0)) start_packet = Signal(bool(0)) error_underflow = Signal(bool(0)) @@ -120,6 +130,11 @@ def bench(): gmii_tx_en=gmii_tx_en, gmii_tx_er=gmii_tx_er, + ptp_ts=ptp_ts, + m_axis_ptp_ts=m_axis_ptp_ts, + m_axis_ptp_ts_tag=m_axis_ptp_ts_tag, + m_axis_ptp_ts_valid=m_axis_ptp_ts_valid, + clk_enable=clk_enable, mii_select=mii_select, diff --git a/tb/test_axis_gmii_tx.v b/tb/test_axis_gmii_tx.v index 99d702451..44ea2a234 100644 --- a/tb/test_axis_gmii_tx.v +++ b/tb/test_axis_gmii_tx.v @@ -32,27 +32,37 @@ THE SOFTWARE. module test_axis_gmii_tx; // Parameters +parameter DATA_WIDTH = 8; parameter ENABLE_PADDING = 1; parameter MIN_FRAME_LENGTH = 64; +parameter PTP_TS_ENABLE = 0; +parameter PTP_TS_WIDTH = 96; +parameter PTP_TAG_ENABLE = 0; +parameter PTP_TAG_WIDTH = 16; +parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] s_axis_tdata = 0; +reg [DATA_WIDTH-1:0] s_axis_tdata = 0; reg s_axis_tvalid = 0; reg s_axis_tlast = 0; -reg s_axis_tuser = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg [PTP_TS_WIDTH-1:0] ptp_ts = 0; reg clk_enable = 1; reg mii_select = 0; reg [7:0] ifg_delay = 0; // Outputs wire s_axis_tready; -wire [7:0] gmii_txd; +wire [DATA_WIDTH-1:0] gmii_txd; wire gmii_tx_en; wire gmii_tx_er; +wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts; +wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag; +wire m_axis_ptp_ts_valid; wire start_packet; wire error_underflow; @@ -66,6 +76,7 @@ initial begin s_axis_tvalid, s_axis_tlast, s_axis_tuser, + ptp_ts, clk_enable, mii_select, ifg_delay @@ -75,6 +86,9 @@ initial begin gmii_txd, gmii_tx_en, gmii_tx_er, + m_axis_ptp_ts, + m_axis_ptp_ts_tag, + m_axis_ptp_ts_valid, start_packet, error_underflow ); @@ -85,8 +99,14 @@ initial begin end axis_gmii_tx #( + .DATA_WIDTH(DATA_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .PTP_TAG_ENABLE(PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(PTP_TAG_WIDTH), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -99,6 +119,10 @@ UUT ( .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), + .ptp_ts(ptp_ts), + .m_axis_ptp_ts(m_axis_ptp_ts), + .m_axis_ptp_ts_tag(m_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(m_axis_ptp_ts_valid), .clk_enable(clk_enable), .mii_select(mii_select), .ifg_delay(ifg_delay), diff --git a/tb/test_axis_xgmii_rx_32.py b/tb/test_axis_xgmii_rx_32.py index 0e12f2aae..7ec9c7e49 100755 --- a/tb/test_axis_xgmii_rx_32.py +++ b/tb/test_axis_xgmii_rx_32.py @@ -46,22 +46,28 @@ def bench(): # Parameters - + DATA_WIDTH = 32 + KEEP_WIDTH = (DATA_WIDTH/8) + CTRL_WIDTH = (DATA_WIDTH/8) + PTP_TS_ENABLE = 0 + PTP_TS_WIDTH = 96 + USER_WIDTH = (PTP_TS_WIDTH if PTP_TS_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) - current_test = Signal(intbv(0)[4:]) + current_test = Signal(intbv(0)[8:]) - xgmii_rxd = Signal(intbv(0x07070707)[32:]) - xgmii_rxc = Signal(intbv(0xf)[4:]) + xgmii_rxd = Signal(intbv(0x07070707)[DATA_WIDTH:]) + xgmii_rxc = Signal(intbv(0xf)[CTRL_WIDTH:]) + ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) # Outputs - m_axis_tdata = Signal(intbv(0)[32:]) - m_axis_tkeep = Signal(intbv(0)[4:]) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) m_axis_tvalid = Signal(bool(0)) m_axis_tlast = Signal(bool(0)) - m_axis_tuser = Signal(bool(0)) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) start_packet = Signal(bool(0)) error_bad_frame = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) @@ -109,6 +115,8 @@ def bench(): m_axis_tlast=m_axis_tlast, m_axis_tuser=m_axis_tuser, + ptp_ts=ptp_ts, + start_packet=start_packet, error_bad_frame=error_bad_frame, error_bad_fcs=error_bad_fcs diff --git a/tb/test_axis_xgmii_rx_32.v b/tb/test_axis_xgmii_rx_32.v index 828f034d8..837519434 100644 --- a/tb/test_axis_xgmii_rx_32.v +++ b/tb/test_axis_xgmii_rx_32.v @@ -32,21 +32,28 @@ THE SOFTWARE. module test_axis_xgmii_rx_32; // Parameters +parameter DATA_WIDTH = 32; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter CTRL_WIDTH = (DATA_WIDTH/8); +parameter PTP_TS_ENABLE = 0; +parameter PTP_TS_WIDTH = 96; +parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1; // Inputs reg clk = 0; reg rst = 0; -reg [3:0] current_test = 0; +reg [7:0] current_test = 0; -reg [31:0] xgmii_rxd = 32'h07070707; -reg [3:0] xgmii_rxc = 4'hf; +reg [DATA_WIDTH-1:0] xgmii_rxd = 32'h07070707; +reg [CTRL_WIDTH-1:0] xgmii_rxc = 4'hf; +reg [PTP_TS_WIDTH-1:0] ptp_ts = 0; // Outputs -wire [31:0] m_axis_tdata; -wire [3:0] m_axis_tkeep; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; wire m_axis_tvalid; wire m_axis_tlast; -wire m_axis_tuser; +wire [USER_WIDTH-1:0] m_axis_tuser; wire start_packet; wire error_bad_frame; wire error_bad_fcs; @@ -58,7 +65,8 @@ initial begin rst, current_test, xgmii_rxd, - xgmii_rxc + xgmii_rxc, + ptp_ts ); $to_myhdl( m_axis_tdata, @@ -76,7 +84,14 @@ initial begin $dumpvars(0, test_axis_xgmii_rx_32); end -axis_xgmii_rx_32 +axis_xgmii_rx_32 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), @@ -87,6 +102,7 @@ UUT ( .m_axis_tvalid(m_axis_tvalid), .m_axis_tlast(m_axis_tlast), .m_axis_tuser(m_axis_tuser), + .ptp_ts(ptp_ts), .start_packet(start_packet), .error_bad_frame(error_bad_frame), .error_bad_fcs(error_bad_fcs) diff --git a/tb/test_axis_xgmii_rx_64.py b/tb/test_axis_xgmii_rx_64.py index 52bd854db..14d0a9318 100755 --- a/tb/test_axis_xgmii_rx_64.py +++ b/tb/test_axis_xgmii_rx_64.py @@ -46,22 +46,30 @@ def bench(): # Parameters - + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + CTRL_WIDTH = (DATA_WIDTH/8) + PTP_PERIOD_NS = 0x6 + PTP_PERIOD_FNS = 0x6666 + PTP_TS_ENABLE = 0 + PTP_TS_WIDTH = 96 + USER_WIDTH = (PTP_TS_WIDTH if PTP_TS_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - xgmii_rxd = Signal(intbv(0x0707070707070707)[64:]) - xgmii_rxc = Signal(intbv(0xff)[8:]) + xgmii_rxd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) + xgmii_rxc = Signal(intbv(0xff)[CTRL_WIDTH:]) + ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) # Outputs - m_axis_tdata = Signal(intbv(0)[64:]) - m_axis_tkeep = Signal(intbv(0)[8:]) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) m_axis_tvalid = Signal(bool(0)) m_axis_tlast = Signal(bool(0)) - m_axis_tuser = Signal(bool(0)) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) start_packet = Signal(intbv(0)[2:]) error_bad_frame = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) @@ -109,6 +117,8 @@ def bench(): m_axis_tlast=m_axis_tlast, m_axis_tuser=m_axis_tuser, + ptp_ts=ptp_ts, + start_packet=start_packet, error_bad_frame=error_bad_frame, error_bad_fcs=error_bad_fcs diff --git a/tb/test_axis_xgmii_rx_64.v b/tb/test_axis_xgmii_rx_64.v index cee56eb27..f8d7e8b06 100644 --- a/tb/test_axis_xgmii_rx_64.v +++ b/tb/test_axis_xgmii_rx_64.v @@ -32,21 +32,30 @@ THE SOFTWARE. module test_axis_xgmii_rx_64; // Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter CTRL_WIDTH = (DATA_WIDTH/8); +parameter PTP_PERIOD_NS = 4'h6; +parameter PTP_PERIOD_FNS = 16'h6666; +parameter PTP_TS_ENABLE = 0; +parameter PTP_TS_WIDTH = 96; +parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1; // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [63:0] xgmii_rxd = 64'h0707070707070707; -reg [7:0] xgmii_rxc = 8'hff; +reg [DATA_WIDTH-1:0] xgmii_rxd = 64'h0707070707070707; +reg [CTRL_WIDTH-1:0] xgmii_rxc = 8'hff; +reg [PTP_TS_WIDTH-1:0] ptp_ts = 0; // Outputs -wire [63:0] m_axis_tdata; -wire [7:0] m_axis_tkeep; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; wire m_axis_tvalid; wire m_axis_tlast; -wire m_axis_tuser; +wire [USER_WIDTH-1:0] m_axis_tuser; wire [1:0] start_packet; wire error_bad_frame; wire error_bad_fcs; @@ -58,7 +67,8 @@ initial begin rst, current_test, xgmii_rxd, - xgmii_rxc + xgmii_rxc, + ptp_ts ); $to_myhdl( m_axis_tdata, @@ -76,7 +86,16 @@ initial begin $dumpvars(0, test_axis_xgmii_rx_64); end -axis_xgmii_rx_64 +axis_xgmii_rx_64 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), @@ -87,6 +106,7 @@ UUT ( .m_axis_tvalid(m_axis_tvalid), .m_axis_tlast(m_axis_tlast), .m_axis_tuser(m_axis_tuser), + .ptp_ts(ptp_ts), .start_packet(start_packet), .error_bad_frame(error_bad_frame), .error_bad_fcs(error_bad_fcs) diff --git a/tb/test_axis_xgmii_tx_32.py b/tb/test_axis_xgmii_tx_32.py index 9fca431b5..41dc13631 100755 --- a/tb/test_axis_xgmii_tx_32.py +++ b/tb/test_axis_xgmii_tx_32.py @@ -46,25 +46,38 @@ def bench(): # Parameters + DATA_WIDTH = 32 + KEEP_WIDTH = (DATA_WIDTH/8) + CTRL_WIDTH = (DATA_WIDTH/8) ENABLE_PADDING = 1 + ENABLE_DIC = 1 MIN_FRAME_LENGTH = 64 + PTP_TS_ENABLE = 0 + PTP_TS_WIDTH = 96 + PTP_TAG_ENABLE = 0 + PTP_TAG_WIDTH = 16 + USER_WIDTH = (PTP_TAG_WIDTH if PTP_TS_ENABLE and PTP_TAG_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) - current_test = Signal(intbv(0)[4:]) + current_test = Signal(intbv(0)[8:]) - s_axis_tdata = Signal(intbv(0)[32:]) - s_axis_tkeep = Signal(intbv(0)[4:]) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) s_axis_tvalid = Signal(bool(0)) s_axis_tlast = Signal(bool(0)) - s_axis_tuser = Signal(bool(0)) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) ifg_delay = Signal(intbv(0)[8:]) # Outputs s_axis_tready = Signal(bool(0)) - xgmii_txd = Signal(intbv(0x07070707)[32:]) - xgmii_txc = Signal(intbv(0xf)[4:]) + xgmii_txd = Signal(intbv(0x07070707)[DATA_WIDTH:]) + xgmii_txc = Signal(intbv(0xf)[CTRL_WIDTH:]) + m_axis_ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) + m_axis_ptp_ts_tag = Signal(intbv(0)[PTP_TAG_WIDTH:]) + m_axis_ptp_ts_valid = Signal(bool(0)) start_packet = Signal(bool(0)) error_underflow = Signal(bool(0)) @@ -116,6 +129,11 @@ def bench(): xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, + ptp_ts=ptp_ts, + m_axis_ptp_ts=m_axis_ptp_ts, + m_axis_ptp_ts_tag=m_axis_ptp_ts_tag, + m_axis_ptp_ts_valid=m_axis_ptp_ts_valid, + ifg_delay=ifg_delay, start_packet=start_packet, diff --git a/tb/test_axis_xgmii_tx_32.v b/tb/test_axis_xgmii_tx_32.v index 244bc341d..7af249a4e 100644 --- a/tb/test_axis_xgmii_tx_32.v +++ b/tb/test_axis_xgmii_tx_32.v @@ -32,25 +32,38 @@ THE SOFTWARE. module test_axis_xgmii_tx_32; // Parameters +parameter DATA_WIDTH = 32; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter CTRL_WIDTH = (DATA_WIDTH/8); parameter ENABLE_PADDING = 1; +parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; +parameter PTP_TS_ENABLE = 0; +parameter PTP_TS_WIDTH = 96; +parameter PTP_TAG_ENABLE = 0; +parameter PTP_TAG_WIDTH = 16; +parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; // Inputs reg clk = 0; reg rst = 0; -reg [3:0] current_test = 0; +reg [7:0] current_test = 0; -reg [31:0] s_axis_tdata = 0; -reg [3:0] s_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] s_axis_tkeep = 0; reg s_axis_tvalid = 0; reg s_axis_tlast = 0; -reg s_axis_tuser = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg [PTP_TS_WIDTH-1:0] ptp_ts = 0; reg [7:0] ifg_delay = 0; // Outputs wire s_axis_tready; -wire [31:0] xgmii_txd; -wire [3:0] xgmii_txc; +wire [DATA_WIDTH-1:0] xgmii_txd; +wire [CTRL_WIDTH-1:0] xgmii_txc; +wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts; +wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag; +wire m_axis_ptp_ts_valid; wire start_packet; wire error_underflow; @@ -65,12 +78,16 @@ initial begin s_axis_tvalid, s_axis_tlast, s_axis_tuser, + ptp_ts, ifg_delay ); $to_myhdl( s_axis_tready, xgmii_txd, xgmii_txc, + m_axis_ptp_ts, + m_axis_ptp_ts_tag, + m_axis_ptp_ts_valid, start_packet, error_underflow ); @@ -81,8 +98,17 @@ initial begin end axis_xgmii_tx_32 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .PTP_TAG_ENABLE(PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(PTP_TAG_WIDTH), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -95,6 +121,10 @@ UUT ( .s_axis_tuser(s_axis_tuser), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .ptp_ts(ptp_ts), + .m_axis_ptp_ts(m_axis_ptp_ts), + .m_axis_ptp_ts_tag(m_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(m_axis_ptp_ts_valid), .ifg_delay(ifg_delay), .start_packet(start_packet), .error_underflow(error_underflow) diff --git a/tb/test_axis_xgmii_tx_64.py b/tb/test_axis_xgmii_tx_64.py index 10d178544..0845a88a0 100755 --- a/tb/test_axis_xgmii_tx_64.py +++ b/tb/test_axis_xgmii_tx_64.py @@ -46,25 +46,40 @@ def bench(): # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + CTRL_WIDTH = (DATA_WIDTH/8) ENABLE_PADDING = 1 + ENABLE_DIC = 1 MIN_FRAME_LENGTH = 64 + PTP_PERIOD_NS = 0x6 + PTP_PERIOD_FNS = 0x6666 + PTP_TS_ENABLE = 0 + PTP_TS_WIDTH = 96 + PTP_TAG_ENABLE = 0 + PTP_TAG_WIDTH = 16 + USER_WIDTH = (PTP_TAG_WIDTH if PTP_TS_ENABLE and PTP_TAG_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - s_axis_tdata = Signal(intbv(0)[64:]) - s_axis_tkeep = Signal(intbv(0)[8:]) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) s_axis_tvalid = Signal(bool(0)) s_axis_tlast = Signal(bool(0)) - s_axis_tuser = Signal(bool(0)) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) ifg_delay = Signal(intbv(0)[8:]) # Outputs s_axis_tready = Signal(bool(0)) - xgmii_txd = Signal(intbv(0x0707070707070707)[64:]) - xgmii_txc = Signal(intbv(0xff)[8:]) + xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) + xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) + m_axis_ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) + m_axis_ptp_ts_tag = Signal(intbv(0)[PTP_TAG_WIDTH:]) + m_axis_ptp_ts_valid = Signal(bool(0)) start_packet = Signal(intbv(0)[2:]) error_underflow = Signal(bool(0)) @@ -116,6 +131,11 @@ def bench(): xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, + ptp_ts=ptp_ts, + m_axis_ptp_ts=m_axis_ptp_ts, + m_axis_ptp_ts_tag=m_axis_ptp_ts_tag, + m_axis_ptp_ts_valid=m_axis_ptp_ts_valid, + ifg_delay=ifg_delay, start_packet=start_packet, diff --git a/tb/test_axis_xgmii_tx_64.v b/tb/test_axis_xgmii_tx_64.v index 71ae92778..8fdc43426 100644 --- a/tb/test_axis_xgmii_tx_64.v +++ b/tb/test_axis_xgmii_tx_64.v @@ -32,25 +32,40 @@ THE SOFTWARE. module test_axis_xgmii_tx_64; // Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter CTRL_WIDTH = (DATA_WIDTH/8); parameter ENABLE_PADDING = 1; +parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; +parameter PTP_PERIOD_NS = 4'h6; +parameter PTP_PERIOD_FNS = 16'h6666; +parameter PTP_TS_ENABLE = 0; +parameter PTP_TS_WIDTH = 96; +parameter PTP_TAG_ENABLE = 0; +parameter PTP_TAG_WIDTH = 16; +parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [63:0] s_axis_tdata = 0; -reg [7:0] s_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] s_axis_tkeep = 0; reg s_axis_tvalid = 0; reg s_axis_tlast = 0; -reg s_axis_tuser = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg [PTP_TS_WIDTH-1:0] ptp_ts = 0; reg [7:0] ifg_delay = 0; // Outputs wire s_axis_tready; -wire [63:0] xgmii_txd; -wire [7:0] xgmii_txc; +wire [DATA_WIDTH-1:0] xgmii_txd; +wire [CTRL_WIDTH-1:0] xgmii_txc; +wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts; +wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag; +wire m_axis_ptp_ts_valid; wire [1:0] start_packet; wire error_underflow; @@ -65,12 +80,16 @@ initial begin s_axis_tvalid, s_axis_tlast, s_axis_tuser, + ptp_ts, ifg_delay ); $to_myhdl( s_axis_tready, xgmii_txd, xgmii_txc, + m_axis_ptp_ts, + m_axis_ptp_ts_tag, + m_axis_ptp_ts_valid, start_packet, error_underflow ); @@ -81,8 +100,19 @@ initial begin end axis_xgmii_tx_64 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .PTP_TAG_ENABLE(PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(PTP_TAG_WIDTH), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -95,6 +125,10 @@ UUT ( .s_axis_tuser(s_axis_tuser), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .ptp_ts(ptp_ts), + .m_axis_ptp_ts(m_axis_ptp_ts), + .m_axis_ptp_ts_tag(m_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(m_axis_ptp_ts_valid), .ifg_delay(ifg_delay), .start_packet(start_packet), .error_underflow(error_underflow) diff --git a/tb/test_eth_mac_10g_32.py b/tb/test_eth_mac_10g_32.py index 43c5b9ba1..ee290e30c 100755 --- a/tb/test_eth_mac_10g_32.py +++ b/tb/test_eth_mac_10g_32.py @@ -54,6 +54,14 @@ def bench(): ENABLE_PADDING = 1 ENABLE_DIC = 1 MIN_FRAME_LENGTH = 64 + TX_PTP_TS_ENABLE = 0 + TX_PTP_TS_WIDTH = 96 + TX_PTP_TAG_ENABLE = 0 + TX_PTP_TAG_WIDTH = 16 + RX_PTP_TS_ENABLE = 0 + RX_PTP_TS_WIDTH = 96 + TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TS_ENABLE and TX_PTP_TAG_ENABLE else 0) + 1 + RX_USER_WIDTH = (RX_PTP_TS_WIDTH if RX_PTP_TS_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) @@ -68,9 +76,11 @@ def bench(): tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) tx_axis_tvalid = Signal(bool(0)) tx_axis_tlast = Signal(bool(0)) - tx_axis_tuser = Signal(bool(0)) + tx_axis_tuser = Signal(intbv(0)[TX_USER_WIDTH:]) xgmii_rxd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_rxc = Signal(intbv(0xff)[CTRL_WIDTH:]) + tx_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:]) + rx_ptp_ts = Signal(intbv(0)[RX_PTP_TS_WIDTH:]) ifg_delay = Signal(intbv(0)[8:]) # Outputs @@ -79,9 +89,12 @@ def bench(): rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) rx_axis_tvalid = Signal(bool(0)) rx_axis_tlast = Signal(bool(0)) - rx_axis_tuser = Signal(bool(0)) + rx_axis_tuser = Signal(intbv(0)[RX_USER_WIDTH:]) xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) + tx_axis_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:]) + tx_axis_ptp_ts_tag = Signal(intbv(0)[TX_PTP_TAG_WIDTH:]) + tx_axis_ptp_ts_valid = Signal(bool(0)) tx_start_packet = Signal(intbv(0)[2:]) tx_error_underflow = Signal(bool(0)) rx_start_packet = Signal(intbv(0)[2:]) @@ -173,6 +186,12 @@ def bench(): xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, + tx_ptp_ts=tx_ptp_ts, + rx_ptp_ts=rx_ptp_ts, + tx_axis_ptp_ts=tx_axis_ptp_ts, + tx_axis_ptp_ts_tag=tx_axis_ptp_ts_tag, + tx_axis_ptp_ts_valid=tx_axis_ptp_ts_valid, + tx_start_packet=tx_start_packet, tx_error_underflow=tx_error_underflow, rx_start_packet=rx_start_packet, diff --git a/tb/test_eth_mac_10g_32.v b/tb/test_eth_mac_10g_32.v index e4efdf3e8..0a98ef33e 100644 --- a/tb/test_eth_mac_10g_32.v +++ b/tb/test_eth_mac_10g_32.v @@ -38,6 +38,14 @@ parameter CTRL_WIDTH = (DATA_WIDTH/8); parameter ENABLE_PADDING = 1; parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; +parameter TX_PTP_TS_ENABLE = 0; +parameter TX_PTP_TS_WIDTH = 96; +parameter TX_PTP_TAG_ENABLE = 0; +parameter TX_PTP_TAG_WIDTH = 16; +parameter RX_PTP_TS_ENABLE = 0; +parameter RX_PTP_TS_WIDTH = 96; +parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1; +parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1; // Inputs reg clk = 0; @@ -52,9 +60,11 @@ reg [DATA_WIDTH-1:0] tx_axis_tdata = 0; reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0; reg tx_axis_tvalid = 0; reg tx_axis_tlast = 0; -reg tx_axis_tuser = 0; +reg [TX_USER_WIDTH-1:0] tx_axis_tuser = 0; reg [DATA_WIDTH-1:0] xgmii_rxd = 0; reg [CTRL_WIDTH-1:0] xgmii_rxc = 0; +reg [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts = 0; +reg [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts = 0; reg [7:0] ifg_delay = 0; // Outputs @@ -63,9 +73,12 @@ wire [DATA_WIDTH-1:0] rx_axis_tdata; wire [KEEP_WIDTH-1:0] rx_axis_tkeep; wire rx_axis_tvalid; wire rx_axis_tlast; -wire rx_axis_tuser; +wire [RX_USER_WIDTH-1:0] rx_axis_tuser; wire [DATA_WIDTH-1:0] xgmii_txd; wire [CTRL_WIDTH-1:0] xgmii_txc; +wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts; +wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag; +wire tx_axis_ptp_ts_valid; wire [1:0] tx_start_packet; wire tx_error_underflow; wire [1:0] rx_start_packet; @@ -89,6 +102,8 @@ initial begin tx_axis_tuser, xgmii_rxd, xgmii_rxc, + tx_ptp_ts, + rx_ptp_ts, ifg_delay ); $to_myhdl( @@ -100,6 +115,9 @@ initial begin rx_axis_tuser, xgmii_txd, xgmii_txc, + tx_axis_ptp_ts, + tx_axis_ptp_ts_tag, + tx_axis_ptp_ts_valid, tx_start_packet, tx_error_underflow, rx_start_packet, @@ -118,7 +136,15 @@ eth_mac_10g #( .CTRL_WIDTH(CTRL_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .TX_PTP_TS_ENABLE(TX_PTP_TS_ENABLE), + .TX_PTP_TS_WIDTH(TX_PTP_TS_WIDTH), + .TX_PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), + .TX_PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), + .RX_PTP_TS_ENABLE(RX_PTP_TS_ENABLE), + .RX_PTP_TS_WIDTH(RX_PTP_TS_WIDTH), + .TX_USER_WIDTH(TX_USER_WIDTH), + .RX_USER_WIDTH(RX_USER_WIDTH) ) UUT ( .rx_clk(rx_clk), @@ -140,6 +166,11 @@ UUT ( .xgmii_rxc(xgmii_rxc), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .tx_ptp_ts(tx_ptp_ts), + .rx_ptp_ts(rx_ptp_ts), + .tx_axis_ptp_ts(tx_axis_ptp_ts), + .tx_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), + .tx_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), .tx_start_packet(tx_start_packet), .tx_error_underflow(tx_error_underflow), .rx_start_packet(rx_start_packet), diff --git a/tb/test_eth_mac_10g_64.py b/tb/test_eth_mac_10g_64.py index ccbc7bed4..2662ed6c6 100755 --- a/tb/test_eth_mac_10g_64.py +++ b/tb/test_eth_mac_10g_64.py @@ -54,6 +54,16 @@ def bench(): ENABLE_PADDING = 1 ENABLE_DIC = 1 MIN_FRAME_LENGTH = 64 + PTP_PERIOD_NS = 0x6 + PTP_PERIOD_FNS = 0x6666 + TX_PTP_TS_ENABLE = 0 + TX_PTP_TS_WIDTH = 96 + TX_PTP_TAG_ENABLE = 0 + TX_PTP_TAG_WIDTH = 16 + RX_PTP_TS_ENABLE = 0 + RX_PTP_TS_WIDTH = 96 + TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TS_ENABLE and TX_PTP_TAG_ENABLE else 0) + 1 + RX_USER_WIDTH = (RX_PTP_TS_WIDTH if RX_PTP_TS_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) @@ -68,9 +78,11 @@ def bench(): tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) tx_axis_tvalid = Signal(bool(0)) tx_axis_tlast = Signal(bool(0)) - tx_axis_tuser = Signal(bool(0)) + tx_axis_tuser = Signal(intbv(0)[TX_USER_WIDTH:]) xgmii_rxd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_rxc = Signal(intbv(0xff)[CTRL_WIDTH:]) + tx_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:]) + rx_ptp_ts = Signal(intbv(0)[RX_PTP_TS_WIDTH:]) ifg_delay = Signal(intbv(0)[8:]) # Outputs @@ -79,9 +91,12 @@ def bench(): rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) rx_axis_tvalid = Signal(bool(0)) rx_axis_tlast = Signal(bool(0)) - rx_axis_tuser = Signal(bool(0)) + rx_axis_tuser = Signal(intbv(0)[RX_USER_WIDTH:]) xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) + tx_axis_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:]) + tx_axis_ptp_ts_tag = Signal(intbv(0)[TX_PTP_TAG_WIDTH:]) + tx_axis_ptp_ts_valid = Signal(bool(0)) tx_start_packet = Signal(intbv(0)[2:]) tx_error_underflow = Signal(bool(0)) rx_start_packet = Signal(intbv(0)[2:]) @@ -173,6 +188,12 @@ def bench(): xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, + tx_ptp_ts=tx_ptp_ts, + rx_ptp_ts=rx_ptp_ts, + tx_axis_ptp_ts=tx_axis_ptp_ts, + tx_axis_ptp_ts_tag=tx_axis_ptp_ts_tag, + tx_axis_ptp_ts_valid=tx_axis_ptp_ts_valid, + tx_start_packet=tx_start_packet, tx_error_underflow=tx_error_underflow, rx_start_packet=rx_start_packet, diff --git a/tb/test_eth_mac_10g_64.v b/tb/test_eth_mac_10g_64.v index 10ef31f8a..db0585b3b 100644 --- a/tb/test_eth_mac_10g_64.v +++ b/tb/test_eth_mac_10g_64.v @@ -38,6 +38,16 @@ parameter CTRL_WIDTH = (DATA_WIDTH/8); parameter ENABLE_PADDING = 1; parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; +parameter PTP_PERIOD_NS = 4'h6; +parameter PTP_PERIOD_FNS = 16'h6666; +parameter TX_PTP_TS_ENABLE = 0; +parameter TX_PTP_TS_WIDTH = 96; +parameter TX_PTP_TAG_ENABLE = 0; +parameter TX_PTP_TAG_WIDTH = 16; +parameter RX_PTP_TS_ENABLE = 0; +parameter RX_PTP_TS_WIDTH = 96; +parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1; +parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1; // Inputs reg clk = 0; @@ -52,9 +62,11 @@ reg [DATA_WIDTH-1:0] tx_axis_tdata = 0; reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0; reg tx_axis_tvalid = 0; reg tx_axis_tlast = 0; -reg tx_axis_tuser = 0; +reg [TX_USER_WIDTH-1:0] tx_axis_tuser = 0; reg [DATA_WIDTH-1:0] xgmii_rxd = 0; reg [CTRL_WIDTH-1:0] xgmii_rxc = 0; +reg [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts = 0; +reg [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts = 0; reg [7:0] ifg_delay = 0; // Outputs @@ -63,9 +75,12 @@ wire [DATA_WIDTH-1:0] rx_axis_tdata; wire [KEEP_WIDTH-1:0] rx_axis_tkeep; wire rx_axis_tvalid; wire rx_axis_tlast; -wire rx_axis_tuser; +wire [RX_USER_WIDTH-1:0] rx_axis_tuser; wire [DATA_WIDTH-1:0] xgmii_txd; wire [CTRL_WIDTH-1:0] xgmii_txc; +wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts; +wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag; +wire tx_axis_ptp_ts_valid; wire [1:0] tx_start_packet; wire tx_error_underflow; wire [1:0] rx_start_packet; @@ -89,6 +104,8 @@ initial begin tx_axis_tuser, xgmii_rxd, xgmii_rxc, + tx_ptp_ts, + rx_ptp_ts, ifg_delay ); $to_myhdl( @@ -100,6 +117,9 @@ initial begin rx_axis_tuser, xgmii_txd, xgmii_txc, + tx_axis_ptp_ts, + tx_axis_ptp_ts_tag, + tx_axis_ptp_ts_valid, tx_start_packet, tx_error_underflow, rx_start_packet, @@ -118,7 +138,17 @@ eth_mac_10g #( .CTRL_WIDTH(CTRL_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .TX_PTP_TS_ENABLE(TX_PTP_TS_ENABLE), + .TX_PTP_TS_WIDTH(TX_PTP_TS_WIDTH), + .TX_PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), + .TX_PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), + .RX_PTP_TS_ENABLE(RX_PTP_TS_ENABLE), + .RX_PTP_TS_WIDTH(RX_PTP_TS_WIDTH), + .TX_USER_WIDTH(TX_USER_WIDTH), + .RX_USER_WIDTH(RX_USER_WIDTH) ) UUT ( .rx_clk(rx_clk), @@ -140,6 +170,11 @@ UUT ( .xgmii_rxc(xgmii_rxc), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .tx_ptp_ts(tx_ptp_ts), + .rx_ptp_ts(rx_ptp_ts), + .tx_axis_ptp_ts(tx_axis_ptp_ts), + .tx_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), + .tx_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), .tx_start_packet(tx_start_packet), .tx_error_underflow(tx_error_underflow), .rx_start_packet(rx_start_packet), diff --git a/tb/test_eth_mac_1g.py b/tb/test_eth_mac_1g.py index b1cd8816c..8a978e8d2 100755 --- a/tb/test_eth_mac_1g.py +++ b/tb/test_eth_mac_1g.py @@ -48,8 +48,17 @@ def bench(): # Parameters + DATA_WIDTH = 8 ENABLE_PADDING = 1 MIN_FRAME_LENGTH = 64 + TX_PTP_TS_ENABLE = 0 + TX_PTP_TS_WIDTH = 96 + TX_PTP_TAG_ENABLE = 0 + TX_PTP_TAG_WIDTH = 16 + RX_PTP_TS_ENABLE = 0 + RX_PTP_TS_WIDTH = 96 + TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TS_ENABLE and TX_PTP_TAG_ENABLE else 0) + 1 + RX_USER_WIDTH = (RX_PTP_TS_WIDTH if RX_PTP_TS_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) @@ -60,13 +69,15 @@ def bench(): rx_rst = Signal(bool(0)) tx_clk = Signal(bool(0)) tx_rst = Signal(bool(0)) - tx_axis_tdata = Signal(intbv(0)[8:]) + tx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) tx_axis_tvalid = Signal(bool(0)) tx_axis_tlast = Signal(bool(0)) - tx_axis_tuser = Signal(bool(0)) - gmii_rxd = Signal(intbv(0)[8:]) + tx_axis_tuser = Signal(intbv(0)[TX_USER_WIDTH:]) + gmii_rxd = Signal(intbv(0)[DATA_WIDTH:]) gmii_rx_dv = Signal(bool(0)) gmii_rx_er = Signal(bool(0)) + tx_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:]) + rx_ptp_ts = Signal(intbv(0)[RX_PTP_TS_WIDTH:]) rx_clk_enable = Signal(bool(1)) tx_clk_enable = Signal(bool(1)) rx_mii_select = Signal(bool(0)) @@ -75,13 +86,16 @@ def bench(): # Outputs tx_axis_tready = Signal(bool(0)) - rx_axis_tdata = Signal(intbv(0)[8:]) + rx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) rx_axis_tvalid = Signal(bool(0)) rx_axis_tlast = Signal(bool(0)) - rx_axis_tuser = Signal(bool(0)) - gmii_txd = Signal(intbv(0)[8:]) + rx_axis_tuser = Signal(intbv(0)[RX_USER_WIDTH:]) + gmii_txd = Signal(intbv(0)[DATA_WIDTH:]) gmii_tx_en = Signal(bool(0)) gmii_tx_er = Signal(bool(0)) + tx_axis_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:]) + tx_axis_ptp_ts_tag = Signal(intbv(0)[TX_PTP_TAG_WIDTH:]) + tx_axis_ptp_ts_valid = Signal(bool(0)) tx_start_packet = Signal(bool(0)) tx_error_underflow = Signal(bool(0)) rx_start_packet = Signal(bool(0)) @@ -177,6 +191,12 @@ def bench(): gmii_tx_en=gmii_tx_en, gmii_tx_er=gmii_tx_er, + tx_ptp_ts=tx_ptp_ts, + rx_ptp_ts=rx_ptp_ts, + tx_axis_ptp_ts=tx_axis_ptp_ts, + tx_axis_ptp_ts_tag=tx_axis_ptp_ts_tag, + tx_axis_ptp_ts_valid=tx_axis_ptp_ts_valid, + rx_clk_enable=rx_clk_enable, tx_clk_enable=tx_clk_enable, diff --git a/tb/test_eth_mac_1g.v b/tb/test_eth_mac_1g.v index 4f92c1e78..25b63dbb2 100644 --- a/tb/test_eth_mac_1g.v +++ b/tb/test_eth_mac_1g.v @@ -32,8 +32,17 @@ THE SOFTWARE. module test_eth_mac_1g; // Parameters +parameter DATA_WIDTH = 8; parameter ENABLE_PADDING = 1; parameter MIN_FRAME_LENGTH = 64; +parameter TX_PTP_TS_ENABLE = 0; +parameter TX_PTP_TS_WIDTH = 96; +parameter TX_PTP_TAG_ENABLE = 0; +parameter TX_PTP_TAG_WIDTH = 16; +parameter RX_PTP_TS_ENABLE = 0; +parameter RX_PTP_TS_WIDTH = 96; +parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1; +parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1; // Inputs reg clk = 0; @@ -44,13 +53,15 @@ reg rx_clk = 0; reg rx_rst = 0; reg tx_clk = 0; reg tx_rst = 0; -reg [7:0] tx_axis_tdata = 0; +reg [DATA_WIDTH-1:0] tx_axis_tdata = 0; reg tx_axis_tvalid = 0; reg tx_axis_tlast = 0; -reg tx_axis_tuser = 0; -reg [7:0] gmii_rxd = 0; +reg [TX_USER_WIDTH-1:0] tx_axis_tuser = 0; +reg [DATA_WIDTH-1:0] gmii_rxd = 0; reg gmii_rx_dv = 0; reg gmii_rx_er = 0; +reg [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts = 0; +reg [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts = 0; reg rx_clk_enable = 1; reg tx_clk_enable = 1; reg rx_mii_select = 0; @@ -59,13 +70,16 @@ reg [7:0] ifg_delay = 0; // Outputs wire tx_axis_tready; -wire [7:0] rx_axis_tdata; +wire [DATA_WIDTH-1:0] rx_axis_tdata; wire rx_axis_tvalid; wire rx_axis_tlast; -wire rx_axis_tuser; -wire [7:0] gmii_txd; +wire [RX_USER_WIDTH-1:0] rx_axis_tuser; +wire [DATA_WIDTH-1:0] gmii_txd; wire gmii_tx_en; wire gmii_tx_er; +wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts; +wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag; +wire tx_axis_ptp_ts_valid; wire tx_start_packet; wire tx_error_underflow; wire rx_start_packet; @@ -89,6 +103,8 @@ initial begin gmii_rxd, gmii_rx_dv, gmii_rx_er, + tx_ptp_ts, + rx_ptp_ts, rx_clk_enable, tx_clk_enable, rx_mii_select, @@ -104,6 +120,9 @@ initial begin gmii_txd, gmii_tx_en, gmii_tx_er, + tx_axis_ptp_ts, + tx_axis_ptp_ts_tag, + tx_axis_ptp_ts_valid, tx_start_packet, tx_error_underflow, rx_start_packet, @@ -117,8 +136,17 @@ initial begin end eth_mac_1g #( + .DATA_WIDTH(DATA_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .TX_PTP_TS_ENABLE(TX_PTP_TS_ENABLE), + .TX_PTP_TS_WIDTH(TX_PTP_TS_WIDTH), + .TX_PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), + .TX_PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), + .RX_PTP_TS_ENABLE(RX_PTP_TS_ENABLE), + .RX_PTP_TS_WIDTH(RX_PTP_TS_WIDTH), + .TX_USER_WIDTH(TX_USER_WIDTH), + .RX_USER_WIDTH(RX_USER_WIDTH) ) UUT ( .rx_clk(rx_clk), @@ -140,6 +168,11 @@ UUT ( .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), + .tx_ptp_ts(tx_ptp_ts), + .rx_ptp_ts(rx_ptp_ts), + .tx_axis_ptp_ts(tx_axis_ptp_ts), + .tx_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), + .tx_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), .rx_clk_enable(rx_clk_enable), .tx_clk_enable(tx_clk_enable), .rx_mii_select(rx_mii_select), diff --git a/tb/test_eth_mac_phy_10g.py b/tb/test_eth_mac_phy_10g.py index e5156b0c9..255aa6f0f 100755 --- a/tb/test_eth_mac_phy_10g.py +++ b/tb/test_eth_mac_phy_10g.py @@ -62,6 +62,16 @@ def bench(): ENABLE_PADDING = 1 ENABLE_DIC = 1 MIN_FRAME_LENGTH = 64 + PTP_PERIOD_NS = 0x6 + PTP_PERIOD_FNS = 0x6666 + TX_PTP_TS_ENABLE = 0 + TX_PTP_TS_WIDTH = 96 + TX_PTP_TAG_ENABLE = 0 + TX_PTP_TAG_WIDTH = 16 + RX_PTP_TS_ENABLE = 0 + RX_PTP_TS_WIDTH = 96 + TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TS_ENABLE and TX_PTP_TAG_ENABLE else 0) + 1 + RX_USER_WIDTH = (RX_PTP_TS_WIDTH if RX_PTP_TS_ENABLE else 0) + 1 BIT_REVERSE = 0 SCRAMBLER_DISABLE = 0 PRBS31_ENABLE = 1 @@ -81,9 +91,11 @@ def bench(): tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) tx_axis_tvalid = Signal(bool(0)) tx_axis_tlast = Signal(bool(0)) - tx_axis_tuser = Signal(bool(0)) + tx_axis_tuser = Signal(intbv(0)[TX_USER_WIDTH:]) serdes_rx_data = Signal(intbv(0)[DATA_WIDTH:]) serdes_rx_hdr = Signal(intbv(1)[HDR_WIDTH:]) + tx_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:]) + rx_ptp_ts = Signal(intbv(0)[RX_PTP_TS_WIDTH:]) ifg_delay = Signal(intbv(0)[8:]) tx_prbs31_enable = Signal(bool(0)) rx_prbs31_enable = Signal(bool(0)) @@ -97,10 +109,13 @@ def bench(): rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) rx_axis_tvalid = Signal(bool(0)) rx_axis_tlast = Signal(bool(0)) - rx_axis_tuser = Signal(bool(0)) + rx_axis_tuser = Signal(intbv(0)[RX_USER_WIDTH:]) serdes_tx_data = Signal(intbv(0)[DATA_WIDTH:]) serdes_tx_hdr = Signal(intbv(1)[HDR_WIDTH:]) serdes_rx_bitslip = Signal(bool(0)) + tx_axis_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:]) + tx_axis_ptp_ts_tag = Signal(intbv(0)[TX_PTP_TAG_WIDTH:]) + tx_axis_ptp_ts_valid = Signal(bool(0)) tx_start_packet = Signal(intbv(0)[2:]) tx_error_underflow = Signal(bool(0)) rx_start_packet = Signal(intbv(0)[2:]) @@ -189,6 +204,11 @@ def bench(): serdes_rx_data=serdes_rx_data, serdes_rx_hdr=serdes_rx_hdr, serdes_rx_bitslip=serdes_rx_bitslip, + tx_ptp_ts=tx_ptp_ts, + rx_ptp_ts=rx_ptp_ts, + tx_axis_ptp_ts=tx_axis_ptp_ts, + tx_axis_ptp_ts_tag=tx_axis_ptp_ts_tag, + tx_axis_ptp_ts_valid=tx_axis_ptp_ts_valid, tx_start_packet=tx_start_packet, tx_error_underflow=tx_error_underflow, rx_start_packet=rx_start_packet, diff --git a/tb/test_eth_mac_phy_10g.v b/tb/test_eth_mac_phy_10g.v index 77f85468d..6a73719e9 100644 --- a/tb/test_eth_mac_phy_10g.v +++ b/tb/test_eth_mac_phy_10g.v @@ -39,6 +39,16 @@ parameter HDR_WIDTH = (DATA_WIDTH/32); parameter ENABLE_PADDING = 1; parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; +parameter PTP_PERIOD_NS = 4'h6; +parameter PTP_PERIOD_FNS = 16'h6666; +parameter TX_PTP_TS_ENABLE = 0; +parameter TX_PTP_TS_WIDTH = 96; +parameter TX_PTP_TAG_ENABLE = 0; +parameter TX_PTP_TAG_WIDTH = 16; +parameter RX_PTP_TS_ENABLE = 0; +parameter RX_PTP_TS_WIDTH = 96; +parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1; +parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1; parameter BIT_REVERSE = 0; parameter SCRAMBLER_DISABLE = 0; parameter PRBS31_ENABLE = 1; @@ -58,9 +68,11 @@ reg [DATA_WIDTH-1:0] tx_axis_tdata = 0; reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0; reg tx_axis_tvalid = 0; reg tx_axis_tlast = 0; -reg tx_axis_tuser = 0; +reg [TX_USER_WIDTH-1:0] tx_axis_tuser = 0; reg [DATA_WIDTH-1:0] serdes_rx_data = 0; reg [HDR_WIDTH-1:0] serdes_rx_hdr = 1; +reg [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts = 0; +reg [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts = 0; reg [7:0] ifg_delay = 0; reg tx_prbs31_enable = 0; reg rx_prbs31_enable = 0; @@ -71,10 +83,13 @@ wire [DATA_WIDTH-1:0] rx_axis_tdata; wire [KEEP_WIDTH-1:0] rx_axis_tkeep; wire rx_axis_tvalid; wire rx_axis_tlast; -wire rx_axis_tuser; +wire [RX_USER_WIDTH-1:0] rx_axis_tuser; wire [DATA_WIDTH-1:0] serdes_tx_data; wire [HDR_WIDTH-1:0] serdes_tx_hdr; wire serdes_rx_bitslip; +wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts; +wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag; +wire tx_axis_ptp_ts_valid; wire [1:0] tx_start_packet; wire tx_error_underflow; wire [1:0] rx_start_packet; @@ -102,6 +117,8 @@ initial begin tx_axis_tuser, serdes_rx_data, serdes_rx_hdr, + tx_ptp_ts, + rx_ptp_ts, ifg_delay, tx_prbs31_enable, rx_prbs31_enable @@ -116,6 +133,9 @@ initial begin serdes_tx_data, serdes_tx_hdr, serdes_rx_bitslip, + tx_axis_ptp_ts, + tx_axis_ptp_ts_tag, + tx_axis_ptp_ts_valid, tx_start_packet, tx_error_underflow, rx_error_count, @@ -140,6 +160,16 @@ eth_mac_phy_10g #( .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .TX_PTP_TS_ENABLE(TX_PTP_TS_ENABLE), + .TX_PTP_TS_WIDTH(TX_PTP_TS_WIDTH), + .TX_PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), + .TX_PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), + .RX_PTP_TS_ENABLE(RX_PTP_TS_ENABLE), + .RX_PTP_TS_WIDTH(RX_PTP_TS_WIDTH), + .TX_USER_WIDTH(TX_USER_WIDTH), + .RX_USER_WIDTH(RX_USER_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .PRBS31_ENABLE(PRBS31_ENABLE), @@ -167,6 +197,11 @@ UUT ( .serdes_rx_data(serdes_rx_data), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_bitslip(serdes_rx_bitslip), + .tx_ptp_ts(tx_ptp_ts), + .rx_ptp_ts(rx_ptp_ts), + .tx_axis_ptp_ts(tx_axis_ptp_ts), + .tx_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), + .tx_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), .tx_start_packet(tx_start_packet), .tx_error_underflow(tx_error_underflow), .rx_start_packet(rx_start_packet),