Simulating CRC32 according to IEEE Std. 802.3

A

ALuPin

Hi,

I have been googling for a while
having noticed that there is no clear answer to my following problem:

The IEEE Std. 802.3 says the following: (section 3.2.8 Frame Check
Sequence field)
Mathematically,the CRC value corresponding to a given frame is de ï¬ned by the following procedure:
a)The ï¬rst 32 bits of the frame are complemented.
...
e)The bit sequence is complemented and the result is the CRC.


I use the following CRC32-VHDL module:

-- File: PCK_CRC32_D8.vhd
-- Purpose: VHDL package containing a synthesizable CRC function
-- * polynomial: (0 1 2 4 5 7 8 10 11 12 16 22 23 26 32)
-- * data width: 8

-- Info: (e-mail address removed)

Now I want to simulate the CRC according to the IEEE standard. I have a
transmitter including the CRC32
module and a receiver including the CRC32 module.
But I have some doubts on how to perform a conform simulation.

Let's assume that the following bytes are transmitted via Ethernet(one
byte interface), they are fed into the easics- module:
byte0 = "00000000" (Integer 0)
byte1 = "00000001" (Integer 1)
....
byte255="11111111" (Integer 255)

Are the following assumptions correct ?

1. The CRC has to be initialized to
NOT ("00000011 00000010 00000001 00000000")

2. The calculated CRC has to be inverted and appended in the following
manner:
first byte appendix: NOT CRC(31 DOWNTO 24)
second byte appendix NOT CRC(23 DOWNTO 16)
third byte appendix NOT CRC(15 DOWNTO 8)
fourth byte appendix NOT CRC(7 DOWNTO 0)

3. To which value do I have to reset the "remote" CRC module ?

4. Do I have to remove the CRC32 appendix of the Ethernet packets and
replace the four bytes with "00000000" ?

I would be very thankful if you could shed some light on it.

Rgds
André
 
S

Sudhir.Singh

Hi André

I have just completed a 802.3 implementation and I think I can give you
some answers.
First of all my CRC implementation was based on the following paper "A
Symbol Based Algorithm for Hardware Implementation of CRC", R. Nair, G.
Ryan and F Farzaneh.
This implementation uses xor equations to calculate CRC.
In this case the CRC is reset to zero before commencing a new
computation.

2) The final output needs to be bit reversed and inverted i.e
for i in 31 downto 0 loop
CRC(i) <= not CRCReg(31 - i);
end loop;
3) On the receiver you pass the whole packet through the CRC generator
including the CRC.
The result in the CRC register after the last byte has gone through
is called the residue, and in the
case of 802.3 it is 0xC704DD7B if there are no errors. All you need
to do is compare the CRC register
with the residue. Note that this is not the bit reversed and
inverted value.

Hope this will help
Sudhir
 
A

ALuPin

Hi Sudhir,

thank you for detailed answer.

If I do that the manner you describe I also get that residuum when
using the easics-module (CRC-Reset Value (OTHERS => '1')).

But I wonder what the IEEE Std. 802.3 (section 3.2.8 Frame Check
Sequence field)

means when claiming
a)The ï¬rst 32 bits of the frame are complemented.

Do you have any idea ?

Rgds
André
 
A

allanherriman

Hi Sudhir,

thank you for detailed answer.

If I do that the manner you describe I also get that residuum when
using the easics-module (CRC-Reset Value (OTHERS => '1')).

But I wonder what the IEEE Std. 802.3 (section 3.2.8 Frame Check
Sequence field)

means when claiming
a)The ï¬rst 32 bits of the frame are complemented.

It means exactly what it says. You invert the first 32 bits of the
frame.

I listed a number of CRC properties in this thread:
http://groups.google.com/group/comp...4d0fc43dbc1/cf1e7d94dedc5733#cf1e7d94dedc5733
Property 3 says:
" Initialising the register to all ones is equivalent to initialising
the register to all zeros and *inverting the first N bits of the
message*."

Regards,
Allan
 
R

Reiner Huober

It means exactly what it says. You invert the first 32 bits of the

Note that you get the same results if you initialize the CRC register
with all ones and do not complement the first 32 bits, due to the
properties of the CRC algorithm.

Inverting the first 32 bits (or equivalently using a start valuie of
0xFFFFFFFF) detects erroneous 0s inside the start sequence (first 32
bits). If you initialize with 0 and have additional 0s at the
beginning, standard CRC will not detect it (CRC uses polynom division,
dividing 0 always gives 0).

Hubble.
 
A

ALuPin

Hi Allan, hi Reiner,

thank you for your responses. They have shed some light on my problem.

I have simulated the test design with respect to your considerations
and they
are correct.

Thanks again for your help.

Rgds
André
 
A

ALuPin

Hi Sudhir,
The result in the CRC register after the last byte has gone through
is called the residue, and in the
case of 802.3 it is 0xC704DD7B

Yes, the simulation shows that.

Rgds
André
 
Joined
Dec 29, 2008
Messages
3
Reaction score
0
Hi, I can get the first byte working for 8 bits input into CRC32.
However, the second byte gives me wrong CRC.
Here is what I did.
1. reverse the bit order for the 8 bits input
2. For the CRC output, 'not' and 'reverse' the bit order.
I got the first byte correct 'coz the initialization is "FFFF". Right now, I just feed the NEW CRC[31..0] directly back to C[31..0], should I modify this path before I feed it back to the C[31..0]? Thx
 
Joined
Dec 29, 2008
Messages
3
Reaction score
0
I use this website to verify my CRC
w w w.lammertbies.nl/comm/info/crc-calculation.html?crc=031c&method=hex
It shows 0x7EF51D73
But I got 0x55D84EB0

Thx.
 
Joined
Apr 14, 2009
Messages
1
Reaction score
0
CRC32 8 bit VHDL

Here is my code, if someone will need it. I have checked my results with HashCalc software and on the website mentioned above. The XOR formulas were generated on this site: ipgeniuscores.com/ipgenius.php?module=CRC_generator
I made it this way:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity crcgenerator_i8b is
Port (
RST: in STD_LOGIC;
CLK: in STD_LOGIC;
GENER_CRC: in STD_LOGIC;
TX_DATA: in STD_LOGIC_VECTOR (7 downto 0);
TXD: out STD_LOGIC_VECTOR (31 downto 0)

);
end crcgenerator_i8b;

architecture crcgenerator_i8b_arch of crcgenerator_i8b is
constant CRC_INIT_VALUE: STD_LOGIC_VECTOR (31 downto 0) := X"FFFF_FFFF";

type CRC_STATE_type is (IDLE, RUN, STOP);
signal STATE: CRC_STATE_type;
signal CRC_BUF: STD_LOGIC_VECTOR (0 to 31); --!!! Important

function COUNT_CRC (d: STD_LOGIC_VECTOR (0 to 7); --!!! Important
c: STD_LOGIC_VECTOR (31 downto 0))
return STD_LOGIC_VECTOR is
variable new_crc: STD_LOGIC_VECTOR (31 downto 0);
begin
new_crc(0) := D(6) XOR D(0) XOR C(30) XOR C(24);
new_crc(1) := D(7) XOR D(6) XOR D(1) XOR D(0) XOR C(31) XOR C(30) XOR C(25) XOR C(24);
new_crc(2) := D(7) XOR D(6) XOR D(2) XOR D(1) XOR D(0) XOR C(31) XOR C(30) XOR C(26) XOR C(25) XOR C(24);
new_crc(3) := D(7) XOR D(3) XOR D(2) XOR D(1) XOR C(31) XOR C(27) XOR C(26) XOR C(25);
new_crc(4) := D(6) XOR D(4) XOR D(3) XOR D(2) XOR D(0) XOR C(30) XOR C(28) XOR C(27) XOR C(26) XOR C(24);
new_crc(5) := D(7) XOR D(6) XOR D(5) XOR D(4) XOR D(3) XOR D(1) XOR D(0) XOR C(31) XOR C(30) XOR C(29) XOR C(28) XOR C(27) XOR C(25) XOR C(24);
new_crc(6) := D(7) XOR D(6) XOR D(5) XOR D(4) XOR D(2) XOR D(1) XOR C(31) XOR C(30) XOR C(29) XOR C(28) XOR C(26) XOR C(25);
new_crc(7) := D(7) XOR D(5) XOR D(3) XOR D(2) XOR D(0) XOR C(31) XOR C(29) XOR C(27) XOR C(26) XOR C(24);
new_crc(8) := D(4) XOR D(3) XOR D(1) XOR D(0) XOR C(28) XOR C(27) XOR C(25) XOR C(24) XOR C(0);
new_crc(9) := D(5) XOR D(4) XOR D(2) XOR D(1) XOR C(29) XOR C(28) XOR C(26) XOR C(25) XOR C(1);
new_crc(10) := D(5) XOR D(3) XOR D(2) XOR D(0) XOR C(2) XOR C(29) XOR C(27) XOR C(26) XOR C(24);
new_crc(11) := D(4) XOR D(3) XOR D(1) XOR D(0) XOR C(3) XOR C(28) XOR C(27) XOR C(25) XOR C(24);
new_crc(12) := D(6) XOR D(5) XOR D(4) XOR D(2) XOR D(1) XOR D(0) XOR C(4) XOR C(30) XOR C(29) XOR C(28) XOR C(26) XOR C(25) XOR C(24);
new_crc(13) := D(7) XOR D(6) XOR D(5) XOR D(3) XOR D(2) XOR D(1) XOR C(5) XOR C(31) XOR C(30) XOR C(29) XOR C(27) XOR C(26) XOR C(25);
new_crc(14) := D(7) XOR D(6) XOR D(4) XOR D(3) XOR D(2) XOR C(6) XOR C(31) XOR C(30) XOR C(28) XOR C(27) XOR C(26);
new_crc(15) := D(7) XOR D(5) XOR D(4) XOR D(3) XOR C(7) XOR C(31) XOR C(29) XOR C(28) XOR C(27);
new_crc(16) := D(5) XOR D(4) XOR D(0) XOR C(8) XOR C(29) XOR C(28) XOR C(24);
new_crc(17) := D(6) XOR D(5) XOR D(1) XOR C(9) XOR C(30) XOR C(29) XOR C(25);
new_crc(18) := D(7) XOR D(6) XOR D(2) XOR C(31) XOR C(30) XOR C(26) XOR C(10);
new_crc(19) := D(7) XOR D(3) XOR C(31) XOR C(27) XOR C(11);
new_crc(20) := D(4) XOR C(28) XOR C(12);
new_crc(21) := D(5) XOR C(29) XOR C(13);
new_crc(22) := D(0) XOR C(24) XOR C(14);
new_crc(23) := D(6) XOR D(1) XOR D(0) XOR C(30) XOR C(25) XOR C(24) XOR C(15);
new_crc(24) := D(7) XOR D(2) XOR D(1) XOR C(31) XOR C(26) XOR C(25) XOR C(16);
new_crc(25) := D(3) XOR D(2) XOR C(27) XOR C(26) XOR C(17);
new_crc(26) := D(6) XOR D(4) XOR D(3) XOR D(0) XOR C(30) XOR C(28) XOR C(27) XOR C(24) XOR C(18);
new_crc(27) := D(7) XOR D(5) XOR D(4) XOR D(1) XOR C(31) XOR C(29) XOR C(28) XOR C(25) XOR C(19);
new_crc(28) := D(6) XOR D(5) XOR D(2) XOR C(30) XOR C(29) XOR C(26) XOR C(20);
new_crc(29) := D(7) XOR D(6) XOR D(3) XOR C(31) XOR C(30) XOR C(27) XOR C(21);
new_crc(30) := D(7) XOR D(4) XOR C(31) XOR C(28) XOR C(22);
new_crc(31) := D(5) XOR C(29) XOR C(23);

return new_crc;
end COUNT_CRC;

begin

SELECT_STATE:process (CLK, RST)

begin
if (RST = '1') then
STATE <= IDLE;
CRC_BUF <= X"0000_0000";
elsif (CLK'event and CLK = '1') then
case STATE is
when IDLE =>
if (GENER_CRC = '1') then
STATE <= RUN;
CRC_BUF <= COUNT_CRC(TX_DATA, CRC_INIT_VALUE);
else
STATE <= IDLE;
end if;
when RUN =>
if (GENER_CRC = '1') then
STATE <= RUN;
CRC_BUF <= COUNT_CRC (TX_DATA, CRC_BUF);
else
STATE <= STOP;
end if;
when STOP =>
STATE <= IDLE;
when others => null;
end case;

end if;

end process;
TXD(31) <= not CRC_BUF(31);
TXD(30) <= not CRC_BUF(30);
TXD(29) <= not CRC_BUF(29);
TXD(28) <= not CRC_BUF(28);
TXD(27) <= not CRC_BUF(27);
TXD(26) <= not CRC_BUF(26);
TXD(25) <= not CRC_BUF(25);
TXD(24) <= not CRC_BUF(24);
TXD(23) <= not CRC_BUF(23);
TXD(22) <= not CRC_BUF(22);
TXD(21) <= not CRC_BUF(21);
TXD(20) <= not CRC_BUF(20);
TXD(19) <= not CRC_BUF(19);
TXD(18) <= not CRC_BUF(18);
TXD(17) <= not CRC_BUF(17);
TXD(16) <= not CRC_BUF(16);
TXD(15) <= not CRC_BUF(15);
TXD(14) <= not CRC_BUF(14);
TXD(13) <= not CRC_BUF(13);
TXD(12) <= not CRC_BUF(12);
TXD(11) <= not CRC_BUF(11);
TXD(10) <= not CRC_BUF(10);
TXD(9) <= not CRC_BUF(9);
TXD(8) <= not CRC_BUF(8);
TXD(7) <= not CRC_BUF(7);
TXD(6) <= not CRC_BUF(6);
TXD(5) <= not CRC_BUF(5);
TXD(4) <= not CRC_BUF(4);
TXD(3) <= not CRC_BUF(3);
TXD(2) <= not CRC_BUF(2);
TXD(1) <= not CRC_BUF(1);
TXD(0) <= not CRC_BUF(0);

end crcgenerator_i8b_arch;


library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity crcgenerator_i8b_tb is
end crcgenerator_i8b_tb;

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

architecture rtl of crcgenerator_i8b_tb is
SIGNAL clk: STD_LOGIC := '0'; -- Input clock
SIGNAL rst: STD_LOGIC; -- Asynchronous active low reset
SIGNAL GENER_CRC: STD_LOGIC; -- Assert to restart calculations
SIGNAL TX_DATA: STD_LOGIC_VECTOR(7 downto 0); -- Input byte
SIGNAL TXD: STD_LOGIC_VECTOR (31 downto 0); -- Output CRC
component crcgenerator_i8b is
Port (
RST: in STD_LOGIC;
CLK: in STD_LOGIC;
GENER_CRC: in STD_LOGIC;
TX_DATA: in STD_LOGIC_VECTOR (7 downto 0);
TXD: out STD_LOGIC_VECTOR (31 downto 0)

);
end component;

FOR U_0 : crcgenerator_i8b USE ENTITY work.crcgenerator_i8b;


begin
U_0 : crcgenerator_i8b
PORT MAP (
RST => RST,
CLK => CLK,
GENER_CRC => GENER_CRC,
TX_DATA => TX_DATA,
TXD => TXD
);
STIMULUS_CLK: CLK <= NOT CLK after 5 ns;
STIMULUS_RST: RST <= '1', '0' after 20 ns;
STIMULUS_newFrame: GENER_CRC <= '0', '1' after 25 ns;
STIMULUS_inByte: TX_DATA <= X"00", X"11" after 25 ns, X"FF" after 35 ns,
X"0F" after 45 ns, X"12" after 55 ns, X"34" after 65 ns,
X"0F" after 75 ns, X"0F" after 85 ns, X"0F" after 95 ns;
end;
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top