📄 crc.vhd
字号:
-- crc.vhd
-- Graham McKenzie 24 Sep 2003
-- Used for calculation of CRC16-CCITT
-- Intended use is as custom instruction for Nios processor
-- When datab (0) is logic 1 =>
-- Internal CRC register is initialised with dataa value
-- When datab (0) is logic 0 =>
-- CRC calulation is updated based on input word on dataa
library ieee;
use ieee.std_logic_1164.all;
entity crc is
port (
reset : in std_logic;
clk : in std_logic;
start : in std_logic;
clk_en : in std_logic;
dataa : in std_logic_vector (31 downto 0);
datab : in std_logic_vector (31 downto 0);
result : out std_logic_vector (31 downto 0)
);
end crc;
architecture behave of crc is
subtype SHORT_WORD is std_logic_vector (15 downto 0);
signal crc_result : SHORT_WORD;
signal crc_reg_input : SHORT_WORD;
signal crc_reg : SHORT_WORD;
signal crc_word : SHORT_WORD;
signal next_crc_word : SHORT_WORD;
begin
-- Set result output
result <= "0000000000000000" & crc_reg;
-- Initialise or update CRC reg based on datab bit 0
crc_reg_input <= crc_result when datab(0) = '0' else dataa (15 downto 0);
-- CRC needs big endian data but Nios is little endian
-- Convert data here
crc_word <= dataa (7 downto 0) & dataa (15 downto 8);
next_crc_word <= dataa (23 downto 16) & dataa (31 downto 24);
-- CRC calculation
process (crc_reg, crc_word, next_crc_word)
type CRC_ARRAY_TYPE is array (0 to 16) of SHORT_WORD;
variable crc_array : CRC_ARRAY_TYPE;
begin
crc_array (16) := crc_reg;
for i in 15 downto 0 loop
crc_array (i)(0) := crc_array (i+1)(15) xor crc_word(i);
crc_array (i)(1) := crc_array (i+1)(0);
crc_array (i)(2) := crc_array (i+1)(1);
crc_array (i)(3) := crc_array (i+1)(2);
crc_array (i)(4) := crc_array (i+1)(3);
crc_array (i)(5) := crc_array (i+1)(4) xor crc_array (i)(0);
crc_array (i)(6) := crc_array (i+1)(5);
crc_array (i)(7) := crc_array (i+1)(6);
crc_array (i)(8) := crc_array (i+1)(7);
crc_array (i)(9) := crc_array (i+1)(8);
crc_array (i)(10) := crc_array (i+1)(9);
crc_array (i)(11) := crc_array (i+1)(10);
crc_array (i)(12) := crc_array (i+1)(11) xor crc_array (i)(0);
crc_array (i)(13) := crc_array (i+1)(12);
crc_array (i)(14) := crc_array (i+1)(13);
crc_array (i)(15) := crc_array (i+1)(14);
end loop;
crc_array (16) := crc_array(0);
for i in 15 downto 0 loop
crc_array (i)(0) := crc_array (i+1)(15) xor next_crc_word(i);
crc_array (i)(1) := crc_array (i+1)(0);
crc_array (i)(2) := crc_array (i+1)(1);
crc_array (i)(3) := crc_array (i+1)(2);
crc_array (i)(4) := crc_array (i+1)(3);
crc_array (i)(5) := crc_array (i+1)(4) xor crc_array (i)(0);
crc_array (i)(6) := crc_array (i+1)(5);
crc_array (i)(7) := crc_array (i+1)(6);
crc_array (i)(8) := crc_array (i+1)(7);
crc_array (i)(9) := crc_array (i+1)(8);
crc_array (i)(10) := crc_array (i+1)(9);
crc_array (i)(11) := crc_array (i+1)(10);
crc_array (i)(12) := crc_array (i+1)(11) xor crc_array (i)(0);
crc_array (i)(13) := crc_array (i+1)(12);
crc_array (i)(14) := crc_array (i+1)(13);
crc_array (i)(15) := crc_array (i+1)(14);
end loop;
crc_result <= crc_array (0);
end process;
-- CRC Register
crc_register: process (reset, clk)
begin
if reset = '1' then
crc_reg <= (others => '0');
elsif rising_edge (clk) then
if (clk_en = '1') and (start = '1') then
crc_reg <= crc_reg_input;
end if;
end if;
end process;
end behave;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -