VHDL implementation of CRC encoding in CAN bus protocol
2026-04-06 07:58:29··#1
Abstract: This paper presents the implementation method and VHDL code for the serial CRC check principle proposed in the CAN protocol. To improve the generation speed of CRC codes and the efficiency of CRC checks, the parallel principle of CRC checks is introduced. Finally , the VHDL code to meet the CAN protocol requirements is given. After testing, both serial and parallel operations meet the design requirements. Keywords:CAN , CRC, serial , parallel To reduce and avoid such errors, in addition to improving hardware reliability, error detection and correction support should also be provided in data encoding. Common check codes include parity check codes, Hamming codes, and Cyclic Redundancy Check (CRC) codes. These all group the data code to be checked into k-bit groups, adding r check bits to each group to form an n-bit code, hence also called (n,k) block check codes. Among them, CRC codes can both detect and correct errors (depending on the selection of the generator polynomial). It is an efficient and reliable error detection and correction method that verifies data blocks. Due to its simple encoding and decoding, strong error correction capability, and very low false positive probability, it has been widely used in industrial measurement and control and communication systems. In the CAN protocol, to ensure the reliability of frame transmission and high error detection efficiency, it adopts the following error detection methods: bit error, stuffing error, CRC error, format error, and acknowledgment error detection. If m represents the message corruption rate, then using the above error detection methods, the probability of not detecting the corruption of a corrupted message is: Therefore, the extremely high error detection rate of the CAN bus makes it widely used in industrial control, communication, automotive, and even military fields. CRC check, as an important and effective error detection method in the CAN protocol, has a generator polynomial capable of checking up to level 7, and boasts advantages such as simple encoding and low false positive rate. 2. CRC Encoding Principle Cyclic redundancy code belongs to polynomial generation code. The encoding and decoding equipment is not very complex, and it has strong error detection (correction) capabilities. Its regularity lies in the fact that after encoding, a code group containing n bits has k information bits and r=nk check bits, which mix to form a regularity. The check bits change with the transmitted information bits. Its working principle is shown in Figure 1, where P is the input data and G is the encoding corresponding to the generator polynomial. [align=center] Fig.1 The Schematic diagram of CRC[/align] Assume the data to be transmitted is P=110, which is the information element. At this time, k=3, and the corresponding polynomial is n=7, and the lowest 4 bits are zero, so as to assemble 4 check bits. Divide by the generator polynomial g(x). The operations used in the calculation are all special modulo 2 operations. The modulo 2 addition and subtraction operation rule used to calculate the CRC code is bitwise addition and subtraction without carry and borrow. This addition and subtraction operation is actually the logical XOR operation. Addition and subtraction are equivalent, and multiplication and division operations are the same as the multiplication and division operations of ordinary algebraic expressions, which conform to the same rules. For example: . Then we have: The remainder Q=101, the transmitted data is, n=7, the first three bits of this data are the information element, and the last four bits are the CRC sequence. When the receiving end receives data, in order to perform verification, g(x) is still used to divide the polynomial corresponding to the received information. From expression (4), we can obtain: The modulo 2 sum of two identical numbers is 0, so if the received data is error-free, it should be divisible by g(x). Under this working mechanism, the above cyclic code can not only detect nk-1 independent errors, but also detect the length b 3. Hardware Implementation of CRC Encoding CRC encoding can be implemented in hardware using either a serial algorithm or a parallel algorithm. The serial algorithm, also known as a shift algorithm or bitstream algorithm, involves inputting the bitstream to be encoded bit by bit. After the bitstream input is complete, a checksum is generated, which is then sent or received immediately following the bitstream to be checked. In the parallel method, every k bits of the bitstream to be checked are input into the checksum generation circuit, resulting in a significantly higher checksum generation efficiency than the serial method. The following section describes the generator polynomial for CRC encoding in the CAN protocol. 3.1 Serial Implementation of CRC Encoding As can be seen from the encoding method of cyclic codes, cyclic code encoding can be implemented using a division circuit. The main body of the division circuit consists of multi-stage shift registers and a modulo-2 adder. Based on the decoding and error correction methods of cyclic codes, the decoder mainly consists of a divider and a buffer shift register. If there is an error in the reception, after several shifts, a "1" is output at the corresponding error bit as an error detection, and the error can be corrected by adding the error bit output from the buffer shift register modulo-2. In the CAN2.0A standard, the first 19 bits of a data frame (without a data field) are 0110001000111001000. The generator polynomial g(x) can be obtained from relevant materials. It must meet the following requirements: (1) Any bit error should result in a non-zero remainder; (2) Errors in different bits should result in different remainders; (3) When performing modulo-2 division on the remainder, the remainder should be rounded down to the current position. To obtain the CRC sequence, a 15-bit shift register CRC_RG (14:0) can be used. If the next bit of the bit stream is marked with NXTBIT, it is given by the sequence of unpadded bits from the beginning of the frame to the end of the data field. The CRC sequence is calculated as follows: CRC_RG=0 //Initialize register REPEAT CRCNXT = NXTBITE XOR CRC_RG (14); CRC_RG (14:1) = CRC_RG (13:0); //Shift register left by one bit CRC_RG (0) = 0; IF CRCNXT THEN CRC_RG (14:0) = CRC_RG (14:0) EXOR (4599H); END IF UNTIL (CRC sequence begins or an error state exists) The CRC sequence is: 000001000110101. After the last bit of the transmitted/received data field, CRC_RG contains the CRC sequence. The CRC sequence is followed by the CRC delimiter, which contains only one hidden bit (high level) 1. The VHDL program code of the serial algorithm is as follows: Library ieee; Use ieee.std_logic_1164.all; Use ieee.std_logic_unsigned.all; Use ieee.std_logic_arith.all; out std_logic_vector(14 downto 0)); End entity can_vhdl_crc; Architecture rtl of can_vhdl_crc is Type xhdl_46 is array(0 ot 7) of std_logic_vector(7 downto 0); Signal crc_next : std_logic; Signal crc_tmp : std_logic_vector(14 DOWNTO 0); Signal crc_xhdl1 : std_logic_vector (14 DOWNTO 0); begin crc <= crc_xhdl1; crc_next <= data xor crc_xhdl1 (14); crc_tmp <= crc_xhdl1 (13 downto 0) & '0' ; process (clk) begin if (clk'event and clk = '1') then if (initialize = '1') then crc_xhdl1 <= "000000000000000"; else if (enable = '1') then then if (crc_next = '1') then crc_xhdl1 <= crc_tmp xor "100010110011001"; else crc_xhdl1 <= crc_tmp ; end if; end if; end if; end if; end process; end Architecture rtl; 3.2 Parallel Calculation of CRC Encoding Currently, parallel CRC algorithms are used, including lookup table methods and some methods derived from lookup table methods. These methods all require storing a large CRC remainder table. As the parallelism increases, the length of the remainder table increases significantly (exponentially), and its practicality decreases accordingly. This algorithm pre-calculates all CRC codes of the information code P to be verified and stores them in a table. During encoding, it only needs to find the corresponding value from the table according to P and process it. Its hardware implementation block diagram is shown in Figure 2. The CRC register is cleared before encoding and decoding. During encoding, after the information code P is input, the value of the CRC register is the check code Q; during decoding and verification, after the transmission code P is input, if the value in the CRC register is zero, it indicates that the transmission is error-free. This algorithm has a fast execution speed and is suitable for high-speed communication, but because it requires a large storage table, the hardware resources consumed are much larger than those of the serial algorithm. [align=center] Fig.2 The Schematic drawing of Parallel Algorithm[/align] In order for the (n, k) code to specifically indicate the bit where the data is erroneous during transmission, the number of data bits k and the number of check bits r should satisfy Hamming's inequality: k + r < 2r - 1. For simplicity, we assume that the data code P to be transmitted is grouped into 4-bit groups (i.e., k=4), then r≥3. If the generator polynomial g(x) = x³ + x² + 1 is selected, the VHDL program for calculating Q using a parallel algorithm is as follows: library ieee; use ieee.std_logic_1164.all; entity crc_jym1 is generic(m_wide:integer:=3; r_wide:integer:=2); port(m_in:in std_logic_vector(m_wide downto 0); r_out:out std_logic_vector(r_wide downto 0)); end crc_jym1; architecture a of crc_jym1 is constant crc_wide:integer:=m_wide+r_wide+1; constant g_wide:integer:=r_wide+1; signal mm:std_logic_vector(crc_wide downto 0); constant g:std_logic_vector(g_wide downto 0):="1101"; begin process(m_in) variable d:std_logic_vector(g_wide downto 0); variable r:std_logic_vector(r_wide downto 0); begin r:=(others=>'0'); mm<=m_in&r; d:=mm(crc_wide downto(crc_wide-g_wide)); for i in(crc_wide-g_wide-1)downto 0 loop if d(g_wide)=’0’then r:=d(r_wide downto 0); else for j in r_wide downto 0 loop r(j):=d(j)xor g(j); end loop; end if; d:=r&mm(i); end loop; if d(g_wide) = '0' then r:=d(r_wide downto 0); else for j in r_wide downto 0 loop r(j):=d(j) xor g(j); end loop; end if; r_out<=r; end process; end a; 4 Summary This paper, based on the analysis of the CRC calculation principle, carefully utilizes the characteristics of VHDL to model serial and parallel CRC algorithms, thereby implementing the design. It not only possesses the advantages of formula-based design but is also well-suited for CRC encoding and decoding applications with varying data block sizes and different generator polynomial selections, significantly reducing design and development workload and greatly shortening the product development cycle. Furthermore, since the generated result occupies very few hardware resources, requiring only a small amount of remaining resources in the system integrated chip, it is even more viable in the current trend of large-scale system design and implementation moving towards single-chip integration. References [1] Wang Haiguang, Research on hardware implementation and VHDL design of parallel CRC algorithm [J]. Journal of Zhangzhou Teachers College (Natural Science Edition), No. 4, 2007 (Total No. 58), 51-56. [2] Li Yongzhong, General parallel CRC calculation principle and its hardware implementation method [J]. Journal of Northwest University for Nationalities (Natural Science Edition), Vol. 23, March 2002 (Total No. 43), 33-37. [3] Jiang Anping, Hardware parallel implementation of Cyclic Redundancy Check Code (CRC) [J]. Microelectronics & Computer, Vol. 24, No. 2, 2007, 107-109, 112.