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延迟不能修正所有的混合仿真问题。

最后的最后,如果对本篇文章有疑问或者有意见,欢迎加WX一起探讨:lmf_AlwaysOnline

  • 62
    点赞
  • 137
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
### 回答1: Verilog 移位寄存器实验是用来演示如何在 Verilog设计和模拟移位寄存器的实验。 移位寄存器是一种常用的数字电路元件,它可以将输入的二进制数据移动到寄存器的左侧或右侧,并且可以通过控制位来指定移位方向。 在 Verilog 中,可以使用类似于这样的代码来实现移位寄存器: module shift_register (input clk, input [3:0] din, input [1:0] dir, output reg [3:0] dout); always @ (posedge clk) begin case (dir) 2'b00: dout <= {dout[2:0], din[3]}; 2'b01: dout <= {dout[3], din}; 2'b10: dout <= {din, dout[3:1]}; 2'b11: dout <= {din[0], dout[3:1]}; endcase end endmodule 在这段代码中,"clk" 是时钟信号,"din" 是输入数据,"dir" 是移位方向控制位,"dout" 是输出数据。当时钟信号为上升沿时,移位寄存器会根据 "dir" 的值来确定移位方向,并将输入数据移动到寄存器的左侧或右侧。 移位寄存器实验的目的是帮助你了解如何在 Verilog设计和模拟移位寄存器,并且可以通过调整输入数据和移位方向来检验移位寄存器的正确性。 ### 回答2: Verilog移位寄存器实验是一种用于探索和研究寄存器移位操作的实验。Verilog是一种硬件描述语言,用于描述数字电子系统,包括寄存器和移位操作。在这个实验中,我们将使用Verilog语言编写代码来实现移位寄存器的功能。 移位寄存器是一种数字电路元件,用于将输入数据按照规定的方式进行移位操作。移位操作可以是向左移位(左移)或向右移位(右移)。在Verilog中,我们可以使用"<<"操作符表示向左移位,使用">>"操作符表示向右移位。 在实验中,我们可以定义一个移位寄存器,包括输入端、输出端和控制信号端。输入端用于输入待移位的数据,输出端用于输出移位后的数据,控制信号端用于控制移位操作的方向。 在编写Verilog代码时,我们需要声明输入信号、输出信号和控制信号的位宽,并使用reg类型定义它们。然后,我们可以使用内置的移位操作符来实现移位寄存器的功能。在移位寄存器的代码中,我们还可以添加其他逻辑和条件来实现特定的功能,如循环移位、循环左移和循环右移等。 完成Verilog代码编写后,我们可以使用仿真工具来验证移位寄存器的功能。在仿真过程中,我们可以输入不同的测试数据,并观察输出结果是否符合预期。如果仿真结果与预期一致,则说明移位寄存器的功能实现正确。 总的来说,Verilog移位寄存器实验是一种通过编写Verilog代码来实现移位操作的实验。通过这个实验,我们可以更好地理解和掌握移位寄存器的原理和应用,并且熟练使用Verilog语言编写数字电路的描述代码。 ### 回答3: Verilog移位寄存器实验是一种通过使用Verilog语言来设计和实现移位寄存器的实验。移位寄存器是一种非常常见的数字电路元件,用于在数字系统中实现数据的移位操作。 在这个实验中,我们将使用Verilog语言来描述和实现一个移位寄存器的功能。我们可以使用Verilog的模块化设计方法,将移位寄存器的功能分解为不同的模块,使整个设计更加清晰和可维护。 首先,我们需要定义一个模块来描述移位寄存器的行为。这个模块可以包含一个输入端口用于接收输入数据,并通过移位操作将数据保存在寄存器中。模块还可以包含一个输出端口,用于输出寄存器中存储的数据。此外,我们还可以添加一些控制信号,如时钟信号,用于控制移位寄存器的操作。 接下来,我们需要实例化设计,并将其与测试台连接。测试台可以模拟不同的输入和时钟信号,以验证设计的正确性和功能性。我们可以使用仿真工具,如ModelSim等,来进行仿真和调试。 当我们完成设计和仿真后,我们可以将设计下载到FPGA开发板上进行实验验证。在实验中,我们可以输入不同的数据,并观察输出结果,以确保移位寄存器的功能正常工作。 总的来说,Verilog移位寄存器实验是一种通过使用Verilog语言来设计和实现移位寄存器的实验。这个实验可以帮助学生理解和掌握数字电路设计中的移位寄存器的原理和应用。通过这个实验,学生可以提高他们的Verilog编程能力和数字电路设计能力。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烟花一时

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值