Once a virtual interface
has been initialized, all the components of the underlying interface instance
are directly available to the virtual interface via the dot notation. These
components can only be used in procedural statements; they cannot be used in
continuous assignments or sensitivity lists. In order for a net to be driven
via a virtual interface, the interface itself must provide a procedural means
to do so. This can be accomplished either via a clocking domain block or by
including a driver that is updated by a continuous assignment from a variable
within the interface.
19.8.1
Virtual interfaces and clocking domains
Clocking domains blocks and
interfaces can be combined to represent the interconnect
between synchronous blocks. Moreover, because clocking domains blocks provide
a procedural mechanism to assign values to both nets and variables, they are
ideally suited to be used by virtual interfaces. For example:
In the preceding example,
interface SyncBus includes a clocking domain block,
which is used by task do_it to ensure
synchronous access to the interface’s signals: a, b, and c. Note that changes
to the storage type of the interface signals (from net to variable and
vice-versa) requires no changes to the task. The interfaces can be instantiated
as shown below.
19.8.2
Virtual interfaces modports and clocking domains
blocks
As shown in the example
above, once a virtual interface is declared, its clocking-domain block can
be referenced using dot-notation. However, this only works for interfaces with
no modports. Typically, a device under test and its testbench exhibit modport
direction. This common case can be handled by including the clocking in the corresponding
modport as described in Section 19.4.5.
And, within the testbench
program, the virtual interface can refer directly to the clocking domain block.
The example above shows how
the clocking-domain block is referenced via the virtual interface by the
tasks within the program block.