目录

  1. 时序控制概述
  2. Verilog 时序控制语句
    • @ 事件控制
    • # 时延控制
    • posedgenegedge 控制
  3. 时序控制的应用
    • 时钟边沿触发
    • 同步复位
  4. 时序控制实例
  5. 参考资料

时序控制概述

时序控制是数字电路中至关重要的组成部分,特别是在时序电路中。Verilog 提供了多种机制来控制过程的执行时序,如通过事件控制、时延控制和时钟边沿触发等。这些控制语句允许用户精确地指定何时、如何进行赋值和更新,确保逻辑符合时序要求。

时序控制的关键点:

  • 时序控制主要通过时钟信号和事件触发来实现。
  • 事件控制和时延控制可以对过程的执行时机进行精细控制。
  • 时序控制有助于准确地描述同步与异步电路行为。

Verilog 时序控制语句

@ 事件控制

@ 符号用于指定触发某个过程的事件。Verilog 中的 always 过程和 initial 过程常常结合 @ 事件控制来精确地描述何时执行过程。

语法:

always @ (sensitivity_list) begin
    // 过程体
end

  • sensitivity_list 可以是一个信号或多个信号。当这些信号发生变化时,always 过程会触发执行。

示例:

module event_control_example(input clk, reset, output reg [3:0] counter);
    always @ (posedge clk or posedge reset) begin
        if (reset)
            counter <= 4'b0000;  // 复位操作
        else
            counter <= counter + 1;  // 计数器加 1
    end
endmodule

在这个例子中,always 过程会在 clk 的上升沿或者 reset 的上升沿触发。当 reset 被置高时,counter 会被清零;否则,counter 会在每个时钟上升沿加 1。


# 时延控制

# 符号用来在 Verilog 中插入时延,使得某些操作或事件在特定的延时后发生。这通常用于组合逻辑的建模,或在仿真中模拟信号延迟。

语法:

#(time_delay) variable = expression;

  • time_delay 是一个数值,表示在执行当前赋值之前的延迟时间。

示例:

module delay_example;
    reg a, b;
    initial begin
        a = 0;
        b = 1;
        #5 a = b;  // 延迟 5 时间单位后将 b 的值赋给 a
    end
endmodule

在这个例子中,a 会在延迟 5 时间单位后更新为 b 的值。这种延迟控制通常用于仿真,模拟某些物理延迟的现象。


posedgenegedge 控制

posedgenegedge 分别表示时钟信号的上升沿和下降沿。在时序电路中,通常使用这些控制来描述时钟边沿触发的行为。

语法:

always @ (posedge clk) begin
    // 时钟上升沿触发的操作
end

always @ (negedge clk) begin
    // 时钟下降沿触发的操作
end

示例:

module clock_edge_example(input clk, reset, output reg [3:0] counter);
    always @ (posedge clk or posedge reset) begin
        if (reset)
            counter <= 4'b0000;  // 复位时清零
        else
            counter <= counter + 1;  // 每次时钟上升沿计数
    end
endmodule

在该示例中,always 过程会在时钟信号 clk 的上升沿触发。当 reset 置高时,counter 会被清零;否则,在每个时钟上升沿,counter 会加 1。


时序控制的应用

时钟边沿触发

在时序电路中,最常见的触发机制是时钟边沿触发。这意味着电路的行为(如计数器、寄存器等)在时钟信号的上升沿或下降沿时才会更新状态。

示例:时钟上升沿触发的计数器

module counter(clk, reset, counter);
    input clk, reset;
    output reg [3:0] counter;
    
    always @ (posedge clk or posedge reset) begin
        if (reset)
            counter <= 4'b0000;
        else
            counter <= counter + 1;
    end
endmodule

这个计数器会在时钟的上升沿触发,并在每个时钟周期加 1,直到达到复位信号时清零。

同步复位

同步复位是一种常见的控制机制,通过时钟信号同步复位信号来确保复位过程不会受到时钟抖动或异步信号的影响。

示例:同步复位

module sync_reset(input clk, reset, output reg [3:0] counter);
    always @ (posedge clk) begin
        if (reset)
            counter <= 4'b0000;  // 同步复位
        else
            counter <= counter + 1;
    end
endmodule

在这个例子中,复位信号 reset 是同步的,只有在时钟上升沿到来时才会检查复位信号,并根据复位状态更新 counter


时序控制实例

示例 1:时钟边沿触发的 D 型触发器

module d_flip_flop(input clk, reset, d, output reg q);
    always @ (posedge clk or posedge reset) begin
        if (reset)
            q <= 0;  // 复位时清零
        else
            q <= d;  // 将输入信号 d 赋值给输出 q
    end
endmodule

在这个例子中,D 型触发器会在时钟上升沿时捕获输入信号 d 的值,并将其传递到输出 q。如果复位信号为高,q 会被清零。

示例 2:计数器与时钟边沿触发

module counter_with_clock(input clk, reset, output reg [3:0] counter);
    always @ (posedge clk or posedge reset) begin
        if (reset)
            counter <= 4'b0000;  // 复位时计数器清零
        else
            counter <= counter + 1;  // 每次时钟上升沿计数
    end
endmodule

这个计数器模块会在时钟的每个上升沿触发,计数器的值加 1,复位信号会将其清零。


参考资料