Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does SystemVerilog `force` work?

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?

like image 822
Gautam Avatar asked Jan 05 '23 22:01

Gautam


1 Answers

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.

like image 149
dave_59 Avatar answered Feb 23 '23 06:02

dave_59