eth: Optimize frame length enforcement logic in BASE-R MACs

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich
2025-10-03 15:49:51 -07:00
parent 8257fdf09e
commit 04df834708
8 changed files with 224 additions and 76 deletions

View File

@@ -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;