Inferring Constraints from Initial Values for Signals and Variables
Proposal Information
- Who Updates: RyanHinton, JimLewis, ...
- Date Proposed: 2013-05-01
- Date Last Updated: 2013-05-01
- Priority:
- Complexity:
- Focus: General Language
Language Change Specification Link
LCS2016_019
Summary
Currently constant subtype constraints can be inferred from initial values. However, variables and signals must be of fully-constrained subtypes before the initial value is considered. This proposal relaxes this constraint for convenience.
Requirements
Allow signals and variables that are given fully constrained initial values to have unconstrained or partially constrained subtypes. The subtype constraints in this situation come from the initial value.
Related Issues: None = General
Competing Issues: None at this time
Use cases
This feature is particularly handy with the new fixed-point types. Currently the following is legal.
constant a : sfixed := to_sfixed(1.56723984, 1, -12);
constant b : sfixed := to_sfixed(-0.56263673, 0, -4);
constant prod : sfixed := a * b;
RyanHinton uses this to infer sizes and ranges of intermediate calculations from unconstrained ports.
entity
port (
a_port : sfixed;
b_port : sfixed;
...
constant prod_proto : sfixed := a_port * b_port; -- don't care about actual value, just subtype
variable prod : prod_proto'subtype; -- use constant just to get the appropriate subtype
...
prod := a_port * b_port;
Often I will have a sequence of 8 or more "prototype" constants depending on ports and earlier constants representing a chain of calculations. But I have to create a bunch of dummy constants. It's a pain to maintain.
Proposal: Part 1
With the proposed change, the above simplifies as follows.
entity
port (
a_port : sfixed;
b_port : sfixed;
...
-- NO DUMMY CONSTANT NEEDED
variable prod : sfixed := a_port * b_port;
-- the initial value may not be meaningful, but the subtype of the
-- result is used to constrain the variable type.
...
prod := a_port * b_port;
The change looks small here, but it adds up with long processing chains (e.g. heavy pipelining).
I agree we should do this, particularly for testbenches, however, for RTL code it has an implication of some flavor of power up value. As a result, I propose Part 2 be considered in conjunction with part 1. --
JimLewis - 2013-05-02
Proposal: Part 2
--
JimLewis - 2013-05-02
Extend 'range and 'subtype to work with an expression.
Rationale: 'range and 'subtype will not initialize a signal and as a result, for hardware will not have any power on implications.
entity
port (
a_port : sfixed;
b_port : sfixed;
...
variable prod : sfixed( (a_port * b_port)'range ) ;
In addition, 'range and 'subtype use a range and a subtype as a first class object. If a predefined function can do this, then so should a user defined function.
Arguments FOR
The following is ok:
constant MY_SLV : std_logic_vector := "0011" ;
signal MySlvSig : std_logic_vector(MY_SLV'range) ;
JimLewis -- 2013-04-24, interpreted from reflector email by
RyanHinton
(Comment by
RyanHinton:) In other words, if a signal can get its subtype (via a range constraint) from a constant that gets its subtype constraint from an expression, why not allow the signal to get its subtype directly from an expression? In yet other words, there are no static-ness issues here. Or if there are, they're no different from the constant case.
Arguments AGAINST
Supporters
--
RyanHinton - 2013-05-02 --
Brent Hayhoe -2013-15-02 --
JimLewis - 2013-05-02 --
KevinJennings - 2013-05-09 (Proposal 2 approach)
Add your signature here to indicate support for this proposal.