1 |
4 |
DFC |
--
|
2 |
|
|
-- crc32_gen.vhd: 32-bit CRC module processing generic number of bits in parallel
|
3 |
|
|
-- Copyright (C) 2011 CESNET
|
4 |
|
|
-- Author(s): Lukas Kekely <xkekel00@stud.fit.vutbr.cz>
|
5 |
|
|
--
|
6 |
|
|
-- Redistribution and use in source and binary forms, with or without
|
7 |
|
|
-- modification, are permitted provided that the following conditions
|
8 |
|
|
-- are met:
|
9 |
|
|
-- 1. Redistributions of source code must retain the above copyright
|
10 |
|
|
-- notice, this list of conditions and the following disclaimer.
|
11 |
|
|
-- 2. Redistributions in binary form must reproduce the above copyright
|
12 |
|
|
-- notice, this list of conditions and the following disclaimer in
|
13 |
|
|
-- the documentation and/or other materials provided with the
|
14 |
|
|
-- distribution.
|
15 |
|
|
-- 3. Neither the name of the Company nor the names of its contributors
|
16 |
|
|
-- may be used to endorse or promote products derived from this
|
17 |
|
|
-- software without specific prior written permission.
|
18 |
|
|
--
|
19 |
|
|
-- This software is provided ``as is'', and any express or implied
|
20 |
|
|
-- warranties, including, but not limited to, the implied warranties of
|
21 |
|
|
-- merchantability and fitness for a particular purpose are disclaimed.
|
22 |
|
|
-- In no event shall the company or contributors be liable for any
|
23 |
|
|
-- direct, indirect, incidental, special, exemplary, or consequential
|
24 |
|
|
-- damages (including, but not limited to, procurement of substitute
|
25 |
|
|
-- goods or services; loss of use, data, or profits; or business
|
26 |
|
|
-- interruption) however caused and on any theory of liability, whether
|
27 |
|
|
-- in contract, strict liability, or tort (including negligence or
|
28 |
|
|
-- otherwise) arising in any way out of the use of this software, even
|
29 |
|
|
-- if advised of the possibility of such damage.
|
30 |
|
|
--
|
31 |
|
|
-- $Id$
|
32 |
|
|
--
|
33 |
|
|
-- TODO:
|
34 |
|
|
--
|
35 |
|
|
--
|
36 |
|
|
|
37 |
|
|
library IEEE;
|
38 |
|
|
use IEEE.std_logic_1164.all;
|
39 |
|
|
use IEEE.std_logic_arith.all;
|
40 |
|
|
use IEEE.std_logic_unsigned.all;
|
41 |
|
|
use IEEE.numeric_std.all;
|
42 |
|
|
use WORK.math_pack.all;
|
43 |
|
|
|
44 |
|
|
entity crc32_gen is
|
45 |
|
|
generic(
|
46 |
|
|
DATA_WIDTH : integer := 64;
|
47 |
|
|
REG_BITMAP : integer := 0
|
48 |
|
|
);
|
49 |
|
|
port(
|
50 |
|
|
DI : in std_logic_vector(DATA_WIDTH-1 downto 0);
|
51 |
|
|
DI_DV : in std_logic;
|
52 |
|
|
EOP : in std_logic;
|
53 |
|
|
MASK : in std_logic_vector(log2(DATA_WIDTH/8)-1 downto 0);
|
54 |
|
|
CLK : in std_logic;
|
55 |
|
|
RESET : in std_logic;
|
56 |
|
|
CRC : out std_logic_vector(31 downto 0);
|
57 |
|
|
DO_DV : out std_logic
|
58 |
|
|
);
|
59 |
|
|
end entity crc32_gen;
|
60 |
|
|
|
61 |
|
|
architecture crc32_gen_arch of crc32_gen is
|
62 |
|
|
constant MW : integer := log2(DATA_WIDTH/8);
|
63 |
|
|
|
64 |
|
|
signal crc_reg: std_logic_vector(DATA_WIDTH-1 downto 0);
|
65 |
|
|
signal crc_reg_input: std_logic_vector(DATA_WIDTH-1 downto 0);
|
66 |
|
|
signal tctl, deop : std_logic;
|
67 |
|
|
signal reg_low, reg_low_data, crctab_do, crctab_tree_do : std_logic_vector(31 downto 0);
|
68 |
|
|
signal mx_di, do_reg : std_logic_vector(31 downto 0);
|
69 |
|
|
|
70 |
|
|
signal reg_mask : std_logic_vector(log2(DATA_WIDTH/8)-1 downto 0);
|
71 |
|
|
signal reg_di : std_logic_vector(DATA_WIDTH-1 downto 0);
|
72 |
|
|
|
73 |
|
|
signal tree_vld : std_logic;
|
74 |
|
|
|
75 |
|
|
begin
|
76 |
|
|
assert DATA_WIDTH >= 32 and DATA_WIDTH mod 8 = 0 report "CRC32: Wrong DATA_WIDTH set! DATA_WIDTH must be multiple of 8 and greater or equal to 32." severity error;
|
77 |
|
|
|
78 |
|
|
crc32_gen_tab_instance: entity work.crc32_fast_tab
|
79 |
|
|
generic map(
|
80 |
|
|
DATA_WIDTH => DATA_WIDTH
|
81 |
|
|
)
|
82 |
|
|
port map(
|
83 |
|
|
DI => crc_reg,
|
84 |
|
|
DO => crctab_do
|
85 |
|
|
);
|
86 |
|
|
|
87 |
|
|
crc32_gen_tab_tree_instance: entity work.crc32_gen_tab_tree
|
88 |
|
|
generic map(
|
89 |
|
|
DATA_WIDTH => DATA_WIDTH,
|
90 |
|
|
REG_BITMAP => REG_BITMAP
|
91 |
|
|
)
|
92 |
|
|
port map(
|
93 |
|
|
CLK => CLK,
|
94 |
|
|
DI => crc_reg,
|
95 |
|
|
DI_DV => deop,
|
96 |
|
|
MASK => reg_mask,
|
97 |
|
|
DO => crctab_tree_do,
|
98 |
|
|
DO_DV => tree_vld
|
99 |
|
|
);
|
100 |
|
|
|
101 |
|
|
crc32_gen_fsm_instance: entity work.crc32_gen_fsm
|
102 |
|
|
port map(
|
103 |
|
|
CLK => CLK,
|
104 |
|
|
RESET => RESET,
|
105 |
|
|
DI_DV => DI_DV,
|
106 |
|
|
EOP => EOP,
|
107 |
|
|
TCTL => tctl
|
108 |
|
|
);
|
109 |
|
|
|
110 |
|
|
reg_di_input_long_gen : if (DATA_WIDTH > 32) generate
|
111 |
|
|
reg_di <= DI(DATA_WIDTH-1 downto 32) & mx_di;
|
112 |
|
|
end generate;
|
113 |
|
|
reg_di_input_short_gen : if (DATA_WIDTH <= 32) generate
|
114 |
|
|
reg_di <= mx_di(DATA_WIDTH-1 downto 0);
|
115 |
|
|
end generate;
|
116 |
|
|
|
117 |
|
|
crc_reg_proc: process(CLK, RESET)
|
118 |
|
|
begin
|
119 |
|
|
if RESET = '1' then
|
120 |
|
|
crc_reg <= (others => '0');
|
121 |
|
|
elsif CLK'event AND clk = '1' then
|
122 |
|
|
if DI_DV = '1' then
|
123 |
|
|
crc_reg <= crc_reg_input;
|
124 |
|
|
end if;
|
125 |
|
|
end if;
|
126 |
|
|
end process;
|
127 |
|
|
crc_di_input_long_gen : if (DATA_WIDTH > 32) generate
|
128 |
|
|
crc_reg_input <= reg_di(DATA_WIDTH-1 downto 32) & reg_low;
|
129 |
|
|
end generate;
|
130 |
|
|
crc_di_input_short_gen : if (DATA_WIDTH <= 32) generate
|
131 |
|
|
crc_reg_input <= reg_low(DATA_WIDTH-1 downto 0);
|
132 |
|
|
end generate;
|
133 |
|
|
|
134 |
|
|
|
135 |
|
|
process(CLK, RESET)
|
136 |
|
|
begin
|
137 |
|
|
if RESET = '1' then
|
138 |
|
|
deop <= '0';
|
139 |
|
|
elsif CLK = '1' AND CLK'event then
|
140 |
|
|
deop <= EOP and DI_DV;
|
141 |
|
|
end if;
|
142 |
|
|
end process;
|
143 |
|
|
|
144 |
|
|
process(CLK, RESET)
|
145 |
|
|
begin
|
146 |
|
|
if RESET = '1' then
|
147 |
|
|
DO_DV <= '0';
|
148 |
|
|
elsif CLK = '1' AND CLK'event then
|
149 |
|
|
DO_DV <= tree_vld;
|
150 |
|
|
end if;
|
151 |
|
|
end process;
|
152 |
|
|
|
153 |
|
|
process(CLK, RESET)
|
154 |
|
|
begin
|
155 |
|
|
if RESET = '1' then
|
156 |
|
|
do_reg <= (others => '0');
|
157 |
|
|
elsif CLK = '1' AND CLK'event then
|
158 |
|
|
do_reg <= crctab_tree_do;
|
159 |
|
|
end if;
|
160 |
|
|
end process;
|
161 |
|
|
|
162 |
|
|
|
163 |
|
|
-- register reg_mask -------------------------------------------------
|
164 |
|
|
reg_maskp: process(RESET, CLK)
|
165 |
|
|
begin
|
166 |
|
|
if (RESET = '1') then
|
167 |
|
|
reg_mask <= (others => '0');
|
168 |
|
|
elsif (CLK'event AND CLK = '1') then
|
169 |
|
|
reg_mask <= MASK;
|
170 |
|
|
end if;
|
171 |
|
|
end process;
|
172 |
|
|
|
173 |
|
|
|
174 |
|
|
-- mx_di multiplexor - handles special situation when MASK > DATA_WIDTH/8 - 4
|
175 |
|
|
mx_di <= X"00" & DI(23 downto 0) when MASK = conv_std_logic_vector(DATA_WIDTH/8-3,MW) else
|
176 |
|
|
X"0000" & DI(15 downto 0) when MASK = conv_std_logic_vector(DATA_WIDTH/8-2,MW) else
|
177 |
|
|
X"000000" & DI( 7 downto 0) when MASK = conv_std_logic_vector(DATA_WIDTH/8-1,MW) else
|
178 |
|
|
DI(31 downto 0);
|
179 |
|
|
|
180 |
|
|
reg_low_data <= crctab_do XOR reg_di(31 downto 0) when (tctl = '0') else
|
181 |
|
|
NOT reg_di(31 downto 0);
|
182 |
|
|
|
183 |
|
|
reg_low <= reg_low_data;
|
184 |
|
|
|
185 |
|
|
CRC <= NOT (do_reg(7 downto 0) & do_reg(15 downto 8) & do_reg(23 downto 16)
|
186 |
|
|
& do_reg(31 downto 24));
|
187 |
|
|
|
188 |
|
|
end architecture;
|