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
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
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
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
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.
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).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.
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.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.
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.
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 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?
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?