Dear all, I have an extremely frustrating situation with a logic array not being updated when a single bit of the array is forced to a constant through the force directive. I’ll illustrate what I mean with an excerpt of the code.
We have a memory array in the DUT that is declared as a reg, in the TB we instantiate a module that we call ‘interface_module’ that uses an SV interface for integration with the environment, so here they are:
interface int_obs_if();
logic [15:0] ram_matrix[0:511];
//... many other signals
modport ram_mapping(input clk, input wr, input ce, input ram_matrix);
//... many other modports
endinterface // int_obs_if
module int_obs_ifm(int_obs_if i_int_obs_if);
wire [15:0] ram_matrix[0:511];
//... many other signals
assign ram_matrix[0:511] = DUT.RAM.ram_matrix[0:511];
//... many more assignments
i_int_obs_if.ram_matrix[0:511] = ram_matrix[0:511];
//... many more assignments
endmodule // int_obs_ifm
Now the int_obs_ifm module is connected through its interface to another component which consumes the data in the ram_matrix in the following way:
module ram_manager(int_obs_if i_int_obs_if);
always @(posedge i_int_obs_if.clk) begin
if (i_int_obs_if.ce && i_int_obs_if.wr) begin
somelocalvar = i_int_obs_if.ram_matrix[i_int_obs_if.addr];
end
end
// do something with somelocalvar
endmodule // ram_manager
Until now everything seems ok and indeed everything seems to work. But the real issue come when another module is trying to force a value directly in the DUT ram_matrix in the following way:
module fault_injection_ifm();
case (injection_type)
SOME_FAULT: begin
if (injection_active) begin
// Forcing one bit of the array to flip
tmp = DUT.RAM.ram_matrix[someaddr][somebit];
force DUT.RAM.ram_matrix[someaddr][somebit] = ~ tmp;
end else begin
// Releasing the fault
force DUT.RAM.ram_matrix[someaddr][somebit] = tmp;
release DUT.RAM.ram_matrix[someaddr][somebit];
end // if (injection_active)
end // SOME_FAULT
endcase // case (injection_type)
endmodule // fault_injection_ifm
So in this case we are forcing the ram_matrix RTL directly while our int_obs_ifm should simply ‘observe’ that something is changing. Apparently the i_int_obs_if.ram_matrix is never updated when we are forcing the signal and this behavior is definitely unexpected and the most bizarre thing is that the whole ram_matrix is not updated, as if it was ‘frozen’. I’ve been thinking whether it was the type definition of the ram_matrix in my interface that was wrong (logic vs wire), but changing it didn’t solve the issue.
Any idea on why this could happen?
On a similar note we’ve also been trying to inject the fault through the interface but it doesn’t seem to work, as if the assign statement doesn’t really propagate in ‘both’ directions (from and to the DUT). Any pointer is appreciated.
Thanks a lot,
Al