eFEX firmware  1.7.3
ATLAS l1-calo - electron and tau feature extraction firmware for eFEX boards

Back to eFEX documentation
crc-20.vhd
1 --******************************************************************************
2 --* *
3 --* Calculates a CRC-20 over the data at Din, data may *
4 --* already arrive when Reset is high *
5 --* The process from Din to CRC takes 2 Clk cycles *
6 --* Frans Schreuder (Nikhef) franss@nikhef.nl *
7 --* *
8 --******************************************************************************
9 
10 
11 library ieee;
12 use ieee.std_logic_1164.all;
13 library work;
14 
15 entity CRC20 is
16  generic(
17  Nbits : positive := 64;
18  CRC_Width : positive := 20;
19  G_Poly : Std_Logic_Vector :=x"8349f";
20  G_InitVal : std_logic_vector :=x"fffff"
21  );
22  port(
23  CRC : out std_logic_vector(CRC_Width-1 downto 0);
24  Calc : in std_logic;
25  Clk : in std_logic;
26  DIn : in std_logic_vector(Nbits-1 downto 0);
27  Reset : in std_logic);
28 end CRC20;
29 
30 
31 architecture rtl of CRC20 is
32 
33  function ToIndirectInitVal(Direct:std_logic_vector; CRC_Width: positive; Poly: std_logic_vector) return std_logic_vector is
34  variable InDirect: std_logic_vector(Direct'high downto Direct'low);
35  begin
36  for k in 0 to CRC_Width loop
37  if(k = 0) then
38  InDirect := Direct;
39  else
40  if(InDirect(0)='1') then
41  InDirect := (('0'&InDirect(CRC_Width-1 downto 1)) xor ('1'&Poly(CRC_Width-1 downto 1)));
42  else
43  InDirect := '0'&InDirect(CRC_Width-1 downto 1);
44  end if;
45  end if;
46  end loop;
47  return InDirect;
48  end function ToIndirectInitVal;
49 
50  constant Poly: Std_Logic_Vector(CRC_Width-1 downto 0) := G_Poly;
51  constant InitVal: Std_Logic_Vector(CRC_Width-1 downto 0) := G_InitVal;
52 
53  constant InDirectInitVal: std_logic_vector(CRC_Width-1 downto 0):=ToIndirectInitVal(InitVal, CRC_Width, Poly);
54  signal Reg_s : std_logic_vector(CRC_Width-1 downto 0);
55 begin
56 
57 
58  process (Clk)
59  variable Reg, Reg2: Std_Logic_Vector (CRC_Width-1 downto 0);
60  variable ApplyPoly: std_logic;
61  begin
62 
63  if rising_Edge(Clk) then
64  if Reset = '1' then
65  if(Calc = '1') then
66  for k In 0 to Nbits loop
67  if(k = 0) then
68  Reg := (InDirectInitVal);--(CRC_Width-1 downto 0)&dinP(k))xor ('0'&Poly);
69  else
70  if Reg(CRC_Width-1) = '1' then
71  Reg := (Reg(CRC_Width-2 downto 0)&din(Nbits - k))xor (Poly);
72  else
73  Reg := Reg(CRC_Width-2 downto 0)&din(Nbits - k);
74  end if;
75  end if;
76  end loop;
77  else
78  Reg := InDirectInitVal;
79  end if;
80  else
81  if Calc = '1' then
82  for k In 1 to Nbits loop
83  if Reg(CRC_Width-1) = '1' then
84  Reg := (Reg(CRC_Width-2 downto 0)&din(Nbits - k))xor (Poly);
85  else
86  Reg := Reg(CRC_Width-2 downto 0)&din(Nbits - k);
87  end if;
88  end loop;
89  else
90  Reg := Reg;
91  end if;
92  end if;
93 
94  Reg_s <= Reg;
95  Reg2 := Reg_s;
96  --we need one more loop to output the CRC register to the output.
97  for k In 1 to CRC_Width loop
98  if Reg2(CRC_Width-1) = '1' then
99  Reg2 := (Reg2(CRC_Width-2 downto 0)&'0')xor (Poly);
100  else
101  Reg2:= Reg2(CRC_Width-2 downto 0)&'0';
102  end if;
103  end loop;
104  CRC <= Reg2;--(CRC_width-1 downto 0);
105  end if;
106  end process;
107 
108 end architecture rtl ; -- of CRC
Definition: crc-20.vhd:15