记一个Verilog一段式状态机的低级错误

本文探讨了在QuartusII环境下使用Verilog实现状态机时遇到的逻辑错误。具体表现为在特定状态下的输出值无法根据输入实时更新,仅在状态转换时才更新。通过对比原代码与综合后的电路逻辑,揭示了代码歧义导致的问题,并提供了正确的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题是这样的:
我想在某个状态state1下根据输入a改变输出b的值,但是在芯片里运行的时候发现只要状态维持在state1下,b的值始终是从上一个状态跳到state1时的值,只有在state1变化的边沿,b的值才会根据输入a更新。

环境:quartus II 12.1

原代码如下:

always @ (posedge clk) 
begin
    if (rst) begin
        b <= 'd0;
        state <= state1;
    end else begin
        case (state):
            state1: begin
                if (a) b <= 'd1;        // 逻辑1
                if (c) state <= state2; // 逻辑2
            end
            state2:
            default:
        endcase
    end
end

这个代码看起来好像没什么问题,在state1下b的值跟随条件a变化(逻辑1),满足条件c则进行状态跳转(逻辑2)。
但实际上state1里的逻辑是这样的(综合后的电路逻辑):

if (c) begin
    state <= state2;
    if (a) b <= 'd1;
end else begin
    state <= state;
    b <= b;
end

跟我想要的逻辑完全不一样,而且掉入这样的坑里面之后,半天爬不出来。在原代码里忽略了if…else…的优先级,本来逻辑1、逻辑2是可以分开的,但必须是写在两个always里才可以,这里写在一个always里,综合工具就不能理解代码的意思了,因为可以分开也可以不分开,代码有歧义。

修改后的代码如下:

always @ (posedge clk) 
begin
    if (rst) begin
        b <= 'd0;
        state <= state1;
    end else begin
        case (state):
            state1: begin
                if (c) begin
                    state <= state2;
                    if (a) b <= 'd1;
                end else begin
                    state <= state1;
                    if (a) b <= 'd1;
                end
            end
            state2:
            default:
        endcase
    end
end

如果是三段式状态机就不会存在这样的问题,所以如果状态机比较大,状态数很多,个人觉得还是三段式好一点,至少出了问题好分析。

.
.
.
.
.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值