Force inout port

Below small test seems to work to force test.foobar. I know inout port type and force/release from LRM, but failed to find out description for them working together. Could anyone provide useful info on this ?

module test;
wire foobar;
endmodule

module probe(inout foobar);
initial force foobar = 'x;
endmodule

bind test probe probe_i(.*)

In reply to robert.liu:

I am not sure what description you are looking for if you already know the example works the way you think it should. The LRM cannot provide the interaction of every possible feature used with another feature. The bind construct is essentially the same as writing

module test;
 wire foobar;
 probe probe_i(.foobar(foobar));
endmodule
 
module probe(inout foobar);
 initial force foobar = 1'bx;
endmodule

In reply to dave_59:

Oh, I didn’t realize there is some confusion here. I was not asking difference between bind and direct instantiation.

In the example, we do force foobar = 1’bx where foobar is an inout port. Is it exactly the same as force test.foobar = 1’bx directly ?

With module probe being instantiated inside module test and port foobar being connected to wire foobar, is that inout port essentially a pointer/handle to the high-conn wire ?

BTW, the LRM has pretty clear description for ref port:

A ref port shall be connected to an equivalent variable data type. References to the port variable
shall be treated as hierarchical references to the variable to which it is connected in its instantiation.

In reply to robert.liu:

This is covered in section 23.3.3.7 Port connections with dissimilar net types (net and port collapsing). The title is a little misleading because this section describes a two step process for connecting nets with dissimilar net types and then merging them into a single net with a dominating type. If the two nets have the same type, there is no need for determining a dominating type and they can be merged directly. Section 23.3.3.1 Port coercion essentially results in port collapsing happening for any direction when both sides of the connections are nets; port direction is ignored.

In reply to dave_59:

Thanks Dave. I studied more in the direction of “port collapsing” and finally understand why force statement in my small test case worked that way.

I have another related question below, on port connection and its implicit continuous assignment and the unidirectional property of continuous assignment.

module test;
wire integer foo;
assign foo = 3;
dut dut(foo);
endmodule

module dut(input integer bar);
initial #2 force bar = 5;
initial begin
    #10;
    $display("dst = ", bar,,,"src = ", test.foo);
    $finish;
end
endmodule

hi-conn signal of input port bar is a wire and input port is a variable, I assume there is an implicit continuous assignment here like

assign test.dut.bar = test.foo;

The simulation results on multiple simulator kind of surprised me since one output src = 3 while another output src = 5. Which one is correct?

In reply to robert.liu:

It seems src = 3 is the right answer. This port connection is an implicit continuous assignment, due to below LRM subsection:

3.9.6 Port connections
Ports connect processes through implicit continuous assignment statements or implicit bidirectional
connections. Bidirectional connections are analogous to an always-enabled tran connection between the
two nets, but without any strength reduction.
Ports can always be represented as declared objects connected, as follows:
— If an input port, then a continuous assignment from an outside expression to a local (input) net or
variable
— If an output port, then a continuous assignment from a local output expression to an outside net or
variable
— If an inout port, then a non-strength-reducing transistor connecting the local net to an outside net

In reply to robert.liu:

The correct answer is src = 5.

As I mentioned from section 23.3.3.1 Port coercion results in all ports with connections to nets on both sides being treated as collapsed. The text in 3.9.6 Port connections is basically saying the same thing, although this text was straight from Verilog before SystemVerilog added the capability to add variables to input port declarations and output port instance connections.

In reply to dave_59:

The port collapsing only happens when both sides of the connection is net. This is my current understanding. However, the header of module dut is

module dut(input integer bar);

Essentially bar is a variable. BTW, if we use VPI get the type of test.dut.bar, it’s a vpiIntegerVar. Then through the vpiPorts relationship we can get the handle to the port itself.

And when we run force bar = 5; we actually force the variable var, rater than port var. Is this right?

In reply to robert.liu:

Fixed typo.

And when we run force bar = 5; we actually force the variable, rater than port. Is this right? Actually force can’t operates on ports, but variables or nets. Usually we define implicit port where port name and variable/net name are the same. These are two types of objects, however.

In reply to robert.liu:

bar is a net according to section 23.2.2.3 Rules for determining port kind, data type, and direction. The implicit kind for a an input or inout port is a net. Two simulators on EDAplayground agree with this interpretation.

You are correct about the distinction between port name and the object it is connected to. Usually they have the same name, but there is syntax to separate them.

In reply to dave_59:

Thanks Dave. You are right. I just saw the rule is different for input and output ports if kind is omitted and explicit data_type syntax is used.

In reply to dave_59:

You are correct about the distinction between port name and the object it is connected to. Usually they have the same name, but there is syntax to separate them.

Hi Dave, I would like to revisit this question again. In below code:

module dut(input integer bar);
initial $check_port_connection(bar);
endmodule

Through the systf handle and argument iterator, we actually get a handle to the net bar. Then through the vpiPorts relationship, we finally got the handle to the port bar.

May I have your idea if you think LRM is clear on this behavior?