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

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