时序仿真中阻塞赋值和非阻塞赋值的区别
1 实验设置
1.1 功能模块编写
设置8位的变量c,通过非阻塞赋值的方式,将同样为8位的变量a和变量b之间按位与的结果赋值给c,代码如下:
module test_a4_and_b4( clk, a, b, c, ); input wire clk; input wire [7:0] a; input wire [7:0] b; output reg [7:0] c = 0; //非阻塞赋值 always @ (posedge clk) begin c <= a & b; end endmodule
1.2 激励代码编写
设置a和b的激励为随机8位0~255的数据,时钟用阻塞赋值,激励源a和b的产生分别用阻塞赋值和非阻塞赋值,数据变化时刻和上升沿同步。
`timescale 1ns/1ns `define clk_period 20 module test_a4_and_b4_tb; reg clk; reg [7:0] a; reg [7:0] b; wire [7:0] c; test_a4_and_b4 test_a4_and_b4_inst( .clk (clk), .a (a), .b (b), .c (c) ); always #(`clk_period/2) clk = ~clk; always #(`clk_period/2) a = {$random}%256; always #(`clk_period/2) b = {$random}%256; initial begin clk = 0; a = 0; b = 0; end endmodule
2 实验分析
2.1 阻塞赋值分析
激励源a和b的产生用阻塞赋值:
always #(`clk_period/2) a = {$random}%256; always #(`clk_period/2) b = {$random}%256;
仿真波形如下:
可以看到,当处于第2个时钟上升沿时,c为a和b变化后的值按位与的值。
2.2 非阻塞赋值分析
激励源a和b的产生用非阻塞赋值:
always #(`clk_period/2) a <= {$random}%256; always #(`clk_period/2) b <= {$random}%256;
仿真波形如下:
可以看到,当处于第2个时钟上升沿时,c为a和b变化前的值按位与的值。
3 实验结论
若时钟和激励源同时变化:
(1)如果激励源使用阻塞赋值,仿真工具会认为时钟和激励源同时变化,则上升治会采集到激励源变化之后的值。
(2)如果激励源使用非阻塞赋值,仿真工具会认为激励源晚于时钟变化,则上升治会采集到激励源变化之前的值。
非阻塞赋值发生赋值的时刻晚于阻塞赋值0ns。
仿真时,激励源的赋值需使用非阻塞赋值。
本文作者:Yamada_Ryo
本文链接:https://www.cnblogs.com/little55/p/18185357
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步