-- -------------------------------------------------------------------------- -- -- TRASHERNET - A Trashy Ethernet Stack for FPGAs -- -- -------------------------------------------------------------------------- -- -- crc.vhd : Generic CRC implementation -- -------------------------------------------------------------------------- -- -- Author : Markus Koch -- Contributors : None -- License : Mozilla Public License (MPL) Version 2 -- -------------------------------------------------------------------------- -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity crc is generic( POLYNOMIAL : std_logic_vector; -- Polynomial, leading '1' is implicit START : std_logic_vector; -- CRC start value (after `crc_clear`) FINAL_XOR : std_logic_vector; -- CRC will be XORed with this value on `crc_out` REVERSE_OUT : boolean -- Bit reverse the output vector ); port( clk : in std_logic; rst : in std_logic; data : in std_logic_vector; data_valid : in std_logic; crc_clear : in std_logic; crc_out : out std_logic_vector(POLYNOMIAL'range) ); end entity crc; architecture rtl of crc is signal crc_i : std_logic_vector(crc_out'range); function reverse_bits(slv : std_logic_vector) return std_logic_vector is variable r : std_logic_vector(slv'range); begin for i in slv'low to slv'high loop r(i) := slv(r'low + slv'high - i); end loop; return r; end function reverse_bits; begin crc_calc : process(clk, rst) is variable crc_v : std_logic_vector(crc_out'range); variable fb : std_logic; begin if rst then crc_i <= START; elsif rising_edge(clk) then if data_valid then crc_v := crc_i; for i in data'low to data'high loop fb := data(i) xor crc_v(crc_v'high); crc_v := (crc_v(crc_v'high - 1 downto crc_v'low) & '0') xor (POLYNOMIAL and fb); end loop; crc_i <= crc_v; end if; if crc_clear then crc_i <= START; end if; end if; end process crc_calc; crc_out <= reverse_bits(crc_i xor FINAL_XOR) when REVERSE_OUT else (crc_i xor FINAL_XOR); end architecture rtl;