diff --git a/src/eth/rtl/taxi_axis_baser_rx_32.sv b/src/eth/rtl/taxi_axis_baser_rx_32.sv index d302fd0..1688ed4 100644 --- a/src/eth/rtl/taxi_axis_baser_rx_32.sv +++ b/src/eth/rtl/taxi_axis_baser_rx_32.sv @@ -176,7 +176,9 @@ logic is_mcast_reg = 1'b0, is_mcast_next; logic is_bcast_reg = 1'b0, is_bcast_next; logic is_8021q_reg = 1'b0, is_8021q_next; logic [15:0] frame_len_reg = '0, frame_len_next; -logic [15:0] frame_len_lim_reg = '0, frame_len_lim_next; +logic [13:0] frame_len_lim_cyc_reg = '0, frame_len_lim_cyc_next; +logic [1:0] frame_len_lim_last_reg = '0, frame_len_lim_last_next; +logic frame_len_lim_check_reg = '0, frame_len_lim_check_next; logic [DATA_W-1:0] m_axis_rx_tdata_reg = '0, m_axis_rx_tdata_next; logic [KEEP_W-1:0] m_axis_rx_tkeep_reg = '0, m_axis_rx_tkeep_next; @@ -278,7 +280,9 @@ always_comb begin is_bcast_next = is_bcast_reg; is_8021q_next = is_8021q_reg; frame_len_next = frame_len_reg; - frame_len_lim_next = frame_len_lim_reg; + frame_len_lim_cyc_next = frame_len_lim_cyc_reg; + frame_len_lim_last_next = frame_len_lim_last_reg; + frame_len_lim_check_next = frame_len_lim_check_reg; m_axis_rx_tdata_next = input_data_d2; m_axis_rx_tkeep_next = {KEEP_W{1'b1}}; @@ -321,10 +325,14 @@ always_comb begin end // counter for max frame length enforcement - if (frame_len_lim_reg[15:2] != 0) begin - frame_len_lim_next = frame_len_lim_reg - 16'(KEEP_W); + if (frame_len_lim_cyc_reg != 0) begin + frame_len_lim_cyc_next = frame_len_lim_cyc_reg - 1; end else begin - frame_len_lim_next = '0; + frame_len_lim_cyc_next = '0; + end + + if (frame_len_lim_cyc_reg == 2) begin + frame_len_lim_check_next = 1'b1; end // address and ethertype checks @@ -349,8 +357,10 @@ always_comb begin // idle state - wait for packet reset_crc = 1'b1; + frame_oversize_next = 1'b0; frame_len_next = 16'(KEEP_W); - frame_len_lim_next = cfg_rx_max_pkt_len; + {frame_len_lim_cyc_next, frame_len_lim_last_next} = cfg_rx_max_pkt_len; + frame_len_lim_check_next = 1'b0; hdr_ptr_next = 0; pre_ok_next = input_data_d2[31:8] == 24'h555555; @@ -376,7 +386,6 @@ always_comb begin STATE_PREAMBLE: begin // drop preamble - frame_len_lim_next = cfg_rx_max_pkt_len; hdr_ptr_next = 0; pre_ok_next = pre_ok_reg && input_data_d2 == 32'hD5555555; @@ -401,10 +410,17 @@ always_comb begin if (input_type_d0[2]) begin stat_rx_byte_next = 3'(input_type_d0[1:0]); - frame_oversize_next = frame_len_lim_reg < 16'(4+4+input_type_d0[1:0]); + if (frame_len_lim_check_reg) begin + if (frame_len_lim_last_reg < input_type_d0[1:0]) begin + frame_oversize_next = 1'b1; + end + end end else begin stat_rx_byte_next = 3'(KEEP_W); - frame_oversize_next = frame_len_lim_reg < 4+4; + if (frame_len_lim_check_reg) begin + // at the limit but this isn't a termination character + frame_oversize_next = 1'b1; + end end if (framing_error_reg) begin @@ -523,7 +539,9 @@ always_ff @(posedge clk) begin is_bcast_reg <= is_bcast_next; is_8021q_reg <= is_8021q_next; frame_len_reg <= frame_len_next; - frame_len_lim_reg <= frame_len_lim_next; + frame_len_lim_cyc_reg <= frame_len_lim_cyc_next; + frame_len_lim_last_reg <= frame_len_lim_last_next; + frame_len_lim_check_reg <= frame_len_lim_check_next; m_axis_rx_tdata_reg <= m_axis_rx_tdata_next; m_axis_rx_tkeep_reg <= m_axis_rx_tkeep_next; diff --git a/src/eth/rtl/taxi_axis_baser_rx_64.sv b/src/eth/rtl/taxi_axis_baser_rx_64.sv index 3db8dcf..c70fd26 100644 --- a/src/eth/rtl/taxi_axis_baser_rx_64.sv +++ b/src/eth/rtl/taxi_axis_baser_rx_64.sv @@ -181,7 +181,9 @@ logic is_mcast_reg = 1'b0, is_mcast_next; logic is_bcast_reg = 1'b0, is_bcast_next; logic is_8021q_reg = 1'b0, is_8021q_next; logic [15:0] frame_len_reg = '0, frame_len_next; -logic [15:0] frame_len_lim_reg = '0, frame_len_lim_next; +logic [12:0] frame_len_lim_cyc_reg = '0, frame_len_lim_cyc_next; +logic [2:0] frame_len_lim_last_reg = '0, frame_len_lim_last_next; +logic frame_len_lim_check_reg = '0, frame_len_lim_check_next; logic [DATA_W-1:0] m_axis_rx_tdata_reg = '0, m_axis_rx_tdata_next; logic [KEEP_W-1:0] m_axis_rx_tkeep_reg = '0, m_axis_rx_tkeep_next; @@ -318,7 +320,9 @@ always_comb begin is_bcast_next = is_bcast_reg; is_8021q_next = is_8021q_reg; frame_len_next = frame_len_reg; - frame_len_lim_next = frame_len_lim_reg; + frame_len_lim_cyc_next = frame_len_lim_cyc_reg; + frame_len_lim_last_next = frame_len_lim_last_reg; + frame_len_lim_check_next = frame_len_lim_check_reg; m_axis_rx_tdata_next = input_data_d1; m_axis_rx_tkeep_next = 8'd0; @@ -359,10 +363,14 @@ always_comb begin end // counter for max frame length enforcement - if (frame_len_lim_reg[15:3] != 0) begin - frame_len_lim_next = frame_len_lim_reg - 16'(KEEP_W); + if (frame_len_lim_cyc_reg != 0) begin + frame_len_lim_cyc_next = frame_len_lim_cyc_reg - 1; end else begin - frame_len_lim_next = '0; + frame_len_lim_cyc_next = '0; + end + + if (frame_len_lim_cyc_reg == 2) begin + frame_len_lim_check_next = 1'b1; end // address and ethertype checks @@ -386,8 +394,10 @@ always_comb begin // idle state - wait for packet reset_crc = 1'b1; + frame_oversize_next = 1'b0; frame_len_next = 16'(KEEP_W); - frame_len_lim_next = cfg_rx_max_pkt_len; + {frame_len_lim_cyc_next, frame_len_lim_last_next} = cfg_rx_max_pkt_len; + frame_len_lim_check_next = 1'b0; hdr_ptr_next = 0; pre_ok_next = input_data_d1[63:8] == 56'hD5555555555555; @@ -411,10 +421,17 @@ always_comb begin if (input_type_d0[3]) begin stat_rx_byte_next = 4'(input_type_d0[2:0]); - frame_oversize_next = frame_len_lim_reg < 16'(8+input_type_d0[2:0]); + if (frame_len_lim_check_reg) begin + if (frame_len_lim_last_reg < input_type_d0[2:0]) begin + frame_oversize_next = 1'b1; + end + end end else begin stat_rx_byte_next = 4'(KEEP_W); - frame_oversize_next = frame_len_lim_reg < 8; + if (frame_len_lim_check_reg) begin + // at the limit but this isn't a termination character + frame_oversize_next = 1'b1; + end end if (input_type_d0[3]) begin @@ -563,7 +580,9 @@ always_ff @(posedge clk) begin is_bcast_reg <= is_bcast_next; is_8021q_reg <= is_8021q_next; frame_len_reg <= frame_len_next; - frame_len_lim_reg <= frame_len_lim_next; + frame_len_lim_cyc_reg <= frame_len_lim_cyc_next; + frame_len_lim_last_reg <= frame_len_lim_last_next; + frame_len_lim_check_reg <= frame_len_lim_check_next; m_axis_rx_tdata_reg <= m_axis_rx_tdata_next; m_axis_rx_tkeep_reg <= m_axis_rx_tkeep_next; diff --git a/src/eth/rtl/taxi_axis_baser_tx_32.sv b/src/eth/rtl/taxi_axis_baser_tx_32.sv index 9c94743..d6188a2 100644 --- a/src/eth/rtl/taxi_axis_baser_tx_32.sv +++ b/src/eth/rtl/taxi_axis_baser_tx_32.sv @@ -190,7 +190,9 @@ logic is_mcast_reg = 1'b0, is_mcast_next; logic is_bcast_reg = 1'b0, is_bcast_next; logic is_8021q_reg = 1'b0, is_8021q_next; logic [15:0] frame_len_reg = '0, frame_len_next; -logic [15:0] frame_len_lim_reg = '0, frame_len_lim_next; +logic [13:0] frame_len_lim_cyc_reg = '0, frame_len_lim_cyc_next; +logic [1:0] frame_len_lim_last_reg = '0, frame_len_lim_last_next; +logic frame_len_lim_check_reg = '0, frame_len_lim_check_next; logic [7:0] ifg_cnt_reg = '0, ifg_cnt_next; logic [7:0] ifg_count_reg = 8'd0, ifg_count_next; @@ -352,7 +354,9 @@ always_comb begin is_bcast_next = is_bcast_reg; is_8021q_next = is_8021q_reg; frame_len_next = frame_len_reg; - frame_len_lim_next = frame_len_lim_reg; + frame_len_lim_cyc_next = frame_len_lim_cyc_reg; + frame_len_lim_last_next = frame_len_lim_last_reg; + frame_len_lim_check_next = frame_len_lim_check_reg; ifg_cnt_next = ifg_cnt_reg; ifg_count_next = ifg_count_reg; @@ -420,10 +424,14 @@ always_comb begin end // counter for max frame length enforcement - if (frame_len_lim_reg[15:2] != 0) begin - frame_len_lim_next = frame_len_lim_reg - 16'(KEEP_W); + if (frame_len_lim_cyc_reg != 0) begin + frame_len_lim_cyc_next = frame_len_lim_cyc_reg - 1; end else begin - frame_len_lim_next = '0; + frame_len_lim_cyc_next = '0; + end + + if (frame_len_lim_cyc_reg == 2) begin + frame_len_lim_check_next = 1'b1; end // address and ethertype checks @@ -453,10 +461,12 @@ always_comb begin STATE_IDLE: begin // idle state - wait for data frame_error_next = 1'b0; + frame_oversize_next = 1'b0; frame_min_count_next = MIN_LEN_W'(MIN_FRAME_LEN-4-KEEP_W); hdr_ptr_next = 0; frame_len_next = 0; - frame_len_lim_next = cfg_tx_max_pkt_len; + {frame_len_lim_cyc_next, frame_len_lim_last_next} = cfg_tx_max_pkt_len-1; + frame_len_lim_check_next = 1'b0; reset_crc = 1'b1; output_data_next = s_tdata_reg; @@ -483,7 +493,6 @@ always_comb begin hdr_ptr_next = 0; frame_len_next = 0; - frame_len_lim_next = cfg_tx_max_pkt_len; s_tdata_next = s_axis_tx_tdata_masked; s_empty_next = keep2empty(s_axis_tx.tkeep); @@ -509,9 +518,16 @@ always_comb begin stat_tx_byte_next = 3'(KEEP_W); if (s_axis_tx.tvalid && s_axis_tx.tlast) begin - frame_oversize_next = frame_len_lim_reg < 16'(4+4+4-keep2empty(s_axis_tx.tkeep)); + if (frame_len_lim_check_reg) begin + if (frame_len_lim_last_reg < 2'(3-keep2empty(s_axis_tx.tkeep))) begin + frame_oversize_next = 1'b1; + end + end end else begin - frame_oversize_next = frame_len_lim_reg < 4+4; + if (frame_len_lim_check_reg) begin + // at the limit but the frame doesn't end in this cycle + frame_oversize_next = 1'b1; + end end if (PADDING_EN && frame_min_count_reg != 0) begin @@ -702,7 +718,9 @@ always_ff @(posedge clk) begin is_bcast_reg <= is_bcast_next; is_8021q_reg <= is_8021q_next; frame_len_reg <= frame_len_next; - frame_len_lim_reg <= frame_len_lim_next; + frame_len_lim_cyc_reg <= frame_len_lim_cyc_next; + frame_len_lim_last_reg <= frame_len_lim_last_next; + frame_len_lim_check_reg <= frame_len_lim_check_next; ifg_cnt_reg <= ifg_cnt_next; ifg_count_reg <= ifg_count_next; diff --git a/src/eth/rtl/taxi_axis_baser_tx_64.sv b/src/eth/rtl/taxi_axis_baser_tx_64.sv index 6fa8cbf..10c6b9a 100644 --- a/src/eth/rtl/taxi_axis_baser_tx_64.sv +++ b/src/eth/rtl/taxi_axis_baser_tx_64.sv @@ -201,7 +201,9 @@ logic is_mcast_reg = 1'b0, is_mcast_next; logic is_bcast_reg = 1'b0, is_bcast_next; logic is_8021q_reg = 1'b0, is_8021q_next; logic [15:0] frame_len_reg = '0, frame_len_next; -logic [15:0] frame_len_lim_reg = '0, frame_len_lim_next; +logic [12:0] frame_len_lim_cyc_reg = '0, frame_len_lim_cyc_next; +logic [2:0] frame_len_lim_last_reg = '0, frame_len_lim_last_next; +logic frame_len_lim_check_reg = '0, frame_len_lim_check_next; logic [7:0] ifg_cnt_reg = '0, ifg_cnt_next; logic [7:0] ifg_count_reg = 8'd0, ifg_count_next; @@ -398,7 +400,9 @@ always_comb begin is_bcast_next = is_bcast_reg; is_8021q_next = is_8021q_reg; frame_len_next = frame_len_reg; - frame_len_lim_next = frame_len_lim_reg; + frame_len_lim_cyc_next = frame_len_lim_cyc_reg; + frame_len_lim_last_next = frame_len_lim_last_reg; + frame_len_lim_check_next = frame_len_lim_check_reg; ifg_cnt_next = ifg_cnt_reg; ifg_count_next = ifg_count_reg; @@ -449,10 +453,14 @@ always_comb begin end // counter for max frame length enforcement - if (frame_len_lim_reg[15:3] != 0) begin - frame_len_lim_next = frame_len_lim_reg - 16'(KEEP_W); + if (frame_len_lim_cyc_reg != 0) begin + frame_len_lim_cyc_next = frame_len_lim_cyc_reg - 1; end else begin - frame_len_lim_next = '0; + frame_len_lim_cyc_next = '0; + end + + if (frame_len_lim_cyc_reg == 2) begin + frame_len_lim_check_next = 1'b1; end // address and ethertype checks @@ -481,10 +489,12 @@ always_comb begin STATE_IDLE: begin // idle state - wait for data frame_error_next = 1'b0; + frame_oversize_next = 1'b0; frame_min_count_next = MIN_LEN_W'(MIN_FRAME_LEN-4-KEEP_W); hdr_ptr_next = 0; frame_len_next = 0; - frame_len_lim_next = cfg_tx_max_pkt_len; + {frame_len_lim_cyc_next, frame_len_lim_last_next} = cfg_tx_max_pkt_len-5; + frame_len_lim_check_next = 1'b0; reset_crc = 1'b1; s_axis_tx_tready_next = cfg_tx_enable; @@ -522,9 +532,16 @@ always_comb begin stat_tx_byte_next = 4'(KEEP_W); if (s_axis_tx.tvalid && s_axis_tx.tlast) begin - frame_oversize_next = frame_len_lim_reg < 16'(8+8+4-keep2empty(s_axis_tx.tkeep)); + if (frame_len_lim_check_reg) begin + if (frame_len_lim_last_reg < 3'(7-keep2empty(s_axis_tx.tkeep))) begin + frame_oversize_next = 1'b1; + end + end end else begin - frame_oversize_next = frame_len_lim_reg < 8+8; + if (frame_len_lim_check_reg) begin + // at the limit but the frame doesn't end in this cycle + frame_oversize_next = 1'b1; + end end if (PADDING_EN && frame_min_count_reg != 0) begin @@ -736,7 +753,9 @@ always_ff @(posedge clk) begin is_bcast_reg <= is_bcast_next; is_8021q_reg <= is_8021q_next; frame_len_reg <= frame_len_next; - frame_len_lim_reg <= frame_len_lim_next; + frame_len_lim_cyc_reg <= frame_len_lim_cyc_next; + frame_len_lim_last_reg <= frame_len_lim_last_next; + frame_len_lim_check_reg <= frame_len_lim_check_next; ifg_cnt_reg <= ifg_cnt_next; ifg_count_reg <= ifg_count_next; diff --git a/src/eth/rtl/taxi_axis_xgmii_rx_32.sv b/src/eth/rtl/taxi_axis_xgmii_rx_32.sv index d545faa..1b33058 100644 --- a/src/eth/rtl/taxi_axis_xgmii_rx_32.sv +++ b/src/eth/rtl/taxi_axis_xgmii_rx_32.sv @@ -130,7 +130,9 @@ logic is_mcast_reg = 1'b0, is_mcast_next; logic is_bcast_reg = 1'b0, is_bcast_next; logic is_8021q_reg = 1'b0, is_8021q_next; logic [15:0] frame_len_reg = '0, frame_len_next; -logic [15:0] frame_len_lim_reg = '0, frame_len_lim_next; +logic [13:0] frame_len_lim_cyc_reg = '0, frame_len_lim_cyc_next; +logic [1:0] frame_len_lim_last_reg = '0, frame_len_lim_last_next; +logic frame_len_lim_check_reg = '0, frame_len_lim_check_next; logic [DATA_W-1:0] m_axis_rx_tdata_reg = '0, m_axis_rx_tdata_next; logic [KEEP_W-1:0] m_axis_rx_tkeep_reg = '0, m_axis_rx_tkeep_next; @@ -231,7 +233,9 @@ always_comb begin is_bcast_next = is_bcast_reg; is_8021q_next = is_8021q_reg; frame_len_next = frame_len_reg; - frame_len_lim_next = frame_len_lim_reg; + frame_len_lim_cyc_next = frame_len_lim_cyc_reg; + frame_len_lim_last_next = frame_len_lim_last_reg; + frame_len_lim_check_next = frame_len_lim_check_reg; m_axis_rx_tdata_next = xgmii_rxd_d2; m_axis_rx_tkeep_next = {KEEP_W{1'b1}}; @@ -275,10 +279,14 @@ always_comb begin end // counter for max frame length enforcement - if (frame_len_lim_reg[15:2] != 0) begin - frame_len_lim_next = frame_len_lim_reg - 16'(CTRL_W); + if (frame_len_lim_cyc_reg != 0) begin + frame_len_lim_cyc_next = frame_len_lim_cyc_reg - 1; end else begin - frame_len_lim_next = '0; + frame_len_lim_cyc_next = '0; + end + + if (frame_len_lim_cyc_reg == 2) begin + frame_len_lim_check_next = 1'b1; end // address and ethertype checks @@ -303,8 +311,10 @@ always_comb begin // idle state - wait for packet reset_crc = 1'b1; + frame_oversize_next = 1'b0; frame_len_next = 16'(CTRL_W); - frame_len_lim_next = cfg_rx_max_pkt_len; + {frame_len_lim_cyc_next, frame_len_lim_last_next} = cfg_rx_max_pkt_len; + frame_len_lim_check_next = 1'b0; hdr_ptr_next = 0; pre_ok_next = xgmii_rxd_d2[31:8] == 24'h555555; @@ -330,7 +340,6 @@ always_comb begin STATE_PREAMBLE: begin // drop preamble - frame_len_lim_next = cfg_rx_max_pkt_len; hdr_ptr_next = 0; pre_ok_next = pre_ok_reg && xgmii_rxd_d2 == 32'hD5555555; @@ -355,10 +364,17 @@ always_comb begin if (term_present_reg) begin stat_rx_byte_next = 3'(term_lane_reg); - frame_oversize_next = frame_len_lim_reg < 16'(4+4+term_lane_reg); + if (frame_len_lim_check_reg) begin + if (frame_len_lim_last_reg < term_lane_reg) begin + frame_oversize_next = 1'b1; + end + end end else begin stat_rx_byte_next = 3'(CTRL_W); - frame_oversize_next = frame_len_lim_reg < 4+4; + if (frame_len_lim_check_reg) begin + // at the limit but this isn't a termination character + frame_oversize_next = 1'b1; + end end if (framing_error_reg) begin @@ -477,7 +493,9 @@ always_ff @(posedge clk) begin is_bcast_reg <= is_bcast_next; is_8021q_reg <= is_8021q_next; frame_len_reg <= frame_len_next; - frame_len_lim_reg <= frame_len_lim_next; + frame_len_lim_cyc_reg <= frame_len_lim_cyc_next; + frame_len_lim_last_reg <= frame_len_lim_last_next; + frame_len_lim_check_reg <= frame_len_lim_check_next; m_axis_rx_tdata_reg <= m_axis_rx_tdata_next; m_axis_rx_tkeep_reg <= m_axis_rx_tkeep_next; diff --git a/src/eth/rtl/taxi_axis_xgmii_rx_64.sv b/src/eth/rtl/taxi_axis_xgmii_rx_64.sv index fd62a96..7d8132f 100644 --- a/src/eth/rtl/taxi_axis_xgmii_rx_64.sv +++ b/src/eth/rtl/taxi_axis_xgmii_rx_64.sv @@ -134,7 +134,9 @@ logic is_mcast_reg = 1'b0, is_mcast_next; logic is_bcast_reg = 1'b0, is_bcast_next; logic is_8021q_reg = 1'b0, is_8021q_next; logic [15:0] frame_len_reg = '0, frame_len_next; -logic [15:0] frame_len_lim_reg = '0, frame_len_lim_next; +logic [12:0] frame_len_lim_cyc_reg = '0, frame_len_lim_cyc_next; +logic [2:0] frame_len_lim_last_reg = '0, frame_len_lim_last_next; +logic frame_len_lim_check_reg = '0, frame_len_lim_check_next; logic [DATA_W-1:0] m_axis_rx_tdata_reg = '0, m_axis_rx_tdata_next; logic [KEEP_W-1:0] m_axis_rx_tkeep_reg = '0, m_axis_rx_tkeep_next; @@ -252,7 +254,9 @@ always_comb begin is_bcast_next = is_bcast_reg; is_8021q_next = is_8021q_reg; frame_len_next = frame_len_reg; - frame_len_lim_next = frame_len_lim_reg; + frame_len_lim_cyc_next = frame_len_lim_cyc_reg; + frame_len_lim_last_next = frame_len_lim_last_reg; + frame_len_lim_check_next = frame_len_lim_check_reg; m_axis_rx_tdata_next = xgmii_rxd_d1; m_axis_rx_tkeep_next = {KEEP_W{1'b1}}; @@ -294,10 +298,14 @@ always_comb begin end // counter for max frame length enforcement - if (frame_len_lim_reg[15:3] != 0) begin - frame_len_lim_next = frame_len_lim_reg - 16'(CTRL_W); + if (frame_len_lim_cyc_reg != 0) begin + frame_len_lim_cyc_next = frame_len_lim_cyc_reg - 1; end else begin - frame_len_lim_next = '0; + frame_len_lim_cyc_next = '0; + end + + if (frame_len_lim_cyc_reg == 2) begin + frame_len_lim_check_next = 1'b1; end // address and ethertype checks @@ -321,8 +329,10 @@ always_comb begin // idle state - wait for packet reset_crc = 1'b1; + frame_oversize_next = 1'b0; frame_len_next = 16'(CTRL_W); - frame_len_lim_next = cfg_rx_max_pkt_len; + {frame_len_lim_cyc_next, frame_len_lim_last_next} = cfg_rx_max_pkt_len; + frame_len_lim_check_next = 1'b0; hdr_ptr_next = 0; pre_ok_next = xgmii_rxd_d1[63:8] == 56'hD5555555555555; @@ -351,10 +361,17 @@ always_comb begin if (term_present_reg) begin stat_rx_byte_next = 4'(term_lane_reg); - frame_oversize_next = frame_len_lim_reg < 16'(8+term_lane_reg); + if (frame_len_lim_check_reg) begin + if (frame_len_lim_last_reg < term_lane_reg) begin + frame_oversize_next = 1'b1; + end + end end else begin stat_rx_byte_next = 4'(CTRL_W); - frame_oversize_next = frame_len_lim_reg < 8; + if (frame_len_lim_check_reg) begin + // at the limit but this isn't a termination character + frame_oversize_next = 1'b1; + end end if (framing_error_reg || framing_error_d0_reg) begin @@ -484,7 +501,9 @@ always_ff @(posedge clk) begin is_bcast_reg <= is_bcast_next; is_8021q_reg <= is_8021q_next; frame_len_reg <= frame_len_next; - frame_len_lim_reg <= frame_len_lim_next; + frame_len_lim_cyc_reg <= frame_len_lim_cyc_next; + frame_len_lim_last_reg <= frame_len_lim_last_next; + frame_len_lim_check_reg <= frame_len_lim_check_next; m_axis_rx_tdata_reg <= m_axis_rx_tdata_next; m_axis_rx_tkeep_reg <= m_axis_rx_tkeep_next; diff --git a/src/eth/rtl/taxi_axis_xgmii_tx_32.sv b/src/eth/rtl/taxi_axis_xgmii_tx_32.sv index 8207763..9e17e9b 100644 --- a/src/eth/rtl/taxi_axis_xgmii_tx_32.sv +++ b/src/eth/rtl/taxi_axis_xgmii_tx_32.sv @@ -146,7 +146,9 @@ logic is_mcast_reg = 1'b0, is_mcast_next; logic is_bcast_reg = 1'b0, is_bcast_next; logic is_8021q_reg = 1'b0, is_8021q_next; logic [15:0] frame_len_reg = '0, frame_len_next; -logic [15:0] frame_len_lim_reg = '0, frame_len_lim_next; +logic [13:0] frame_len_lim_cyc_reg = '0, frame_len_lim_cyc_next; +logic [1:0] frame_len_lim_last_reg = '0, frame_len_lim_last_next; +logic frame_len_lim_check_reg = '0, frame_len_lim_check_next; logic [7:0] ifg_cnt_reg = '0, ifg_cnt_next; logic [7:0] ifg_count_reg = 8'd0, ifg_count_next; @@ -301,7 +303,9 @@ always_comb begin is_bcast_next = is_bcast_reg; is_8021q_next = is_8021q_reg; frame_len_next = frame_len_reg; - frame_len_lim_next = frame_len_lim_reg; + frame_len_lim_cyc_next = frame_len_lim_cyc_reg; + frame_len_lim_last_next = frame_len_lim_last_reg; + frame_len_lim_check_next = frame_len_lim_check_reg; ifg_cnt_next = ifg_cnt_reg; ifg_count_next = ifg_count_reg; @@ -371,10 +375,14 @@ always_comb begin end // counter for max frame length enforcement - if (frame_len_lim_reg[15:2] != 0) begin - frame_len_lim_next = frame_len_lim_reg - 16'(CTRL_W); + if (frame_len_lim_cyc_reg != 0) begin + frame_len_lim_cyc_next = frame_len_lim_cyc_reg - 1; end else begin - frame_len_lim_next = '0; + frame_len_lim_cyc_next = '0; + end + + if (frame_len_lim_cyc_reg == 2) begin + frame_len_lim_check_next = 1'b1; end // address and ethertype checks @@ -404,10 +412,12 @@ always_comb begin STATE_IDLE: begin // idle state - wait for data frame_error_next = 1'b0; + frame_oversize_next = 1'b0; frame_min_count_next = MIN_LEN_W'(MIN_FRAME_LEN-4-CTRL_W); hdr_ptr_next = 0; frame_len_next = 0; - frame_len_lim_next = cfg_tx_max_pkt_len; + {frame_len_lim_cyc_next, frame_len_lim_last_next} = cfg_tx_max_pkt_len-1; + frame_len_lim_check_next = 1'b0; reset_crc = 1'b1; // XGMII idle @@ -435,7 +445,6 @@ always_comb begin hdr_ptr_next = 0; frame_len_next = 0; - frame_len_lim_next = cfg_tx_max_pkt_len; s_tdata_next = s_axis_tx_tdata_masked; s_empty_next = keep2empty(s_axis_tx.tkeep); @@ -461,9 +470,16 @@ always_comb begin stat_tx_byte_next = 3'(CTRL_W); if (s_axis_tx.tvalid && s_axis_tx.tlast) begin - frame_oversize_next = frame_len_lim_reg < 16'(4+4+4-keep2empty(s_axis_tx.tkeep)); + if (frame_len_lim_check_reg) begin + if (frame_len_lim_last_reg < 2'(3-keep2empty(s_axis_tx.tkeep))) begin + frame_oversize_next = 1'b1; + end + end end else begin - frame_oversize_next = frame_len_lim_reg < 4+4; + if (frame_len_lim_check_reg) begin + // at the limit but the frame doesn't end in this cycle + frame_oversize_next = 1'b1; + end end if (PADDING_EN && frame_min_count_reg != 0) begin @@ -656,7 +672,9 @@ always_ff @(posedge clk) begin is_bcast_reg <= is_bcast_next; is_8021q_reg <= is_8021q_next; frame_len_reg <= frame_len_next; - frame_len_lim_reg <= frame_len_lim_next; + frame_len_lim_cyc_reg <= frame_len_lim_cyc_next; + frame_len_lim_last_reg <= frame_len_lim_last_next; + frame_len_lim_check_reg <= frame_len_lim_check_next; ifg_cnt_reg <= ifg_cnt_next; ifg_count_reg <= ifg_count_next; diff --git a/src/eth/rtl/taxi_axis_xgmii_tx_64.sv b/src/eth/rtl/taxi_axis_xgmii_tx_64.sv index f92f550..744ac0a 100644 --- a/src/eth/rtl/taxi_axis_xgmii_tx_64.sv +++ b/src/eth/rtl/taxi_axis_xgmii_tx_64.sv @@ -148,7 +148,9 @@ logic is_mcast_reg = 1'b0, is_mcast_next; logic is_bcast_reg = 1'b0, is_bcast_next; logic is_8021q_reg = 1'b0, is_8021q_next; logic [15:0] frame_len_reg = '0, frame_len_next; -logic [15:0] frame_len_lim_reg = '0, frame_len_lim_next; +logic [12:0] frame_len_lim_cyc_reg = '0, frame_len_lim_cyc_next; +logic [2:0] frame_len_lim_last_reg = '0, frame_len_lim_last_next; +logic frame_len_lim_check_reg = '0, frame_len_lim_check_next; logic [7:0] ifg_cnt_reg = '0, ifg_cnt_next; logic [7:0] ifg_count_reg = 8'd0, ifg_count_next; @@ -340,7 +342,9 @@ always_comb begin is_bcast_next = is_bcast_reg; is_8021q_next = is_8021q_reg; frame_len_next = frame_len_reg; - frame_len_lim_next = frame_len_lim_reg; + frame_len_lim_cyc_next = frame_len_lim_cyc_reg; + frame_len_lim_last_next = frame_len_lim_last_reg; + frame_len_lim_check_next = frame_len_lim_check_reg; ifg_cnt_next = ifg_cnt_reg; ifg_count_next = ifg_count_reg; @@ -392,10 +396,14 @@ always_comb begin end // counter for max frame length enforcement - if (frame_len_lim_reg[15:3] != 0) begin - frame_len_lim_next = frame_len_lim_reg - 16'(CTRL_W); + if (frame_len_lim_cyc_reg != 0) begin + frame_len_lim_cyc_next = frame_len_lim_cyc_reg - 1; end else begin - frame_len_lim_next = '0; + frame_len_lim_cyc_next = '0; + end + + if (frame_len_lim_cyc_reg == 2) begin + frame_len_lim_check_next = 1'b1; end // address and ethertype checks @@ -424,10 +432,12 @@ always_comb begin STATE_IDLE: begin // idle state - wait for data frame_error_next = 1'b0; + frame_oversize_next = 1'b0; frame_min_count_next = MIN_LEN_W'(MIN_FRAME_LEN-4-CTRL_W); hdr_ptr_next = 0; frame_len_next = 0; - frame_len_lim_next = cfg_tx_max_pkt_len; + {frame_len_lim_cyc_next, frame_len_lim_last_next} = cfg_tx_max_pkt_len-5; + frame_len_lim_check_next = 1'b0; reset_crc = 1'b1; s_axis_tx_tready_next = cfg_tx_enable; @@ -466,9 +476,16 @@ always_comb begin stat_tx_byte_next = 4'(CTRL_W); if (s_axis_tx.tvalid && s_axis_tx.tlast) begin - frame_oversize_next = frame_len_lim_reg < 16'(8+8+4-keep2empty(s_axis_tx.tkeep)); + if (frame_len_lim_check_reg) begin + if (frame_len_lim_last_reg < 3'(7-keep2empty(s_axis_tx.tkeep))) begin + frame_oversize_next = 1'b1; + end + end end else begin - frame_oversize_next = frame_len_lim_reg < 8+8; + if (frame_len_lim_check_reg) begin + // at the limit but the frame doesn't end in this cycle + frame_oversize_next = 1'b1; + end end if (PADDING_EN && frame_min_count_reg != 0) begin @@ -678,7 +695,9 @@ always_ff @(posedge clk) begin is_bcast_reg <= is_bcast_next; is_8021q_reg <= is_8021q_next; frame_len_reg <= frame_len_next; - frame_len_lim_reg <= frame_len_lim_next; + frame_len_lim_cyc_reg <= frame_len_lim_cyc_next; + frame_len_lim_last_reg <= frame_len_lim_last_next; + frame_len_lim_check_reg <= frame_len_lim_check_next; ifg_cnt_reg <= ifg_cnt_next; ifg_count_reg <= ifg_count_next;