How does uvm_hdl_force different from force?

Hi,

I am trying to use uvm_hdl_force to force design signals, however, it doesn’t work. However, force works. I wonder what is the difference between uvm_hdl_force and force except the syntax.

Interestingly, VCS and Incisive give different results on uvm_hdl_force.
For the below example,
VCS output: X
Incisive: Z 1 0 X Z

import uvm_pkg::*;

module tb;
  dut dutI();
  
  initial run_test("test1");
  initial $monitor($time,,dutI.force_bit);
  
  initial begin
    $dumpfile("test.vcd");
    $dumpvars(0, tb);
  end
  
  `ifdef USE_FORCE
  initial begin
      force tb.dutI.force_bit = 1;
      #1ns;
      force tb.dutI.force_bit = 0;
      #1ns;
      force tb.dutI.force_bit = 'x;
      #1ns;
      force tb.dutI.force_bit = 'z;
      #1ns;
  end
  `endif
endmodule


class test1 extends uvm_test;
  string force_path = "tb.dutI.force_bit";
  
  `uvm_component_utils(test1)
  
  function new(string name, uvm_component parent);
    super.new(name,parent); 
  endfunction
  
  virtual function void start_of_simulation_phase(uvm_phase phase);
    super.start_of_simulation_phase(phase);
    //uvm_hdl_force force the value of 'z
    `ifndef USE_FORCE
    uvm_hdl_force(force_path,'z);
    `endif
  endfunction
  
  virtual task run_phase(uvm_phase phase);
    logic val_set[$] = '{1,0,'x,'z};
    
    phase.raise_objection(this);
    #1ns;
    `ifndef USE_FORCE
    foreach(val_set[i]) begin
      uvm_hdl_force(force_path,val_set[i]);
      #1ns;
    end
    `endif
    
    #10ns;
    phase.drop_objection(this);
  endtask
  
endclass
module dut();
  logic[1:0] force_bit;
  model modelI(.*);
endmodule

module model(input logic[1:0] force_bit);
  parameter ONE = 1;
  //initial force force_bit = ONE;
endmodule

In reply to mlsxdx:

The difference is that SystemVerilog’s force construct searches for pathnames at the compilation time and symbolically binds the path to the assignment statement, the same as it does for any kind of hierarchical reference in any kind of statement.

The UVM’s uvm_hdl_force() method uses the C VPI interface to search for signal using a string pathname at runtime. Once it finds the signal via a string loop-up, it uses another C VPI routine that applies a force. In order to lookup a signal using a string pathname, certain optimizations need to be turned off that keeps the signal visible, and the string names have to be stored as well. There may be tool specific options to make this work, and this forum is not for tool specific help.

In reply to dave_59:

Would this mean that uvm_hdl_force takes non-zero simulation time as comepared to SV force?

In reply to Vaishnavi Balasubramanian:

Both constructs do not consume time (or block). The uvm_hdl_force can only apply a constant forced value, whereas the SV force can apply non-constant expression as well as constants.