External Names; Beyond the scope of VHDL
There are many things that differentiate VHDL from Verilog. One example, is the ability to use global signals in Verilog, which enables a signal at the top-level to connect to one or more points in the hierarchy. This particular feature is used very effectively by Xilinx, to distribute the Global Set/Reset signal GSR to their IP and cell simulation models. The signal is generated in the glbl.v, which is created when you configure the Xilinx IP. This feature was lacking in VHDL until recently.
Before VHDL-2008, if you needed to feed a signal into a lower level of hierarchy, you would have had to feed it through the Port maps of the entity, through its declaration and instantiation (lots of work!). Although Aldec did provide a proprietary solution to the problem, with the ‘Signal Agent’ feature in Active-HDL and Riviera-PRO. Was this a useful feature? Well, there are certain times when it could be helpful to reach inside a model, for example:
- Monitoring signals for testbenches
- Quick what/if analysis during design and debug
With the release of VHDL-2008 the “Signal Agent” type access became part of the VHDL language with the ability to define external names. External names allow hierarchical access to objects that were hidden by the scoping rules of previous versions of VHDL. The syntax definition for an external name is:
external_name ::=
< < constant external_pathname : subtype_indication > > |
< < signal external_pathname : subtype_indication > > |
< < variable external_pathname : subtype_indication > >
external_pathname ::=
absolute_pathname | relative_pathname | package_pathname
As the rule specification suggests, when we write an external name, we provide more information than just the path to the object. You also specify the object class, whether it is a constant, signal or variable as well as the subtype of the object. These specifications are used during analysis to ensure correct usage of the named object and are checked for validity during elaboration. From the specification, you will see that you can use an absolute, relative or package path, but for this article, we will just look at the relative example.
We can use an external name to directly access an object in the design hierarchy, as demonstrated below where we are checking the value of a state register:
assert < < signal tb.dut.controller.state : std_logic_vector ( 4 downto 0 ) > > = “00000”
report “Illegal controller state“;
In other cases, it may be more convenient to ally the external name with an alias statement, to give a local data object that you can manipulate directly, as shown here:
alias FSM_State is < < signal tb.dut.controller.state : std_logic_vector ( 4 downto 0 ) > > ;
I do not want to overload you, so I think that will do for now! But please check back for my next post, where we will continue on this subject and use an external name to capture the activity of a state machine as part of an OSVVM functional coverage model.