1 代碼生成
verilog實現CRC校驗,可以充分發揮FPGA的硬件特性,即並行運算的能力。
具體實現方式,可以參考我上一篇博客,關鍵是用線性反饋移位寄存器表示出多項式,另外注意校驗數據高位在先。然后根據電路結構推導出邏輯表達式,再轉換成verilog就行了。
更高效的方法是利用現成的代碼生成工具,例如附件的鏈接就是一種在線的CRC校驗代碼生成工具。
我這里用代碼生成工具生成多項式為x^4 + x^1 + 1,即CRC-4/ITU校驗模型,校驗輸入數據位寬為4bit的代碼,下面分享一下修改移植時的心得。
2 修改移植
這個多項式和我上一篇博客舉例所用多項式一樣,生成的代碼和前面推導的邏輯表達式是一致的。生成的代碼如下
function [3:0] nextCRC4_D4;
input [3:0] Data;
input [3:0] crc;
reg [3:0] d;
reg [3:0] c;
reg [3:0] newcrc;
begin
d = Data;
c = crc;
newcrc[0] = d[3] ^ d[0] ^ c[0] ^ c[3];
newcrc[1] = d[3] ^ d[1] ^ d[0] ^ c[0] ^ c[1] ^ c[3];
newcrc[2] = d[2] ^ d[1] ^ c[1] ^ c[2];
newcrc[3] = d[3] ^ d[2] ^ c[2] ^ c[3];
nextCRC4_D4 = newcrc;
end
endfunction
其實這段代碼有用的只是中間那四行行為級賦值語句,可以直接拷貝到工程里使用。其中d是4位的校驗數據,c是CRC寄存器。
用這段代碼做CRC校驗時,有幾點需要明確:
1)數據位寬。
2)輸入輸出是否高低位反轉。
3)c的初值。
4)輸出是否按位取反。
第1點取決於通信時1幀數據的長度,第2、3點一般在常用的CRC校驗模型中規定好了。這里的CRC-4/ITU校驗模型規定c的初值為0,輸出不取反,輸入輸出高低位反轉。
如果被校驗數據data只有4bit,那么直接令data高低位反轉,賦值給d。c=0,組合邏輯輸出的newcrc進行高低位反轉,得到的就是CRC校驗碼。
假如被校驗的數據位數大於4bit,需要分字節進行“疊加”校驗。
比如數據data[15:0]=1577h,那么可以按照這樣的校驗流程:
高字節低4bit(5h)反轉后賦值給d——newcrc作為下次校驗的c——高字節高4bit(1h)反轉后賦值給d——newcrc作為下次校驗的c的值——低字節低4bit(7h)反轉后賦值給d——newcrc作為下次校驗的c的值——低字節高4bit(7h)反轉后賦值給d——newcrc反轉后作為CRC校驗碼。
c的更新可以用寄存器實現。如下所示:
reg [3:0] c;
wire [3:0] d; //參與校驗數據
assign d = {data_r[0], data_r[1], data_r[2], data_r[3]};//翻轉數據位
assign newcrc[0] = crc_en & (d[3] ^ d[0] ^ c[0] ^ c[3]);
assign newcrc[1] = crc_en & (d[3] ^ d[1] ^ d[0] ^ c[0] ^ c[1] ^ c[3]);
assign newcrc[2] = crc_en & (d[2] ^ d[1] ^ c[1] ^ c[2]);
assign newcrc[3] = crc_en & (d[3] ^ d[2] ^ c[2] ^ c[3]);
always @(posedge clk or negedge rstn) begin
if(!rstn)
c <= 4'h0;//初始0
else begin
if(start_pos)
c <= 4'h0;
else if(crc_en)
c <= newcrc;
end
end
3 功能驗證
為了驗證上面修改的代碼功能,編寫了測試代碼,對16bit的數據求校驗碼。這里分別驗證data[15:0]=1577h,data[15:0]=4511h兩個數據的CRC校驗碼。
1)data[15:0]=1577h
在開發板上運行測試代碼,用signalTAP觀察結果,其中data_in為待校驗數據,經過4次計算,得到校驗碼為crc_out=0x2。

利用在線CRC計算工具(鏈接見我之前的博客)計算1577h的校驗碼,與測試結果一致:

2)data[15:0]=4511h
得到校驗碼為crc_out=0xF。

利用在線CRC計算工具(鏈接見我之前的博客)計算4511h的校驗碼,與測試結果一致:

這就說明,本文的“疊加”校驗,可以實現對多字節數據的“分段”校驗。多字節數據可以是4字節、16字節等,CRC校驗代碼中的輸入數據d可以是1bit、2bit、4bit、8bit等。
根據我的經驗,要實現“疊加”校驗,必須設置輸入輸出數據高低位反轉,不然結果不對。
也就是說如果你選的校驗模型不需要數據位反轉,那么只能做一次性的校驗,不能用本篇博客介紹的分段校驗的方式。具體原因咱也研究不清楚,不知道有沒有大神解答。
在線CRC代碼生成鏈接:
1、https://www.easics.com/crctool/
