Skip to content
Snippets Groups Projects
Commit abc2952a authored by Reinier van der Walle's avatar Reinier van der Walle
Browse files

No commit message

No commit message
parent a0ebd21e
No related branches found
No related tags found
No related merge requests found
......@@ -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;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment