Menu
CoddyTech

赋值延迟

本课属于 Coddy Verilog 学习旅程的“基础知识”单元。第 69 课,共 90 课。

在之前的课中,我们学习了普通延迟(#10 a = b;)和门延迟(and #5 (out, a, b);)。现在,我们来学习赋值延迟,也就是在过程块(如 initial 或 always)内部,作为赋值语句一部分发生的延迟。

赋值延迟会等待指定的时间,然后执行赋值操作。延迟放在 # 符号之后,赋值之前。

语法:

variable = #delay expression;

与常规延迟 #10 a = b;(先延迟,再赋值)不同,赋值延迟 a = #10 b; 会先获取此刻 b 的值,等待 10 个时间单位,然后将其赋给 a。

赋值延迟与一般延迟

 一般延迟赋值延迟
语法#10 a = b;a = #10 b;
何时读取值?赋值时(延迟之后)立即(延迟之前)
赋的是什么值?当时 b 的值时间 0 时(或读取时)b 的值
何时赋值?延迟之后延迟之后

示例:区别

initial begin
  b = 1;
  #5 b = 0;
  
  // 普通延迟
  #10 a1 = b;     // 等待 10 后读取 b(b=0),得到 a1=0
  
  // 赋值延迟
  a2 = #10 b;     // 现在读取 b(b=0),等待 10 后再赋值,得到 a2=0
end

在这里,两者的结果相同。区别会在延迟期间 b 发生变化时显现出来。

关键差异示例

To show b changing during the delay, we need two separate initial blocks that run in parallel:

initial begin
  b = 1;
  a1 = #10 b;     // 在时间 0 读取 b=1,在时间 10 将 a1 赋值为 1
end

initial begin
  #5 b = 0;       // 在时间 5 将 b 改为 0(延迟期间)
end
  • 在时间 0:a1 读取 b = 1
  • 在时间 5:b 变为 0(此时 a1 仍在等待)
  • 在时间 10:a1 被赋值为 1(在时间 0 读取的值),而不是 0

如果在单独的代码块中使用普通延迟 #10 a2 = b;,则会在时间 10 读取 b(值为 0)。

重要规则

规则说明
= 放在 # 前面写作 a = #10 b;,而不是 a #10 = b;
立即读取值右侧会立即求值
延迟后进行赋值左侧稍后获取该值
仅用于过程块用于 initial 或 always
challenge icon

挑战

要做什么:

添加缺失的赋值延迟,使 a 在 15 个时间单位后获得 b 的值,但立即读取 b。

亲手试试

module assignment_challenge;
  reg a, b;
  
  // 用单独的代码块在延迟期间修改 b
  initial begin
    b = 1;
    // TODO: 添加赋值延迟
    // 经过 15 个时间单位后,a 应获得 b 的值
    // 现在读取 b,延迟后再赋值

  end
  
  initial begin
    #5 b = 0;      // 在延迟期间修改 b
    #20 $display("Time %0t: a = %b", $time, a);
    $finish;
  end
endmodule
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

基础知识中的所有课

自己练习: Verilog 在线编译器