我正在尝试用VHDL语言实现CCITT 16真实类型(Kermit)。
以下是参数:
width=16
poly=0x1021
init=0x0000
refin=true
refout=true
xorout=0x0000
check=0x2189
residue=0x0000
name="KERMIT"
我有32位数据,想要生成16位CRC Kermit类型。我使用CRC Generator生成VHDL代码。用于生成代码的设置/参数是:
0x0000
32
x^15+x^12+x^5+1
或CCITT 16 bit XMODEM type
0x0000
以下是一个例子:
Data_in: 0x54091010
CRC value kermit: 0xBEF4
CRC value Xmodem: 0x3019
CRC generated from code: 0x980C
如果您观察到模拟波图,那么您将发现代码生成正确的XModem CRC,但由于REFIn和REFOUT对于Kermit是真的,因此反映了CRC,即0x980C
(0x3019
非反射CRC)。下一步是将其与初始值0x0000
进行异或,产生相同的CRC,即0x980C
。
数据也在最终CRC之前反映出来。
如果由于许多CRC格式而感到困惑,请告诉我是否犯了一些错误。
-- ********************************
-- Specification
-- ********************************
-- File Name : CRC16_DATA32.vhd
-- Description : CRC Engine ENTITY
-- Clock : Positive Edge
-- Reset : Active Low
-- First Serial : MSB
-- Data Bus Width : 32 bits
-- Polynomial : (0 5 12 16)
-- Date : 14-Sep-2017
-- Version : 1.0
-- ########################################################################
LIBRARY IEEE ;
USE ieee.std_logic_1164.all ;
USE ieee.std_logic_arith.all ;
USE ieee.std_logic_unsigned.all ;
ENTITY crc_gen IS
PORT(
clock : IN STD_LOGIC;
reset : IN STD_LOGIC;
data_i : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
data_valid : IN STD_LOGIC;
data_o : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
crc : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
crc_valid : OUT STD_LOGIC;
crc_c_o : out STD_LOGIC_VECTOR(15 DOWNTO 0);
crc_i_o : out STD_LOGIC_VECTOR(15 DOWNTO 0);
crc_inv_o : out STD_LOGIC_VECTOR(15 DOWNTO 0);
crc_xor_o : out STD_LOGIC_VECTOR(15 DOWNTO 0));
END crc_gen;
ARCHITECTURE behave OF crc_gen IS
function reverse_any_vector (a: in std_logic_vector)
return std_logic_vector is
variable result: std_logic_vector(a'RANGE);
alias aa: std_logic_vector(a'REVERSE_RANGE) is a;
begin
for i in aa'RANGE loop
result(i) := aa(i);
end loop;
return result;
end; -- function reverse_any_vector
function crc_xor(b: in std_logic_vector; c: in std_logic_vector)
return std_logic_vector is
variable crc_xor_c: std_logic_vector (15 downto 0);
begin
crc_xor_c := b xor c;
return crc_xor_c;
end;
SIGNAL crc_r : STD_LOGIC_VECTOR(15 DOWNTO 0);--reverse crc value
SIGNAL crc_c : STD_LOGIC_VECTOR(15 DOWNTO 0);-- computing crc value
SIGNAL crc_i : STD_LOGIC_VECTOR(15 DOWNTO 0); --initial crc value
SIGNAL crc_inv_i : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL crc_xor_i : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL data : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL clk_count : INTEGER range 0 to 3;
BEGIN
crc_c(0) <= data(31) XOR data(27) XOR data(20) XOR data(11) XOR data(4) XOR crc_i(11) XOR crc_i(4) XOR data(3) XOR crc_i(12) XOR data(9) XOR crc_i(6) XOR data(12) XOR crc_i(3) XOR data(23) XOR data(5) XOR crc_i(10) XOR data(19);
crc_c(1) <= data(30) XOR data(26) XOR data(19) XOR data(10) XOR data(3) XOR crc_i(12) XOR crc_i(5) XOR data(2) XOR crc_i(13) XOR data(8) XOR crc_i(7) XOR data(11) XOR crc_i(4) XOR data(22) XOR data(4) XOR crc_i(11) XOR data(18);
crc_c(2) <= data(29) XOR data(25) XOR data(18) XOR data(9) XOR data(2) XOR crc_i(13) XOR crc_i(6) XOR data(1) XOR crc_i(14) XOR data(7) XOR crc_i(8) XOR data(10) XOR crc_i(5) XOR data(21) XOR data(3) XOR crc_i(12) XOR data(17);
crc_c(3) <= data(28) XOR data(24) XOR data(17) XOR data(8) XOR data(1) XOR crc_i(14) XOR crc_i(7) XOR data(0) XOR crc_i(15) XOR data(6) XOR crc_i(9) XOR data(9) XOR crc_i(6) XOR data(20) XOR data(2) XOR crc_i(13) XOR data(16);
crc_c(4) <= data(27) XOR data(23) XOR data(16) XOR data(7) XOR data(0) XOR crc_i(15) XOR crc_i(8) XOR data(5) XOR crc_i(10) XOR data(8) XOR crc_i(7) XOR data(19) XOR data(1) XOR crc_i(14) XOR data(15) XOR crc_i(0);
crc_c(5) <= data(31) XOR data(26) XOR data(22) XOR data(15) XOR data(6) XOR crc_i(9) XOR crc_i(0) XOR data(7) XOR crc_i(8) XOR data(18) XOR data(0) XOR crc_i(15) XOR data(14) XOR crc_i(1) XOR data(27) XOR data(20) XOR data(11) XOR crc_i(4) XOR data(3) XOR crc_i(12) XOR data(9) XOR crc_i(6) XOR data(12) XOR crc_i(3) XOR data(23) XOR data(5) XOR crc_i(10) XOR data(19);
crc_c(6) <= data(30) XOR data(25) XOR data(21) XOR data(14) XOR data(5) XOR crc_i(10) XOR crc_i(1) XOR data(6) XOR crc_i(9) XOR data(17) XOR data(13) XOR crc_i(2) XOR data(26) XOR data(19) XOR data(10) XOR crc_i(5) XOR data(2) XOR crc_i(13) XOR data(8) XOR crc_i(7) XOR data(11) XOR crc_i(4) XOR data(22) XOR data(4) XOR crc_i(11) XOR data(18);
crc_c(7) <= data(29) XOR data(24) XOR data(20) XOR data(13) XOR data(4) XOR crc_i(11) XOR crc_i(2) XOR data(5) XOR crc_i(10) XOR data(16) XOR data(12) XOR crc_i(3) XOR data(25) XOR data(18) XOR data(9) XOR crc_i(6) XOR data(1) XOR crc_i(14) XOR data(7) XOR crc_i(8) XOR data(10) XOR crc_i(5) XOR data(21) XOR data(3) XOR crc_i(12) XOR data(17);
crc_c(8) <= data(28) XOR data(23) XOR data(19) XOR data(12) XOR data(3) XOR crc_i(12) XOR crc_i(3) XOR data(4) XOR crc_i(11) XOR data(15) XOR data(11) XOR crc_i(0) XOR crc_i(4) XOR data(24) XOR data(17) XOR data(8) XOR crc_i(7) XOR data(0) XOR crc_i(15) XOR data(6) XOR crc_i(9) XOR data(9) XOR crc_i(6) XOR data(20) XOR data(2) XOR crc_i(13) XOR data(16);
crc_c(9) <= data(27) XOR data(22) XOR data(18) XOR data(11) XOR data(2) XOR crc_i(13) XOR crc_i(4) XOR data(3) XOR crc_i(12) XOR data(14) XOR data(10) XOR crc_i(1) XOR crc_i(5) XOR data(23) XOR data(16) XOR data(7) XOR crc_i(8) XOR data(5) XOR crc_i(10) XOR data(8) XOR crc_i(7) XOR data(19) XOR data(1) XOR crc_i(14) XOR data(15) XOR crc_i(0);
crc_c(10) <= data(26) XOR data(21) XOR data(17) XOR data(10) XOR data(1) XOR crc_i(14) XOR crc_i(5) XOR data(2) XOR crc_i(13) XOR data(13) XOR data(9) XOR crc_i(2) XOR crc_i(6) XOR data(22) XOR data(15) XOR data(6) XOR crc_i(9) XOR data(4) XOR crc_i(0) XOR crc_i(11) XOR data(7) XOR crc_i(8) XOR data(18) XOR data(0) XOR crc_i(15) XOR data(14) XOR crc_i(1);
crc_c(11) <= data(25) XOR data(20) XOR data(16) XOR data(9) XOR data(0) XOR crc_i(15) XOR crc_i(6) XOR data(1) XOR crc_i(14) XOR data(12) XOR data(8) XOR crc_i(3) XOR crc_i(7) XOR data(21) XOR data(14) XOR data(5) XOR crc_i(10) XOR data(3) XOR crc_i(1) XOR crc_i(12) XOR data(6) XOR crc_i(9) XOR data(17) XOR data(13) XOR crc_i(2);
crc_c(12) <= data(31) XOR data(24) XOR data(15) XOR data(8) XOR crc_i(7) XOR data(0) XOR crc_i(15) XOR crc_i(0) XOR data(7) XOR crc_i(8) XOR data(13) XOR data(2) XOR crc_i(2) XOR crc_i(13) XOR data(16) XOR data(27) XOR data(3) XOR crc_i(12) XOR data(9) XOR crc_i(6) XOR data(23);
crc_c(13) <= data(30) XOR data(23) XOR data(14) XOR data(7) XOR crc_i(8) XOR crc_i(1) XOR data(6) XOR crc_i(9) XOR data(12) XOR data(1) XOR crc_i(3) XOR crc_i(14) XOR data(15) XOR crc_i(0) XOR data(26) XOR data(2) XOR crc_i(13) XOR data(8) XOR crc_i(7) XOR data(22);
crc_c(14) <= data(29) XOR data(22) XOR data(13) XOR data(6) XOR crc_i(9) XOR crc_i(2) XOR data(5) XOR crc_i(10) XOR data(11) XOR data(0) XOR crc_i(4) XOR crc_i(15) XOR data(14) XOR crc_i(1) XOR data(25) XOR data(1) XOR crc_i(14) XOR data(7) XOR crc_i(8) XOR data(21);
crc_c(15) <= data(28) XOR data(21) XOR data(12) XOR data(5) XOR crc_i(10) XOR crc_i(3) XOR data(4) XOR crc_i(11) XOR data(10) XOR crc_i(5) XOR data(13) XOR crc_i(2) XOR data(24) XOR data(0) XOR crc_i(15) XOR data(6) XOR crc_i(9) XOR data(20);
crc_gen_process : PROCESS(clock, reset)
BEGIN
IF(reset = '0') THEN
crc_r <= "0000000000000000" ;
crc_valid <='0';
clk_count <= 0 ;
ELSIF( clock 'EVENT AND clock = '1') THEN
if (data_valid = '1' and clk_count = 0) then
--data<=data_i;
data <= reverse_any_vector (data_i);
crc_i <= "0000000000000000" ;
crc_valid <='0';
clk_count<= clk_count+1;
elsif (data_valid = '1' and clk_count = 1) then
crc_inv_i <= reverse_any_vector (crc_c);
crc_valid <='0';
clk_count<= clk_count+1;
elsif (data_valid = '1' and clk_count = 2) then
crc_xor_i <= crc_xor (x"0000", crc_inv_i);
crc_valid <='0';
clk_count<= clk_count+1;
elsif (data_valid = '1' and clk_count = 3) then
crc_r <= crc_xor_i;
crc_valid <='1';
clk_count <= 0 ;
END IF;
END IF;
END PROCESS crc_gen_process;
data_o <= data;
crc_c_o <= crc_c;
crc_i_o <= crc_i;
crc_inv_o <= crc_inv_i;
crc_xor_o <= crc_xor_i;
crc <= crc_r;
END behave;
****************************************************************************
Simulation testbench
****************************************************************************
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY crc_check_test IS
END crc_check_test;
ARCHITECTURE behavior OF crc_check_test IS
component crc_gen
port (
clock : IN STD_LOGIC;
reset : IN STD_LOGIC;
data_i : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
data_valid : IN STD_LOGIC;
data_o : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
crc : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
crc_valid : OUT STD_LOGIC;
crc_c_o : out STD_LOGIC_VECTOR(15 DOWNTO 0);
crc_i_o : out STD_LOGIC_VECTOR(15 DOWNTO 0);
crc_inv_o : out STD_LOGIC_VECTOR(15 DOWNTO 0);
crc_xor_o : out STD_LOGIC_VECTOR(15 DOWNTO 0));
end component crc_gen;
signal clock: std_logic :='0';
signal reset: std_logic :='0';
signal data_i: std_logic_vector(31 DOWNTO 0):= x"54_09_10_10";
signal data_valid: std_logic :='0';
signal data_o: std_logic_vector(31 DOWNTO 0);
signal crc : std_logic_vector(15 DOWNTO 0);--:="0000_0000_0000_0000";
signal crc_valid : std_logic; -- :='0';
SIGNAL crc_c_o : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL crc_i_o : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL crc_inv_o : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL crc_xor_o : STD_LOGIC_VECTOR(15 DOWNTO 0);
constant clock_period : time := 20 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: crc_gen PORT MAP (
clock=>clock,
reset=>reset,
data_i=>data_i,
data_valid=>data_valid,
data_o=>data_o,
crc=>crc,
crc_valid=>crc_valid,
crc_c_o => crc_c_o,
crc_i_o => crc_i_o,
crc_inv_o => crc_inv_o,
crc_xor_o => crc_xor_o);
clock_process :process
begin
clock <= '0';
wait for clock_period/2;
clock <= '1';
wait for clock_period/2;
end process;
stop_simulation :process
begin
wait for 600 ns; --run the simulation for this duration
assert false
report "simulation ended"
severity failure;
end process ;
-- Applying inputs to the entity under test
stim_proc: process
begin
reset <= '0'; data_valid <= '0'; wait for 100 ns;
reset <= '1'; data_valid <= '1'; wait for 300 ns;
reset <= '1'; data_valid <= '0'; wait for 100 ns;
wait;
end process;
END;