Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] testbench display for CRC code

Status
Not open for further replies.

rrucha

Member level 3
Joined
Jul 17, 2019
Messages
66
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
675
Why Am I getting a display error for this code. I just want to see my final CRC value for a 0 data input.


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
`timescale 1ns/1ns
module CRC(CLK, RST, CRC, DATA);
input CLK, RST;
input [0:0] DATA;
output [63:0] CRC;
reg [63:0] CRC;
 
always @(posedge CLK or negedge RST) 
 if (!RST)
 CRC = 64'b1111111111111111111111111111111111111111111111111111111111111111 ;
 else begin
  CRC[63] <= CRC[62] ;
  CRC[62] <= CRC[63] ^ CRC[61] ^ DATA[0] ;
  CRC[61] <= CRC[60] ;
  CRC[60] <= CRC[59] ;
  CRC[59] <= CRC[58] ;
  CRC[58] <= CRC[57] ;
  CRC[57] <= CRC[61] ^ CRC[56] ^ DATA[0] ;
  CRC[56] <= CRC[55] ;
  CRC[55] <= CRC[61] ^ CRC[54] ^ DATA[0] ;
  CRC[54] <= CRC[61] ^ CRC[53] ^ DATA[0] ;
  CRC[53] <= CRC[61] ^ CRC[52] ^ DATA[0] ;
  CRC[52] <= CRC[61] ^ CRC[51] ^ DATA[0] ;
  CRC[51] <= CRC[50] ;
  CRC[50] <= CRC[49] ;
  CRC[49] <= CRC[48] ;
  CRC[48] <= CRC[47] ;
  CRC[47] <= CRC[61] ^ CRC[46] ^ DATA[0] ;
  CRC[46] <= CRC[61] ^ CRC[45] ^ DATA[0] ;
  CRC[45] <= CRC[61] ^ CRC[44] ^ DATA[0] ;
  CRC[44] <= CRC[43] ;
  CRC[43] <= CRC[42] ;
  CRC[42] <= CRC[41] ;
  CRC[41] <= CRC[40] ;
  CRC[40] <= CRC[61] ^ CRC[39] ^ DATA[0] ;
  CRC[39] <= CRC[61] ^ CRC[38] ^ DATA[0] ;
  CRC[38] <= CRC[61] ^ CRC[37] ^ DATA[0] ;
  CRC[37] <= CRC[61] ^ CRC[36] ^ DATA[0] ;
  CRC[36] <= CRC[35] ;
  CRC[35] <= CRC[61] ^ CRC[34] ^ DATA[0] ;
  CRC[34] <= CRC[33] ;
  CRC[33] <= CRC[61] ^ CRC[32] ^ DATA[0] ;
  CRC[32] <= CRC[61] ^ CRC[31] ^ DATA[0] ;
  CRC[31] <= CRC[61] ^ CRC[30] ^ DATA[0] ;
  CRC[30] <= CRC[29] ;
  CRC[29] <= CRC[61] ^ CRC[28] ^ DATA[0] ;
  CRC[28] <= CRC[27] ;
  CRC[27] <= CRC[61] ^ CRC[26] ^ DATA[0] ;
  CRC[26] <= CRC[25] ;
  CRC[25] <= CRC[24] ;
  CRC[24] <= CRC[61] ^ CRC[23] ^ DATA[0] ;
  CRC[23] <= CRC[61] ^ CRC[22] ^ DATA[0] ;
  CRC[22] <= CRC[61] ^ CRC[21] ^ DATA[0] ;
  CRC[21] <= CRC[61] ^ CRC[20] ^ DATA[0] ;
  CRC[20] <= CRC[19] ;
  CRC[19] <= CRC[61] ^ CRC[18] ^ DATA[0] ;
  CRC[18] <= CRC[17] ;
  CRC[17] <= CRC[61] ^ CRC[16] ^ DATA[0] ;
  CRC[16] <= CRC[15] ;
  CRC[15] <= CRC[14] ;
  CRC[14] <= CRC[13] ;
  CRC[13] <= CRC[61] ^ CRC[12] ^ DATA[0] ;
  CRC[12] <= CRC[61] ^ CRC[11] ^ DATA[0] ;
  CRC[11] <= CRC[10] ;
  CRC[10] <= CRC[61] ^ CRC[9] ^ DATA[0] ;
  CRC[9] <= CRC[61] ^ CRC[8] ^ DATA[0] ;
  CRC[8] <= CRC[7] ;
  CRC[7] <= CRC[61] ^ CRC[6] ^ DATA[0] ;
  CRC[6] <= CRC[5] ;
  CRC[5] <= CRC[4] ;
  CRC[4] <= CRC[61] ^ CRC[3] ^ DATA[0] ;
  CRC[3] <= CRC[2] ;
  CRC[2] <= CRC[1] ;
  CRC[1] <= CRC[61] ^ CRC[0] ^ DATA[0] ;
  CRC[0] <= CRC[61] ^ DATA[0] ;
end
endmodule




Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
module tb ();
    reg CLK=1;
    reg RST=0;
    reg DATA=0;
    
    wire [63:0] CRC;
    
    //instantiating the top module 
    CRC top_module (CLK,RST,CRC,DATA);
    
    $display("%b",CLK);
    $display("%d",CRC);
    
endmodule

 
Last edited by a moderator:

Your testbench is very poorly written, it never even changes any of the signals so how do you expect anything to happen?

You don't generate a clock you don't release reset i.e. RST=0 so the UUT stays in reset forever in the testbench.

You need to learn how to write a proper testbench.
 

You should have something like this in your testbench code at a minimum.

Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
// produce a 50 MHz clock
always #10 CLK = ~CLK;
 
// produce a 100 ns long reset
initial begin
    RST = 0;
    #100;
    RST = 1;
end

 

CRC Output interpretation (serial and parallel)

I ran an auto generated CRC code and gave it an input of 0 for a period of time . The output CRC code that is generated keeps changing. I wanted to understand how the CRC gets generated and how to analyze what the final value of CRC is. Also, for the same data but with more than 1 bit, the CRC is different.

My top module and testbench are :



Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
`timescale 1ns/1ns
 
module CRC(CLK, RST, CRC, DATA);
input CLK,RST;
input [0:0] DATA;
output [63:0] CRC;
reg [63:0] CRC;
 
always @(posedge CLK or negedge RST )
if(!RST)
CRC=64'b1111111111111111111111111111111111111111111111111111111111111111 ;
else  begin
  CRC[63] <= CRC[62] ;
  CRC[62] <= CRC[63] ^ CRC[61] ^ DATA[0] ;
  CRC[61] <= CRC[60] ;
  CRC[60] <= CRC[59] ;
  CRC[59] <= CRC[58] ;
  CRC[58] <= CRC[57] ;
  CRC[57] <= CRC[61] ^ CRC[56] ^ DATA[0] ;
  CRC[56] <= CRC[55] ;
  CRC[55] <= CRC[61] ^ CRC[54] ^ DATA[0] ;
  CRC[54] <= CRC[61] ^ CRC[53] ^ DATA[0] ;
  CRC[53] <= CRC[61] ^ CRC[52] ^ DATA[0] ;
  CRC[52] <= CRC[61] ^ CRC[51] ^ DATA[0] ;
  CRC[51] <= CRC[50] ;
  CRC[50] <= CRC[49] ;
  CRC[49] <= CRC[48] ;
  CRC[48] <= CRC[47] ;
  CRC[47] <= CRC[61] ^ CRC[46] ^ DATA[0] ;
  CRC[46] <= CRC[61] ^ CRC[45] ^ DATA[0] ;
  CRC[45] <= CRC[61] ^ CRC[44] ^ DATA[0] ;
  CRC[44] <= CRC[43] ;
  CRC[43] <= CRC[42] ;
  CRC[42] <= CRC[41] ;
  CRC[41] <= CRC[40] ;
  CRC[40] <= CRC[61] ^ CRC[39] ^ DATA[0] ;
  CRC[39] <= CRC[61] ^ CRC[38] ^ DATA[0] ;
  CRC[38] <= CRC[61] ^ CRC[37] ^ DATA[0] ;
  CRC[37] <= CRC[61] ^ CRC[36] ^ DATA[0] ;
  CRC[36] <= CRC[35] ;
  CRC[35] <= CRC[61] ^ CRC[34] ^ DATA[0] ;
  CRC[34] <= CRC[33] ;
  CRC[33] <= CRC[61] ^ CRC[32] ^ DATA[0] ;
  CRC[32] <= CRC[61] ^ CRC[31] ^ DATA[0] ;
  CRC[31] <= CRC[61] ^ CRC[30] ^ DATA[0] ;
  CRC[30] <= CRC[29] ;
  CRC[29] <= CRC[61] ^ CRC[28] ^ DATA[0] ;
  CRC[28] <= CRC[27] ;
  CRC[27] <= CRC[61] ^ CRC[26] ^ DATA[0] ;
  CRC[26] <= CRC[25] ;
  CRC[25] <= CRC[24] ;
  CRC[24] <= CRC[61] ^ CRC[23] ^ DATA[0] ;
  CRC[23] <= CRC[61] ^ CRC[22] ^ DATA[0] ;
  CRC[22] <= CRC[61] ^ CRC[21] ^ DATA[0] ;
  CRC[21] <= CRC[61] ^ CRC[20] ^ DATA[0] ;
  CRC[20] <= CRC[19] ;
  CRC[19] <= CRC[61] ^ CRC[18] ^ DATA[0] ;
  CRC[18] <= CRC[17] ;
  CRC[17] <= CRC[61] ^ CRC[16] ^ DATA[0] ;
  CRC[16] <= CRC[15] ;
  CRC[15] <= CRC[14] ;
  CRC[14] <= CRC[13] ;
  CRC[13] <= CRC[61] ^ CRC[12] ^ DATA[0] ;
  CRC[12] <= CRC[61] ^ CRC[11] ^ DATA[0] ;
  CRC[11] <= CRC[10] ;
  CRC[10] <= CRC[61] ^ CRC[9] ^ DATA[0] ;
  CRC[9] <= CRC[61] ^ CRC[8] ^ DATA[0] ;
  CRC[8] <= CRC[7] ;
  CRC[7] <= CRC[61] ^ CRC[6] ^ DATA[0] ;
  CRC[6] <= CRC[5] ;
  CRC[5] <= CRC[4] ;
  CRC[4] <= CRC[61] ^ CRC[3] ^ DATA[0] ;
  CRC[3] <= CRC[2] ;
  CRC[2] <= CRC[1] ;
  CRC[1] <= CRC[61] ^ CRC[0] ^ DATA[0] ;
  CRC[0] <= CRC[61] ^ DATA[0] ;
end
endmodule




Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
module tb ();
    reg CLK;
    reg DATA;
    reg RST;
    wire [63:0] CRC;
    
    //instantiating the top module 
    CRC top_module (CLK,RST,CRC,DATA);
    
    always begin 
        #5 CLK = ~CLK;
    end 
    
    initial begin
    $display ("time\t CLK RST CRC");
    $monitor ("%g\t %b %b %b", $time, CLK, RST, CRC);
    CLK = 1;
    RST = 0;
    #2 RST = 1;
    #6 DATA = 0;
    #20 $finish;
    end 
    
endmodule



Final output is :

Code:
time	 CLK RST CRC
0	 1 0 1111111111111111111111111111111111111111111111111111111111111111
2	 1 1 1111111111111111111111111111111111111111111111111111111111111111
5	 0 1 1111111111111111111111111111111111111111111111111111111111111111
10	 1 1 1011110100001111000111100001010001010110000101011100100101101101
15	 0 1 1011110100001111000111100001010001010110000101011100100101101101
20	 1 1 0011100011101110110111011100001100000101110000011010010001001001
25	 0 1 0011100011101110110111011100001100000101110000011010010001001001
 
Last edited by a moderator:

I understand. I have edited my test bench now and I wanted help analyzing the output. CRC value keeps changing for the same data. Which is the actualu CRC value?
 

Your CRC will keep changing as long as it is being clocked. Doesn't matter that you keep DATA[0] the same you are just CRCing a 0 bit stream in your simulation. Perhaps you should read the wiki page on the CRC, since I'm not sure you understand how the CRC works.

If you want to check your CRC do a google search for an online CRC calculator (which there are several) and plug in your polynomial and the data you want to CRC to find out what the CRC result is.
 

Hi Ads-ee,

Thank you for your reply. Yes I got that. I see the current CRC value gets fed into it again. What i need to know is what happens in the case of parallel CRC? Does it take a certain number of clock cycles to reach the final CRC based on the number of bits in the input stream?
 

Hi Ads-ee,

Thank you for your reply. Yes I got that. I see the current CRC value gets fed into it again. What i need to know is what happens in the case of parallel CRC? Does it take a certain number of clock cycles to reach the final CRC based on the number of bits in the input stream?

I don't understand your question...the CRC code you've posted is not a parallel implementation it is a serial implementation.

If you make it a parallel implementation it's going to be a lot bigger as you have to have the code that does the n-cycles for the n-bits (parallel data) of data you are inputting.

If your question is when the output CRC value is correct for N-bits it is correct after you've shifted in all N-bits. If you keep shifting after that then you are appending whatever data is on the data[0] input.
 

Hi Ads-ee,

I have a code for the parallel implementation for the same polynomial. It is using one of the generators that we get online. The issue is, for a 256 bit data, when do I arrive at the desired CRC code? I read a lot of comments by the authors that it gets implemented in one clock regardless of the polynomial degree of data bits. Yet, for the same data, my CRC does not match for the serial and parallel implementation. Does it take a certain number of clocks to arrive at the final CRC that will match the serial implementation?

- - - Updated - - -

I don't understand your question...the CRC code you've posted is not a parallel implementation it is a serial implementation.

If you make it a parallel implementation it's going to be a lot bigger as you have to have the code that does the n-cycles for the n-bits (parallel data) of data you are inputting.

If your question is when the output CRC value is correct for N-bits it is correct after you've shifted in all N-bits. If you keep shifting after that then you are appending whatever data is on the data[0] input.

I used the online generator to generate the parallel CRC for a 256-bit data. They do not match. When I tried changing the initialization value from all F's to 0, my output CRC's match for parallel and serial. Any idea whats wrong?
 

I used the online generator to generate the parallel CRC for a 256-bit data. They do not match. When I tried changing the initialization value from all F's to 0, my output CRC's match for parallel and serial. Any idea whats wrong?
Seems you've found the problem. I figured the all F's was what you wanted to initialize to. You won't get the same CRC if you start at a different value between the two implementations (parallel, serial).

For 256-bits if the parallel implementation is clocked with a 64-bit input then it should be done after 4 clocks. The serial version should be done after 256 clocks. The results should be identical if you start with the same initialization value. The only other issue you might run into is making sure that the input bit order is correct on the parallel version.
 

Seems you've found the problem. I figured the all F's was what you wanted to initialize to. You won't get the same CRC if you start at a different value between the two implementations (parallel, serial).

For 256-bits if the parallel implementation is clocked with a 64-bit input then it should be done after 4 clocks. The serial version should be done after 256 clocks. The results should be identical if you start with the same initialization value. The only other issue you might run into is making sure that the input bit order is correct on the parallel version.

Hi,

Even though I initialize both of them to all F's, the CRC's are different. When I initialize both serial and parallel CRC to 0's, the CRC in the very first clock matches.

this doesn't abide by the explanation you gave in the second paragraph.

If I do initialize it to all F's, my serial CRC generator (64 bits CRC with 1-bit data input) will produce the correct CRC after 256 cycles and my parallel CRC generator (again a 64 bit CRC code but with a 256 bit input data) will produce the correct CRC after 4 clocks. Is that what you are saying?
 

Hi,

Even though I initialize both of them to all F's, the CRC's are different. When I initialize both serial and parallel CRC to 0's, the CRC in the very first clock matches.

this doesn't abide by the explanation you gave in the second paragraph.

If I do initialize it to all F's, my serial CRC generator (64 bits CRC with 1-bit data input) will produce the correct CRC after 256 cycles and my parallel CRC generator (again a 64 bit CRC code but with a 256 bit input data) will produce the correct CRC after 4 clocks. Is that what you are saying?
I misread your other post "I read a lot of comments by the authors that it gets implemented in one clock regardless of the polynomial degree of data bits." didn't realize this meant that the input to the CRC code was the entire 256-bit word, I thought the code was using 64-bit input data and 4 clocks would end up being the 256-bits of input data. As the parallel implementation CRCs the entire 256-bits then you only need 1 clock to get the CRC output.

Such a parallel implementation obviously won't scale well, as increasing the input data width will keep increasing the number of logic levels and hence the amount of logic required.

The result from the 1 clock cycle parallel should be the same as the final result of the serial version after 256-bits are clocked in as long as the initial CRC value is the same. If they aren't there is something wrong with one of the implementations.
 

I misread your other post "I read a lot of comments by the authors that it gets implemented in one clock regardless of the polynomial degree of data bits." didn't realize this meant that the input to the CRC code was the entire 256-bit word, I thought the code was using 64-bit input data and 4 clocks would end up being the 256-bits of input data. As the parallel implementation CRCs the entire 256-bits then you only need 1 clock to get the CRC output.

Such a parallel implementation obviously won't scale well, as increasing the input data width will keep increasing the number of logic levels and hence the amount of logic required.

The result from the 1 clock cycle parallel should be the same as the final result of the serial version after 256-bits are clocked in as long as the initial CRC value is the same. If they aren't there is something wrong with one of the implementations.

Hi,

Thanks a lot. I have been trying but still havent reached a point where the two CRC's match. But at least now I know what the point is where the match should occur. I will keep trying. Thanks for your help.
 

Yet I do not understand how the CRC matched in the very first clock when reset in both the cases initialized the CRC to 0.
 

There are several things that can go wrong with a CRC implementation.
The initial value is not as simple as it sounds.
The direct serial implementation from the mathematical equations is normally optimized, and the optimization affects the initial value.
Another common confusion is the bit order for the input data, the generated CRC, and the polynomial.
There are several combinations, and only one of them is correct.

What is your polynomial?
What tool/tools did you use to generate the implementations?
Did you generate the serial and parallel implementations with the same tool?
What is the specified initial value?
How do you know what the correct CRC is?
Do you have an example bit sequence with a known good CRC?

Even when you get both implementations correct, you must give them the same number of bits for the CRC to be identical. There is no "final value" as long as the logic is clocked.
Every clock cycle new data is clocked in and the CRC will change.
 

There are several things that can go wrong with a CRC implementation.
The initial value is not as simple as it sounds.
The direct serial implementation from the mathematical equations is normally optimized, and the optimization affects the initial value.
Another common confusion is the bit order for the input data, the generated CRC, and the polynomial.
There are several combinations, and only one of them is correct.

What is your polynomial?
What tool/tools did you use to generate the implementations?
Did you generate the serial and parallel implementations with the same tool?
What is the specified initial value?
How do you know what the correct CRC is?
Do you have an example bit sequence with a known good CRC?

Even when you get both implementations correct, you must give them the same number of bits for the CRC to be identical. There is no "final value" as long as the logic is clocked.
Every clock cycle new data is clocked in and the CRC will change.

Hi std_match,

Thank you for your reply. I am using an online generator that lets me pick the polynomial by selecting the coefficients. Its a CRC-64-ECMA protocol. Not a lot of tools are available for it but I found one.
I used the same generator for both parallel and serial implementation.
I gave both of them the same initial value of all F's.
I do not know what the correct CRC is but I assumed whats obtained in the first clock after reset in parallel implementation is the correct CRC value. (Also, when reset initialization value of CRC is made 0, both serial and parallel CRC match in the first clock after reset, so I am assuming that is the correct CRC).

No, I do not have any good CRC value. As of now, I am just giving a value of '1' to both serial and parallel implementation and just want to arrive at the same CRC after 256 clocks. Which is not the case.

I even tried to change the endianess of the input data, I tried bit swizzling of the obtained CRC. It does not work.
I could really use some help.
 

I used the same generator for both parallel and serial implementation.
I'm assuming you generated your parallel version here given that you posted in the comments section. From what I can see there doesn't seem to be any option to produce a serial version only the parallel version. Where did you get the serial version from?
 

I'm assuming you generated your parallel version here given that you posted in the comments section. From what I can see there doesn't seem to be any option to produce a serial version only the parallel version. Where did you get the serial version from?

Serial implementation is easy and the same generator can be used for generating the Verilog code by giving the data width as 1. I had to end up swizzling the CRC bits to get the correct answer. Thanks for the help.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top