5

I have a hierarchy of modules where I am trying to do a force to get different value at different module interface. I am working on a component whose task is to inject transaction to a module down the hierarchy, bypassing the drives from the modules higher up in the hierarchy. I thought I could use force on the control signals in order to disengage drives from higher up modules and start driving into the module of interest. So I have been trying to see how force will work. The full code is at http://www.edaplayground.com/x/69PB. In particular, I am trying to understand effect of these two statements within initial block:

force u_DataReceiveTop.u_DataReceiveWrap.DataReceiveIfWrp_inst.valid = 1'b0;
force u_DataReceiveTop.valid = 1'b1;

what I expected the values to be is:

u_DataReceiveTop.u_DataReceiveWrap.DataReceiveIfWrp_inst.valid == 0
u_DataReceiveTop.valid == 1

but I see from waves:

u_DataReceiveTop.u_DataReceiveWrap.DataReceiveIfWrp_inst.valid == 1
u_DataReceiveTop.valid == 1

It is as if the second force statement force u_DataReceiveTop.valid = 1'b1; has propagated down the hierarchy even though there is another force. What is happening here?

jskroch
  • 333
  • 2
  • 8
Gautam
  • 375
  • 2
  • 6
  • 23

1 Answers1

11

A wire in Verilog is a network of drivers and receivers all connected to the same signal. The value of that signal is some resolution function of all the drivers and the type of the wire. When you connect two wires through a port, the two wires get collapsed into a single signal, but you still have two different names for the same signal.

When you use the force statement on a wire, that overrides all the drivers on the network until encountering another force or release statement. In your example, the second force statement replaces the first force. I doesn't matter which hierarchical reference you use in the force because they all refer to the same signal.

If you want the behavior you are expecting, you need to use variables instead of wires. When you connect a variable to a port, SystemVerilog creates an implicit continuous assignment, depending on the direction of the port. SystemVerilog does not allow more than one continuous assignment to a variable, which is why you can't use variables with an inout port. So you will need to be more careful about the port directions then.

dave_59
  • 39,096
  • 3
  • 24
  • 63
  • thanks for the answer. I understand now what happened. Now it looks like I cannot achieve what I intended to do with `force`. Any hints on how I could prevent higher up modules from driving signals at my module of interest so that I can inject a different set of transaction into the module? – Gautam Jun 13 '16 at 03:59
  • I need to mention that I am not allowed to change the design code. I need to some how do it from testbench. I need to be able to inject transactions into required module when required after some how disengaging higher up modules so they don't drive any thing. – Gautam Jun 13 '16 at 04:07
  • 2
    Design and Verification engineers need to work as a team. Either the designers need to change the way the code is structured so it can be tested, or the Verification engineers need to modify the code to perform the needed testing. – dave_59 Jun 13 '16 at 05:29
  • Dave, if I use a register or a wire that is varying to _force_ on my signal, does the "force" constantly assigns the the varying value to the signal, or the forced value stays constant equal to the value reg/wire that was at the moment of "forcing"? Is _force_ the same as _@always_ ? – Nazar Jun 04 '20 at 17:29
  • 2
    `force` is a temporary continuous assignment. Changes on the RHS continually update the LHS. – dave_59 Jun 04 '20 at 17:34