69 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
			
		
		
	
	
			69 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
| -- -------------------------------------------------------------------------- --
 | |
| --               TRASHERNET - A Trashy Ethernet Stack for FPGAs               --
 | |
| -- -------------------------------------------------------------------------- --
 | |
| -- crc.vhd : Generic CRC implementation
 | |
| -- -------------------------------------------------------------------------- --
 | |
| -- Author       : Markus Koch <markus@notsyncing.net>
 | |
| -- 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;
 |