I defined an interface in system verilog and use bind statement to bind to internal RTL signals. I want to be able to force internal RTL signals through the interface. However, this is causing the RTL signal to go to 'x' if I don't force these signals explicitly, it seems bind to interface is having driving capability. I don't want RTL signal to change to 'x' when nothing is forcing it in this case, not sure what I am doing wrong here?
my code looks like this with DUT being the design:
interface myInf( inout RTL_a, inout RTL_b ); bind DUT myInf myInf_inst( .RTL_a(DUT.a), .RTL_b(DUT.b) ); bind DUT myDrv(myInf_inst);
where myDrv is a module which drives the ports on myInf.
In this case, DUT.a and DUT.b are internal RTL signals, they have their driver from design, but I want to be able to force them if needed. however, these signals becoming 'x' when I am just binding them to myInf without actually driving them.
11 Answer
The inout
signals might be a non-net type. It is better to be explicit in the the declaration and define them as inout wire
. Inside the interface
, assign the nets to a logic
and initialize the logic
s to z
. A non-z
value will apply a driver while a z
will allow signals to drive. Example:
interface myInf( inout wire RTL_a, inout wire RTL_b ); logic drv_a, drv_b; initial {drv_a,drv_b} = 'z; // z means not driving assign RTL_a = drv_a; assign RTL_b = drv_b; endinterface
There might be conflicting drivers, such as the normal drivers from the design. In this case you will need to override the driver. Assuming the signal being overrode is a net type, this is done by changing the assign statements to assign (supply1,suppl0) RTL_a = drv_a;
. This is utilizing the Verilog concept of drive strength. Assigning to z
will still all other drivers. Most nets are driven with a strength of strong1,strong0
which is weaker then supply1,supply0
. Drive strength will not work for non-net types (e.g. logic
& reg
). These register/variable-types use a last-assignment-wins approach. Fore more on drive strength read IEEE Std 1800-2012 sections 28.11 through 28.15
Your sample code has some bugs. The pin connections for myInf_inst
should use hierarchical references relative to its target scope. Unless there is an instance called DUT
inside module DUT
, then the DUT.
should be omitted (See IEEE Std 1800-2012 § 23.11 Binding auxiliary code to scopes or instances). The bind statement for myDrv
is missing an instance name. The code should be:
bind DUT myInf myInf_inst( .RTL_a(a), // no DUT. .RTL_b(b) // no DUT. ); bind DUT myDrv myDrv_inst(myInf_inst);
sample code: http://www.edaplayground.com/x/2NG
ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJoaWpuaWWEdYCOrLCsrJWierex0aKjqJ9dl7avsIyuqp6cXam8qLHToZyrZaeewal5yKernqqWlrCm