首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用verilog实现CRC32模块

用verilog实现CRC32模块
EN

Stack Overflow用户
提问于 2014-08-16 08:56:50
回答 1查看 4.6K关注 0票数 0

我对FPGA有点陌生。今年夏天,我有一个关于这个领域的项目,正在用4端口实现以太网交换机。我已经编码了所有的部分,以检查前导和MAC地址等,他们工作正常,但我有严重的问题,实现CRC32。

  • 我知道IEEE 802.3的CRC32算法。
  • 然后,用18字节的数据创建了一个框架。
  • 然后用这个小程序生成我的帧的CRC (这是一个链接

但是对于我制作的任何帧,校验CRC的结果都是错误的(用我的模块来说,每个帧都有错误)。

我很乐意知道你的意见

下面是我的CRC32模块代码:

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

发布于 2014-08-18 05:53:00

CRC计算是在每比特基础上实现的。因此,每个输入数据字-让我们说每时钟周期一个字节@ 125 MHz千兆位以太网-结果是8个CRC计算每时钟周期。因此,您的代码需要一个额外的循环来完成这8个子周期的计算。

我还建议您将fsm分解为控制状态机和crc计算(数据路径)。

正如Mark注意到的,CRC内部LFSR的初始值必须用0xFFFFFFF初始化。我能从你的代码中看到这个。

你为什么在你的过程中使用两个不同的时钟?

编辑1:

我不太擅长编写verilog,所以我将从我们的VHDL库中复制一些VHDL代码。我认为您将能够将这些语句转换为相应的verilog代码。我避免了使用重置和时钟启用的单独注册进程:)

代码语言:javascript
复制
-- 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;
  • 位是一个泛型,并设置为32。
  • lfsr (线性反馈移位寄存器)宽32位,存储当前的“校验和”。
  • 临时工。变量v由当前寄存器值(lfsr)初始化。
  • for循环遍历din (数据中)的每一位,并执行crc计算(shift + xor)。
  • =>因此每个时钟周期执行32次CRC计算。
  • GN是CRC32的归一化生成多项式
  • 结果存储在lfsn (下一个lfsr值)中,该值连接到32位宽的D,并启用重置和时钟功能。
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25338537

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档