我对FPGA有点陌生。今年夏天,我有一个关于这个领域的项目,正在用4端口实现以太网交换机。我已经编码了所有的部分,以检查前导和MAC地址等,他们工作正常,但我有严重的问题,实现CRC32。
但是对于我制作的任何帧,校验CRC的结果都是错误的(用我的模块来说,每个帧都有错误)。
我很乐意知道你的意见
下面是我的CRC32模块代码:
module CRC( clk10x, clk, rst, SFD, length, lengthReady, dataIn, hasError//, MACready
);
.
.
// input and outputs and registers are here
.
.
.
initial
begin
CRC <= 32'h04C11DB7;
zeros <= 32'h00000000;
end
always @ ( posedge clk10x )
begin
if ( rst )
begin
counter32bit <= 0;
shiftFlag <= 1;
shift <= 0;
shift2 <= 0;
first32bit <= 0;
state <= 0;
index <= 0;
calcEnd <= 0;
end
else if ( clk )
begin
if ( SFD )
begin
case ( state )
'b00 : begin
first32bit <= ( counter32bit == 32 ) ? 1 : 0;
state <= ( first32bit ) ? 'b01 : 'b00;
{MSB, window} <= {window, ~dataIn}; // shift Register;
counter32bit <= counter32bit + 1;
end
'b01 : begin
{MSB, window} <= ( MSB ) ? ( {window, dataIn} ^ CRC ) : {window, dataIn};
shift <= ( lengthReady && shiftFlag ) ? ( length * 8 ) : shift - 1;
shiftFlag <= ( lengthReady ) ? 0 : shiftFlag;
shift2 <= ( shift == 0 && lengthReady ) ? 32 : shift2 -1;
//shift2 <= ( !shift2 ) ? shift2 - 1 : shift2;
state <= ( shift2 == 2 && lengthReady ) ? 'b10 : 'b01;
end
'b10 : begin
{MSB, window} <= ( MSB && !calcEnd ) ? ( {window, zeros[index]} ^ CRC ) : {window, zeros[index]};
index <= ( index == 32 && !calcEnd ) ? 40 : index + 1;
calcEnd <= ( index == 40 ) ? 1 : 0;
state <= ( calcEnd ) ? 'b11 : state;
end
'b11 : begin
window <= window ^ 32'b11111111_11111111_11111111_11111111;
hasError <= ( window == 0 ) ? 0 : 1;
end
default : begin
//state <= 0;
first32bit <= 0;
//shift <= 0;
end
endcase
// have to assign index 0 again
end发布于 2014-08-18 05:53:00
CRC计算是在每比特基础上实现的。因此,每个输入数据字-让我们说每时钟周期一个字节@ 125 MHz千兆位以太网-结果是8个CRC计算每时钟周期。因此,您的代码需要一个额外的循环来完成这8个子周期的计算。
我还建议您将fsm分解为控制状态机和crc计算(数据路径)。
正如Mark注意到的,CRC内部LFSR的初始值必须用0xFFFFFFF初始化。我能从你的代码中看到这个。
你为什么在你的过程中使用两个不同的时钟?
编辑1:
我不太擅长编写verilog,所以我将从我们的VHDL库中复制一些VHDL代码。我认为您将能够将这些语句转换为相应的verilog代码。我避免了使用重置和时钟启用的单独注册进程:)
-- Compute next combinational Value
process(lfsr, din)
variable v : std_logic_vector(lfsr'range);
begin
v := lfsr;
for i in BITS-1 downto 0 loop
v := (v(v'left-1 downto 0) & '0') xor
(GN and (GN'range => (din(i) xor v(v'left))));
end loop;
lfsn <= v;
end process;https://stackoverflow.com/questions/25338537
复制相似问题