Why Force release is not working as expected while having always_comb in design?

Hi,

I want to force some internal design signals from testbench for some experiment and using uvm_hdl_force/uvm_hdl_release.
Design is having always_comb block as shown in the attached snippet.
I forced the signal i_a_wire with value 0 at #12ns and released at #17ns. Expectation is, at #17, signal “i_a_wire” should take it original value 1, rather it is still at value 0 due to sensitivity of always_comb block.
Could you please help what change needs to be done such that “i_a_wire” takes the value of “i_a” while releasing at #17ns.


import uvm_pkg::*;
`include "uvm_macros.svh"

module designn(input wire i_a);
  logic i_a_wire;

  always_comb i_a_wire = i_a;
endmodule

module force_release_module;
  logic b = 0;
  designn dut(
      .i_a(b)
      );

  initial begin
      #12;
      $display("@%0t: Injecting force",$realtime);
      void'(uvm_hdl_force("force_release_module.dut.i_a_wire",0));
      #5;
     
     

> //Note: This code helped me, but this is not feasible for current scenario as I have thousands to signals to force and finding the driver for all signals looks cumbersome
//void'(uvm_hdl_read("force_release_module.dut.i_a",str_read));
//$display("@%0t: str_read=%0d",$realtime,str_read);
//void'(uvm_hdl_force("force_release_module.dut.i_a_wire",str_read));



     $display("@%0t: Releasing force",$realtime);
     void'(uvm_hdl_release("force_release_module.dut.i_a_wire"));

  end

  initial begin //Driving signal b.
      #10;
      b = 1;
      #10;
      b = 0;
      #10;
      b = 1;
      #10;
      b = 0;
      #10;
      $finish;
  end

  initial begin //fsdb dump
      $dumpfile("force_release_sim.fsdb");
      $dumpvars(0,force_release_module);
  end

endmodule

Thanks.

In reply to hvalec:

This is the correct behavior when forcing variables that are procedurally assigned. A release will not change the value until there is another procedural assignment.

Can you use a continuous assignment here instead of always_comb?

You could put a wrapper around uvm_hdl_force/release that saves the current value before applying the force, then restores the the saved value before the release.

Another option is finding a way to eliminate the forces in the first place, especially using uvm_hdl_force. They are terrible for performance slowing your entire simulation down regardless of how much the force is used.

In reply to dave_59:

In reply to hvalec:
This is the correct behavior when forcing variables that are procedurally assigned. A release will not change the value until there is another procedural assignment.
#(1)
Can you use a continuous assignment here instead of always_comb?
#(2)
You could put a wrapper around uvm_hdl_force/release that saves the current value before applying the force, then restores the the saved value before the release.
#(3)
Another option is finding a way to eliminate the forces in the first place, especially using uvm_hdl_force. They are terrible for performance slowing your entire simulation down regardless of how much the force is used.

Thanks for quick reply Dave. Got your point.
Regarding #1, I need to check with designer to change the design which I don’t think designer will do just for the sake of this experiment. There might be certain reasons he would have used always_comb block (might be to avoid multi-drivers, what do you think?)

Regarding #2, Saving the values will not help as “i_a” might change during the forced period. and we’ll end up forcing other values during release.

Regarding #3, I don’t have any other option, btw I am trying to backpressure something in the design, creating real backpressure (to eliminate the need of force itself) is difficult in this scenario as this design hierarchy is very deep inside the design (atlest 9 modules deep).

Do you have any other suggestion for this scenario.
Thanks is advance.

In reply to hvalec:
Sorry, without many more details it will be hard to suggest.