diff --git a/src/eth/rtl/taxi_axis_baser_rx_32.sv b/src/eth/rtl/taxi_axis_baser_rx_32.sv index 291f29a..4b31a5f 100644 --- a/src/eth/rtl/taxi_axis_baser_rx_32.sv +++ b/src/eth/rtl/taxi_axis_baser_rx_32.sv @@ -174,6 +174,10 @@ logic framing_error_reg = 1'b0; logic [9:0] rep_cnt_reg = '0; logic rep_stall_reg = 1'b0; +logic rep_stall_d0_reg = 1'b0; +logic rep_stall_d1_reg = 1'b0; +logic rep_en_reg = 1'b0; +logic rep_start_reg = 1'b0; logic [DATA_W-1:0] input_data_d0_reg = '0; logic [DATA_W-1:0] input_data_d1_reg = '0; @@ -214,7 +218,7 @@ logic rx_os_valid_reg = 1'b0; logic [1:0] rx_os_match_reg = '0; logic [1:0] rx_idle_match_reg = '0; -logic start_packet_reg = 1'b0, start_packet_next; +logic start_packet_reg = 1'b0; logic frame_reg = 1'b0; logic [2:0] stat_rx_byte_reg = '0, stat_rx_byte_next; @@ -233,7 +237,7 @@ logic stat_rx_err_bad_block_reg = 1'b0; logic stat_rx_err_framing_reg = 1'b0, stat_rx_err_framing_next; logic stat_rx_err_preamble_reg = 1'b0, stat_rx_err_preamble_next; -logic [PTP_TS_W-1:0] ptp_ts_out_reg = '0, ptp_ts_out_next; +logic [PTP_TS_W-1:0] ptp_ts_out_reg = '0; logic [31:0] crc_state_reg = '1; @@ -325,10 +329,6 @@ always_comb begin m_axis_rx_tlast_next = 1'b0; m_axis_rx_tuser_next = 1'b0; - ptp_ts_out_next = ptp_ts_out_reg; - - start_packet_next = 1'b0; - stat_rx_byte_next = '0; stat_rx_pkt_len_next = '0; stat_rx_pkt_fragment_next = 1'b0; @@ -347,7 +347,7 @@ always_comb begin if (GBX_IF_EN && !encoded_rx_data_valid) begin // data from gearbox not valid - hold state state_next = state_reg; - end else if (USXGMII_EN && rep_stall_reg) begin + end else if (USXGMII_EN && rep_stall_d1_reg) begin // USXGMII stall - hold state state_next = state_reg; end else begin @@ -423,9 +423,6 @@ always_comb begin state_next = STATE_PREAMBLE; end end else begin - if (PTP_TS_EN) begin - ptp_ts_out_next = ptp_ts; - end state_next = STATE_IDLE; end end @@ -442,7 +439,6 @@ always_comb begin stat_rx_err_framing_next = 1'b1; state_next = STATE_IDLE; end else begin - start_packet_next = 1'b1; stat_rx_byte_next = 3'(KEEP_W); state_next = STATE_PAYLOAD; end @@ -598,9 +594,7 @@ always_ff @(posedge clk) begin rx_os_valid_reg <= 1'b0; - ptp_ts_out_reg <= ptp_ts_out_next; - - start_packet_reg <= start_packet_next; + start_packet_reg <= 1'b0; stat_rx_byte_reg <= stat_rx_byte_next; stat_rx_pkt_len_reg <= stat_rx_pkt_len_next; @@ -636,7 +630,7 @@ always_ff @(posedge clk) begin input_start_alt_reg <= 1'b0; - if (!USXGMII_EN || !rep_stall_reg) begin + if (!USXGMII_EN || !rep_stall_d1_reg) begin term_lane_d0_reg <= term_lane_reg; input_data_d0_reg <= encoded_rx_data_reg; @@ -648,6 +642,18 @@ always_ff @(posedge clk) begin input_start_d2_reg <= input_start_d1_reg; end + if (input_start_d1_reg) begin + ptp_ts_out_reg <= ptp_ts; + if (!USXGMII_EN || !rep_en_reg) begin + start_packet_reg <= 1'b1; + end + end + + if (USXGMII_EN && rep_start_reg && !rep_stall_d0_reg) begin + ptp_ts_out_reg <= ptp_ts; + start_packet_reg <= 1'b1; + end + if (encoded_rx_hdr_valid_reg) begin // portion with header if (encoded_rx_hdr_reg[0] == 0) begin @@ -853,25 +859,80 @@ always_ff @(posedge clk) begin end if (USXGMII_EN && cfg_rx_usxgmii_en) begin - if (rep_cnt_reg == 0 || (encoded_rx_hdr_valid_reg && encoded_rx_hdr_reg[0]) || input_start_alt_reg) begin + if ((encoded_rx_hdr_valid_reg && encoded_rx_hdr_reg[0] && encoded_rx_data_reg[7:4] == BLOCK_TYPE_START_0[7:4]) || input_start_alt_reg) begin + rep_stall_reg <= !rep_stall_d0_reg; + rep_en_reg <= 1'b1; + rep_start_reg <= 1'b0; + if (cfg_rx_usxgmii_5g) begin + case (cfg_rx_usxgmii_speed) + 3'b000: rep_cnt_reg <= 497; // 10 Mbps + 3'b001: rep_cnt_reg <= 47; // 100 Mbps + 3'b010: rep_cnt_reg <= 2; // 1 Gbps + 3'b100: begin + // 2.5 Gbps + rep_cnt_reg <= 1; + rep_stall_reg <= 1'b0; + end + default: begin + // 5 Gbps + rep_cnt_reg <= 0; + rep_stall_reg <= 1'b0; + end + endcase + end else begin + case (cfg_rx_usxgmii_speed) + 3'b000: rep_cnt_reg <= 997; // 10 Mbps + 3'b001: rep_cnt_reg <= 97; // 100 Mbps + 3'b010: rep_cnt_reg <= 7; // 1 Gbps + 3'b100: rep_cnt_reg <= 1; // 2.5 Gbps + 3'b101: begin + // 5 Gbps + rep_cnt_reg <= 1; + rep_stall_reg <= 1'b0; + end + default: begin + // 10 Gbps + rep_cnt_reg <= 0; + rep_stall_reg <= 1'b0; + rep_en_reg <= 1'b0; + end + endcase + end + end else if (rep_cnt_reg == 0) begin + rep_en_reg <= 1'b1; + rep_start_reg <= input_start_d2_reg; if (cfg_rx_usxgmii_5g) begin case (cfg_rx_usxgmii_speed) 3'b000: rep_cnt_reg <= 499; // 10 Mbps 3'b001: rep_cnt_reg <= 49; // 100 Mbps 3'b010: rep_cnt_reg <= 4; // 1 Gbps - 3'b100: rep_cnt_reg <= 1; // 2.5 Gbps - 3'b101: rep_cnt_reg <= 0; // 5 Gbps - default: rep_cnt_reg <= 0; + 3'b100: begin + rep_cnt_reg <= 1; // 2.5 Gbps + rep_start_reg <= input_start_d1_reg; + end + default: begin + // 5 Gbps + rep_cnt_reg <= 0; + rep_en_reg <= 1'b0; + rep_start_reg <= 1'b0; + end endcase end else begin case (cfg_rx_usxgmii_speed) 3'b000: rep_cnt_reg <= 999; // 10 Mbps 3'b001: rep_cnt_reg <= 99; // 100 Mbps 3'b010: rep_cnt_reg <= 9; // 1 Gbps - 3'b011: rep_cnt_reg <= 0; // 10 Gbps 3'b100: rep_cnt_reg <= 3; // 2.5 Gbps - 3'b101: rep_cnt_reg <= 1; // 5 Gbps - default: rep_cnt_reg <= 0; + 3'b101: begin + rep_cnt_reg <= 1; // 5 Gbps + rep_start_reg <= input_start_d1_reg; + end + default: begin + // 10 Gbps + rep_cnt_reg <= 0; + rep_en_reg <= 1'b0; + rep_start_reg <= 1'b0; + end endcase end @@ -880,9 +941,16 @@ always_ff @(posedge clk) begin rep_cnt_reg <= rep_cnt_reg-1; rep_stall_reg <= 1'b1; end + + rep_stall_d0_reg <= rep_stall_reg; + rep_stall_d1_reg <= rep_stall_d0_reg; end else begin rep_cnt_reg <= '0; rep_stall_reg <= 1'b0; + rep_stall_d0_reg <= 1'b0; + rep_stall_d1_reg <= 1'b0; + rep_en_reg <= 1'b0; + rep_start_reg <= 1'b0; end end @@ -891,6 +959,10 @@ always_ff @(posedge clk) begin rep_cnt_reg <= '0; rep_stall_reg <= 1'b0; + rep_stall_d0_reg <= 1'b0; + rep_stall_d1_reg <= 1'b0; + rep_en_reg <= 1'b0; + rep_start_reg <= 1'b0; m_axis_rx_tvalid_reg <= 1'b0; diff --git a/src/eth/tb/baser.py b/src/eth/tb/baser.py index fe2c9b3..8dde39a 100644 --- a/src/eth/tb/baser.py +++ b/src/eth/tb/baser.py @@ -373,7 +373,7 @@ class BaseRSerdesSource(): c = frame.ctrl[frame_offset] if frame.sim_time_sfd is None and not in_pre: frame.sim_time_sfd = sim_time + (clk_period // self.byte_lanes * k) - gbx_delay - if d == EthPre.SFD: + if d == EthPre.SFD and (not self.xgmii_rep_count or rep_cnt == 1): in_pre = False if c and d == XgmiiCtrl.START: if sof: