看一下race代码
`timescale 1ns/1ns
module race1;
bit clk1, clk2;
bit rstn;
logic[7:0] d1;
initial begin
forever #5 clk1 <= !clk1; //5ns一翻转,所以时钟周期是10ns
end
always @(clk1) clk2 <= clk1; //当clk1上升沿到来时,赋值给clk2,利用组合逻辑使得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; //注意这个d1,仅被clk1驱动,当clk1,rstn都为1时,d1加1
end
always @(posedge clk1) $display("%0t ns d1 value is 0x%0x", $time, d1); //clk1上升沿时打印d1此时刻的值
always @(posedge clk2) $display("%0t ns d1 value is 0x%0x", $time, d1); //clk2上升沿时,对D1进行采样,打印d1此时刻的值
endmodule
我们可以看一下,35ns处其实已经发生问题了,对35ns处分析,其实不难发现,通俗的分析,
1、d1的+1运算与clk不是同步的,d1+1显然要慢clk1一点,所以在ckl1上升沿来的时候,clk采到了0值(快速完成),之后d1+1才进行运算
2、对于clk2来说,clk2相对于clk1来说也是慢一点的,两者间有逻辑运算(<=),当clk2对d1进行采样时,d1已经完成d1+1的过程
3、对45ns分析与35ns一致
如图所示
波形图