目录

  1. 时延概述
  2. Verilog 中的时延类型
  3. 延迟赋值
  4. 连续赋值的时延
  5. 时延控制语句
  6. 时延实例
  7. 参考资料

时延概述

在 Verilog 中,时延用于模拟电路中的信号传播延迟或操作延迟。时延控制语句或时延赋值在仿真中非常重要,因为它们能够帮助描述信号或事件的延迟行为。通过引入时延,可以更准确地模拟现实电路中的传输延时。

Verilog 提供了几种方式来控制时延,这包括连续赋值中的时延、过程块中的时延控制、以及时间单位(timescale)的使用。


Verilog 中的时延类型

在 Verilog 中,时延通常有两种形式:

  1. 连续赋值时延:用于描述连续赋值语句中的信号延迟。
  2. 过程块时延:用于过程块中,控制代码执行的延时。

1. # 时延(延迟赋值)

  • # 符号用于表示延迟时间。
  • 延迟时间可以是数值常量,表示信号变化的延时。

2. @ 时延控制(事件控制)

  • @ 符号用于事件控制,在指定的事件发生后执行某些操作。
  • 事件控制可以加上延迟,从而设置时延。

延迟赋值

延迟赋值指的是在某个特定的时延后,对信号进行赋值。在 Verilog 中,通过在赋值语句中使用 # 来指定延迟时间。

基本语法:

#delay_time expression;

  • delay_time 是延迟的时间,通常是一个数值常量,单位可以是时间单位(如 ns、ps)。
  • expression 是赋给信号的值。

示例:

module delay_example;
    reg a, b;
    wire c;

    assign #5 a = b;  // 延迟 5 时间单位后将 b 的值赋给 a
endmodule

在上面的例子中,a 的值会在 5 个时间单位后被更新为 b 的值。


连续赋值的时延

在连续赋值中,也可以使用时延控制来控制信号变化的时间。通常情况下,时延用于仿真中,以模拟信号传播的延迟。

示例:

module delayed_signal;
    reg a, b;
    wire c;
    
    assign #10 c = a & b;  // 按位与的结果将延迟 10 时间单位赋值给 c
endmodule

在这个例子中,c 的值在 a & b 计算后会延迟 10 个时间单位。


时延控制语句

Verilog 中还提供了时延控制语句,可以在时序块(如 initialalways 块)中控制执行的时延。

语法:

#delay_time;

  • delay_time 是延迟时间,通常是一个常量或者表达式,表示要延迟的时间。

示例:

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

在这个例子中,a 会在 5 时间单位后更新为 b 的值。

使用 @ 语句控制时延

Verilog 也可以使用 @ 来控制执行时延,这通常用于事件驱动的行为。

语法:

@ (event_expression) #delay_time;

  • event_expression 是一个事件表达式,可以是信号的变化、时钟边沿等。
  • delay_time 是延迟时间。

示例:

module event_control_example;
    reg clk, a, b;
    
    initial begin
        clk = 0;
        a = 0;
        b = 1;
    end
    
    always begin
        #5 clk = ~clk;  // 每 5 时间单位反转一次时钟信号
    end
    
    always @ (posedge clk) begin
        #2 a = b;  // 在时钟上升沿后延迟 2 时间单位,将 b 的值赋给 a
    end
endmodule

在这个例子中,a 会在 clk 的上升沿后延迟 2 个时间单位更新为 b 的值。


时延实例

以下是一个包含延迟赋值和时延控制语句的完整示例:

module delay_example;
    reg clk, a, b;
    wire c;

    // 时钟生成
    always begin
        #5 clk = ~clk;  // 时钟信号每 5 时间单位反转一次
    end
    
    // 在时钟上升沿后延迟赋值
    always @ (posedge clk) begin
        #2 a = b;  // 延迟 2 时间单位将 b 的值赋给 a
    end
    
    // 组合逻辑,按位与
    assign #3 c = a & b;  // 按位与的结果延迟 3 时间单位赋给 c
    
    initial begin
        clk = 0;
        a = 0;
        b = 1;
        #10 b = 0;  // 在 10 时间单位后将 b 的值改为 0
        #20 $finish;  // 结束仿真
    end
endmodule

在这个示例中:

  1. 时钟信号 clk 每 5 时间单位反转一次。
  2. 每次 clk 的上升沿会延迟 2 时间单位,将 b 的值赋给 a
  3. 连续赋值语句使用时延 #3,表示将 a & b 的结果延迟 3 时间单位赋给 c
  4. 在仿真开始后 10 时间单位,b 的值被更改为 0,这将影响后续的赋值和计算。

参考资料