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;