diff --git a/hdl/EB_SPEC_Test/EB_2_wb_converter.vhd b/hdl/EB_SPEC_Test/EB_2_wb_converter.vhd index f0110bddf2e682675ae7c64482bdcb3c653a7f05..a4e434ac108e3da7a7e78d4778e3c4211a8369ba 100644 --- a/hdl/EB_SPEC_Test/EB_2_wb_converter.vhd +++ b/hdl/EB_SPEC_Test/EB_2_wb_converter.vhd @@ -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; diff --git a/hdl/EB_SPEC_Test/EB_RX_CTRL.vhd b/hdl/EB_SPEC_Test/EB_RX_CTRL.vhd index 9e96216b2d0b92fe0e3c1337a1a0230696e7d8f5..5f512da77289e8406932e2bd3cc480a86f05aff0 100644 --- a/hdl/EB_SPEC_Test/EB_RX_CTRL.vhd +++ b/hdl/EB_SPEC_Test/EB_RX_CTRL.vhd @@ -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; diff --git a/hdl/EB_SPEC_Test/EB_TX_CTRL.vhd b/hdl/EB_SPEC_Test/EB_TX_CTRL.vhd index a190b01ea364ebb8a79ab09e2d3ccc7b1a6412e8..e336748b950fad7db5ed0a8e8271a229941c409e 100644 --- a/hdl/EB_SPEC_Test/EB_TX_CTRL.vhd +++ b/hdl/EB_SPEC_Test/EB_TX_CTRL.vhd @@ -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;