少于 1 分钟阅读 次阅读

FPGA状态机赋值核心原则是时序逻辑用非阻塞赋值 (<=),组合逻辑用阻塞赋值 (=)。通常采用三段式结构:第一段时序逻辑负责状态寄存器更新,第二段组合逻辑负责状态跳转条件判断,第三段逻辑负责输出(建议时序输出以消除毛刺)。

1 详细赋值原则与结构

  • 状态跳转(时序逻辑): 在 always @(posedge clk or negedge rst_n) 块中,使用非阻塞赋值更新当前状态:current_state <= next_state;。
  • 状态控制(组合逻辑): 在 always @(*) 块中,使用阻塞赋值判断下一状态:next_state = …;。
  • 状态输出(建议时序): 在 always @(posedge clk or negedge rst_n) 块中,使用非阻塞赋值更新输出,以避免组合逻辑的毛刺现象。

三段式状态机示例:

// 1. 时序逻辑,状态切换
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) current_state <= IDLE;
    else        current_state <= next_state; // <= 非阻塞
end

// 2. 组合逻辑,下一状态判断
always @(*) begin
    case (current_state)
        IDLE: if (start) next_state = WORK; // = 阻塞
              else       next_state = IDLE;
        WORK: next_state = IDLE;
        default: next_state = IDLE;
    endcase
end

// 3. 时序逻辑,输出
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) out <= 1'b0;
    else if (next_state == WORK) out <= 1'b1; // <= 非阻塞
    else out <= 1'b0;
end

1.1 关键点总结:

  • 禁止混合: 严禁在同一个 always 块中混合使用 = 和 <=。
  • 阻塞与非阻塞: 组合逻辑用 =,为了立即更新;时序逻辑用 <=,为了并行操作。
  • 安全性: 使用时序输出可有效消除状态机输出毛刺。

2 关于毛刺(Glitch)的预防

毛刺(Glitch)是指信号在达到稳定状态之前,由于内部路径延迟不同而产生的短暂、错误的尖峰脉冲。

2.1 毛刺的产生原因

毛刺的根本原因是信号通过不同逻辑门或走线的“速度”不一样(即传播延迟)。

假设状态机从状态 A (2'b01) 切换到状态 B (2'b10)

  1. 在理想情况下,两个比特位应该同时翻转。
  2. 但在物理实现中,第 1 位变 0 稍微快了一点点,而第 0 位变 1 稍微慢了一点点。
  3. 那么在极短的瞬间(比如几个皮秒),逻辑电路看到的中间态就是 2'b00

如果你的输出逻辑是 assign out = (state == 2'b00),那么这个 out 信号就会瞬间跳成高电平,然后立刻变回低电平。这个瞬间的高电平就是毛刺。

2.2 使用D触发器避免

always @(posedge clk) begin
    base_pwr_allow <= (state == ST_ALLOW);
end

这种写法叫做寄存器输出。它的原理是:

  1. 滤除过程中的杂乱: 无论组合逻辑在时钟周期内怎么跳动(毛刺乱飞),D触发器(Register)都视而不见。
  2. 定点采样: 只有在时钟的上升沿那一刻,D触发器才会去抓取当时的稳定值。
  3. 干净输出: 一旦抓取完成,输出就在整个时钟周期内保持恒定,绝对不会有中间的抖动。

标签:

分类:

更新时间:

留下评论