TWiki
>
P1076/Ballots Web
>
Vhdl2019CollectedRequirements
>
ArrayTypeGenerics
(2020-02-17,
JimLewis
)
(raw view)
E
dit
A
ttach
---+ Array Type Generics <br />%TOC% ---++ Proposal Information * Who Updates: Main.RyanHinton * Date Proposed: 2013-05-02 * Date Last Updated: 2013-05-02 * Priority: * Complexity: * Focus: General Language ---++ Summary Type generics allow passing data of arbitrary types through an entity or subprogram. A classic example is a generic 2-way mux component. However, often two types are involved where the second type is an array of the first type. An example is an N-way mux component. This proposal allows annotating (and requiring) a generic type to be an array of another generic type. ---++ Requirements Allow a type generic to be annotated as being an array of another generic type. See #Use_cases for syntax. ---++ Related Issues: None = General ---++ Competing Issues: None at this time ---++ Use cases ---++ N-way mux Consider an N-way mux component. <verbatim> entity mux generic ( type ELEM; type ARR is array (integer) of ELEM); port ( inputs : in ARR; select : in integer; muxed : out ELEM); end entity;</verbatim> The ARR type generic declaration indicates that the index type is integer and the element type is ELEM. We could allow a full subtype indication, but it probably isn't necessary. I can use this component in a variety of settings. * <verbatim>ELEM => time </verbatim> and <verbatim>ARR => time_vector</verbatim> * <pre>ELEM => signed </pre> and <pre>ARR => signed_vector</pre> * <pre>ELEM => real </pre> and <pre>ARR => real_vector</pre> * <pre>ELEM => std_logic</pre> and <pre>ARR => std_logic_vector</pre> ---++ Inner product Another example is an inner product, a key operation in an FIR filter (and lots of other settings). <verbatim> entity inner_product generic ( type ELEM; type ARR is array (integer) of ELEM; ZERO : ELEM; function "*"(a,b : ELEM) return ELEM is <>; function "+"(a,b : ELEM) return ELEM is <>); port ( left : in ARR; right : in ARR; iprod : out ELEM); end entity; architecture generic of inner_product is begin process(all) is variable tmp : ELEM; begin tmp := ZERO; for idx in left'range loop tmp := tmp + left(idx) * right(idx); end loop; iprod <= tmp; -- this only works if they have identical ranges; it's easy to extend to -- different ranges as long as both are ascending or descending, which can -- be guaranteed with an alias end process; end architecture;</verbatim> This inner product component works equally well for any numeric type. * <pre>ELEM => integer </pre> and <pre>ARR => integer_vector</pre> * <pre>ELEM => real </pre> and <pre>ARR => real_vector</pre> * <pre>ELEM => complex </pre> and <pre>ARR => complex_vector</pre> * <pre>ELEM => signed </pre> and <pre>ARR => signed_vector</pre> * <pre>ELEM => sfixed </pre> and <pre>ARR => sfixed_vector</pre> (Some of these vector types are not defined in the current standard, but they're obvious.) Pipelining the calculation is left as an exercise for the designer. The point is that without special getter functions, this would not be possible. ---++ Serial to parallel This case shows using the array as an L-value, which isn't possible using subprograms. <verbatim> entity serial_to_parallel generic ( type ELEM; type ARR is array (integer) of ELEM); port ( serial : in ELEM; parallel : out ARR; parallel_stb : out std_logic; clk : in std_logic); end entity; architecture generic of serial_to_parallel is begin process(clk) is variable collect : parallel'subtype; variable pos : parallel'range := parallel'low; --BUG: inserts values right-to-left for descending ranges begin if rising_edge(clk) then -- CANNOT DO THIS directly, and indirectly only with major headache -- without this proposal collect(pos) := serial; parallel_stb <= '0'; if pos = parallel'high then pos := parallel'low; parallel_stb <= '1'; parallel <= collect; else pos := pos + 1; end if; end if; end process; end architecture;</verbatim> ---++ Variations ---++ Generic index We could also allow the array index to come from a type generic. <verbatim> entity mux generic ( type ELEM; type INDEX; type ARR is array (INDEX) of ELEM; ...</verbatim> Main.RyanHinton can't come up with a good use case for this, but it would be nice to not preclude the capability if it's easy to specify and implement. (Main.RyanHinton: implementors seem to pick and choose which features to implement according to their resources and perceived importance of various features. So if allowing the index to be a type generic is particularly hard and/or rare, they will simply postpone implementation. In other words, the committee can specify what it wants, and the cost/benefit tradeoff will determine if/when it is implemented.) ---++ No index specified We could probably get away without specifying the index at all. Especially if we add a 'index attribute to array types to get the index subtype. But in most cases we can just use attributes on the object of interest. These uses break down if the array type of interest has more than one index, but the #Generic_index case can't handle this seamlessly, either. <verbatim> entity mux generic ( type ELEM; type INDEX; type ARR is array of ELEM; ...</verbatim> ---++ Comments Peter's original proposal had provisions for marking items as arrays. It also had a sense of numeric, however, I don't remember there being a way to allow types such as unsigned, and signed to be designated as a numeric. This is part of the reason I added a proposal for abstract packages. -- Main.JimLewis - 2013-05-02 ADA has already solved this issue: https://en.wikibooks.org/wiki/Ada_Programming/Generics#Generic_formal_types -- Main.LievenLemiengre - 2016-04-22 ---++ Arguments FOR ---++ Arguments AGAINST -- Main.KevinJennings - 2013-05-09 Since the type is defined within the entity, how does the user of the entity define a signal of the correct type? For the N-way mux example, there would have to be an array of the proper type hooked up...since the array type is defined locally to the entity, it would not be visible. That's why, in today's world, one would define these things in a package which would then be used both by the N-way mux and the code that instantiates the N-way mux. Am I missing something? [Main.RyanHinton - 2013-06-18] The array type is not *defined* in the entity. What looks like an array type declaration is merely specifying that an array type with some features is expected as a generic. I like the similarity to an array type declaration because it's familiar. But you can't decalre a new type in an interface list, so there shouldn't be any ambiguity. --Main.CliffordWalinsky - 2013-11-13 I agree with KevenJennings -- the appropriate abstraction to use in the generic list for the inner product example is an interface package. Generic packages can define multiple types and subtypes dependent on generic types. ---++ Supporters -- Main.RyanHinton - 2013-05-02 -- [[Main.BrentHahoe][Brent Hayhoe]] -2013-15-02 -- Main.JimLewis - 2014-12-04 -- Main.MortenZilmer - 2015-01-21 _Add your signature here to indicate support for this proposal._
E
dit
|
A
ttach
|
P
rint version
|
H
istory
: r10
<
r9
<
r8
<
r7
<
r6
|
B
acklinks
|
V
iew topic
|
Ra
w
edit
|
M
ore topic actions
Topic revision: r10 - 2020-02-17 - 15:34:49 -
JimLewis
P1076/Ballots
Log In
or
Register
P1076/Ballots Web
Create New Topic
Index
Search
Changes
Notifications
RSS Feed
Statistics
Preferences
Webs
Main
P1076
Ballots
LCS2016_080
P10761
P1647
P16661
P1685
P1734
P1735
P1778
P1800
P1801
Sandbox
TWiki
VIP
VerilogAMS
Copyright © 2008-2026 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki?
Send feedback