CRC(循環冗余校驗)
CRC介紹
臨時“插播”,后面有實例。
CRC(Cyclic Redundancy Check,循環冗余校驗)是數據幀傳輸中常用的一種差錯控制編碼方式,針對要發送的數據幀,使用一些特定的多項式可以計算出CRC校驗結果,CRC校驗結果和原始數據一起傳輸到接收端。
接收端在接收數據的同時按照相同的多項式對接收數據進行校驗運算,并將校驗結果和接收的結果進行對比,如果二二者相同則認為沒有發生傳輸錯誤;如果不同,則認為是發生了傳輸錯誤。
從理論上說,如果接收端計算出的CRC值與接收到的CRC值匹配,數據中仍有出錯的可能,但由于這種可能性極低,在實際應用中可以視為0,即沒有錯誤出現。
當接收端CRC不匹配時,接收端可以采取不同的措施,例如,丟棄數據包并通知對端,要求對端重新發送,或者只進行丟棄處理,通過高層協議實現數據的重傳。
串行CRC計算
計算CRC步驟如下:
選擇一個CRC算法或生成多項式,如CRC8-CCITT的生成多項式表示為(x^8+x^2+x+1);
CRC8硬件上由8個觸發器實現,整合為一個移位寄存器,稱為CRC寄存器。
計算CRC之前,CRC寄存器初始化為一個已知的值,稱為CRC初始值;這里要求確定的初始值,因為接收端的CRC校驗電路需要使用和發送端相同的初始值;
CRC寄存器初始化之后,每個時鐘都有一個數據比特輸入,與當前寄存器的值共同參與計算;CRC校驗電路中,一些寄存器的輸入直接來自前級的輸出,有的是前級的輸出與當前輸入數據進行邏輯運算的結果;
在每個周期,新的數據不斷輸入,CRC寄存器不斷更新,直到最后一個輸入比特到達;
當最后一個數據比特到達時,CRC內部所存儲的就是最后的CRC校驗結果;
正如上面提到的,CRC校驗結果的位寬取決于具體的CRC算法。例如,CRC5-USB中的CRC校驗結果為5比特,CRC8-CCITT中CCRC校驗結果為8比特;
在最后1個數據比特發出后,存儲在寄存器中的的CRC校驗結果逐比特依次輸出,直至最后一個比特。可以看岀,校驗結果緊跟在用戶數據后面輸出;
以下是CRC8-CCITT算法圖:
module CRC8_CCITT
(clk,reset,
din,
init_crc,
calc_crc,
crc_out);
input clk,reset;
input din;
input [7:0]init_crc;
input calc_crc;
output [7:0] crc_out;
parameter CRC_INIT_VALUE = 8‘hFF;
reg [7:0]crcreg,crcreg_nxt;
wire [7:0] newcrc;
wire [7:0] crc_out;
assign newcrc[0] = crcreg[7]^din;
assign newcrc[1] = (crcreg[7]^din)^crcreg[0];
assign newcrc[2] = (crcreg[7]^din)^crcreg[1];
assign newcrc[3] = crcreg[2];
assign newcrc[4] = crcreg[3];
assign newcrc[5] = crcreg[4];
assign newcrc[6] = crcreg[5];
assign newcrc[7] = crcreg[6];
always @(*)begin
if(init_crc)
crcreg_nxt = CRC_INIT_VALUE;
else if(calc_crc)
crcreg_nxt = newcrc;
else
crcreg_nxt = crcreg;
end
always @(posedge clk or negedge reset)begin
if(!reset)
crcreg = CRC_INIT_VALUE;
else
crcreg = crcreg_nxt;
end
assign crc_out = crcreg;
endmodule
測試testbench
`timescale 1ns/1ns
module testbench_CRC8_CCITT;
reg clk_tb,reset_tb;
reg din_tb;
reg init_crc_tb,calc_crc_tb;
wire [7:0] crc_out_tb;
parameter CLK_HALF_PERIOD = 5;
parameter RST_DEASSERT_DLY = 100;
initial begin
clk_tb = 1’b0;
forever begin
#CLK_HALF_PERIOD clk_tb = ~clk_tb;
end
end
initial begin
reset_tb = 1‘b0;
#RST_DEASSERT_DLY reset_tb = 1’b1;
end
initial begin
din_tb = 0;
#RST_DEASSERT_DLY;
#1 din_tb = 1;
@(posedge clk_tb);
#1 din_tb = 0;
@(posedge clk_tb);
#1 din_tb = 0;
@(posedge clk_tb);
#1 din_tb = 1;
@(posedge clk_tb);
#1 din_tb = 1;
@(posedge clk_tb);
#1 din_tb = 0;
@(posedge clk_tb);
#1 din_tb = 1;
@(posedge clk_tb);
#1 din_tb = 1;
@(posedge clk_tb);
#1 din_tb = 0;
end
initial begin
init_crc_tb = 0;
calc_crc_tb = 1;
end
CRC8_CCITT test_CRC8_CCITT
(.clk(clk_tb),.reset(reset_tb),
.din(din_tb),
.init_crc(init_crc_tb),
.calc_crc(calc_crc_tb),
.crc_out(crc_out_tb)
);
endmodule
并行CRC計算
在前一部分,我們討論了單比特輸人數據的CRC計算方法。然而,在實際應用中,數據路徑寬度通常為多比特的,并且每個時鐘周期并行數據邡會改變。
例如,對于32位寬的并行數據,我們可以通過遞歸方法推導出32比特之后CRC寄存器的值。推導出來的每個32位并行CRC寄存器的輸入值是當前輸入datain[31:0]當前CRC寄存器的值crcreg組成的函數。
這一遞歸推導過程可以在理論上進行,但十分煩瑣。Easics公司已經開發了網頁版的工具(http://www.easics.com)/(https://www.easics.com/crctool/),設計者可以根據需要得到所需的計算公式。
部分數據CRC計算
我們討論了串行數據的CRC計算,又討論了使用遞歸方法計算并行數據的CRC在并行CRC計算時,如果最后一個輸入數據中只有部分字節是有效的,那么應該怎么辦呢?本部分將進行討論。
以每個時鐘周期到達8字節的PCle x8為例,在最后一個周期,有兩種可能的情況,一種是所有8字節都是有效的,另一種是只有4字節32比特)是有效的。不攜帶有效數據的4字節由專用符號進行填充,稱為PAD,PAD不參與CRC計算。
這意味著在前期每個時鐘周期需要處理64比特數據,且需要在一個時鐘周期內計算其CRC值。在最后一個周期中,CRC計算涉及所有8字節或只有4字節。此時,可以通過兩種方式進行處理:
第一種方式是在一個計算CRC校驗值的流水線中使用兩個CRC校驗計算電路,一個對64位數據進行計算,一個對32位數據進行計算,二者結合起來計算最后的CRC結果;第二種方式中只用一組CRC寄存器,但是,對于最后輸入的并行數據,使用兩個不同的電路計算CRC內部寄存器的輸入值。這兩種方式將在后面分別介紹。
流水線方式
這種機制需要兩個CRC校驗計算電路,一個用于每次計算64比特的CRC值,一個用于每次計算32比特的CRC值。
下面是具體內容:
使用一個64比特CRC計算電路和一個32比特CRC計算電路;
64比特CRC計算電路用于計算64位數據的CRC值;
對于最后一個并行數據,如果所有的8字節都是有效字節,則CRC校驗結果由64比特CRC計算電路計算得到(32位的CRC計算電路在此次計算中沒有起作用);
如果最后一個數據中只有4字節是有效的,最終的CRC校驗結果由32比特CRC計算電路計算得到;
在倒數第二個并行數據輸入64比特CRC計算電路之后,64比特CRC計算電路中每個寄存器的輸入值(注意,不是寄存器的輸出值)被傳遞給32比特CRC計算電路,這樣,當最后一組并行數據到達時,32位CRC計算電路的寄存器中存儲的是來自于64位計算電路中前期計算的結果,該結果與當前數據一起進行32位并行計算,得到最終的校驗結果。
僅使用一組CRC寄存器
在這種電路結構中,只使用一組CRC寄存器。
下面是其相關細節:
電路中有兩個異或邏輯模塊,第一個的輸入是基于當前寄存器的值和64比特輸入數據,第二個的輸入是當前寄存器的值和32比特輸入數據;
對于前面的數據,每個時鐘周期內CRC計算電路使用64比特異或邏輯模塊的輸出結果;
對于最后一組數據,如果所有的8字節都有效,則使用64比特異或邏輯模塊的計算結果作為最后一個時鐘周期CRC寄存器的輸入;如果只有4字節有效,則使用32比特異或邏輯模塊的輸出結果作為最后一個時鐘周期CRC寄存器的輸入。
從定時特性上看,使用流水線結構的并行CRC校驗電路可以達到更高的速度,但它需要兩組CRC寄存器。第二種方式僅需要一組CRC寄存器,但是其組合邏輯部分更為復雜,路徑延遲更大,從而不利于提高處理速度。
下面是每個時鐘周期計算64比特并行數據CRC校驗結果的RTL代碼,由Easics網站上的Web工具具計算得到。我們還可以生成32比特或者所需要的任何其他位寬的CRC并行計算電路。
// Copyright 2008 Altera Corporation. All rights reserved.
// Altera products are protected under numerous U.S. and foreign patents,
// maskwork rights, copyrights and other intellectual property laws.
//
// This reference design file, and your use thereof, is subject to and governed
// by the terms and conditions of the applicable Altera Reference Design
// License Agreement (either as signed by you or found at www.altera.com)。 By
// using this reference design file, you indicate your acceptance of such terms
// and conditions between you and Altera Corporation. In the event that you do
// not agree with such terms and conditions, you may not use the reference
// design file and please promptly destroy any copies you have made.
//
// This reference design file is being provided on an “as-is” basis and as an
// accommodation and therefore all warranties, representations or guarantees of
// any kind (whether express, implied or statutory) including, without
// limitation, warranties of merchantability, non-infringement, or fitness for
// a particular purpose, are specifically disclaimed. By making this reference
// design file available, Altera expressly does not recommend, suggest or
// require that this reference design file be used in combination with any
// other product not provided by Altera.
/////////////////////////////////////////////////////////////////////////////
//
// 24 bit CRC of 64 data bits (reversed - MSB first)
// polynomial : 00328b63
// x^21 + x^20 + x^17 + x^15 + x^11 + x^9 + x^8 + x^6 + x^5 + x^1 + x^0
//
// CCCCCCCCCCCCCCCCCCCCCCCC DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
// 000000000011111111112222 0000000000111111111122222222223333333333444444444455555555556666
// 012345678901234567890123 0123456789012345678901234567890123456789012345678901234567890123
// C00 = .#.。。.#.##..##..#.###.## #..##.###.##..#.#.。。。。.#.。。。.####.#.####.#.。。.#.##..##..#.###.##
// C01 = ###.。.###.#.#.#.###..##. ##.#.##..##.#.####.。。。.##.。。.#.。.####.。.###.。.###.#.#.#.###..##.
// C02 = .###.。.###.#.#.#.###..## .##.#.##..##.#.####.。。。.##.。。.#.。.####.。.###.。.###.#.#.#.###..##
// C03 = 。.###.。.###.#.#.#.###..# 。.##.#.##..##.#.####.。。。.##.。。.#.。.####.。.###.。.###.#.#.#.###..#
// C04 = 。。.###.。.###.#.#.#.###.。 。。.##.#.##..##.#.####.。。。.##.。。.#.。.####.。.###.。.###.#.#.#.###.。
// C05 = ##..##..####.##.。。.#.#.# #..#.##.##.#.#.。。.####.#.。.########.#.。.##..##..####.##.。。.#.#.#
// C06 = 。.#..#..#.##.####.##.。.# ##.#.。。.##.##.。.#..######.。.#.。。.#.##.##..#..#..#.##.####.##.。.#
// C07 = #..#..#..#.##.####.##.。。 .##.#.。。.##.##.。.#..######.。.#.。。.#.##.##..#..#..#.##.####.##.。。
// C08 = #.。.#.#####.。。.#.#.#.### #.#.#####.。。.#..#.#..##.###..#.##.###..##.。.#.#####.。。.#.#.#.###
// C09 = #.。。.###..####.。。。.#.。。。 ##..##.。.###.。。.##.#..#..###.#.#.###..###.。。.###..####.。。。.#.。。。
// C10 = ##.。。.###..####.。。。.#.。。 .##..##.。.###.。。.##.#..#..###.#.#.###..###.。。.###..####.。。。.#.。。
// C11 = #.#.。.##.。。。。.###.###### #.#.#.。.#.#.###.#.##.#.##..##.#.####..###.#.。.##.。。。。.###.######
// C12 = ##.#.。.##.。。。。.###.##### .#.#.#.。.#.#.###.#.##.#.##..##.#.####..###.#.。.##.。。。。.###.#####
// C13 = ###.#.。.##.。。。。.###.#### 。.#.#.#.。.#.#.###.#.##.#.##..##.#.####..###.#.。.##.。。。。.###.####
// C14 = .###.#.。.##.。。。。.###.### 。。.#.#.#.。.#.#.###.#.##.#.##..##.#.####..###.#.。.##.。。。。.###.###
// C15 = .####.。.######..#.。。。。。。 #..#.。.#..###.。。.##.#.#..#.####.。。。。。。。。.####.。.######..#.。。。。。。
// C16 = 。.####.。.######..#.。。。。。 .#..#.。.#..###.。。.##.#.#..#.####.。。。。。。。。.####.。.######..#.。。。。。
// C17 = .#.###..####..###..##.## #.############..#..##.###..#.。。。。.#.####.#.###..####..###..##.##
// C18 = #.#.###..####..###..##.# .#.############..#..##.###..#.。。。。.#.####.#.###..####..###..##.#
// C19 = ##.#.###..####..###..##. 。.#.############..#..##.###..#.。。。。.#.####.#.###..####..###..##.
// C20 = #.#.#..#.#.#..#.##..#.。。 #.。.##.。.#..##.#.。.#..#..###.#.##.#.#.#.#.#.#..#.#.#..#.##..#.。。
// C21 = 。。.#.##..##..#.###.##### ##.###.##..#.#.。。。。.#.。。。.####.#.####.#.。。.#.##..##..#.###.#####
// C22 = 。。。.#.##..##..#.###.#### .##.###.##..#.#.。。。。.#.。。。.####.#.####.#.。。.#.##..##..#.###.####
// C23 = #.。。.#.##..##..#.###.### 。.##.###.##..#.#.。。。。.#.。。。.####.#.####.#.。。.#.##..##..#.###.###
//
// Number of XORs used is 24
// Total XOR inputs 1090
module crc24_dat64 (
input[23:0] crc_in,
input[63:0] dat_in,
output[23:0] crc_out
);
parameter METHOD = 1;
generate
if (METHOD == 0)
crc24_dat64_flat cc (.c(crc_in),.d(dat_in),.crc_out(crc_out));
else
crc24_dat64_factor cc (.c(crc_in),.d(dat_in),.crc_out(crc_out));
endgenerate
endmodule
module crc24_dat64_flat (c,d,crc_out);
input[23:0] c;
input[63:0] d;
output[23:0] crc_out;
wire[23:0] crc_out;
assign crc_out[0] =
c[1] ^ c[6] ^ c[8] ^ c[9] ^ c[12] ^ c[13] ^
c[16] ^ c[18] ^ c[19] ^ c[20] ^ c[22] ^ c[23] ^ d[63] ^
d[62] ^ d[60] ^ d[59] ^ d[58] ^ d[56] ^ d[53] ^ d[52] ^
d[49] ^ d[48] ^ d[46] ^ d[41] ^ d[39] ^ d[38] ^ d[37] ^
d[36] ^ d[34] ^ d[32] ^ d[31] ^ d[30] ^ d[29] ^ d[23] ^
d[16] ^ d[14] ^ d[11] ^ d[10] ^ d[8] ^ d[7] ^ d[6] ^
d[4] ^ d[3] ^ d[0];
assign crc_out[1] =
c[0] ^ c[1] ^ c[2] ^ c[6] ^ c[7] ^ c[8] ^
c[10] ^ c[12] ^ c[14] ^ c[16] ^ c[17] ^ c[18] ^ c[21] ^
c[22] ^ d[62] ^ d[61] ^ d[58] ^ d[57] ^ d[56] ^ d[54] ^
d[52] ^ d[50] ^ d[48] ^ d[47] ^ d[46] ^ d[42] ^ d[41] ^
d[40] ^ d[36] ^ d[35] ^ d[34] ^ d[33] ^ d[29] ^ d[24] ^
d[23] ^ d[17] ^ d[16] ^ d[15] ^ d[14] ^ d[12] ^ d[10] ^
d[9] ^ d[6] ^ d[5] ^ d[3] ^ d[1] ^ d[0];
assign crc_out[2] =
c[1] ^ c[2] ^ c[3] ^ c[7] ^ c[8] ^ c[9] ^
c[11] ^ c[13] ^ c[15] ^ c[17] ^ c[18] ^ c[19] ^ c[22] ^
c[23] ^ d[63] ^ d[62] ^ d[59] ^ d[58] ^ d[57] ^ d[55] ^
d[53] ^ d[51] ^ d[49] ^ d[48] ^ d[47] ^ d[43] ^ d[42] ^
d[41] ^ d[37] ^ d[36] ^ d[35] ^ d[34] ^ d[30] ^ d[25] ^
d[24] ^ d[18] ^ d[17] ^ d[16] ^ d[15] ^ d[13] ^ d[11] ^
d[10] ^ d[7] ^ d[6] ^ d[4] ^ d[2] ^ d[1];
assign crc_out[3] =
c[2] ^ c[3] ^ c[4] ^ c[8] ^ c[9] ^ c[10] ^
c[12] ^ c[14] ^ c[16] ^ c[18] ^ c[19] ^ c[20] ^ c[23] ^
d[63] ^ d[60] ^ d[59] ^ d[58] ^ d[56] ^ d[54] ^ d[52] ^
d[50] ^ d[49] ^ d[48] ^ d[44] ^ d[43] ^ d[42] ^ d[38] ^
d[37] ^ d[36] ^ d[35] ^ d[31] ^ d[26] ^ d[25] ^ d[19] ^
d[18] ^ d[17] ^ d[16] ^ d[14] ^ d[12] ^ d[11] ^ d[8] ^
d[7] ^ d[5] ^ d[3] ^ d[2];
assign crc_out[4] =
c[3] ^ c[4] ^ c[5] ^ c[9] ^ c[10] ^ c[11] ^
c[13] ^ c[15] ^ c[17] ^ c[19] ^ c[20] ^ c[21] ^ d[61] ^
d[60] ^ d[59] ^ d[57] ^ d[55] ^ d[53] ^ d[51] ^ d[50] ^
d[49] ^ d[45] ^ d[44] ^ d[43] ^ d[39] ^ d[38] ^ d[37] ^
d[36] ^ d[32] ^ d[27] ^ d[26] ^ d[20] ^ d[19] ^ d[18] ^
d[17] ^ d[15] ^ d[13] ^ d[12] ^ d[9] ^ d[8] ^ d[6] ^
d[4] ^ d[3];
assign crc_out[5] =
c[0] ^ c[1] ^ c[4] ^ c[5] ^ c[8] ^ c[9] ^
c[10] ^ c[11] ^ c[13] ^ c[14] ^ c[19] ^ c[21] ^ c[23] ^
d[63] ^ d[61] ^ d[59] ^ d[54] ^ d[53] ^ d[51] ^ d[50] ^
d[49] ^ d[48] ^ d[45] ^ d[44] ^ d[41] ^ d[40] ^ d[36] ^
d[34] ^ d[33] ^ d[32] ^ d[31] ^ d[30] ^ d[29] ^ d[28] ^
d[27] ^ d[23] ^ d[21] ^ d[20] ^ d[19] ^ d[18] ^ d[13] ^
d[11] ^ d[9] ^ d[8] ^ d[6] ^ d[5] ^ d[3] ^ d[0];
assign crc_out[6] =
c[2] ^ c[5] ^ c[8] ^ c[10] ^ c[11] ^ c[13] ^
c[14] ^ c[15] ^ c[16] ^ c[18] ^ c[19] ^ c[23] ^ d[63] ^
d[59] ^ d[58] ^ d[56] ^ d[55] ^ d[54] ^ d[53] ^ d[51] ^
d[50] ^ d[48] ^ d[45] ^ d[42] ^ d[39] ^ d[38] ^ d[36] ^
d[35] ^ d[33] ^ d[28] ^ d[24] ^ d[23] ^ d[22] ^ d[21] ^
d[20] ^ d[19] ^ d[16] ^ d[12] ^ d[11] ^ d[9] ^ d[8] ^
d[3] ^ d[1] ^ d[0];
assign crc_out[7] =
c[0] ^ c[3] ^ c[6] ^ c[9] ^ c[11] ^ c[12] ^
c[14] ^ c[15] ^ c[16] ^ c[17] ^ c[19] ^ c[20] ^ d[60] ^
d[59] ^ d[57] ^ d[56] ^ d[55] ^ d[54] ^ d[52] ^ d[51] ^
d[49] ^ d[46] ^ d[43] ^ d[40] ^ d[39] ^ d[37] ^ d[36] ^
d[34] ^ d[29] ^ d[25] ^ d[24] ^ d[23] ^ d[22] ^ d[21] ^
d[20] ^ d[17] ^ d[13] ^ d[12] ^ d[10] ^ d[9] ^ d[4] ^
d[2] ^ d[1];
assign crc_out[8] =
c[0] ^ c[4] ^ c[6] ^ c[7] ^ c[8] ^ c[9] ^
c[10] ^ c[15] ^ c[17] ^ c[19] ^ c[21] ^ c[22] ^ c[23] ^
d[63] ^ d[62] ^ d[61] ^ d[59] ^ d[57] ^ d[55] ^ d[50] ^
d[49] ^ d[48] ^ d[47] ^ d[46] ^ d[44] ^ d[40] ^ d[39] ^
d[36] ^ d[35] ^ d[34] ^ d[32] ^ d[31] ^ d[29] ^ d[26] ^
d[25] ^ d[24] ^ d[22] ^ d[21] ^ d[18] ^ d[16] ^ d[13] ^
d[8] ^ d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[0];
assign crc_out[9] =
c[0] ^ c[5] ^ c[6] ^ c[7] ^ c[10] ^ c[11] ^
c[12] ^ c[13] ^ c[19] ^ d[59] ^ d[53] ^ d[52] ^ d[51] ^
d[50] ^ d[47] ^ d[46] ^ d[45] ^ d[40] ^ d[39] ^ d[38] ^
d[35] ^ d[34] ^ d[33] ^ d[31] ^ d[29] ^ d[27] ^ d[26] ^
d[25] ^ d[22] ^ d[19] ^ d[17] ^ d[16] ^ d[11] ^ d[10] ^
d[9] ^ d[5] ^ d[4] ^ d[1] ^ d[0];
assign crc_out[10] =
c[0] ^ c[1] ^ c[6] ^ c[7] ^ c[8] ^ c[11] ^
c[12] ^ c[13] ^ c[14] ^ c[20] ^ d[60] ^ d[54] ^ d[53] ^
d[52] ^ d[51] ^ d[48] ^ d[47] ^ d[46] ^ d[41] ^ d[40] ^
d[39] ^ d[36] ^ d[35] ^ d[34] ^ d[32] ^ d[30] ^ d[28] ^
d[27] ^ d[26] ^ d[23] ^ d[20] ^ d[18] ^ d[17] ^ d[12] ^
d[11] ^ d[10] ^ d[6] ^ d[5] ^ d[2] ^ d[1];
assign crc_out[11] =
c[0] ^ c[2] ^ c[6] ^ c[7] ^ c[14] ^ c[15] ^
c[16] ^ c[18] ^ c[19] ^ c[20] ^ c[21] ^ c[22] ^ c[23] ^
d[63] ^ d[62] ^ d[61] ^ d[60] ^ d[59] ^ d[58] ^ d[56] ^
d[55] ^ d[54] ^ d[47] ^ d[46] ^ d[42] ^ d[40] ^ d[39] ^
d[38] ^ d[35] ^ d[34] ^ d[33] ^ d[32] ^ d[30] ^ d[28] ^
d[27] ^ d[24] ^ d[23] ^ d[21] ^ d[19] ^ d[18] ^ d[16] ^
d[14] ^ d[13] ^ d[12] ^ d[10] ^ d[8] ^ d[4] ^ d[2] ^
d[0];
assign crc_out[12] =
c[0] ^ c[1] ^ c[3] ^ c[7] ^ c[8] ^ c[15] ^
c[16] ^ c[17] ^ c[19] ^ c[20] ^ c[21] ^ c[22] ^ c[23] ^
d[63] ^ d[62] ^ d[61] ^ d[60] ^ d[59] ^ d[57] ^ d[56] ^
d[55] ^ d[48] ^ d[47] ^ d[43] ^ d[41] ^ d[40] ^ d[39] ^
d[36] ^ d[35] ^ d[34] ^ d[33] ^ d[31] ^ d[29] ^ d[28] ^
d[25] ^ d[24] ^ d[22] ^ d[20] ^ d[19] ^ d[17] ^ d[15] ^
d[14] ^ d[13] ^ d[11] ^ d[9] ^ d[5] ^ d[3] ^ d[1];
assign crc_out[13] =
c[0] ^ c[1] ^ c[2] ^ c[4] ^ c[8] ^ c[9] ^
c[16] ^ c[17] ^ c[18] ^ c[20] ^ c[21] ^ c[22] ^ c[23] ^
d[63] ^ d[62] ^ d[61] ^ d[60] ^ d[58] ^ d[57] ^ d[56] ^
d[49] ^ d[48] ^ d[44] ^ d[42] ^ d[41] ^ d[40] ^ d[37] ^
d[36] ^ d[35] ^ d[34] ^ d[32] ^ d[30] ^ d[29] ^ d[26] ^
d[25] ^ d[23] ^ d[21] ^ d[20] ^ d[18] ^ d[16] ^ d[15] ^
d[14] ^ d[12] ^ d[10] ^ d[6] ^ d[4] ^ d[2];
assign crc_out[14] =
c[1] ^ c[2] ^ c[3] ^ c[5] ^ c[9] ^ c[10] ^
c[17] ^ c[18] ^ c[19] ^ c[21] ^ c[22] ^ c[23] ^ d[63] ^
d[62] ^ d[61] ^ d[59] ^ d[58] ^ d[57] ^ d[50] ^ d[49] ^
d[45] ^ d[43] ^ d[42] ^ d[41] ^ d[38] ^ d[37] ^ d[36] ^
d[35] ^ d[33] ^ d[31] ^ d[30] ^ d[27] ^ d[26] ^ d[24] ^
d[22] ^ d[21] ^ d[19] ^ d[17] ^ d[16] ^ d[15] ^ d[13] ^
d[11] ^ d[7] ^ d[5] ^ d[3];
assign crc_out[15] =
c[1] ^ c[2] ^ c[3] ^ c[4] ^ c[8] ^ c[9] ^
c[10] ^ c[11] ^ c[12] ^ c[13] ^ c[16] ^ d[56] ^ d[53] ^
d[52] ^ d[51] ^ d[50] ^ d[49] ^ d[48] ^ d[44] ^ d[43] ^
d[42] ^ d[41] ^ d[30] ^ d[29] ^ d[28] ^ d[27] ^ d[25] ^
d[22] ^ d[20] ^ d[18] ^ d[17] ^ d[12] ^ d[11] ^ d[10] ^
d[7] ^ d[3] ^ d[0];
assign crc_out[16] =
c[2] ^ c[3] ^ c[4] ^ c[5] ^ c[9] ^ c[10] ^
c[11] ^ c[12] ^ c[13] ^ c[14] ^ c[17] ^ d[57] ^ d[54] ^
d[53] ^ d[52] ^ d[51] ^ d[50] ^ d[49] ^ d[45] ^ d[44] ^
d[43] ^ d[42] ^ d[31] ^ d[30] ^ d[29] ^ d[28] ^ d[26] ^
d[23] ^ d[21] ^ d[19] ^ d[18] ^ d[13] ^ d[12] ^ d[11] ^
d[8] ^ d[4] ^ d[1];
assign crc_out[17] =
c[1] ^ c[3] ^ c[4] ^ c[5] ^ c[8] ^ c[9] ^
c[10] ^ c[11] ^ c[14] ^ c[15] ^ c[16] ^ c[19] ^ c[20] ^
c[22] ^ c[23] ^ d[63] ^ d[62] ^ d[60] ^ d[59] ^ d[56] ^
d[55] ^ d[54] ^ d[51] ^ d[50] ^ d[49] ^ d[48] ^ d[45] ^
d[44] ^ d[43] ^ d[41] ^ d[39] ^ d[38] ^ d[37] ^ d[36] ^
d[34] ^ d[27] ^ d[24] ^ d[23] ^ d[22] ^ d[20] ^ d[19] ^
d[16] ^ d[13] ^ d[12] ^ d[11] ^ d[10] ^ d[9] ^ d[8] ^
d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[3] ^ d[2] ^ d[0];
assign crc_out[18] =
c[0] ^ c[2] ^ c[4] ^ c[5] ^ c[6] ^ c[9] ^
c[10] ^ c[11] ^ c[12] ^ c[15] ^ c[16] ^ c[17] ^ c[20] ^
c[21] ^ c[23] ^ d[63] ^ d[61] ^ d[60] ^ d[57] ^ d[56] ^
d[55] ^ d[52] ^ d[51] ^ d[50] ^ d[49] ^ d[46] ^ d[45] ^
d[44] ^ d[42] ^ d[40] ^ d[39] ^ d[38] ^ d[37] ^ d[35] ^
d[28] ^ d[25] ^ d[24] ^ d[23] ^ d[21] ^ d[20] ^ d[17] ^
d[14] ^ d[13] ^ d[12] ^ d[11] ^ d[10] ^ d[9] ^ d[8] ^
d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[3] ^ d[1];
assign crc_out[19] =
c[0] ^ c[1] ^ c[3] ^ c[5] ^ c[6] ^ c[7] ^
c[10] ^ c[11] ^ c[12] ^ c[13] ^ c[16] ^ c[17] ^ c[18] ^
c[21] ^ c[22] ^ d[62] ^ d[61] ^ d[58] ^ d[57] ^ d[56] ^
d[53] ^ d[52] ^ d[51] ^ d[50] ^ d[47] ^ d[46] ^ d[45] ^
d[43] ^ d[41] ^ d[40] ^ d[39] ^ d[38] ^ d[36] ^ d[29] ^
d[26] ^ d[25] ^ d[24] ^ d[22] ^ d[21] ^ d[18] ^ d[15] ^
d[14] ^ d[13] ^ d[12] ^ d[11] ^ d[10] ^ d[9] ^ d[8] ^
d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[2];
assign crc_out[20] =
c[0] ^ c[2] ^ c[4] ^ c[7] ^ c[9] ^ c[11] ^
c[14] ^ c[16] ^ c[17] ^ c[20] ^ d[60] ^ d[57] ^ d[56] ^
d[54] ^ d[51] ^ d[49] ^ d[47] ^ d[44] ^ d[42] ^ d[40] ^
d[38] ^ d[36] ^ d[34] ^ d[32] ^ d[31] ^ d[29] ^ d[27] ^
d[26] ^ d[25] ^ d[22] ^ d[19] ^ d[15] ^ d[13] ^ d[12] ^
d[9] ^ d[5] ^ d[4] ^ d[0];
assign crc_out[21] =
c[3] ^ c[5] ^ c[6] ^ c[9] ^ c[10] ^ c[13] ^
c[15] ^ c[16] ^ c[17] ^ c[19] ^ c[20] ^ c[21] ^ c[22] ^
c[23] ^ d[63] ^ d[62] ^ d[61] ^ d[60] ^ d[59] ^ d[57] ^
d[56] ^ d[55] ^ d[53] ^ d[50] ^ d[49] ^ d[46] ^ d[45] ^
d[43] ^ d[38] ^ d[36] ^ d[35] ^ d[34] ^ d[33] ^ d[31] ^
d[29] ^ d[28] ^ d[27] ^ d[26] ^ d[20] ^ d[13] ^ d[11] ^
d[8] ^ d[7] ^ d[5] ^ d[4] ^ d[3] ^ d[1] ^ d[0];
assign crc_out[22] =
c[4] ^ c[6] ^ c[7] ^ c[10] ^ c[11] ^ c[14] ^
c[16] ^ c[17] ^ c[18] ^ c[20] ^ c[21] ^ c[22] ^ c[23] ^
d[63] ^ d[62] ^ d[61] ^ d[60] ^ d[58] ^ d[57] ^ d[56] ^
d[54] ^ d[51] ^ d[50] ^ d[47] ^ d[46] ^ d[44] ^ d[39] ^
d[37] ^ d[36] ^ d[35] ^ d[34] ^ d[32] ^ d[30] ^ d[29] ^
d[28] ^ d[27] ^ d[21] ^ d[14] ^ d[12] ^ d[9] ^ d[8] ^
d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1];
assign crc_out[23] =
c[0] ^ c[5] ^ c[7] ^ c[8] ^ c[11] ^ c[12] ^
c[15] ^ c[17] ^ c[18] ^ c[19] ^ c[21] ^ c[22] ^ c[23] ^
d[63] ^ d[62] ^ d[61] ^ d[59] ^ d[58] ^ d[57] ^ d[55] ^
d[52] ^ d[51] ^ d[48] ^ d[47] ^ d[45] ^ d[40] ^ d[38] ^
d[37] ^ d[36] ^ d[35] ^ d[33] ^ d[31] ^ d[30] ^ d[29] ^
d[28] ^ d[22] ^ d[15] ^ d[13] ^ d[10] ^ d[9] ^ d[7] ^
d[6] ^ d[5] ^ d[3] ^ d[2];
endmodule
module crc24_dat64_factor (c,d,crc_out);
input[23:0] c;
input[63:0] d;
output[23:0] crc_out;
wire[23:0] crc_out;
wire[114:0] h ;
xor6 cx_0 (crc_out[0], h[51] , h[60] , h[66] , h[73] , h[80] , h[93]);
xor6 cx_1 (crc_out[1], h[16] , h[37] , h[44] , h[61] , h[104] , h[114]);
xor6 cx_2 (crc_out[2], h[35] , h[36] , h[44] , h[57] , h[112] , h[113]);
xor6 cx_3 (crc_out[3], h[32] , h[35] , h[37] , h[40] , h[41] , h[111]);
xor6 cx_4 (crc_out[4], h[44] , h[46] , h[59] , h[65] , h[109] , h[110]);
xor6 cx_5 (crc_out[5], h[45] , h[46] , h[63] , h[64] , h[107] , h[108]);
xor6 cx_6 (crc_out[6], h[24] , h[34] , h[65] , h[67] , h[105] , h[106]);
xor6 cx_7 (crc_out[7], h[40] , h[49] , h[58] , h[67] , h[102] , h[103]);
xor6 cx_8 (crc_out[8], h[35] , h[39] , h[63] , h[66] , h[100] , h[101]);
xor6 cx_9 (crc_out[9], h[27] , h[45] , h[61] , h[66] , h[98] , h[99]);
xor6 cx_10 (crc_out[10], h[33] , h[44] , h[48] , h[95] , h[96] , h[97]);
xor6 cx_11 (crc_out[11], h[22] , h[33] , h[36] , h[49] , h[59] , h[94]);
xor6 cx_12 (crc_out[12], h[12] , h[44] , h[62] , h[90] , h[91] , h[92]);
xor6 cx_13 (crc_out[13], h[35] , h[38] , h[50] , h[64] , h[88] , h[89]);
xor6 cx_14 (crc_out[14], h[34] , h[50] , h[56] , h[62] , h[86] , h[87]);
xor6 cx_15 (crc_out[15], h[19] , h[38] , h[48] , h[55] , h[84] , h[85]);
xor6 cx_16 (crc_out[16], h[30] , h[38] , h[42] , h[54] , h[62] , h[83]);
xor6 cx_17 (crc_out[17], h[25] , h[31] , h[54] , h[66] , h[81] , h[82]);
xor6 cx_18 (crc_out[18], h[41] , h[55] , h[60] , h[63] , h[78] , h[79]);
xor6 cx_19 (crc_out[19], h[21] , h[28] , h[74] , h[75] , h[76] , h[77]);
xor6 cx_20 (crc_out[20], h[42] , h[45] , h[51] , h[57] , h[71] , h[72]);
xor6 cx_21 (crc_out[21], h[29] , h[56] , h[67] , h[68] , h[69] , h[70]);
xor6 cx_22 (crc_out[22], h[31] , h[37] , h[39] , h[52] , h[53] , h[58]);
xor6 cx_23 (crc_out[23], h[19] , h[23] , h[43] , h[47] , h[63] , h[73]);
xor6 hx_0 (h[0], c[19] , c[23] , d[63] , d[59] , d[36] , d[13]); // used by 8
xor6 hx_1 (h[1], c[16] , c[20] , d[60] , d[56] , d[36] , d[12]); // used by 5
xor6 hx_2 (h[2], c[17] , c[21] , d[61] , d[57] , d[35] , d[5]); // used by 8
xor6 hx_3 (h[3], c[9] , c[17] , d[57] , d[49] , d[37] , d[4]); // used by 4
xor6 hx_4 (h[4], c[9] , c[10] , d[50] , d[49] , d[11] , d[7]); // used by 4
xor6 hx_5 (h[5], c[5] , c[10] , c[11] , d[51] , d[50] , d[45]); // used by 8
xor6 hx_6 (h[6], c[0] , c[7] , d[47] , d[40] , d[34] , d[10]); // used by 4
xor6 hx_7 (h[7], c[6] , d[46] , d[39] , d[34] , d[8] , d[4]); // used by 3
xor6 hx_8 (h[8], c[18] , c[22] , d[62] , d[58] , d[16] , d[2]); // used by 3
xor6 hx_9 (h[9], c[0] , d[40] , d[29] , d[25] , d[22] , d[9]); // used by 4
xor6 hx_10 (h[10], c[12] , c[13] , d[53] , d[52] , d[29] , d[11]); // used by 3
xor6 hx_11 (h[11], c[1] , c[16] , c[22] , d[62] , d[56] , d[41]); // used by 5
xor6 hx_12 (h[12], c[15] , c[20] , d[60] , d[55] , d[39] , d[20]); // used by 4
xor6 hx_13 (h[13], c[8] , c[14] , d[54] , d[48] , d[23] , d[3]); // used by 4
xor6 hx_14 (h[14], c[2] , c[14] , d[54] , d[42] , d[38] , d[19]); // used by 3
xor6 hx_15 (h[15], c[4] , c[9] , d[49] , d[44] , d[21] , d[6]); // used by 3
xor6 hx_16 (h[16], c[6] , c[12] , d[52] , d[46] , d[24] , d[12]); // used by 3
xor6 hx_17 (h[17], c[1] , c[13] , d[53] , d[41] , d[30] , d[18]); // used by 4
xor6 hx_18 (h[18], c[18] , d[58] , d[37] , d[31] , d[30] , d[3]); // used by 3
xor6 hx_19 (h[19], c[8] , c[11] , c[12] , d[52] , d[51] , d[48]); // used by 3
xor6 hx_20 (h[20], c[16] , d[56] , d[33] , d[28] , d[8] , d[0]); // used by 3
xor6 hx_21 (h[21], c[3] , d[43] , d[38] , d[26] , d[18] , d[8]); // used by 2
xor6 hx_22 (h[22], c[23] , d[63] , d[32] , d[30] , d[23] , d[14]); // used by 3
xor6 hx_23 (h[23], c[7] , c[22] , d[62] , d[47] , d[29] , d[2]); // used by 3
xor6 hx_24 (h[24], c[19] , c[23] , d[63] , d[59] , d[35] , d[16]); // used by 2
xor6 hx_25 (h[25], c[3] , d[43] , d[34] , d[24] , d[11] , d[10]); // used by 3
xor6 hx_26 (h[26], d[38] , d[17] , d[9] , d[1] , 1‘b0 , 1’b0); // used by 1
xor6 hx_27 (h[27], c[6] , c[19] , d[59] , d[46] , d[39] , d[17]); // used by 2
xor6 hx_28 (h[28], c[21] , d[61] , d[21] , d[15] , d[10] , d[6]); // used by 2
xor6 hx_29 (h[29], c[3] , d[43] , d[31] , d[26] , d[3] , d[1]); // used by 1
xor6 hx_30 (h[30], c[14] , d[54] , d[28] , d[23] , d[21] , d[1]); // used by 1
xor6 hx_31 (h[31], c[4] , d[44] , d[37] , d[27] , d[9] , d[6]); // used by 2
xor6 hx_32 (h[32], c[3] , c[4] , d[44] , d[43] , d[26] , d[17]); // used by 1
xor6 hx_33 (h[33], c[6] , c[20] , d[60] , d[46] , d[39] , d[27]); // used by 3
xor6 hx_34 (h[34], c[2] , d[42] , d[38] , d[24] , d[22] , d[21]); // used by 2
xor6 hx_35 (h[35], c[8] , d[48] , d[25] , d[18] , 1‘b0 , 1’b0); // used by 4
xor6 hx_36 (h[36], c[15] , d[55] , d[35] , d[18] , 1‘b0 , 1’b0); // used by 2
xor6 hx_37 (h[37], c[18] , d[58] , d[14] , 1‘b0 , 1’b0 , 1‘b0); // used by 3
xor6 hx_38 (h[38], c[2] , c[4] , d[44] , d[42] , 1’b0 , 1‘b0); // used by 3
xor6 hx_39 (h[39], c[10] , d[50] , d[32] , 1’b0 , 1‘b0 , 1’b0); // used by 2
xor6 hx_40 (h[40], c[12] , d[52] , d[2] , 1‘b0 , 1’b0 , 1‘b0); // used by 2
xor6 hx_41 (h[41], d[37] , d[8] , d[3] , 1’b0 , 1‘b0 , 1’b0); // used by 2
xor6 hx_42 (h[42], c[17] , d[57] , d[13] , d[4] , 1‘b0 , 1’b0); // used by 2
xor6 hx_43 (h[43], d[15] , d[9] , h[0] , h[2] , h[18] , 1‘b0); // used by 1
xor6 hx_44 (h[44], d[17] , d[15] , d[6] , d[1] , 1’b0 , 1‘b0); // used by 5
xor6 hx_45 (h[45], d[31] , d[27] , d[5] , d[0] , 1’b0 , 1‘b0); // used by 3
xor6 hx_46 (h[46], d[32] , d[19] , d[9] , 1’b0 , 1‘b0 , 1’b0); // used by 2
xor6 hx_47 (h[47], c[5] , c[15] , d[55] , d[45] , d[38] , d[33]); // used by 1
xor6 hx_48 (h[48], d[28] , d[20] , d[12] , 1‘b0 , 1’b0 , 1‘b0); // used by 2
xor6 hx_49 (h[49], d[24] , d[21] , d[13] , 1’b0 , 1‘b0 , 1’b0); // used by 2
xor6 hx_50 (h[50], c[1] , d[41] , d[26] , 1‘b0 , 1’b0 , 1‘b0); // used by 2
xor6 hx_51 (h[51], c[9] , d[49] , d[32] , 1’b0 , 1‘b0 , 1’b0); // used by 2
xor6 hx_52 (h[52], h[1] , h[2] , h[7] , h[23] , 1‘b0 , 1’b0); // used by 1
xor6 hx_53 (h[53], c[23] , d[63] , d[30] , d[28] , d[21] , d[1]); // used by 1
xor6 hx_54 (h[54], c[9] , d[49] , d[12] , d[8] , 1‘b0 , 1’b0); // used by 2
xor6 hx_55 (h[55], c[16] , d[56] , d[25] , d[10] , 1‘b0 , 1’b0); // used by 2
xor6 hx_56 (h[56], c[5] , c[22] , d[62] , d[45] , 1‘b0 , 1’b0); // used by 2
xor6 hx_57 (h[57], c[7] , c[11] , d[51] , d[47] , 1‘b0 , 1’b0); // used by 2
xor6 hx_58 (h[58], c[11] , c[14] , d[54] , d[51] , 1‘b0 , 1’b0); // used by 2
xor6 hx_59 (h[59], c[19] , c[21] , d[61] , d[59] , 1‘b0 , 1’b0); // used by 2
xor6 hx_60 (h[60], d[32] , d[30] , h[22] , 1‘b0 , 1’b0 , 1‘b0); // used by 2
xor6 hx_61 (h[61], d[33] , d[9] , d[0] , 1’b0 , 1‘b0 , 1’b0); // used by 2
xor6 hx_62 (h[62], c[3] , d[43] , d[19] , 1‘b0 , 1’b0 , 1‘b0); // used by 3
xor6 hx_63 (h[63], c[0] , d[40] , d[28] , d[7] , 1’b0 , 1‘b0); // used by 4
xor6 hx_64 (h[64], d[34] , d[29] , d[20] , 1’b0 , 1‘b0 , 1’b0); // used by 2
xor6 hx_65 (h[65], c[13] , d[53] , d[36] , 1‘b0 , 1’b0 , 1‘b0); // used by 2
xor6 hx_66 (h[66], d[38] , d[22] , d[16] , d[0] , 1’b0 , 1‘b0); // used by 4
xor6 hx_67 (h[67], c[15] , d[55] , d[20] , d[1] , 1’b0 , 1‘b0); // used by 3
xor6 hx_68 (h[68], h[0] , h[2] , h[4] , h[20] , 1’b0 , 1‘b0); // used by 1
xor6 hx_69 (h[69], d[38] , d[34] , d[29] , d[27] , d[4] , d[1]); // used by 1
xor6 hx_70 (h[70], c[13] , d[53] , d[39] , d[27] , h[33] , 1’b0); // used by 1
xor6 hx_71 (h[71], h[9] , h[14] , 1‘b0 , 1’b0 , 1‘b0 , 1’b0); // used by 1
xor6 hx_72 (h[72], c[4] , d[44] , d[34] , d[26] , d[15] , h[1]); // used by 1
xor6 hx_73 (h[73], d[22] , d[10] , d[6] , 1‘b0 , 1’b0 , 1‘b0); // used by 2
xor6 hx_74 (h[74], h[9] , h[11] , h[16] , 1’b0 , 1‘b0 , 1’b0); // used by 1
xor6 hx_75 (h[75], d[11] , d[7] , d[5] , d[4] , d[2] , h[5]); // used by 1
xor6 hx_76 (h[76], c[18] , d[58] , d[39] , d[36] , d[14] , d[13]); // used by 1
xor6 hx_77 (h[77], c[7] , c[13] , c[17] , d[57] , d[53] , d[47]); // used by 1
xor6 hx_78 (h[78], c[2] , d[42] , h[15] , h[16] , h[26] , 1‘b0); // used by 1
xor6 hx_79 (h[79], d[13] , d[11] , d[4] , h[2] , h[5] , h[12]); // used by 1
xor6 hx_80 (h[80], c[8] , c[19] , c[20] , d[60] , d[59] , d[48]); // used by 1
xor6 hx_81 (h[81], h[5] , h[11] , h[12] , h[13] , 1’b0 , 1‘b0); // used by 1
xor6 hx_82 (h[82], d[19] , d[7] , d[5] , d[4] , d[2] , h[0]); // used by 1
xor6 hx_83 (h[83], d[31] , d[30] , d[26] , d[18] , h[5] , h[10]); // used by 1
xor6 hx_84 (h[84], d[3] , d[0] , h[4] , h[17] , 1’b0 , 1‘b0); // used by 1
xor6 hx_85 (h[85], c[3] , d[43] , d[29] , d[27] , d[22] , d[17]); // used by 1
xor6 hx_86 (h[86], h[2] , h[4] , h[18] , 1’b0 , 1‘b0 , 1’b0); // used by 1
xor6 hx_87 (h[87], d[33] , d[27] , d[17] , d[16] , d[15] , h[0]); // used by 1
xor6 hx_88 (h[88], h[22] , h[28] , 1‘b0 , 1’b0 , 1‘b0 , 1’b0); // used by 1
xor6 hx_89 (h[89], c[0] , d[40] , d[35] , h[1] , h[3] , h[8]); // used by 1
xor6 hx_90 (h[90], d[3] , h[0] , h[2] , h[9] , h[11] , 1‘b0); // used by 1
xor6 hx_91 (h[91], d[31] , d[28] , d[24] , d[14] , d[11] , d[6]); // used by 1
xor6 hx_92 (h[92], c[7] , c[8] , d[48] , d[47] , d[34] , d[33]); // used by 1
xor6 hx_93 (h[93], d[36] , d[7] , h[7] , h[10] , h[11] , h[18]); // used by 1
xor6 hx_94 (h[94], d[12] , d[4] , h[6] , h[8] , h[14] , h[20]); // used by 1
xor6 hx_95 (h[95], h[17] , h[19] , 1’b0 , 1‘b0 , 1’b0 , 1‘b0); // used by 1
xor6 hx_96 (h[96], d[23] , d[15] , d[11] , d[5] , d[2] , h[6]); // used by 1
xor6 hx_97 (h[97], c[14] , d[54] , d[36] , d[35] , d[32] , d[26]); // used by 1
xor6 hx_98 (h[98], h[5] , h[6] , h[10] , 1’b0 , 1‘b0 , 1’b0); // used by 1
xor6 hx_99 (h[99], d[35] , d[26] , d[25] , d[19] , d[4] , d[1]); // used by 1
xor6 hx_100 (h[100], d[24] , h[0] , h[2] , h[7] , h[15] , h[23]); // used by 1
xor6 hx_101 (h[101], c[15] , d[55] , d[38] , d[31] , d[28] , d[26]); // used by 1
xor6 hx_102 (h[102], h[3] , h[9] , h[27] , 1‘b0 , 1’b0 , 1‘b0); // used by 1
xor6 hx_103 (h[103], d[24] , d[23] , d[11] , h[1] , h[25] , 1’b0); // used by 1
xor6 hx_104 (h[104], c[2] , c[10] , d[50] , d[42] , d[36] , d[29]); // used by 1
xor6 hx_105 (h[105], d[9] , h[5] , h[13] , h[20] , 1‘b0 , 1’b0); // used by 1
xor6 hx_106 (h[106], c[18] , d[58] , d[39] , d[19] , d[12] , d[11]); // used by 1
xor6 hx_107 (h[107], h[0] , h[5] , h[13] , h[15] , h[17] , 1‘b0); // used by 1
xor6 hx_108 (h[108], c[21] , d[61] , d[33] , d[11] , d[8] , d[7]); // used by 1
xor6 hx_109 (h[109], d[1] , h[3] , h[5] , h[12] , h[21] , 1’b0); // used by 1
xor6 hx_110 (h[110], c[4] , d[44] , d[27] , d[13] , d[12] , d[3]); // used by 1
xor6 hx_111 (h[111], d[31] , d[5] , h[1] , h[4] , h[14] , h[24]); // used by 1
xor6 hx_112 (h[112], h[17] , h[25] , 1‘b0 , 1’b0 , 1‘b0 , 1’b0); // used by 1
xor6 hx_113 (h[113], c[2] , d[42] , d[7] , h[0] , h[3] , h[8]); // used by 1
xor6 hx_114 (h[114], d[16] , h[2] , h[6] , h[11] , h[13] , 1‘b0); // used by 1
endmodule
常用CRC類型PCIe:CRC16
用于鏈路層幀的校驗;
多項式是100Bh(16,12,3,1,0);
初始值是16’hFFFF;
發送電路中對計算結果(余數)取補,即在發送過程中進行比特取反;
接收電路比較本地計算的CRC結果與接收到的CRC結果,判斷兩者是否匹配,接收到的CRC不參與校驗計算。
PCIe:CRC32
用于處理層數據包的校驗;
多項式是04CllDB7h(32,26,23,22,16,12,11,10,8,7,5,4,2,1,0);
初始值是32’hFFFF_FFFF;
發送電路中對計算結果(余數)取補,即在發送過程中對比特取反;
接收電路比較本地計算的CRC結果與接收到的CRC結果,判斷兩者是否匹配,接收到的CRC不參與校驗計算。
USB3.0:CRC16
用于USB3.0包頭校驗;
多項式是l00Bh(16,12,3,1,0);
初始值是16’hFFFF;
在傳輸過程中對結果取補;
接收電路的余數是16’hFCAA;
接收的CRC值參與接收端的CRC計算。
關于和已知余數進行比較:
接收電路邊接收數據邊計算CRC校驗值,如果接收數據中沒有錯誤,則計算得到的余數為5’b0_100。將接收端的CRC計算結果和一個已知的值進行比較,比和接收的CRC進行比較要更加簡單。在實際電路設計中,當接收到END符號時,電路內部產生end_pkt(包結束)信號,但此時接收數據中的CRC已經進入接收CRC計算電路中了,對于變長的數據包來說,預先知道接收的數據何時結束及接收包中CRC域何時開始是比較困難的。此時可以考慮使用多級移位寄存器對數據進行緩沖,然后得到新的start_pkt及end_pkt信號,并利用它們將接收數據域和接收的CRC域區分開。
USB2.0:CRC16
用于USB2.0數據傳輸;
多項式是8005h(16,15,2,0);
初始值是16’hFFFF;
在發送過程中對計算結果進行取補;
接收電路的余數是16’h800D;
在接收端,接收到的CRC值包含在CRC計算中。
USB:CRC5
用于鏈路控制字段的校驗;
多項式是05h(5,2,0);
初始值是5’b1_lll;
在發送過程中對計算結果取補;
接收端的校驗結果都是5’b0_l100;
接收的CRC值參與CRC計算;
接收電路將校驗結果和5’b0_1100進行比較。
USB3.0:CRC32
用于USB3.0數據包傳輸;
多項式是04Cl_1DB7h(32,26,23,22,16,12,11,10,8,7,5,4,2,1,0);
初始值是32’hFFFF_FFFF;
發送電路在傳輸過程中對余數(校驗結果)取補;
接收電路的校驗余數是32’hC704_DD7B;
接收到的CRC值參與CRC計算;
接收電路將校驗結果和32’hC704_DD7B進行比較。
SATA:CRC32
用于FIS(Frame Information Structure)包;
多項式是04C11DB7h(32,26,23,22,16,12,11,10,8,7,5,4,2,1,0);
初始值是32’h5232_5032;
發送電路對校驗余數校驗結果取補,在傳輸過程中,將1字節內的比特翻轉;
接收電路的余數是16’h0000;
接收端,接收的CRC值參與校驗運算,校驗結果應該為全0。
關于實例整篇文章偏理論,計算實例可以通過(https://www.easics.com/crctool/)(可以直接得到Verilog源碼)計算得到,當然還有一個腳本可以使用-任意多項式,任意位寬crc verilog代碼自動生成perl腳本《https://cloud.tencent.com/developer/article/1652744》。
使用方法:
鏈接:https://pan.baidu.com/s/1pBlDHDxGRoXwyFKVuypR9A提取碼:open
gen_crc.pl 輸入數據位寬 多項式
多項式輸入方法:從低位向高位依次輸入,以USB TOKEN為例,x^5 + x^2 + 1,從低到高位輸入為101001usb token的crc生成方法:gen_crc.pl 8 101001usb data的crc(x^16+x^15+x^2+1)生成方法:gen_crc.pl 8 10100000000000011
鏈接: https://pan.baidu.com/s/1kqRsSBJRq64tNnmv1SYjXQ
提取碼: jr8i
說明:
windows下要安裝ActivePerl。
1、在Windows上用ActivePerl寫一個HelloWorld,測試完畢后,我們在C盤創建一個文件。
HelloWorld.pl
2、右鍵HelloWorld.pl文件 -》 用記事本打開該文件,然后輸入以下代碼:
#!/usr/bin/env perl
print “HelloWorld”
3、然后保存
4、回到cmd命令提示符。
cd
返回到C盤根目錄
perl HelloWorld.pl
或者直接鍵入HelloWorld.pl
解釋下:2行代碼的作用
#!/usr/bin/env perl是典型的解釋器路徑聲明(魔法聲明),如果考慮到跨平臺,在Unix/Linux上使用的,是必須要加上這個聲明的,如果只是單純的在windows上學習Perl,這個聲明無關緊要。
print “HelloWorld”則是一條語句,作用就是在屏幕上輸出一個字符串,“”內的則是字符串,例如小伙伴可以嘗試修改“”內的內容。
Linux下就命令行perl perlname.pl
我是在虛擬機下運行的,所以無需安裝特殊軟件,直接perl gen_crc.pl 8 101001
就可以了。
編輯:jq
-
寄存器
+關注
關注
31文章
5317瀏覽量
120003 -
數據
+關注
關注
8文章
6890瀏覽量
88826 -
Linux
+關注
關注
87文章
11225瀏覽量
208920 -
WINDOWS
+關注
關注
3文章
3524瀏覽量
88419 -
crc
+關注
關注
0文章
199瀏覽量
29434
原文標題:Verilog數字系統基礎設計-CRC
文章出處:【微信號:gh_339470469b7d,微信公眾號:FPGA與數據通信】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論