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) beginc <= a & b;endendmodule
1.2 激励代码编写
设置a和b的激励为随机8位0~255的数据,时钟用阻塞赋值,激励源a和b的产生分别用阻塞赋值和非阻塞赋值,数据变化时刻和上升沿同步。
`timescale 1ns/1ns
`define clk_period 20module 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 beginclk = 0;a = 0;b = 0;endendmodule
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。
仿真时,激励源的赋值需使用非阻塞赋值。