#include <stdio.h>
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<sizeof(data); n++)
{
crc = (crc >> 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<4; n++) /* display the CRC, lower byte first */
{
printf("%02X ", crc & 0xFF);
crc >>= 8;
}
printf("\n");
return 0;
}
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) crc_out=32'h00000000;
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] ^ data1[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] ^ data1[7:4];
d_out=crc_table_adr;
#100 crc_out=(crc_out>>4)^crc_table_data;
end
end
endmodule
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) crc_out=32'h00000000;
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] ^ data1[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] ^ data1[7:4];
d_out=crc_table_adr;
#100 crc_out=(crc_out>>4)^crc_table_data;
end
end
endmodule
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
-----------------------------------------------------------------------
-- File: PCK_CRC32_D8.vhd
-- Date: Mon Oct 29 15:04:32 2007
--
-- Copyright (C) 1999-2003 Easics NV.
-- This source file may be used and distributed without restriction
-- provided that this copyright statement is not removed from the file
-- and that any derivative work contains the original copyright notice
-- and the associated disclaimer.
--
-- THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS
-- OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-- WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
--
-- 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: [email]tools@easics.be[/email]
-- [url]https://www.easics.com[/url]
-----------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
package PCK_CRC32_D8 is
-- polynomial: (0 1 2 4 5 7 8 10 11 12 16 22 23 26 32)
-- data width: 8
-- convention: the first serial data bit is D(7)
function nextCRC32_D8
( Data: std_logic_vector(7 downto 0);
CRC: std_logic_vector(31 downto 0) )
return std_logic_vector;
end PCK_CRC32_D8;
library IEEE;
use IEEE.std_logic_1164.all;
package body PCK_CRC32_D8 is
-- polynomial: (0 1 2 4 5 7 8 10 11 12 16 22 23 26 32)
-- data width: 8
-- convention: the first serial data bit is D(7)
function nextCRC32_D8
( Data: std_logic_vector(7 downto 0);
CRC: std_logic_vector(31 downto 0) )
return std_logic_vector is
variable D: std_logic_vector(7 downto 0);
variable C: std_logic_vector(31 downto 0);
variable NewCRC: std_logic_vector(31 downto 0);
begin
D := Data;
C := CRC;
NewCRC(0) := D(6) xor D(0) xor C(24) xor C(30);
NewCRC(1) := D(7) xor D(6) xor D(1) xor D(0) xor C(24) xor C(25) xor
C(30) xor C(31);
NewCRC(2) := D(7) xor D(6) xor D(2) xor D(1) xor D(0) xor C(24) xor
C(25) xor C(26) xor C(30) xor C(31);
NewCRC(3) := D(7) xor D(3) xor D(2) xor D(1) xor C(25) xor C(26) xor
C(27) xor C(31);
NewCRC(4) := D(6) xor D(4) xor D(3) xor D(2) xor D(0) xor C(24) xor
C(26) xor C(27) xor C(28) xor C(30);
NewCRC(5) := D(7) xor D(6) xor D(5) xor D(4) xor D(3) xor D(1) xor
D(0) xor C(24) xor C(25) xor C(27) xor C(28) xor C(29) xor
C(30) xor C(31);
NewCRC(6) := D(7) xor D(6) xor D(5) xor D(4) xor D(2) xor D(1) xor
C(25) xor C(26) xor C(28) xor C(29) xor C(30) xor C(31);
NewCRC(7) := D(7) xor D(5) xor D(3) xor D(2) xor D(0) xor C(24) xor
C(26) xor C(27) xor C(29) xor C(31);
NewCRC(8) := D(4) xor D(3) xor D(1) xor D(0) xor C(0) xor C(24) xor
C(25) xor C(27) xor C(28);
NewCRC(9) := D(5) xor D(4) xor D(2) xor D(1) xor C(1) xor C(25) xor
C(26) xor C(28) xor C(29);
NewCRC(10) := D(5) xor D(3) xor D(2) xor D(0) xor C(2) xor C(24) xor
C(26) xor C(27) xor C(29);
NewCRC(11) := D(4) xor D(3) xor D(1) xor D(0) xor C(3) xor C(24) xor
C(25) xor C(27) xor C(28);
NewCRC(12) := D(6) xor D(5) xor D(4) xor D(2) xor D(1) xor D(0) xor
C(4) xor C(24) xor C(25) xor C(26) xor C(28) xor C(29) xor
C(30);
NewCRC(13) := D(7) xor D(6) xor D(5) xor D(3) xor D(2) xor D(1) xor
C(5) xor C(25) xor C(26) xor C(27) xor C(29) xor C(30) xor
C(31);
NewCRC(14) := D(7) xor D(6) xor D(4) xor D(3) xor D(2) xor C(6) xor
C(26) xor C(27) xor C(28) xor C(30) xor C(31);
NewCRC(15) := D(7) xor D(5) xor D(4) xor D(3) xor C(7) xor C(27) xor
C(28) xor C(29) xor C(31);
NewCRC(16) := D(5) xor D(4) xor D(0) xor C(8) xor C(24) xor C(28) xor
C(29);
NewCRC(17) := D(6) xor D(5) xor D(1) xor C(9) xor C(25) xor C(29) xor
C(30);
NewCRC(18) := D(7) xor D(6) xor D(2) xor C(10) xor C(26) xor C(30) xor
C(31);
NewCRC(19) := D(7) xor D(3) xor C(11) xor C(27) xor C(31);
NewCRC(20) := D(4) xor C(12) xor C(28);
NewCRC(21) := D(5) xor C(13) xor C(29);
NewCRC(22) := D(0) xor C(14) xor C(24);
NewCRC(23) := D(6) xor D(1) xor D(0) xor C(15) xor C(24) xor C(25) xor
C(30);
NewCRC(24) := D(7) xor D(2) xor D(1) xor C(16) xor C(25) xor C(26) xor
C(31);
NewCRC(25) := D(3) xor D(2) xor C(17) xor C(26) xor C(27);
NewCRC(26) := D(6) xor D(4) xor D(3) xor D(0) xor C(18) xor C(24) xor
C(27) xor C(28) xor C(30);
NewCRC(27) := D(7) xor D(5) xor D(4) xor D(1) xor C(19) xor C(25) xor
C(28) xor C(29) xor C(31);
NewCRC(28) := D(6) xor D(5) xor D(2) xor C(20) xor C(26) xor C(29) xor
C(30);
NewCRC(29) := D(7) xor D(6) xor D(3) xor C(21) xor C(27) xor C(30) xor
C(31);
NewCRC(30) := D(7) xor D(4) xor C(22) xor C(28) xor C(31);
NewCRC(31) := D(5) xor C(23) xor C(29);
return NewCRC;
end nextCRC32_D8;
end PCK_CRC32_D8;
process(clk_i)
variable i_nextCRC32_D8 : std_logic_vector(31 downto 0);
begin
if rising_edge(clk_i) then
if rst_i = '1' then
i_crc <= (others=>'1');
match_o <= '0';
elsif clken_i = '1' then
i_nextCRC32_D8 := nextCRC32_D8(data_r, i_crc);
i_crc <= i_nextCRC32_D8;
if i_nextCRC32_D8 = 0 then
match_o <= '1';
else
match_o <= '0';
end if;
end if;
end if;
end process;
`timescale 1ns / 1ps
module cccc(clk, CRC_out);
input clk;
output [31:0] CRC_out;
reg [31:0] CRC_out;
reg[32:0] CRCPoly ;
reg[32:0] CRC,crc_temp ;
reg [7:0] j,k;
reg [15:0] temp_buf;
reg [7:0] Inbuff[90:0];
reg first_time;
always @(posedge clk) begin
Inbuff[0]=8'h55;
Inbuff[1]=8'h55;
Inbuff[2]=8'h55;
Inbuff[3]=8'h55;
Inbuff[4]=8'h55;
Inbuff[5]=8'h55;
Inbuff[6]=8'h55;
Inbuff[7]=8'hD5;
Inbuff[8]=8'h00;//not inverted FF
Inbuff[9]=8'h0A; // not inveted AF
Inbuff[10]=8'hE6; //~ inverterd 98
Inbuff[11]=8'hF0;//~ inverted F0
Inbuff[12]=8'h05;
Inbuff[13]=8'hA3;
Inbuff[14]=8'h00;
Inbuff[15]=8'h12;
Inbuff[16]=8'h34;
Inbuff[17]=8'h56;
Inbuff[18]=8'h78;
Inbuff[19]=8'h90;
Inbuff[20]=8'h08;
Inbuff[21]=8'h00;
Inbuff[22]=8'h45;
Inbuff[23]=8'h00;
Inbuff[24]=8'h00;
Inbuff[25]=8'h30;
Inbuff[26]=8'hB3;
Inbuff[27]=8'hFE;
Inbuff[28]=8'h00;
Inbuff[29]=8'h00;
Inbuff[30]=8'h80;
Inbuff[31]=8'h11;
Inbuff[32]=8'h72;
Inbuff[33]=8'hBA;
Inbuff[34]=8'h0A;
Inbuff[35]=8'h00;
Inbuff[36]=8'h00;
Inbuff[37]=8'h03;
Inbuff[38]=8'h0A;
Inbuff[39]=8'h00;
Inbuff[40]=8'h00;
Inbuff[41]=8'h02;
Inbuff[42]=8'h04;
Inbuff[43]=8'h00;
Inbuff[44]=8'h04;
Inbuff[45]=8'h00;
Inbuff[46]=8'h00;
Inbuff[47]=8'h1C;
Inbuff[48]=8'h89;
Inbuff[49]=8'h4D;
Inbuff[50]=8'h00;
Inbuff[51]=8'h01;
Inbuff[52]=8'h02;
Inbuff[53]=8'h03;
Inbuff[54]=8'h04;
Inbuff[55]=8'h05;
Inbuff[56]=8'h06;
Inbuff[57]=8'h07;
Inbuff[58]=8'h08;
Inbuff[59]=8'h09;
Inbuff[60]=8'h0A;
Inbuff[61]=8'h0B;
Inbuff[62]=8'h0C;
Inbuff[63]=8'h0D;
Inbuff[64]=8'h0E;
Inbuff[65]=8'h0F;
Inbuff[66]=8'h10;
Inbuff[67]=8'h11;
Inbuff[68]=8'h12;
Inbuff[69]=8'h13;
Inbuff[70]=8'h00;
Inbuff[71]=8'h00;//7AD5;
Inbuff[72]=8'h00;
Inbuff[73]=8'h00;//6BB3;
CRCPoly =33'b100000100110000010001110110110111;
CRC[32:0]=33'h0FFAF98F0; //IEEE asked to complement 32bits before putting to the CRC generator
for (j=12;j<=69;j=j+1) begin
for (k=0;k<=7;k=k+1) begin
temp_buf=Inbuff[j];
CRC={CRC[32:1],temp_buf[k]}; //LSB put to the crc gen first
if(CRC[32]==1'b1) CRC = CRC ^ CRCPoly;
end
end
CRC_out=~CRC[31:0];
end
endmodule
module top (clk, crc, ready);
input clk;
reg [7:0] data [0:69];
reg [6:0] addr = 8;
wire [31:0] crc1, crc2;
output reg [31:0] crc = 0;
output reg ready = 0;
initial begin
data[0]=8'h55; data[1]=8'h55; data[2]=8'h55; data[3]=8'h55;
data[4]=8'h55; data[5]=8'h55; data[6]=8'h55; data[7]=8'hD5;
data[8]=8'h00; data[9]=8'h0A; data[10]=8'hE6; data[11]=8'hF0;
data[12]=8'h05; data[13]=8'hA3; data[14]=8'h00; data[15]=8'h12;
data[16]=8'h34; data[17]=8'h56; data[18]=8'h78; data[19]=8'h90;
data[20]=8'h08; data[21]=8'h00; data[22]=8'h45; data[23]=8'h00;
data[24]=8'h00; data[25]=8'h30; data[26]=8'hB3; data[27]=8'hFE;
data[28]=8'h00; data[29]=8'h00; data[30]=8'h80; data[31]=8'h11;
data[32]=8'h72; data[33]=8'hBA; data[34]=8'h0A; data[35]=8'h00;
data[36]=8'h00; data[37]=8'h03; data[38]=8'h0A; data[39]=8'h00;
data[40]=8'h00; data[41]=8'h02; data[42]=8'h04; data[43]=8'h00;
data[44]=8'h04; data[45]=8'h00; data[46]=8'h00; data[47]=8'h1C;
data[48]=8'h89; data[49]=8'h4D; data[50]=8'h00; data[51]=8'h01;
data[52]=8'h02; data[53]=8'h03; data[54]=8'h04; data[55]=8'h05;
data[56]=8'h06; data[57]=8'h07; data[58]=8'h08; data[59]=8'h09;
data[60]=8'h0A; data[61]=8'h0B; data[62]=8'h0C; data[63]=8'h0D;
data[64]=8'h0E; data[65]=8'h0F; data[66]=8'h10; data[67]=8'h11;
data[68]=8'h12; data[69]=8'h13;
end
function [31:0] crc_table;
input [3:0] addr;
case (addr)
0: crc_table = 32'h4DBDF21C;
1: crc_table = 32'h500AE278;
2: crc_table = 32'h76D3D2D4;
3: crc_table = 32'h6B64C2B0;
4: crc_table = 32'h3B61B38C;
5: crc_table = 32'h26D6A3E8;
6: crc_table = 32'h000F9344;
7: crc_table = 32'h1DB88320;
8: crc_table = 32'hA005713C;
9: crc_table = 32'hBDB26158;
10: crc_table = 32'h9B6B51F4;
11: crc_table = 32'h86DC4190;
12: crc_table = 32'hD6D930AC;
13: crc_table = 32'hCB6E20C8;
14: crc_table = 32'hEDB71064;
15: crc_table = 32'hF0000000;
default: crc_table = 32'bx;
endcase
endfunction
assign crc1 = crc[31:4] ^ crc_table(crc[3:0] ^ data[addr][3:0]);
assign crc2 = crc1[31:4] ^ crc_table(crc1[3:0] ^ data[addr][7:4]);
always @ (posedge clk) begin
crc <= crc2;
addr <= addr + 1;
ready <= (addr == 69);
end
endmodule
You can find explanations and an online CRC calculator here:
On-line CRC calculation and free library
When I paste your sequence into the window and press "hex" and "calculate", it gives "0xB36BD57A" for CRC-32.
That is your wanted "frame checksum" in reverse byte order.
If you want efficient implementations in VHDL or Verilog, look here:
Easics
I now see that user "benradu" already have linked to both these sites earlier in the thread.
Anyone that is going to implement CRC in hardware (VHDL, Verilog) should NOT try to port a software implementation. An efficient hardware implementation is just a bunch of XOR gates, working on individual bits. Software can't do that efficiently, so it is normally done using tricks that are completely meaningless for a hardware implementation. You will only get confused if you start with a software implementation. Look at the code generated by the easics page and you will understand how it should be done in hardware.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?