implementing ethernet FCS code in verilog

hi, i am going to use easics tool for generating crc32 verilog code (8bit input)

formatting link
. i was able to implement correctly.but i need more info to how use this crc to generate FCS of a ethernet packt.

i heard about there must be some bit reversal before applying to crc generator. but i am not clear about it .can any one guide me to what have to data stream before applying to crc and when checksum created if further processing had to be done on checksum

thanks dilan

Reply to
Dilan
Loading thread data ...

The crc you need to apply is the CRC32 AUTODIN II. This is to be applied to all bits after the frame start. In 10/100M ethernet each 4-bits is in reverse order (low nibble - high nibble). So you may need to swap these before feeding the bits to the crc32 generator.

A C example of this crc is at:

formatting link

You can use it for verification this way: cat pktdata | cksum -o 3 | perl -ne 'if( /^(\d+)/ ){ printf("%08X\n",$1); }'

A tip is to capture some packets and use them as reference to verify your crc is correct. Watch out for the order of bits coming out of the crc generator aswell, sometimes these may need swapping aswell. A quick way to find accidential bit swaps is to display the number in binrary like this: perl -e 'printf("%032b\n",2);'

Hope this helps you a bit.

Reply to
sky465nm

tahanks sky46. i try to download above c file but i borweser can locate the c file. i think some thing wrong with URL. i really appritiate if u can post a verilog code for this implemntaion.i found following c code from other forum . it seems it works correctly. but i don't know whether this is the one you mentioned as crc32 atuodin II . following is the c code //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include

int main(void) { unsigned char data[] = { 0x00, 0x0A, 0xE6, 0xF0, 0x05, 0xA3, 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0x08, 0x00, 0x45, 0x00, 0x00, 0x30, 0xB3, 0xFE, 0x00, 0x00, 0x80, 0x11, 0x72, 0xBA, 0x0A, 0x00, 0x00, 0x03, 0x0A, 0x00, 0x00, 0x02, 0x04, 0x00, 0x04, 0x00, 0x00, 0x1C, 0x89, 0x4D, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 }; unsigned int crc_table[] = { 0x4DBDF21C, 0x500AE278, 0x76D3D2D4, 0x6B64C2B0, 0x3B61B38C, 0x26D6A3E8, 0x000F9344, 0x1DB88320, 0xA005713C, 0xBDB26158, 0x9B6B51F4, 0x86DC4190, 0xD6D930AC, 0xCB6E20C8, 0xEDB71064, 0xF0000000 }; unsigned int n, crc=0;

for (n=0; n> 4) ^ crc_table[(crc ^ (data[n] >> 0)) & 0x0F]; /* lower nibble */ crc = (crc >> 4) ^ crc_table[(crc ^ (data[n] >> 4)) & 0x0F]; /* upper nibble */ } for (n=0; n>= 8; } printf("\n"); return 0; }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

it works correctly but when try to implement it on verilog it gives me wrong answer.please check the following verilog code

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// module FCS_CAL(clk,data,enable,crc_out,reset); input clk;

input [7:0] data; input enable; input reset;

output [31:0] crc_out;

reg [31:0] crc_out; reg[3:0] crc_table_adr; reg[31:0] crc_table_data;

always @(crc_table_adr) begin case (crc_table_adr) 4'h0:crc_table_data=32'h4DBDF21C; 4'h1:crc_table_data=32'h500AE278; 4'h2:crc_table_data=32'h76D3D2D4; 4'h3:crc_table_data=32'h6B64C2B0; 4'h4:crc_table_data=32'h3B61B38C; 4'h5:crc_table_data=32'h26D6A3E8; 4'h6:crc_table_data=32'h000F9344; 4'h7:crc_table_data=32'h1DB88320; 4'h8:crc_table_data=32'hA005713C; 4'h9:crc_table_data=32'hBDB26158; 4'hA:crc_table_data=32'h9B6B51F4; 4'hB:crc_table_data=32'h86DC4190; 4'hC:crc_table_data=32'hD6D930AC; 4'hD:crc_table_data=32'hCB6E20C8; 4'hE:crc_table_data=32'hEDB71064; 4'hF:crc_table_data=32'hF0000000;

endcase end

always @(posedge clk)begin if(reset==1 && enable==0) begin crc_out=32'h00000000; end

if(reset==0 && enable==1) begin //crc = (crc >> 4) ^ crc_table[(crc ^ (data[n] >> 0)) & 0x0F]; /* lower nibble */

crc_table_adr=crc_out[3:0] ^ data[3:0]; #100 crc_out=(crc_out>>4)^crc_table_data;

//crc = (crc >> 4) ^ crc_table[(crc ^ (data[n] >> 4)) & 0x0F]; /* upper nibble */

crc_table_adr=crc_out[3:0] ^ data[7:4]; #100 crc_out=(crc_out>>4)^crc_table_data; end

end endmodule ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

thanks

regards dilan

Reply to
Dilan

formatting link
or google for "This code implements the AUTODIN II polynomial used by "

Btw, capture some real packets and use them for verification.

This data:

00000000 41 42 43 44 45 46 47 48 31 32 33 34 35 36 37 38 |ABCDEFGH12345678|

Should generate the crc32 number: 3E EF 64 89 00111110111011110110010010001001

echo -n ABCDEFGH12345678 | cksum -o 3 | perl -ne 'if( /^(\d+)/ ){ printf("%08X\n",$1); }'

Reply to
sky465nm

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.