首先知道几个概念:
delta_cycle:默认情况下时钟对于组合电路的驱动会添加一个无限最小时间(delta_cycle)的延迟,而该延迟无法用绝对时间单位衡量,它要比最小时间单位精度还小。
时间片(time_slot):从时间单位上看要比fs还要小上很多,但是一个时间片又包含无数个delta_cycle。
指令“run 0”并不是不跑仿真,而是运行了一个时间片,一个时间片中又包含了无数个delta_cycle。
assign赋值右端的信号变化都会立刻引起左端信号的变化,而always块中的赋值必须在对应事件(例如时钟有效沿跳变)发生变化才会赋值。
仿真未开始前:二值逻辑初始默认为X,二值逻辑初始默认为0。
仿真执行“run 0”后:仿真跑了一个时间片(time slot),对于assign会立即发生赋值,而always则不会立即发生赋值。
可以试着跑这段程序:
`timescale 1ns/1ns
module race1;
bit clk1, clk2;
bit rstn;
logic[7:0] d1;
initial begin
forever #5 clk1 <= !clk1;
end
always @(clk1) clk2 <= clk1;
initial begin
#10 rstn <= 0;
#20 rstn <= 1;
end
always @(posedge clk1, negedge rstn) begin
if(!rstn) d1 <= 0;
else d1 <= d1 + 1;
end
always @(posedge clk1) $display("%0t ns d1 value is 0x%0x", $time, d1);
always @(posedge clk2) $display("%0t ns d1 value is 0x%0x", $time, d1);
endmodule
仿真时如果引入delta_cycle: