ROD firmware  1.0.5
ATLAS l1-calo - ROD_eFEX and ROD_jFEX firmware for the L1Calo ROD board

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