VHDL中的并行CRC CCITT 16 Kermit

时间:2017-09-18 20:27:11

标签: vhdl fpga xilinx modelsim crc16

我正在尝试用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代码。用于生成代码的设置/参数是:

  1. 时钟正边沿触发
  2. 重置为低有效,初始值为0x0000
  3. 输入寄存器的第一位是LSB,因为Kermit具有Refin true
  4. 数据总线宽度32
  5. Poly x^15+x^12+x^5+1CCITT 16 bit XMODEM type
  6. 初始值0x0000
  7. 以下是一个例子:

    Data_in:                 0x54091010
    CRC value kermit:        0xBEF4
    CRC value Xmodem:        0x3019
    CRC generated from code: 0x980C
    

    以下是Modelsim的模拟: simulation waveform (点击放大)

    如果您观察到模拟波图,那么您将发现代码生成正确的XModem CRC,但由于REFIn和REFOUT对于Kermit是真的,因此反映了CRC,即0x980C0x3019非反射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;
    

0 个答案:

没有答案