From abc2952ac6c6984167d681fa68e26f5150b51a71 Mon Sep 17 00:00:00 2001 From: Reinier van der Walle <walle@astron.nl> Date: Thu, 20 Jul 2017 12:21:03 +0000 Subject: [PATCH] --- .../io/eth/src/vhdl/eth_checksum_10G.vhd | 183 +++++++----------- 1 file changed, 75 insertions(+), 108 deletions(-) diff --git a/libraries/io/eth/src/vhdl/eth_checksum_10G.vhd b/libraries/io/eth/src/vhdl/eth_checksum_10G.vhd index 19e45a8d07..f18ca271ba 100644 --- a/libraries/io/eth/src/vhdl/eth_checksum_10G.vhd +++ b/libraries/io/eth/src/vhdl/eth_checksum_10G.vhd @@ -25,7 +25,6 @@ USE IEEE.std_logic_1164.ALL; USE IEEE.numeric_std.ALL; USE common_lib.common_pkg.ALL; USE dp_lib.dp_stream_pkg.ALL; -USE work.eth_pkg.ALL; -- Purpose: -- Can be used to calculate the checksum for IPv4, ICMP and UDP, provided @@ -47,131 +46,99 @@ USE work.eth_pkg.ALL; -- snk_in.valid is inactive and that snk_in.valid is only active for new -- data. -ENTITY eth_checksum_10G IS +ENTITY eth_checksum_10G_tx IS PORT ( rst : IN STD_LOGIC; clk : IN STD_LOGIC; + src_out : OUT t_dp_sosi; snk_in : IN t_dp_sosi; - checksum : OUT STD_LOGIC_VECTOR(c_halfword_w-1 DOWNTO 0); - checksum_val : OUT STD_LOGIC + src_in : IN t_dp_siso; + snk_out : OUT t_dp_siso ); -END eth_checksum_10G; +END eth_checksum_10G_tx; +ARCHITECTURE rtl OF eth_checksum_10G_tx IS -ARCHITECTURE rtl OF eth_checksum_10G IS + CONSTANT c_cin_w : NATURAL := 4; --true_log2(c_nof_half_words - 1); + CONSTANT c_pipeline_delay : NATURAL := 2; + + SIGNAL sum : UNSIGNED(c_halfword_w + c_cin_w -1 DOWNTO 0) := (OTHERS => '0'); + SIGNAL checksum : STD_LOGIC_VECTOR(c_halfword_w-1 DOWNTO 0); + SIGNAL dp_pipeline_src_out : t_dp_sosi; + SIGNAL cnt_clr : STD_LOGIC; + SIGNAL cnt_en : STD_LOGIC; + SIGNAL count : STD_LOGIC_VECTOR(31 DOWNTO 0); - SIGNAL in_data : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0); - SIGNAL in_valid : STD_LOGIC; - SIGNAL in_sop : STD_LOGIC; - SIGNAL in_eop : STD_LOGIC; - - SIGNAL prev_in_valid : STD_LOGIC; - SIGNAL prev_in_eop : STD_LOGIC; - SIGNAL prev_in_eop_dly : STD_LOGIC; - - SIGNAL word_sum_cin : UNSIGNED(1 DOWNTO 0); -- carry in - SIGNAL word_sum_dat : UNSIGNED(c_halfword_w-1 DOWNTO 0); - SIGNAL word_sum : UNSIGNED(c_halfword_w+1 DOWNTO 0); - SIGNAL nxt_word_sum : UNSIGNED(c_halfword_w+1 DOWNTO 0); - - SIGNAL sum_cin : UNSIGNED(0 DOWNTO 0); -- carry in - SIGNAL sum_dat : UNSIGNED(c_halfword_w-1 DOWNTO 0); - SIGNAL sum : UNSIGNED(c_halfword_w DOWNTO 0); - SIGNAL nxt_sum : UNSIGNED(c_halfword_w DOWNTO 0); - - SIGNAL last_dat : UNSIGNED(c_halfword_w-1 DOWNTO 0); - - SIGNAL i_checksum : STD_LOGIC_VECTOR(checksum'RANGE); - SIGNAL nxt_checksum : STD_LOGIC_VECTOR(checksum'RANGE); - SIGNAL i_checksum_val : STD_LOGIC; - SIGNAL nxt_checksum_val : STD_LOGIC; - - SIGNAL data_p0 : STD_LOGIC_VECTOR(c_halfword_w+1 DOWNTO 0); - SIGNAL data_p1 : STD_LOGIC_VECTOR(c_halfword_w+1 DOWNTO 0); - SIGNAL data_p2 : STD_LOGIC_VECTOR(c_halfword_w+1 DOWNTO 0); - SIGNAL data_p3 : STD_LOGIC_VECTOR(c_halfword_w+1 DOWNTO 0); BEGIN - - data_p0 <= "00" & in_data(c_longword_w -1 DOWNTO c_halfword_w * 3); - data_p1 <= "00" & in_data(c_halfword_w*3 -1 DOWNTO c_halfword_w * 2); - data_p2 <= "00" & in_data(c_halfword_w*2 -1 DOWNTO c_halfword_w ); - data_p3 <= "00" & in_data(c_halfword_w -1 DOWNTO 0); - - checksum <= i_checksum; - checksum_val <= i_checksum_val; - - p_clk : PROCESS(rst, clk) + p_calc_chksum : PROCESS(clk) BEGIN - IF rst='1' THEN - prev_in_valid <= '0'; - prev_in_eop <= '0'; - prev_in_eop_dly <= '0'; - word_sum <= (OTHERS=>'0'); - sum <= (OTHERS=>'0'); - i_checksum <= (OTHERS=>'0'); - i_checksum_val <= '0'; - ELSIF rising_edge(clk) THEN - -- input - prev_in_valid <= in_valid; - prev_in_eop <= in_eop; - prev_in_eop_dly <= prev_in_eop; - -- internal - word_sum <= nxt_word_sum; - sum <= nxt_sum; - -- outputs - i_checksum <= nxt_checksum; - i_checksum_val <= nxt_checksum_val; + IF rst = '1' THEN + sum <= (OTHERS => '0'); + --checksum <= (OTHERS => '0'); + + ELSIF RISING_EDGE(clk) THEN + IF cnt_clr = '1' THEN + sum <= (OTHERS => '0'); + + ELSIF cnt_en = '1' THEN + CASE TO_UINT(count) IS + WHEN 0 => + sum <= sum + UNSIGNED(snk_in.data(c_halfword_w-1 DOWNTO 0)); + WHEN 1 => + sum <= sum + UNSIGNED(snk_in.data(c_halfword_w*4 -1 DOWNTO c_halfword_w *3)) + + UNSIGNED(snk_in.data(c_halfword_w*3 -1 DOWNTO c_halfword_w *2)) + + UNSIGNED(snk_in.data(c_halfword_w*2 -1 DOWNTO c_halfword_w)) + + UNSIGNED(snk_in.data(c_halfword_w -1 DOWNTO 0)); + WHEN 2 => + sum <= sum + UNSIGNED(snk_in.data(c_halfword_w*3 -1 DOWNTO c_halfword_w *2)) + + UNSIGNED(snk_in.data(c_halfword_w*2 -1 DOWNTO c_halfword_w)) + + UNSIGNED(snk_in.data(c_halfword_w -1 DOWNTO 0)); + WHEN 3 => + sum <= sum + UNSIGNED(snk_in.data(c_halfword_w*4 -1 DOWNTO c_halfword_w *3)); + + WHEN OTHERS => + END CASE; + END IF; END IF; - END PROCESS; + END PROCESS; - -- Combinatorial sink input - p_zero_empty : PROCESS(snk_in, in_eop) + checksum <= NOT(STD_LOGIC_VECTOR(sum(c_halfword_w-1 DOWNTO 0)+sum(sum'HIGH DOWNTO c_halfword_w))); + p_insert_chksum : PROCESS(dp_pipeline_src_out, checksum, count) BEGIN - in_data <= snk_in.data(c_longword_w-1 DOWNTO 0); - IF in_eop='1' THEN - CASE TO_INTEGER(UNSIGNED(snk_in.empty(c_eth_empty_w-1 DOWNTO 0))) IS - WHEN 1 => in_data <= snk_in.data(c_longword_w-1 DOWNTO c_byte_w) & c_slv0( c_byte_w-1 DOWNTO 0); - WHEN 2 => in_data <= snk_in.data(c_longword_w-1 DOWNTO 2*c_byte_w) & c_slv0(2*c_byte_w-1 DOWNTO 0); - WHEN 3 => in_data <= snk_in.data(c_longword_w-1 DOWNTO 3*c_byte_w) & c_slv0(3*c_byte_w-1 DOWNTO 0); - WHEN 4 => in_data <= snk_in.data(c_longword_w-1 DOWNTO 4*c_byte_w) & c_slv0(4*c_byte_w-1 DOWNTO 0); - WHEN 5 => in_data <= snk_in.data(c_longword_w-1 DOWNTO 5*c_byte_w) & c_slv0(5*c_byte_w-1 DOWNTO 0); - WHEN 6 => in_data <= snk_in.data(c_longword_w-1 DOWNTO 6*c_byte_w) & c_slv0(6*c_byte_w-1 DOWNTO 0); - WHEN 7 => in_data <= snk_in.data(c_longword_w-1 DOWNTO 7*c_byte_w) & c_slv0(7*c_byte_w-1 DOWNTO 0); - WHEN OTHERS => NULL; - END CASE; + src_out <= dp_pipeline_src_out; + IF TO_UINT(count) = 2+c_pipeline_delay THEN + src_out.data(c_halfword_w*4 -1 DOWNTO c_halfword_w *3) <= checksum; END IF; - END PROCESS; - - in_valid <= snk_in.valid; - in_sop <= snk_in.sop; - in_eop <= snk_in.eop; + END PROCESS; - -- Word sum - word_sum_cin <= (OTHERS => '0') WHEN in_sop='1' ELSE word_sum(c_halfword_w +1 DOWNTO c_halfword_w); - word_sum_dat <= word_sum(c_halfword_w-1 DOWNTO 0); - nxt_word_sum <= UNSIGNED(data_p0) + - UNSIGNED(data_p1) + - UNSIGNED(data_p2) + - UNSIGNED(data_p3) + - word_sum_cin WHEN in_valid='1' ELSE - word_sum; - - -- Accumulated sum - sum_cin(0) <= sum(c_halfword_w); - sum_dat <= sum(c_halfword_w-1 DOWNTO 0); - nxt_sum <= (OTHERS=>'0') WHEN in_sop='1' ELSE - ('0' & sum_dat) + word_sum_dat + sum_cin WHEN prev_in_valid='1' ELSE - sum; + cnt_en <= snk_in.valid; + cnt_clr <= snk_in.sop; - -- Accumulate the last carry - last_dat <= sum(c_halfword_w-1 DOWNTO 0) + sum_cin; - - -- Checksum is 1-complement of the sum - nxt_checksum <= NOT(STD_LOGIC_VECTOR(last_dat)) WHEN prev_in_eop_dly='1' ELSE i_checksum; - nxt_checksum_val <= '1' WHEN prev_in_eop_dly='1' ELSE - '0' WHEN in_sop='1' ELSE i_checksum_val; + u_calc_counter : ENTITY common_lib.common_counter + PORT MAP ( + rst => rst, + clk => clk, + cnt_clr => cnt_clr, + cnt_en => cnt_en, + count => count + ); + u_dp_pipeline : ENTITY dp_lib.dp_pipeline + GENERIC MAP ( + g_pipeline => c_pipeline_delay + ) + PORT MAP ( + rst => rst, + clk => clk, + -- ST sink + snk_out => snk_out, + snk_in => snk_in, + -- ST source + src_in => src_in, + src_out => dp_pipeline_src_out + ); + END rtl; -- GitLab