The fork/join list did not adequately support the tree of processes
that can happen in Verilog, so this patch reworks that support to
make it all more natural.
Making the scope type NESTED_MODULE was just plain wrong, because
it didn't really encapsulate the meaning of program blocks OR
nested modules. So instead create nested_module() and program_block()
flags and use those to test scope constraints.
An important advantage of program blocks is its ability to nest
within a module. This winds up also allowing modules to nest, which
is legal but presumably less used feature.
It is common for typedefs of complex types to use further typedefs.
Emit the type definitions depth first so that the types that are used
are defined first. This reduces the need for pre-declaration of types.
When concatenation expressions have aggregate arguments, we need to
get the type of the result down to the aggregate expressions so that
it can know how to interpret the elements.
Elaborate records and emit them as packed SV records. Also handle
record members so handle name prefixes.
While we are at it, handle some cases of array aggregate expressions.
When signals/variables are records, they are often referenced by
their members, using a prefix.name syntax. Parse that syntax and
generate "sorry" messages in elaboration.
A NetScope object currently has two lists of parameters, 'parameters'
and 'localparams'. However, user-declared localparams are stored in
the 'parameters' list, and 'localparams' is only used for adding
genvar values to the parameter list. There seems no good reason to
maintain separate lists, as the lists are merged before being passed
to the target DLL. This is most likely a hang-over from older code.
This patch extends the compiler to support all specparam declarations
allowed by the 1364-2005 standard. For compatibility with other
simulators, it allows specparam values to be used in any constant
expression, but outputs a warning message and disables run-time
annotation of a specparam if it is used in an expression that must
be evaluated at compile time.
SystemVerilog allows a variable to be used as a variable OR
as an unresolved wire. The detection of this case was checking
the references to the affected value, instead of the l-value
references.
(cherry picked from commit cceeaa30f27260cd444015cb39b04353cb858768)
The final step of expression elaboration is to reduce the width of
lossless/unsized constant expressions to the minimum needed to hold
the resulting constant value. This leads to unexpected results if
the user supplies a literal number with redundant digits that gets
passed to a system task that is sensitive to the width (e.g. $display).
This patch prevents width reduction occurring in this case.