FPGA 学习系列(4):Verilog 时序逻辑设计

FPGA 学习系列(4):Verilog 时序逻辑设计

在 FPGA 设计中,时序逻辑(Sequential Logic) 是构建存储和控制电路的关键部分,与组合逻辑不同,时序逻辑依赖时钟信号(Clock)和寄存器(Register)来存储和处理数据。本篇博客将介绍 Verilog 时序逻辑设计的基本方法,包括 always @(posedge clk) 语法、寄存器、触发器以及有限状态机(FSM)设计。


1. 什么是时序逻辑?

时序逻辑依赖 时钟信号 进行数据存储和更新。典型的时序逻辑电路包括:

  • 触发器(D 触发器、JK 触发器等)
  • 移位寄存器(Shift Register)
  • 计数器(Counter)
  • 有限状态机(Finite State Machine, FSM)

下图展示了一个典型的时序逻辑结构:

+------------+  时钟输入 clk
| 寄存器单元 |  输入信号 D
|  (触发器)  | --->  输出信号 Q
+------------+

时序逻辑的核心特点:

  1. 存储数据:状态由寄存器存储,直到下一个时钟沿更新。
  2. 同步更新:所有时序逻辑电路在时钟信号的上升沿或下降沿触发。
  3. 受时序约束:数据更新必须满足建立时间(Setup Time)和保持时间(Hold Time)。

2. Verilog 时序逻辑设计方法

2.1 always @(posedge clk)

Verilog 时序逻辑通常使用 always @(posedge clk) 代码块:

always @(posedge clk) begin
    q <= d;  // d 触发器:时钟上升沿采样 d,并存入 q
end
  • posedge clk 表示 时钟上升沿 触发更新。
  • 使用 非阻塞赋值 (<=),以确保寄存器同步更新。

3. 时序逻辑实例

3.1 D 触发器(基本存储单元)

module d_flip_flop (
    input wire clk, d,
    output reg q
);
    always @(posedge clk) begin
        q <= d;  // 时钟上升沿更新数据
    end
endmodule
  • d 为输入信号,在 clk 上升沿时存入 q

3.2 4 位移位寄存器(Shift Register)

module shift_register (
    input wire clk,
    input wire d,
    output reg [3:0] q
);
    always @(posedge clk) begin
        q <= {q[2:0], d};  // 向左移位,输入 d 进入最低位
    end
endmodule
  • q 的内容在每个 clk 上升沿 左移一位,新数据 d 进入最低位。

3.3 计数器(Counter)

module counter (
    input wire clk, rst,
    output reg [3:0] count
);
    always @(posedge clk or posedge rst) begin
        if (rst)
            count <= 4'b0000;  // 复位时清零
        else
            count <= count + 1;  // 计数递增
    end
endmodule
  • rst异步复位 信号,高电平时立即清零 count
  • countclk 上升沿 递增

3.4 2 位有限状态机(FSM)

FSM 是控制逻辑的核心,如通信协议、指令解析、流水线控制等。

(1) FSM 状态定义
typedef enum logic [1:0] {
    S_IDLE  = 2'b00,  // 空闲状态
    S_LOAD  = 2'b01,  // 载入数据
    S_EXEC  = 2'b10   // 执行操作
} state_t;
  • S_IDLE:初始状态,等待触发。
  • S_LOAD:数据载入状态。
  • S_EXEC:执行操作。
(2) FSM 状态机设计
module fsm_example (
    input wire clk, rst, start,
    output reg [1:0] state
);
    always @(posedge clk or posedge rst) begin
        if (rst)
            state <= S_IDLE;  // 复位时回到初始状态
        else begin
            case (state)
                S_IDLE:  if (start) state <= S_LOAD;
                S_LOAD:  state <= S_EXEC;
                S_EXEC:  state <= S_IDLE;
                default: state <= S_IDLE;
            endcase
        end
    end
endmodule
  • rst 复位状态机至 S_IDLE
  • start 触发状态转换,按照 IDLE → LOAD → EXEC 的顺序执行。

4. 时序逻辑优化技巧

  1. 避免组合逻辑反馈

    • 确保 always @(posedge clk) 代码块只用于时序逻辑,避免误用 always @(*) 造成不稳定反馈。
  2. 使用非阻塞赋值 (<=)

    • 时序逻辑必须用 <=,保证寄存器同步更新:
      always @(posedge clk) begin
          q <= d;  // 正确
      end
      
    • 若使用 =,可能导致竞争问题:
      always @(posedge clk) begin
          q = d;  // 可能会产生竞态
      end
      
  3. 优化 FSM 状态数量

    • 状态机设计应尽量减少状态数量,避免冗余状态影响性能。
  4. 使用同步复位

    • 同步复位 (always @(posedge clk)) 更易满足 FPGA 时序约束:
      always @(posedge clk) begin
          if (rst) q <= 0;
          else q <= d;
      end
      

5. 结语

本篇博客介绍了 Verilog 时序逻辑设计 的基本方法,包括 always @(posedge clk) 语法、D 触发器、移位寄存器、计数器和 FSM 设计。在 FPGA 设计中,时序逻辑用于数据存储、流水线控制和信号同步,是所有复杂电路的基础。

下一期:《FPGA 学习系列(5):Verilog 设计仿真与调试》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值