1 程式碼生成
verilog實現CRC校驗,可以充分發揮FPGA的硬體特性,即並行運算的能力。
具體實現方式,可以參考我上一篇部落格,關鍵是用線性反饋移位暫存器表示出多項式,另外注意校驗資料高位在先。然後根據電路結構推匯出邏輯表示式,再轉換成verilog就行了。
更高效的方法是利用現成的程式碼生成工具,例如附件的連結1,就是一種線上的CRC校驗程式碼生成工具。
2 修改移植
我這裡用程式碼生成工具生成多項式為x^4 + x^1 + 1,即CRC-4/ITU校驗模型,校驗輸入資料位寬為4bit的CRC程式碼,並分享一下修改移植時的心得。
生成的程式碼如下,這個多項式和我上一篇部落格舉例所用多項式一樣,所以生成的程式碼之前推導的邏輯表示式也是相同的。
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點取決於通訊時一幀資料的長度,第2、3點一般在常用的CRC校驗模型中規定好了。這裡用的CRC-4/ITU校驗模型規定c的初值為0,輸出不需要取反,輸入輸出高低位需要反轉。
如果被校驗資料data只有4bit,那麼直接令data高低位反轉後賦值d,c=0,組合邏輯輸出的就是4位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觀察結果(電腦上沒有裝Modelsim),其中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/