SystemVerilog requires that functions and tasks are not implicitly imported
if a symbol with the same name appears in the scope, even if it the symbol
is declared after its usage.
To support this a list of potential imports is collected while parsing a
scope and only when the end of the scope is reached it is evaluated whether
the symbol should be imported or not based on whether it already exists in
the scope.
This currently works fine for all scopes except for the unit scope. Since
the unit scope might span multiple files it is never explicitly closed and
the potential imports are never checked.
Make sure that after parsing all files is done the potential imports for
the unit scope are checked.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
SystemVerilog allows to omit the default value of a parameter declared in a
parameter port list. In this case the parameter must be overridden for
every module instance. This is defined in section 6.20.1 ("Parameter
declaration syntax") of the LRM (1800-2017).
In addition a module that has a parameter without a default value does not
qualify for automatic toplevel module selection.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
When elaborating a subclass, the base class scope needs to be elaborated
before the subclass scope. If the base class and subclass are defined in
different packages, this requires the package scopes to be elaborated in
the correct order. SystemVerilog reqires packages to be defined before
they are used, so that is the order we should elaborate them in.
__CYGWIN32__ is not defined when building with the 64-bit Cygwin
toolchain. According to the Cygwin FAQ, __CYGWIN__ has been defined
since 1998, so this should still work for users on 32-bit systems.
The '-i' option is there to allow the compiler to be used to check an
incomplete design for errors. With no top-level modules, nothing will
be elaborated, but at least will be checked for syntax errors.
This implements and enforces the full set of rules for determining
timescales in SystemVerilog. The previous relaxation of the rules
that allowed timescales to be redefined within the compilation unit
scope has been removed. Time unit and precision redeclarations are
now recognised after a nested module declaration.
The compilation unit scope is now treated as a specialised form of
package (with an automatically generated name). All items declared
outside a design element are added to the current compilation unit
package. Apart from when searching for a symbol, once we get into
elaboration we can treat these just like any other package.
This adds a -u option to the driver to allow the user to specify that
they want each source file to be treated as a separate compilation
unit, and modifies the compiler to accept a list of files (either on
the command line or via a file specified by a new -F option). This
list of files is then preprocessed and parsed separately, causing all
compiler directives (including macro definitions) to only apply to the
file containing them, as required by the SystemVerilog standard.
Two fixes needed:
- when searching for a base class, we need to look in the root scope
if the base class isn't found in the scope hierarchy
- the classes in the root scope need to be stored in an ordered
list, not a map, to ensure they are elaborated in the order they
were declared. Without this, the compiler may try elaborating an
extended class before its base class is known about.
Replace explicit comparisons against generation_flag with calls to
the gn_system_verilog helper function, both for code clarity and
to fix a couple of bugs. Also simplify the implementation of the
function, as we already rely on the generation_flag enumeration
being an ordered list.
Unsized expressions can expand to extremely large widths. Usually this
is actually a mistake in the source code, but it can lead to the compiler
temporarily using extremely large amounts of memory, or in the worst
case, crashing. This adds a cap on the width of unsized expressions (by
default 65536 bits, but overridable by the user), and causes a warning
message to be output when the cap is reached.
Emit the elaborated class methods. Also generate root scopes to
represent the classes in order to hold the methods. These scopes
can also in the future be used to implement static properties.
Pure functions with constant operands can be evaluated at compile
time rather than at run time. This patch provides a global control
to enable this optimisation. Until constant function support is
complete, by default it is disabled.
Since the vlog95 code generator needs the strength information we do
not want to hide it behind a concat-Z optimization. For now we abort
the optimization, but in the future we could add parts of this back
in (e.g. all the drivers have matching strength then replace with a
normal concat and a buf-Z if the strength are not both strong. The
original buf-Z should be removed to reduce the number of LPM devices).