ipv4: Fix header parsing

The current FSM locks up when receiving an IPv4 packet that is not
addressed to the design itself. It gets stuck in `HEADER` with
block_done asserted, which resets bytecount to the payload length
instead of `BYTECOUNT_HEADER`, even when `crc_ok` or `rx_crc_error` is
asserted.

This commit fixes this by moving the reset condition (now based on
`rx_header_rcv`) to the bottom, and by properly handling the "not for
us" case by jumping to `DONE` directly.
This commit is contained in:
Markus Koch 2025-09-25 19:51:20 +02:00
parent ac553483df
commit f13e9bf907

View File

@ -77,7 +77,7 @@ begin
rx_fsm : process(clk, rst) is
begin
if rst then
state <= HEADER;
state <= DONE;
ipv4_out.rx_ok_stb <= '0';
ipv4_out.rx_error_stb <= '0';
ipv4_out.rx_header_rcv <= '0';
@ -89,9 +89,6 @@ begin
ipv4_out.rx_header_rcv <= '0';
if (ethernet_ii_out.rx_crc_ok or ethernet_ii_out.rx_crc_error) then
state <= HEADER;
bytecount <= BYTECOUNT_HEADER;
ipv4_out.rx_error_stb <= ethernet_ii_out.rx_crc_error or to_std_logic(state = PAYLOAD);
ipv4_out.rx_ok_stb <= ethernet_ii_out.rx_crc_ok and to_std_logic(state = DONE);
end if;
@ -109,6 +106,8 @@ begin
if header_ok then
state <= OPT;
ipv4_out.rx_header_rcv <= '1';
else
state <= DONE;
end if;
end if;
@ -126,6 +125,10 @@ begin
when DONE => -- @suppress "Dead state 'DONE'": Outgoing state transition is outside of case statement
null; -- We just wait here until the MAC gives us a CRC OK/error
end case;
if (ethernet_ii_out.rx_header_rcv) then
state <= HEADER;
bytecount <= BYTECOUNT_HEADER;
end if;
end if;
end process rx_fsm;