CRC原理与快速Verilog仿真

1 CRC算法

如 POLY=10011;
输入DATA=11100110;

  1. POLY位宽=5;
  2. 将DATA后面添加5-1=4位个0;DATA=111001100000;
  3. 将CRC=4'b0和DATA拼在一起,DATA={CRC,DATA}
  4. DATA从高到低,每次计算最高位如果为1,则次高4位和POLY做异或计算,否则与0做异或计算;
  5. 最后1 bit做完除法,即得到CRC:

CRC的演算:


微信图片_20200819205200.jpg

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
测试结果:

image.png

5 总结

遇到bit类的运算等和数字硬件强烈相关的操作,总感觉使用C或python等语言构建模型,仿真还是太不直观;本文给出了一种简单的方法来验证此类算法设计;

你可能感兴趣的:(CRC原理与快速Verilog仿真)