verilog设计过程中#1的问题
verilog代码中使用#1延迟
有这样子的一种“神话”,为了修正非阻塞赋值的问题,要求加上#1 delay。因此在一般的非阻塞赋值中经常会看到#1的延迟,工程师的解释是为了防止非阻塞赋值奔溃。实际上,加不加#1都不会导致非阻塞赋值奔溃!在非阻塞赋值的RHS加#1延迟,既有好的原因,也有很多坏的原因。
好的原因1:在非阻塞赋值上加#1,输出变化会有一个时间单位的延迟,便于查看波形。例如,看一下下面的寄存器模型:
`timescale 1ns/1ns
module delay_test ( q , d , clk , rst_n);
input clk , rst_n;
input d;
output reg q;
always@(posedge clk or negedge rst_n) begin
if(!rst_n) q <= #1 1'b0 ;
else q <= #1 d ;
end
endmodule
这个模型在posedge clk之后或在negedge rst_n之后让输出延迟1时间单位(1ns)。这个延迟有效地实现了1ns的clk-to-q 或者rst-to-q 的延迟,查看波形时更容易理解,因为这个延迟让我们更容易理解波形。波形上的小延迟也可以让人更容易地看到时序逻辑输出在时钟沿之前的值,通过把波形查看工具的一条竖线放在时钟沿上,在波形工具左侧就会把每个信号对应的值显示出来,然后把竖线移动到时钟沿1ns之后的位置,就可以看到因为时钟信号更改后的值。
好的原因2:许多高性能触发器的hold时间是在0~800ps之间。在那些驱动门级模型的RTL模型上加上#1延迟后,通常就可以修正很多与RTL和门级混合仿真相关的问题。当然也有例外,例如门级模型要求的hold时间大于1ns,或者时钟树偏差大于1ns。
坏的原因1:Verilog非阻塞赋值会奔溃吗?这是错误的!即使没有#1的延迟,非阻塞赋值也会工作得很好。如果在不知道添加延迟原因的情况下在非阻塞赋值上添加#1延迟,那么有可能会陷入到与RTL和门级混合仿真相关的问题中,例如门级模型要求的hold时间大于1ns,或者时钟树偏差大于1ns,你的仿真就会失败。
坏的原因2:仿真器对于高速cycle-based的仿真具有内在的优化(Build-in optimization),但是在非阻塞赋值加上#1延迟后,仿真器的运行速度就会明显地变慢。在对没有延迟的非阻塞赋值和带有延迟的非阻塞赋值做了仿真性能上的对比,发现带有延迟的非阻塞赋值对仿真性能有很大的影响。
结论与建议
非阻塞赋值加#1的延迟能够提供一些仿真上的便利,但是这个延迟对仿真性能有很大的影响,虽然VCS的+nbaopt编译选项可以对#1延迟的非阻塞赋值提高仿真性能,但是还是没有达到与不使用延迟的非阻塞赋值一样的性能。
如果工程师坚持要对非阻塞赋值使用#1延迟,最好使用D宏定义添加延迟,那么当D定义为空时,就可以达到对非阻塞赋值不使用延迟时的性能。
不管怎样,还是编写没有延迟的非阻塞赋值更好。如果以后需要做RTL和门级混合仿真,那么就对连接RTL模型输出的非阻塞赋值加上延迟,而且只要在那些真正需要的位置添加即可。你也可以使用shell命令做全局替换,把所有的<=替换为<= `D即可。
当然在工程开始的时候就要求在所有的RTL代码对非阻塞赋值使用`D宏定义。这个方法可以避免90%的RTL和门级混合仿真潜在问题。注意:#1延迟不能修正所有的混合仿真问题。
- 简单分页的性能优化
- Flash/Flex学习笔记(42):坐标旋转
- 分布式监控系统Zabbix-完整安装记录 -添加端口监控
- Flash/Flex学习笔记(40):弹性运动续--弹簧
- 表格样式—粗边框细表格线
- 分布式监控系统Zabbix--完整安装记录 -添加apache监控
- Flash/Flex学习笔记(38):缓动动画
- 把EmEditor改造成简单的Word
- centos7下FFmpeg环境部署记录
- Mac下使用rz、sz远程上传下载文件的配置记录
- 写文件
- Mac下通过VMware Fusion安装centos虚拟机操作记录
- 进程管理利器-supervisor部署记录
- python大小写转换函数
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法