I have a very bizarre behavior in this piece of code:
// fault_if is an interface with two fields:
// - logic active (to start/stop fault injection)
// - fault_e option (enumeration)
always @ (fault_if.active) begin
if(fault_if.active) // active fault injection
case(fault_if.option)
OPTION0: begin
bfr = `TB.DUT.MYBLOCK0.port[0];
force `TB.DUT.MYBLOCK0.port[0] = ~bfr;
end
OPTION1: begin
bfr = `TB.DUT.MYBLOCK1.port[0];
force `TB.DUT.MYBLOCK1.port[0] = ~bfr;
end
// more options follow
endecase
end else begin // inactive fault injection
case(fault_if.option)
OPTION0: begin
release `TB.DUT.MYBLOCK0.port[0];
`TB.DUT.MYBLOCK0.port[0] = bfr;
end
OPTION1: begin
release `TB.DUT.MYBLOCK1.port[0];
`TB.DUT.MYBLOCK1.port[0] = bfr;
end
// more options follow
endecase
end
This piece of code tries to inject faults in our DUT with the aim to verify if the necessary mechanisms detect such faults and take the appropriate actions to report the fault. The fault_if is an interface driven by a UVM agent that is in charge to decide when the fault is active and when it is not, together with the option. The sequence is built in a way to start an injection in one place (i.e. OPTION0), and then remove it after some time before injecting the new one. So the force/release statements go always in pairs.
The weird behavior happens at some point when in one of the options it looks like two branches of the case are active at the same time and the force is happening at the same time in two different places. When the release happens though only one of them is actually released, leaving the circuit with a permanent fault injected.
I’ve tried to step through with the simulator (Incisive), but without success.
Can anyone provide some direction? I’m kind of lost.