From 9665df8a442d9c0ea8fdc29f8708513dc0cadac1 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 8 Jul 2023 01:41:14 -0700 Subject: [PATCH] Fix PTP timestamping in 1G MAC Signed-off-by: Alex Forencich --- rtl/axis_gmii_rx.v | 40 +++++++++++++++++++++++++--------------- rtl/axis_gmii_tx.v | 23 +++++++++++++++++++---- 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/rtl/axis_gmii_rx.v b/rtl/axis_gmii_rx.v index 6203b2b27..64ff1d77f 100644 --- a/rtl/axis_gmii_rx.v +++ b/rtl/axis_gmii_rx.v @@ -100,7 +100,7 @@ reg reset_crc; reg update_crc; reg mii_odd = 1'b0; -reg mii_locked = 1'b0; +reg in_frame = 1'b0; reg [DATA_WIDTH-1:0] gmii_rxd_d0 = {DATA_WIDTH{1'b0}}; reg [DATA_WIDTH-1:0] gmii_rxd_d1 = {DATA_WIDTH{1'b0}}; @@ -125,11 +125,12 @@ 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; -reg start_packet_reg = 1'b0, start_packet_next; +reg start_packet_int_reg = 1'b0; +reg start_packet_reg = 1'b0; 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 [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0; reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next; @@ -170,12 +171,9 @@ always @* begin m_axis_tlast_next = 1'b0; m_axis_tuser_next = 1'b0; - start_packet_next = 1'b0; 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; @@ -189,8 +187,6 @@ 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 state_next = STATE_IDLE; @@ -246,21 +242,28 @@ end always @(posedge clk) begin state_reg <= state_next; - ptp_ts_reg <= ptp_ts_next; - m_axis_tdata_reg <= m_axis_tdata_next; m_axis_tvalid_reg <= m_axis_tvalid_next; m_axis_tlast_reg <= m_axis_tlast_next; m_axis_tuser_reg <= m_axis_tuser_next; + start_packet_int_reg <= 1'b0; + start_packet_reg <= 1'b0; + + if (start_packet_int_reg) begin + ptp_ts_reg <= ptp_ts; + start_packet_reg <= 1'b1; + end + if (clk_enable) begin if (mii_select) begin mii_odd <= !mii_odd; - if (mii_locked) begin - mii_locked <= gmii_rx_dv; + if (in_frame) begin + in_frame <= gmii_rx_dv; end else if (gmii_rx_dv && {gmii_rxd[3:0], gmii_rxd_d0[7:4]} == ETH_SFD) begin - mii_locked <= 1'b1; + in_frame <= 1'b1; + start_packet_int_reg <= 1'b1; mii_odd <= 1'b1; end @@ -288,6 +291,13 @@ always @(posedge clk) begin gmii_rx_er_d0 <= gmii_rx_er; end end else begin + if (in_frame) begin + in_frame <= gmii_rx_dv; + end else if (gmii_rx_dv && gmii_rxd == ETH_SFD) begin + in_frame <= 1'b1; + start_packet_int_reg <= 1'b1; + end + gmii_rxd_d0 <= gmii_rxd; gmii_rxd_d1 <= gmii_rxd_d0; gmii_rxd_d2 <= gmii_rxd_d1; @@ -314,7 +324,6 @@ always @(posedge clk) begin crc_state <= crc_next; end - start_packet_reg <= start_packet_next; error_bad_frame_reg <= error_bad_frame_next; error_bad_fcs_reg <= error_bad_fcs_next; @@ -323,11 +332,12 @@ always @(posedge clk) begin m_axis_tvalid_reg <= 1'b0; + start_packet_int_reg <= 1'b0; start_packet_reg <= 1'b0; error_bad_frame_reg <= 1'b0; error_bad_fcs_reg <= 1'b0; - mii_locked <= 1'b0; + in_frame <= 1'b0; mii_odd <= 1'b0; gmii_rx_dv_d0 <= 1'b0; diff --git a/rtl/axis_gmii_tx.v b/rtl/axis_gmii_tx.v index b731ebd90..d887536e9 100644 --- a/rtl/axis_gmii_tx.v +++ b/rtl/axis_gmii_tx.v @@ -136,6 +136,7 @@ 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_int_reg = 1'b0, start_packet_int_next; reg start_packet_reg = 1'b0, start_packet_next; reg error_underflow_reg = 1'b0, error_underflow_next; @@ -195,6 +196,13 @@ always @* begin gmii_tx_en_next = 1'b0; gmii_tx_er_next = 1'b0; + if (start_packet_reg) begin + 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; + end + + start_packet_int_next = start_packet_int_reg; start_packet_next = 1'b0; error_underflow_next = 1'b0; @@ -211,6 +219,10 @@ always @* begin gmii_tx_en_next = gmii_tx_en_reg; gmii_tx_er_next = gmii_tx_er_reg; state_next = state_reg; + if (start_packet_int_reg) begin + start_packet_int_next = 1'b0; + start_packet_next = 1'b1; + end end else begin case (state_reg) STATE_IDLE: begin @@ -253,10 +265,11 @@ 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; + if (mii_select) begin + start_packet_int_next = 1'b1; + end else begin + start_packet_next = 1'b1; + end state_next = STATE_PAYLOAD; end else begin state_next = STATE_PREAMBLE; @@ -427,6 +440,7 @@ always @(posedge clk) begin crc_state <= crc_next; end + start_packet_int_reg <= start_packet_int_next; start_packet_reg <= start_packet_next; error_underflow_reg <= error_underflow_next; @@ -440,6 +454,7 @@ always @(posedge clk) begin gmii_tx_en_reg <= 1'b0; gmii_tx_er_reg <= 1'b0; + start_packet_int_reg <= 1'b0; start_packet_reg <= 1'b0; error_underflow_reg <= 1'b0; end