Verilog 时间尺度

2025年3月17日 | 阅读 7 分钟

Verilog 仿真取决于时间的定义方式,因为仿真器需要知道 #1 在时间上意味着什么。`timescale 编译器指令指定了后续模块的时间单位和精度。

语法

time_unit 是延迟和仿真时间的测量单位,而 time_precision 指定了延迟值在仿真中使用之前如何进行四舍五入。

使用以下时间单位构造,以便在同一设计中使用不同的时间单位。设计中的延迟规范不可综合,也无法转换为硬件逻辑。

  • 'timescale 用于时间的基本测量单位和精度。
  • $printtimescale 系统任务用于显示时间单位和精度。
  • $time$realtime 系统函数返回当前时间,并且可以使用另一个系统任务 $timeformat 更改默认报告格式。
CharacterUnit
s
msmilliseconds
us微秒
ns纳秒
ps皮秒
fs飞秒

这些规范中的整数可以是 1、10 或 100,并且指定单位的字符串可以采用上表中提到的任何值。

示例 1: 1ns/1ns

第一个延迟语句使用 #1,使仿真器等待恰好 1 个时间单位,指定为 1ns 并且使用 `timescale 指令。第二个延迟语句使用 0.49,小于半个时间单位。

但是,时间精度指定为 1ns,并且仿真器不能小于 1 ns,这使得它对给定的延迟语句进行四舍五入并产生 0ns。因此,第二个延迟无法推进仿真时间。

第三个延迟语句使用恰好一半的时间单位 [hl]#0.5[/lh],并且仿真器再次将该值四舍五入以获得 #1,表示一个完整的时间单位。因此,此打印在 T=2ns 时进行。

第四个延迟语句使用大于半个时间单位的值,并且也被四舍五入,使得显示语句在 T=3ns 时打印。执行后,它给出以下输出

仿真按预期运行 8ns,但请注意,波形在每个纳秒之间没有更小的划分。这是因为时间的精度与时间单位相同。

示例 2: 10ns/1ns

与前一个示例相比,此示例中唯一的变化是将时间单位从 1ns/1ns 更改为 10ns/1ns。因此,时间单位为 10ns,精度为 1ns。

实际仿真时间是通过将使用 # 指定的延迟与时间单位相乘获得的,然后根据精度对其进行四舍五入。然后,第一个延迟语句将产生 10ns,第二个延迟语句将产生 14.9,四舍五入后变为 15ns。

第三个语句类似地添加 5ns (0.5 * 10ns),总时间变为 20ns。第四个语句再添加 5ns (0.51 * 10) 以将总时间推进到 25ns。

注意:波形中的基本单位以纳秒为单位,精度为 1ns。

示例 3: 1ns/1ps

与前一个示例相比,此示例中唯一的变化是将时间单位从 1ns/1ns 更改为 1ns/1ps。因此,时间单位为 1ns,精度为 1ps。

请注意,时间单位已缩放以匹配新的精度值 1ps。并且时间以最小分辨率表示,在本例中为皮秒。

默认时间单位

尽管希望 Verilog 模块在模块之前定义时间单位,但仿真器可能会插入默认时间单位。

可以使用系统任务 $printtimescale 打印在 Verilog 详细层次结构中的任何范围内应用的实际时间单位,该系统任务接受范围作为参数。

注意:此模块之前未放置时间单位指令。仿真器最终应用了 1ns/1ns 时间单位值。

标准时间单位范围

默认情况下,放置在文件中的时间单位指令将应用于指令之后的所有模块,直到另一个时间单位指令的定义为止。

在上面的示例中,tbalu 最终的时间单位为 1ns/1ns,而 des 的时间单位为 1ns/10ps,这是因为在定义 des 模块之前放置了指令。

Verilog 文件

可以使用 `include 指令将其他文件包含在当前文件中,这是一个预处理器指令,使编译器在编译之前放置包含文件的内容。

这相当于简单地将另一个文件的全部内容粘贴到此主文件中。

请注意,结果与前一个示例完全相同。alu 的时间单位为 1ns/1ps,因为它是在编译器找到 alu 定义之前保持有效的最后一个指令,而不是将其放置在不同的文件中。

des 的时间单位为 1ns/10ps,因为该指令在其定义之前被替换。

交换文件可以更改时间单位。

文件的包含顺序在时间单位指令的重新定义中起着重要作用,这在下面的示例中很明显。

请注意,模块 alu 现在的时间单位为 1ns/10ps。

这是在文件顶部放置时间单位指令的原因之一,以便该文件中的所有模块都采用正确的时间单位,而与文件包含无关。

但是,如果没有更改每个文件,此方法可能会使使用不同的时间单位精度进行编译变得困难。

许多编译器和仿真器还提供了一个选项来覆盖默认时间单位值,该值将应用于所有模块。