2

Is there a way to force an arbitrary wire to a certain value in a Verilog task without specifying what the wire's name is or its hierarchical path ahead of time? Preferably without having to write a ton of if-statements for each possible wire.

My goal is to be modular enough such that this task could be used to drive any wire from a testbench perspective.

Example of what I hope to do:

task force;
input value;
input [8*N-1:0] string;              // Assume N is large enough
begin
    force ... = value;
end
endtask

Where the three dots '...' would be the path of the wire passed in (e.g. counter0.clk0.in_enable).

Let's say I have 64 wires and I want to force some of them high. They are not on a single bus and they all have different names or hierarchical paths. In a testbench setup, I would write a C function that reads a table of the wires I care to drive to a certain value and pass each wire to this Verilog task, but how can I tell the simulator which wire to drive high without having to write out every single wire everytime in the task itself?

If I can do this, what is the correct way to do it? If I can't do this, what could you suggest instead?

supernun
  • 437
  • 1
  • 6
  • 16
  • This question isn't clear to me. How are you determining at runtime which wires to drive? –  Jul 11 '12 at 18:03
  • You could define a system task that uses the VPI interface to drive wires. I believe this could very easily become a performance bottleneck. – Ross Rogers Jul 11 '12 at 18:08
  • @Adam12 To determine which wires: I am provided a table of the hierarchical paths to all the wires that need to be driven. If you mean how do I tell the simulator which wires to drive then I'm not sure. In fact, That's what I'm trying to figure out. – supernun Jul 11 '12 at 18:36
  • @RossRogers The C to Verilog interface is already setup. My next step is to figure out if it's possible to create a place-holder for the wire, which I would set in my C function and then invoke the task to force that wire high or low. edit: Essentially my C function call would be: callForce("counter0.clk0.in_enable", HIGH); callForce("counter1.clk0.in_enable", LOW); etc... – supernun Jul 11 '12 at 18:36
  • Are you really trying to force or deposit values from the C/C++ world? If so, then you can use `vpi_put_value` like [this](http://verificationhack.com/2011/05/18/put-hdl-values-from-cc/). – Ross Rogers Jul 11 '12 at 20:34
  • Supernun. Per your edit, it doesn't sound like you want a verilog-side lookup table at all, in this case. You really *do* want to use `vpi_put_val` exactly [like this](http://verificationhack.com/2011/05/18/put-hdl-values-from-cc/). The VPI interface allows forcing nodes in verilog based on a hierarchical path name. – Ross Rogers Jul 20 '12 at 21:10

2 Answers2

2

There very well may be a PLI/VPI method to do this, but I'm not very experienced with it, so take this with a grain of salt. I'm also not aware of any reflection in verilog either to turn a string into a wire reference.

Having said that, what I would do is just use a scripting language to read your table, and spit out a procedurally generated .v file with a gigantic case statement.

You could have a PLI call like force_wire(int wireId), release_wire(int wireId) where the wire id could just be the row of the table or something.

In C routine you could lookup the id from the string name, and then this would call the verilog task with the id, and the id would select from the generated case statement what to force. Maybe something like:

task force
input forceVal;
input wireId
begin
   case (wireId)
   //AUTOGENERATED BELOW
   0 : force foo.bar = forceVal;
   1 : force foo.baz = forceVal;
   2 : force bar.foo = forceVal;
   ...
   endcase
end
Tim
  • 35,413
  • 11
  • 95
  • 121
  • I'm not very experienced in PLI/VPI either nor am I with scripting! Still learning the ropes though. Thanks! I would still like to see if anyone knows how to implement it the way I originally intended without case or if statements. – supernun Jul 11 '12 at 20:13
1

Sadly, no, you cannot do what you are attempting using non-PLI Verilog constructs. The target of the force needs to be the hierarchical path of the net, and there is no way to use a string for it.

Tim's suggestion in another answer, basically creating a big lookup table, would probably be the best approach without using the Verilog PLI.

If you want to use the PLI, you should be able to write a function that would take in the string and do the force. I have wanted to do a similar thing for a while now, but have not got around to trying it. If you find a better way please answer your own question here.

EDIT: Here is a discussion with some possible implementations using the PLI or SystemVerilog bind.

dwikle
  • 6,820
  • 1
  • 28
  • 38