Generics vs Constants - what criteria do you use to choose between these?
I've found a very interesting hybrid approach to managing constant
design parameters, but let me summarize some pro's and con's of
constants vs generics.
Constants can be defined in a global package for the project, and one
can simply be added anytime a new parameter in some lower level module
is needed. Constants, so long as they are not deferred, are locally
static values, and can be used virtually anywhere. But modifying
constants requires changing source code in a difficult-to-manage way.
Different sets of constants (say for build vs verification) must be
managed with separate files that define the same package, and are
selectively used based on the application (there are no named package
bodies that can be chosen via configurations, etc., and even if there
were, it would require deferred constants, which then loses the locally
static advantage).
Generics are not locally static, and must be passed down through the
hierarchy if they are to be centrally managed. However, they can be
managed within the abilities of vhdl, without resorting to file naming
slight-of-hand, by instantiation, configuration, and tool command line
options.
While there is nothing that can be done to address the non-locally
static problem of generics, managing their passing through the
hierarchy can be made easier. By defining a record type in a global
package which contains elements for each constant required, we can have
a flexible "handle" by which to pass all the parameters to every level
with a single generic map association. Whenever a new parameter is
needed, the record type is changed to add it, the value is set at the
top (entity, instance, configuration, or tool) and only the lower level
entity/architecture that needs it is modified to extract it from the
record.
The default values for the top level generic can be defined in the
generic declaration, or by referencing a constant defined in the same
global package that defined the record type. Either way, the default
assignments can be overridden by the testbench that instantiates the
top level entity, by one or more configuration declarations (requiring
a wrapper around the otherwise top level entity), or by tool command
line options.
BTW, I almost always use a ns_per_clk : positive generic to pass clock
period info for timers, etc. Synopsis used to not be able to specify
non-integer generics from the command line. I don't know if they can
today. To get around such a problem with records, the top leve entity
can have all the separate integer generics declared, and then assemble
them into a record in the top level architecture, for passing down
through the hierarchy.
No matter which method is used (constants or generics), I strongly
recommend subtyping them to constrain the values to practical limits.
If a parameter must, say, be a integral power of two, then a concurrent
assertion statement should verify that at the point of use.
Comments?
Andy
|