用Verilog實現CRC-8的串行計算,G(D)=D8+D2+D+1,計算流程如下圖所示:
一、分析
CRC循環冗余校驗碼(Cyclic Redundancy Check),檢錯碼。
(1)該題目所述為CRC-8,即輸出8位CRC校驗值,給定一段長為N-bit的有效輸入序列,輸出(N+8)-bit的數據,其中前N-bit數據為輸入的原始數據,添加的8-bit數據為CRC校驗數據;
(2)該CRC-8的生成多項式為G(D)=D8+D2+D+1,對CRC進行簡化表示時可以忽略最高位的D8,結合圖示中三個異或運算的位置更容易理解生成多項式,8位CRC有8個寄存器C0~C7,根據多項式,C0、C1和C2的輸入是由異或運算而來;
二、Verilog編程
1. 并行計算,串行輸出
對于輸入位寬為****1 的輸入,這種方法的計算非常簡單,直接根據生成多項式運算 。
( 注意! 如果輸入位寬不為1,則需要根據多項式進行化簡,可以生成運算邏輯和代碼)
1.1 自己一步一步寫
( 1 )先定義8個寄存器****reg [7:0]
reg [7:0] crc_reg_q;// 寄存器 Q 輸出端
reg [7:0] crc_reg_d;// 寄存器 D 輸入端
(對crc_reg_d,使用always賦值就定義成reg,使用assign就定義成wire)
( 2 )異或計算
** 寄存器0的輸入** crc_reg_d[0] ,來自寄存器7的輸出 crc_reg_q[7] 和數據輸入****data_in 異或運算 ,即:
crc_reg_d [0] = crc_reg_q[7] ^ data_in;
同理可得:
always @ (*)
begin
crc_reg_d[0] = crc_reg_q[7] ^ data_in;
crc_reg_d[1] = crc_reg_q[7] ^ data_in ^ crc_reg_q[0];
crc_reg_d[2] = crc_reg_q[7] ^ data_in ^ crc_reg_q[1];
crc_reg_d[3] = crc_reg_q[2];
crc_reg_d[4] = crc_reg_q[3];
crc_reg_d[5] = crc_reg_q[4];
crc_reg_d[6] = crc_reg_q[5];
crc_reg_d[7] = crc_reg_q[6];
end
上述使用組合邏輯實現異或運算和數據的傳遞,另外,對于每個寄存器的輸入到輸出(D端到Q端),使用時序邏輯,并且按照題目要求,設置初始值為全1,將數據有效標志作為控制邏輯:
always @ (posedge clk)
begin
if( rst)
crc_reg_q <= 8’hff;
elsebegin
if(data_valid )
crc_reg_q<= crc_reg_d;// 輸入數據有效就更新值
else
crc_reg_q<= crc_reg_q;// 輸入數據無效就等待
end
end
( 3 )串行輸出
上述已經實現了并行的 CRC,計算出的 CRC 結果就是直接的 8 位 CRC,按照題目要求,需要串行輸出 CRC 結果。
思路:寫一個計數器,當需要輸出 CRC 時,串行計數輸出,實現并串轉換。這里,由于題目給了一個信號 crc_start,我把這個信號作為 CRC 的標志,當 data_valid 有效時表示輸入的是數據,當 data_valid 無效且crc_start 有效表示數據輸入完畢,該輸出 CRC 了。
reg [2:0] count;
always @ (posedge clk)
begin
if(rst)begin
crc_out <= 0;
count<= 0;
end
elsebegin
if(data_valid) begin
crc_out <= data_in;
crc_valid <= 1'b0;
end
elseif(crc_start)begin
count <= count + 1'b1;
crc_out <= crc_reg_q [7-count];
crc_valid <= 1'b1;
end
elsebegin
crc_valid <= 1'b0;
end
end
end
1.2 CRC Generator自動生成
根據生成多項式,勾選1、X1、X2即可(對應1+D1+D2,最高位的D8不用管)。
//-----------------------------------------------------------------------------
// Copyright (C) 2009 OutputLogic.com
// This source file may be used and distributedwithout restriction
// provided that this copyright statement is notremoved from the file
// and that any derivative work contains theoriginal copyright notice
// and the associated disclaimer.
//
// THIS SOURCE FILE IS PROVIDED "ASIS" AND WITHOUT ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, WITHOUTLIMITATION, THE IMPLIED
// WARRANTIES OF MERCHANTIBILITY AND FITNESS FORA PARTICULAR PURPOSE.
//-----------------------------------------------------------------------------
// CRC module for data[0:0] , crc[7:0]=1+x^1+x^2+x^8;
//-----------------------------------------------------------------------------
module crc(
input [0:0] data_in,
input crc_en,
output [7:0] crc_out,
input rst,
input clk);
reg [7:0] lfsr_q,lfsr_c;
assign crc_out = lfsr_q;
always @(*) begin
lfsr_c[0] = lfsr_q[7] ^ data_in[0];
lfsr_c[1] = lfsr_q[0] ^ lfsr_q[7]^ data_in[0];
lfsr_c[2] = lfsr_q[1] ^ lfsr_q[7]^ data_in[0];
lfsr_c[3] = lfsr_q[2];
lfsr_c[4] = lfsr_q[3];
lfsr_c[5] = lfsr_q[4];
lfsr_c[6] = lfsr_q[5];
lfsr_c[7] = lfsr_q[6];
end // always
always @(posedge clk, posedge rst) begin
if(rst) begin
lfsr_q <= {8{1'b1}};
end
else begin
lfsr_q <= crc_en ? lfsr_c: lfsr_q;
end
end // always
endmodule // crc
將上述代碼按照題目要求改變輸入輸出的名稱,并進行串并轉換(并->串)即可。
1.3 easics自動生成
(1)1處選擇CRC的生成多項式,這里與1.2的不同在于,要把最高位的D8選上,easics能識別的CRC協議更多;
(2)2處自動識別出這個CRC多項式其實是CRC8 ATM HEC協議使用的 CRC;
(3)3處設置輸入數據位寬為1;
(4)選擇生成Verilog代碼;
(5)下載代碼。
仔細閱讀代碼注釋,注意!
convention: the first serial bit is D[0]
數據的最低位先輸出 ,此代碼將會把低位作為異或移出位,而上面已經提到的兩種方法均是將最高位作為移出位去異或, 所以,代碼中需要稍作修改 ,將d[0]改成d[7],d[1]改成d[6],…,以此類推,c[0]- c[7]不要變。
有興趣的可以去看看【大小端問題】,在不同處理器、不同協議中非常常見。
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1999-2008 Easics NV.
// This source file may be used and distributedwithout restriction
// provided that this copyright statement is notremoved from the file
// and that any derivative work contains theoriginal copyright notice
// and the associated disclaimer.
//
// THIS SOURCE FILE IS PROVIDED "AS IS"AND WITHOUT ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, WITHOUTLIMITATION, THE IMPLIED
// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR APARTICULAR PURPOSE.
//
// Purpose : synthesizable CRC function
// *polynomial: x^8 + x^2 + x^1 + 1
// * datawidth: 1
//
// Info : tools@easics.be
// http://www.easics.com
///////////////////////////////////////////////////////////////////////////////
module CRC8_D1;
//polynomial: x^8 + x^2 + x^1 + 1
// datawidth: 1
//convention: the first serial bit is D[0]
function[7:0] nextCRC8_D1;
inputData;
input[7:0] crc;
reg [0:0]d;
reg [7:0]c;
reg [7:0]newcrc;
begin
d[0] =Data;
c = crc;
newcrc[0]= d[0] ^ c[7];
newcrc[1]= d[0] ^ c[0] ^ c[7];
newcrc[2