I'm seeing strange behavior in my testbench where a nonblocking assignment is acting as a continuous assignment instead of outputting the RHS delayed by one cycle.
My testbench binds a module "cov" to the DUT at cpu.cache via bind cache cov cov_top
, and inside the "cov" module I have this nonblocking assignment:
module cov
import cachePkg::*;
(
input logic clk,
input logic rst
);
clocking cclk @(posedge clk iff !rst); endclocking
logic [1:0] LinkState_d1, LinkState_d2;
always @(cclk) begin
LinkState_d1 <= cache.cntrl.LinkState;
LinkState_d2 <= LinkState_d1;
end
endmodule
And the cache.cntrl.LinkState in the DUT is the output of a nonblocking assignment, so I would expect LinkState_d1 to simply follow LinkState from the DUT just delayed by one cycle. However in the waveform viewer I see LinkState_d1 is exactly matching LinkState as if it were a continuous assignment, here's the clock diagram of what I'm seeing in the waveform:
__ __ __
clk __| |__| |__| |__
________
LinkState _____|
________
LinkState_d1 _____|
__
LinkState_d2 ___________|
Is there something different that happens when we use a hierarchical reference in the RHS of a continuous assignment? Or is this just a simulator bug? I'm using questasim 2019.4
Your edited question is very different from the original. The problem is you are using different clocks. It has nothing to do with hierarchical references or that you are using an NBA statement in the module
cov
.The clocking block event
cclk
gets scheduled in the observed region, which is presumably aftercache.cntrl.LinkState
gets updated with its new value.You should not mix clocking blocks with signals from outside the clocking block. Either stop using the clocking block, or move everything inside it.