关于CRC的一些问题
时间:10-02
整理:3721RD
点击:
这个一个CRC-16校验码产生模块,并行输出,代码如下:
module CRC(
input wire clk,
input wire rst_n,
input wire En_Sig,
input wire[7:0] Data_In,
output reg[15:0] CRC_Out);
reg[4:0] i ,j, k, l;
reg[15:0] CRC_Temp;
reg temp;
always @ (posedge clk)
begin
if(rst_n == 1'b0)
CRC_Out <= 16'd0;
else
CRC_Out <= CRC_Temp;
end
always @ (CRC_Out or Data_In or rst_n)
begin
if(rst_n == 1'b0) begin
CRC_Temp = 16'd0;
i = 5'd0;
j = 5'd0;
k = 5'd0;
l = 5'd0;
temp = 0;
end
else begin
//CRC_Temp = CRC_Out;
if(En_Sig == 1'b1) begin
for( i = 5'd7;i >= 5'd0;i = i - 5'b1) begin
temp = Data_In ^ CRC_Temp[15];
for(j = 5'd15; j > 5'd12; j = j - 5'b1)
CRC_Temp[j] = CRC_Temp[j-1];
CRC_Temp[12] = CRC_Temp[11] ^ temp;
for(k = 5'd11; k > 5'd5; k = k - 5'b1)
CRC_Temp[k] = CRC_Temp[k-1];
CRC_Temp[5] = CRC_Temp[4] ^ temp;
for(l = 5'd4;l > 5'd0;l =l- 5'b1)
CRC_Temp[l] = CRC_Temp[l-1];
CRC_Temp[0] = temp;
end
end
end
end
endmodule
此程序原理图如下:

简单测试代码如下:
`timescale 1ns/1ns
module CRC_tb;
reg clk;
reg rst_n;
reg En_Sig;
reg[7:0] Data_In;
wire[15:0] CRC_Out;
CRC dut(.clk(clk),
.rst_n(rst_n),
.En_Sig(En_Sig),
.Data_In(Data_In),
.CRC_Out(CRC_Out));
parameter period = 20;
always #(period/2) clk = ~clk;
initial
begin
clk = 0; rst_n = 1; En_Sig = 0; Data_In = 0;
#20 rst_n = 0;En_Sig = 1;
#20 rst_n = 1;
#20 Data_In=8'h99;
end
endmodule
问题:仿真只能到40ns就停止,找不到错误,仿真图如下:

求指导,谢谢!
module CRC(
input wire clk,
input wire rst_n,
input wire En_Sig,
input wire[7:0] Data_In,
output reg[15:0] CRC_Out);
reg[4:0] i ,j, k, l;
reg[15:0] CRC_Temp;
reg temp;
always @ (posedge clk)
begin
if(rst_n == 1'b0)
CRC_Out <= 16'd0;
else
CRC_Out <= CRC_Temp;
end
always @ (CRC_Out or Data_In or rst_n)
begin
if(rst_n == 1'b0) begin
CRC_Temp = 16'd0;
i = 5'd0;
j = 5'd0;
k = 5'd0;
l = 5'd0;
temp = 0;
end
else begin
//CRC_Temp = CRC_Out;
if(En_Sig == 1'b1) begin
for( i = 5'd7;i >= 5'd0;i = i - 5'b1) begin
temp = Data_In ^ CRC_Temp[15];
for(j = 5'd15; j > 5'd12; j = j - 5'b1)
CRC_Temp[j] = CRC_Temp[j-1];
CRC_Temp[12] = CRC_Temp[11] ^ temp;
for(k = 5'd11; k > 5'd5; k = k - 5'b1)
CRC_Temp[k] = CRC_Temp[k-1];
CRC_Temp[5] = CRC_Temp[4] ^ temp;
for(l = 5'd4;l > 5'd0;l =l- 5'b1)
CRC_Temp[l] = CRC_Temp[l-1];
CRC_Temp[0] = temp;
end
end
end
end
endmodule
此程序原理图如下:

简单测试代码如下:
`timescale 1ns/1ns
module CRC_tb;
reg clk;
reg rst_n;
reg En_Sig;
reg[7:0] Data_In;
wire[15:0] CRC_Out;
CRC dut(.clk(clk),
.rst_n(rst_n),
.En_Sig(En_Sig),
.Data_In(Data_In),
.CRC_Out(CRC_Out));
parameter period = 20;
always #(period/2) clk = ~clk;
initial
begin
clk = 0; rst_n = 1; En_Sig = 0; Data_In = 0;
#20 rst_n = 0;En_Sig = 1;
#20 rst_n = 1;
#20 Data_In=8'h99;
end
endmodule
问题:仿真只能到40ns就停止,找不到错误,仿真图如下:

求指导,谢谢!
我怀疑是时钟的位置放错了。你调整一下,放到init之后吧。
我觉得不是这个问题,毕竟always块跟initial块是并行的!
组合逻辑还是时序逻辑?
没明白小编的意思,是跑的结果不对还是你的仿真跑不下去
是跑不下去,等待许久,也就仿真到40ns!
死循环了。在描述i的那个for语句里,i>=5'd0永远成立,因为i是无符号的。
这是并行输出,要想在一个时钟内输出,只好借用组合逻辑!
好像是这么一回事,如果真是这样的话,那么将i,j,k,l改为integer型,不知这样妥否?或者有什么方法解决?
for( i = 5'd7;i <= 5'd7;i = i - 5'b1) begin
应该就是你要的效果。
当i=0时,再减1就变成5'h1F,就大于5'd7,循环就终止了。
好的,应该就是这样子,谢谢了!
