All Interface Lists Can Be Ordered
Proposal Details
- Who Updates:Main.CliffordWalinsky
- Date Proposed:2013-11-12
- Date Last Updated:2013-11-12
Language Change Specification Link
LCS-2016-086
Current Situation
1076-2008 states, in section 6.5.6.1 "Interface lists", the following regarding interface lists:
"A name that denotes an interface object declared in a port interface list or a parameter interface list shall not appear in any interface declaration within the interface list containing the denoted interface object except to declare this object. A name that denotes an interface declaration in a generic interface list may appear in an interface declaration within the interface list containing the denoted interface declaration."
There is no statement in the LRM describing the reason that generic lists are different from entity and subprogram interface lists. Allowing generics to refer to earlier objects in the same lists is a convenience prohibited to entity and subprogram interface lists, with no obvious reason.
This proposal explores the impacts of removing the requirement for all interface lists, allowing all lists to refer to earlier elements of the same list.
Requirement
LRM changes would be restricted to removing the statement cited in the previous section.
Implementation details
Code Examples
If it is possible to refer to earlier elements of interface lists, the following entity declaration would be legal:
entity ent is
port( x : std_logic_vector; y : x'subtype := x );
end entity ent;
?Meeting
June 2, should Y be able to be initialized to the value of X? That seems of little value. The main value here is to get the type and subtype information.
function Mux4 is
( Sel :std_logic_vector (1 downto 0) ;
A : std_logic_vector;
B, C, D : std_logic_vector(A'range) := (A'range => '0')
) return std_logic_vector is
variable result : std_logic_vector(A'range) ;
begin
case
. . .
when ... => result := B ;
. . .
Arguments FOR
The code example illustrates how it is possible to not only refer to a previous element's value, but also to the previous elements subtype, making it clear how element types are constrained.
We need a means to statically require that a parameter (or port) has the same subtype constraints as a previous one.
As another example, I frequently need to do the following with bus interfaces:
port (
din : in std_logic_vector;
dout : out std_logic_vector(din'range);
be : in std_logic_vector((din'length/8)-1 downto 0);
...
)
Without the ability to get the earlier information, I instead have to do it all in a package
constant DATA_WIDTH : integer := 64;
constant BE_WIDTH : integer := DATA_WIDTH / 8;
subtype t_bus_data : std_logic_vector(DATA_WIDTH-1 downto 0);
subtype t_bus_be : std_logic_vector(BE_WIDTH-1 downto 0);
--
RobGaddi - 2016-07-28
Alternatively, a generic parameter
DATA_WIDTH
is needed to constrain
din, dout
and
be
.
This inline calculation blows up the port declaration.
generic (
DATA_WIDTH : positive
);
port (
din : in std_logic_vector(DATA_WITH - 1 downt 0);
dout : out std_logic_vector(DATA_WITH - 1 downt 0);
be : in std_logic_vector((DATA_WITH/8) - 1 downt 0);
...
)
--
PatrickLehmann - 2016-08-01
Arguments AGAINST
From
JohnRies:
"The code
signal a : bit := '1';
signal b : bit := a;
Is illegal so I don't know why it should be legal in a port declaration. If the default value is taken to mean the value given in the port declaration then that is really confusing and prone to errors because the default value for a port is only evaluate if the port is left unconnected.
Take:
port ( a : bit_vector := ( 0 to 7 => '0');
b : out bit_vector(a'range) := a );
signal c : bit_vector ( 0 to 2);
port map ( a => c );
What value does b get? If you say the initial value of a, which is c's value, this is currently clearly illegal because you need the effective value of signals during elaboration. If you say all '0' then you have the problem that a has two different sizes. The real size and the size of default value which don't match and will result in an error. Ugly, confusing and hard to explain."
--
ErnstChristen - 2015-01-21
In support of John's argument against, this proposal appears to try to impose ordering in essentially concurrent operations.
Response
(
RyanHinton:) No, we're not trying to impose ordering on concurrent operations. The goal is to impose ordering on an interface list. It feels and looks very much like a declarative region, which
is ordered. Similar to a declarative region, once the interface list is ordered, we can define some items in terms of others. As shown in the examples, these types of constraints are quite common.
Regarding John's example, I agree that using the initial value of a signal is a bad idea. I'm happy to discard it.
Out of curiosity, what do you expect to happen if you try the same thing with generics, which
are ordered in 2008?
generic ( a : bit_vector := ( 0 to 7 => '0');
b : bit_vector(a'range) := a );
constant c : bit_vector ( 0 to 2);
generic map ( a => c );
I get an error from my tool when I do something like this, then I fix my code. I expect similar behavior when doing similar things with ports.
--
RyanHinton - 2016-12-15
General Comments
Current Status (June 7, 2016)
June 2 2016 meeting (
http://www.eda-twiki.org/cgi-bin/view.cgi/P1076/2016_MeetingJune2) decided to go ahead with this proposal. LRM changes added as an attachment.
Supporters
Add your signature here to indicate your support for the proposal
In Opposition
Add your signature here to indicate your opposition to the proposal