Skip to content
Snippets Groups Projects
Commit 80e84385 authored by Mathias Kreider's avatar Mathias Kreider
Browse files

No commit message

No commit message
parent e7828d6f
Branches
Tags
No related merge requests found
......@@ -435,15 +435,12 @@ begin
report "EB: MALFORMED PACKET" severity note;
else
--eb hdr seems valid, prepare answering packet. Prefill RX buffer
if(unsigned(s_rx_fifo_gauge) > 3) then
s_state_RX <= CYC_HDR_REC;
s_state_TX <= EB_HDR_INIT;
else
--report "EB: Waiting for buffer ..." severity note;
end if;
s_state_TX <= EB_HDR_INIT;
if(s_EB_RX_HDR.PROBE = '1') then -- no probe, prepare cycle reception
s_state_RX <= EB_HDR_PROBE_ID ;
s_state_TX <= EB_HDR_INIT;
s_state_RX <= EB_HDR_PROBE_ID ;
else
s_state_RX <= CYC_HDR_REC;
end if;
end if;
......@@ -492,7 +489,7 @@ begin
end if;
when CYC_HDR_READ_GET_ADR => if(s_rx_fifo_am_empty = '0') then
when CYC_HDR_READ_GET_ADR => if(s_rx_fifo_empty = '0') then
s_state_RX <= WB_READ_RDY;
end if;
......@@ -527,11 +524,7 @@ begin
when ERROR => s_state_TX <= IDLE;
s_state_RX <= IDLE;
if((s_EB_RX_HDR.VER /= c_EB_VER) -- wrong version
OR (s_EB_RX_HDR.ADDR_SIZE /= c_MY_EB_ADDR_SIZE) -- wrong size
OR (s_EB_RX_HDR.PORT_SIZE /= c_MY_EB_PORT_SIZE)) then
s_state_TX <= ERROR;
end if;
when others => s_state_RX <= IDLE;
end case;
......
......@@ -165,7 +165,8 @@ signal RX_HDR_slv : std_logic_vector(c_IPV4_HLEN*8-1 downto 0) ;
--shift register input and control signals
signal byte_count : natural range 0 to 1600;
signal counter_comp : natural range 0 to 1600;
signal s_timeout_cnt : unsigned(14 downto 0);
alias a_timeout : unsigned(0 downto 0) is s_timeout_cnt(s_timeout_cnt'left downto s_timeout_cnt'left);
signal eop : natural range 0 to 1600;
......@@ -296,8 +297,21 @@ begin
end if;
end process;
timeout : process(clk_i)
begin
if rising_edge(clk_i) then
--Counter: Timeout
-- reset timeout if idle
if((nRST_i = '0') or (state = IDLE)) then
--s_timeout_cnt <= (others => '1');
s_timeout_cnt <= to_unsigned(5000, s_timeout_cnt'length);
else
s_timeout_cnt <= s_timeout_cnt -1;
end if;
end if;
end process;
......@@ -427,21 +441,24 @@ begin
--
when chk => parser_wait <= '1';
if((IPV4_RX.DST = my_ip_i or IPV4_RX.DST = c_BROADCAST_IP) and IPV4_RX.PRO = c_PRO_UDP)then
if(UDP_RX.DST_PORT = my_port_i) then
report("RX: hdr parsed successfully, handing over payload ...") severity note;
parse <= done;
else
report("RX: wrong port") severity warning;
parse <= errors;
end if;
else
report("RX: not addressed to my IP") severity warning;
if(IPV4_RX.PRO = c_PRO_UDP) then
--if((IPV4_RX.DST = my_ip_i) or (IPV4_RX.DST = c_BROADCAST_IP)) then
if(UDP_RX.DST_PORT = my_port_i) then
report("RX: hdr parsed successfully, handing over payload ...") severity note;
parse <= done;
else
report("RX: wrong port") severity warning;
parse <= errors;
end if;
--else
-- report("RX: not addressed to my IP") severity warning;
-- parse <= errors;
--parse <= errors;
parse <= done;
end if;
--end if;
else
report("RX: Non UDP packet") severity warning;
parse <= errors;
end if;
when done => --parser_wait <= '1';
valid_o <= '1';
if(parser_reset = '1') then
......@@ -466,71 +483,85 @@ begin
state <= IDLE;
else
snk_hdr_fsm_STALL <= '0';
parser_reset <= '0';
case state is
--no timeout? Good, run FSM
if(a_timeout = "0") then
snk_hdr_fsm_STALL <= '0';
parser_reset <= '0';
case state is
when IDLE =>
if(snk_i.cyc = '1' AND snk_i.adr = c_WRF_DATA) then
--snk_hdr_fsm_STALL <= '0';
state <= HEADER;
end if;
when HEADER => if(snk_i.cyc = '0') then
report("Header was aborted") severity warning;
state <= ERRORS;
else
if(parse = DONE) then
eop <= (counter_comp + to_integer(unsigned(IPV4_RX.IHL)*4) + to_integer(unsigned(UDP_RX.MLEN)) -2);
state <= PAYLOAD;
--snk_hdr_fsm_STALL <= '1';
else
if(snk_i.cyc = '0') then
report("RX: packet hdr aborted") severity warning;
state <= ERRORS;
end if;
if(parse = errors) then
report("Not a valid Eth frame") severity warning;
state <= ERRORS;
end if;
end if;
end if;
when PAYLOAD => if(byte_count < c_ETH_FRAME_MIN_END) then
when IDLE =>
if(snk_i.cyc = '1' AND snk_i.adr = c_WRF_DATA) then
--snk_hdr_fsm_STALL <= '0';
state <= HEADER;
end if;
when HEADER => if(snk_i.cyc = '0') then
report("Header was aborted") severity warning; state <= ERRORS;
else
if(parse = DONE) then
eop <= (counter_comp + to_integer(unsigned(IPV4_RX.IHL)*4) + to_integer(unsigned(UDP_RX.MLEN)) -2);
state <= PAYLOAD;
--snk_hdr_fsm_STALL <= '1';
else
if(snk_i.cyc = '0') then
report("RX: packet hdr aborted") severity warning; state <= ERRORS;
end if;
if(parse = errors) then
report("Not a valid Eth frame") severity warning; state <= ERRORS;
end if;
end if;
end if;
when PAYLOAD => if(byte_count < c_ETH_FRAME_MIN_END) then
if(snk_i.cyc = '0') then
report("RX: runt frame (< 64)") severity warning; state <= ERRORS;
elsif(byte_count = eop AND snk_i.STB = '1' AND snk_payload_conv.stall = '0') then
state <= PADDING;
end if;
else
if(byte_count = eop AND snk_i.STB = '1' AND snk_payload_conv.stall = '0') then
state <= DONE;
--elsif(byte_count > eop AND ) then
-- report("RX: frame too long") severity warning; state <= ERRORS;
-- else
-- report("RX: frame cut short") severity warning; state <= ERRORS;
if(snk_i.cyc = '0') then
report("RX: runt frame (< 64)") severity warning; state <= ERRORS;
elsif(byte_count = eop AND snk_i.STB = '1' AND snk_payload_conv.stall = '0') then
state <= PADDING;
end if;
--end if;
else
if(byte_count = eop AND snk_i.STB = '1' AND snk_payload_conv.stall = '0') then
state <= DONE;
--elsif(byte_count > eop AND ) then
-- report("RX: frame too long") severity warning; state <= ERRORS;
-- else
-- report("RX: frame cut short") severity warning; state <= ERRORS;
end if;
--end if;
end if;
when PADDING => if(snk_i.cyc = '0') then
if(byte_count = c_ETH_FRAME_MIN_END +2) then state <= DONE;
elsif(byte_count > c_ETH_FRAME_MIN_END +2) then
report("RX: frame too long") severity warning; state <= ERRORS;
else
report("RX: frame cut short") severity warning; state <= ERRORS;
end if;
end if;
when DONE => if(snk_i.cyc = '0') then
parser_reset <= '1'; state <= IDLE;
end if;
when ERRORS => parser_reset <= '1'; state <= IDLE;
when others => parser_reset <= '1'; state <= IDLE;
end case;
end if;
when PADDING => if(snk_i.cyc = '0') then
if(byte_count = c_ETH_FRAME_MIN_END +2) then
state <= DONE;
elsif(byte_count > c_ETH_FRAME_MIN_END +2) then
report("RX: frame too long") severity warning;
state <= ERRORS;
else
report("RX: frame cut short") severity warning;
state <= ERRORS;
end if;
end if;
when DONE => if(snk_i.cyc = '0') then
parser_reset <= '1'; state <= IDLE;
end if;
when ERRORS => if(snk_i.cyc = '0') then
parser_reset <= '1'; state <= IDLE;
end if;
when others => parser_reset <= '1'; state <= IDLE;
end case;
else
--timeout. something went seriously wrong, reset
parser_reset <= '1'; state <= IDLE;
end if;
end if;
end if;
end process;
......
......@@ -159,6 +159,8 @@ signal TX_HDR_slv : std_logic_vector(c_IPV4_HLEN*8 -1 downto 0);
--shift register output and control signals
signal byte_count : natural range 0 to 1600;
signal counter_comp : natural range 0 to 1600;
signal s_timeout_cnt : unsigned(14 downto 0);
alias a_timeout : unsigned(0 downto 0) is s_timeout_cnt(s_timeout_cnt'left downto s_timeout_cnt'left);
......@@ -333,6 +335,20 @@ uut: WB_bus_adapter_streaming_sg generic map ( g_adr_width_A => 32,
timeout : process(clk_i)
begin
if rising_edge(clk_i) then
--Counter: Timeout
-- reset timeout if idle
if((nRST_i = '0') or (state = IDLE)) then
--s_timeout_cnt <= (others => '1');
s_timeout_cnt <= to_unsigned(5000, s_timeout_cnt'length);
else
s_timeout_cnt <= s_timeout_cnt -1;
end if;
end if;
end process;
main_fsm : process(clk_i)
......@@ -376,111 +392,113 @@ begin
else
ld_hdr <= '0';
sh_hdr_en <= '0';
ld_p_chk_vals <= '0';
sh_chk_en <= '0';
calc_chk_en <= '0';
case state is
when IDLE => state_mux <= NONE;
if(valid_i = '1') then
ETH_TX.DST <= reply_MAC_i;
IPV4_TX.DST <= reply_IP_i;
IPV4_TX.TOL <= TOL_i;
UDP_TX.MLEN <= payload_len_i;
UDP_TX.DST_PORT <= reply_PORT_i;
ld_p_chk_vals <= '1';
state <= CALC_CHKSUM;
end if;
if(a_timeout = "0") then
ld_hdr <= '0';
sh_hdr_en <= '0';
when CALC_CHKSUM => if(chksum_empty = '0') then
sh_chk_en <= '1';
calc_chk_en <= '1';
else
if(chksum_done = '1') then
IPV4_TX.SUM <= IP_chk_sum;
ld_hdr <= '1';
state <= WAIT_SEND_REQ;
end if;
end if;
ld_p_chk_vals <= '0';
sh_chk_en <= '0';
calc_chk_en <= '0';
when WAIT_SEND_REQ => if(wb_slave_i.CYC = '1') then
state <= PREP_ETH;
state_mux <= HEADER;
case state is
when IDLE => state_mux <= NONE;
if(valid_i = '1') then
ETH_TX.DST <= reply_MAC_i;
IPV4_TX.DST <= reply_IP_i;
IPV4_TX.TOL <= TOL_i;
UDP_TX.MLEN <= payload_len_i;
UDP_TX.DST_PORT <= reply_PORT_i;
ld_p_chk_vals <= '1';
state <= CALC_CHKSUM;
end if;
when CALC_CHKSUM => if(chksum_empty = '0') then
sh_chk_en <= '1';
calc_chk_en <= '1';
else
if(chksum_done = '1') then
IPV4_TX.SUM <= IP_chk_sum;
ld_hdr <= '1';
state <= WAIT_SEND_REQ;
end if;
end if;
when WAIT_SEND_REQ => if(wb_slave_i.CYC = '1') then
state <= PREP_ETH;
state_mux <= HEADER;
end if;
when PREP_ETH =>
TX_HDR_slv(TX_HDR_slv'left downto TX_HDR_slv'length-c_ETH_HLEN*8) <= to_std_logic_vector(ETH_TX);
s_ETH_end <= c_ETH_HLEN -2;
ld_hdr <= '1';
state <= ETH;
when ETH =>
s_src_hdr_o.stb <= '1';
if(byte_count = s_ETH_end and src_i.stall = '0') then
TX_HDR_slv <= to_std_logic_vector(IPV4_TX);
ld_hdr <= '1';
state <= IPV4;
s_src_hdr_o.stb <= '0';
end if;
when PREP_ETH =>
TX_HDR_slv(TX_HDR_slv'left downto TX_HDR_slv'length-c_ETH_HLEN*8) <= to_std_logic_vector(ETH_TX);
s_ETH_end <= c_ETH_HLEN -2;
ld_hdr <= '1';
state <= ETH;
when ETH =>
s_src_hdr_o.stb <= '1';
if(byte_count = s_ETH_end and src_i.stall = '0') then
TX_HDR_slv <= to_std_logic_vector(IPV4_TX);
ld_hdr <= '1';
state <= IPV4;
s_src_hdr_o.stb <= '0';
end if;
when IPV4 => s_src_hdr_o.stb <= '1';
if((byte_count = (s_ETH_end + c_IPV4_HLEN)) and src_i.stall = '0') then
TX_HDR_slv(TX_HDR_slv'left downto TX_HDR_slv'length-c_UDP_HLEN*8) <= to_std_logic_vector(UDP_TX);
ld_hdr <= '1';
state <= UDP;
s_src_hdr_o.stb <= '0';
end if;
when UDP => s_src_hdr_o.stb <= '1';
if(byte_count = (s_ETH_end + c_IPV4_HLEN + c_UDP_HLEN) and src_i.stall = '0') then
state <= HDR_SEND;
s_src_hdr_o.stb <= '0';
end if;
when HDR_SEND => state_mux <= PAYLOAD;
state <= PAYLOAD_SEND;
when PAYLOAD_SEND => if( s_src_payload_o.cyc = '0') then
if(byte_count < c_ETH_FRAME_MIN_END) then
state <= PADDING;
state_mux <= PADDING;
else
state <= WAIT_IFGAP;
state_mux <= NONE;
when IPV4 => s_src_hdr_o.stb <= '1';
if((byte_count = (s_ETH_end + c_IPV4_HLEN)) and src_i.stall = '0') then
TX_HDR_slv(TX_HDR_slv'left downto TX_HDR_slv'length-c_UDP_HLEN*8) <= to_std_logic_vector(UDP_TX);
ld_hdr <= '1';
state <= UDP;
s_src_hdr_o.stb <= '0';
end if;
when UDP => s_src_hdr_o.stb <= '1';
if(byte_count = (s_ETH_end + c_IPV4_HLEN + c_UDP_HLEN) and src_i.stall = '0') then
state <= HDR_SEND;
s_src_hdr_o.stb <= '0';
end if;
when HDR_SEND => state_mux <= PAYLOAD;
state <= PAYLOAD_SEND;
when PAYLOAD_SEND => if( s_src_payload_o.cyc = '0') then
if(byte_count < c_ETH_FRAME_MIN_END) then
state <= PADDING;
state_mux <= PADDING;
else
state <= WAIT_IFGAP;
state_mux <= NONE;
end if;
end if;
when PADDING => s_src_padding_o.stb <= '1';
if((byte_count = c_ETH_FRAME_MIN_END) and src_i.stall = '0') then
s_src_padding_o.stb <= '0';
state <= WAIT_IFGAP;
state_mux <= NONE;
end if;
end if;
when WAIT_IFGAP => --ensure interframe gap
--if(counter_ouput < 10) then
-- counter_ouput <= counter_ouput +1;
--else
state <= IDLE;
--end if;
when others => state <= IDLE;
when PADDING => s_src_padding_o.stb <= '1';
if((byte_count = c_ETH_FRAME_MIN_END) and src_i.stall = '0') then
s_src_padding_o.stb <= '0';
state <= WAIT_IFGAP;
state_mux <= NONE;
end if;
when WAIT_IFGAP => --ensure interframe gap
--if(counter_ouput < 10) then
-- counter_ouput <= counter_ouput +1;
--else
state <= IDLE;
--end if;
when others => state <= IDLE;
end case;
end case;
else
state <= IDLE;
end if;
end if;
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment