diff --git a/libraries/io/nw_10GbE/src/vhdl/nw_ping_response.vhd b/libraries/io/nw_10GbE/src/vhdl/nw_ping_response.vhd index e0bec9f240cebfa95bc632875830aaf4c9369fc9..9ecaa256899c7fbafa32bf0ad8754e4b09ea9bb4 100644 --- a/libraries/io/nw_10GbE/src/vhdl/nw_ping_response.vhd +++ b/libraries/io/nw_10GbE/src/vhdl/nw_ping_response.vhd @@ -60,7 +60,7 @@ ARCHITECTURE rtl of nw_ping_response IS CONSTANT c_dp_fifo_size : NATURAL := 16; CONSTANT c_cin_w : NATURAL := 4; - CONSTANT c_pipeline : NATURAL := c_network_total_header_64b_nof_words + 3; -- Header length and 3 more pipeline cycles to allow for the other states + CONSTANT c_pipeline : NATURAL := c_network_total_header_64b_nof_words + 5; -- Header length and 5 more pipeline cycles to allow for the other states TYPE t_state IS (s_idle, s_capture, s_check, s_sum, s_output, s_wait); @@ -150,23 +150,33 @@ BEGIN WHEN s_output => -- Send out ICMP response v.src_out := dp_pipeline_src_out; IF dp_pipeline_src_out.valid = '1' THEN - IF r.word_cnt = 0 THEN - -- Also perform final checksum calculation - v.ip_checksum := NOT(STD_LOGIC_VECTOR(r.ip_sum(c_halfword_w-1 DOWNTO 0)+r.ip_sum(r.ip_sum'HIGH DOWNTO c_halfword_w))); -- checksum = inverted (sum + carry) - v.icmp_checksum := TO_UVEC((2048 + TO_UINT(r.hdr_fields.icmp.checksum)), c_halfword_w); -- checksum = original checksum + 0x0800 (incremental update) - END IF; - IF r.word_cnt < c_network_total_header_64b_nof_words THEN - v.word_cnt := r.word_cnt+1; - v.src_out.data(c_data_w-1 DOWNTO 0) := r.hdr_response(r.word_cnt); - END IF; - - IF r.word_cnt = 3 THEN -- insert ip checksum - v.src_out.data(c_halfword_w*4 -1 DOWNTO c_halfword_w *3) := r.ip_checksum; - ELSIF r.word_cnt = 4 THEN -- insert icmp checksum - v.src_out.data(c_halfword_w*2 -1 DOWNTO c_halfword_w) := r.icmp_checksum; - ELSIF dp_pipeline_src_out.eop = '1' THEN - v.state := s_wait; - END IF; + CASE r.word_cnt IS + WHEN 0 => + -- Also perform final checksum calculation + IF dp_pipeline_src_out.sop = '1' THEN -- Wait for SOP + v.src_out.data(c_data_w-1 DOWNTO 0) := r.hdr_response(r.word_cnt); + v.ip_checksum := NOT(STD_LOGIC_VECTOR(r.ip_sum(c_halfword_w-1 DOWNTO 0)+r.ip_sum(r.ip_sum'HIGH DOWNTO c_halfword_w))); -- checksum = inverted (sum + carry) + v.icmp_checksum := TO_UVEC((2048 + TO_UINT(r.hdr_fields.icmp.checksum)), c_halfword_w); -- checksum = original checksum + 0x0800 (incremental update) + v.word_cnt := r.word_cnt+1; + ELSE + v.src_out := c_dp_sosi_rst; + END IF; + WHEN 1 TO 2 => + v.src_out.data(c_data_w-1 DOWNTO 0) := r.hdr_response(r.word_cnt); + v.word_cnt := r.word_cnt+1; + WHEN 3 => + v.src_out.data(c_data_w-1 DOWNTO 0) := r.hdr_response(r.word_cnt); + v.src_out.data(c_halfword_w*4 -1 DOWNTO c_halfword_w *3) := r.ip_checksum; + v.word_cnt := r.word_cnt+1; + WHEN 4 => + v.src_out.data(c_data_w-1 DOWNTO 0) := r.hdr_response(r.word_cnt); + v.src_out.data(c_halfword_w*2 -1 DOWNTO c_halfword_w) := r.icmp_checksum; + v.word_cnt := r.word_cnt+1; + WHEN OTHERS => + IF dp_pipeline_src_out.eop = '1' THEN + v.state := s_wait; + END IF; + END CASE; END IF; WHEN s_wait =>