Analysis of CRC Generator (Generator of synthesizable CRC functions)
1. 1bit serial CRC using Synthesized CRC functions
Polynomial:1 + x2 +
x5
Data bus width: 1
Let's see generated code by condition above.
///////////////////////////////////////////////////////////////////////
// File: CRC5_D1.v
// Date: Wed May 4 22:47:04 2005
//
// 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: Verilog module containing a synthesizable CRC function
// * polynomial: (0 2 5)
// * data width: 1
//
// Info: tools@easics.be
// http://www.easics.com
///////////////////////////////////////////////////////////////////////
module CRC5_D1;
// polynomial: (0 2 5)
// data width: 1
function [4:0] nextCRC5_D1;
input Data;
input [4:0] CRC;
reg [0:0] D;
reg [4:0] C;
reg [4:0] NewCRC;
begin
D[0] = Data;
C = CRC;
NewCRC[0] = D[0] ^ C[4];
NewCRC[1] = C[0];
NewCRC[2] = D[0] ^ C[1] ^ C[4];
NewCRC[3] = C[2];
NewCRC[4] = C[3];
nextCRC5_D1 = NewCRC;
end
endfunction
endmodule
Here is a general imprementation of CRC using shift register.

Since polynomial is 1 + x2 +
x5 ,
g4=0;
g3=0;
g2=1;
g1=0;
g0=1;
You see the generated code is the same as general implementation of CRC.
Here is a complete module.
///////////////////////////////////////////////////////////////////////
// File: CRC5_D1.v
// Date: Tue May 3 05:20:40 2005
//
// 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: Verilog module containing a synthesizable CRC function
// * polynomial: (0 2 5)
// * data width: 1
//
// Info: tools@easics.be
// http://www.easics.com
///////////////////////////////////////////////////////////////////////
//Add some interface May.4.2005 Tak.Sugawara
module CRC5_D1_Module #(parameter integer initial_value=-1, poly_width=5) (input clock,
input data,sync_reset,hold,
output reg [poly_width-1:0] crc);
always @(posedge clock) begin
if (sync_reset) crc <=initial_value;
else if (hold) crc <=crc;
else crc<=nextCRC5_D1(data,crc);
end
// polynomial: (0 2 5)
// data width: 1
function [4:0] nextCRC5_D1;
input Data;
input [4:0] CRC;
reg [0:0] D;
reg [4:0] C;
reg [4:0] NewCRC;
begin
D[0] = Data;
C = CRC;
NewCRC[0] = D[0] ^ C[4];
NewCRC[1] = C[0];
NewCRC[2] = D[0] ^ C[1] ^ C[4];
NewCRC[3] = C[2];
NewCRC[4] = C[3];
nextCRC5_D1 = NewCRC;
end
endfunction
endmodule
,and test bench.
module CRC5D1_test_bench;
parameter integer initial_value=-1;
parameter integer poly_width=5;
parameter integer maximum_no_of_errors=3;
parameter integer data_length=10;
reg data;
reg clock=0;
reg sync_reset=1;
reg hold=0, receiver_hold=0;
wire [poly_width-1:0] crc_sender,crc_receiver;
reg done=0;
reg error=0;
integer i,test_loops,error_counter;
wire receive_data=data^ error;
always #10 clock=~clock;
initial begin
#5;
test_loops=0;
//Test 1 Make sure no crc error occurs
repeat (100) begin
test_loops=test_loops+1;
if (test_loops%100==0) $display("Test Loops=%d",test_loops);
sync_reset=1;
@(negedge clock);
@(negedge clock);
sync_reset=0; hold=0;
for (i=0;i<data_length;i=i+1) begin
data=$random;
@(negedge clock);
end
hold=1;
for (i=0;i<poly_width;i=i+1) begin
data=crc_sender[poly_width-1-i];
@(negedge clock);
end
done=1;
if (crc_receiver !==0) $display("Miss Detectio or Programming Error");
@(negedge clock);
done=0;
end
//Make sure crc error occurs
test_loops=0;
repeat (100) begin
test_loops=test_loops+1;
if (test_loops%1000==0) $display("Test Loops=%d",test_loops);
sync_reset=1;
@(negedge clock);
@(negedge clock);
sync_reset=0; hold=0;error_counter=0;
for (i=0;i<data_length;i=i+1) begin
data=$random;
if (i==0) begin
error=1;//We add at least one error.
error_counter=error_counter+1;
end else begin//Limit maxinum no of errors
if (error_counter <maximum_no_of_errors) begin
error=$random;//$random error addition
error_counter=error_counter+1;
end
end
@(negedge clock);
end
hold=1;//Stop CRC generation in sender
for (i=0;i<poly_width;i=i+1) begin
data=crc_sender[poly_width-1-i];//CRC polynominal are sent
@(negedge clock);
end
done=1;
if (crc_receiver ==0) $display("Miss Error Detection or Programming Error Test Loops=%d",test_loops);
@(negedge clock);
done=0;
end
$finish;
end
CRC5_D1_Module #(.initial_value(initial_value),.poly_width(poly_width)) crc_sender( clock,
data,sync_reset,hold,
crc_sender);
CRC5_D1_Module #(.initial_value(initial_value),.poly_width(poly_width)) crc_receiver( clock,
receive_data,sync_reset,receiver_hold,
crc_receiver);
endmodule

2. 5bit serial CRC using Synthesized CRC functions
Polynomial:1 + x2 +
x5
Data bus width: 5
Let's see generated code by condition above
///////////////////////////////////////////////////////////////////////
// File: CRC5_D5.v
// Date: Tue May 3 09:53:42 2005
//
// 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: Verilog module containing a synthesizable CRC function
// * polynomial: (0 2 5)
// * data width: 5
//
// Info: tools@easics.be
// http://www.easics.com
///////////////////////////////////////////////////////////////////////
module CRC5_D5;
// polynomial: (0 2 5)
// data width: 5
// convention: the first serial data bit is D[4]
function [4:0] nextCRC5_D5;
input [4:0] Data;
input [4:0] CRC;
reg [4:0] D;
reg [4:0] C;
reg [4:0] NewCRC;
begin
D = Data;
C = CRC;
NewCRC[0] = D[3] ^ D[0] ^ C[0] ^ C[3];
NewCRC[1] = D[4] ^ D[1] ^ C[1] ^ C[4];
NewCRC[2] = D[3] ^ D[2] ^ D[0] ^ C[0] ^ C[2] ^ C[3];
NewCRC[3] = D[4] ^ D[3] ^ D[1] ^ C[1] ^ C[3] ^ C[4];
NewCRC[4] = D[4] ^ D[2] ^ C[2] ^ C[4];
nextCRC5_D5 = NewCRC;
end
endfunction
endmodule
Where the code come from? That is next problem.
We can define transition matrix ,the same function as 1bit serial CRC as follows.

To compile 5bit parallel, just do it by mathematica.
Clear[g0,g1,g2,g3,g4,g5,g6,g7]
a4v={D4,0,D4,0,0}
a3v={D3,0,D3,0,0}
a2v={D2,0,D2,0,0}
a1v={D1,0,D1,0,0}
a0v={D0,0,D0,0,0}
CC={c0,c1,c2,c3,c4}
mat[x_] ={{0,0,0,0,g0},
{1,0,0,0,g1},
{0,1,0,0,g2},
{0,0,1,0,g3},
{0,0,0,1,g4}}
MatrixForm[mat[x_]]
g0=1
g1=0
g2=1
g3=0
g4=0
(* Some examples *)
MatrixForm[mat[x].CC+a0v] (* 1 Degree *)
MatrixForm[mat[x].(mat[x].CC+a1v)+a0v] (* 2 Degree *)
MatrixForm[mat[x].(mat[x].(mat[x].CC+a2v)+a1v)+a0v] (* 3 Degree *)
MatrixForm[mat[x].(mat[x].(mat[x].(mat[x].CC+a3v)+a2v)+a1v)+a0v] (*
4 Degree *)
(* Solve the problem *)
MatrixForm[MatrixPower[mat[x],5].CC+
MatrixPower[mat[x],4].a4v+
MatrixPower[mat[x],3].a3v+
MatrixPower[mat[x],2].a2v+
MatrixPower[mat[x],1].a1v+a0v] (* 5 Degree *)
Then mathematica computes as follows.

You see the same code is generated by mathematica.
Here is a complete module and test bench
///////////////////////////////////////////////////////////////////////
// File: CRC5_D5.v
// Date: Tue May 3 09:53:42 2005
//
// 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: Verilog module containing a synthesizable CRC function
// * polynomial: (0 2 5)
// * data width: 5
//
// Info: tools@easics.be
// http://www.easics.com
///////////////////////////////////////////////////////////////////////
//Add interface for test May.4.2005 Tak.Sugawara
module CRC5_D5_Module #(parameter integer initial_value=-1, poly_width=5,data_width=5) (input clock,
input [data_width-1:0] data,
input sync_reset,hold,
output reg [poly_width-1:0] crc);
always @(posedge clock) begin
if (sync_reset) crc <=initial_value;
else if (hold) crc <=crc;
else crc<=nextCRC5_D5(data,crc);
end
// polynomial: (0 2 5)
// data width: 5
// convention: the first serial data bit is D[4]
function [4:0] nextCRC5_D5;
input [4:0] Data;
input [4:0] CRC;
reg [4:0] D;
reg [4:0] C;
reg [4:0] NewCRC;
begin
D = Data;
C = CRC;
NewCRC[0] = D[3] ^ D[0] ^ C[0] ^ C[3];
NewCRC[1] = D[4] ^ D[1] ^ C[1] ^ C[4];
NewCRC[2] = D[3] ^ D[2] ^ D[0] ^ C[0] ^ C[2] ^ C[3];
NewCRC[3] = D[4] ^ D[3] ^ D[1] ^ C[1] ^ C[3] ^ C[4];
NewCRC[4] = D[4] ^ D[2] ^ C[2] ^ C[4];
nextCRC5_D5 = NewCRC;
end
endfunction
endmodule
module CRC5D5_test_bench;
parameter integer initial_value=-1;
parameter integer poly_width=5;
parameter integer data_width=poly_width;
parameter integer maximum_no_of_errors=3;
parameter integer data_length=10;
reg clock=0;
reg sync_reset=1;
reg hold=0, receiver_hold=0;
wire [poly_width-1:0] crc_sender,crc_receiver;
reg done=0;
integer i,test_loops,error_counter=0;
reg error=0;
reg [data_width-1:0] data=0;
wire [data_width-1:0] receive_data=data^ error;
always #10 clock=~clock;
initial begin
#5;
test_loops=0;
//Test 1 Make sure no crc error occurs
repeat (100) begin
test_loops=test_loops+1;
if (test_loops%100==0) $display("Test Loops=%d",test_loops);
sync_reset=1;
@(negedge clock);
@(negedge clock);
sync_reset=0; hold=0;
for (i=0;i<data_length;i=i+1) begin
data=$random;
@(negedge clock);
end
hold=1;
data=crc_sender;
@(negedge clock);
done=1;
if (crc_receiver !==0) $display("Miss Detectio or Programming Error");
@(negedge clock);
done=0;
end
//Make sure crc error occurs
test_loops=0;
repeat (100) begin
test_loops=test_loops+1;
if (test_loops%1000==0) $display("Test Loops=%d",test_loops);
sync_reset=1;
@(negedge clock);
@(negedge clock);
sync_reset=0; hold=0;error_counter=0;
for (i=0;i<data_length;i=i+1) begin
data=$random;
if (i==0) begin
error=1;//We add at least one error.
error_counter=error_counter+1;
end else begin//Limit maxinum no of errors
if (error_counter <maximum_no_of_errors) begin
error=$random;//$random error addition
error_counter=error_counter+1;
end
end
@(negedge clock);
end
hold=1;//Stop CRC generation in sender
data=crc_sender;//CRC polynominal are sent
@(negedge clock);
done=1;
if (crc_receiver ==0) $display("Miss Error Detection or Programming Error Test Loops=%d",test_loops);
@(negedge clock);
done=0;
end
$finish;
end
CRC5_D5_Module #(.initial_value(initial_value),.poly_width(poly_width),.data_width(data_width)) crc_sender( clock,
data,sync_reset,hold,
crc_sender);
CRC5_D5_Module #(.initial_value(initial_value),.poly_width(poly_width),.data_width(data_width)) crc_receiver( clock,
receive_data,sync_reset,receiver_hold,
crc_receiver);
endmodule
3. 8bit serial CRC using Synthesized CRC functions
Here is an another example.
Polynomial: 1 + x1 + x2 +
x8
Data bus width: 4/8
We define transition matrix.

Here is a mathematica code.
Clear[g0,g1,g2,g3,g4,g5,g6,g7]
a7v={D7,D7,D7,0,0,0,0,0}
a6v={D6,D6,D6,0,0,0,0,0}
a5v={D5,D5,D5,0,0,0,0,0}
a4v={D4,D4,D4,0,0,0,0,0}
a3v={D3,D3,D3,0,0,0,0,0}
a2v={D2,D2,D2,0,0,0,0,0}
a1v={D1,D1,D1,0,0,0,0,0}
a0v={D0,D0,D0,0,0,0,0,0}
CC={c0,c1,c2,c3,c4,c5,c6,c7}
mat[x_] ={ {0,0,0,0,0,0,0,g0},
{1,0,0,0,0,0,0,g1},
{0,1,0,0,0,0,0,g2},
{0,0,1,0,0,0,0,g3},
{0,0,0,1,0,0,0,g4},
{0,0,0,0,1,0,0,g5},
{0,0,0,0,0,1,0,g6},
{0,0,0,0,0,0,1,g7}}
MatrixForm[mat[x_]]
g0=1
g1=1
g2=1
g3=0
g4=0
g5=0
g6=0
g7=0
(* Solve the problem degree 4*)
A4=MatrixPower[mat[x],4].CC+
MatrixPower[mat[x],3].a3v+
MatrixPower[mat[x],2].a2v+
MatrixPower[mat[x],1].a1v+a0v
(* Solve the problem dgree 8 *)
A8=MatrixPower[mat[x],8].CC+
MatrixPower[mat[x],7].a7v+
MatrixPower[mat[x],6].a6v+
MatrixPower[mat[x],5].a5v+
MatrixPower[mat[x],4].a4v+
MatrixPower[mat[x],3].a3v+
MatrixPower[mat[x],2].a2v+
MatrixPower[mat[x],1].a1v+a0v
MatrixForm[A4]
MatrixForm[A8]
MatrixForm[PolynomialMod[A8,2]] (* Reduce! *)
The result of computation of mathematica for 4 degree

The result of computation of mathematica for 8 degree

Note GF(2) addition is exor and 2 D7=> 0, 2 C7 =>0 ,

Here is a complete module and test bench for 4bits data width.
You see the same result as mathematica computation. Same program can be
written in any language, such as c++, perl,and matlab.
///////////////////////////////////////////////////////////////////////
// File: CRC8_D4.v
// Date: Wed May 4 09:56:21 2005
//
// 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: Verilog module containing a synthesizable CRC function
// * polynomial: (0 1 2 8)
// * data width: 4
//
// Info: tools@easics.be
// http://www.easics.com
///////////////////////////////////////////////////////////////////////
//Add interface for test May.4.2005 Tak.Sugawara
module CRC8_D4_Module #(parameter integer initial_value=-1, poly_width=8,data_width=4) (input clock,
input [data_width-1:0] data,
input sync_reset,hold,
output reg [poly_width-1:0] crc);
always @(posedge clock) begin
if (sync_reset) crc <=initial_value;
else if (hold) crc <=crc;
else crc<=nextCRC8_D4(data,crc);
end
// polynomial: (0 1 2 8)
// data width: 4
// convention: the first serial data bit is D[3]
function [7:0] nextCRC8_D4;
input [3:0] Data;
input [7:0] CRC;
reg [3:0] D;
reg [7:0] C;
reg [7:0] NewCRC;
begin
D = Data;
C = CRC;
NewCRC[0] = D[0] ^ C[4];
NewCRC[1] = D[1] ^ D[0] ^ C[4] ^ C[5];
NewCRC[2] = D[2] ^ D[1] ^ D[0] ^ C[4] ^ C[5] ^ C[6];
NewCRC[3] = D[3] ^ D[2] ^ D[1] ^ C[5] ^ C[6] ^ C[7];
NewCRC[4] = D[3] ^ D[2] ^ C[0] ^ C[6] ^ C[7];
NewCRC[5] = D[3] ^ C[1] ^ C[7];
NewCRC[6] = C[2];
NewCRC[7] = C[3];
nextCRC8_D4 = NewCRC;
end
endfunction
endmodule
module CRC8D4_test_bench;
parameter integer initial_value=-1;
parameter integer poly_width=8;
parameter integer data_width=poly_width/2;
parameter integer maximum_no_of_errors=6;
parameter integer data_length=10;
reg clock=0;
reg sync_reset=1;
reg hold=0, receiver_hold=0;
wire [poly_width-1:0] crc_sender,crc_receiver;
reg done=0;
integer i,test_loops,error_counter=0;
reg error=0;
reg [data_width-1:0] data=0;
wire [data_width-1:0] receive_data=data^ error;
always #10 clock=~clock;
initial begin
#5;
test_loops=0;
//Test 1 Make sure no crc error occurs
repeat (100) begin
test_loops=test_loops+1;
if (test_loops%100==0) $display("Test Loops=%d",test_loops);
sync_reset=1;
@(negedge clock);
@(negedge clock);
sync_reset=0; hold=0;
for (i=0;i<data_length;i=i+1) begin
data=$random;
@(negedge clock);
end
hold=1;
for (i=0;i<2;i=i+1) begin
data=crc_sender[poly_width-1-data_width*i -:data_width];
@(negedge clock);
end
done=1;
if (crc_receiver !==0) $display("Miss Detectio or Programming Error");
@(negedge clock);
done=0;
end
//Make sure crc error occurs
test_loops=0;
repeat (1000) begin
test_loops=test_loops+1;
if (test_loops%1000==0) $display("Test Loops=%d",test_loops);
sync_reset=1;
@(negedge clock);
@(negedge clock);
sync_reset=0; hold=0;error_counter=0;
for (i=0;i<data_length;i=i+1) begin
data=$random;
if (i==0) begin
error=1;//We add at least one error.
error_counter=error_counter+1;
end else begin//Limit maxinum no of errors
if (error_counter <maximum_no_of_errors) begin
error=$random;//$random error addition
error_counter=error_counter+1;
end
end
@(negedge clock);
end
hold=1;//Stop CRC generation in sender
for (i=0;i<2;i=i+1) begin
data=crc_sender[poly_width-1-data_width*i -:data_width];
@(negedge clock);
end
done=1;
if (crc_receiver ==0) $display("Miss Error Detection or Programming Error Test Loops=%d",test_loops);
@(negedge clock);
done=0;
end
$finish;
end
CRC8_D4_Module #(.initial_value(initial_value),.poly_width(poly_width),.data_width(data_width)) crc_sender( clock,
data,sync_reset,hold,
crc_sender);
CRC8_D4_Module #(.initial_value(initial_value),.poly_width(poly_width),.data_width(data_width)) crc_receiver( clock,
receive_data,sync_reset,receiver_hold,
crc_receiver);
endmodule
Here is a complete module and test bench for 8bits data width.
///////////////////////////////////////////////////////////////////////
// File: CRC8_D8.v
// Date: Tue May 3 12:56:07 2005
//
// 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: Verilog module containing a synthesizable CRC function
// * polynomial: (0 1 2 8)
// * data width: 8
//
// Info: tools@easics.be
// http://www.easics.com
///////////////////////////////////////////////////////////////////////
//Add interface for test May.4.2005 Tak.Sugawara
module CRC8_D8_Module #(parameter integer initial_value=-1, poly_width=8,data_width=8) (input clock,
input [data_width-1:0] data,
input sync_reset,hold,
output reg [poly_width-1:0] crc);
always @(posedge clock) begin
if (sync_reset) crc <=initial_value;
else if (hold) crc <=crc;
else crc<=nextCRC8_D8(data,crc);
end
// polynomial: (0 1 2 8)
// data width: 8
// convention: the first serial data bit is D[7]
function [7:0] nextCRC8_D8;
input [7:0] Data;
input [7:0] CRC;
reg [7:0] D;
reg [7:0] C;
reg [7:0] NewCRC;
begin
D = Data;
C = CRC;
NewCRC[0] = D[7] ^ D[6] ^ D[0] ^ C[0] ^ C[6] ^ C[7];
NewCRC[1] = D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[1] ^ C[6];
NewCRC[2] = D[6] ^ D[2] ^ D[1] ^ D[0] ^ C[0] ^ C[1] ^ C[2] ^ C[6];
NewCRC[3] = D[7] ^ D[3] ^ D[2] ^ D[1] ^ C[1] ^ C[2] ^ C[3] ^ C[7];
NewCRC[4] = D[4] ^ D[3] ^ D[2] ^ C[2] ^ C[3] ^ C[4];
NewCRC[5] = D[5] ^ D[4] ^ D[3] ^ C[3] ^ C[4] ^ C[5];
NewCRC[6] = D[6] ^ D[5] ^ D[4] ^ C[4] ^ C[5] ^ C[6];
NewCRC[7] = D[7] ^ D[6] ^ D[5] ^ C[5] ^ C[6] ^ C[7];
nextCRC8_D8 = NewCRC;
end
endfunction
endmodule
module CRC8D8_test_bench;
parameter integer initial_value=-1;
parameter integer poly_width=8;
parameter integer data_width=poly_width;
parameter integer maximum_no_of_errors=6;
parameter integer data_length=10;
reg clock=0;
reg sync_reset=1;
reg hold=0, receiver_hold=0;
wire [poly_width-1:0] crc_sender,crc_receiver;
reg done=0;
integer i,test_loops,error_counter=0;
reg error=0;
reg [data_width-1:0] data=0;
wire [data_width-1:0] receive_data=data^ error;
always #10 clock=~clock;
initial begin
#5;
test_loops=0;
//Test 1 Make sure no crc error occurs
repeat (100) begin
test_loops=test_loops+1;
if (test_loops%100==0) $display("Test Loops=%d",test_loops);
sync_reset=1;
@(negedge clock);
@(negedge clock);
sync_reset=0; hold=0;
for (i=0;i<data_length;i=i+1) begin
data=$random;
@(negedge clock);
end
hold=1;
for (i=0;i<1;i=i+1) begin
data=crc_sender[poly_width-1-data_width*i -:data_width];
@(negedge clock);
end
done=1;
if (crc_receiver !==0) $display("Miss Detectio or Programming Error");
@(negedge clock);
done=0;
end
//Make sure crc error occurs
test_loops=0;
repeat (1000) begin
test_loops=test_loops+1;
if (test_loops%1000==0) $display("Test Loops=%d",test_loops);
sync_reset=1;
@(negedge clock);
@(negedge clock);
sync_reset=0; hold=0;error_counter=0;
for (i=0;i<data_length;i=i+1) begin
data=$random;
if (i==0) begin
error=1;//We add at least one error.
error_counter=error_counter+1;
end else begin//Limit maxinum no of errors
if (error_counter <maximum_no_of_errors) begin
error=$random;//$random error addition
error_counter=error_counter+1;
end
end
@(negedge clock);
end
hold=1;//Stop CRC generation in sender
for (i=0;i<1;i=i+1) begin
data=crc_sender[poly_width-1-data_width*i -:data_width];
@(negedge clock);
end
done=1;
if (crc_receiver ==0) $display("Miss Error Detection or Programming Error Test Loops=%d",test_loops);
@(negedge clock);
done=0;
end
$finish;
end
CRC8_D8_Module #(.initial_value(initial_value),.poly_width(poly_width),.data_width(data_width)) crc_sender( clock,
data,sync_reset,hold,
crc_sender);
CRC8_D8_Module #(.initial_value(initial_value),.poly_width(poly_width),.data_width(data_width)) crc_receiver( clock,
receive_data,sync_reset,receiver_hold,
crc_receiver);
endmodule
4. Notes for implementation
Some consideration will be necessary for actual implementation.
Miss-synchronization sometimes results successive zero-codeword, which
will cause zero-CRC,means success. You can avoid this situation by initializing CRC word not zero.
Note miss-detection probability is not zero by any means of polynomial
if raw-error rate is not zero.However it is important to choose appropriate
polynomial to suppress miss-detection probability.
For example,you can easily find miss-detection error in small number of
loops if random numbers of errors are added in CRC5 . (Miss-detection should
never be happened in less than 4 errors addition since CRC5 minimum
distance is at least 4 in appropriate code length. )
module CRC5D1_test_bench;
parameter integer initial_value=-1;
parameter integer poly_width=5;
parameter integer maximum_no_of_errors=10;
