0
votes

I want to calculate crc32 for the ethernet packet and check if I had received correct data. I want to implement crc as a System Verilog function. I will use online crc value generator to get the code in verilog to calculate crc32 with data width 8 bits. I have the following questions:

  1. In case, of Ethernet 802.3 standard, I believe crc is calculated for data, where data = {destination address, source address, length and payload}. Correct me, if I am missing something in the data.

  2. Theoretically, data is appended with (polynomial_length-1) number of zeros, do I have to append similarly before sending the data message as input to the crc32 function?

  3. Once crc is calculated, now I have to know if my data received is correct. So, do I have to pass the data along with calculated crc value as input to the crc32 function again, to check if I get zeros as function output, so as to ensure I have received correct data, is this correct? If not tell me how to check if I had received correct data. Thanks in advance.

Below is the SV version of crc32 function, which I intend to use.

function nextCRC32_D8(byte unsigned data[]);
 bit [7:0] d;
 bit [31:0] newcrc, crc,c;
 int i;
 crc=0;

for (i=0; i<data.size(); i++) begin
        d = data[i];
        c = crc;

newcrc[0] = d[6] ^ d[0] ^ c[24] ^ c[30];
newcrc[1] = d[7] ^ d[6] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[30] ^ c[31];
newcrc[2] = d[7] ^ d[6] ^ d[2] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[26] ^ c[30] ^ c[31];
newcrc[3] = d[7] ^ d[3] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[27] ^ c[31];
newcrc[4] = d[6] ^ d[4] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[28] ^ c[30];
newcrc[5] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28] ^ c[29] ^ c[30] ^ c[31];
newcrc[6] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30] ^ c[31];
newcrc[7] = d[7] ^ d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[29] ^ c[31];
newcrc[8] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28];
newcrc[9] = d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29];
newcrc[10] = d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[2] ^ c[24] ^ c[26] ^ c[27] ^ c[29];
newcrc[11] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[3] ^ c[24] ^ c[25] ^ c[27] ^ c[28];
newcrc[12] = d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ d[0] ^ c[4] ^ c[24] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30];
newcrc[13] = d[7] ^ d[6] ^ d[5] ^ d[3] ^ d[2] ^ d[1] ^ c[5] ^ c[25] ^ c[26] ^ c[27] ^ c[29] ^ c[30] ^ c[31];
newcrc[14] = d[7] ^ d[6] ^ d[4] ^ d[3] ^ d[2] ^ c[6] ^ c[26] ^ c[27] ^ c[28] ^ c[30] ^ c[31];
newcrc[15] = d[7] ^ d[5] ^ d[4] ^ d[3] ^ c[7] ^ c[27] ^ c[28] ^ c[29] ^ c[31];
newcrc[16] = d[5] ^ d[4] ^ d[0] ^ c[8] ^ c[24] ^ c[28] ^ c[29];
newcrc[17] = d[6] ^ d[5] ^ d[1] ^ c[9] ^ c[25] ^ c[29] ^ c[30];
newcrc[18] = d[7] ^ d[6] ^ d[2] ^ c[10] ^ c[26] ^ c[30] ^ c[31];
newcrc[19] = d[7] ^ d[3] ^ c[11] ^ c[27] ^ c[31];
newcrc[20] = d[4] ^ c[12] ^ c[28];
newcrc[21] = d[5] ^ c[13] ^ c[29];
newcrc[22] = d[0] ^ c[14] ^ c[24];
newcrc[23] = d[6] ^ d[1] ^ d[0] ^ c[15] ^ c[24] ^ c[25] ^ c[30];
newcrc[24] = d[7] ^ d[2] ^ d[1] ^ c[16] ^ c[25] ^ c[26] ^ c[31];
newcrc[25] = d[3] ^ d[2] ^ c[17] ^ c[26] ^ c[27];
newcrc[26] = d[6] ^ d[4] ^ d[3] ^ d[0] ^ c[18] ^ c[24] ^ c[27] ^ c[28] ^ c[30];
newcrc[27] = d[7] ^ d[5] ^ d[4] ^ d[1] ^ c[19] ^ c[25] ^ c[28] ^ c[29] ^ c[31];
newcrc[28] = d[6] ^ d[5] ^ d[2] ^ c[20] ^ c[26] ^ c[29] ^ c[30];
newcrc[29] = d[7] ^ d[6] ^ d[3] ^ c[21] ^ c[27] ^ c[30] ^ c[31];
newcrc[30] = d[7] ^ d[4] ^ c[22] ^ c[28] ^ c[31];
newcrc[31] = d[5] ^ c[23] ^ c[29];


end
return newcrc;
endfunction
1
The answer to (3) is yes.user207421
@EJP what about (2) ?user_rak

1 Answers

4
votes
  1. Correct.
  2. CRC-32 algorithms, both in software and hardware, can be and are designed to avoid the mathematical artifact of appending zero bits to the message. I have not checked your posted code for that property.
  3. You do exactly what was done on transmission, which is to calculate the CRC on the addresses through payload (and not on the CRC itself), and then compare that to the CRC in the transmitted packet. If you like, you can instead compute all the way through the CRC and check the result against a specific "residue" value, 0xC704DD7B. It is less transparent what's going on there, but it does work.