CRC Generator(sender) and Checker(receiver) - parallel implementation VHDL

5.2k views Asked by At

I have generated CRC generator VHDL code for parallel realization from the following website Sigmatone.

The polynomial is 100011101 (0x1D) and data width is 16 bits.

Here is the code:

-- ########################################################################
-- CRC Engine RTL Design 
-- Copyright (C) www.ElectronicDesignworks.com 
-- Source code generated by ElectronicDesignworks IP Generator (CRC).
-- Documentation can be downloaded from www.ElectronicDesignworks.com 
-- ******************************** 
--            License     
-- ******************************** 
-- This source file may be used and distributed freely provided that this
-- copyright notice, list of conditions and the following disclaimer is
-- not removed from the file.                    
-- Any derivative work should contain this copyright notice and associated disclaimer.                    
-- This source code file is provided "AS IS" AND WITHOUT ANY WARRANTY, 
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
-- PARTICULAR PURPOSE.
-- ********************************
--           Specification 
-- ********************************
-- File Name       : CRC8_DATA16.vhd    
-- Description     : CRC Engine ENTITY 
-- Clock           : Positive Edge 
-- Reset           : Active High
-- First Serial    : MSB 
-- Data Bus Width  : 16 bits 
-- Polynomial      : (0 2 3 4 8)                   
-- Date            : 16-Jun-2015  
-- 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; 
           soc        : IN  STD_LOGIC; 
           data       : IN  STD_LOGIC_VECTOR(15 DOWNTO 0); 
           data_valid : IN  STD_LOGIC; 
           eoc        : IN  STD_LOGIC; 
           crc        : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); 
           crc_valid  : OUT STD_LOGIC 
       );
end crc_gen; 

ARCHITECTURE behave OF crc_gen IS 

 SIGNAL crc_r          : STD_LOGIC_VECTOR(7 DOWNTO 0);
 SIGNAL crc_c          : STD_LOGIC_VECTOR(7 DOWNTO 0);
 SIGNAL crc_i          : STD_LOGIC_VECTOR(7 DOWNTO 0);
 SIGNAL crc_const      : STD_LOGIC_VECTOR(7 DOWNTO 0) := "00000000";

begin


crc_i    <= crc_const when soc = '1' else
            crc_r;

crc_c(0) <= data(0) XOR data(4) XOR data(5) XOR data(6) XOR data(13) XOR crc_i(5) XOR data(15) XOR crc_i(7) XOR data(10) XOR crc_i(2); 
crc_c(1) <= data(1) XOR data(5) XOR data(6) XOR data(7) XOR data(14) XOR crc_i(6) XOR data(11) XOR crc_i(3); 
crc_c(2) <= data(0) XOR data(2) XOR data(7) XOR data(8) XOR crc_i(0) XOR data(12) XOR crc_i(4) XOR data(4) XOR data(5) XOR data(13) XOR crc_i(5) XOR data(10) XOR crc_i(2); 
crc_c(3) <= data(0) XOR data(1) XOR data(3) XOR data(8) XOR data(9) XOR crc_i(1) XOR crc_i(0) XOR data(14) XOR crc_i(6) XOR data(11) XOR crc_i(3) XOR data(4) XOR data(15) XOR crc_i(7) XOR data(10) XOR crc_i(2); 
crc_c(4) <= data(0) XOR data(1) XOR data(2) XOR data(9) XOR crc_i(1) XOR data(12) XOR crc_i(4) XOR data(11) XOR crc_i(3) XOR data(6) XOR data(13) XOR crc_i(5); 
crc_c(5) <= data(1) XOR data(2) XOR data(3) XOR data(10) XOR crc_i(2) XOR data(13) XOR crc_i(5) XOR data(12) XOR crc_i(4) XOR data(7) XOR data(14) XOR crc_i(6); 
crc_c(6) <= data(2) XOR data(3) XOR data(4) XOR data(11) XOR crc_i(3) XOR data(14) XOR crc_i(6) XOR data(13) XOR crc_i(5) XOR data(8) XOR data(15) XOR crc_i(7) XOR crc_i(0); 
crc_c(7) <= data(3) XOR data(4) XOR data(5) XOR data(12) XOR crc_i(4) XOR data(15) XOR crc_i(7) XOR data(14) XOR crc_i(6) XOR data(9) XOR crc_i(1); 
crc_gen_process : PROCESS(clock, reset) 
BEGIN                                    
 IF(reset = '1') THEN  
    crc_r <= "00000000" ;
 ELSIF( clock 'EVENT AND clock = '1') THEN 
    IF(data_valid = '1') THEN 
         crc_r <= crc_c; 
    END IF; 
 END IF;    
END PROCESS crc_gen_process;      


crc_valid_gen : PROCESS(clock, reset) 
BEGIN                                    
 If(reset = '1') THEN 
     crc_valid <= '0'; 
 ELSIF( clock 'EVENT AND clock = '1') THEN 
    IF(data_valid = '1' AND eoc = '1') THEN 
        crc_valid <= '1'; 
    ELSE 
        crc_valid <= '0'; 
    END IF; 
 END IF;    
END PROCESS crc_valid_gen; 

crc <= crc_r;

END behave;

Now I have a message with appended CRC which will be transmitted.

But, at the receiver end I receive Data+CRC message and I need to retrieve the message by CRC detection technique. At the sender end CRC is generated by message with appended zeroes for calculation. What happens at the receiver end if I were to find the message back again?

Should I use the same algorithm but this time instead of appending zeroes, append the CRC received? Or does the algorithm change for the receiver end?

(I am using the parallel CRC calculation)

1

There are 1 answers

4
Paebbels On BEST ANSWER

There are 2 solutions:

1. Solution:
You can compute the CRC over all your input data and append zeros at the end where the CRC will be inserted. The receiver calculates the CRC with the same algorithmn over all data (payload + crc). The CRC is zero if all data is correct.

2. Solution:
You compute the CRC over all data words and append it directly after the datastream. The receiver uses the same technique and compares his CRC with the transmitted one. If they are equal, all data was transmitted correctly. (See David's comment).

Both solutions can use a seed value (CRC start value). It must be equal on both sides.

The second solution is faster and needs less buffers.