From 352e22e0234d33f3dda03451eaaa188a5e3405d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20W=C5=82ostowski?= <tomasz.wlostowski@cern.ch> Date: Wed, 3 Oct 2012 09:46:35 +0200 Subject: [PATCH] common/gc_crc_gen: generic byte swapping Conflicts: modules/common/gc_crc_gen.vhd --- modules/common/gc_crc_gen.vhd | 96 ++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 31 deletions(-) diff --git a/modules/common/gc_crc_gen.vhd b/modules/common/gc_crc_gen.vhd index 31ea2c48..e7d6b666 100644 --- a/modules/common/gc_crc_gen.vhd +++ b/modules/common/gc_crc_gen.vhd @@ -72,7 +72,8 @@ entity gc_crc_gen is -- word when 0) g_dual_width : integer range 0 to 1 := 0; -- if true, match_o output is registered, otherwise it's driven combinatorially - g_registered_match_output : boolean := true); + g_registered_match_output : boolean := true; + g_registered_crc_output : boolean := true); port ( clk_i : in std_logic; -- clock rst_i : in std_logic; -- reset, active high @@ -80,7 +81,8 @@ entity gc_crc_gen is half_i : in std_logic; -- 1: input word has g_half_width bits -- 0: input word has g_data_width bits - data_i : in std_logic_vector(g_data_width - 1 downto 0); -- data input + data_i : in std_logic_vector(g_data_width - 1 downto 0); -- data input + restart_i : in std_logic := '0'; match_o : out std_logic; -- CRC match flag: 1 - CRC matches @@ -100,23 +102,35 @@ architecture rtl of gc_crc_gen is return v_result; end; - constant msb : integer := g_polynomial'length - 1; - constant init_msb : integer := g_init_value'length - 1; - constant p : std_logic_vector(msb downto 0) := g_polynomial; - constant dw : integer := g_data_width; - constant pw : integer := g_polynomial'length; - type fb_array is array (dw downto 1) of std_logic_vector(msb downto 0); - type dmsb_array is array (dw downto 1) of std_logic_vector(msb downto 1); - signal crca : fb_array; - signal da, ma : dmsb_array; - signal crc : std_logic_vector(msb downto 0); - signal arst, srst : std_logic; - - signal data_i2 : std_logic_vector(15 downto 0); - signal en_d0 : std_logic; - signal crc_tmp : std_logic_vector(31 downto 0); - signal crc_int : std_logic_vector(31 downto 0); - + function f_reverse_bytes (a : in std_logic_vector) + return std_logic_vector is + variable tmp : std_logic_vector(a'length-1 downto 0); + variable v_result : std_logic_vector(a'length-1 downto 0); + begin + tmp := a; + for i in tmp'range loop + v_result(i) := tmp(((tmp'length/8-1) - i/8)*8 + (i mod 8)); + end loop; + return v_result; + end; + + + constant msb : integer := g_polynomial'length - 1; + constant init_msb : integer := g_init_value'length - 1; + constant p : std_logic_vector(msb downto 0) := g_polynomial; + constant dw : integer := g_data_width; + constant pw : integer := g_polynomial'length; + type fb_array is array (dw downto 1) of std_logic_vector(msb downto 0); + type dmsb_array is array (dw downto 1) of std_logic_vector(msb downto 1); + signal crca : fb_array; + signal da, ma : dmsb_array; + signal crc : std_logic_vector(msb downto 0); + signal arst, srst : std_logic; + + + signal data_i2 : std_logic_vector(g_data_width-1 downto 0); + signal en_d0 : std_logic; + signal crc_cur, crc_next : std_logic_vector(g_polynomial'length-1 downto 0); begin @@ -149,8 +163,9 @@ begin end process; end generate PCHK3; - data_i2(15 downto 0) <= (data_i(7 downto 0) & data_i(15 downto 8)); --- data_i2(15 downto 0) <= f_reverse_vector(data_i(15 downto 0)); + data_i2 <= f_reverse_bytes(data_i); + + crc_cur <= g_init_value when restart_i = '1' else crc; -- Generate vector of each data bit CA : for i in 1 to dw generate -- data bits @@ -161,7 +176,7 @@ begin -- Generate vector of each CRC MSB MS0 : for i in 1 to msb generate - ma(1)(i) <= crc(msb); + ma(1)(i) <= crc_cur(msb); end generate MS0; MSP : for i in 2 to dw generate MSU : for j in 1 to msb generate @@ -170,8 +185,8 @@ begin end generate MSP; -- Generate feedback matrix - crca(1)(0) <= da(1)(1) xor crc(msb); - crca(1)(msb downto 1) <= crc(msb - 1 downto 0) xor ((da(1) xor ma(1)) and p(msb downto 1)); + crca(1)(0) <= da(1)(1) xor crc_cur(msb); + crca(1)(msb downto 1) <= crc_cur(msb - 1 downto 0) xor ((da(1) xor ma(1)) and p(msb downto 1)); FB : for i in 2 to dw generate crca(i)(0) <= da(i)(1) xor crca(i - 1)(msb); crca(i)(msb downto 1) <= crca(i - 1)(msb - 1 downto 0) xor @@ -188,11 +203,6 @@ begin arst <= rst_i; end generate AR; --- CRC process - crc_tmp <= f_reverse_vector(not crc); - crc_int <= crc_tmp(7 downto 0) & crc_tmp(15 downto 8) & crc_tmp(23 downto 16) & crc_tmp(31 downto 24); - - crc_o <= crc_int; CRCP : process (clk_i, arst) begin @@ -212,6 +222,30 @@ begin end if; end process; + p_crc_next : process(crc, half_i, crca) + begin + if(g_registered_crc_output) then + crc_next <= f_reverse_bytes(f_reverse_vector(not crc)); + else + if(half_i = '1' and g_dual_width = 1) then + crc_next <= f_reverse_bytes(f_reverse_vector(not crca(g_half_width))); + else + crc_next <= f_reverse_bytes(f_reverse_vector(not crca(g_data_width))); + end if; + end if; + end process; + + p_crc_output : process(crc_next, crc, en_i) + begin + if(g_registered_crc_output) then + crc_o <= crc_next; + elsif(en_i = '1') then + crc_o <= crc_next; + else + crc_o <= f_reverse_bytes(f_reverse_vector(not crc)); + end if; + end process; + gen_reg_match_output : if(g_registered_match_output) generate match_gen : process (clk_i, arst) @@ -227,7 +261,7 @@ begin en_d0 <= en_i; if(en_d0 = '1') then - if crc_int = g_residue then + if crc_next = g_residue then match_o <= '1'; else match_o <= '0'; @@ -240,7 +274,7 @@ begin end generate gen_reg_match_output; gen_comb_match_output : if (not g_registered_match_output) generate - match_o <= '1' when crc_int = g_residue else '0'; + match_o <= '1' when crc_next = g_residue else '0'; end generate gen_comb_match_output; end rtl; -- GitLab