When unsized literals are used in case item expressions, it is likely
that the calculated expression width will be larger than necessary to
unambiguously select the correct case item (particularly when using
"strict" expression elaboration). This patch adds an optimisation
step that prunes the expressions to the minimum necessary width.
This patch fixes the following enumeration bugs:
When looking for an enumeration look in the current scope and then
recursively in any parent scope.
Add enumeration definitions to a package scope.
Internally, treat the "$" as a special expression type that takes
as an argument the signal that is being indexed. In the vvp target,
use the $last system function to implement this.
Like this:
... if (ce0) foo <= foo_in;
... if (ce1) bar <= bar_in;
Note that this is within a block, and represents multiple FF nodes
with different clock enables.
When for example assigning to foo[<x>] within a contitional, and
doing synthesis, we need to create a NetSubstitute device to manage
the l-value bit selects.
This generates an EQZ LPM device that carries the case-z-ness to
the code generator.
Also add to the vvp code generator support for the EQZ device so
that the synthesis results can be simulated.
Account for the wildcard devices in the sizer.
When conditional ports are blending (by allowing NetPartSelects be
connected together to the outputs) make sure there isn't an accidental
overlap of drivers that invalidates the process.
In a design, there may be lingering NexusSet objects, or the
nodangle may itself use NexusSet objects. This creates links,
and this should not confuse the functor.
While we are at it, clean up some handling of events structures.
This required keeping for-loops as actual things through the
netlist form so that the synthesizer can get at and understand
the parts of the for-loop. This may improve vvp code generation
in the future, but for now continue to present to the vvp code
generation the block-while form.
If statements within blocks can confuse the synthesizer when there
are outputs that are assigned ahead of the if statement. This patch
handles that case.
If the l-value is an unresolved wire, then elaboration can allow
the assignment as long as it is to bits that are not otherwise
driven. Handle this in some simple cases.
When a module is instantiated multiple times, the enum
types contained within would cause trouble. This fixes
that by elaborating in proper scope context.
This patchs adds support for the $dimensions() and $unpacked_dimensions()
array functions. Since the argument is only used to get the type information
these functions can always be evaluated at compile time.
For the following functions if the dimension argument is constant or omitted
and the first argument is not dynamic (a string or dynamic array) they will
return the specified information.
$left(), $right(), $high(), $low(), $increment() and $size()
Dynamic information and a variable second argument will be implement in a
future patch.
This allows for syntax like a.b.c where a is a class with member
b, which is a class with member c, and so on. The handling is mostly
for the support of compound objects like classes.
This gets nested l-values to (but just short of) the ivl_target API.
Now the elaborator can process nested l-values, but I haven't figured
out how to present that at the ivl_target.h API.