You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Verilog 32位Galois LFSR代码case语句误触发default分支问题

32位Galois LFSR的Verilog代码错误排查

我正在学习Verilog,尝试实现一个抽头位于第32、22、2、1位(位编号1-based)的32位Galois型线性反馈移位寄存器(LFSR),但代码运行报错,相关代码和错误信息如下:

原代码

module top_module(
    input clk,
    input reset,    // 高电平有效同步复位至32'h1
    output [31:0] q
); 
    always @(posedge clk) begin
        if (reset)
            q <= 32'h1;
        else begin
            integer i;
            for (i=0; i<32; i=i+1) begin
                case (i)
                    0 : q[i] <= q[0] ^ q[i+1];
                    1 : q[i] <= q[0] ^ q[i+1];
                    21 : q[i] <= q[0] ^ q[i+1];
                    31 : q[i] <= q[0];
                    default : q[i] <= q[i+1];
                endcase
            end
        end
    end
endmodule

错误信息

Error (10232): Verilog HDL error at top_module.v(17): index 32 cannot fall outside the declared range [31:0] for vector "q" File: /home/h/work/hdlbits.14205831/top_module.v Line: 17

我的疑问:我猜测是i=31时误触发了case语句的default分支,但已经为该情况单独设置了分支,请问哪里出错了?


错误原因

问题不在于i=31时触发了default分支,而是Verilog编译器会检查case语句所有分支中的表达式合法性,无论该分支是否会被执行。当i=31时,default分支里的q[i+1]等价于q[32],超出了q[31:0]的位宽范围,因此编译器直接抛出越界错误,哪怕这个分支在i=31时根本不会被触发。

另外还有一个隐藏问题:原代码中output [31:0] q没有声明为reg类型,但在always块中对q进行了赋值,这也是不符合Verilog语法的,需要修正为output reg [31:0] q。

修正方案

方案一:直接按位赋值(推荐,逻辑更清晰)

避开for循环的潜在问题,直接按照Galois LFSR的移位规则编写逻辑:

module top_module(
    input clk,
    input reset,    // 高电平有效同步复位至32'h1
    output reg [31:0] q
); 
    always @(posedge clk) begin
        if (reset)
            q <= 32'h1;
        else begin
            // 先将所有位右移一位
            reg [31:0] next_q;
            next_q = q >> 1;
            // 处理抽头的反馈逻辑(抽头对应索引31、21、1、0,对应1-based的32、22、2、1位)
            next_q[31] = q[0];          // 最高位由原最低位反馈
            next_q[21] = q[22] ^ q[0];  // 第22位(索引21)与原最低位异或
            next_q[1] = q[2] ^ q[0];    // 第2位(索引1)与原最低位异或
            next_q[0] = q[1] ^ q[0];    // 第1位(索引0)与原最低位异或
            q <= next_q;
        end
    end
endmodule

方案二:拆分for循环,单独处理最高位

将for循环限制在0~30位,避免出现i=31时的越界表达式,再单独处理第31位:

module top_module(
    input clk,
    input reset,    // 高电平有效同步复位至32'h1
    output reg [31:0] q
); 
    always @(posedge clk) begin
        if (reset)
            q <= 32'h1;
        else begin
            integer i;
            // 处理0~30位
            for (i=0; i<31; i=i+1) begin
                case (i)
                    0 : q[i] <= q[0] ^ q[i+1];
                    1 : q[i] <= q[0] ^ q[i+1];
                    21 : q[i] <= q[0] ^ q[i+1];
                    default : q[i] <= q[i+1];
                endcase
            end
            // 单独处理第31位
            q[31] <= q[0];
        end
    end
endmodule

内容的提问来源于stack exchange,提问作者Anish Das

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 05:16:03