Implicit Parameter and Port Connections
Proposal Information
- Current Owner: JimLewis, ...
- Contributors: JimLewis, ...
- Date Proposed: 2011-Dec-15
- Date Last Updated: 2011-Dec-15
- Priority:
- Complexity:
- Focus: Testbench and RTL (minor role for ports)
- Related Issues: None
- Competing Issues: None
Requirement Summary
Provide a shorthand notation to facilitate mapping parameters and ports
Rationale
- Parameters -- JimLewis - 2011-06-28
- Simplify signal parameter mapping in a transaction based procedure for testbenches.
- In a testbench, procedure that implements a transaction may get called 100's of times. The interface to the procedure must have all signals that connect to the DUT. These signals specify connection, as opposed to a value, and from the perspective of the test developer they "just go along for the ride". Many techniques have been used to avoid this issue, however, all have limitations and reduce the readability of the code.
- Ports -- JohnShields - 2011-0609
- Support binding of separate assertion components to DUT components
- Facilitate mixed language design and verification environment where language boundary is at the instance
Current Situation: Parameters
The following package shows the declaration of two procedures that implement transactions for a CPU.
package CpuPkg is
procedure CpuRead (
constant AddrI : In std_logic_vector ;
variable rData : Out std_logic_vector ;
signal Clk : In std_logic ;
signal nAds : Out std_logic ;
signal Addr : Out std_logic_vector ;
signal Data : InOut std_logic_vector ;
signal Wr_nRd : Out std_logic ;
signal nRdy : In std_logic ;
) ;
procedure CpuWrite (
constant AddrI : In std_logic_vector ;
constant DataI : In std_logic_vector ;
signal Clk : In std_logic ;
signal nAds : Out std_logic ;
signal Addr : Out std_logic_vector ;
signal Data : InOut std_logic_vector ;
signal Wr_nRd : Out std_logic ;
signal nRdy : In std_logic ;
) ;
end package CpuPkg ;
A simple test is created by repeating calls to these procedures:
use work.CpuPkg.all ;
entity TB is
end TB
Architecture test1 of TB is
begin
. . .
TestPro : process
begin
. . .
CpuWrite(MEM_BASE, X"0001", Clk, nAds, Addr, DATA, Wr_nRd, nRdy) ;
CpuRead (MEM_BASE, rData, Clk, nAds, Addr, DATA, Wr_nRd, nRdy) ;
assert rData = X"0001" report "MEM OP 1 Failed" severity failure ;
CpuWrite(MEM_BASE+1, X"0002", Clk, nAds, Addr, DATA, Wr_nRd, nRdy) ;
CpuRead (MEM_BASE+1, rData, Clk, nAds, Addr, DATA, Wr_nRd, nRdy) ;
assert rData = X"0002" report "MEM OP 2 Failed" severity failure ;
. . .
Proposal, Part 1:
Leverage the syntax added for generics to specify subprogram defaults.
- For formal subprogram generics, the syntax is:
- interface_subprogram_specification [ is <> | alternate_subprogram_name ]
- "<>" specifies to implicitly map to a subprogram of the same name if no other mapping is provided.
For example:
package yaya is
generic (
type T;
function LT (L, R : T) return boolean is <> ) ;
The package instance does not need to specify a actual for LT if a function LT exists for the type specified for T and it is visible. This is assumed in the following package instance:
package integer yaya is new work.yaya
generic map ( T => integer ) ;
Applying this to subprogram parameters, we would declare the subprograms as follows:
package CpuPkg is
procedure CpuRead (
constant AddrI : In std_logic_vector ;
variable rData : Out std_logic_vector is <> ;
signal Clk : In std_logic is <> ;
signal nAds : Out std_logic is <> ;
signal Addr : Out std_logic_vector is <> ;
signal Data : InOut std_logic_vector is <> ;
signal Wr_nRd : Out std_logic is <> ;
signal nRdy : In std_logic is <> ;
) ;
procedure CpuWrite (
constant AddrI : In std_logic_vector ;
constant DataI : In std_logic_vector ;
signal Clk : In std_logic is <> ;
signal nAds : Out std_logic is <> ;
signal Addr : Out std_logic_vector is <> ;
signal Data : InOut std_logic_vector is <> ;
signal Wr_nRd : Out std_logic is <> ;
signal nRdy : In std_logic is <> ;
) ;
end package CpuPkg ;
The simplified test using the defaults:
use work.CpuPkg.all ;
entity TB is
end TB
Architecture test1 of TB is
begin
. . .
TestPro : process
begin
. . .
CpuWrite(MEM_BASE, X"0001") ;
CpuRead (MEM_BASE, rData) ;
assert rData = X"0001" report "MEM OP 1 Failed" severity failure ;
CpuWrite(MEM_BASE+1, X"0002") ;
CpuRead (MEM_BASE+1) ; -- rData can also default map
assert rData = X"0002" report "MEM OP 2 Failed" severity failure ;
. . .
In the case where a default bound parameter is to be left open, an explicit open can be used. In the following, the rData out mode parameter is unbound, and hence, the return value is discarded. Note parameters may only be open where allowed by the language.
CpuRead(MemBase + 2, open) ; -- leave rData unbound and no return value
Proposal, Part 2 (option 1)
Revised 2012-08-16 based on
DanielKho suggested that others or all on the RHS of an association is inconsistent with other aspects of VHDL. This option tries to factor that in.
Another thing we could do is add syntax to the instance that would simplify named association in a similar fashion to what was done with Verilog/SystemVerilog. Although I am not real fond of this option, I am going to put it out there. This is not something I thought I would like, however, in our meeting on January 5, 2012, Peter Flake pointed out that using a notation such as this notifies the reader that there is more mapping going on than is visible. Hence, perhaps it adds to readability and is better than Part 1. Have to look at the code examples to make a decision.
SystemVerilog allows a ".*" notation when doing port maps that will connect all ports to identically named signals. In VHDL, something like either "all => <>" or "all" could handle this. However, there would seem to be times in which perhaps we want to map a couple, but not all, so it seems consistent that we would map the remaining with "others => <>" or "others". In this case, "<>" would designate a default mapping.
It may also make sense to allow specification of just the actual when the formal and actual match, such that "Wr_nRd =>" would be the same as mapping, "Wr_nRd => Wr_nRd".
Should we consider "all =>" instead of "all => <>" and "others =>" in place of "others => <>"?
It may also be ok to drop all of the named style mapping and only support "all" and "others".
use work.CpuPkg.all ;
entity TB is
end TB
Architecture test1 of TB is
begin
. . .
TestPro : process
begin
. . .
CpuWrite(MEM_BASE, X"0001", others ) ;
CpuRead (MEM_BASE, rData, others ) ;
assert rData = X"0001" report "MEM OP 1 Failed" severity failure ;
CpuWrite(MEM_BASE+1, X"0002", others) ;
CpuRead (MEM_BASE+1, others ) ; -- rData can also default map
assert rData = X"0002" report "MEM OP 2 Failed" severity failure ;
. . .
--
DanielKho - 2013-09-27
I'm in favor of the two variants on this theme (probably both should be supported):
CpuWrite(MEM_BASE+1, x"0002", others);
CpuWrite(MEM_BASE+1, x"0002", others => <>);
and similarly, with "all" and "all => <>" as well. I'm not that fond of the hanging "others =>" or "all =>" though. Looks like an incomplete clause to me (I'd _mistakenly spot it as a design error).
I also favor the idea in Part 1 where some parameters can be left unbound. For example:
CpuWrite(MEM_BASE+1, x"0002", rData => open, Wr_nRd => open, others => <>);
Proposal, Part 2 (option 2 - orig):
Note that option 1 and 2 are mutually exclusive
Another thing we could do is add syntax to the instance that would simplify named association in a similar fashion to what was done with Verilog/SystemVerilog. Although I am not real fond of this option, I am going to put it out there. This is not something I thought I would like, however, in our meeting on January 5, 2012, Peter Flake pointed out that using a notation such as this notifies the reader that there is more mapping going on than is visible. Hence, perhaps it adds to readability and is better than Part 1. Have to look at the code examples to make a decision.
SystemVerilog allows a ".*" notation when doing port maps that will connect all ports to identically named signals. In VHDL, something like "=> all" could handle this. However, there would seem to be times in which perhaps we want to map a couple, but not all, so it seems consistent that we would map the remaining with "=> others". It would also make sense to allow specification of just the actual when the formal and actual match, such that "=> Wr_nRd" would be the same as mapping, "Wr_nRd => Wr_nRd".
use work.CpuPkg.all ;
entity TB is
end TB
Architecture test1 of TB is
begin
. . .
TestPro : process
begin
. . .
CpuWrite(MEM_BASE, X"0001", => others ) ;
CpuRead (MEM_BASE, rData, => others ) ;
assert rData = X"0001" report "MEM OP 1 Failed" severity failure ;
CpuWrite(MEM_BASE+1, X"0002", => others) ;
CpuRead (MEM_BASE+1, => others ) ; -- rData can also be left off
assert rData = X"0002" report "MEM OP 2 Failed" severity failure ;
. . .
Current Situation: Ports
The thought here is to make it easier to connect to assertion and other verification components. To keep the language consistent, we we should adopt the same syntax for ports as parameters.
Comments
General
To keep the language consistent, it would be nice if we keep the syntax for parameters and ports the same.
Arguments Against
Supporters
-- JimLewis Part 1, Part 2 ?
I support option 2 part 2 -
PeterFlake
I support Part 2 (Option 1) --
DanielKho - 2013-09-27
Combine options 1 and 2 of part 2 to allow both named and positional associations, e.g. [others =>] others. --
ErnstChristen - 2015-01-21
Add your signature here to indicate your support for the proposal
Also indicate which options you prefer