1 CRC算法
如 POLY=10011;
输入DATA=11100110;
- POLY位宽=5;
- 将DATA后面添加5-1=4位个0;DATA=111001100000;
- 将CRC=4'b0和DATA拼在一起,DATA={CRC,DATA}
- DATA从高到低,每次计算最高位如果为1,则次高4位和POLY做异或计算,否则与0做异或计算;
- 最后1 bit做完除法,即得到CRC:
CRC的演算:
2 Verilog 快速验证
硬件实现算法可以先load 4bit data到crc_sft逻辑,然后做8次循环,每次data左移1bit数据到crc_sht,如果crc_sft最高位为1,则crc_sft和poly做异或运算;
module crc_test;
//1 stimulator defination
logic clk;
logic rst_n;
logic [11:0] data;
logic [3:0] poly;
logic [3:0] crc;
logic [4:0] crc_sft;
integer i;
//2 algorithm defination
always@(*) begin
crc_sft=5’b0; //load the crc initial var;
for(i=0;i<12;i=i+1) begin //loop 12 for the other data caculation
crc_sft ={crc_sft[3:0],data[7-i]};
crc_sft[3:0] =crc_sft[4] ? crc_sft[3:0]^poly : crc_sft[3:0];
$display("round:%d,data is %b, shift in bit is:%b,crc is: %b",i,data,data[7-i]),crc_sft[3:0]
end
end
always@(posedge clk or nededge rst_n) begin
if(rst_n==1'b0)
crc<=4'b0;
else
crc<=crc_sft[3:0];
end
//3 start the stimulator
initial begin
clk=1'b0;
forever #10 clk=~clk;
end
initial begin
rst_n=1'b0;
data=0;
poly=4'b0011;
#30 rst_n=1'b1;
#100 data=12'b1110_0110_0000;
#3000 $finish()
end
//4 dump wave files
initial begin
$fsdbDumpfile("top_tb.fsdb");
$fsdbDumpvars;
end
endmodule
3 makefile
case := crc
file := $(addsuffix .sv,$(case))
comp:
vcs -sverilog -debug_access $(file)
sim:
./simv
run: comp sim
clean:
rm -r *log *fsdb *.key csrc verdiLog simv.daidir simv *.rc *.conf
4 测试举例
make run case=crc4_1
测试结果:
5 总结
遇到bit类的运算等和数字硬件强烈相关的操作,总感觉使用C或python等语言构建模型,仿真还是太不直观;本文给出了一种简单的方法来验证此类算法设计;