Verilog系列:【14】timescale去哪儿了
1 `timescale
格式:
`timescale time_unit / time_precision
time_unit - 指定了设计中的时间单位;
time_precision - 指定了设计中时间的精度;
例如:
`timescale 1 ns / 1 ns // 时间单位为1s,精度为1ps
注意: time_precision不能大于time_unit,且在整个仿真过程中,仿真精度由整体设计中最小的 time_precision决定,同时需要注意的是时间单位和时间精度的量级必须是“1、10、100”等。
常用的时间单位和精度如下表所示:
单位 | 含义 |
s | 秒 |
ms | 毫秒 |
us | 微妙 |
ns | 纳秒 |
ps | 皮秒 |
fs | 飞秒 |
2 $printtimescale
格式:
$printtimescale[(hierarchical_identifier)];
该系统任务用于显示指定模块的时间单位和时间精度。
3 内幕
· `timescale不从属于任何模块,本身是条编译命令,仅影响其后的模块,影响范围限于下一条`timescale或者`resetall出现之前。如果不是所有文件都指定了`timescale,那么不同的文件编译顺序将导致没有指定`timescale的模块的时间单位和精度随着编译顺序的变化而变化,从而可能导致仿真结果异常;
· 如果所有的相关文件都没有制定`timescale,部分EDA工具会指定默认的时间单位和精度,但是不要将代码的功能寄托在仿真工具上,因为不同的仿真工具指定的时间单位和精度可能不一致;
· 如果能够保证所有的文件的编译顺序一定,那么可以仅在第一个被编译文件开始前指定`timescale,但是不推荐这样使用,主要因为系统集成时无法保证所有源代码都不使用`timescale;
· `timescale采用就近原则,即当模块定义之前使用了多条`timescale,那么模块将采用仅有最后一条`timescale;
为了保证整个设计使用相同的`timescale,可以采用如下方法:
· 所哟肚饿设计文件均不使用`timescale,而是通过EDA工具在编译命令中指定;
· 确保每个模块定义开始之前都显示定义`timescale;
4 示例
仿真结果如下:
以下为使用$printtimescale输出的各个模块具体使用的使用的时间单位和精度:
从仿真结果可以得到:
信号 | 周期 |
clka | 2.250ns(1.125x2) |
clkb | 2.26ns(1.13x2) |
clkc | 2.2ns(1.1x2) |
clkd | 2ns(1x2) |
clke | 22ns(11x2) |
clk | 32ns(16x2) |
此处以clk和clke分析:clke模块定义之前没有指定`timescale,但该模块的定义位于clk模块定义之后,而clk模块定义之前使用了`timescale,所以clke和clk使用相同的`timescale,即时间单位为10ns,精度为1ns。在进行周期计算时,根据时间单位和精度对具体时间进行四舍五入后获得,即clk周期为32ns(1.55x10得到15.5ns,因为时间精度为1ns,所以得到的最终时间为15ns),类似可以得到clke周期为22ns(1.125x10得到11.25ns,四舍五入得到11ns)。