- Arithmetic right shift used the MSB of the C++ type as the sign bit,
instead of the MSB at the Verilog width.
- Constant shift amounts with their top bit set were treated as
negative, so the oversized shift was emitted as undefined behavior.
- Shifts of an impure operand were replaced by zero, discarding the
side effects of the operand.
Follow up to #8476 and #8493, now that elaboration fully expands
instance arrays, linkDotArrayed's only remaining purpose was to name
AstBegin blocks created after V3Width.
Fix up earlier passes to name all Begin blocks they create, or avoid
creating AstBegin in the first place if possible.
One warning about assigning to a modport input of a generic interface
port had to move into LinkLValue (previously this only used to be
reported by linkDotArrayed, as the type/modportness only resolved in
V3Param, and the lvalueness is subsequently only known in LinkLValue).
Then remove linkDotArrayed and simplify V3LinkDot.cpp
Companion to #8476, and this now moves all instance array and interface
array/modport array port expansion into elaboration. Fixes#2675.
Arrays of interface instances and interface array ports are now split
into their elements during elaboration, instead of after V3Width in
V3Inst::dearrayAll, which is removed.
Background: next to every interface instance 'intf ifs()', V3LinkCells
creates a companion variable 'ifs__Viftop' of type IfaceRefDType
referring to the instance, so the instantiating module can use the
interface as a value (in pin connections, virtual interface assignments,
arguments, ...) just like a module referring to it through an interface
port. For an array of instances 'intf ifs[N]()', this variable is an
unpacked array of IfaceRefDType, but an IfaceRefDType can only refer to
a single instance, so it must be split into a variable for each element,
and every use of the whole array replaced.
V3Param expands interface instance arrays like module instance arrays,
also splitting the __Viftop variable referencing the whole array into a
variable for each element cell ('ifs__BRA__i__KET____Viftop', the
companion of element cell 'ifs__BRA__i__KET__'), and splits each
interface array port into a variable for each element. The whole array
variables remain until all references to them are replaced, so V3LinkDot
can link hierarchical references to the correct specialization.
In V3Width, every reference to a whole interface array, including
hierarchical ones, is replaced by an AstInitArray of references to its
element variables, typed as the whole array, e.g. 'ifs' becomes
'{ifs[0], ifs[1], ...}. The AstInitArray keeps its own type, so its uses
are checked as those of the whole array. The whole array variables are
removed at the end of V3Width.
V3Width then treats a whole interface array replaced by an AstInitArray
as an ordinary unpacked array value:
- A constant select yields the element, a slice the selected elements.
- A pin of an element of a module instance array selects its part of an
interface array connection like any other connection.
- A pin of an interface array port is split into a pin for each element
port, connected left index to left index.
- A member of an element is referenced through the interface, as for
any other interface.
This supports slices of interface arrays, and interface ports of
multi-dimensional module instance arrays connected to interface arrays.
Arrays of module instances are now expanded into their element cells
during elaboration in V3Param, instead of after V3Width in
V3Inst::dearrayAll. Element cells are named as before
(name__BRA__i__KET__...), are ordered from the left index to the right
index, and hierarchical references to them resolve in linkDotParamed.
Arrays of interface instances are still expanded by V3Inst. They will
move in a follow up patch.
Algorithmically:
- V3Praram replaces an arrayed AstCell, with a scalar Cell for each
element. linkDotParamed can resolve against these as normal.
- V3Width then fixes up the AstPins of each expanded Cell according to
the LRM rules. Either leaving the alone to connect to all instances,
or inserting ArraySel/Sel to connect the relevant part to the relevant
instance.
Partial #2675
This moves V3Inline after V3Scope. Not doing #2226 yet as it has some
fallout. The inlining heuristic is identical to before, but the node
counts might have shifted, so output can be perturbed.
There is a wart needing to be fixed up with how Fsm coverage is
collected, which inserts declarations into the MODULE for each instance
of that module, but we can fix it up.
Otherwise it's fairly straight forward translation of the old algorithm,
there are some quirks due to V3Scope, but nothing drastic. Moving it far
later might be hard though, because of the Fsm-like rewrites, but that's
not something we want to do anyway.
Fixes#1539
Use AstAlias instead of AstAssignW in V3Inst port connection lowering,
the same way as V3Inline would do if the instance is inlined. This
closes some of the gap between -finline and -fno-inline behaviour, and
is also required for moving V3Inline post scope, where it could not
create aliases anymore (hence required for future patch to maintain
current behaviour).
This is also a partial fix to #4698 (only when the connected expression
is a plain VarRef)
Preserve previous whole-element drivers when synthesizing successive
constant-index assignments to unpacked arrays. Retain earlier values
through their assignment temporaries and keep the default while some
elements remain uncovered.
Complete the array-default tracing path exposed by this representation.
Keep public-write checks, control-flow restrictions, and scheduling
unchanged, and cover propagation and conservative fallbacks in the
existing DFG regressions.
Part of #7964; array-only follow-up to #7966.