Compare commits

..

381 Commits

Author SHA1 Message Date
Lars-Peter Clausen b5fdf06475 Add regression tests for elaborated cast targets
Check a type cast with an inline packed dimension and reject dimensions
following a type identifier in a cast target. Use a dimensioned typedef in
the reject test to distinguish dimensions in the type from dimensions after
the identifier.

Check that an error reported while elaborating a cast-target type is emitted
only once when width checking and expression elaboration reuse the cached
target information. Also check that each module instance resolves a
type-parameter cast target using its own parameter value.

Check that typed dynamic-array elaboration constructs the explicit cast
target rather than the enclosing expression type.

Run the tests through the native and vlog95 backends.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 19:31:38 -07:00
Lars-Peter Clausen bea0fdeb3c Resolve type and size cast targets during elaboration
A SystemVerilog cast target can be either a type or a constant size
expression. Currently the parser commits to `PECastType` or `PECastSize`
based on how the target identifier is classified while parsing. This is too
early for identifiers whose meaning is only known after symbol lookup. As a
result, corner cases are handled incorrectly when parser-time classification
does not match the result of elaboration. For example, the parser can not
decide whether an identifier inherited from a base class is a type or a
constant size expression. Supporting the inherited lookup is separate, but
the cast target must remain unresolved until elaboration for that lookup to
be used.

Parse both forms through `expr_primary_or_typename` and represent them with
one `PECast`. Keep atomic types wrapped in `PETypename` and preserve named
targets as `PEIdent`.

Resolve the target during elaboration. First use `test_type()` to distinguish
a type target from a constant size expression. For a type target, use a
contextual `elaborate_type()` call to resolve the type. Diagnose dimensions
after a type identifier directly from `PEIdent::elaborate_type()` when it is
used as a cast target. A failed type elaboration returns `nullptr` and does
not fall back to interpreting the target as a size expression. Dimensions
contained in the named type remain valid.

Cache the resolved target information during width checking because ordinary
expression elaboration needs the same information. Tag the cache with the
`NetScope` and recompute it when the scope changes since type parameters can
give the same cast expression a different target type in each instance.
Typed elaboration can bypass width checking, so resolve into a local value
when no matching cache is available. This avoids modifying the parsed
expression from a const elaboration method while still avoiding repeated
diagnostics between the normal width checking and expression elaboration
phases.

Share the type and size conversion paths between width-based and typed
elaboration. Use the explicit cast target when constructing a dynamic array
instead of the enclosing expression type. Own the cast target and operand
with `std::unique_ptr`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 19:31:38 -07:00
Lars-Peter Clausen 506eaa5415 Add tests for dimensions on named types
Check that packed dimensions are preserved when local and
package-qualified identifiers resolve to types in type parameter values and
system function arguments. Verify that symbolic dimensions are evaluated in
the scope of each module instance.

Check the diagnostics for unsized and queue suffixes, indexed part selects,
and packed dimensions applied to an unpacked named type.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 17:19:54 -07:00
Lars-Peter Clausen 21bfe06b33 Add tests for named type expression lookup
Check that lookup chooses the nearest visible type or value when an
identifier can denote either. Cover lexical ordering, inherited properties,
and a bracket suffix that must remain a value select after lookup.

Check typed expression and l-value contexts where a type must be rejected
instead of binding an outer value. Check that a hierarchical type reference
is rejected with the type-specific diagnostic.

Check that probing an invalid hierarchical type parameter does not elaborate
its signal prefix and report a false circular dependency.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 17:19:54 -07:00
Lars-Peter Clausen db90f0ef06 Resolve named types during expression elaboration
Named types in expression-like contexts are currently converted to
`PETypename` by the parser. This commits to the type interpretation before
symbol lookup, although the same syntax can represent an ordinary identifier.

Keep atomic types as `PETypename`, but parse local and package-qualified type
identifier candidates as `PEIdent`. Preserve any bracket suffixes so they can
be interpreted as packed dimensions for a type or as selects for a value.

Add `PExpr::test_type()` for non-elaborating type detection and
`PExpr::elaborate_type()` to return the elaborated type. Use these interfaces
for `$bits()`, `$sizeof()` and type parameters. Callers test the
interpretation before elaborating it, so a null type reports an elaboration
failure without incorrectly falling back to value elaboration.

Type testing is normally followed by elaboration, and both operations need
the same symbol lookup. Let `PEIdent::test_type()` cache the result and its
declaration scope, keyed by the lookup scope. Keep `elaborate_type()` const and
perform a local lookup when type testing was skipped or the cached result is
from another scope. This avoids repeated lookup without reusing a
scope-dependent result.

Search the complete identifier path before deciding whether it names a type.
Stop lookup at signal placeholders so they still hide matching types in outer
scopes without being elaborated by the type probe.

The LRM section 6.18 does not allow hierarchical references to type
identifiers, so reject a dotted type reference after lookup and report where
the type was declared. This distinguishes an invalid `test.T` type reference
from a path that does not name a type.

Use the unified symbol lookup result to choose the type or value
interpretation. Report an error when a type reaches an expression or l-value
context. This preserves normal lexical shadowing while deferring only the
syntactic decision.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 17:19:54 -07:00
Lars-Peter Clausen a7e258fad1 symbol_search(): Add lookup flags
`symbol_search()` currently uses a boolean argument to allow forward
references to the terminal name. Additional lookup options would require more
boolean arguments and make call sites difficult to read.

Replace the boolean with a bitmask and use a named flag at the existing
forward-reference call sites. Add a second flag that stops lookup at an
unelaborated signal instead of elaborating it. Stopping the lookup makes the
signal continue to hide matching symbols in outer scopes.

Forward-reference permission applies only to the terminal name, while signal
elaboration suppression applies to the complete path. This allows callers
that only need to classify a name to avoid triggering signal elaboration
during lookup.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 17:19:54 -07:00
Lars-Peter Clausen 9a2106a439 Add regression tests for types during symbol lookup
Check that a visible type prevents lookup from continuing to an outer value
for function and task calls and implicit `.name` and wildcard `.*` port
connections. Check that types are rejected as disable targets, named events,
procedural l-values, and expressions elaborated with a required type.

Also check the opposite lexical-order case where a typedef declared after a
reference does not hide an outer named event or variable. Use diagnostic gold
files for each negative case that emits the type-specific error.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 13:56:31 -07:00
Lars-Peter Clausen c5ab989dc7 Consider types during symbol lookup
SystemVerilog places user-defined types and data identifiers in the same
namespace. Symbol lookup cannot currently return a type, so a value lookup can
skip a nearer typedef and incorrectly bind a value in an outer scope when an
ambiguous identifier is resolved during elaboration.

Add typedef results to `symbol_search()` and check visible typedefs before
continuing to enclosing scopes. Use the lexical visibility limit selected by
the caller. This is normally the reference position, while function and task
call lookup uses the end of the current scope as required by the LRM section
26.3.

Let callers that require a value or another non-type symbol diagnose the type
result and report its declaration location. This includes function and task
calls, expressions with and without a required type, procedural l-values,
named-event triggers, and disable targets. Callers that only probe for a
particular kind of symbol, including port-connection matching, ignore a type
result. Also ensure scope-only callers do not confuse the typedef's owning scope
with the resolved object.

This prepares expression elaboration to defer the type-versus-value decision
while preserving lexical shadowing.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 13:56:31 -07:00
Lars-Peter Clausen 3ed306bab8 Add regression tests for disable target lookup
Check separately that a local variable, named event, and parameter hide a
compilation-unit task used as a disable target.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 08:43:32 -07:00
Lars-Peter Clausen 6e8c05eda8 Use `symbol_search()` for disable targets
Disable targets currently use `Design::find_scope()`, which searches only
scope names. A task or named block from an outer scope is therefore selected
even when a variable, named event, or parameter in a closer scope has the
same name.

The LRM section 3.13 places tasks, named blocks, parameters, named events, and
variables in the same local name space. Use normal symbol lookup and require
the result to be a scope. This lets a closer non-scope object hide the outer
disable target and reports an error for the non-scope result.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 08:43:32 -07:00
Lars-Peter Clausen b3d0677d08 Add regression tests for task and function call lookup
Check that a closer variable, named event, or parameter hides a task or
function used as a statement. Also check object method lookup and recursive
function calls used as statements.

Check that a later compilation-unit task or function takes precedence over a
matching subroutine in an enclosing instance. Check that different instances
of the same module resolve task calls through their respective enclosing
instances. Check ordinary lexical ordering for a task-call receiver declared
before or after the reference.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 08:43:32 -07:00
Lars-Peter Clausen 7c5c1acf02 Use `symbol_search()` for task and function calls
Task and function calls used as statements currently use
`Design::find_task()` and `Design::find_function()`, which only search for
scopes of the requested type. A closer variable, named event, or parameter is
skipped. This can call a hidden task or function, and can make the non-void
discarded-return path resolve a different symbol and abort.

Use one `symbol_search()` for both task lookup and the function fallback so
all declarations in the shared name space participate in lookup. Accept a
function scope or the return variable of a recursive function call, while
preserving the existing method fallback.

Allow the terminal task or function name to be declared later while resolving
a receiver prefix at the call position. Use the call position when the method
fallback searches for the receiver as well.

Remove the now unused `Design::find_task()` and `Design::find_function()`
helpers.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 08:43:32 -07:00
Lars-Peter Clausen e5f2975a97 Add regression tests for compilation-unit lookup order
Check that same-named scopes in the enclosing instance hierarchy do not
interfere with lookup of compilation-unit variables, parameters, named events,
and imported variables. Cover expressions, procedural l-values, implicit and
wildcard port connections, and lookup from module and nested function scopes.

Check task and function calls, including method receivers and chained calls.
Verify that receiver prefixes follow ordinary lexical ordering while direct,
imported, and chained compilation-unit function names can be declared after
their references. Check the enclosing-instance fallback when the compilation
unit has no match.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 08:15:31 -07:00
Lars-Peter Clausen 9d7e8e67ab symbol_search(): Search compilation-unit scope before instance hierarchy
`symbol_search()` currently searches the enclosing instance hierarchy before
the compilation-unit scope for ordinary names. An enclosing instance scope can
therefore hide an earlier compilation-unit variable or object, including when
the object is the prefix of a dotted reference.

The LRM section 3.12.1 requires a common lookup order. First search the local
lexical scopes through the design unit. Next search the compilation-unit scope
up to the reference position. If there is no match, resume at the saved
instantiation parent and continue through the instance hierarchy. Disable data
object lookup when resuming so only enclosing scope names can match.

Task and function names follow the same traversal, but the LRM section 23.8.1
lets the terminal subroutine name search the complete compilation unit. Use a
separate terminal lexical limit for this. Resolve a prefix such as `object` in
`object.func()` at the reference position while allowing a forward declaration
of `func`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 08:15:31 -07:00
Lars-Peter Clausen f35515ac65 symbol_search(): Track compilation-unit search explicitly
The scope traversal clears `start_scope` after switching to the compilation
unit and uses the null value to prevent a second compilation-unit search.
This gives the scope used for path evaluation two separate purposes.

Track whether the compilation-unit scope has been searched with a separate
flag. Keep the existing instance-before-compilation-unit traversal order.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 08:15:31 -07:00
Lars-Peter Clausen 4e425289bb symbol_search(): Track object visibility directly
The scope traversal tracks whether it has crossed a module boundary and
uses the inverse of that state to decide whether objects are visible.

Track object visibility directly instead. This keeps the existing behavior
while making the module-boundary rule and later traversal changes easier to
follow.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 08:15:31 -07:00
Lars-Peter Clausen 6155d56482 symbol_search(): Factor child scope lookup into a helper
Child scopes and interface aliases are matched directly in the scope
traversal. This obscures the code that decides which scope to search next.

Move the child scope and interface alias lookup into a helper. Keep the
existing lookup order and error handling unchanged so the traversal can be
restructured separately.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 08:15:31 -07:00
Lars-Peter Clausen cf6f70e03b symbol_search(): Factor object lookup into a helper
The object lookup for each scope is embedded in the scope traversal. This
makes the traversal order and the module boundary handling difficult to
follow.

Move net, event, parameter, class property, and placeholder lookup into a
helper. Use separate found, not found, and failure results so the existing
lookup behavior is preserved. This prepares the scope traversal to be
changed independently.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-16 08:15:31 -07:00
Lars-Peter Clausen 1d2aa1b6fa Add regression tests for duplicate class property names
Check that a class property cannot share a name with another property, a
function, a task, a parameter, a type, or an enum named constant. Check
duplicate properties in both separate and comma-separated declarations. The
latter guards the shared declaration type ownership that previously caused a
crash.

Exercise properties in both declaration orders so both member registration
paths are covered.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-10 20:30:46 -07:00
Lars-Peter Clausen 7752cb8ec1 Reject duplicate class member names involving properties
The LRM requires an identifier to name only one item within a scope. Class
properties are currently stored only in `class_type_t::properties`, outside
the common local symbol table. As a result, declarations such as:

    class C;
      int value;
      function int value;
        return 0;
      endfunction
    endclass

are accepted. A second property in a separate declaration silently replaces
the first property map entry. A repeated name in a comma-separated declaration
such as `int value, value` can crash because both declarators share the same raw
type.

Make `prop_info_t` a named item and register each property in the class local
symbol table. Check the declaration before taking ownership of its type or
initializer, since comma-separated properties share the raw declaration type.
Use `emplace()` for the property map so an accepted property cannot replace an
existing entry.

Properties now take part in the common symbol lookup. Give them a distinct
symbol type so duplicate declaration diagnostics identify them as class
properties, and remove the separate property check from type-identifier
classification.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-10 20:30:46 -07:00
Lars-Peter Clausen 2efe188b52 Add regression tests for invalid index component contexts
Consolidating variable dimensions and hierarchy indices into a shared
grammar makes all index component forms parse in either context.

Check that `+:` and `-:` indexed part selects are rejected as dimensions,
and that `[]` and `[$:N]` are rejected as hierarchy indices. These forms
were previously excluded by the context-specific grammar rules.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-10 20:17:46 -07:00
Lars-Peter Clausen cb3bf494f2 Consolidate variable dimension and hierarchy index grammar
Variable declaration dimensions and hierarchical identifier indices both
use bracketed components, but are parsed by separate grammar rules.
Consolidate them into a shared `index_component` rule and convert the
components once the surrounding context is known.

This prepares for accepting a `TYPE_IDENTIFIER` token as an ordinary name
in a hierarchical path. A path component can have the same spelling as a
typedef visible in the current scope. In the path it is an ordinary
identifier. The hierarchical reference does not override or replace the
typedef.

The shared rule parses component forms that are not valid in both contexts.
Preserve the previous restrictions by explicitly rejecting indexed part
selects in variable dimensions and empty or bounded-queue components in
hierarchical identifiers. Track the location of each component so these
errors point to the invalid suffix.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-10 20:17:46 -07:00
Lars-Peter Clausen 008b76eae6 Add regression tests for `null` array dimensions
Check that source `null` expressions in `[null]` and `[null:N]` are
rejected rather than treated as the `$` marker for unbounded and bounded
queue dimensions.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-09 15:08:01 -07:00
Lars-Peter Clausen 04c21e1982 Distinguish queue dimensions from `null` expressions
Queue dimensions use a `PENull` expression as an internal marker for `$`.
This also represents a source `null` expression, so declarations such as:

    integer value[null:2];

are accepted and elaborated as bounded queues.

Use a dedicated `PEQueueDimension` marker for queue dimensions. This lets
source `null` expressions follow normal range expression validation while
preserving the existing representation of dynamic and fixed dimensions.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-09 15:08:01 -07:00
Lars-Peter Clausen 72998c5415 Add regression test for inherited non-void function calls
Check that a bare inherited non-void function call used as a statement emits
the required discarded-return warning and executes the function.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-08 18:44:26 -07:00
Lars-Peter Clausen d1e0fa7da0 Handle inherited non-void function calls as statements
The LRM section 13.4.1 permits a non-void function call to be used as a
statement and requires a warning when the return value is implicitly
discarded. A bare call to an inherited class function currently emits that
warning and then aborts.

Method lookup finds the inherited function through the implicit `this`
receiver. The discarded-result path then rebuilds a `PECallFunction` from the
original bare name, losing the receiver and leaving the expression without a
type.

Pass the resolved method path to the discarded-result path so the rebuilt call
remains qualified by `this`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-08 18:44:26 -07:00
Lars-Peter Clausen aa8f928ffa Add regression tests for initialized const static properties
Check that a `const static` class property with a declaration
initializer is accepted and has the initialized value. Also check that
subsequent assignments through unqualified and object-member lookup are
rejected.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-08 18:06:24 -07:00
Lars-Peter Clausen 4ffeb748f4 Accept initialized const static properties
Static property declaration initializers are elaborated as standalone
initialization processes instead of through a class constructor. The
const-property bookkeeping therefore does not see the initializer and
reports an initialized `const static` property as missing initialization.

Record whether each parsed property has a declaration initializer and
mark an initialized static const property when its signal is created.
Also mark the signal as const and its declaration assignment as an
initializer. This permits that initial assignment while rejecting later
writes. Uninitialized static const properties remain errors.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-08 18:06:24 -07:00
Lars-Peter Clausen b883f7713c Add regression test for nested const property initialization
Check that a const property can be assigned from a named block inside its
class constructor.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-08 18:06:24 -07:00
Lars-Peter Clausen 14066871e5 Allow const property initialization in nested constructor blocks
A named block inside a class constructor has its own scope. The const property
assignment check currently tests the name of this immediate scope and rejects
the assignment because it is not named `new` or `new@`.

Find the containing class method before deciding whether the assignment is in
the constructor. Assignments from nested blocks in other methods remain
invalid.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-08 18:06:24 -07:00
Lars-Peter Clausen bfc0121fb9 Add regression test for const properties in derived classes
Check that an inherited property does not offset initialization bookkeeping
for a const property assigned in the derived class constructor.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-08 18:06:24 -07:00
Lars-Peter Clausen 6e2c7f352e Fix const property initialization in derived classes
Property indices include the properties inherited from base classes.
`netclass_t::get_prop_initialized()` currently uses this combined index
without removing the inherited property count when accessing the local
property table. This can read past the table and treat a derived const
property as already initialized.

Subtract the inherited property count, matching the other property accessors.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-08 18:06:24 -07:00
Lars-Peter Clausen f493076882 Add regression test for nested class method calls
Check that an unqualified method call from a named block uses the implicit
`this` signal from the containing class method. The compiler currently looks
for the signal in the named-block scope and crashes.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-05 20:45:56 -07:00
Lars-Peter Clausen b4d92f7bb9 Find implicit `this` in the containing class method
An unqualified method call inside a named block is elaborated from the block
scope. When the call resolves to another method in the same class, receiver
construction looks for the implicit `this` signal directly in that scope:

    function int call_method();
      begin : nested
        return get_value();
      end
    endfunction

The signal belongs to the containing method scope, so the lookup returns null
and the compiler dereferences it.

Find the containing method first and obtain the implicit `this` signal from
that scope.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-05 20:45:56 -07:00
Lars-Peter Clausen c71709d75d Add regression tests for `$unit::` reference order
Check separately that `$unit::` references to a variable, named event, and
parameter declared later in the compilation unit are rejected.

Also check that preceding compilation-unit items remain visible and that a
later function name remains visible as permitted by the LRM section 3.12.1
exception.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-05 20:45:43 -07:00
Lars-Peter Clausen 9a06cf5483 Check declaration order for `$unit::` variables, events, and parameters
The LRM section 3.12.1 says that `$unit::` only disambiguates a name in
the compilation-unit scope and does not allow a reference to an item declared
later. Currently every bound scope is exempt from declaration-order checks, so
this incorrectly resolves `value`:

    module test;
      initial $display("%0d", $unit::value);
    endmodule

    integer value;

Apply the existing variable, named event, and parameter declaration-order
checks when lookup is bound to a compilation-unit scope. Other hierarchical,
package, and imported lookups remain bound without comparing unrelated lexical
positions. Task and function lookup remains unchanged, as required by the
exception in the same LRM section.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-05 20:45:43 -07:00
Lars-Peter Clausen 8e420f56ff Add regression tests for enum named constant reference order
Check that a reference before an inner enum declaration resolves to a
matching enum named constant in the outer scope, while a reference after the
declaration resolves to the inner constant.

Also check that `-gno-strict-parameter-declaration` continues to allow a
reference to a later enum named constant and identifies it correctly in the
declaration-after-use warning.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-04 21:22:08 -07:00
Lars-Peter Clausen f6f7f9d6d7 Consider lexical ordering for enum named constants
Enum named constants use the parameter lookup path, including its lexical
declaration-order check. Their declaration position is currently reported as
zero, however, so a later enum named constant can incorrectly hide a matching
constant from an outer scope.

Attach the parsed enum item's source location to the elaborated enum constant
and use its lexical position during lookup. Have the position lookup also
identify enum named constants so relaxed-mode warnings do not call them
parameters. Update the position after a warning to retain the existing warning
suppression behavior.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-04 21:22:08 -07:00
Cary R 591d2c2473 Fix for GH 1140 2026-08-03 21:31:18 -07:00
Lars-Peter Clausen 8cd52ac5be Add regression test for wildcard imports in bare delays
Check that a bare delay identifier before a wildcard package import resolves
an outer constant. Check that a following bare delay activates the import and
resolves the package constant.

Run the test through the native and vlog95 backends.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-03 21:20:46 -07:00
Lars-Peter Clausen 101bf5f841 Activate wildcard imports for bare delay identifiers
Bare identifiers used as unparenthesized delays construct `PEIdent` directly.
This bypasses wildcard package import activation, so a delay reference after
an import can resolve to an outer declaration instead of the imported name.

Create the identifier through `pform_new_ident()` so the import becomes
visible at the reference's lexical position.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-03 21:20:46 -07:00
Lars-Peter Clausen e4d29bb1c1 Add regression test for cross-unit package imports
Check that value parameters, `localparam` constants, scalar variables,
unpacked arrays, named events, and enum literals imported from a package in
another compilation unit are visible in the importing module. Exercise both
explicit and wildcard imports.

Give the package declarations larger unit-local lexical positions than the
references in the importing unit so that comparing these unrelated positions
exposes the bug.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-03 20:56:29 -07:00
Lars-Peter Clausen da0adf6614 Avoid comparing lexical positions across units for package imports
Package imports already resolve names declared in packages from other
compilation units. After `NetScope::find_import()` finds such an import,
however, `symbol_search()` continues with an unbound lookup. It then compares
the declaration position in the package with the reference position in the
importing unit. Lexical positions are local to a compilation unit, so these
unrelated values can make a legal imported variable, named event, or parameter
appear to be used before its declaration.

Set `scope_is_bound` after `NetScope::find_import()` has checked that the
import is visible at the reference. The import already identifies the package
that declares the name, so binding the search avoids the invalid cross-unit
comparison and prevents lookup from continuing outside that package.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-03 20:56:29 -07:00
Lars-Peter Clausen 431b3ba1a2 Rename `prefix_scope` to `scope_is_bound`
The `prefix_scope` flag indicates that symbol lookup has been bound to a
specific scope. It controls whether lookup can continue outside that scope
and whether declaration ordering must be checked.

Rename it to `scope_is_bound` to describe the lookup state instead of how the
scope was selected. This allows other scope bindings to reuse it.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-03 20:56:29 -07:00
Lars-Peter Clausen e393487126 Add regression test for wildcard imports in implicit named ports
Check that an implicit `.name` port connection before a wildcard import
resolves an outer declaration, while a connection after the import
resolves the declaration from the package.

Run the test through the native and vlog95 backends.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-03 20:37:59 -07:00
Lars-Peter Clausen 19772cfe07 Activate wildcard imports for implicit named port connections
The LRM section 23.3.2.4 says that an implicit `.name` port
connection is a reference that can make a name from a preceding wildcard
package import visible. Currently `.name` creates its `PEIdent` directly
and skips the package import reference bookkeeping, so the imported name
can not be resolved.

Allow `pform_new_ident()` to suppress implicit net creation and use it for
`.name`. This keeps import activation, `PEIdent` construction, and source
location handling in one place while preserving the existing behavior
that prevents `.name` from creating an implicit net.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-03 20:37:59 -07:00
Lars-Peter Clausen c5dbdddf7b Add regression tests for specparam reference order
Check separately that a module-body specparam declaration following a
reference is rejected and that a specparam declared in a specify block
remains visible before its declaration.

Run both tests through the native and vlog95 backends.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-03 20:37:46 -07:00
Lars-Peter Clausen dd403e7ea0 Honor declaration order for module-body specparams
The LRM section 6.20.5 permits `specparam` declarations both in a
module body and in a `specify` block. It states:

    A specify parameter declared outside a specify block shall be declared
    before it is referenced.

Currently all specparams retain a declaration position of zero, making a
later module-body declaration visible to an earlier expression:

    module test;
      wire value;
      assign value = delay;
      specparam delay = 1;
    endmodule

Record the source position for module-body specparams. Track when the
parser is inside a `specify` block so the outside-block restriction is
not applied there.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-03 20:37:46 -07:00
Lars-Peter Clausen 2556b5f073 Add regression test for wildcard import in class copy construction
Check that class copy construction in a nested scope activates a wildcard
package import and resolves the imported source. Check that construction in
the enclosing scope still resolves the same-named local source.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-03 20:37:27 -07:00
Lars-Peter Clausen d05b13b604 Activate wildcard imports for class copy construction
The source expression of a class copy constructor currently bypasses
`pform_new_ident()`. An identifier made visible by a wildcard package import
is therefore not activated and can not be resolved during elaboration.

Create the source expression through `pform_new_ident()`, matching ordinary
identifier expressions and preserving the source location.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-03 20:37:27 -07:00
Cary R b1635c21cc Cleanup cppcheck 2026-08-03 00:39:39 -07:00
Lars-Peter Clausen b8b6e225fc Add regression tests for package import reference order
Check separately that explicit and wildcard package imports only affect
following references. Use outer-scope declarations and package declarations
with the same names so references before and after each import resolve
differently.

Also cover implicit named port connections and repeated explicit imports.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-01 19:04:31 -07:00
Lars-Peter Clausen 3679d25e4b Honor package import lexical order during identifier lookup
Package imports become visible from the import declaration, or for wildcard
imports, from the reference that makes an identifier locally visible. For
example:

    package p;
      parameter X = 2;
    endpackage

    parameter X = 1;

    module m;
      localparam A = X;
      import p::X;
      localparam B = X;
    endmodule

Currently both `A` and `B` resolve to `p::X`. `A` should resolve to the
compilation-unit `X`, while only `B` should resolve to `p::X`.

Record the lexical position where each imported name becomes locally visible.
Pass reference positions through ordinary symbol lookup and implicit named
port connections so imports introduced later are ignored.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-08-01 19:04:31 -07:00
Lars-Peter Clausen eda9fdcd13 Add regression test for imported typedef reference order
Check that a typedef reference in a nested scope keeps the package typedef
selected during parsing when another typedef with the same name is imported
later. Check that a reference following the import selects the new typedef.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-26 20:14:31 -07:00
Lars-Peter Clausen 41f4ff0fbc Use the bound typedef to find its declaration scope
Type names are resolved to `typedef_t` objects during parsing. During
elaboration `find_typedef_scope()` currently resolves the name again through
the completed import table. An import appearing after the original reference
can therefore redirect it to a different typedef with the same name.

Search the enclosing and package scopes for the exact `typedef_t` object
instead. This preserves the parsing-time binding and returns the scope that
owns the selected typedef.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-26 20:14:31 -07:00
Lars-Peter Clausen 8df804c273 Add regression tests for wildcard port declaration order
Check separately that a wildcard port connection ignores a declaration after
the module instance in strict mode and uses the port default.

Check the exact position of `.*`: an implicit net created by an explicit
connection before `.*` is connected, while one created after `.*` is not.
Check that `-gno-strict-net-var-declaration` preserves relaxed behavior and
binds a declaration introduced after `.*`.

Run all three tests through the native and vlog95 backends.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-26 20:14:20 -07:00
Lars-Peter Clausen 8997c01d6f Honor declaration order for wildcard port connections
IEEE 1800-2023 section 23.3.2.4 defines a `.*` connection as equivalent
to an implicit `.name` connection for every port not connected explicitly.
The existing `.name` path resolves the matching identifier at the
connection's lexical position. Wildcard port matching instead searches at
the end of the scope, making it find declarations after the connection:

    child i_child(.*);
    wire value;

Use the lexical position carried by the wildcard binding when looking up
and creating wildcard connections. The position of `.*` itself matters
because an earlier explicit port connection can create an implicit net
that the wildcard connection should see:

    child i_child(.source(value), .*);

This also preserves the relaxed lookup provided by
`-gno-strict-net-var-declaration`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-26 20:14:20 -07:00
Lars-Peter Clausen 5f479cbad4 Store lexical positions in LineInfo
Several source and netlist objects inherit `LineInfo` while separately
storing the lexical position associated with the same source location. This
requires callers to copy the file, line, and lexical position independently.

Add the lexical position to `LineInfo`. Have `set_line()` initialize it when
it is unset, so new objects inherit the complete source location while later
diagnostic location updates preserve their established declaration order.
Initialize the field to `UINT_MAX` so zero remains available as a valid
scanner position and missing initialization is distinguishable. Have
`FILE_NAME()` preserve a more precise identifier position.

Remove constructor parameters that duplicate the position supplied through
`FILE_NAME()`. Use the shared field for identifiers, wires, events, event
triggers, nets, and elaborated events. Assign static class property nets
their declaration location since they previously relied on the standalone
`NetNet` position defaulting to zero.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-26 20:14:20 -07:00
Lars-Peter Clausen beaf44895a Use LineInfo::set_line() to copy source locations
Some elaboration paths copy the file and line from a LineInfo object
individually. Use set_line() instead. This keeps the copies together when
LineInfo is extended with additional source location information.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-26 20:14:20 -07:00
Cary R. a4989d023d
Merge pull request #1422 from muhammadjawadkhan/split/06-sv-array-ordering
SV: reverse(), sort(), rsort(), shuffle() for queues/darrays
2026-07-21 00:00:54 -07:00
mjoekhan 9378bbf337 SV: address review feedback for array ordering methods
Drop redundant eeq checks in descending vec4 sorts, brace reverse loops,
and merge duplicate queue/darray class-property method elab.
2026-07-21 11:48:54 +05:00
mjoekhan f796a59367 SV: merge darray/queue method checks in elab_expr
Combine the nearly identical dynamic-array and queue method blocks in
test_width_method_ and elaborate_expr_method_ (including class property
paths), keeping queue-only pop_front/pop_back gated on queue type.
2026-07-21 11:05:57 +05:00
mjoekhan afe849249c SV: reverse(), sort(), rsort(), shuffle() for queues/darrays
Add ordering methods for queues and dynamic arrays.  Update ivtest gold
files for always_*_warn, br1005, and br_gh710b LXT per review.

Split from steveicarus/iverilog#1330 (part 06/6).
2026-07-21 11:01:29 +05:00
Cary R. f0b6d3addc
Merge pull request #1421 from muhammadjawadkhan/split/05-sv-sum-product
SV: sum() and product() reductions on queues/darrays
2026-07-20 22:51:40 -07:00
mjoekhan e628e6c8c5 SV: sum() and product() reductions on queues/darrays
Add integral sum() and product() reductions, including expression
forms, for queues, dynamic arrays, and class properties.

Split from steveicarus/iverilog#1330 (part 05/6).
2026-07-21 10:32:45 +05:00
Cary R. 31d1850bc8
Merge pull request #1445 from larsclausen/procedural-block-prefix-label
Support prefix labels on procedural blocks
2026-07-20 21:32:25 -07:00
Cary R. 402c96583f
Merge pull request #1444 from larsclausen/assertion-item-label-type-id-shadow
Support assertion item labels shadowing type identifiers
2026-07-20 21:29:37 -07:00
Cary R f5e496b032 cppcheck cleanup 2026-07-20 21:24:03 -07:00
Lars-Peter Clausen 9c56f0172d Add regression tests for prefix labels on procedural blocks
Check the reproducer from GitHub issue #1321, which uses a prefix label on a
begin-end block inside an `always_comb` process.

Check prefix labels on sequential and parallel blocks. Place attributes between
the labels and block keywords, verify that the sequential label creates a named
scope, cover all fork join types, and use matching closing labels.

Check separately that visible type identifiers can be shadowed by prefix labels
on sequential and parallel blocks.

Check that matching and different block names after `begin` or `fork` are
rejected when a prefix label is already present.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-20 20:55:48 -07:00
Lars-Peter Clausen fd902d1501 Support prefix labels on procedural blocks
SystemVerilog sequential and parallel blocks allow a block identifier before
the `begin` or `fork` keyword:

    LABEL: begin
      statement;
    end

    LABEL: fork
      statement;
    join

The parser currently only accepts the block identifier after `begin` and
`fork`. Add a prefix-label rule using `identifier_name`. This accepts labels
returned as either `IDENTIFIER` or `TYPE_IDENTIFIER` without duplicating the
label grammar. The mixed procedural item list lets the parser use the following
`:` to distinguish a visible type identifier used as a label from the start of
a variable declaration.

Use a shared optional prefix rule for sequential and parallel block forms.
Resolve the prefix and post-keyword names before starting the common block path,
and bind attributes placed between the label and block keyword. Require
SystemVerilog mode when a prefix label is present.

IEEE 1800-2023 section 9.3.5 does not allow a prefix label and a block name
after `begin` or `fork` at the same time. Report an error for this form while
keeping it in the grammar for error recovery. Keep the existing closing label
handling, which allows a matching name after `end` or a join keyword.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-20 20:31:23 -07:00
Lars-Peter Clausen dcc8e93d7e Factor procedural block parsing
The sequential and parallel block grammar duplicates scope setup and teardown,
statement transfer, and closing label handling.

Move the common logic into `pform_start_block()` and
`pform_finish_block()`. This keeps the grammar actions focused on their
syntax-specific checks and makes both block forms use the same scope and
statement ownership paths without changing the accepted syntax.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-20 20:29:48 -07:00
Cary R. 1cf8133420
Merge pull request #1420 from muhammadjawadkhan/split/04-sv-class-prop-locators
SV: locator methods on class queue/darray properties
2026-07-20 18:02:30 -07:00
mjoekhan 78aa852bf1 SV: apply caryr if-style formatting to locator runtime
Use single-line early returns and same-line simple if bodies, matching
the formatting conventions from #1416/#1418 reviews.
2026-07-20 21:08:21 +05:00
mjoekhan 243dccc368 SV: locator methods on class queue/darray properties
Extend locator methods to class queue and dynamic-array properties,
including min/max, unique/min/max with-predicates, and VVP array-pattern
object handling. Built on the #1419 locator helpers.

Split from steveicarus/iverilog#1330 (part 04/6).
2026-07-20 20:41:19 +05:00
Lars-Peter Clausen 713ad762af Add regression test for assertion item labels shadowing type identifiers
Check that a visible type identifier can be shadowed by labels on module
level assertion items. Cover both a concurrent assertion item and a
deferred immediate assertion item.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-19 20:19:07 -07:00
Lars-Peter Clausen a0e5240109 Support assertion item labels shadowing type identifiers
SystemVerilog assertion item labels use ordinary identifiers. A visible
type identifier should therefore be accepted as the label on a module
level assertion item:

    typedef int CHECK;
    module test;
      CHECK: assert property (1);
    endmodule

Procedural assertion statements already accept either identifier token in
their optional label rule. Reusing that rule for module level concurrent
and deferred assertion items exposes a declaration ambiguity: module items
can also start with a typedef name followed by a variable declaration.

Keep the grammar conflict-free by parsing typedef-start variable
declarations in a single production that includes the first declarator.
This lets the parser see `:` before reducing the typedef-start declaration
path, so module and procedural assertions can share the same label rule
while preserving the existing declaration handling for typedef data types.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-19 20:19:07 -07:00
Lars-Peter Clausen 11af9fb3b3 Add regression tests for procedural labels shadowing type identifiers
Check that a visible type identifier can be reused as a procedural assertion
label after a declaration in both task and block bodies. These are the contexts
where label and declaration parsing meet.

Also check that a null statement ends the declaration portion of a procedural
body and a following declaration is rejected.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-19 20:12:11 -07:00
Lars-Peter Clausen 173f6af729 Support shadowing type identifiers in procedural labels
SystemVerilog procedural labels use ordinary identifiers. A visible type
identifier can therefore also be used as a label:

    typedef int T;
    module test;
      initial begin
        T value;
        T: assert (1);
      end
    endmodule

The parser currently handles procedural declarations and statements as
separate lists. After `T value;`, it must decide whether the next
`TYPE_IDENTIFIER` starts another declaration before it can see that the
following `:` makes it an assertion label. Extending the label rule alone
therefore introduces parser conflicts.

Replace the separate lists with a mixed procedural item accumulator so the
parser can keep the declaration-or-statement decision open. Track whether
declarations have been seen, use allocation of the statement vector to record
whether a statement has been seen, collect concrete statements and old-style
task/function ports, and reject a declaration after a statement. A null
statement allocates an empty statement vector and therefore also starts the
statement section, preserving the existing declaration ordering rule. Own the
accumulated statement and port vectors with `unique_ptr` and release old-style
port vectors only when transferring them to a task or function.

Parse assertion labels as `identifier_name ':'` and use the accumulator for
constructors, functions, tasks, and sequential and parallel blocks. Keep the
temporary scope for an unnamed block until its body has been classified. If it
has no declarations, move nested named scopes into the enclosing scope and
reparent them before discarding the temporary scope.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-19 20:12:11 -07:00
Lars-Peter Clausen 36f013f97f Factor statement-or-null grammar
`statement_or_null` currently reaches statements and null statements through
an optional attribute list. Reducing that empty prefix before the parser knows
which form follows makes the rule difficult to use in a mixed procedural item
list without conflicts.

Expand the rule into explicit attributed and unattributed statement and null
forms. This preserves attribute binding and null-statement behavior while
allowing the parser to distinguish the forms from their leading token.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-19 20:12:11 -07:00
Lars-Peter Clausen 97928cfb15 Factor block variable declaration grammar
Block variable declarations currently combine optional `const` and lifetime
qualifiers with the data type. This requires reducing empty qualifier rules
before the parser can determine which declaration form follows, making the
rule difficult to use in a mixed procedural item list without conflicts.

Split the declaration productions according to their leading syntax. Share
required and optional variable lifetime handling and add a rule for data types
following the historical leading `reg` extension. This keeps the declaration
behavior unchanged while allowing the parser to distinguish each form from
its leading token.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-19 20:12:11 -07:00
Lars-Peter Clausen 7792b5ab8a Fix locations of unattributed statements
The `statement` and null-statement rules start with an optional attribute
list. When it is empty, the reduced location starts at the previous token
instead of the statement. Diagnostics using that location can consequently
point to the beginning of the source file.

Use the statement or semicolon location when no attributes are present.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-19 20:12:11 -07:00
Lars-Peter Clausen 3c3f46099d Add regression tests for interface identifier names
Check separately that a visible interface name can be reused as a member,
modport, interface port, ordinary port, interface instance and procedural block
name.

Also check an attributed forward interface port type after another ANSI port
declaration.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-18 11:22:09 -07:00
Lars-Peter Clausen 60f366790b Remove special interface identifier token
The lexer currently returns `INTERFACE_IDENTIFIER` for names of interfaces
that have already been parsed. There are two issues with this approach:

1. Once an interface has been parsed, its name can no longer be used in
   grammar positions that accept an ordinary identifier.
2. The LRM allows an interface to be used before its declaration. Before the
   declaration has been parsed, however, the name remains an ordinary
   identifier and can not be accepted by productions requiring
   `INTERFACE_IDENTIFIER`. Lexer lookahead tries to recognize forward
   interface port types, but this depends on parser-managed port-list state
   and does not cover all cases.

Parse interface port declarations from ordinary `IDENTIFIER` tokens instead.
An interface port can not simply be added to `port_declaration` using an
`IDENTIFIER` token. This creates a shift/reduce conflict on the identifier at
the start of the port list. Shifting starts an old-style `port_reference`,
while reducing the empty `attribute_list_opt` starts an interface
`port_declaration`. The parser has not yet seen the following identifier or
`.` that distinguishes the two forms.

Add leading interface port declarations as base cases of
`list_of_port_declarations`. Both the old-style and ANSI port-list rules can
then shift the common identifier and use the following identifier or `.` to
distinguish the interface port. Keep a separate base case for a non-empty
attribute list so no empty reduction is needed before the identifier. Handle
later interface ports in the recursive list rule and use
`interface_port_modport_opt` to share the forms with and without a modport.
Interface instances can use the existing module instantiation rules.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-18 11:22:09 -07:00
Cary R. 35a809d55b
Merge pull request #1419 from muhammadjawadkhan/split/03-sv-locator-methods
SV: queue/darray locator methods (find*, unique*, min/max)
2026-07-16 14:10:18 -07:00
mjoekhan 9740f7bc76 SV: refactor locator elaboration and tgt-vvp lowering
Collapse duplicated unique*/find* paths into parameterized helpers
and table-driven opcode emission so adding types does not require
copying whole method blocks. Align multi-line call arguments.
2026-07-16 23:45:41 +05:00
mjoekhan e3222e77ad SV: queue/darray locator methods (find*, unique*, min/max)
Add find*, unique*, min/max, and with-predicate locator methods for
queues and dynamic arrays, with VVP runtime support and ivtest.

Split from steveicarus/iverilog#1330 (part 03/6).
2026-07-15 22:49:12 +05:00
Cary R 614607c135 Cppcheck fixes in vvp 2026-07-14 01:31:09 -07:00
Cary R dec4e939f4 Fix compile issues in previous patch 2026-07-14 00:09:31 -07:00
Cary R e367080276 Fix incorrect definition 2026-07-14 00:09:24 -07:00
Cary R e4bede3c76 Fix some compile warnings under mingw/cygwin 2026-07-13 23:51:10 -07:00
Cary R. 812c1cedcb
Merge pull request #1418 from muhammadjawadkhan/split/02-sv-chained-calls
SV: chained method calls a().b()
2026-07-13 23:05:04 -07:00
Cary R. 67d39803e6
Fix formatting and add braces for clarity 2026-07-13 22:54:26 -07:00
Cary R. 55250457ed
Fix formatting in parse.y for call_chain_expr 2026-07-13 22:50:55 -07:00
Cary R. 29a8a4d052
Simplify conditional checks in elab_expr.cc 2026-07-13 22:48:28 -07:00
mjoekhan 4a505546a1 SV: chained method calls a().b()
Add parsing and elaboration for chained calls on expression results,
with sv_call_chain_method1 regression.

Split from steveicarus/iverilog#1330 (part 02/6).
2026-07-13 18:48:30 +05:00
Cary R 15689210c1 Fix the building of libvvp.pc 2026-07-12 17:33:29 -07:00
Cary R e5482b89b1 Fix compile warning 2026-07-12 10:05:55 -07:00
Cary R d376375020 Fix br1005 tests for fsv and vlog95 2026-07-12 10:05:49 -07:00
Cary R. d15f24ff49
Merge pull request #1416 from muhammadjawadkhan/split/01-sv-class-queue-darray-props
SV: class queue/darray property foundation
2026-07-12 08:18:25 -07:00
Cary R. 2ff0be6bfd
Fix conditional check for net class type 2026-07-12 08:00:14 -07:00
Cary R. e7233856c8
Simplify conditional return statements 2026-07-12 07:57:09 -07:00
Cary R. 9a7178fef0
Refactor format_darray_pretty for readability 2026-07-12 07:52:48 -07:00
Cary R. 82350c4866
Fix conditional block for boolean type handling 2026-07-12 07:44:20 -07:00
Cary R. 4d07a8466c
Merge pull request #1439 from larsclausen/ams-type-id-shadow
Support discipline and nature names shadowing type identifiers
2026-07-12 07:20:11 -07:00
Lars-Peter Clausen 0e3ac8685c Add regression tests for discipline and nature type identifier names
Check that nature and discipline declaration names can match visible type
identifiers. Also check `potential` and `flow` references to nature names that
are visible as type identifiers.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-11 17:47:52 -07:00
Lars-Peter Clausen 1d623a67d1 Support discipline and nature names shadowing type identifiers
Verilog-AMS nature and discipline declarations can use names that are also
visible as type identifiers. The `potential` and `flow` discipline items can
likewise reference a nature whose name is returned as `TYPE_IDENTIFIER` by the
lexer. These grammar positions currently only accept `IDENTIFIER`.

Use `identifier_name` for nature and discipline declaration names and for the
`potential` and `flow` nature references.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-11 17:44:54 -07:00
Lars-Peter Clausen a540a7a163 Add regression tests for for and foreach type identifier names
Check that a for loop variable declaration can use the same name as a
visible typedef, including references from the loop condition and step
expressions.

Also check that procedural foreach can parse an array expression name that
is initially seen as a type identifier. Declare the array after the loop so
the parser sees the outer typedef while parsing the foreach header, then
elaboration resolves the array declaration as a module item.

Use unsigned variables and omit the foreach iterator because these tests do
not depend on signed values or iteration behavior. This lets both tests run
through the vlog95 backend as normal regressions.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-11 15:58:18 -07:00
Lars-Peter Clausen 9ec8f8e2dd Support for and foreach identifiers shadowing type identifiers
SystemVerilog allows a declaration in an inner scope to use the same name as
a type identifier from an outer scope. The lexer reports such names as
`TYPE_IDENTIFIER` until the new declaration has been installed.

The parser previously created the synthetic loop scope and declared the loop
variable only after parsing the complete `for` header. When the variable name
matches a visible typedef, this is too late: the lexer can continue returning
`TYPE_IDENTIFIER` for references to the variable in the initializer,
condition, and step expressions. Accept `identifier_name` for the declaration
name and create the loop scope and variable in a mid-rule action immediately
after it, so the declaration is visible while the rest of the header is
parsed.

The executable foreach grammar also used to require the array expression name
before the index list to be an `IDENTIFIER`. Use `identifier_name` there as
well, since this position is an expression name followed by `[` and not a type
name.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-11 15:58:18 -07:00
Lars-Peter Clausen 36a79568b7 Add regression tests for attribute names matching type identifiers
Check that a standard attribute name can match a visible typedef. Also check
that the global `$attribute` extension can target a primitive whose name is
visible as a type identifier.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-11 15:58:02 -07:00
Lars-Peter Clausen ee14022127 Support type identifier names in attributes
Standard attribute names and target names in both forms of the Icarus
`$attribute` extension are unambiguous identifier positions. When such a name
matches a visible typedef the lexer returns `TYPE_IDENTIFIER`, while the
grammar only accepts `IDENTIFIER`.

Use `identifier_name` for all of these positions.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-11 15:58:02 -07:00
Cary R. 0723d9a477
Merge pull request #1435 from larsclausen/br-gh1385-vlog95
ivtest: Run nested enum tests through vlog95
2026-07-10 10:43:04 -07:00
Cary R. f8069416f2
Merge pull request #1434 from larsclausen/parameter-omit-implicit-type
parser: Reject implicit parameter types without parameter
2026-07-10 10:42:15 -07:00
Lars-Peter Clausen c0cf842eb2 ivtest: Move parameter omit tests to JSON
The parameter_omit tests have different expectations depending on whether the
regression is run in the default Verilog mode or with force SystemVerilog.
The old list files modelled this by registering the same tests in both
regress-vlg.list and regress-fsv.list.

Move the tests to JSON descriptors. Use the existing force-sv override for the
forms that are valid SystemVerilog, and keep the implicit type cases as CE in
both modes. This also runs the tests through the additional configurations
supported by vvp_reg.py, providing better coverage in CI.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-09 20:49:01 -07:00
Lars-Peter Clausen 20a34d33c6 parser: Reject implicit parameter types without `parameter`
The LRM allows omitting the `parameter` keyword in a module parameter port
list, but the optional type in that form is a data_type, not an implicit
data type. A parameter port list like this is therefore invalid:

    module M #([3:0] P = 1);

The parameter declaration grammar was reusing the general
value_parameter_assign_with_type rule for the omitted-keyword form. That rule
also accepts implicit types so that ordinary `parameter signed P = 1`
declarations work, which made the omitted-keyword form accept implicit types
as well.

Add a separate rule for value parameter assignments without the `parameter`
keyword. The rule still accepts bare identifiers and explicit data types so a
parameter name can shadow a visible typedef name, but it rejects implicit
types.

Fixes: e56c93a2be ("Support shadowing type identifiers in parameter declarations")
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-09 20:49:01 -07:00
Lars-Peter Clausen f870c755fa ivtest: Run nested enum tests through vlog95
The br_gh1385a, br_gh1385b, and br_gh1385c JSON descriptors mark the vlog95
variants as compile errors. The enum typedefs are translated correctly, so the
compile error expectation causes the tests to fail when compilation succeeds.

Remove the stale overrides and run the translated tests through vlog95.

Fixes: 10349287a0 ("Add regression tests for enum typedefs in nested scopes")
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-09 20:45:55 -07:00
Lars-Peter Clausen 3e0c298b25 Add regression tests for named selectors matching typedef names
Check that a named binding selector can have the same text as a visible typedef
name. Cover named module port connections, named parameter overrides, and named
task, function and constructor arguments.

Also check that a modport simple port selector can shadow a visible typedef
name. Modport simple port aliases share the same parser rule but declare the
modport-visible name rather than binding to an existing formal.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-09 20:08:25 -07:00
Lars-Peter Clausen 6844ed4194 Accept type-identifier tokens in named binding selectors
A named binding selector such as `.T(expr)` names an existing formal port,
parameter, task or function argument, or constructor argument. It is not a
declaration of a new identifier. If a visible typedef named `T` exists at the
use site the lexer returns `TYPE_IDENTIFIER`, which made the parser reject the
binding selector.

Modport simple port aliases use the same grammar, but are slightly different:
the selector is the modport-visible port name and can shadow a visible typedef
name in the interface scope.

Use `identifier_name` for the selector name in `named_expression` and
`named_expression_opt`. This covers named parameter overrides, named task and
function arguments, named constructor arguments, and modport simple port
aliases. Also use `identifier_name` in the named module port connection rules,
including implicit named port connections and error recovery.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-09 20:08:25 -07:00
mjoekhan 9880fb8d5e SV: class queue/darray property foundation
Fold in Windows VPI routing for vpip_format_pretty, fix queue method
argument elaboration via elaborate_rval_expr, reject class tasks used as
expressions cleanly, and update br1005 now that class queues compile.

Review follow-up: move vpip_format_pretty to vpip_format.cc with
diagnostic return strings, restore NetNet-based queue method elaboration
with a separate property path, drop spurious /devel/ from .gitignore,
and bump copyright years on touched files.

Formatting pass per inline review: brace style for multi-line if bodies,
||/&& at end-of-line continuations, switch/case indentation, single-line
if returns, NetNet-based sys_task_method_ again, and aligned extern decls.
2026-07-07 00:46:45 +05:00
Cary R. e02a0bc2ec
Merge pull request #1431 from larsclausen/event-variable-type-id-shadow
Support event names shadowing type identifiers
2026-07-06 09:32:00 -07:00
Lars-Peter Clausen abfb4e83bc Add regression test for event names shadowing type identifiers
Check that event declarations can use visible type identifiers as event names.
Also check that the resulting named event can be triggered and waited on.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-05 21:44:44 -07:00
Lars-Peter Clausen 17ca0948f4 Support event names shadowing type identifiers
SystemVerilog allows a declaration in an inner scope to use the same name as a
type identifier from an outer scope. This also applies to named event
declarations. The lexer reports such names as `TYPE_IDENTIFIER` before the
event has been installed, which made constructs such as:

    typedef int T;
    module test;
      event T;
    endmodule

fail in the event declaration grammar.

Event declarations do not have the local type/name ambiguity that exists for
variable, net, or parameter declarations. The name in `event_variable` is
always the event name. Use `identifier_name` so a `TYPE_IDENTIFIER` token can
be accepted as the event name.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-05 21:44:44 -07:00
Lars-Peter Clausen f6848300b7 Add regression tests for block labels shadowing type identifiers
Check that visible type identifiers can be reused as named block labels. Cover
procedural `begin` blocks, fork blocks, and conditional generate blocks. Also
check matching end labels where the grammar consumes the shared `label_opt`
rule.

The generate test keeps the existing vlog95 compile-error expectation because
named generate scopes are not translated by the vlog95 target.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-05 21:36:32 -07:00
Lars-Peter Clausen 06740d0dda Support block labels shadowing type identifiers
SystemVerilog allows a named block label in an inner scope to use the same
name as a visible type identifier from an outer scope. The lexer reports such
names as `TYPE_IDENTIFIER` before the label has been installed, which made
constructs such as:

    typedef int T;
    module test;
      initial begin
        begin : T
        end : T
      end
    endmodule

fail in the block label grammar.

The affected grammar positions are label names, not declarations with an
adjacent type/name ambiguity. Use `identifier_name` for `label_opt` and for the
anachronistic named generate begin form so a token returned as `TYPE_IDENTIFIER`
can still be accepted as the label name. With `label_opt` able to handle
`TYPE_IDENTIFIER`, the separate class end-label rule is no longer needed.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-05 21:36:32 -07:00
Lars-Peter Clausen 15277c9fa4 Add regression test for package names shadowing type identifiers
Check that a package declaration can use a visible type identifier as its
package name. Also check that the resulting package scope can be selected with
a scope-qualified reference.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-05 21:36:18 -07:00
Lars-Peter Clausen ca5c6fc59f Support package names shadowing type identifiers
SystemVerilog allows a package declaration to use a name that is also visible
as a type identifier. The lexer reports such names as `TYPE_IDENTIFIER` before
the package has been installed, which made constructs such as:

    package p;
      typedef int T;
    endpackage
    import p::*;
    package T;
    endpackage

fail in the package declaration grammar.

Package declarations do not have the local type/name ambiguity that exists for
variable, net, or parameter declarations. After the optional lifetime the next
token is always the package name. Use `identifier_name` so a
`TYPE_IDENTIFIER` token can be accepted as the package name.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-05 21:36:18 -07:00
Lars-Peter Clausen 2cef311be2 Make Bison parser conflicts errors
Bison reports shift/reduce and reduce/reduce parser conflicts as warnings by
default. This allows parser changes to introduce new conflicts while the normal
build still succeeds.

Pass the conflict warning classes as errors to Bison when generating the
parsers. This makes the regular build fail if either parser has unresolved
conflicts.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-05 21:36:03 -07:00
Lars-Peter Clausen ff0b4a3154 parser: Fix parameter assignment grammar conflict
The parameter declaration grammar allows a visible type identifier to be used
as a parameter name. The assignment continuation rule still used
`identifier_name`, which made Bison reduce a `TYPE_IDENTIFIER` before it had
seen whether following dimensions belonged to the parameter name or to an
explicit type identifier.

Match ordinary and type identifiers directly in `parameter_assign` so the
parser can shift dimensions before deciding between a parameter name and an
explicit parameter type.

Fixes: e56c93a2be ("Support shadowing type identifiers in parameter declarations")
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-05 21:36:03 -07:00
Lars-Peter Clausen 2b67d9f754 Add regression tests for UDP names shadowing type identifiers
Check that UDP primitive and port names can shadow visible type identifiers.
Cover old-style UDP declarations, including input and output declarations and
the initial target, as well as ANSI-style UDP port declarations.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-05 13:58:11 -07:00
Lars-Peter Clausen 56c42dcf37 Support UDP names shadowing type identifiers
SystemVerilog allows a UDP primitive or UDP port declaration to use the same
name as a visible type identifier from another namespace or outer scope. The
lexer reports such names as `TYPE_IDENTIFIER` before the UDP name has been
installed, which made constructs such as:

    typedef int T;
    primitive T (Q, A);
      output Q;
      input A;
      table
        0 : 0;
      endtable
    endprimitive

fail in the UDP grammar.

UDP primitive and port names do not have the local type/name ambiguity that
exists for variable, net, or parameter declarations. Use `identifier_name` for
the primitive name, the UDP port list, UDP port declarations, and the UDP
initial target so a `TYPE_IDENTIFIER` token can be accepted as the UDP name.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-05 13:58:11 -07:00
Lars-Peter Clausen c8568998af Add regression tests for UDP declaration diagnostics
Check that UDP initial values on non-registered outputs generate compile
errors for both old-style and ANSI-style UDP declarations. Also check that
conflicting UDP port declarations generate an error and that a valid
ANSI-style `output reg` initializer is accepted.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-05 13:57:30 -07:00
Lars-Peter Clausen 8d4faf2744 Report UDP declaration errors instead of asserting
Malformed UDP declarations can reach `pform_make_udp()` with conflicting
duplicate port declarations or with an initial value on an output that was not
declared as a register. These cases currently trigger internal assertions
instead of reporting normal compile errors.

The ANSI-style UDP output initializer path also treats the initializer
expression as if it was the old-style `initial out = value` assignment
statement. This makes a valid `output reg out = 1'b0` initializer assert as
well.

Report errors for the invalid declarations and read the ANSI-style initializer
value directly from the initializer expression.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-05 13:57:30 -07:00
Cary R. 025cbcc81f
Merge pull request #1426 from larsclausen/enum-item-type-id-shadow
Support enum items shadowing type identifiers
2026-07-04 07:29:07 -07:00
Cary R. b6829ab504
Merge pull request #1425 from larsclausen/taskfunc-type-id-shadow
Support task and function names shadowing type identifiers
2026-07-04 07:26:52 -07:00
Lars-Peter Clausen 43817251f4 Add regression test for enum items shadowing type identifiers
Check that enum item names can shadow visible type identifiers. Cover plain enum
items as well as the counted and ranged enum item sequence forms.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-03 18:13:51 -07:00
Lars-Peter Clausen 0c7341be37 Support enum items shadowing type identifiers
SystemVerilog allows a declaration in an inner scope to use the same name as a
type identifier from an outer scope. This also applies to enum item names. The
lexer reports such names as `TYPE_IDENTIFIER` before the enum item has been
installed, which made constructs such as:

    typedef int T;
    module test;
      enum { T = 1 } e;
    endmodule

fail in the enum item grammar.

Enum item declarations do not have the local type/name ambiguity that exists for
variable, net, or parameter declarations. The name in each `enum_name`
production is always the enum item name, including the sequence forms like
`T[2]` and `T[1:2]`. Use `identifier_name` for these names so they can shadow a
visible type identifier.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-03 18:10:54 -07:00
Lars-Peter Clausen 21b0107bae Add regression tests for type identifier task and function names
Check that function and task declarations can use a visible type identifier as
the declaration name. Cover both ANSI declarations and the non-ANSI forms where
the name is parsed without a separate return type or port list.

Also check class method declarations where the method name is the same as the
enclosing class name. Add GitHub issue #670 coverage for the `function void`
case using the issue-based regression naming scheme.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-03 17:33:07 -07:00
Lars-Peter Clausen 24743af7d5 Support task and function names shadowing type identifiers
SystemVerilog allows a declaration in an inner scope to use the same name as a
type identifier from an outer scope. This also applies to task and function
names. The lexer reports such names as `TYPE_IDENTIFIER` before the new task or
function has been installed, which made constructs such as:

    typedef int T;
    module test;
      function int T(input int value);
        return value;
      endfunction
      task T;
      endtask
    endmodule

fail in the task and function declaration grammar. A class method with the same
name as the class itself hits the same problem because the class name is visible
as a type identifier in the class scope.

The task grammar can accept `identifier_name` directly, because a task has no
return type and the token after `task` and the optional lifetime is always the
task name.

Function declarations have a local return-type/name ambiguity. After
`function T` the parser does not know yet whether `T` is the function name with
no explicit return type, or whether a following identifier will make `T` the
explicit return type as in `function T f`. Parse the optional function return
type and function name together. This allows a `TYPE_IDENTIFIER` token to be
interpreted as the function name when no separate function name follows, while
still parsing typed forms and `void` return types correctly.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-03 17:29:40 -07:00
Cary R. 60a81493cd
Merge pull request #1424 from larsclausen/type-id-parameter-declarations
Support shadowing type identifiers in parameter declarations
2026-07-03 07:14:53 -07:00
Lars-Peter Clausen bc6d421ff2 Add regression tests for parameter declarations shadowing type identifiers
Check that visible type identifiers can be shadowed by value parameter names
and by type parameter names. Cover ordinary parameter declarations, typed
parameter declarations, and parameter port list declarations separately.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-02 19:32:32 -07:00
Lars-Peter Clausen e56c93a2be Support shadowing type identifiers in parameter declarations
SystemVerilog allows a visible type identifier to be shadowed by a
parameter declaration name. Parameter declarations still required the
parameter name to be an `IDENTIFIER` token and rejected declarations like:

    typedef int P;
    module test;
      parameter int P = 1;
    endmodule

The parameter grammar can not just accept `TYPE_IDENTIFIER` in every name
position. After `parameter P` the parser does not know yet whether `P` is
the parameter name, or whether a following identifier will make `P` the
parameter type.

Parse the optional value parameter type and the first parameter assignment
together. This allows a `TYPE_IDENTIFIER` token to be interpreted as the
parameter name when no explicit type is present, while still parsing a
following identifier as the parameter name for typed parameters.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-02 19:32:32 -07:00
Cary R. 98d10727f2
Merge pull request #1423 from larsclausen/type-id-class-property
Support class properties shadowing type names
2026-07-02 19:01:57 -07:00
Cary R. 50b477bc1f
Merge pull request #1404 from sifferman/param-string-compare
Fix assert on constant == with unequal-length string operands
2026-07-02 18:57:44 -07:00
Lars-Peter Clausen 5364f11d16 Add regression tests for class properties shadowing type names
Check that a class property can have the same name as a type declared in
an outer scope, or a type imported through a wildcard import. Also check
that a class property can have the same name as the class itself.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-02 16:58:42 -07:00
Lars-Peter Clausen dc66f2fe7e Support class properties shadowing type names
SystemVerilog allows a class property to have the same name as a visible
type. The lexer reports the visible type name as `TYPE_IDENTIFIER` before
the property has been installed, which made constructs such as
`typedef int T; class C; int T; endclass` fail in the class item grammar.
A class property with the same name as the class itself hits the same
problem. Member references such as `obj.T` or `obj.C` can also hit the
same tokenization problem in hierarchical names.

Parse class properties through the same declaration helper used for
variables so the first type/name pair can be disambiguated. Also let
hierarchical member names use `identifier_name`.

Stop type lookup when a class scope already has a property with the same
name. This makes method body references resolve as properties instead of
visible types, including type names found through wildcard imports.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-02 16:58:42 -07:00
Ethan Sifferman e2ab464656 Fix unequal-length string comparison 2026-07-02 16:21:17 -07:00
Cary R. d01efc910b
Merge pull request #1415 from larsclausen/aa-pattern-terms
Detect automatic terms in assignment patterns
2026-07-02 10:00:36 -07:00
Cary R. 158d7b76f2
Merge pull request #1414 from larsclausen/nb-ec-repeat-auto
Allow repeat expression in event control to contain automatic terms
2026-07-02 09:59:07 -07:00
Cary R. 823aa224db
Merge pull request #1413 from larsclausen/type-id-vars-wires
Support declaration names shadowing type identifiers
2026-07-02 09:52:03 -07:00
Cary R 5a99d0e449 Update to the latest config.guess and config.sub files 2026-07-01 09:10:08 -07:00
Lars-Peter Clausen 9bbdb0da0e Add regression test for automatic terms in assignment patterns
Check that automatic variables referenced through an assignment pattern in a
procedural `force` statement are rejected.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-30 18:25:52 -07:00
Lars-Peter Clausen 9bff2399df Detect automatic terms in assignment patterns
Assignment patterns contain child expressions, but currently inherit
`PExpr::has_aa_term()` which always returns false. This means automatic
variables inside a pattern are not caught by checks for procedural `force`
and procedural continuous assignment statements.

Implement `has_aa_term()` for `PEAssignPattern` and recurse into all pattern
elements.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-30 18:25:52 -07:00
Lars-Peter Clausen f358b3fa8f Add regression test for automatic event control repeat counts
Check that the repeat count expression of a non-blocking intra-assignment
event control can reference an automatic task argument. The repeat count is
evaluated when the assignment is scheduled, so the automatic variable is not
referenced after the task scope is freed.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-30 16:58:32 -07:00
Lars-Peter Clausen be298d1cca Allow repeat expression in event control to contain automatic terms
The repeat expression of an event controlled non-blocking assignment is
evaluated once when the assignment is scheduled. This means there is no
risk of it being referenced when its scope has already been freed. And
hence there is no need to require the repeat expression to only contain
static terms.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-30 16:20:06 -07:00
Lars-Peter Clausen 89b2c8bd80 Add regression tests for declaration names shadowing type identifiers
Check that variable and net declaration names can shadow a visible type
identifier. Check this for explicit data type declarations, `var` declarations,
and net declarations.

Check that task and function formal argument names can shadow a visible type
identifier, and that typed arguments still use the visible typedef when an
argument name follows.

Check ambiguous module port declarations where a type identifier can be either
the port name or the port type, with and without dimensions, and that
declaration lists continue to use the type selected by the first ambiguous
declarator. Cover both ANSI and non-ANSI module port declarations.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-30 14:47:54 -07:00
Lars-Peter Clausen 7cffbf440d Support declaration names shadowing type identifiers
SystemVerilog allows a declaration in an inner scope to use the same name as a
type identifier from an outer scope. The lexer reports such names as
`TYPE_IDENTIFIER` before the new declaration has been installed, which made
constructs such as `int T;`, `wire T;`, and `input T` fail when `T` was a
visible typedef.

The affected declaration forms have a local type/name/dimension ambiguity. For
example, after `input T` or `wire T` the parser does not know whether `T` is the
declared name, or whether a following identifier will make `T` the declaration
type in `input T x` or `wire T x`. With dimensions, `input T [1:0]` and
`wire T [1:0]` can be either a declaration named `T` with unpacked dimensions or
a declaration using typedef `T` as a packed type followed by another name.

Parse these declaration forms with productions that decide the first declarator
and carry the selected declaration type across the rest of the list. This covers
variable declarations, net declarations, ANSI and non-ANSI module port
declarations, and task/function port declarations. Other identifier uses still
need separate grammar changes.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-30 14:41:06 -07:00
Lars-Peter Clausen a1c333ea6e Add regression test for delayed real assignments
Check that a blocking intra-assignment delay on a real value preserves the
assigned value after the delay.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-29 10:27:57 -07:00
Lars-Peter Clausen d5306085c5 vvp: Support local flag on real variables
The vvp parser did not accept the local flag on `.var/real`
declarations. This can happen when elaboration creates a compiler-generated
real temporary, for example when a blocking intra-assignment delay is
rewritten from:

    r = #1 1.25;

to assign the right hand side to a temporary before the delay and assign
the temporary to the target after the delay.

Add support for the local flag. Keep a VPI symbol for the variable so
`%load/real` can still resolve the label, but do not attach local real
variables to the current scope.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-29 10:27:57 -07:00
Lars-Peter Clausen 77fdcfd800 Add regression tests for shadowing type identifiers
Check that visible type identifiers can be shadowed by declarations in
other namespaces or nested scopes. Keep each grammar category in a
separate regression so failures identify the affected rule.

Also check that package import and export items can name a type
identifier.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-29 09:52:44 -07:00
Lars-Peter Clausen d2a97663b9 Allow type identifiers to be shadowed in more places
SystemVerilog allows an identifier that is visible as a typedef to be
shadowed by a declaration in a nested scope or reused as a declaration
name in another namespace. The lexer can return `TYPE_IDENTIFIER` before
the new name has been installed, so these grammar positions reject
otherwise valid code.

This is not a complete conversion of all identifier grammar sites. Only
handle the trivial conflict-free cases where `IDENTIFIER` can be replaced
by `identifier_name` without any surrounding grammar changes.

Also stop type lookup when the current scope already has a local symbol
with the same name. This makes later references to a shadowing
declaration use the local symbol instead of an outer typedef.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-29 09:52:44 -07:00
Lars-Peter Clausen d246979d26 Add regression test for string substr() arity error
Check that a string substr() call with too few arguments is rejected with a
normal compile error.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-29 09:51:06 -07:00
Lars-Peter Clausen 55d78cf1a8 Handle missing string substr() arguments
The string substr() method reports an error if it is called with the wrong
number of arguments, but the error was not counted and elaboration continued
with missing function arguments. A call such as `s.substr(0)` could therefore
crash after printing the diagnostic.

Count the arity error and fill missing internal arguments with dummy constants
so elaboration can recover without building an incomplete system function call.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-29 09:51:06 -07:00
Cary R. 78750c51d0
Merge pull request #1402 from larsclausen/real-unary-minus-opcode
vvp: Add opcode for unary real minus
2026-06-22 10:00:17 -07:00
Lars-Peter Clausen 0e7c62d579 Add regression tests for unary real minus special values
Check that unary real minus preserves the sign or bit pattern for zero,
NaN, and infinity. Each test starts with the positive value, negates it,
and then negates the result back to the positive value.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-22 07:43:02 -07:00
Lars-Peter Clausen 5311c0cd38 vvp: Add opcode for unary real minus
Currently the vvp target emits unary real minus as `0.0 - value`.
This is not the same operation for all real values. It loses the
negative zero result for `-(+0.0)` and does not reliably flip the sign
bit for NaN values whose bits are visible through `$realtobits`.

Add `%neg/wr` and use it for unary real minus. This performs a direct
negation of the real stack value, so zero, NaN and infinity all use the
same operation as unary minus instead of a binary subtraction from zero.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-22 07:43:02 -07:00
Cary R 8c7f8f3f7b Fix gold file to fix error message change 2026-06-21 23:04:23 -07:00
Cary R 1babbc0c92 Fix segmentation fault when the input file is missing 2026-06-21 22:53:15 -07:00
Cary R. e9bc3488fb
Merge pull request #1401 from larsclausen/fix-bad-member-lval-proc-crash
Handle bogus member l-value paths
2026-06-21 21:12:43 -07:00
Cary R. f472a77e3a
Merge pull request #1400 from larsclausen/fix-lval-indexed-part-invalid-base-crash
Handle invalid l-value indexed part select bases
2026-06-21 21:11:37 -07:00
Cary R. 8c27786a27
Merge pull request #1398 from larsclausen/vlog95-unsigned-concat-context
tgt-vlog95: Use concatenation for unsigned expression contexts
2026-06-21 21:09:50 -07:00
Cary R. e31c441dbe
Merge pull request #1387 from flaviens/patch-2
Preserve sign of negative zero
2026-06-21 21:07:05 -07:00
Cary R. ff0b269ce9
Merge pull request #1397 from larsclausen/draw-net-input-mux-array-port
tgt-vvp: Avoid interleaving array ports into mux output
2026-06-21 21:05:16 -07:00
Flavien Solt c53e4245b9 Add regression test for negative zero sign preservation
Check that the vvp code generator emits a -0.0 real constant with its
sign bit set, so the compiled value matches the runtime real value. The
sign used to be detected with (value < 0), which is false for IEEE 754
-0.0, and a -0.0 constant was turned into +0.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 10:38:26 +08:00
Lars-Peter Clausen 3c7250eb51 Add regression test for bogus member l-values
Check that bogus member access on a procedural l-value is rejected with a
normal compile error instead of aborting during elaboration.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-21 18:39:21 -07:00
Lars-Peter Clausen 9fb607d98e Add regression test for indexed part select l-value bases
Check that an invalid indexed part select base on a procedural l-value is
reported as a normal compile error instead of crashing after the bind error.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-21 18:39:21 -07:00
Lars-Peter Clausen eaa7197602 Handle bogus member l-value paths
Currently the procedural l-value path asserts if symbol lookup leaves a
member tail for a variable that is not a struct or class. For example,
`r.bad = 1'b1;` where `r` is a scalar variable aborts during elaboration
instead of reporting a normal error.

Report an error for the leftover member path before the assertion. This
matches the r-value path behavior for the same kind of invalid member access.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-21 18:39:21 -07:00
Lars-Peter Clausen 9004d10df4 Handle invalid l-value indexed part select bases
The l-value indexed part select path elaborates the base expression with
`elab_and_eval()`. If the base expression can not be bound this returns a
nullptr, but the l-value path dereferenced it while checking the expression
type. For example, `a[does_not_exist -: 2] = 2'b00;` reported the bind error
and then crashed.

Return early when base elaboration fails. This matches the r-value indexed
part select path and leaves the existing bind error as the reported
elaboration error.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-21 18:39:21 -07:00
Lars-Peter Clausen 4e168a4d1f ivtest: Detect execution errors in vvp_reg.py
Currently vvp_reg.py uses `returncode >= 256` to distinguish execution
errors from ordinary compile or simulation failures. That matches the encoded
status returned by wait(), but subprocess.run() does not expose that value. Its
returncode is the decoded process exit status, or `-N` if the process was
terminated by signal N. Shell wrappers can also report signal termination as
`128 + N`.

As a result a compiler crash can be reported as `-11` or `139`. Both values
pass the old check and a CE test can be accepted as a normal compiler error.

Treat negative return codes and return codes greater than or equal to 128 as
execution errors before accepting CE and EF results. Also make sure that CE gold
mismatches are reported as failures.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-21 17:23:52 -07:00
Lars-Peter Clausen e75b0d7968 tgt-vlog95: Use concatenation for unsigned expression contexts
The vlog95 backend currently emits `$unsigned()` when it needs to create a
self-determined unsigned expression context. `$unsigned()` is part of the
optional signed expression support in this backend and is only available when
the signed support flag is enabled.

Concatenation is part of the baseline Verilog-95 output and also creates a
self-determined unsigned expression context. Use `{expr}` for the unsigned case
and keep using `$signed()` when a signed context is needed.

Remove `-pallowsigned=1` from the existing vlog95 regression tests that now
pass without the optional signed support flag.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-21 12:48:00 -07:00
Lars-Peter Clausen 167a6bbcdb Add regression test for case muxes with array word inputs
Check that synthesized case statement muxes can use array words as inputs.
This used to generate invalid VVP because .array/port statements were emitted
in the middle of .functor statements.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-21 11:44:15 -07:00
Lars-Peter Clausen a5bf5e145f tgt-vvp: Avoid interleaving array ports into mux output
Currently draw_lpm_mux_nest() calls draw_net_input() while printing a
.functor statement. For array word inputs draw_net_input() emits an
.array/port statement as a side effect, which interleaves the .array/port
text into the middle of the .functor line and generates invalid VVP.

draw_lpm_substitute() has the same pattern. Collect the input labels before
starting to print the consuming statement so any side-effect output appears
as a separate statement first.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-21 11:44:15 -07:00
Cary R. a615ee03e7
Merge pull request #1395 from larsclausen/sv-generate-class
Support classes in generate blocks
2026-06-21 10:00:54 -07:00
Lars-Peter Clausen bb8b05bb5d Add regression test for classes in generate blocks
Check that a class declared in a conditional generate block can be used.
Also check that classes declared in a generate loop get separate class scopes
for each generated instance.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-21 09:30:28 -07:00
Lars-Peter Clausen 7934ab9eeb Support classes in generate blocks
SystemVerilog allows class declarations as module and generate items.
Currently a class declaration in a generate block triggers an assert because
`pform_push_class_scope()` only records classes in `PScopeExtra` scopes.

Add class storage to `PGenerate` and elaborate those classes like module and
package classes. When registering task, function or class declarations, only
use the current `PGenerate` object as the target if it is also the current
lexical scope. This distinction matters for generated classes because
`pform_cur_generate` remains set while the class body is parsed, but the
current lexical scope has changed to the `PClass`. This records the class
declaration in the generate block while leaving methods and constructors in
the class scope.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-21 09:29:54 -07:00
Cary R. daadc38f18
Merge pull request #1394 from larsclausen/class-task-method-expression-error
Report error for class tasks used as expressions
2026-06-21 07:23:17 -07:00
Cary R. a5b9879ada
Merge pull request #1393 from larsclausen/netassignnb-dump-rval-error
NetAssignNB: Fix dump fallback for invalid rval
2026-06-21 07:21:37 -07:00
Cary R. 72833b9570
Merge pull request #1392 from larsclausen/fix-negative-packed-slice-width
Fix width calculation for packed array bounds
2026-06-21 07:20:43 -07:00
Lars-Peter Clausen 449abb6bda Add regression test for class tasks used as expressions
Check that using a class task through an object method call in expression
context reports a compile/elaboration error instead of triggering an assert.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-20 17:06:36 -07:00
Lars-Peter Clausen 0637afd284 Report error for class tasks used as expressions
Class object method calls in expression context call func_def() without first
checking that the resolved class method is a function. If the method is a task,
func_def() triggers an assert instead of reporting a normal elaboration error.

Check the method scope type before accessing the function definition and report
an error for tasks.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-20 17:06:36 -07:00
Lars-Peter Clausen c124abaa3e NetAssignNB: Fix dump fallback for invalid rval
Currently NetAssignNB::dump() prints a malformed fallback marker when
there is no rval expression. The leading '<' is missing, making it
inconsistent with the blocking assignment dump output.

Print the complete error marker.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-20 15:15:52 -07:00
Lars-Peter Clausen 03f1bbdd37 Consolidate net up/down part select
The methods for handling up and down part select are nearly identical
and only differ in a hand full of lines.

Consolidate them into a single method to remove the duplicated code.
This makes it easier to maintain the code and add future changes.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-20 14:25:16 -07:00
Lars-Peter Clausen e9d3fe4ea3 Consolidate parameter up/down part select
The methods for handling up and down part select are nearly identical
and only differ in a hand full of lines.

Consolidate them into a single method to remove the duplicated code.
This makes it easier to maintain the code and add future changes.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-20 14:25:16 -07:00
Lars-Peter Clausen 10349287a0 Add regression tests for enum typedefs in nested scopes
Check that enum literals declared by enum typedefs in generate blocks, named
blocks, tasks and functions can be referenced from the same scope.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-20 14:24:53 -07:00
Lars-Peter Clausen 9bc86af284 elab: Elaborate enum types in nested scopes
Enum types declared inside nested scopes are stored separately from typedefs.
The enum sets need to be elaborated when the `NetScope` is created so enum
literals are available for declarations and statements in the same scope.

Module, package and class scopes already do this. Generate, task, function and
named block scopes can also declare enum typedefs, but did not elaborate their
enum sets. Elaborate them while setting up these scopes.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-20 14:24:53 -07:00
Lars-Peter Clausen 593a97bede vvp: Bound VPI label scanset parsing
The VPI label resolver parses word and string labels into a 32 byte
temporary buffer. The scansets used by sscanf() did not specify a width,
so malformed labels could write past the end of the buffer.

Limit the scansets to the size of the buffer.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-20 13:13:24 -07:00
Lars-Peter Clausen d5a16b31a1 Add regression test for empty old-style UDP table
Check that an empty old-style UDP table reports the parser error and the
invalid primitive error instead of crashing.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-20 13:13:05 -07:00
Lars-Peter Clausen 20a969bf38 Handle invalid old-style UDP tables
An empty old-style UDP table leaves the parsed table pointer unset after
the parser reports the table error. The old-style UDP creation path still
passed the null pointer to process_udp_table(), which crashes.

Report an invalid UDP table instead and do not register the primitive.
Also keep the new-style invalid-table diagnostic formatting consistent.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-20 13:13:05 -07:00
Cary R 4b9675abd7 Update unused function in lz4 2026-06-20 08:53:42 -07:00
Cary R 8caa3af689 Update to the latest GTKWave files. 2026-06-20 07:57:16 -07:00
Lars-Peter Clausen 6326c5b1ba Add regression test for negative packed array bounds
Check that variable selects of a packed array with negative bounds use the
correct index width and can read back assigned elements.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-19 22:08:17 -07:00
Lars-Peter Clausen 128c621e85 Fix width calculation for packed array bounds
Variable select base normalization extends the base expression to cover
the packed array bounds. The current code compared min_wid against
num_bits() of each bound, but then assigned the bound value itself to
min_wid.

For positive bounds this can make the generated index expression much
wider than required. For negative bounds the effect is much worse since
min_wid is unsigned. Assigning a negative bound converts it to a huge
width, causing elaboration to try to pad the expression to that size and
abort or run out of memory for otherwise valid variable selects.

Use the bit width of the bound instead of the bound value.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-19 22:08:12 -07:00
Flavien Solt f963322076
Preserve sign of negative zero 2026-06-19 16:00:16 +08:00
Lars-Peter Clausen de415b2f03 Add regression tests for nested function and final contexts
Check that statements that are not allowed in functions or final procedures
are still rejected when they are placed in a named block scope.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-09 21:34:34 -07:00
Lars-Peter Clausen 5b512e4f1e Preserve function and final context in nested scopes
Currently checks for statements that are not allowed in functions or final
procedures only inspect the immediate scope. If the statement is inside a
named block or a block with declarations, the current scope is the block and
the context is lost.

Make `NetScope::in_func()` and `NetScope::in_final()` preserve the context
through begin-end, fork-join and generate block scopes. Other scope types are
treated as context boundaries so function and final state does not leak across
subroutine or definition scopes.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-09 21:34:34 -07:00
Lars-Peter Clausen c5c0b09ef6 Add regression tests for queue method argument count errors
Check that queue push_back(), push_front() and insert() report errors when
called with too few or too many arguments.

These tests are expected to fail as compile/elaboration errors. They also make
sure the invalid calls do not crash during elaboration while reporting the
argument count error.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-09 21:33:58 -07:00
Lars-Peter Clausen aa3d804b72 Fix out-of-bounds write for missing queue method arguments
When a method argument is missing, the error path stores a nullptr in the
argument vector for that missing slot. The vector was sized from the number of
arguments that were present in the source, so calls such as `q.push_back()` or
`q.insert(0)` wrote those nullptr placeholders past the end of the vector.

Size the vector from the number of arguments required by the queue method
instead. This gives the error path slots for the missing arguments while
leaving valid calls unchanged.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-09 21:33:58 -07:00
Lars-Peter Clausen 2fc9d27190 Add regression test for multi-dimensional packed class properties
Check that multi-dimensional packed vector class properties can be emitted,
assigned, and read back through a class object.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-09 21:33:18 -07:00
Lars-Peter Clausen 1e6e69ee7f Support multi-dimensional packed vectors as class properties
Currently multi-dimensional packed vector class properties will cause an
assert and only single dimensional or scalar vectors will pass.

But just as for regular vectors there is nothing special about class
property multi-dimensional vectors as they will be represented in vector
form in vvp.

Removing the asserts allows multi-dimensional packed vectors to be used for
class properties. Indexed access to these properties is not supported yet;
that requires follow-up work to elaborate packed property selects and to
support partial stores to vector class properties.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-06-09 21:33:18 -07:00
Lars-Peter Clausen c7530dbcc1 Add regression test for assignment patterns as queue method arguments
Check that assignment patterns are evaluated in the queue element type
context when they are passed to the queue `push_front()`, `push_back()` and
`insert()` methods.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-31 18:32:44 -07:00
Lars-Peter Clausen e47160c6a8 Evaluate queue method arguments in assignment-like contexts
The arguments of the queue `push_front()`, `push_back()` and `insert()`
methods are passed to subroutine input ports. This makes them
assignment-like contexts with the declared argument type as target type.

Use `elaborate_rval_expr()` instead of `elab_and_eval()` for these
arguments. This evaluates the item argument with the queue element type and
the `insert()` index argument with `integer`, so target-type-dependent
expressions such as assignment patterns work and enum compatibility checks
use the queue element type.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-31 18:32:44 -07:00
Cary R. 311c22e4de
Merge pull request #1373 from MrCookieeeee/Ignore-configure-generated-files
Ignore configure generated files
2026-05-22 10:15:55 -07:00
Cary R. 2d3502f4b7
Cleanup .gitignore organization and files 2026-05-22 10:14:31 -07:00
Cary R e54b404700 Update driver make check to work with all systems 2026-05-22 00:28:27 -07:00
Cookie 297dbe94c2 Ignore configure generated files 2026-05-22 15:05:02 +08:00
Cary R. 7b2c050457
Merge pull request #1371 from rhabacker/fix-issue-1370
iverilog: add command line option -BI and -Bt
2026-05-21 09:38:57 -07:00
Cary R. 6a6ff90197
Update clean target in Makefile to remove test.conf
Remove test.conf from the clean target in Makefile.
2026-05-21 09:27:48 -07:00
Cary R aafda65b99 Cppcheck cleanup 2026-05-21 05:21:35 -07:00
Cary R. 129a5c980f
Merge pull request #1369 from larsclausen/unpacked-array-assign-strength-delay
Preserve delay and strength in unpacked array continuous assignments
2026-05-20 18:49:41 -07:00
Cary R. da42011b97
Merge pull request #1372 from larsclausen/netevwait-repeat-control
NetEvWait: Don't delete event in destructor
2026-05-20 18:41:38 -07:00
Lars-Peter Clausen e35c857a24 Extend non-blocking event control with <= 0 repeat test
Extend the non-blocking event control assignment tests to check that a 0 or
negative repeat value is handled correctly. In this case the assignment
should be executed like a regular non-blocking assignment and the event
control should be ignored.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-19 21:00:56 -07:00
Lars-Peter Clausen 7e7d0ae94b NetEvWait: Don't delete event in destructor
`NetEvWait` deletes the event that is assigned to it when itself
is deleted. But the event is not owned by the `NetEvWait`, it is shared among
all consumers of the event. Deleting it when the `NetEvWait` is deleted can
result in undefined behavior.

This is mainly a problem for non-blocking event control assignments with a
zero or negative immediate valued repeat. In this case the `NetEvWait` will
be deleted as it is not needed.

```
reg x;
event e;
x <= repeat(1) @e 1'b0;
x <= repeat(0) @e 1'b1; // Assert triggered since in-use event is freed
```

Remove the delete to fix this. Events that end up being unused will be
freed by the nodangle functor.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-19 21:00:39 -07:00
Ralf Habacker 0d74d5b211 iverilog: add test for the vvp example mentioned in the documentation
This test was added to verify the new options
in the `iverilog` program, which allow it to
be run from a build directory.

Since `iverilog` is not compatible with the MSYS2
runtime environment used in CI, the added test is
excluded on this platform.
2026-05-19 22:22:43 +02:00
Ralf Habacker 2e50fb2f06 iverilog: add -Bt option to find <target>.conf when using -t<target> in custom install or build dir 2026-05-18 14:01:02 +02:00
Ralf Habacker 8b861b4171 iverilog: add -BI option to support custom location for the ivl parser 2026-05-18 07:50:07 +02:00
Ralf Habacker ecb8a70bed iverilog: add missing -B<selector> options to man page and app usage 2026-05-18 07:49:42 +02:00
Lars-Peter Clausen 635bdd8eb8 Add regression tests for unpacked array continuous assignment strength and delay
Check that continuous assignments to unpacked net arrays preserve delay and
drive strength on the generated element drivers.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-17 14:46:31 -07:00
Lars-Peter Clausen ab6a0e0799 Preserve delay and strength in unpacked array continuous assignments
Continuous assignments to unpacked arrays are expanded into per-element
BUFZ drivers. Currently this path drops the delay and drive strength from
the original continuous assignment, so `assign #5 a = b` updates the array
immediately and `assign (weak1, weak0) a = b` drives with the default
strength.

Pass the evaluated delay and strength values through the unpacked array
assignment helper and apply them to each generated element driver.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-17 14:34:25 -07:00
Lars-Peter Clausen 85c58d0a7a Use helper types for drive strengths and delays
Drive strengths and delays are often handled as a pair of drive values
and a rise/fall/decay triple. Add small helper types to carry these
groups and use them in the continuous assignment and gate/UDP elaboration
paths.

Use the same helper types when propagating drive and delay values through
netlist links.

Also add helpers for dumping the values in debug output. This keeps the
behavior consistent and fixes one small bug where some of the debug
dumps printed the pointer value for the delays, rather than the actual
delay values.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-17 14:27:45 -07:00
Cary R. cc86f69a89
Merge pull request #1368 from larsclausen/net-decl-consolidation
Support SystemVerilog net declaration assignments
2026-05-17 12:16:25 -07:00
Lars-Peter Clausen 28e121c040 Add regression tests for net declaration assignments
Check that SystemVerilog net declarations can mix entries with and
without initialization.

Check that in SystemVerilog it is possible to do assignments within net array
declarations.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-17 11:12:26 -07:00
Lars-Peter Clausen 02fa1a9978 pform_set_data_type(): Remove `net_type` parameter
`pform_set_data_type()` is now only called on wires that already have the
correct wire type set. There is no need to pass the same type to
`pform_set_data_type()` and set it again.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-17 11:11:54 -07:00
Lars-Peter Clausen 3495889112 Support SystemVerilog net declaration assignments
SystemVerilog allows initialized and uninitialized net declaration entries to
be mixed in the same declaration, e.g. `wire x, y = 1'b1`. In Verilog,
either all nets need to have an initializer or non can have one.

In addition SystemVerilog also allows assignments to arrays of wires during
declaration. E.g. `wire a[3:0] = b;`

Currently there are two different rules for net declarations, one for each
of the Verilog variants. Combine these into a single rule to support
SystemVerilog mixed declarations as well as the assignment to array nets.

When running in Verilog mode still reject mixed initialized and
uninitialized with a check after the parsing.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-17 11:06:44 -07:00
Lars-Peter Clausen e7934d5e66 pform_makewire(): Fix indentation
The assignment handling block uses space-based indentation that does not match
the surrounding code.

Fix the indentation before changing the block.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-17 11:05:02 -07:00
Cary R 86546b5960 Set LD_LIBRARY for BSD so make check works 2026-05-16 23:17:11 -07:00
Cary R ca3a00a51a Update some vlog95 interface configurations 2026-05-16 23:17:11 -07:00
Cary R. e6cfb08dd6
Merge pull request #1367 from larsclausen/uarray-lvalue-concat
Handle single element static unpacked array assignments
2026-05-16 22:04:59 -07:00
Lars-Peter Clausen 74491cfe9f Add regression tests for single element unpacked array assignments
Check that continuous assignment of an assignment pattern to a single element
unpacked array is accepted. Check that assigning a scalar expression to the
whole unpacked array is rejected for both procedural and continuous
assignments.

Check that a selected element of a single element static unpacked array can be
used in a continuous l-value concatenation.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-16 21:11:30 -07:00
Lars-Peter Clausen dea82c5a91 Handle single element static unpacked array assignments
Currently single element static unpacked arrays are not always treated as
unpacked arrays when elaborating assignment l-values. The net only has one pin,
so checks using `pin_count() > 1` treat the array as a scalar value and skip
the unpacked array path.

Use `unpacked_dimensions() > 0` instead of `pin_count() > 1` when checking
whether a signal is an unpacked array. This lets single element arrays follow
the same l-value elaboration paths as other unpacked arrays.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-16 21:06:16 -07:00
Cary R. 8229ce1b49
Merge pull request #1366 from larsclausen/sv2023-type-param-restrictions
Add support for restricted type parameters
2026-05-16 17:44:12 -07:00
Lars-Peter Clausen 08479888b1 Add regression tests for restricted type parameters
Check that enum, struct, union and class restricted type parameters are
accepted. Check that mismatched default values and overrides are rejected.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-16 17:29:32 -07:00
Lars-Peter Clausen 46c0526dab Add support for restricted type parameters
SystemVerilog 2023 allows type parameters to be restricted to a
specific kind of type, e.g. `parameter type struct T = T0`.

This is very similar to the type restrictions that can be applied to
forward typedefs.

Factor the support code from the typedefs into a standalone helper and
reuse it for both.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-16 17:20:40 -07:00
Cary R. 0f75156d37
Merge pull request #1365 from larsclausen/soft-unions
Support soft packed unions
2026-05-16 17:11:41 -07:00
Lars-Peter Clausen f8e9384689 Add regression tests for soft packed unions
Check that soft packed unions can have members with different widths.
Check that the `soft` qualifier implies `packed` and that nested soft
packed unions use the same representation recursively.

Also check that member bits are right-justified and that assignments to
narrower members leave the MSBs beyond the member bits unchanged. Check
that soft packed unions reject default member values.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-16 16:46:57 -07:00
Lars-Peter Clausen fb3be420b4 Support soft packed unions
SystemVerilog 2023 adds soft packed unions. They are pretty much the same
as regular packed unions except they remove the restriction that all
elements have to have the same packed width.

The packed with of the union itself is the maximum packed width of any
element.

The bits of each member are right-justified towards the LSBs and this
representation is applied recursively to nested soft packed unions. The
existing packed union member offsets already use that layout. When
accessing a field that is smaller than the union itself upper bits are
ignored for both reading and writing.

The `soft` qualifier implies a packed union so both `union soft U { ... }`
and `union soft packed U { ... }` declare a soft packed union.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-16 16:43:06 -07:00
Cary R eb45fb6eec Fix Makefile generation warning in tgt-fpga 2026-05-16 16:23:41 -07:00
Cary R. 1f5c7c888a
Merge pull request #1364 from larsclausen/sv2017-2023-generations
Add 2017 and 2023 language flag support
2026-05-16 15:45:52 -07:00
Cary R. 3f0d02350f
Merge pull request #1310 from rhabacker/libvpp-versioned-library
vvp: create libvvp as versioned library
2026-05-16 15:41:59 -07:00
Lars-Peter Clausen 0a6fa449de Add regression tests for `begin_keywords` versions
Check that each valid `begin_keywords` selector is accepted. Only check
that the selector itself is accepted, in these tests there is no check if
the correct keywords are actually accepted or rejected since that would get
pretty exhaustive.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-16 15:40:37 -07:00
Lars-Peter Clausen eadb1d24ae Add 2017 and 2023 language flag support
Add flags to enable IEEE1800-2017 and IEEE1800-2023 languages generations
and also support them in the `begin_keywords macro. Since neither defines
new keywords they'll use the same keyword mask as 2012.

Update the driver, compiler, documentation and regression test harness so
-g2017 and -g2023 are recognized as language generation flags.

There are no specific features from these versions added yet, this is just
the necessary infrastructure to allow gating new features from those
generations when they are added later.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-16 15:40:37 -07:00
Cary R. 00325f3efb
Merge pull request #1348 from jotego/interface-ports
Support SystemVerilog interface-typed module ports
2026-05-16 15:33:56 -07:00
Cary R. b605f42a1e
Update copyright year in parse_misc.h 2026-05-16 15:19:40 -07:00
Cary R. 9f3f35e451
Update copyright year in netmisc.h 2026-05-16 15:19:02 -07:00
Cary R. 73cee3b3e0
Update copyright year in Module.h 2026-05-16 15:18:15 -07:00
Cary R. 9ff4a42171
Update copyright year in Module.cc 2026-05-16 15:17:52 -07:00
Cary R. 84dc4ec99f
Update copyright year in elab_net.cc 2026-05-16 15:16:47 -07:00
Cary R. 1751f4ed0b
Merge pull request #1361 from larsclausen/unpacked-lvalue-concat-error
Reject unpacked l-value concatenation operands
2026-05-16 14:37:36 -07:00
Lars-Peter Clausen 96cea271ba ivtest: Fix VVP regression test metadata
A few JSON regression test entries reference the wrong source or gold
files. There are also two regress-vvp list entries that reference each
other's JSON file.

Use the matching source and gold files for those entries.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-16 13:43:10 -07:00
Lars-Peter Clausen b8eac7fc19 ivtest: Fix source for sv_mixed_assign2 test
The sv_mixed_assign2 JSON entry accidentally references
sv_mixed_assign1.v. Point it at sv_mixed_assign2.v instead.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-16 12:51:43 -07:00
Lars-Peter Clausen f9ab26b3d9 Add regression tests for unpacked l-value concat errors
Check that class objects, dynamic arrays, queues, strings and static
unpacked arrays can not be used as l-value concatenation operands. Check
procedural and continuous assignment concatenations, including single
operand concatenations.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-15 20:48:19 -07:00
Lars-Peter Clausen 208078838e Reject unpacked l-value concatenation operands
L-value concatenation operands must be packed values. Using an unpacked
array, string, class object or other non-packed value as an operand can
reach later assignment code with an invalid l-value representation.

Check the operand type after l-value elaboration and report an
elaboration error instead.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-15 20:44:47 -07:00
Cary R. 73ae5bd1db
Merge pull request #1360 from larsclausen/vvp-case-cmp-e
tgt-vvp: Use `%cmp/e` instead of `%cmp/u` for `case` comparisons
2026-05-15 07:47:46 -07:00
Cary R. 5b62f32ad6
Update copyright year in vvp_process.c 2026-05-15 07:47:24 -07:00
Cary R. a6ba0eef5e
Merge pull request #1359 from larsclausen/remove-unused-parser-union-fields
parse.y: Remove unused fields from union
2026-05-14 22:35:07 -07:00
Lars-Peter Clausen d84f1b9843 tgt-vvp: Use `%cmp/e` instead of `%cmp/u` for `case` comparisons
`%cmp/e` and `%cmp/u` are very similar with `%cmp/e` not setting the lt
flag and being a bit faster due to it. For case comparisons the flag is not
needed so switch to `%cmp/e`. This speeds up simulation time designs which
make use of case comparisons.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-14 20:34:30 -07:00
Lars-Peter Clausen f1c71eff5c parse.y: Remove unused fields from union
The parser union still has a few fields that are not used by any
grammar rule. They do not have matching semantic type tags and no
action references them.

Remove the unused fields.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-14 20:18:28 -07:00
Cary R. 5fac9fae4d
Merge pull request #1358 from hwhsu1231-fork/edit-this-page
docs: add edit this page to sidebar
2026-05-13 10:01:53 -07:00
Haowei Hsu a042847b38
docs: add edit this page to sidebar 2026-05-13 22:12:30 +08:00
Cary R. 2f1987bded
Merge pull request #1357 from hwhsu1231-fork/add-github-url
docs: add github url to html theme options
2026-05-13 02:46:19 -07:00
Ralf Habacker a1299f7ca8 CI: enable building with libvvp and suffix on MacOSX
Adding these build variants to the platform in question results
in the smallest increase in the number of additional build jobs.
2026-05-13 10:48:24 +02:00
Ralf Habacker 00bb35a0ce CI: Add support to compile on all platforms with libvvp and/or suffix enabled
The specified jobs runs the build, check, install and a post install
test stage.
2026-05-13 10:45:04 +02:00
Ralf Habacker 9d3101fd19 vvp: build and install libvvp as a versioned shared library
It uses a dedicated LIBVVP_SOVERSION specified in onfigure.ac
for the SONAME and full library version.

For linking, a pkg-config file is generated, and when building on
Windows, an import library is created that can be used with both
GCC and MSVC compilers.

On non-Windows platforms, all object files are compiled with -fPIC
to ensure compatibility with shared libraries.

On Windows use 'lib' prefix for library name with MinGW compiler
only. Other compiler like MSVC normally are not using any library
prefix.

With this commit the build rules for the vpp executable has been
cleaned too because the complex structure of the manually created
Makefile.in made it very difficult to extract specific parts of
them.
2026-05-13 10:45:04 +02:00
Ralf Habacker 4014db47e0 vvp: introduce variable names for object files used by the vvp library 2026-05-13 10:45:04 +02:00
Ralf Habacker 3e7135aabb vvp: add DLLIB to LIBS to simplify build rules 2026-05-13 10:45:04 +02:00
Ralf Habacker 38a24e71b5 vpp: install missing include directory when installing from 'vvp' directory
This fixes an issue unrelated to the addition of support for
versioned VVP library.
2026-05-13 10:45:04 +02:00
Haowei Hsu 214324db8c
docs: add github url to html theme options
Include the GitHub repository URL in the HTML theme options
for better visibility and access to the project's source code.
2026-05-13 15:34:04 +08:00
Cary R 6b1878c1b5 Update to the latest actions to remove Node.js warnings 2026-05-12 21:53:53 -07:00
Cary R 1476f36ff3 Upgrade actions/checkout to version 5 to support proper nodeJS 2026-05-12 21:35:22 -07:00
Cary R. 89740e6f0e
Merge pull request #1346 from hwhsu1231-fork/venv-switch-shibuya-theme
docs: switch docs to shibuya theme and install via venv
2026-05-12 21:09:51 -07:00
Cary R. 2449ee2054
Merge pull request #1355 from larsclausen/super-member-access-error
Reject super access without a parent class
2026-05-12 21:08:27 -07:00
Lars-Peter Clausen e4afd6dc25 Add regression test for `super` access error
Check that access through `super` is rejected when the current class has no
parent class.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-12 20:43:38 -07:00
Lars-Peter Clausen cdb9bc2c21 Reject `super` access without a parent class
The `super` keyword refers to the parent class of the current class. If the
class has no parent the lookup still returned the current class handle and left
the `super` path component for l-value elaboration. This triggered the
`tail_path.empty()` assert.

Report an error during symbol lookup instead.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-12 20:43:38 -07:00
Cary R. a8eda65859
Merge pull request #1353 from rhabacker/simplify-doc-rules
vvp,tgt-fpga: cleanup doc related rules
2026-05-12 05:27:44 -07:00
Ralf Habacker 33584ec6f1 tgt-fpga: cleanup doc related rules
With this commit, the file “iverilog-fgpa.pdf” is now
also installed in the directory where all the other
PDF files are located.
2026-05-12 10:35:02 +02:00
Ralf Habacker 46a329f16f vvp: cleanup doc related rules 2026-05-12 10:31:19 +02:00
Cary R. 49ee58c356
Merge pull request #1352 from larsclausen/named-event-edge-errors
Report error for `edge` event controls on named events
2026-05-11 22:30:49 -07:00
Cary R 5b51ed9aa5 Fix building and dependency for verion_base.h 2026-05-11 22:16:00 -07:00
Lars-Peter Clausen ba3f46722c Add regression tests for edge controls on named event errors
Check that the compiler reports an error for `posedge`, `negedge` and `edge`
event controls on named events. Edge controls can not be used with named
events.

There is already an existing test that checks both `posedge` and `negedge`.
Split it into separate tests so that each invalid event control is checked
independently.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-11 21:10:35 -07:00
Lars-Peter Clausen 265272a962 Report error for `edge` event controls on named events
Using an edge control with a named event is invalid. The existing elaboration
code already reports an error for `posedge` and `negedge`, but the `edge` case
falls through to the default path and triggers an assert.

Handle `PEEvent::EDGE` like the other edge-control cases and report the same
kind of error instead.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-11 21:10:32 -07:00
Jose Tejada 56afcb6e75 fix(interface): allow forward interface port types 2026-05-11 22:25:32 +02:00
Haowei Hsu a52bef20ed
docs: switch docs to shibuya theme and install via venv
- change documentation theme from `alabaster` to `shibuya`
- add pinned Documentation requirements for `sphinx` and `shibuya`
- update workflows to create `.venv` and install with `requirements.txt`
- ignore common virtual environment directories (`.conda` and `.venv`)
2026-05-11 20:48:58 +08:00
Cary R. f696064af1
Merge pull request #1351 from rhabacker/fixup-for-1331
Makefile.in: 'version_base.h' must not be deleted when running `make …
2026-05-11 04:51:42 -07:00
Ralf Habacker 1ea5f72496 Makefile.in: 'version_base.h' must not be deleted when running `make clean`
Since this file, just like 'config.h', is generated by autoconf,
it should only be deleted in the `distclean` target.

Also since the project does not currently use automake, manual
maintenance of the timestamp file for 'version_base.h' is required.

Fixup for commit 10b5f70e7 from #1331
2026-05-11 13:16:08 +02:00
Jose Tejada 377881b723 fix(interface): address port array review feedback 2026-05-11 07:44:43 +02:00
Cary R. bcc3a66657
Merge pull request #1350 from larsclausen/array-index-real-error
Reject `real` array indices
2026-05-10 22:40:23 -07:00
Lars-Peter Clausen ea57b6dd9a Add regression test for real array index error
Check that using a real valued expression as an array index is rejected
during elaboration.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-10 22:26:48 -07:00
Lars-Peter Clausen ba74c7b5ad Reject `real` array indices
Array indices must be integral expressions. Using a real valued expression
as an unpacked array index currently reaches the vvp real expression code
and triggers an assert.

Packed bit and part select indices already report an elaboration error for
real expressions since commit 2249d224de ("Bit/part selects cannot have
real index expressions"). Do the same for unpacked array indices.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-10 22:26:44 -07:00
Cary R. fb6dfebcec
Merge pull request #1349 from larsclausen/new-array-init-cleanup
elab: Use common new array initializer elaboration
2026-05-10 15:24:56 -07:00
Cary R 13d5155e88 Docopt is no longer used in the Python test script 2026-05-10 15:19:09 -07:00
Lars-Peter Clausen fde4ef85c1 elab: Use common new array initializer elaboration
here are two separate paths `PENewArray::elaborate_expr()`, one for
assignment patterns and one for everything else.

But since since commit 5ca058bfb ("Add support for darray initialisation
from another darray"). The two paths have been effectively the same.

Both call `elaborate_expr()` on the init values with the same parameters.
The only difference is the regular path casts the type to `netarray_t`, but
that doesn't really do anything since it gets passed to a function that
takes a `ivl_type_t`, so is immediately cast back to the base type.

The comment on the regular path is also outdated since it still refers to
the tpre 5ca058bfb code.

Remove the branching and route it through the same path.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-10 14:59:44 -07:00
Cary R. 8c7f3452c5
Merge pull request #1347 from larsclausen/enum-const-width-cleanup
elab: Remove redundant enum parameter width handling
2026-05-10 14:49:33 -07:00
Cary R 5240790480 Fix/update latest cppcheck issues 2026-05-10 14:47:40 -07:00
Jose Tejada 417ab54445 feat(interface): support interface port arrays 2026-05-10 17:30:54 +02:00
Jose Tejada 2228e31a6a refactor(interface): share port resolution paths 2026-05-10 17:08:35 +02:00
Jose Tejada 39072cd452 feat(interface): broaden interface port binding 2026-05-10 16:34:21 +02:00
Jose Tejada c963809709 feat(sv): support interface-typed module ports 2026-05-10 14:45:33 +02:00
Lars-Peter Clausen 71ce460caa elab: Remove redundant enum parameter width handling
`PEIdent::test_width_parameter_()` has a special case for
`NetEConstEnum` that queries the enum base type directly. This was needed
when enum constants kept their enum type separately from the `NetExpr`
type.

Commit f63a162329 ("Provide data type for more NetExpr subclasses") made
`NetEConstEnum` attach the enum type to the `NetExpr`. The generic
parameter width path now gets the same type, width and signedness as the
special case.

Remove the redundant special case and use the common path for enum
constants as well.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-09 19:05:18 -07:00
Cary R e212ea1a1c package liftime test needs signed for vlog95 testing 2026-05-08 05:54:13 -07:00
Cary R 3d8f906bdd Update Copyright that was missed for a few files 2026-05-08 05:35:16 -07:00
Cary R. 3986804264
Merge pull request #1343 from larsclausen/lifetime_package
Allow lifetime specifier for variables declared in packages
2026-05-08 05:21:19 -07:00
Cary R. e0e4a2af48
Merge pull request #1342 from larsclausen/vvp-reduce-speed-up
vvp: Improve reduction operator performance
2026-05-08 05:17:52 -07:00
Lars-Peter Clausen 81222402c7 Add regression tests for package variable lifetimes
Check that package variables can use explicit static lifetime. Check that
automatic lifetime is rejected for package variables.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-07 22:14:20 -07:00
Lars-Peter Clausen c2b63e69a4 Allow lifetime specifier for variables declared in packages
The LRM allows to add a lifetime specified for variables declared in
package scope. It is not particular useful since only static lifetime is
allowed. But it is legal syntax, so support it.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-07 22:14:20 -07:00
Lars-Peter Clausen 48242818b3 vvp: Improve reduction operator performance
The vvp reduction operators evaluate their input bit by bit. This is
expensive for wide vectors.

Add word wide reduction helpers to `vvp_vector4_t` and use them for both
reduction functors and vthread reduction opcodes.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-07 21:26:17 -07:00
Cary R e4c4247266 Fix the full PDF document name 2026-05-07 19:40:58 -07:00
Cary R d8e7cd4037 iverilog-vpi is not in the main directory 2026-05-07 19:34:36 -07:00
Cary R f559a05672 Net arrays are not supported for Verilog 95 2026-05-06 21:25:25 -07:00
Cary R. 99c7a9f940
Merge pull request #1338 from larsclausen/byte-array-string-literal
Support assignment of string literals to byte arrays
2026-05-06 20:44:13 -07:00
Cary R. 33a6d58258
Merge pull request #1341 from larsclausen/vvp-vector-ops-speed-up
vvp: Use word wide bitwise logical ops
2026-05-06 20:37:49 -07:00
Lars-Peter Clausen 6ffb4b9a3a Add regression tests for string literals assigned to byte arrays
Check that string literals can be assigned to byte arrays. Check that
invalid target array types are reported as errors.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-06 19:20:47 -07:00
Cary R. e9cffe506b
Merge pull request #1340 from rhabacker/followup-for-1331
Makefile.in: remove obsolete dependency
2026-05-06 18:48:01 -07:00
Cary R. e02eb2a4d8
Merge pull request #1339 from rhabacker/fix-build-rules
Fix incomplete build rules for generating header files
2026-05-06 18:47:37 -07:00
Cary R. 68244563ca
Merge pull request #1335 from rhabacker/cleanup-iverilog-vpi
iverilog-vpi: Consolidate creation in driver-vpi
2026-05-06 18:47:05 -07:00
Lars-Peter Clausen 0f454ff548 vvp: Use word wide vector operations for logic functors
The logic functors combine their input vectors bit by bit.

Use the in-place `vvp_vector4_t` operators for the vector operation and
invert the result once for the inverted functors.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-06 13:19:53 -07:00
Lars-Peter Clausen cf53479ba2 vvp: vthread: Use word wide vector operations
The vthread binary logic opcodes update vectors bit by bit.

Use the in-place `vvp_vector4_t` operators instead. This reuses the word
wide implementation and avoids per-bit `value()` and `set_bit()` calls.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-06 13:19:53 -07:00
Lars-Peter Clausen 41c3423209 vvp: Implement `vvp_vector4_t` xor operator
`vvp_vector4_t` has word wide in-place operators for and and or, but not
for xor.

Add `operator ^=` using the same internal word representation.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-06 13:19:53 -07:00
Ralf Habacker f8e20f5a09 Makefile.in: remove obsolete dependency
Fixup for commit 49eaafe88 from #1331
2026-05-05 08:16:33 +02:00
Ralf Habacker d59e2c97ba Add missing autoconf macro for generating header stamp files
Fixes #1334

Fixup for commit 804e06cce.
2026-05-05 01:16:12 +02:00
Lars-Peter Clausen 272cf91eae Support assignment of string literals to byte arrays
SystemVerilog defines a special case that allows to assign string literals
to byte arrays. Each character of the string is copied to 1 element of the
byte array.

The size of string literal and the byte array does not have to match. If
the string literal is longer it is truncated. If it is shorter it will be
padded with null-bytes.

The assignment is done left aligned, the first character ends up in the
left most entry of the array. This means the order will differ whether the
array is declared with ascending or descending element order.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-03 19:48:38 -07:00
Lars-Peter Clausen 8519a30354 Add regression test for unpacked array output port expressions
Check that assignment patterns cannot be connected directly to unpacked
array output ports.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-03 17:31:09 -07:00
Lars-Peter Clausen d39e81e1d1 Reject non-assignable unpacked array output port expressions
Output port expressions must support continuous assignment. Assignment
patterns for unpacked array output ports are currently elaborated as
temporary arrays and the connection is silently discarded.

Report an error instead.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-03 17:31:09 -07:00
Lars-Peter Clausen be3be03fec Add regression test for drive strength net declarations
Check that drive strength can be specified between the net type and the
data type in a net declaration and that vector gate arrays resolve
strengths correctly.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-03 17:30:56 -07:00
Lars-Peter Clausen 11c619e265 Fix drive strength in net declaration parsing
The drive strength of a net must be declared between the net type and the data type. E.g.

    wire (weak0, strong1) [7:0] x;

The current implementation expects the drive strength after the data type. Update the parser to fix this.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-05-03 17:30:56 -07:00
Ralf Habacker 181cb7b2ed iverilog-vpi: Consolidate creation in driver-vpi
This change standardizes the creation of iverilog-vpi-related
targets, which now follow the same pattern as the iverilog targets
in the 'driver' subdirectory.
2026-05-02 14:03:00 +02:00
Ralf Habacker 9b42bf0df6 Makefile.in, vvp/Makefile.in: introduce ivl_includedir
This variable was introduced to avoid conflicts with
the existing `includedir` variable, which is used for
the general include directory.
2026-05-02 14:02:59 +02:00
Ralf Habacker 0846198602 Makefile.in, driver/Makefile.in: fix setup of generated doc types for iverilog*
This resolves an issue where the man page is built even if
the 'man' program is not installed.
2026-05-02 14:02:59 +02:00
Cary R 6c52271afa Reorder check-installed targets 2026-04-30 08:31:50 -07:00
Cary R. ed7240b392
Merge pull request #1332 from rhabacker/ivtest-in-build-system
Ivtest in build system
2026-04-30 08:22:24 -07:00
Ralf Habacker c14c73dd9a ivtest: Integration of regression tests into the build system
Replace .github/test.sh with a unified set of targets installed
via `make check-*` in ivtest/, thereby removing CI-specific test
coordination. This avoids duplication in the regression logic and
ensures consistent execution between local and CI environments.
PLI1-dependent tests are now correctly controlled via
`configure --enable-libveriuser`.

Currently, the regression suite still depends on an iverilog package,
which must be installed manually at the location specified with
`configure --prefix=*`. Afterward, the complete regression suite
(VVP, VPI, and Python tests) can be run via `make check-installed`
and individual checks can be run with `check-installed-vpi`,
`check-installed-vvp` and `check-installed-vvp-py`.
2026-04-30 17:04:53 +02:00
Cary R. 03cac78504
Merge pull request #1331 from rhabacker/version-base-fixup
Move the use of version.exe to the build system
2026-04-30 08:02:07 -07:00
Ralf Habacker 49eaafe886 Remove support for creating 'version.exe' from the build system
Since this functionality has now been taken over by the build system
and is no longer needed, it can be removed from the build system.
2026-04-30 09:11:21 +02:00
Ralf Habacker 731891b58f Update documentation to clarify that 'version.exe' is no longer used 2026-04-30 09:11:21 +02:00
Ralf Habacker 92d345ddb2 Use autoconf variables in generated man and pdf output 2026-04-30 09:11:21 +02:00
Ralf Habacker 10b5f70e71 Move version info into configure.ac and generate version_base.h from template 2026-04-30 09:11:18 +02:00
Ralf Habacker 68f461f5a9 configure.ac: Sort and reformat the list of generated config files
If there is only one file per line, it is easier to add additional files.
2026-04-30 07:29:03 +02:00
Cary R 6f3beca5fb FST can dump packages 2026-04-29 20:59:19 -07:00
Cary R. 15989f3d62
Merge pull request #1329 from rhabacker/fix-1313
Fix test error with --enable-libvvp
2026-04-28 08:21:43 -07:00
Cary R. db06b37243
Merge pull request #1328 from rhabacker/split-aclocal
Split aclocal macros into m4 files for aclocal-managed autoconf setup
2026-04-28 08:15:34 -07:00
Ralf Habacker 047974bdb6 Fix test error with --enable-libvvp
When running `make check` on a UNIX-like operating system
with the specified `configure` option, `vvp` was unable to
find the required shared library.

This commit ensures that the runtime linker can locate the library.

This fixes issue #1313.
2026-04-28 13:36:47 +02:00
Ralf Habacker e8a4cc7c9e configure: explicitly require C++11
Newer autoconf/toolchains may default to newer C++ standards
(e.g. C++23). Explicitly enforce C++11 to preserve expected
behavior.
2026-04-28 13:15:17 +02:00
Ralf Habacker 804e06cce9 Split aclocal macros into m4 files for aclocal-managed autoconf setup
Future updates are handled via aclocal --install or autoreconf,
no manual edits to aclocal.m4 required.
2026-04-28 13:15:07 +02:00
Martin Whitaker ca756322a7 Add regression test for issue #1323. 2026-04-15 16:44:35 +01:00
Martin Whitaker eed88fc61f ivlpp: Ensure def_buf is allocated when calling macro_start_args()
macro_start_args() inserts a null string for arg 0 at the start of def_buf.
This allows macro_finish_arg() to calculate the length of the first actual
argument (arg 1). But macro_start_args() relied on def_buf having already
been allocated, which isn't the case when all the macros are pre-defined.

This fixes issue #1323.
2026-04-15 16:24:32 +01:00
Cary R 9b0d46b4bf Update to the latest GTKWave files 2026-03-27 19:16:23 -07:00
Cary R 1248394a5d Fix possible parallel build race with compile and dep directory 2026-03-27 18:38:34 -07:00
Cary R fa518a3409 Remove versioned manual pages during `make clean` 2026-03-27 18:38:34 -07:00
Cary R. aa417d7575
Merge pull request #1315 from vowstar/fix/dep-mkdir-race
Fix parallel build race with dep/ directory
2026-03-27 18:20:06 -07:00
Huang Rui f20865a5ea Include mach-o/dyld.h for _NSGetExecutablePath on macOS
driver/main.c uses _NSGetExecutablePath in the __APPLE__ code path
but does not include the header that declares it, causing a build
failure on macOS.

Signed-off-by: Huang Rui <vowstar@gmail.com>
2026-03-27 11:45:32 +08:00
Huang Rui ac3ef217c3 Fix parallel build race with dep/ directory
Pattern rules that move .d files into dep/ do not depend on the dep
directory target, so parallel make can attempt the move before the
directory exists.

Add dep as an order-only prerequisite to all affected pattern rules.

Bug: https://bugs.gentoo.org/880921
Bug: https://bugs.gentoo.org/911647
Bug: https://bugs.gentoo.org/917344
Closes: https://github.com/steveicarus/iverilog/issues/1314
Signed-off-by: Huang Rui <vowstar@gmail.com>
2026-03-27 11:29:24 +08:00
Martin Whitaker 6767a07956 Merge branch 'SiB64-strict-parameter-declaration'
Pulled from https://codeberg.org/SiB64/iverilog strict-parameter-declaration
with further enhancements.
2026-03-21 20:53:12 +00:00
Martin Whitaker 42d0c3fd4a Update test suite to cover -gno-strict-declaration options. 2026-03-21 20:50:18 +00:00
Martin Whitaker 5da8894590 Fix documentation for -Wno-declaration-after-use. 2026-03-21 20:21:05 +00:00
Martin Whitaker 4c315b32d4 Change strict-net-declaration to strict-net-var-declaration.
Internally the compiler uses 'net' for both nets and variables, but
we should make it clear to the user that this option applies to both.
2026-03-21 20:18:53 +00:00
Martin Whitaker dc0d162fa9 Report declaration position when warning about declaration after use. 2026-03-21 19:35:29 +00:00
Martin Whitaker 29e128ed94 Only warn about declaration after use once for each data object. 2026-03-21 18:25:15 +00:00
Martin Whitaker 475f098cab Minor grammar and white space fixes in documentation. 2026-03-21 17:20:27 +00:00
Stephan I. Böttcher 7d438b66c8 add option -gno-strict-declaration
The new option allows parameter, net and events to be used before
declaration.  With variants

 -gno-strict-net-declaration for nets and events,
 -gno-strict-parameter-declaration for parameters.
2026-03-18 18:01:54 +01:00
Stephan I. Böttcher 54f17a2cb1 Add warning class -Wno-declaration-after-use
With `-ggno-strict-parameter-declaration` a warning is issued for
parameter use before declaration.  This warning suppressed with
the new class `-Wno-declaration-after-use`, instead of `-Wno-anachronisms`.
2026-03-18 12:46:42 +01:00
Stephan I. Böttcher 42f7d3a922 strict_param_decl: dedup use after decl test 2026-03-18 12:08:39 +01:00
Stephan I. Böttcher 1f8991e382 Emit a warning with -gno-strict-parameter-declaration
When a parameter is used before declaration, a warning is printed,
unless `-Wno-anachronisms`.
2026-03-17 20:32:06 +01:00
Stephan I. Böttcher ab74cafa20 Add option -gno-strict-parameter-declaration
The standards requires that parameters must be declared
before they are used.  Using -gno-strict-parameter-declaration
will allow using a parameter before declaration, e.g., in a port
declaration, with the parameter declared in the body of the
module.  Prior to version 13 this was allowed, so there is a large body
of existing code depending on the pre version 13 behaviour.
2026-03-17 19:39:51 +01:00
Cary R. ff2f4c6864
Merge pull request #1303 from aelmahmoudy/rename-manpage
Rename manpage to iverilog.1 to match executable name
2026-03-08 15:17:54 -07:00
Cary R. d3bda52d69
Fix man page entry for Icarus Verilog documentation 2026-03-08 15:07:02 -07:00
Cary R d64bf0b0b3 Update to the latest GTKWAve files 2026-03-08 14:51:32 -07:00
Cary R c836236b28 Add Copyright to a couple LGPL2 files 2026-03-08 14:07:04 -07:00
Cary R. 462a15dcbb
Merge pull request #1302 from aelmahmoudy/fix-typos
Fix typo: contributer -> contributor
2026-03-05 19:08:39 -08:00
أحمد المحمودي (Ahmed El-Mahmoudy) 57385f9ac6 Rename manpage to iverilog.1 to match executable name 2026-03-05 23:38:16 +01:00
أحمد المحمودي (Ahmed El-Mahmoudy) f9a0542a49 Fix typo: contributer -> contributor 2026-03-05 22:48:57 +01:00
Martin Whitaker 14a25bfe92 Update the copy of ax_prog_cc_for_build.m4 embedded in aclocal.m4
This correctly generates the EXEEXT variable when cross-compiling and
using autoconf 2.70+ (issue #1301).
2026-03-05 17:52:09 +00:00
Martin Whitaker 4dfac864ce Remove duplicated typeders and functions from t-dll.h and t-dll.c
These duplicate the contents of ivl_dlfcn.h
2026-03-05 12:01:03 +00:00
Martin Whitaker 3f936d2d8b Merge duplicated ivl_dlfcn.h files.
The vvp/ivl_dlfcn.h and cadpli/ivl_dlfcn.h files are essentially the
same, but have diverged a bit over the years. Merge them into a single
shared file at the top level. Use the static prefix for all inline
functins (currently only used in the cadpli version) as that will fix
issue #1301. We now require the compiler to support at least C99, so
can use "inline", not "__inline__".
2026-03-05 11:55:56 +00:00
Cary R b8de0499a9 Update vvp examples to match the correct version 2026-03-02 10:48:10 -08:00
Cary R 98391b56bc Update example to match new version 2026-03-01 15:31:50 -08:00
947 changed files with 23500 additions and 4398 deletions

20
.github/test.sh vendored
View File

@ -1,20 +0,0 @@
#!/usr/bin/env sh
echo "Using the bundled ivtest to run regression tests."
echo " pwd = $(pwd)"
cd ivtest
status=0
perl vvp_reg.pl || status=1
if [ "x$1" = "xno-pli1" ] ; then
perl vpi_reg.pl || status=1
else
perl vpi_reg.pl --with-pli1 || status=1
fi
python3 vvp_reg.py || status=1
exit $status

View File

@ -19,10 +19,15 @@ jobs:
- name: Install dependencies
run: |
sudo apt update -qq
sudo apt install -y make autoconf python3-sphinx
sudo apt install -y make autoconf python3-venv
python3 -m venv .venv
. .venv/bin/activate
pip install --upgrade pip
pip install -r Documentation/requirements.txt
- name: Make Documentation
run: |
. .venv/bin/activate
cd Documentation
make html

View File

@ -14,60 +14,82 @@ jobs:
mac:
strategy:
fail-fast: false
matrix:
libvvp: [true]
suffix: [true]
runs-on: macos-15-intel
name: '🍏 macOS'
name: 🍏 macOS${{ matrix.libvvp && ' +libvvp' || '' }}${{ matrix.suffix && ' +suffix' || '' }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Install dependencies
run: |
brew install bison
pip3 install --break-system-packages docopt
- name: Build, check and install
run: |
export PATH="/usr/local/opt/bison/bin:$PATH"
CONFIG_OPTS="--enable-libveriuser"
if [ "${{ matrix.libvvp }}" = "true" ]; then
CONFIG_OPTS="$CONFIG_OPTS --enable-libvvp"
fi
if [ "${{ matrix.suffix }}" = "true" ]; then
CONFIG_OPTS="$CONFIG_OPTS --enable-suffix"
fi
autoconf
./configure --enable-libveriuser
./configure $CONFIG_OPTS
make -j$(nproc) check
sudo make install
- name: Test
run: ./.github/test.sh
run: |
make check-installed
lin:
strategy:
fail-fast: false
matrix:
os: [
'22.04',
'24.04'
]
os: ['22.04', '24.04']
# libvvp: [false, true]
# suffix: [false, true]
runs-on: ubuntu-${{ matrix.os }}
name: '🐧 Ubuntu ${{ matrix.os }}'
name: 🐧 Ubuntu ${{ matrix.os }}${{ matrix.libvvp && ' +libvvp' || '' }}${{ matrix.suffix && ' +suffix' || '' }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Install dependencies
run: |
sudo apt update -qq
sudo apt install -y make g++ git bison flex gperf libreadline-dev libbz2-dev autoconf python3-sphinx python3-docopt
sudo apt install -y make g++ git bison flex gperf libreadline-dev libbz2-dev autoconf python3-venv
python3 -m venv .venv
. .venv/bin/activate
pip install --upgrade pip
pip install -r Documentation/requirements.txt
- name: Build, check and install
run: |
CONFIG_OPTS="--enable-libveriuser"
if [ "${{ matrix.libvvp }}" = "true" ]; then
CONFIG_OPTS="$CONFIG_OPTS --enable-libvvp"
fi
if [ "${{ matrix.suffix }}" = "true" ]; then
CONFIG_OPTS="$CONFIG_OPTS --enable-suffix"
fi
autoconf
./configure --enable-libveriuser
./configure $CONFIG_OPTS
make -j$(nproc) check
sudo make install
- name: Test
run: ./.github/test.sh
run:
make check-installed
- name: Documentation
run: |
. .venv/bin/activate
cd Documentation
make html
@ -76,11 +98,14 @@ jobs:
strategy:
fail-fast: false
matrix:
msystem: [MINGW64, UCRT64, CLANG64]
# libvvp: [false, true]
# suffix: [false, true]
include:
- { msystem: MINGW64, env: x86_64 }
- { msystem: UCRT64, env: ucrt-x86_64 }
- { msystem: CLANG64, env: clang-x86_64 }
name: 🟪 ${{ matrix.msystem}}
name: 🟪 ${{ matrix.msystem }}${{ matrix.libvvp && ' +libvvp' || '' }}${{ matrix.suffix && ' +suffix' || '' }}
defaults:
run:
shell: msys2 {0}
@ -91,7 +116,7 @@ jobs:
- run: git config --global core.autocrlf input
shell: bash
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: msys2/setup-msys2@v2
with:
@ -103,16 +128,24 @@ jobs:
python-pip
mingw-w64-${{ matrix.env }}-perl
- uses: actions/setup-python@v5
- uses: actions/setup-python@v6
with:
python-version: '>=3.5'
- name: Build and check
run: |
cd msys2
CONFIG_OPTS=""
if [ ${{ matrix.msystem }} != "CLANG64" ] ; then
export IVL_CONFIG_OPTIONS="--enable-libveriuser"
CONFIG_OPTS="$CONFIG_OPTS --enable-libveriuser"
fi
if [ "${{ matrix.libvvp }}" = "true" ] ; then
CONFIG_OPTS="$CONFIG_OPTS --enable-libvvp"
fi
if [ "${{ matrix.suffix }}" = "true" ]; then
CONFIG_OPTS="$CONFIG_OPTS --enable-suffix"
fi
export IVL_CONFIG_OPTIONS="$CONFIG_OPTS"
makepkg-mingw --noconfirm --noprogressbar -sCLf
- name: Install
@ -120,13 +153,9 @@ jobs:
- name: Test
run: |
if [ ${{ matrix.msystem }} = "CLANG64" ] ; then
./.github/test.sh no-pli1
else
./.github/test.sh
fi
make check-installed
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: ${{ matrix.msystem }}
name: 🟪 ${{ matrix.msystem }}${{ matrix.libvvp && ' +libvvp' || '' }}
path: msys2/*.zst

47
.gitignore vendored
View File

@ -8,6 +8,10 @@
*.swp
*~
# Virtual environments
.conda/
.venv/
# Top level generic files
tags
TAGS
@ -31,16 +35,19 @@ Makefile
/_pli_types.h
config.h
/tgt-pcb/pcb_config.h
/tgt-pcb/fp.cc
/tgt-pcb/fp.h
/tgt-pcb/fp.output
/tgt-pcb/fp_lex.cc
/tgt-vvp/vvp_config.h
/tgt-vhdl/vhdl_config.h
/vhdlpp/vhdlpp_config.h
/vpi/vpi_config.h
stamp-*-h
/version.h
/version_tag.h
/version_base.h
/driver-vpi/iverilog-vpi.man
/driver-vpi/res.rc
/driver/iverilog.man
/vvp/libvvp.pc
/vvp/vvp.man
# Directories
autom4te.cache
@ -52,8 +59,6 @@ dep
*.vpi
/cadpli/cadpli.vpl
/tgt-blif/Makefile
# lex, yacc and gperf output
/driver/cflexor.c
/driver/cfparse.c
@ -62,14 +67,6 @@ dep
/ivlpp/lexor.c
/vhdlpp/lexor.cc
/vhdlpp/lexor_keyword.cc
/vhdlpp/parse.cc
/vhdlpp/parse.h
/vhdlpp/parse.output
/vhdlpp/vhdlpp_config.h
/vhdlpp/vhdlpp
/lexor.cc
/lexor_keyword.cc
/parse.cc
@ -78,6 +75,17 @@ dep
/syn-rules.cc
/syn-rules.output
/tgt-pcb/fp.cc
/tgt-pcb/fp.h
/tgt-pcb/fp.output
/tgt-pcb/fp_lex.cc
/vhdlpp/lexor.cc
/vhdlpp/lexor_keyword.cc
/vhdlpp/parse.cc
/vhdlpp/parse.h
/vhdlpp/parse.output
/vpi/sdf_lexor.c
/vpi/sdf_parse.c
/vpi/sdf_parse.h
@ -97,17 +105,13 @@ dep
# Program created files
/vvp/tables.cc
/iverilog-vpi.man
/driver-vpi/res.rc
/driver/iverilog.man
/vvp/vvp.man
# The executables.
*.exe
/driver/iverilog
/iverilog-vpi
/driver-vpi/iverilog-vpi
/ivl
/ivlpp/ivlpp
/vhdlpp/vhdlpp
/vvp/vvp
/ivl.exp
@ -115,3 +119,4 @@ dep
# Check output
/check.vvp
/driver/top.vvp

View File

@ -73,16 +73,29 @@ highlight_language = 'none'
# -- Options for HTML output -------------------------------------------------
# A dictionary of values to pass into the template engine's context for all pages.
#
html_context = {
# Edit this page
"source_type": "github",
"source_user": "steveicarus",
"source_repo": "iverilog",
"source_version": "master",
"source_docs_path": "/Documentation/",
}
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'alabaster'
html_theme = 'shibuya'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
html_theme_options = {
"github_url": "https://github.com/steveicarus/iverilog",
}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
@ -142,7 +155,7 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'icarusverilog', 'Icarus Verilog Documentation',
(master_doc, 'iverilog-docs', 'Icarus Verilog Documentation',
[author], 1)
]

View File

@ -8,7 +8,7 @@ source code itself, so that you can find the global parts where you
can look for even better detail.
The documentation for getting, building and installing Icarus Verilog
is kept and maintained at :doc:`Getting Started as a Contributer <../getting_started>`
is kept and maintained at :doc:`Getting Started as a Contributor <../getting_started>`
See the Installation Guide for getting the current source from the git
repository (and how to use the git repository) and see the Developer Guide

View File

@ -812,6 +812,10 @@ result is pushed back on the vec4 stack.
This opcode multiplies two real words together.
* %neg/wr
This opcode negates the real value on top of the real stack.
* %nand
Perform the bitwise NAND of two vec4 vectors, and push the result. Each

View File

@ -17,7 +17,7 @@ the "make version" target, or automatically if the version_tag.h
file doesn't exist at all. This implies that a "make version" is
something worth doing when you do a "git pull" or create commits.
The files below are now edited by the Makefile and the version.exe program:
The files below are now edited by the Makefile:
* iverilog-vpi.man -- The .TH tag has a version string
* driver/iverilog.man -- The .TH tag has a version string

View File

@ -0,0 +1,2 @@
sphinx==8.1.3
shibuya==2026.1.9

View File

@ -68,6 +68,16 @@ These flags affect the general behavior of the compiler.
This flag enables the IEEE1800-2012 standard, which includes
SystemVerilog.
* 2017
This flag enables the IEEE1800-2017 standard, which includes
SystemVerilog.
* 2023
This flag enables the IEEE1800-2023 standard, which includes
SystemVerilog.
* verilog-ams
This flag enables Verilog-AMS features that are supported by Icarus
@ -131,6 +141,18 @@ These flags affect the general behavior of the compiler.
containing an unsized constant number, and unsized constant numbers are
not truncated to integer width.
* strict-declaration/no-strict-declaration
* strict-net-var-declaration/no-strict-net-var-declaration
* strict-parameter-declaration/no-strict-parameter-declaration
The standards require that nets, variables, and parameters must be
declared lexically before they are used. Using -gno-strict-declaration
will allow using a data object before declaration, with a warning. The
warning can be suppressed with -Wno-declaration-after-use. The option
can be applied for nets and variables and for parameters separately.
* shared-loop-index/no-shared-loop-index
Enable or disable the exclusion of for-loop control variables from
@ -260,6 +282,7 @@ These flags affect the general behavior of the compiler.
-Wanachronisms
-Wimplicit
-Wimplicit-dimensions
-Wdeclaration-after-use
-Wmacro-replacement
-Wportbind
-Wselect-range
@ -288,6 +311,15 @@ These flags affect the general behavior of the compiler.
This flag is supported in release 10.1 or master branch snapshots after
2016-02-06.
* declaration-after-use
This enables warnings for declarations after use, when those are not
flagged as errors (enabled by default). Use no-declaration-after-use
to disable this.
This flag was added in version 14.0 or later (and is in the master branch
as of 2026-03-21).
* macro-redefinition
This enables warnings when a macro is redefined, even if the macro text

View File

@ -373,7 +373,5 @@ Next, compile with the command::
$ make
The configure generated the cross compiler flags, but there are a few
bits that need to be compiled with the native compiler. (version.exe
for example is used by the build process but is not installed.) The
The configure generated the cross compiler flags. The
configure script should have gotten all that right.

View File

@ -2,7 +2,7 @@
Reporting Issues
================
The developers of and contributers to Icarus Verilog use github to track
The developers of and contributors to Icarus Verilog use github to track
issues and to create patches for the product. If you believe you have found a
problem, use the Issues tracker at the
`Icarus Verilog github page <https://github.com/steveicarus/iverilog>`__.
@ -60,7 +60,7 @@ Bug reports with patches/PRs are very welcome. Please also add a new test case i
If you are editing the source, you should be using the latest
version from git. Please see the developer documentation for more
detailed instructions -- :doc:`Getting Started as a Contributer <getting_started>` .
detailed instructions -- :doc:`Getting Started as a Contributor <getting_started>` .
COPYRIGHT ISSUES

View File

@ -36,9 +36,12 @@ prefix = @prefix@
exec_prefix = @exec_prefix@
srcdir = @srcdir@
datarootdir = @datarootdir@
VERSION_MAJOR = @VERSION_MAJOR@
VERSION_MINOR = @VERSION_MINOR@
SUBDIRS = ivlpp vhdlpp vvp vpi tgt-null tgt-stub tgt-vvp \
tgt-vhdl tgt-vlog95 tgt-pcb tgt-blif tgt-sizer driver
tgt-vhdl tgt-vlog95 tgt-pcb tgt-blif tgt-sizer driver \
ivtest
# Only run distclean for these directories.
NOTUSED = tgt-fpga tgt-pal tgt-verilog
@ -48,11 +51,7 @@ else
NOTUSED += libveriuser cadpli
endif
ifeq (@MINGW32@,yes)
SUBDIRS += driver-vpi
else
NOTUSED += driver-vpi
endif
# To get the version headers to build correctly we only want to look
# for C++ files in the source directory. All other files will require
@ -67,9 +66,7 @@ bindir = @bindir@
libdir = @libdir@
# This is actually the directory where we install our own header files.
# It is a little different from the generic includedir.
includedir = @includedir@/iverilog$(suffix)
mandir = @mandir@
pdfdir = @docdir@
ivl_includedir = @includedir@/iverilog$(suffix)
dllib=@DLLIB@
@ -81,12 +78,14 @@ BUILDCC = @CC_FOR_BUILD@
BUILDEXT = @BUILD_EXEEXT@
CC = @CC@
CXX = @CXX@
ENV_VVP=@ENV_VVP@
INSTALL = @INSTALL@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
LEX = @LEX@
YACC = @YACC@
YACC_CONFLICT_FLAGS = -Werror=conflicts-sr -Werror=conflicts-rr
MAN = @MAN@
PS2PDF = @PS2PDF@
GROFF = @GROFF@
@ -131,7 +130,7 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
PGate.o PGenerate.o PModport.o PNamedItem.o PPackage.o PScope.o PSpec.o PTimingCheck.o \
PTask.o PUdp.o PWire.o Statement.o AStatement.o $M $(FF) $(TT)
all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
all: dep config.h _pli_types.h version_tag.h version_base.h ivl@EXEEXT@
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
# In the windows world, the installer will need a dosify program to
@ -142,34 +141,26 @@ dosify$(BUILDEXT): $(srcdir)/dosify.c
$(BUILDCC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o dosify$(BUILDEXT) $(srcdir)/dosify.c
endif
# This rule rules the compiler in the trivial hello.vl program to make
# sure the basics were compiled properly.
# This rule runs the compiler using the trivial hello.vl program to make sure
# the base programs are compiled properly.
check: all
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
rm -f check.vvp
test -r check.conf || cp $(srcdir)/check.conf .
driver/iverilog -B. -BMvpi -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
ifeq (@WIN32@,yes)
ifeq (@install_suffix@,)
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
else
# On Windows if we have a suffix we must run the vvp part of
# the test with a suffix since it was built/linked that way.
ln vvp/vvp.exe vvp/vvp$(suffix).exe
vvp/vvp$(suffix) -M- -M./vpi ./check.vvp | grep 'Hello, World'
rm vvp/vvp$(suffix).exe
endif
else
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
endif
driver/iverilog@EXEEXT@ -B. -BMvpi -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl && \
$(ENV_VVP) vvp/vvp$(suffix)@EXEEXT@ -M- -M./vpi ./check.vvp | grep 'Hello, World'
check-installed check-installed-vpi check-installed-vvp check-installed-vvp-py:
$(MAKE) -C ivtest $@
clean:
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
rm -f *.o parse.cc parse.h lexor.cc
rm -f ivl.exp iverilog-vpi.man iverilog-vpi.pdf iverilog-vpi.ps
rm -f ivl.exp
rm -f iverilog_man.ps iverilog_man.pdf iverilog_man_$(VERSION_MAJOR)_$(VERSION_MINOR).pdf
rm -f parse.output syn-rules.output dosify$(BUILDEXT) ivl@EXEEXT@ check.vvp
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc
rm -f lexor_keyword.cc libivl.a libvpi.a syn-rules.cc
rm -rf dep
rm -f version.exe
distclean: clean
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
@ -177,13 +168,14 @@ distclean: clean
rm -f Makefile config.status config.log config.cache
rm -f stamp-config-h config.h
rm -f stamp-_pli_types-h _pli_types.h
rm -f stamp-version_base-h version_base.h
ifneq (@srcdir@,.)
rm -f version_tag.h check.conf
rmdir $(SUBDIRS) $(NOTUSED)
endif
rm -rf autom4te.cache
cppcheck: $(O:.o=.cc) $(srcdir)/dosify.c $(srcdir)/version.c
cppcheck: $(O:.o=.cc) $(srcdir)/dosify.c
cppcheck --enable=all --std=c99 --std=c++11 -f \
--check-level=exhaustive \
--suppressions-list=$(srcdir)/cppcheck-global.sup \
@ -214,6 +206,11 @@ stamp-_pli_types-h: $(srcdir)/_pli_types.h.in config.status
./config.status _pli_types.h
_pli_types.h: stamp-_pli_types-h
stamp-version_base-h: $(srcdir)/version_base.h.in config.status
@rm -f $@
./config.status version_base.h
version_base.h: stamp-version_base-h
$(srcdir)/configure: $(srcdir)/configure.ac $(srcdir)/aclocal.m4
cd $(srcdir) && autoconf
@ -232,27 +229,7 @@ ivl@EXEEXT@: $O
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
endif
ifeq (@MINGW32@,no)
all: iverilog-vpi
iverilog-vpi: $(srcdir)/iverilog-vpi.sh Makefile
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
-e 's;@ENABLE_PLI1@;@LIBVERIUSER@;' \
-e 's;@SUFFIX@;$(suffix);' \
-e 's;@IVCC@;$(CC);' \
-e 's;@IVCXX@;$(CXX);' \
-e 's;@IVCFLAGS@;$(CFLAGS);' \
-e 's;@IVCXXFLAGS@;$(CXXFLAGS);' \
-e 's;@IVCTARGETFLAGS@;$(CTARGETFLAGS);' \
-e 's;@INCLUDEDIR@;$(includedir);' \
-e 's;@LIBDIR@;@libdir@;' $< > $@
chmod +x $@
endif
version.exe: $(srcdir)/version.c $(srcdir)/version_base.h version_tag.h
$(BUILDCC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o version.exe -I. -I$(srcdir) $(srcdir)/version.c
%.o: %.cc config.h
%.o: %.cc config.h | dep
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
mv $*.d dep/$*.d
@ -265,10 +242,10 @@ parse.o: parse.cc
# Use pattern rules to avoid parallel build issues (see pr3462585)
parse%cc parse%h: $(srcdir)/parse%y
$(YACC) --verbose -t -p VL --defines=parse.h -o parse.cc $<
$(YACC) --verbose $(YACC_CONFLICT_FLAGS) -t -p VL --defines=parse.h -o parse.cc $<
syn-rules.cc: $(srcdir)/syn-rules.y
$(YACC) --verbose -t -p syn_ -o $@ $<
$(YACC) --verbose $(YACC_CONFLICT_FLAGS) -t -p syn_ -o $@ $<
lexor.cc: $(srcdir)/lexor.lex
$(LEX) -s -t $< > $@
@ -278,22 +255,12 @@ lexor_keyword.o: lexor_keyword.cc parse.h
lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf
gperf -o -i 7 -C -k 1-4,6,9,$$ -H keyword_hash -N check_identifier -t $< > $@ || (rm -f $@ ; false)
iverilog-vpi.man: $(srcdir)/iverilog-vpi.man.in version.exe
./version.exe `head -1 $<`'\n' > $@
tail -n +2 $< >> $@
iverilog-vpi.ps: iverilog-vpi.man
$(MAN) -t ./$< > $@
iverilog-vpi.pdf: iverilog-vpi.ps
$(PS2PDF) $< $@
iverilog_man.ps: driver/iverilog.man vvp/vvp.man iverilog-vpi.man
iverilog_man.ps: driver/iverilog.man vvp/vvp.man driver-vpi/iverilog-vpi.man
$(GROFF) -man -rC1 -rD1 -T ps $^ > $@
iverilog_man.pdf: iverilog_man.ps version.exe
iverilog_man.pdf: iverilog_man.ps
$(PS2PDF) $< $@
cp $@ iverilog_man_`./version.exe %M_%n`.pdf
cp $@ iverilog_man_$(VERSION_MAJOR)_$(VERSION_MINOR).pdf
# For VERSION_TAG in driver/main.c, first try git-describe, then look for a
# release_tag.h file in the source tree (included in snapshots and releases),
@ -319,33 +286,6 @@ version_tag.h version:
echo '#define VERSION_TAG ""' > version_tag.h; \
fi
ifeq (@MINGW32@,yes)
ifeq ($(MAN),none)
INSTALL_DOC = installman
INSTALL_PDFDIR = $(prefix)
else
ifeq ($(PS2PDF),none)
INSTALL_DOC = installman
INSTALL_PDFDIR = $(prefix)
else
INSTALL_DOC = installpdf installman
INSTALL_PDFDIR = $(pdfdir)
all: dep iverilog-vpi.pdf
endif
endif
INSTALL_DOCDIR = $(mandir)/man1
else
INSTALL_DOC = installman
INSTALL_DOCDIR = $(mandir)/man1
INSTALL_PDFDIR = $(prefix)
endif
ifeq (@MINGW32@,yes)
WIN32_INSTALL =
else
WIN32_INSTALL = installwin32
endif
install: all installdirs installfiles
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
@ -357,37 +297,24 @@ F = ./ivl@EXEEXT@ \
$(srcdir)/sv_vpi_user.h \
$(srcdir)/vpi_user.h \
$(srcdir)/acc_user.h \
$(srcdir)/veriuser.h \
$(INSTALL_DOC) \
$(WIN32_INSTALL)
installwin32: ./iverilog-vpi installdirs
$(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)"
installman: iverilog-vpi.man installdirs
$(INSTALL_DATA) iverilog-vpi.man "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1"
installpdf: iverilog-vpi.pdf installdirs
$(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(pdfdir)/iverilog-vpi$(suffix).pdf"
$(srcdir)/veriuser.h
installfiles: $(F) | installdirs
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/ivl@EXEEXT@"
$(INSTALL_DATA) $(srcdir)/constants.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/constants.vams"
$(INSTALL_DATA) $(srcdir)/disciplines.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/disciplines.vams"
$(INSTALL_DATA) $(srcdir)/ivl_target.h "$(DESTDIR)$(includedir)/ivl_target.h"
$(INSTALL_DATA) ./_pli_types.h "$(DESTDIR)$(includedir)/_pli_types.h"
$(INSTALL_DATA) $(srcdir)/sv_vpi_user.h "$(DESTDIR)$(includedir)/sv_vpi_user.h"
$(INSTALL_DATA) $(srcdir)/vpi_user.h "$(DESTDIR)$(includedir)/vpi_user.h"
$(INSTALL_DATA) $(srcdir)/acc_user.h "$(DESTDIR)$(includedir)/acc_user.h"
$(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(includedir)/veriuser.h"
$(INSTALL_DATA) $(srcdir)/ivl_target.h "$(DESTDIR)$(ivl_includedir)/ivl_target.h"
$(INSTALL_DATA) ./_pli_types.h "$(DESTDIR)$(ivl_includedir)/_pli_types.h"
$(INSTALL_DATA) $(srcdir)/sv_vpi_user.h "$(DESTDIR)$(ivl_includedir)/sv_vpi_user.h"
$(INSTALL_DATA) $(srcdir)/vpi_user.h "$(DESTDIR)$(ivl_includedir)/vpi_user.h"
$(INSTALL_DATA) $(srcdir)/acc_user.h "$(DESTDIR)$(ivl_includedir)/acc_user.h"
$(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(ivl_includedir)/veriuser.h"
installdirs: $(srcdir)/mkinstalldirs
$(srcdir)/mkinstalldirs "$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(includedir)" \
"$(DESTDIR)$(ivl_includedir)" \
"$(DESTDIR)$(libdir)/ivl$(suffix)" \
"$(DESTDIR)$(libdir)/ivl$(suffix)/include" \
"$(DESTDIR)$(INSTALL_DOCDIR)" \
"$(DESTDIR)$(INSTALL_PDFDIR)"
"$(DESTDIR)$(libdir)/ivl$(suffix)/include"
uninstall:
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
@ -395,13 +322,13 @@ uninstall:
do rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/$$f"; done
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)/include"
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)"
for f in verilog$(suffix) iverilog-vpi$(suffix) gverilog$(suffix)@EXEEXT@; \
for f in verilog$(suffix) gverilog$(suffix)@EXEEXT@; \
do rm -f "$(DESTDIR)$(bindir)/$$f"; done
for f in ivl_target.h vpi_user.h _pli_types.h sv_vpi_user.h acc_user.h veriuser.h; \
do rm -f "$(DESTDIR)$(includedir)/$$f"; done
-test X$(suffix) = X || rmdir "$(DESTDIR)$(includedir)"
rm -f "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1" \
"$(DESTDIR)$(pdfdir)/iverilog-vpi$(suffix).pdf"
do rm -f "$(DESTDIR)$(ivl_includedir)/$$f"; done
-test X$(suffix) = X || rmdir "$(DESTDIR)$(ivl_includedir)"
-include $(patsubst %.o, dep/%.d, $O)
.PHONY: check-installed check-installed-vpi check-installed-vvp check-installed-vvp-py

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2022 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -21,13 +21,65 @@
# include "Module.h"
# include "PGate.h"
# include "PModport.h"
# include "PWire.h"
# include "parse_api.h"
# include "ivl_assert.h"
# include <iostream>
using namespace std;
list<Module::named_expr_t> Module::user_defparms;
Module::port_t::port_t()
: port_kind(P_SIGNAL), default_value(0), interface_unpacked_dimensions(0), lexical_pos(0)
{
}
bool resolve_interface_formal_port(const LineInfo*li, Design*des,
const Module::port_t*port,
interface_formal_port_t&res,
bool emit_errors)
{
ivl_assert(*li, port);
ivl_assert(*li, port->is_interface_port());
res = interface_formal_port_t();
map<perm_string,Module*>::const_iterator mod =
pform_modules.find(port->interface_type);
if (mod == pform_modules.end() || !mod->second->is_interface) {
if (emit_errors) {
cerr << li->get_fileline() << ": error: Interface port "
<< port->name << " uses unknown interface type `"
<< port->interface_type << "'." << endl;
des->errors += 1;
}
return false;
}
res.module = mod->second;
if (port->modport_name.str()) {
map<perm_string,PModport*>::const_iterator mp =
mod->second->modports.find(port->modport_name);
if (mp == mod->second->modports.end()) {
if (emit_errors) {
cerr << li->get_fileline() << ": error: Interface port "
<< port->name << " uses unknown modport `"
<< port->modport_name << "' of interface `"
<< port->interface_type << "'." << endl;
des->errors += 1;
}
return false;
}
res.modport = mp->second;
}
return true;
}
/* n is a permallocated string. */
Module::Module(LexicalScope*parent, perm_string n)
: PScopeExtra(n, parent)
@ -63,12 +115,18 @@ const vector<PEIdent*>& Module::get_port(unsigned idx) const
ivl_assert(*this, idx < ports.size());
static const vector<PEIdent*> zero;
if (ports[idx])
if (ports[idx] && !ports[idx]->is_interface_port())
return ports[idx]->expr;
else
return zero;
}
const Module::port_t* Module::get_port_info(unsigned idx) const
{
ivl_assert(*this, idx < ports.size());
return ports[idx];
}
unsigned Module::find_port(const char*name) const
{
ivl_assert(*this, name != 0);

View File

@ -1,7 +1,7 @@
#ifndef IVL_Module_H
#define IVL_Module_H
/*
* Copyright (c) 1998-2025 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -43,6 +43,7 @@ class PFunction;
class PWire;
class PProcess;
class Design;
class LineInfo;
class NetScope;
/*
@ -65,9 +66,25 @@ class Module : public PScopeExtra, public PNamedItem {
default value. */
public:
struct port_t {
enum port_kind_t { P_SIGNAL, P_INTERFACE };
port_t();
port_kind_t port_kind;
perm_string name;
std::vector<PEIdent*> expr;
PExpr*default_value;
/* Interface formal port metadata. For signal ports these
fields are empty/zero. The modport name is optional in the
representation, although the parser initially only accepts
the explicit interface_type.modport form. */
perm_string interface_type;
perm_string modport_name;
std::list<pform_range_t>*interface_unpacked_dimensions;
unsigned lexical_pos;
bool is_interface_port() const { return port_kind == P_INTERFACE; }
};
public:
@ -148,6 +165,7 @@ class Module : public PScopeExtra, public PNamedItem {
unsigned port_count() const;
const std::vector<PEIdent*>& get_port(unsigned idx) const;
const port_t* get_port_info(unsigned idx) const;
unsigned find_port(const char*name) const;
// Return port name ("" for undeclared port)
@ -181,4 +199,16 @@ class Module : public PScopeExtra, public PNamedItem {
Module& operator= (const Module&);
};
struct interface_formal_port_t {
interface_formal_port_t() : module(0), modport(0) { }
const Module*module;
const PModport*modport;
};
extern bool resolve_interface_formal_port(const LineInfo*li, Design*des,
const Module::port_t*port,
interface_formal_port_t&res,
bool emit_errors);
#endif /* IVL_Module_H */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2025 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -130,10 +130,11 @@ static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr)
return expr;
}
static NetExpr* calc_decay_time(NetExpr *rise, NetExpr *fall)
static const NetExpr *calc_decay_time(const NetExpr *rise,
const NetExpr *fall)
{
const NetEConst *c_rise = dynamic_cast<NetEConst*>(rise);
const NetEConst *c_fall = dynamic_cast<NetEConst*>(fall);
const NetEConst *c_rise = dynamic_cast<const NetEConst*>(rise);
const NetEConst *c_fall = dynamic_cast<const NetEConst*>(fall);
if (c_rise && c_fall) {
if (c_rise->value() < c_fall->value()) return rise;
else return fall;
@ -142,44 +143,43 @@ static NetExpr* calc_decay_time(NetExpr *rise, NetExpr *fall)
return 0;
}
void PDelays::eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time,
NetExpr*&fall_time,
NetExpr*&decay_time,
void PDelays::eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays,
bool as_nets_flag) const
{
assert(scope);
if (delay_[0]) {
rise_time = calculate_val(des, scope, delay_[0]);
NetExpr *rise = calculate_val(des, scope, delay_[0]);
if (as_nets_flag)
rise_time = make_delay_nets(des, scope, rise_time);
rise = make_delay_nets(des, scope, rise);
delays.rise = rise;
if (delay_[1]) {
fall_time = calculate_val(des, scope, delay_[1]);
NetExpr *fall = calculate_val(des, scope, delay_[1]);
if (as_nets_flag)
fall_time = make_delay_nets(des, scope, fall_time);
fall = make_delay_nets(des, scope, fall);
delays.fall = fall;
if (delay_[2]) {
decay_time = calculate_val(des, scope, delay_[2]);
NetExpr *decay = calculate_val(des, scope, delay_[2]);
if (as_nets_flag)
decay_time = make_delay_nets(des, scope,
decay_time);
decay = make_delay_nets(des, scope, decay);
delays.decay = decay;
} else {
// If this is zero then we need to do the min()
// at run time.
decay_time = calc_decay_time(rise_time, fall_time);
delays.decay = calc_decay_time(delays.rise,
delays.fall);
}
} else {
assert(delay_[2] == 0);
fall_time = rise_time;
decay_time = rise_time;
delays.fall = delays.rise;
delays.decay = delays.rise;
}
} else {
rise_time = 0;
fall_time = 0;
decay_time = 0;
delays.rise = nullptr;
delays.fall = nullptr;
delays.decay = nullptr;
}
}

View File

@ -1,7 +1,7 @@
#ifndef IVL_PDelays_H
#define IVL_PDelays_H
/*
* Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -27,6 +27,7 @@ class Design;
class NetScope;
class NetExpr;
class PExpr;
struct delay_exprs_t;
/*
* Various PForm objects can carry delays. These delays include rise,
@ -46,10 +47,7 @@ class PDelays {
unsigned delay_count() const;
void eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time,
NetExpr*&fall_time,
NetExpr*&decay_time,
void eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays,
bool as_nets_flag =false) const;
void dump_delays(std::ostream&out) const;

View File

@ -22,8 +22,9 @@
# include "PEvent.h"
PEvent::PEvent(perm_string n, unsigned lexical_pos)
: name_(n), lexical_pos_(lexical_pos)
: name_(n)
{
LineInfo::lexical_pos(lexical_pos);
}
PEvent::~PEvent()

View File

@ -41,15 +41,12 @@ class PEvent : public PNamedItem {
perm_string name() const;
unsigned lexical_pos() const { return lexical_pos_; }
void elaborate_scope(Design*des, NetScope*scope) const;
SymbolType symbol_type() const override;
private:
perm_string name_;
unsigned lexical_pos_;
private: // not implemented
PEvent(const PEvent&);

104
PExpr.cc
View File

@ -108,6 +108,16 @@ PEAssignPattern::~PEAssignPattern()
{
}
bool PEAssignPattern::has_aa_term(Design*des, NetScope*scope) const
{
bool flag = false;
for (const auto *parm : parms_) {
if (parm)
flag = parm->has_aa_term(des, scope) || flag;
}
return flag;
}
PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
: op_(op), left_(l), right_(r)
{
@ -129,31 +139,12 @@ bool PEBinary::has_aa_term(Design*des, NetScope*scope) const
return left_->has_aa_term(des, scope) || right_->has_aa_term(des, scope);
}
PECastSize::PECastSize(PExpr*si, PExpr*b)
: size_(si), base_(b)
PECast::PECast(PExpr *target, PExpr *base)
: target_(target), base_(base)
{
}
PECastSize::~PECastSize()
{
}
bool PECastSize::has_aa_term(Design *des, NetScope *scope) const
{
return base_->has_aa_term(des, scope);
}
PECastType::PECastType(data_type_t*t, PExpr*b)
: target_(t), base_(b)
{
target_type_ = nullptr;
}
PECastType::~PECastType()
{
}
bool PECastType::has_aa_term(Design *des, NetScope *scope) const
bool PECast::has_aa_term(Design *des, NetScope *scope) const
{
return base_->has_aa_term(des, scope);
}
@ -261,26 +252,60 @@ PECallFunction::PECallFunction(perm_string n, const list<named_pexpr_t> &parms)
{
}
PECallFunction::PECallFunction(PExpr* chain_prefix, const pform_name_t &method,
const vector<named_pexpr_t> &parms)
: path_(method), parms_(parms), chain_prefix_(chain_prefix), is_overridden_(false)
{
}
PECallFunction::PECallFunction(PExpr* chain_prefix, const pform_name_t &method,
const list<named_pexpr_t> &parms)
: path_(method), parms_(parms.begin(), parms.end()),
chain_prefix_(chain_prefix), is_overridden_(false)
{
}
void PECallFunction::set_with_clause(PExpr* with_expr)
{
delete with_expr_;
with_expr_ = with_expr;
}
PECallFunction::~PECallFunction()
{
delete chain_prefix_;
delete with_expr_;
}
void PECallFunction::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{
if (chain_prefix_) {
chain_prefix_->declare_implicit_nets(scope, type);
}
if (with_expr_) {
with_expr_->declare_implicit_nets(scope, type);
}
for (const auto &parm : parms_) {
if (parm.parm)
if (parm.parm) {
parm.parm->declare_implicit_nets(scope, type);
}
}
}
bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const
{
bool flag = false;
for (const auto &parm : parms_) {
if (parm.parm)
flag |= parm.parm->has_aa_term(des, scope);
if (chain_prefix_ && chain_prefix_->has_aa_term(des, scope)) {
return true;
}
return flag;
if (with_expr_ && with_expr_->has_aa_term(des, scope)) {
return true;
}
for (const auto &parm : parms_) {
if (parm.parm && parm.parm->has_aa_term(des, scope)) {
return true;
}
}
return false;
}
PEConcat::PEConcat(const list<PExpr*>&p, PExpr*r)
@ -362,19 +387,22 @@ const verireal& PEFNumber::value() const
return *value_;
}
PEIdent::PEIdent(const pform_name_t&that, unsigned lexical_pos)
: path_(that), lexical_pos_(lexical_pos), no_implicit_sig_(false)
PEIdent::PEIdent(const pform_name_t&that, unsigned lexical_pos,
bool no_implicit_sig)
: path_(that), no_implicit_sig_(no_implicit_sig)
{
LineInfo::lexical_pos(lexical_pos);
}
PEIdent::PEIdent(perm_string s, unsigned lexical_pos, bool no_implicit_sig)
: lexical_pos_(lexical_pos), no_implicit_sig_(no_implicit_sig)
: no_implicit_sig_(no_implicit_sig)
{
LineInfo::lexical_pos(lexical_pos);
path_.name.push_back(name_component_t(s));
}
PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that, unsigned lexical_pos)
: path_(pkg, that), lexical_pos_(lexical_pos), no_implicit_sig_(true)
PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that)
: path_(pkg, that), no_implicit_sig_(true)
{
}
@ -425,9 +453,8 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
ss = ss->parent_scope();
}
PWire*net = new PWire(name, lexical_pos_, type, NetNet::NOT_A_PORT);
net->set_file(get_file());
net->set_lineno(get_lineno());
PWire*net = new PWire(name, lexical_pos(), type, NetNet::NOT_A_PORT);
net->set_line(*this);
scope->wires[name] = net;
if (warn_implicit) {
cerr << get_fileline() << ": warning: implicit "
@ -439,7 +466,10 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
{
symbol_search_results sr;
if (!symbol_search(this, des, scope, path_, lexical_pos_, &sr))
if (!symbol_search(this, des, scope, path_, lexical_pos(), &sr))
return false;
if (sr.type_def)
return false;
// Class properties are not considered automatic since a non-blocking

219
PExpr.h
View File

@ -1,7 +1,7 @@
#ifndef IVL_PExpr_H
#define IVL_PExpr_H
/*
* Copyright (c) 1998-2025 Stephen Williams <steve@icarus.com>
* Copyright (c) 1998-2026 Stephen Williams <steve@icarus.com>
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@ -37,6 +37,7 @@ class NetExpr;
class NetScope;
class PPackage;
struct symbol_search_results;
class netclass_t;
/*
* The PExpr class hierarchy supports the description of
@ -50,6 +51,11 @@ class PExpr : public LineInfo {
// Mode values used by test_width() (see below for description).
enum width_mode_t { SIZED, UNSIZED, EXPAND, LOSSLESS, UPSIZE };
enum class type_elaboration_context_t {
DEFAULT,
CAST_TARGET
};
// Flag values that can be passed to elaborate_expr().
static const unsigned NO_FLAGS = 0x0;
static const unsigned NEED_CONST = 0x1;
@ -127,6 +133,17 @@ class PExpr : public LineInfo {
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
// Return true if this expression represents a type in this scope. This
// may cache lookup state for a subsequent elaborate_type() call.
virtual bool test_type(Design *des, NetScope *scope);
// Elaborate this expression as a type in a specific context. Return
// null if the expression is not a type or elaboration fails.
virtual ivl_type_t elaborate_type(
Design *des, NetScope *scope,
type_elaboration_context_t context =
type_elaboration_context_t::DEFAULT) const;
// After the test_width method is complete, these methods
// return valid results.
ivl_variable_type_t expr_type() const { return expr_type_; }
@ -208,6 +225,8 @@ class PEAssignPattern : public PExpr {
void dump(std::ostream&) const override;
virtual bool has_aa_term(Design*des, NetScope*scope) const override;
virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode) override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const override;
@ -342,8 +361,9 @@ class PEIdent : public PExpr {
public:
explicit PEIdent(perm_string, unsigned lexical_pos, bool no_implicit_sig=false);
explicit PEIdent(PPackage*pkg, const pform_name_t&name, unsigned lexical_pos);
explicit PEIdent(const pform_name_t&, unsigned lexical_pos);
explicit PEIdent(PPackage*pkg, const pform_name_t&name);
explicit PEIdent(const pform_name_t&, unsigned lexical_pos,
bool no_implicit_sig = false);
~PEIdent() override;
// Add another name to the string of hierarchy that is the
@ -373,6 +393,11 @@ class PEIdent : public PExpr {
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const override;
bool test_type(Design *des, NetScope *scope) override;
ivl_type_t elaborate_type(
Design *des, NetScope *scope,
type_elaboration_context_t context =
type_elaboration_context_t::DEFAULT) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid,
unsigned flags) const override;
@ -391,14 +416,23 @@ class PEIdent : public PExpr {
const pform_scoped_name_t& path() const { return path_; }
unsigned lexical_pos() const { return lexical_pos_; }
private:
// Type testing and elaboration normally happen as a pair. Preserve the
// lookup result between them, but only reuse it in the same scope.
struct type_lookup_t {
const NetScope *lookup_scope = nullptr;
NetScope *declaration_scope = nullptr;
typedef_t *type_def = nullptr;
bool valid = false;
};
pform_scoped_name_t path_;
unsigned lexical_pos_;
bool no_implicit_sig_;
type_lookup_t type_lookup_;
bool find_type_(Design *des, NetScope *scope,
struct symbol_search_results &search_results) const;
private:
// Common functions to calculate parts of part/bit
// selects. These methods return true if the expressions
// elaborate/calculate, or false if there is some sort of
@ -488,18 +522,12 @@ class PEIdent : public PExpr {
const NetScope*found_in,
ivl_type_t par_type,
unsigned expr_wid) const;
NetExpr*elaborate_expr_param_idx_up_(Design*des,
NetScope*scope,
const NetExpr*par,
const NetScope*found_in,
ivl_type_t par_type,
bool need_const) const;
NetExpr*elaborate_expr_param_idx_do_(Design*des,
NetScope*scope,
const NetExpr*par,
const NetScope*found_in,
ivl_type_t par_type,
bool need_const) const;
NetExpr*elaborate_expr_param_idx_up_do_(Design*des,
NetScope*scope,
const NetExpr*par,
const NetScope*found_in,
ivl_type_t par_type,
bool up, bool need_const) const;
NetExpr*elaborate_expr_net(Design*des,
NetScope*scope,
NetNet*net,
@ -517,16 +545,11 @@ class PEIdent : public PExpr {
NetESignal*net,
NetScope*found,
unsigned expr_wid) const;
NetExpr*elaborate_expr_net_idx_up_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found,
bool need_const) const;
NetExpr*elaborate_expr_net_idx_do_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found,
bool need_const) const;
NetExpr*elaborate_expr_net_idx_up_do_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found,
bool up, bool need_const) const;
NetExpr*elaborate_expr_net_bit_(Design*des,
NetScope*scope,
NetESignal*net,
@ -645,6 +668,12 @@ class PENull : public PExpr {
unsigned flags) const override;
};
// Internal marker for the '$' in a queue dimension.
class PEQueueDimension : public PExpr {
public:
void dump(std::ostream&) const override;
};
class PENumber : public PExpr {
public:
@ -690,12 +719,16 @@ class PEString : public PExpr {
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override;
virtual NetEConst*elaborate_expr(Design*des, NetScope*scope,
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const override;
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned) const override;
NetExpr *elaborate_expr_uarray_(Design *des, NetScope *scope,
const netuarray_t *uarray_type,
const std::vector<netrange_t> &dims,
unsigned int cur_dim) const;
private:
char*text_;
};
@ -710,8 +743,11 @@ class PETypename : public PExpr {
width_mode_t&mode) override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const override;
inline data_type_t* get_type() const { return data_type_; }
bool test_type(Design *des, NetScope *scope) override;
ivl_type_t elaborate_type(
Design *des, NetScope *scope,
type_elaboration_context_t context =
type_elaboration_context_t::DEFAULT) const override;
private:
data_type_t*data_type_;
@ -924,8 +960,22 @@ class PECallFunction : public PExpr {
explicit PECallFunction(const pform_name_t &n, const std::list<named_pexpr_t> &parms);
explicit PECallFunction(perm_string n, const std::list<named_pexpr_t> &parms);
// SystemVerilog: prefix().method(args) — prefix elaborates to a class handle.
explicit PECallFunction(PExpr* chain_prefix, const pform_name_t &method,
const std::vector<named_pexpr_t> &parms);
explicit PECallFunction(PExpr* chain_prefix, const pform_name_t &method,
const std::list<named_pexpr_t> &parms);
// SystemVerilog: q.find with (expr) — iterator "item"/"index" in expr.
void set_with_clause(PExpr* with_expr);
const PExpr* peek_with_clause(void) const { return with_expr_; }
~PECallFunction() override;
// For chained-call resolution (path is only the final method name).
const pform_scoped_name_t& peek_path(void) const { return path_; }
const PExpr* peek_chain_prefix(void) const { return chain_prefix_; }
virtual void dump(std::ostream &) const override;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override;
@ -944,6 +994,9 @@ class PECallFunction : public PExpr {
private:
pform_scoped_name_t path_;
std::vector<named_pexpr_t> parms_;
// If non-null, this call is prefix().tail_name(...) (SV method chain).
PExpr* chain_prefix_ = nullptr;
PExpr* with_expr_ = nullptr;
// For system functions.
bool is_overridden_;
@ -981,60 +1034,86 @@ class PECallFunction : public PExpr {
unsigned elaborate_arguments_(Design*des, NetScope*scope,
const NetFuncDef*def, bool need_const,
std::vector<NetExpr*>&parms,
unsigned parm_off) const;
unsigned parm_off,
const std::vector<named_pexpr_t>*src_parms = nullptr) const;
NetExpr* elaborate_class_method_net_(Design*des, NetScope*scope,
NetNet*net, const netclass_t*class_type,
perm_string method_name,
const std::vector<named_pexpr_t>*src_parms) const;
NetExpr* elaborate_class_method_net_this_(Design*des, NetScope*scope,
NetExpr* this_expr,
const netclass_t*class_type,
perm_string method_name,
const std::vector<named_pexpr_t>*src_parms) const;
NetExpr* elaborate_expr_method_chained_(Design*des, NetScope*scope,
symbol_search_results&search_results) const;
NetExpr* elaborate_expr_chain_(Design*des, NetScope*scope, unsigned flags) const;
unsigned test_width_chain_(Design*des, NetScope*scope, width_mode_t&mode);
};
/*
* Support the SystemVerilog cast to size.
*/
class PECastSize : public PExpr {
/* Support SystemVerilog size and type casts. */
class PECast : public PExpr {
public:
explicit PECastSize(PExpr*size, PExpr*base);
~PECastSize() override;
explicit PECast(PExpr *target, PExpr *base);
~PECast() override = default;
void dump(std::ostream &out) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid,
unsigned flags) const override;
NetExpr *elaborate_expr(Design *des, NetScope *scope,
ivl_type_t type, unsigned int flags) const override;
virtual bool has_aa_term(Design *des, NetScope *scope) const override;
NetExpr *elaborate_expr(Design *des, NetScope *scope,
unsigned int expr_wid,
unsigned int flags) const override;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override;
bool has_aa_term(Design *des, NetScope *scope) const override;
unsigned int test_width(Design *des, NetScope *scope,
width_mode_t &mode) override;
private:
PExpr* size_;
PExpr* base_;
};
NetExpr *elaborate_size_cast_(Design *des, NetScope *scope,
unsigned int expr_wid,
unsigned int target_width,
bool signed_flag,
unsigned int flags) const;
NetExpr *elaborate_type_cast_(Design *des, NetScope *scope,
unsigned int expr_wid,
ivl_type_t target_type,
unsigned int target_width,
bool signed_flag,
unsigned int flags) const;
/*
* Support the SystemVerilog cast to a different type.
*/
class PECastType : public PExpr {
enum class target_kind_t {
ERROR,
SIZE,
TYPE
};
public:
explicit PECastType(data_type_t*target, PExpr*base);
~PECastType() override;
struct target_info_t {
target_kind_t kind = target_kind_t::ERROR;
ivl_type_t type = nullptr;
unsigned int width = 0;
};
void dump(std::ostream &out) const override;
target_info_t resolve_target_(Design *des, NetScope *scope) const;
target_info_t target_for_scope_(Design *des, NetScope *scope) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const override;
std::unique_ptr<PExpr> target_;
std::unique_ptr<PExpr> base_;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags) const override;
virtual bool has_aa_term(Design *des, NetScope *scope) const override;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override;
private:
data_type_t* target_;
ivl_type_t target_type_;
PExpr* base_;
// Cast targets can depend on parameters in the instance scope. Width
// testing and expression elaboration run sequentially for one scope, so
// retain only the most recent result.
const NetScope *target_scope_ = nullptr;
target_info_t target_info_;
bool target_resolved_ = false;
};
/*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2025 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -41,29 +41,23 @@ void PGate::set_pins_(list<PExpr*>*pins)
}
PGate::PGate(perm_string name, list<PExpr*>*pins, const list<PExpr*>*del)
: name_(name), pins_(pins? pins->size() : 0), ranges_(0)
: name_(name), pins_(pins? pins->size() : 0), ranges_(nullptr)
{
if (pins) set_pins_(pins);
if (del) delay_.set_delays(del);
str0_ = IVL_DR_STRONG;
str1_ = IVL_DR_STRONG;
}
PGate::PGate(perm_string name, list<PExpr*>*pins, PExpr*del)
: name_(name), pins_(pins? pins->size() : 0), ranges_(0)
: name_(name), pins_(pins? pins->size() : 0), ranges_(nullptr)
{
if (pins) set_pins_(pins);
if (del) delay_.set_delay(del);
str0_ = IVL_DR_STRONG;
str1_ = IVL_DR_STRONG;
}
PGate::PGate(perm_string name, list<PExpr*>*pins)
: name_(name), pins_(pins? pins->size() : 0), ranges_(0)
: name_(name), pins_(pins? pins->size() : 0), ranges_(nullptr)
{
if (pins) set_pins_(pins);
str0_ = IVL_DR_STRONG;
str1_ = IVL_DR_STRONG;
}
PGate::~PGate()
@ -76,24 +70,14 @@ void PGate::set_ranges(list<pform_range_t>*ranges)
ranges_ = ranges;
}
ivl_drive_t PGate::strength0() const
drive_strength_t PGate::strength() const
{
return str0_;
return strength_;
}
void PGate::strength0(ivl_drive_t s)
void PGate::strength(const drive_strength_t &str)
{
str0_ = s;
}
ivl_drive_t PGate::strength1() const
{
return str1_;
}
void PGate::strength1(ivl_drive_t s)
{
str1_ = s;
strength_ = str;
}
void PGate::elaborate_scope(Design*, NetScope*) const
@ -109,15 +93,10 @@ void PGate::elaborate_scope(Design*, NetScope*) const
* numbers of expressions.
*/
void PGate::eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_expr,
NetExpr*&fall_expr,
NetExpr*&decay_expr,
void PGate::eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays,
bool as_net_flag) const
{
delay_.eval_delays(des, scope,
rise_expr, fall_expr, decay_expr,
as_net_flag);
delay_.eval_delays(des, scope, delays, as_net_flag);
}
unsigned PGate::delay_count() const

30
PGate.h
View File

@ -31,6 +31,8 @@
class PExpr;
class PUdp;
class Module;
struct delay_exprs_t;
struct drive_strength_t;
/*
* A PGate represents a Verilog gate. The gate has a name and other
@ -66,10 +68,7 @@ class PGate : public PNamedItem {
// This evaluates the delays as far as possible, but returns
// an expression, and do not signal errors.
void eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time,
NetExpr*&fall_time,
NetExpr*&decay_time,
void eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays,
bool as_net_flag =false) const;
unsigned delay_count() const;
@ -77,11 +76,9 @@ class PGate : public PNamedItem {
unsigned pin_count() const { return pins_.size(); }
PExpr*pin(unsigned idx) const { return pins_[idx]; }
ivl_drive_t strength0() const;
ivl_drive_t strength1() const;
drive_strength_t strength() const;
void strength0(ivl_drive_t);
void strength1(ivl_drive_t);
void strength(const drive_strength_t &str);
std::map<perm_string,PExpr*> attributes;
@ -109,7 +106,7 @@ class PGate : public PNamedItem {
std::list<pform_range_t>*ranges_;
ivl_drive_t str0_, str1_;
drive_strength_t strength_;
void set_pins_(std::list<PExpr*>*pins);
@ -133,7 +130,9 @@ class PGAssign : public PGate {
virtual void elaborate(Design*des, NetScope*scope) const override;
private:
void elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval) const;
void elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval,
const drive_strength_t &drive,
const delay_exprs_t &delays) const;
};
@ -236,11 +235,20 @@ class PGModule : public PGate {
unsigned nparms_;
friend class delayed_elaborate_scope_mod_instances;
void elaborate_mod_(Design*, Module*mod, NetScope*scope) const;
void elaborate_mod_(Design*, const Module*mod, NetScope*scope) const;
void elaborate_udp_(Design*, PUdp *udp, NetScope*scope) const;
void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const;
void elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*sc) const;
bool elaborate_sig_mod_(Design*des, NetScope*scope, const Module*mod) const;
bool bind_interface_ports_(Design*des, const Module*mod,
NetScope*parent_scope, NetScope*instance_scope,
const std::vector<PExpr*>&pins,
const std::vector<bool>&pins_fromwc) const;
bool match_module_ports_(Design*des, const Module*mod,
NetScope*scope,
std::vector<PExpr*>&pins,
std::vector<bool>&pins_fromwc,
std::vector<bool>&pins_is_explicitly_not_connected) const;
// Not currently used.
#if 0
bool elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const;

View File

@ -26,10 +26,12 @@
# include <list>
# include <map>
# include <valarray>
# include <vector>
# include "pform_types.h"
class Design;
class NetScope;
class PClass;
class PExpr;
class PFunction;
class PProcess;
@ -92,9 +94,11 @@ class PGenerate : public PNamedItem, public LexicalScope {
std::list<PGate*> gates;
void add_gate(PGate*);
// Tasks instantiated within this scheme.
// Definitions instantiated within this scheme.
std::map<perm_string,PTask*> tasks;
std::map<perm_string,PFunction*>funcs;
std::map<perm_string,PClass*> classes;
std::vector<PClass*> classes_lexical;
// Generate schemes can contain further generate schemes.
std::list<PGenerate*> generate_schemes;

View File

@ -48,6 +48,9 @@ std::ostream& operator << (std::ostream&o, PNamedItem::SymbolType st)
case PNamedItem::VAR:
o << "a variable";
break;
case PNamedItem::CLASS_PROPERTY:
o << "a class property";
break;
case PNamedItem::GENVAR:
o << "a genvar";
break;

View File

@ -31,7 +31,7 @@ class PNamedItem : virtual public LineInfo {
enum SymbolType { ANY, PARAM, NET, VAR, GENVAR, EVENT, TYPE, ENUM,
CLASS, FUNCTION, TASK, BLOCK, GENBLOCK, MODPORT,
PACKAGE, MODULE, PROGRAM, INTERFACE, PRIMITIVE,
INSTANCE };
INSTANCE, CLASS_PROPERTY };
explicit PNamedItem();
virtual ~PNamedItem() override;

View File

@ -1,7 +1,7 @@
#ifndef IVL_PScope_H
#define IVL_PScope_H
/*
* Copyright (c) 2008-2025 Stephen Williams (steve@icarus.com)
* Copyright (c) 2008-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -43,6 +43,16 @@ class PCallTask;
class Design;
class NetScope;
struct package_import_t : public LineInfo {
package_import_t() = default;
explicit package_import_t(PPackage *pkg) : package(pkg) { }
PPackage *package = nullptr;
// LineInfo records where the imported name became locally visible.
};
using package_import_map_t = std::map<perm_string, package_import_t>;
/*
* The PScope class is a base representation of an object that
* represents lexical scope. For example, a module, a function/task, a
@ -71,7 +81,7 @@ class LexicalScope {
// Symbols that are explicitly imported. This contains the package where
// the symbol has been decelared. When using exports, this might not be
// the same as the package where it has been imported from.
std::map<perm_string,PPackage*>explicit_imports;
package_import_map_t explicit_imports;
// Symbols that are explicitly imported. This contains the set of
// packages from which the symbol has been imported. When using exports
// the same identifier can be imported via multiple packages.
@ -86,7 +96,7 @@ class LexicalScope {
// later in the scope. So here we stash the potential imports for
// task and function calls. They will be added to the explicit
// imports if we don't find a local definition.
std::map<perm_string,PPackage*>possible_imports;
package_import_map_t possible_imports;
struct range_t {
// True if this is an exclude
@ -121,6 +131,8 @@ class LexicalScope {
bool overridable;
// Whether the parameter is a type parameter
bool type_flag = false;
// Type restriction for a type parameter
type_restrict_t type_restrict;
// The lexical position of the declaration
unsigned lexical_pos = 0;
@ -164,6 +176,7 @@ class LexicalScope {
unsigned generate_counter;
LexicalScope* parent_scope() const { return parent_; }
void set_parent_scope(LexicalScope *parent) { parent_ = parent; }
virtual bool var_init_needs_explicit_lifetime() const;

View File

@ -29,10 +29,12 @@ PWire::PWire(perm_string n,
NetNet::Type t,
NetNet::PortType pt,
PWSRType rt)
: name_(n), lexical_pos_(lp), type_(t), port_type_(pt), signed_(false),
: name_(n), type_(t), port_type_(pt), signed_(false),
port_set_(false), net_set_(false), is_scalar_(false),
error_cnt_(0), discipline_(0)
{
lexical_pos(lp);
switch (rt) {
case SR_PORT:
port_set_ = true;

View File

@ -63,8 +63,6 @@ class PWire : public PNamedItem {
// Return a hierarchical name.
perm_string basename() const;
unsigned lexical_pos() const { return lexical_pos_; }
NetNet::Type get_wire_type() const;
bool set_wire_type(NetNet::Type);
@ -102,7 +100,6 @@ class PWire : public PNamedItem {
private:
perm_string name_;
unsigned lexical_pos_;
NetNet::Type type_;
NetNet::PortType port_type_;
bool signed_;

View File

@ -396,8 +396,8 @@ PReturn::~PReturn()
delete expr_;
}
PTrigger::PTrigger(PPackage*pkg, const pform_name_t&ev, unsigned lexical_pos)
: event_(pkg, ev), lexical_pos_(lexical_pos)
PTrigger::PTrigger(PPackage*pkg, const pform_name_t&ev)
: event_(pkg, ev)
{
}
@ -405,8 +405,8 @@ PTrigger::~PTrigger()
{
}
PNBTrigger::PNBTrigger(const pform_name_t&ev, unsigned lexical_pos, PExpr*dly)
: event_(ev), lexical_pos_(lexical_pos), dly_(dly)
PNBTrigger::PNBTrigger(const pform_name_t&ev, PExpr*dly)
: event_(ev), dly_(dly)
{
}

View File

@ -40,6 +40,8 @@ class NetCAssign;
class NetDeassign;
class NetForce;
class NetScope;
class NetNet;
class netdarray_t;
/*
* The PProcess is the root of a behavioral process. Each process gets
@ -249,10 +251,12 @@ class PCallTask : public Statement {
NetProc*elaborate_method_(Design*des, NetScope*scope,
bool add_this_flag = false) const;
NetProc*elaborate_function_(Design*des, NetScope*scope) const;
NetProc *elaborate_function_(
Design *des, NetScope *scope, NetScope *func_scope) const;
NetProc*elaborate_void_function_(Design*des, NetScope*scope,
NetFuncDef*def) const;
NetProc *elaborate_non_void_function_(Design *des, NetScope *scope) const;
NetProc *elaborate_non_void_function_(Design *des, NetScope *scope,
const pform_name_t &path) const;
NetProc*elaborate_build_call_(Design*des, NetScope*scope,
NetScope*task, NetExpr*use_this) const;
@ -261,16 +265,42 @@ class PCallTask : public Statement {
perm_string method_name,
const char *sys_task_name,
const std::vector<perm_string> &parm_names = {}) const;
NetProc*elaborate_sys_task_property_method_(Design*des, NetScope*scope,
NetNet*net, int property_idx,
perm_string method_name,
const char *sys_task_name,
const std::vector<perm_string> &parm_names = {}) const;
NetProc*elaborate_queue_method_(Design*des, NetScope*scope,
NetNet*net,
perm_string method_name,
const char *sys_task_name,
const std::vector<perm_string> &parm_names) const;
NetProc*elaborate_queue_property_method_(Design*des, NetScope*scope,
NetNet*net, int property_idx,
perm_string method_name,
const char *sys_task_name,
const std::vector<perm_string> &parm_names) const;
NetProc*elaborate_method_func_(NetScope*scope,
NetNet*net,
ivl_type_t type,
perm_string method_name,
const char*sys_task_name) const;
NetProc*elaborate_method_property_func_(NetScope*scope,
NetNet*net, int property_idx,
ivl_type_t type,
perm_string method_name,
const char*sys_task_name) const;
NetProc*elaborate_queue_method_expr_(Design*des, NetScope*scope,
NetExpr*queue_base,
const netdarray_t*use_darray,
perm_string method_name,
const char *sys_task_name,
const std::vector<perm_string> &parm_names) const;
NetProc*elaborate_method_func_expr_(NetScope*scope,
NetExpr*queue_base,
ivl_type_t type,
perm_string method_name,
const char*sys_task_name) const;
bool test_task_calls_ok_(Design*des, const NetScope*scope) const;
PPackage*package_;
@ -632,7 +662,7 @@ class PReturn : public Statement {
class PTrigger : public Statement {
public:
explicit PTrigger(PPackage*pkg, const pform_name_t&ev, unsigned lexical_pos);
explicit PTrigger(PPackage*pkg, const pform_name_t&ev);
~PTrigger() override;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
@ -640,12 +670,11 @@ class PTrigger : public Statement {
private:
pform_scoped_name_t event_;
unsigned lexical_pos_;
};
class PNBTrigger : public Statement {
public:
explicit PNBTrigger(const pform_name_t&ev, unsigned lexical_pos, PExpr*dly);
explicit PNBTrigger(const pform_name_t&ev, PExpr*dly);
~PNBTrigger() override;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
@ -653,7 +682,6 @@ class PNBTrigger : public Statement {
private:
pform_name_t event_;
unsigned lexical_pos_;
PExpr*dly_;
};

411
aclocal.m4 vendored
View File

@ -1,392 +1,27 @@
# generated automatically by aclocal 1.18.1 -*- Autoconf -*-
# AX_ENABLE_SUFFIX
# ----------------
# Create the configure option --enable-suffix[=suffix] to generate suffix
# strings for the installed commands. This allows for shared installs of
# different builds. Remember to change the default suffix string to some
# value appropriate for the current version.
AC_DEFUN([AX_ENABLE_SUFFIX],
[AC_ARG_ENABLE([suffix],[AS_HELP_STRING([--enable-suffix],
[Use/set the installation command suffix])],
[true],[enable_suffix=no])
if test X$enable_suffix = Xyes; then
install_suffix='-dev'
elif test X$enable_suffix = Xno; then
install_suffix=''
else
install_suffix="$enable_suffix"
fi
AC_SUBST(install_suffix)
])# AX_ENABLE_SUFFIX
# Copyright (C) 1996-2025 Free Software Foundation, Inc.
# _AX_C_UNDERSCORES_MATCH_IFELSE(PATTERN, ACTION-IF-MATCH, ACTION-IF-NOMATCH)
# ------------------------------
# Sub-macro for AX_C_UNDERSCORES_LEADING and AX_C_UNDERSCORES_TRAILING.
# Unwarranted assumptions:
# - the object file produced by AC_COMPILE_IFELSE is called
# "conftest.$ac_objext"
# - the nm(1) utility or an equivalent is available, and its name
# is defined by the $NM variable.
AC_DEFUN([_AX_C_UNDERSCORES_MATCH_IF],
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([void underscore(void){}])],
[AS_IF([$NM conftest.$ac_objext|grep $1 >/dev/null 2>/dev/null],[$2],[$3])],
[AC_MSG_ERROR([underscore test crashed])]
)])
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
# AX_C_UNDERSCORES_LEADING
# ---------------------------------
# Check if symbol names in object files produced by C compiler have
# leading underscores. Define NEED_LU if so.
AC_DEFUN([AX_C_UNDERSCORES_LEADING],
[AC_CACHE_CHECK([for leading underscores], ax_cv_c_underscores_leading,
[_AX_C_UNDERSCORES_MATCH_IF([_underscore],
[AS_VAR_SET(ax_cv_c_underscores_leading, yes)],
[AS_VAR_SET(ax_cv_c_underscores_leading, no)])])
if test $ax_cv_c_underscores_leading = yes -a "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; then
AC_DEFINE([NEED_LU], [1], [Symbol names in object files produced by C compiler have leading underscores.])
fi
])# AX_C_UNDERSCORES_LEADING
# AX_C_UNDERSCORES_TRAILING
# ---------------------------------
# Check if symbol names in object files produced by C compiler have
# trailing underscores. Define NEED_TU if so.
AC_DEFUN([AX_C_UNDERSCORES_TRAILING],
[AC_CACHE_CHECK([for trailing underscores], ax_cv_c_underscores_trailing,
[_AX_C_UNDERSCORES_MATCH_IF([underscore_],
[AS_VAR_SET(ax_cv_c_underscores_trailing, yes)],
[AS_VAR_SET(ax_cv_c_underscores_trailing, no)])])
if test $ax_cv_c_underscores_trailing = yes; then
AC_DEFINE([NEED_TU], [1], [Symbol names in object files produced by C compiler have trailing underscores.])
fi
])# AX_C_UNDERSCORES_TRAILING
# AX_WIN32
# --------
# Combined check for several flavors of Microsoft Windows so
# their "issues" can be dealt with
AC_DEFUN([AX_WIN32],
[AC_MSG_CHECKING([for Microsoft Windows])
AC_REQUIRE([AC_CANONICAL_HOST]) []dnl
case $host_os in
*cygwin*) MINGW32=no; WIN32=yes;;
*mingw*) MINGW32=yes; WIN32=yes;;
*) MINGW32=no; WIN32=no;;
esac
AC_SUBST(MINGW32)
AC_SUBST(WIN32)
AC_MSG_RESULT($WIN32)
if test $WIN32 = yes; then
AC_MSG_CHECKING([for MinGW])
AC_MSG_RESULT($MINGW32)
fi
])# AX_WIN32
# AX_LD_EXTRALIBS
# ---------------
# mingw needs to link with libiberty.a, but cygwin alone can't tolerate it
AC_DEFUN([AX_LD_EXTRALIBS],
[AC_MSG_CHECKING([for extra libs needed])
EXTRALIBS=
case "${host}" in
*-*-cygwin* )
if test "$MINGW32" = "yes"; then
EXTRALIBS="-liberty"
fi
;;
esac
AC_SUBST(EXTRALIBS)
AC_MSG_RESULT($EXTRALIBS)
])# AX_LD_EXTRALIBS
# AX_LD_SHAREDLIB_OPTS
# --------------------
# linker options when building a shared library
AC_DEFUN([AX_LD_SHAREDLIB_OPTS],
[AC_MSG_CHECKING([for shared library link flag])
shared=-shared
case "${host}" in
*-*-cygwin*)
shared="-shared -Wl,--enable-auto-image-base"
;;
*-*-mingw*)
shared="-shared -Wl,--enable-auto-image-base"
;;
*-*-hpux*)
shared="-b"
;;
*-*-darwin1.[0123])
shared="-bundle -undefined dynamic_lookup"
;;
*-*-darwin*)
shared="-bundle -undefined dynamic_lookup -flat_namespace"
;;
*-*-solaris*)
if test ${using_sunpro_c} = 1
then
shared="-G"
fi
;;
esac
AC_SUBST(shared)
AC_MSG_RESULT($shared)
])# AX_LD_SHAREDLIB_OPTS
# AX_C_PICFLAG
# ------------
# The -fPIC flag is used to tell the compiler to make position
# independent code. It is needed when making shared objects.
AC_DEFUN([AX_C_PICFLAG],
[AC_MSG_CHECKING([for flag to make position independent code])
PICFLAG=-fPIC
case "${host}" in
*-*-cygwin*)
PICFLAG=
;;
*-*-mingw*)
PICFLAG=
;;
*-*-hpux*)
PICFLAG=+z
;;
*-*-solaris*)
if test ${using_sunpro_c} = 1
then
PICFLAG=-G
fi
;;
esac
AC_SUBST(PICFLAG)
AC_MSG_RESULT($PICFLAG)
])# AX_C_PICFLAG
# AX_LD_RDYNAMIC
# --------------
# The -rdynamic flag is used by iverilog when compiling the target,
# to know how to export symbols of the main program to loadable modules
# that are brought in by -ldl
AC_DEFUN([AX_LD_RDYNAMIC],
[AC_MSG_CHECKING([for -rdynamic compiler flag])
rdynamic=-rdynamic
case "${host}" in
*-*-netbsd*)
rdynamic="-Wl,--export-dynamic"
;;
*-*-openbsd*)
rdynamic="-Wl,--export-dynamic"
;;
*-*-solaris*)
rdynamic=""
;;
*-*-cygwin*)
rdynamic=""
;;
*-*-mingw*)
rdynamic=""
;;
*-*-hpux*)
rdynamic="-E"
;;
*-*-darwin*)
rdynamic="-Wl,-all_load"
strip_dynamic="-SX"
;;
esac
AC_SUBST(rdynamic)
AC_MSG_RESULT($rdynamic)
AC_SUBST(strip_dynamic)
# since we didn't tell them we're "checking", no good place to tell the answer
# AC_MSG_RESULT($strip_dynamic)
])# AX_LD_RDYNAMIC
# AX_C99_STRTOD
# -------------
AC_DEFUN([AX_C99_STRTOD],
[# On MinGW we need to jump through hoops to get a C99 compliant strtod().
# mingw-w64 doesn't need this, and the 64-bit version doesn't support it.
case "${host}" in
x86_64-w64-mingw32)
;;
aarch64-w64-mingw32)
;;
*-*-mingw32)
LDFLAGS+=" -Wl,--undefined=___strtod,--wrap,strtod,--defsym,___wrap_strtod=___strtod"
;;
esac
])# AX_C99_STRTOD
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp file name are based on the header name.
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
# loop where config.status creates the headers, so we can generate
# our stamp files there.
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
[
_config_header=$1
_stamp_name=stamp-`expr //$_config_header : '.*/\([[^./]]*\)\.[[^./]]*$'`-h
echo "timestamp for $_config_header" > `AS_DIRNAME(["$_config_header"])`/[]$_stamp_name
]) #_AC_AM_CONFIG_HEADER_HOOK
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PROG_CC_FOR_BUILD
#
# DESCRIPTION
#
# This macro searches for a C compiler that generates native executables,
# that is a C compiler that surely is not a cross-compiler. This can be
# useful if you have to generate source code at compile-time like for
# example GCC does.
#
# The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything
# needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD).
# The value of these variables can be overridden by the user by specifying
# a compiler with an environment variable (like you do for standard CC).
#
# It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object
# file extensions for the build platform, and GCC_FOR_BUILD to `yes' if
# the compiler we found is GCC. All these variables but GCC_FOR_BUILD are
# substituted in the Makefile.
#
# LICENSE
#
# Copyright (c) 2008 Paolo Bonzini <bonzini@gnu.org>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 18
AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD])
AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_PROG_CPP])dnl
AC_REQUIRE([AC_CANONICAL_BUILD])dnl
dnl Use the standard macros, but make them use other variable names
dnl
pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl
pushdef([ac_cv_prog_cc_c89], ac_cv_build_prog_cc_c89)dnl
pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl
pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl
pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl
pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl
pushdef([ac_cv_c_compiler_gnu], ac_cv_build_c_compiler_gnu)dnl
pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl
pushdef([ac_cv_objext], ac_cv_build_objext)dnl
pushdef([ac_exeext], ac_build_exeext)dnl
pushdef([ac_objext], ac_build_objext)dnl
pushdef([CC], CC_FOR_BUILD)dnl
pushdef([CPP], CPP_FOR_BUILD)dnl
pushdef([GCC], GCC_FOR_BUILD)dnl
pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl
pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl
pushdef([EXEEXT], BUILD_EXEEXT)dnl
pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl
pushdef([OBJEXT], BUILD_OBJEXT)dnl
pushdef([host], build)dnl
pushdef([host_alias], build_alias)dnl
pushdef([host_cpu], build_cpu)dnl
pushdef([host_vendor], build_vendor)dnl
pushdef([host_os], build_os)dnl
pushdef([ac_cv_host], ac_cv_build)dnl
pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl
pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl
pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl
pushdef([ac_cv_host_os], ac_cv_build_os)dnl
pushdef([ac_tool_prefix], ac_build_tool_prefix)dnl
pushdef([am_cv_CC_dependencies_compiler_type], am_cv_build_CC_dependencies_compiler_type)dnl
pushdef([am_cv_prog_cc_c_o], am_cv_build_prog_cc_c_o)dnl
pushdef([cross_compiling], cross_compiling_build)dnl
cross_compiling_build=no
ac_build_tool_prefix=
AS_IF([test -n "$build"], [ac_build_tool_prefix="$build-"],
[test -n "$build_alias"],[ac_build_tool_prefix="$build_alias-"])
AC_LANG_PUSH([C])
AC_PROG_CC
_AC_COMPILER_EXEEXT
_AC_COMPILER_OBJEXT
AC_PROG_CPP
dnl Restore the old definitions
dnl
popdef([cross_compiling])dnl
popdef([am_cv_prog_cc_c_o])dnl
popdef([am_cv_CC_dependencies_compiler_type])dnl
popdef([ac_tool_prefix])dnl
popdef([ac_cv_host_os])dnl
popdef([ac_cv_host_vendor])dnl
popdef([ac_cv_host_cpu])dnl
popdef([ac_cv_host_alias])dnl
popdef([ac_cv_host])dnl
popdef([host_os])dnl
popdef([host_vendor])dnl
popdef([host_cpu])dnl
popdef([host_alias])dnl
popdef([host])dnl
popdef([OBJEXT])dnl
popdef([LDFLAGS])dnl
popdef([EXEEXT])dnl
popdef([CPPFLAGS])dnl
popdef([CFLAGS])dnl
popdef([GCC])dnl
popdef([CPP])dnl
popdef([CC])dnl
popdef([ac_objext])dnl
popdef([ac_exeext])dnl
popdef([ac_cv_objext])dnl
popdef([ac_cv_exeext])dnl
popdef([ac_cv_c_compiler_gnu])dnl
popdef([ac_cv_prog_cc_g])dnl
popdef([ac_cv_prog_cc_cross])dnl
popdef([ac_cv_prog_cc_works])dnl
popdef([ac_cv_prog_cc_c89])dnl
popdef([ac_cv_prog_gcc])dnl
popdef([ac_cv_prog_CPP])dnl
dnl restore global variables ac_ext, ac_cpp, ac_compile,
dnl ac_link, ac_compiler_gnu (dependant on the current
dnl language after popping):
AC_LANG_POP([C])
dnl Finally, set Makefile variables
dnl
AC_SUBST(BUILD_EXEEXT)dnl
AC_SUBST(BUILD_OBJEXT)dnl
AC_SUBST([CFLAGS_FOR_BUILD])dnl
AC_SUBST([CPPFLAGS_FOR_BUILD])dnl
AC_SUBST([LDFLAGS_FOR_BUILD])dnl
])
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
m4_include([m4/_ac_am_config_header_hook.m4])
m4_include([m4/_ax_c_underscores_match_if.m4])
m4_include([m4/ax_c99_strtod.m4])
m4_include([m4/ax_c_picflag.m4])
m4_include([m4/ax_c_underscores_leading.m4])
m4_include([m4/ax_c_underscores_trailing.m4])
m4_include([m4/ax_cxx_compile_stdcxx.m4])
m4_include([m4/ax_enable_suffix.m4])
m4_include([m4/ax_ld_extralibs.m4])
m4_include([m4/ax_ld_rdynamic.m4])
m4_include([m4/ax_ld_sharedlib_opts.m4])
m4_include([m4/ax_prog_cc_for_build.m4])
m4_include([m4/ax_win32.m4])

View File

@ -71,7 +71,7 @@ Makefile: $(srcdir)/Makefile.in ../config.status
dep:
mkdir dep
%.o: %.c
%.o: %.c | dep
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $<
mv $*.d dep

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2003-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -53,7 +53,7 @@ static void thunker_register(void)
strncpy(module, cp, bp-cp);
module[bp-cp] = 0;
mod = ivl_dlopen(module);
mod = ivl_dlopen(module, false);
if (mod == 0) {
vpi_printf("%s link: %s\n", vlog_info.argv[idx], dlerror());
free(module);

View File

@ -4,4 +4,4 @@ nullPointerOutOfMemory:cadpli.c:53
nullPointerOutOfMemory:cadpli.c:54
// Unused function
unusedFunction:ivl_dlfcn.h:73
unusedFunction:ivl_dlfcn.h:87

View File

@ -1,94 +0,0 @@
#ifndef IVL_ivl_dlfcn_H
#define IVL_ivl_dlfcn_H
/*
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#if defined(__MINGW32__)
# include <windows.h>
# include <stdio.h>
typedef void * ivl_dll_t;
#elif defined(HAVE_DLFCN_H)
# include <dlfcn.h>
typedef void* ivl_dll_t;
#elif defined(HAVE_DL_H)
# include <dl.h>
typedef shl_t ivl_dll_t;
#endif
#if defined(__MINGW32__)
static __inline__ ivl_dll_t ivl_dlopen(const char *name)
{ return (void *)LoadLibrary(name); }
static __inline__ void *ivl_dlsym(ivl_dll_t dll, const char *nm)
{ return (void *)GetProcAddress((HINSTANCE)dll,nm);}
static __inline__ void ivl_dlclose(ivl_dll_t dll)
{ (void)FreeLibrary((HINSTANCE)dll);}
static __inline__ const char *dlerror(void)
{
static char msg[256];
unsigned long err = GetLastError();
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &msg,
sizeof(msg) - 1,
NULL
);
return msg;
}
#elif defined(HAVE_DLFCN_H)
static __inline__ ivl_dll_t ivl_dlopen(const char*name)
{ return dlopen(name,RTLD_LAZY); }
static __inline__ void* ivl_dlsym(ivl_dll_t dll, const char*nm)
{
void*sym = dlsym(dll, nm);
/* Not found? try without the leading _ */
if (sym == 0 && nm[0] == '_')
sym = dlsym(dll, nm+1);
return sym;
}
static __inline__ void ivl_dlclose(ivl_dll_t dll)
{ dlclose(dll); }
#elif defined(HAVE_DL_H)
static __inline__ ivl_dll_t ivl_dlopen(const char*name)
{ return shl_load(name, BIND_IMMEDIATE, 0); }
static __inline__ void* ivl_dlsym(ivl_dll_t dll, const char*nm)
{
void*sym;
int rc = shl_findsym(&dll, nm, TYPE_PROCEDURE, &sym);
return (rc == 0) ? sym : 0;
}
static __inline__ void ivl_dlclose(ivl_dll_t dll)
{ shl_unload(dll); }
static __inline__ const char*dlerror(void)
{ return strerror( errno ); }
#endif
#endif /* IVL_ivl_dlfcn_H */

View File

@ -1,7 +1,7 @@
#ifndef IVL_compiler_H
#define IVL_compiler_H
/*
* Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -104,6 +104,9 @@ extern bool warn_sens_entire_arr;
/* Warn about level-appropriate anachronisms. */
extern bool warn_anachronisms;
/* Warn about declaration after use (unless flaged as errors). */
extern bool warn_decl_after_use;
/* Warn about nets that are references but not driven. */
extern bool warn_floating_nets;
@ -162,6 +165,8 @@ enum generation_t {
GN_VER2005_SV = 5,
GN_VER2009 = 6,
GN_VER2012 = 7,
GN_VER2017 = 8,
GN_VER2023 = 9,
GN_DEFAULT = 4
};
@ -210,6 +215,20 @@ extern bool gn_strict_expr_width_flag;
loop. */
extern bool gn_shared_loop_index_flag;
/* If this flag is true (default), then parameters must be declared before
use. `-gno-strict[-parameter]-declaration` allows to use parameters before
declaration, as prior to version 13.
A warning is emited with -Wdeclaration-after-use (default).
*/
extern bool gn_strict_parameter_declaration;
/* If this flag is true (default), then nets and variablesmust be declared
before use. `-gno-strict[-net-var]-declaration` allows to use nets and
variables before declaration, as prior to version 13.
A warning is emited with -Wdeclaration-after-use (default).
*/
extern bool gn_strict_net_var_declaration;
static inline bool gn_system_verilog(void)
{
if (generation_flag >= GN_VER2005_SV)

17
config.guess vendored
View File

@ -1,10 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright 1992-2025 Free Software Foundation, Inc.
# Copyright 1992-2026 Free Software Foundation, Inc.
# shellcheck disable=SC2006,SC2268 # see below for rationale
timestamp='2025-07-10'
timestamp='2026-05-17'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@ -60,7 +60,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright 1992-2025 Free Software Foundation, Inc.
Copyright 1992-2026 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -150,7 +150,7 @@ UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
case $UNAME_SYSTEM in
Linux|GNU|GNU/*)
Ironclad|Linux|GNU|GNU/*)
LIBC=unknown
set_cc_for_build
@ -167,6 +167,8 @@ Linux|GNU|GNU/*)
LIBC=gnu
#elif defined(__LLVM_LIBC__)
LIBC=llvm
#elif defined(__mlibc__)
LIBC=mlibc
#else
#include <stdarg.h>
/* First heuristic to detect musl libc. */
@ -1186,6 +1188,9 @@ EOF
sparc:Linux:*:* | sparc64:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
sw_64:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
tile*:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
@ -1598,10 +1603,10 @@ EOF
GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
;;
x86_64:[Ii]ronclad:*:*|i?86:[Ii]ronclad:*:*)
GUESS=$UNAME_MACHINE-pc-ironclad-mlibc
GUESS=$UNAME_MACHINE-pc-ironclad-$LIBC
;;
*:[Ii]ronclad:*:*)
GUESS=$UNAME_MACHINE-unknown-ironclad-mlibc
GUESS=$UNAME_MACHINE-unknown-ironclad-$LIBC
;;
esac

11
config.sub vendored
View File

@ -1,10 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright 1992-2025 Free Software Foundation, Inc.
# Copyright 1992-2026 Free Software Foundation, Inc.
# shellcheck disable=SC2006,SC2268,SC2162 # see below for rationale
timestamp='2025-07-10'
timestamp='2026-05-17'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@ -76,7 +76,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright 1992-2025 Free Software Foundation, Inc.
Copyright 1992-2026 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -1432,6 +1432,7 @@ case $cpu-$vendor in
| sparcv9v \
| spu \
| sv1 \
| sw_64 \
| sx* \
| tahoe \
| thumbv7* \
@ -1525,7 +1526,7 @@ EOF
;;
ironclad*)
kernel=ironclad
os=`echo "$basic_os" | sed -e 's|ironclad|mlibc|'`
os=`echo "$basic_os" | sed -e 's|ironclad|gnu|'`
;;
linux*)
kernel=linux
@ -2220,7 +2221,7 @@ case $kernel-$os-$obj in
;;
uclinux-uclibc*- | uclinux-gnu*- )
;;
ironclad-mlibc*-)
ironclad-gnu*- | ironclad-mlibc*- )
;;
managarm-mlibc*- | managarm-kernel*- )
;;

View File

@ -1,6 +1,35 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT
AC_CONFIG_MACRO_DIRS([m4])
dnl Define project version
m4_define([VER_MAJOR], [14])
m4_define([VER_MINOR], [0])
m4_define([VER_EXTRA], [devel])
dnl define libvvp ABI version
m4_define([LIBVVP_SOVERSION], [1])
AC_INIT([iverilog], [VER_MAJOR.VER_MINOR (VER_EXTRA)])
AC_SUBST([VERSION_MAJOR], [VER_MAJOR])
AC_SUBST([VERSION_MINOR], [VER_MINOR])
AC_SUBST([VERSION_EXTRA], [" (VER_EXTRA)"])
AC_SUBST([VERSION], ["VER_MAJOR.VER_MINOR (VER_EXTRA)"])
# used in res.rc
AC_SUBST([PRODUCTVERSION], ["VER_MAJOR,VER_MINOR,0,0"])
# setup libvvp soversion, which depends on abi not package version
AC_SUBST([LIBVVP_SOVERSION], [LIBVVP_SOVERSION])
# setup libvvp version
AC_SUBST([LIBVVP_VERSION], [LIBVVP_SOVERSION.VER_MAJOR.VER_MINOR])
AC_CONFIG_SRCDIR([netlist.h])
# Need a stamp file like the other header files
AC_CONFIG_FILES([version_base.h],[
_config_header=version_base.h
_stamp_name=stamp-`expr //$_config_header : '.*/\([[^./]]*\)\.[[^./]]*$'`-h
echo "timestamp for $_config_header" > `AS_DIRNAME(["$_config_header"])`/[]$_stamp_name
])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_HEADERS([_pli_types.h])
AC_CONFIG_HEADERS([vhdlpp/vhdlpp_config.h])
@ -18,6 +47,10 @@ AX_PROG_CC_FOR_BUILD
AC_PREREQ([2.62])
m4_version_prereq([2.70], [], [AC_PROG_CC_C99])
AC_PROG_CXX
# Require C++11 (avoid newer defaults like C++23 from newer toolchains)
AX_CXX_COMPILE_STDCXX(11, noext, mandatory)
AC_PROG_RANLIB
AC_CHECK_TOOL(LD, ld, false)
AC_CHECK_TOOL(AR, ar, false)
@ -65,6 +98,20 @@ AC_SUBST(EXEEXT)
# Combined check for Microsoft-related bogosities; sets WIN32 if found
AX_WIN32
# Detect which directory/file separator to use
AC_MSG_CHECKING([for directory/file separator])
AS_CASE([$host_os:$MSYSTEM],
[*mingw*:UCRT64|*mingw*:MINGW64|*mingw*:MINGW32|*mingw*:CLANG64|*mingw*:CLANGARM64], [
PATH_SEP=\\\\
],
[
PATH_SEP=/
]
)
AC_MSG_RESULT([$PATH_SEP])
AC_SUBST([PATH_SEP])
# Check to see if we are using the Sun compiler. If so then configure
# some of the flags to match the Sun compiler syntax. This is also used
# in the aclocal.m4 file to configure the flags used to build and link
@ -184,7 +231,14 @@ AC_FUNC_FSEEKO
# Build VVP as a library and stub
AC_ARG_ENABLE([libvvp],
[AS_HELP_STRING([--enable-libvvp], [build VVP as a shared library])],
[AC_SUBST(LIBVVP, yes)],[])
[enable_libvvp=yes],
[enable_libvvp=no])
AC_SUBST([LIBVVP], [$enable_libvvp])
AS_IF([test "x$enable_libvvp" = "xyes"],
[AC_MSG_NOTICE([Building with libvvp support enabled])],
[AC_MSG_NOTICE([Building with libvvp support disabled])])
AC_ARG_ENABLE([libveriuser],
[AS_HELP_STRING([--enable-libveriuser], [include support for PLI 1 (deprecated)])],
@ -269,6 +323,27 @@ case "${host}" in
;;
esac
# Setup test environment for running vvp from build directory
VVP_BUILDDIR="$(pwd)/vvp"
case "$host_os" in
linux*)
ENV_VVP="LD_LIBRARY_PATH=$VVP_BUILDDIR"
;;
*bsd*)
ENV_VVP="LD_LIBRARY_PATH=$VVP_BUILDDIR"
;;
darwin*)
ENV_VVP="DYLD_LIBRARY_PATH=$VVP_BUILDDIR"
;;
*)
# Since the libvvp DLL is located in the same directory as the
# vvp executable, no action is required here
ENV_VVP=""
;;
esac
AC_SUBST([ENV_VVP])
# Do some more operating system specific setup. We put the file64_support
# define in a substitution instead of simply a define because there
# are source files (namely lxt support files) that don't include any
@ -366,5 +441,32 @@ then
AC_MSG_ERROR(cannot configure white space in libdir: $libdir)
fi
AC_MSG_RESULT(ok)
AC_CONFIG_FILES([Makefile ivlpp/Makefile vhdlpp/Makefile vvp/Makefile vpi/Makefile driver/Makefile driver-vpi/Makefile cadpli/Makefile libveriuser/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-vvp/Makefile tgt-vhdl/Makefile tgt-fpga/Makefile tgt-verilog/Makefile tgt-pal/Makefile tgt-vlog95/Makefile tgt-pcb/Makefile tgt-blif/Makefile tgt-sizer/Makefile])
AC_CONFIG_FILES([
Makefile
cadpli/Makefile
driver-vpi/Makefile
driver-vpi/iverilog-vpi.man
driver-vpi/res.rc
driver/Makefile
driver/iverilog.man
ivlpp/Makefile
ivtest/Makefile
libveriuser/Makefile
tgt-blif/Makefile
tgt-fpga/Makefile
tgt-null/Makefile
tgt-pal/Makefile
tgt-pcb/Makefile
tgt-sizer/Makefile
tgt-stub/Makefile
tgt-verilog/Makefile
tgt-vhdl/Makefile
tgt-vlog95/Makefile
tgt-vvp/Makefile
vhdlpp/Makefile
vpi/Makefile
vvp/Makefile
vvp/libvvp.pc
vvp/vvp.man
])
AC_OUTPUT

View File

@ -10,47 +10,49 @@ nullPointerOutOfMemory
ctuuninitvar:parse_misc.cc:61
// Skip strdup() not constant.
constVariablePointer:main.cc:400
constVariablePointer:main.cc:404
constVariablePointer:main.cc:654
constVariablePointer:main.cc:421
constVariablePointer:main.cc:425
constVariablePointer:main.cc:675
// const auto should be const
constVariablePointer:elab_expr.cc:344
constVariablePointer:elab_expr.cc:413
constVariablePointer:elab_expr.cc:628
constVariablePointer:elab_expr.cc:631
constVariablePointer:elab_expr.cc:700
// The reference cannot be const since it is updated in the calling function.
constParameterReference:net_udp.cc:37
// These cannot be static since they access object data
functionStatic:net_link.cc:178
functionStatic:net_link.cc:183
functionStatic:net_link.cc:188
functionStatic:net_link.cc:193
functionStatic:net_link.cc:184
functionStatic:net_link.cc:189
functionStatic:net_link.cc:194
// This cannot be static when checking with valgrind
functionStatic:libmisc/StringHeap.cc
// Skip not initialized in the constructor for target scope
uninitMemberVar:t-dll.cc:41
uninitMemberVar:t-dll.cc:109
// By convention we put statics at the top scope.
variableScope:pform.cc:3461
variableScope:pform.cc:3630
// These are correct and are used to find the base (zero) pin.
thisSubtraction:netlist.h:5309
thisSubtraction:netlist.h:5318
thisSubtraction:netlist.h:5370
thisSubtraction:netlist.h:5379
// This is used when running a debugger
// debugger_release
knownConditionTrueFalse:main.cc:931
knownConditionTrueFalse:main.cc:955
// These should be checked, but are not real issues
knownConditionTrueFalse:elaborate.cc:7621
knownConditionTrueFalse:elab_sig.cc:271
knownConditionTrueFalse:elab_sig.cc:338
knownConditionTrueFalse:elaborate.cc:8165
knownConditionTrueFalse:elab_sig.cc:272
knownConditionTrueFalse:elab_sig.cc:345
// Yes, it's a duplicate
duplicateCondition:elaborate.cc:7672
duplicateCondition:elaborate.cc:8216
// To complicated to use std::find_if()
useStlAlgorithm:map_named_args.cc:38
@ -59,7 +61,7 @@ useStlAlgorithm:map_named_args.cc:38
derefInvalidIterator:netmisc.cc:420
// By convention we put statics at the top scope.
variableScope:t-dll.cc:2377
variableScope:t-dll.cc:2309
// We check memory allocation with valgrind
unsafeClassCanLeak:libmisc/StringHeap.h:79
@ -716,35 +718,37 @@ unusedFunction:t-dll-api.cc:980
// has_compat_attributes()
unusedFunction:Attrib.cc:72
// bl_type()
unusedFunction:Statement.h:192
unusedFunction:Statement.h:194
// chain_args()
unusedFunction:Statement.h:341
unusedFunction:Statement.h:369
// gn_modules_nest()
unusedFunction:compiler.h:228
unusedFunction:compiler.h:247
// driven_mask()
unusedFunction:link_const.cc:275
// find_root_scope()
unusedFunction:net_design.cc:121
// assign_lval()
unusedFunction:net_link.cc:282
unusedFunction:net_link.cc:283
// intersect()
unusedFunction:net_link.cc:689
unusedFunction:net_link.cc:687
// get_def_fileline()
unusedFunction:net_scope.cc:201
unusedFunction:net_scope.cc:200
// get_module_port_info()
unusedFunction:net_scope.cc:591
unusedFunction:net_scope.cc:631
// find_link_signal()
unusedFunction:netlist.cc:111
unusedFunction:netlist.cc:113
// find_link()
unusedFunction:netlist.cc:297
unusedFunction:netlist.cc:304
// set_module_port_index()
unusedFunction:netlist.cc:651
unusedFunction:netlist.cc:658
// width_a()
unusedFunction:netlist.cc:1678
unusedFunction:netlist.cc:1685
// width_b()
unusedFunction:netlist.cc:1683
unusedFunction:netlist.cc:1690
// result_sig()
unusedFunction:netlist.cc:2184
unusedFunction:netlist.cc:2191
// soft_union()
unusedFunction:netstruct.h:93
// test_protected()
unusedFunction:property_qual.h:50
// test_rand()
@ -756,13 +760,14 @@ unusedFunction:t-dll-expr.cc:55
// mul_expr_by_const_()
unusedFunction:t-dll-expr.cc:91
// net_assign()
unusedFunction:t-dll.cc:2368
unusedFunction:t-dll.cc:2300
// is_before()
unusedFunction:verinum.cc:588
// Errors/limitations in the generated yacc and lex files
constVariablePointer:<stdout>
cstyleCast:<stdout>
duplicateBreak:<stdout>
nullPointer:<stdout>
redundantInitialization:<stdout>
syntaxError:<stdout>

View File

@ -180,9 +180,7 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
<< "Replace binary MUX with constant select=" << sel_val
<< " with a BUFZ to the selected input." << endl;
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
tmp->delay_times(obj->delay_times());
connect(tmp->pin(0), obj->pin_Result());
if (sel_val == verinum::V1)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -90,6 +90,30 @@ ostream& operator << (ostream&o, ivl_drive_t str)
return o;
}
ostream &operator << (ostream &o, const drive_strength_t &strength)
{
o << strength.drive0 << "0 " << strength.drive1 << "1";
return o;
}
static void dump_delay_expr(ostream &o, const NetExpr *expr)
{
if (expr)
o << *expr;
else
o << "0";
}
ostream &operator << (ostream &o, const delay_exprs_t &delays)
{
dump_delay_expr(o, delays.rise);
o << ",";
dump_delay_expr(o, delays.fall);
o << ",";
dump_delay_expr(o, delays.decay);
return o;
}
ostream& operator << (ostream&o, ivl_variable_type_t val)
{
switch (val) {
@ -454,8 +478,7 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")";
if (scope())
o << " scope=" << scope_path(scope());
o << " #(" << rise_time() << "," << fall_time() << ","
<< decay_time() << ") vector_width=" << vector_width()
o << " #(" << delay_times() << ") vector_width=" << vector_width()
<< " pin_count=" << pin_count();
if (pins_are_virtual()) {
o << " pins_are_virtual" << endl;
@ -486,8 +509,7 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
void NetNode::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "node: ";
o << typeid(*this).name() << " #(" << rise_time()
<< "," << fall_time() << "," << decay_time() << ") " << name()
o << typeid(*this).name() << " #(" << delay_times() << ") " << name()
<< endl;
dump_node_pins(o, ind+4);
@ -518,8 +540,7 @@ void NetPins::dump_node_pins(ostream&o, unsigned ind, const char**pin_names) con
break;
}
o << " (" << pin(idx).drive0() << "0 "
<< pin(idx).drive1() << "1): ";
o << " (" << pin(idx).drive() << "): ";
if (pin(idx).is_linked()) {
const Nexus*nex = pin(idx).nexus();
@ -622,11 +643,7 @@ void NetConcat::dump_node(ostream&o, unsigned ind) const
o << setw(ind) << "" << "NetConcat: ";
o << name();
if (rise_time())
o << " #(" << *rise_time()
<< "," << *fall_time() << "," << *decay_time() << ")";
else
o << " #(0,0,0)";
o << " #(" << delay_times() << ")";
o << " scope=" << scope_path(scope())
<< " width=" << width_ << endl;
dump_node_pins(o, ind+4);
@ -651,14 +668,7 @@ void NetPow::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "LPM_POW (NetPow): " << name()
<< " scope=" << scope_path(scope())
<< " delay=(";
if (rise_time())
o << *rise_time() << "," << *fall_time() << ","
<< *decay_time();
else
o << "0,0,0";
o << ")" << endl;
<< " delay=(" << delay_times() << ")" << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
@ -676,8 +686,7 @@ void NetBUFZ::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "NetBUFZ: " << name()
<< " scope=" << scope_path(scope())
<< " delay=(" << rise_time() << "," << fall_time() << "," <<
decay_time() << ") width=" << width()
<< " delay=(" << delay_times() << ") width=" << width()
<< (transparent()? " " : " non-") << "transparent" << endl;
dump_node_pins(o, ind+4);
}
@ -693,10 +702,8 @@ void NetConst::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "constant " << value_;
o << ": " << name();
if (rise_time())
o << " #(" << *rise_time()
<< "," << *fall_time()
<< "," << *decay_time() << ")";
if (delay_times().has_delay())
o << " #(" << delay_times() << ")";
else
o << " #(.,.,.)";
o << endl;
@ -729,10 +736,8 @@ void NetLiteral::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "constant real " << real_
<< ": " << name();
if (rise_time())
o << " #(" << *rise_time()
<< "," << *fall_time()
<< "," << *decay_time() << ")";
if (delay_times().has_delay())
o << " #(" << delay_times() << ")";
else
o << " #(.,.,.)";
o << endl;
@ -810,8 +815,7 @@ void NetLogic::dump_node(ostream&o, unsigned ind) const
o << "xor";
break;
}
o << " #(" << rise_time()
<< "," << fall_time() << "," << decay_time() << ") " << name()
o << " #(" << delay_times() << ") " << name()
<< " scope=" << scope_path(scope())
<< endl;
@ -839,10 +843,8 @@ void NetPartSelect::dump_node(ostream&o, unsigned ind) const
}
o << setw(ind) << "" << "NetPartSelect(" << pt << "): "
<< name();
if (rise_time())
o << " #(" << *rise_time()
<< "," << *fall_time()
<< "," << *decay_time() << ")";
if (delay_times().has_delay())
o << " #(" << delay_times() << ")";
else
o << " #(.,.,.)";
o << " off=" << off_ << " wid=" << wid_ <<endl;
@ -854,10 +856,8 @@ void NetSubstitute::dump_node(ostream&fd, unsigned ind) const
{
fd << setw(ind) << "" << "NetSubstitute: "
<< name();
if (rise_time())
fd << " #(" << *rise_time()
<< "," << *fall_time()
<< "," << *decay_time() << ")";
if (delay_times().has_delay())
fd << " #(" << delay_times() << ")";
else
fd << " #(.,.,.)";
fd << " width=" << wid_ << " base=" << off_ <<endl;
@ -877,10 +877,8 @@ void NetReplicate::dump_node(ostream&o, unsigned ind) const
void NetSignExtend::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "NetSignExtend: " << name();
if (rise_time())
o << " #(" << *rise_time()
<< "," << *fall_time()
<< "," << *decay_time() << ")";
if (delay_times().has_delay())
o << " #(" << delay_times() << ")";
else
o << " #(.,.,.)";
o << " output width=" << width_ << endl;
@ -914,8 +912,7 @@ void NetUReduce::dump_node(ostream&o, unsigned ind) const
o << "xnor";
break;
}
o << " #(" << rise_time()
<< "," << fall_time() << "," << decay_time() << ") " << name()
o << " #(" << delay_times() << ") " << name()
<< " scope=" << scope_path(scope())
<< endl;
@ -935,10 +932,8 @@ void NetUserFunc::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "USER FUNC: "
<< scope_path(def_);
if (rise_time())
o << " #(" <<*rise_time()
<<","<<*fall_time()
<< "," <<*decay_time() << ")";
if (delay_times().has_delay())
o << " #(" << delay_times() << ")";
o << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
@ -986,14 +981,7 @@ void NetTran::dump_node(ostream&o, unsigned ind) const
<< " part=" << part_width()
<< " offset=" << part_offset();
}
o << " delay=(";
if (rise_time())
o << *rise_time() << "," << *fall_time() << ","
<< *decay_time();
else
o << "0,0,0";
o << ")" << endl;
o << " delay=(" << delay_times() << ")" << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
@ -1001,8 +989,7 @@ void NetTran::dump_node(ostream&o, unsigned ind) const
void NetUDP::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "UDP (" << udp_name() << "): ";
o << " #(" << rise_time() << "," << fall_time() << "," << decay_time() <<
") " << name() << endl;
o << " #(" << delay_times() << ") " << name() << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
@ -1151,7 +1138,7 @@ void NetAssignNB::dump(ostream&o, unsigned ind) const
if (rval())
o << *rval() << ";" << endl;
else
o << "rval elaboration error>;" << endl;
o << "<rval elaboration error>;" << endl;
}

View File

@ -31,7 +31,11 @@ suffix = @install_suffix@
bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
includedir = $(prefix)/include
mandir = @mandir@
# This is actually the directory where we install our own header files.
# It is a little different from the generic includedir.
ivl_includedir = @includedir@/iverilog$(suffix)
man1dir = @mandir@/man1
docdir = @docdir@
dllib=@DLLIB@
@ -39,8 +43,11 @@ CC = @CC@
HOSTCC := @CC@
WINDRES = @WINDRES@
INSTALL = @INSTALL@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
MAN = @MAN@
PS2PDF = @PS2PDF@
ifeq (@srcdir@,.)
INCLUDE_PATH = -I. -I..
@ -48,19 +55,36 @@ else
INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
endif
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@
CPPFLAGS = @DEFS@ $(INCLUDE_PATH) @CPPFLAGS@
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
LDFLAGS = @LDFLAGS@
PICFLAGS = @PICFLAG@
LDFLAGS = @rdynamic@ @LDFLAGS@
O = main.o res.o
ifeq (@MINGW32@,yes)
all: iverilog-vpi@EXEEXT@
else
all: iverilog-vpi
endif
INSTALL_DOC =
ifneq ($(MAN),none)
INSTALL_DOC += installman
ifneq ($(PS2PDF),none)
ifeq (@MINGW32@,yes)
INSTALL_DOC += installpdf
all: iverilog-vpi.pdf
endif
endif
endif
check: all
clean:
rm -f *.o config.h iverilog-vpi@EXEEXT@ res.rc
rm -f *.o config.h iverilog-vpi@EXEEXT@ iverilog-vpi \
iverilog-vpi.man iverilog-vpi.ps iverilog-vpi.pdf res.rc
distclean: clean
rm -f Makefile config.log
@ -75,8 +99,24 @@ cppcheck: main.c config.h
Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; ./config.status --file=driver-vpi/$@
ifeq (@MINGW32@,yes)
iverilog-vpi@EXEEXT@: $O
$(CC) $(LDFLAGS) $O -o iverilog-vpi@EXEEXT@ @EXTRALIBS@
endif
ifeq (@MINGW32@,no)
iverilog-vpi: $(srcdir)/iverilog-vpi.sh ../config.status
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
-e 's;@ENABLE_PLI1@;@LIBVERIUSER@;' \
-e 's;@SUFFIX@;$(suffix);' \
-e 's;@IVCC@;$(CC);' \
-e 's;@IVCXX@;@CXX@;' \
-e 's;@IVCFLAGS@;$(CFLAGS);' \
-e 's;@IVCXXFLAGS@;$(CXXFLAGS);' \
-e 's;@IVCTARGETFLAGS@;@CTARGETFLAGS@;' \
-e 's;@INCLUDEDIR@;$(ivl_includedir);' \
-e 's;@LIBDIR@;@libdir@;' $< > $@
chmod +x $@
endif
main.o: $(srcdir)/main.c config.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c
@ -95,20 +135,39 @@ else
endif
# Windows specific...
res.rc: $(srcdir)/res.rc.in ../version.exe
sed -e 's;@PRODUCTVERSION@;'`../version.exe '%M,%n,0,0'`';' \
$(srcdir)/res.rc.in > $@
res.rc: $(srcdir)/res.rc.in ../config.status
cd ..; ./config.status --file=driver-vpi/$@
res.o: res.rc
$(WINDRES) -i res.rc -o res.o
#
iverilog-vpi.man: $(srcdir)/iverilog-vpi.man.in ../config.status
cd ..; ./config.status --file=driver-vpi/$@
iverilog-vpi.ps: iverilog-vpi.man
$(MAN) -t ./$< > $@
iverilog-vpi.pdf: iverilog-vpi.ps
$(PS2PDF) $< $@
install: all installdirs installfiles
F = ./iverilog-vpi@EXEEXT@
F = $(INSTALL_DOC)
ifeq (@MINGW32@,yes)
F += ./iverilog-vpi@EXEEXT@
endif
ifeq (@MINGW32@,no)
F += ./iverilog-vpi
endif
installfiles: $(F) | installdirs
ifeq (@MINGW32@,yes)
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)@EXEEXT@"
endif
ifeq (@MINGW32@,no)
$(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)"
endif
ifeq (@WIN32@,yes)
ifneq ($(HOSTCC),$(CC))
$(INSTALL_PROGRAM) $(shell $(HOSTCC) --print-file-name=libwinpthread-1.dll) "$(DESTDIR)$(bindir)"
@ -117,8 +176,24 @@ ifneq ($(HOSTCC),$(CC))
endif
endif
installman: iverilog-vpi.man installdirs
$(INSTALL_DATA) iverilog-vpi.man "$(DESTDIR)$(man1dir)/iverilog-vpi$(suffix).1"
installpdf: iverilog-vpi.pdf installdirs
$(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(docdir)/iverilog-vpi$(suffix).pdf"
installdirs: $(srcdir)/../mkinstalldirs
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)"
$(srcdir)/../mkinstalldirs \
"$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(docdir)" \
"$(DESTDIR)$(man1dir)"
uninstall:
ifeq (@MINGW32@,yes)
rm -f $(DESTDIR)$(bindir)/iverilog-vpi$(suffix)@EXEEXT@
endif
ifeq (@MINGW32@,no)
rm -f $(DESTDIR)$(bindir)/iverilog-vpi$(suffix)
endif
rm -f "$(DESTDIR)$(man1dir)/iverilog-vpi$(suffix).1" \
"$(DESTDIR)$(docdir)/iverilog-vpi$(suffix).pdf"

View File

@ -1,4 +1,4 @@
.TH iverilog-vpi 1 "Jan 13th, 2026" "" "Version %M.%n%E"
.TH iverilog-vpi 1 "Jan 13th, 2026" "" "Version @VERSION@"
.SH NAME
iverilog-vpi - Compile front end for VPI modules

View File

@ -1,5 +1,7 @@
#!/bin/sh
#
# Copyright (c) 1998-2026 Stephen Williams (steve@icarus.com)
#
# This source code is free software; you can redistribute it
# and/or modify it in source code form under the terms of the GNU
# Library General Public License as published by the Free Software

View File

@ -17,20 +17,26 @@
#
SHELL = /bin/sh
EXEEXT = @EXEEXT@
ENV_VVP=@ENV_VVP@
PATH_SEP=@PATH_SEP@
suffix = @install_suffix@
prefix = @prefix@
exec_prefix = @exec_prefix@
srcdir = @srcdir@
datarootdir = @datarootdir@
builddir=@builddir@
top_builddir=@top_builddir@
VPATH = $(srcdir)
bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
includedir = $(prefix)/include
mandir = @mandir@
pdfdir = @docdir@
man1dir = @mandir@/man1
docdir = @docdir@
dllib=@DLLIB@
@ -58,11 +64,22 @@ O = main.o substit.o cflexor.o cfparse.o
all: dep iverilog@EXEEXT@ iverilog.man
check: all
@echo "driver/iverilog: create a vvp file and then run it."
@rm -f top.vvp
@$(builddir)/iverilog@EXEEXT@ \
-B$(top_builddir)$(PATH_SEP)tgt-vvp \
-BI$(top_builddir) \
-BM$(top_builddir)$(PATH_SEP)vpi \
-BP$(top_builddir)$(PATH_SEP)ivlpp \
-Bt$(top_builddir)$(PATH_SEP)tgt-vvp \
$(verbose) -o top.vvp -s top $(srcdir)/hello_world.v && \
$(ENV_VVP) $(top_builddir)/vvp/vvp$(suffix)@EXEEXT@ top.vvp
clean:
rm -f *.o cflexor.c cfparse.c cfparse.h cfparse.output
rm -f iverilog@EXEEXT@ iverilog.man iverilog.pdf iverilog.ps
rm -rf dep
rm -f top.vvp
distclean: clean
rm -f Makefile config.log
@ -92,19 +109,18 @@ cflexor.c: $(srcdir)/cflexor.lex
cfparse%c cfparse%h: $(srcdir)/cfparse%y
$(YACC) --verbose -t -p cf -d -o cfparse.c $<
%.o: %.c
%.o: %.c | dep
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
mv $*.d dep
main.o: main.c globals.h $(srcdir)/../version_base.h ../version_tag.h Makefile
main.o: main.c globals.h ../version_base.h ../version_tag.h Makefile | dep
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c -DIVL_ROOT='"@libdir@/ivl$(suffix)"' -DIVL_SUFFIX='"$(suffix)"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' -DIVL_INCLUDE_INSTALL_DIR="\"$(realpath $(DESTDIR)/$(includedir))\"" $(srcdir)/main.c
mv $*.d dep
cflexor.o: cflexor.c cfparse.h
iverilog.man: $(srcdir)/iverilog.man.in ../version.exe
../version.exe `head -1 $<`'\n' > $@
tail -n +2 $< >> $@
iverilog.man: $(srcdir)/iverilog.man.in ../config.status
cd ..; ./config.status --file=driver/$@
iverilog.ps: iverilog.man
$(MAN) -t ./$< > $@
@ -112,25 +128,15 @@ iverilog.ps: iverilog.man
iverilog.pdf: iverilog.ps
$(PS2PDF) $< $@
INSTALL_DOC =
ifneq ($(MAN),none)
INSTALL_DOC += installman
ifneq ($(PS2PDF),none)
ifeq (@MINGW32@,yes)
ifeq ($(MAN),none)
INSTALL_DOC = installman
INSTALL_PDFDIR = $(prefix)
else
ifeq ($(PS2PDF),none)
INSTALL_DOC = installman
INSTALL_PDFDIR = $(prefix)
else
INSTALL_DOC = installpdf installman
INSTALL_PDFDIR = $(pdfdir)
INSTALL_DOC += installpdf
all: iverilog.pdf
endif
endif
INSTALL_DOCDIR = $(mandir)/man1
else
INSTALL_DOC = installman
INSTALL_DOCDIR = $(mandir)/man1
INSTALL_PDFDIR = $(prefix)
endif
install: all installdirs installfiles
@ -139,21 +145,23 @@ F = ./iverilog@EXEEXT@ \
$(INSTALL_DOC)
installman: iverilog.man installdirs
$(INSTALL_DATA) iverilog.man "$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1"
$(INSTALL_DATA) iverilog.man "$(DESTDIR)$(man1dir)/iverilog$(suffix).1"
installpdf: iverilog.pdf installdirs
$(INSTALL_DATA) iverilog.pdf "$(DESTDIR)$(pdfdir)/iverilog$(suffix).pdf"
$(INSTALL_DATA) iverilog.pdf "$(DESTDIR)$(docdir)/iverilog$(suffix).pdf"
installfiles: $(F) | installdirs
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@"
installdirs: $(srcdir)/../mkinstalldirs
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(INSTALL_DOCDIR)" \
"$(DESTDIR)$(INSTALL_PDFDIR)"
$(srcdir)/../mkinstalldirs \
"$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(docdir)" \
"$(DESTDIR)$(man1dir)"
uninstall:
rm -f "$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@"
rm -f "$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1" "$(DESTDIR)$(pdfdir)/iverilog$(suffix).pdf"
rm -f "$(DESTDIR)$(man1dir)/iverilog$(suffix).1" \
"$(DESTDIR)$(docdir)/iverilog$(suffix).pdf"
-include $(patsubst %.o, dep/%.d, $O)

View File

@ -1,10 +1,10 @@
// cppcheck is wrong this is correct usage
syntaxError:main.c:405
syntaxError:main.c:408
syntaxError:main.c:415
syntaxError:main.c:412
// cppcheck is missing the code adds a \0 at the previous location.
knownConditionTrueFalse:main.c:1086
redundantAssignment:main.c:1085
knownConditionTrueFalse:main.c:1123
redundantAssignment:main.c:1122
// Skip all memory issues since they should be handled by ivl_alloc.h
memleakOnRealloc
@ -18,9 +18,12 @@ memleakOnRealloc:cfparse.y
allocaCalled:cfparse.c
constParameterPointer:cfparse.c
constVariablePointer:cfparse.c
invalidPrintfArgType_sint:cfparse.c
knownConditionTrueFalse:cfparse.c
sizeofwithnumericparameter:cfparse.c
unsignedPositive:cfparse.c
constVariablePointer:<stdout>
duplicateBreak:<stdout>
nullPointer:<stdout>
redundantInitialization:<stdout>
staticFunction:<stdout>

3
driver/hello_world.v Normal file
View File

@ -0,0 +1,3 @@
module top;
initial $display("Hello World!");
endmodule

View File

@ -1,12 +1,12 @@
.TH iverilog 1 "Jan 13th, 2026" "" "Version %M.%n%E"
.TH iverilog 1 "Jan 13th, 2026" "" "Version @VERSION@"
.SH NAME
iverilog - Icarus Verilog compiler
.SH SYNOPSIS
.B iverilog
[\-EiRSuVv] [\-Bpath] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]]
[\-EiRSuVv] [\-B[IMPVt]path] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]]
[\-Pparameter=value] [\-pflag=value] [\-dname]
[\-g1995\:|\-g2001\:|\-g2005\:|\-g2005-sv\:|\-g2009\:|\-g2012\:|\-g<feature>]
[\-g1995\:|\-g2001\:|\-g2005\:|\-g2005-sv\:|\-g2009\:|\-g2012\:|\-g2017\:|\-g2023\:|\-g<feature>]
[\-Iincludedir] [\-Lmoduledir] [\-mmodule] [\-M[mode=]file] [\-Nfile]
[\-ooutputfilename] [\-stopmodule] [\-ttype] [\-Tmin/typ/max] [\-Wclass]
[\-ypath] [\-lfile]
@ -21,13 +21,36 @@ further processing. The main target is \fIvvp\fP for simulation.
.SH OPTIONS
\fIiverilog\fP accepts the following options:
.TP 8
.B -B\fIbase\fP
.BI \-B path
The \fIiverilog\fP program uses external programs and configuration
files to preprocess and compile the Verilog source. Normally, the path
used to locate these tools is built into the \fIiverilog\fP
program. However, the \fB\-B\fP switch allows the user to select a
different set of programs. The path given is used to locate
\fIivlpp\fP, \fIivl\fP, code generators and the VPI modules.
files to preprocess and compile Verilog source files. Normally, the
paths used to locate these tools are built into the
\fIiverilog\fP executable. The \fB\-B\fP option allows the user to
override these paths.
The specified path is used as the default base directory for locating
\fIivlpp\fP, \fIivl\fP, code generators, configuration files, and
VPI modules.
Specialized forms of this option may be used to override individual
tool paths:
.RS
.TP
.BI \-BI path
Directory for the \fIivl\fP parser.
.TP
.BI \-BM path
Directory for VPI modules.
.TP
.BI \-BP path
Directory for the \fIivlpp\fP preprocessor.
.TP
.BI \-BV path
Directory for the \fIvhdlpp\fP VHDL preprocessor.
.TP
.BI \-Bt path
Directory used to locate target configuration files for the
\fB\-t\fP\fItarget\fP option. The configuration file name is
\fItarget\fP.conf.
.RE
.TP 8
.B -c\fIfile\fP -f\fIfile\fP
These flags specify an input file that contains a list of Verilog
@ -63,11 +86,11 @@ is the Verilog input, but with file inclusions and macro references
expanded and removed. This is useful, for example, to preprocess
Verilog source for use by other compilers.
.TP 8
.B -g1995\fI|\fP-g2001\fI|\fP-g2001-noconfig\fI|\fP-g2005\fI|\fP-g2005-sv\fI|\fP-g2009\fI|\fP-g2012
.B -g1995\fI|\fP-g2001\fI|\fP-g2001-noconfig\fI|\fP-g2005\fI|\fP-g2005-sv\fI|\fP-g2009\fI|\fP-g2012\fI|\fP-g2017\fI|\fP-g2023
Select the Verilog language \fIgeneration\fP to support in the compiler.
This selects between \fIIEEE1364\-1995\fP, \fIIEEE1364\-2001\fP,
\fIIEEE1364\-2005\fP, \fIIEEE1800\-2005\fP, \fIIEEE1800\-2009\fP, or
\fIIEEE1800\-2012\fP.
\fIIEEE1364\-2005\fP, \fIIEEE1800\-2005\fP, \fIIEEE1800\-2009\fP,
\fIIEEE1800\-2012\fP, \fIIEEE1800\-2017\fP, or \fIIEEE1800\-2023\fP.
Icarus Verilog currently defaults to the \fIIEEE1364\-2005\fP generation
of the language. This flag is used to restrict the language to a set of
keywords/features, this allows simulation of older Verilog code that may
@ -124,7 +147,7 @@ to disable extended types if compiling code that clashes with the few
new keywords used to implement the type system.
.TP 8
.B -gio-range-error\fI|\fP-gno-io-range-error
The standards requires that a vectored port have matching ranges for its
The standards require that a vectored port have matching ranges for its
port declaration as well as any net/register declaration. It was common
practice in the past to only specify the range for the net/register
declaration and some tools still allow this. By default any mismatch is
@ -150,6 +173,17 @@ parameter assignment is evaluated as a lossless expression, as is any
expression containing an unsized constant number, and unsized constant
numbers are not truncated to integer width.
.TP 8
.B -gstrict-declaration\fI|\fP-gno-strict-declaration
.TP 8
.B -gstrict-net-var-declaration\fI|\fP-gno-strict-net-var-declaration
.TP 8
.B -gstrict-parameter-declaration\fI|\fP-gno-strict-parameter-declaration
The standards require that nets, variables, and parameters are declared
lexically before they are used. Using \fB\-gno\-strict\-declaration\fP
will allow using a data object before declaration, with a warning. The
warning can be suppressed with -Wno-declaration-after-use. The option
can be applied for nets and variables and for parameters separately.
.TP 8
.B -gshared-loop-index\fI|\fP-gno-shared-loop-index
Enable (default) or disable the exclusion of for-loop control variables
from implicit event_expression lists. When enabled, if a for-loop control
@ -367,6 +401,11 @@ This enables warnings for creation of implicit declarations. For
example, if a scalar wire X is used but not declared in the Verilog
source, this will print a warning at its first use.
.TP 8
.B declaration-after-use
This enables warnings for declarations after use, when
those are not flagged as errors (default).
.TP 8
.B macro-redefinition\fI | \fPmacro-replacement
This enables preprocessor warnings when a macro is being redefined.

View File

@ -38,8 +38,8 @@ const char NOTICE[] =
;
const char HELP[] =
"Usage: iverilog [-EiRSuvV] [-B base] [-c cmdfile|-f cmdfile]\n"
" [-g1995|-g2001|-g2005|-g2005-sv|-g2009|-g2012] [-g<feature>]\n"
"Usage: iverilog [-EiRSuvV] [-B[IMPVt] base] [-c cmdfile|-f cmdfile]\n"
" [-g1995|-g2001|-g2005|-g2005-sv|-g2009|-g2012|-g2017|-g2023] [-g<feature>]\n"
" [-D macro[=defn]] [-I includedir] [-L moduledir]\n"
" [-M [mode=]depfile] [-m module]\n"
" [-N file] [-o filename] [-p flag=value]\n"
@ -69,6 +69,9 @@ const char HELP[] =
# include <libiberty.h>
#endif
#endif
#ifdef __APPLE__
# include <mach-o/dyld.h>
#endif
#include <fcntl.h>
#ifdef HAVE_GETOPT_H
@ -109,6 +112,8 @@ extern void cfreset(FILE*fd, const char*path);
const char*base = 0;
const char*vpi_dir = 0;
const char*tconfig_dir = 0;
const char*ivl_dir = 0;
const char*ivlpp_dir = 0;
const char*vhdlpp_dir= 0;
const char*vhdlpp_work = 0;
@ -134,6 +139,8 @@ const char*gen_strict_ca_eval = "no-strict-ca-eval";
const char*gen_strict_expr_width = "no-strict-expr-width";
const char*gen_shared_loop_index = "shared-loop-index";
const char*gen_verilog_ams = "no-verilog-ams";
const char*gen_strict_net_var_declaration = "strict-net-var-declaration";
const char*gen_strict_parameter_declaration = "strict-parameter-declaration";
/* Boolean: true means use a default include dir, false means don't */
int gen_std_include = 1;
@ -142,7 +149,7 @@ int gen_std_include = 1;
of the include list. */
int gen_relative_include = 0;
char warning_flags[17] = "n";
char warning_flags[18] = "nu";
int separate_compilation_flag = 0;
@ -335,7 +342,7 @@ static int t_version_only(void)
}
fflush(0);
snprintf(tmp, sizeof tmp, "%s%civl -V -C\"%s\" -C\"%s\"", base, sep,
snprintf(tmp, sizeof tmp, "%s%civl -V -C\"%s\" -C\"%s\"", ivl_dir, sep,
iconfig_path, iconfig_common_path);
rc = system(tmp);
if (rc != 0) {
@ -442,7 +449,7 @@ static int t_compile(void)
#endif
/* Build the ivl command. */
snprintf(tmp, sizeof tmp, "%s%civl", base, sep);
snprintf(tmp, sizeof tmp, "%s%civl", ivl_dir, sep);
rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp);
@ -527,6 +534,7 @@ static void process_warning_switch(const char*name)
{
if (strcmp(name,"all") == 0) {
process_warning_switch("anachronisms");
process_warning_switch("declaration-after-use");
process_warning_switch("implicit");
process_warning_switch("implicit-dimensions");
process_warning_switch("macro-replacement");
@ -537,6 +545,9 @@ static void process_warning_switch(const char*name)
} else if (strcmp(name,"anachronisms") == 0) {
if (! strchr(warning_flags, 'n'))
strcat(warning_flags, "n");
} else if (strcmp(name,"declaration-after-use") == 0) {
if (! strchr(warning_flags, 'u'))
strcat(warning_flags, "u");
} else if (strcmp(name,"floating-nets") == 0) {
if (! strchr(warning_flags, 'f'))
strcat(warning_flags, "f");
@ -578,6 +589,12 @@ static void process_warning_switch(const char*name)
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-declaration-after-use") == 0) {
char*cp = strchr(warning_flags, 'u');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-floating-nets") == 0) {
char*cp = strchr(warning_flags, 'f');
if (cp) while (*cp) {
@ -725,6 +742,12 @@ static int process_generation(const char*name)
else if (strcmp(name,"2012") == 0)
generation = "2012";
else if (strcmp(name,"2017") == 0)
generation = "2017";
else if (strcmp(name,"2023") == 0)
generation = "2023";
else if (strcmp(name,"1") == 0) { /* Deprecated: use 1995 */
generation = "1995";
gen_xtypes = "no-xtypes";
@ -815,6 +838,26 @@ static int process_generation(const char*name)
else if (strcmp(name,"no-verilog-ams") == 0)
gen_verilog_ams = "no-verilog-ams";
else if (strcmp(name,"strict-declaration") == 0) {
gen_strict_net_var_declaration = "strict-net-var-declaration";
gen_strict_parameter_declaration = "strict-parameter-declaration";
}
else if (strcmp(name,"no-strict-declaration") == 0) {
gen_strict_net_var_declaration = "no-strict-net-var-declaration";
gen_strict_parameter_declaration = "no-strict-parameter-declaration";
}
else if (strcmp(name,"strict-net-var-declaration") == 0)
gen_strict_net_var_declaration = "strict-net-var-declaration";
else if (strcmp(name,"no-strict-net-var-declaration") == 0)
gen_strict_net_var_declaration = "no-strict-net-var-declaration";
else if (strcmp(name,"strict-parameter-declaration") == 0)
gen_strict_parameter_declaration = "strict-parameter-declaration";
else if (strcmp(name,"no-strict-parameter-declaration") == 0)
gen_strict_parameter_declaration = "no-strict-parameter-declaration";
else {
fprintf(stderr, "Unknown/Unsupported Language generation "
"%s\n\n", name);
@ -825,6 +868,8 @@ static int process_generation(const char*name)
" 2005-sv -- IEEE1800-2005\n"
" 2009 -- IEEE1800-2009\n"
" 2012 -- IEEE1800-2012\n"
" 2017 -- IEEE1800-2017\n"
" 2023 -- IEEE1800-2023\n"
"Other generation flags:\n"
" assertions | supported-assertions | no-assertions\n"
" specify | no-specify\n"
@ -837,7 +882,9 @@ static int process_generation(const char*name)
" io-range-error | no-io-range-error\n"
" strict-ca-eval | no-strict-ca-eval\n"
" strict-expr-width | no-strict-expr-width\n"
" shared-loop-index | no-shared-loop-index\n");
" shared-loop-index | no-shared-loop-index\n"
" strict-declaration | no-strict-declaration\n"
" [no-]strict-[net-var|parameter]-declaration\n");
return 1;
}
@ -1179,6 +1226,9 @@ int main(int argc, char **argv)
character of the path indicates which path the
user is specifying. */
switch (optarg[0]) {
case 'I': /* Path for the ivl parser */
ivl_dir = optarg+1;
break;
case 'M': /* Path for the VPI modules */
vpi_dir = optarg+1;
break;
@ -1188,6 +1238,9 @@ int main(int argc, char **argv)
case 'V': /* Path for the vhdlpp VHDL processor */
vhdlpp_dir = optarg+1;
break;
case 't': /* Path to target.conf for the -ttarget option */
tconfig_dir = optarg+1;
break;
default: /* Otherwise, this is a default base. */
base=optarg;
break;
@ -1330,8 +1383,12 @@ int main(int argc, char **argv)
vpi_dir = base;
if (ivlpp_dir == 0)
ivlpp_dir = base;
if (ivl_dir == 0)
ivl_dir = base;
if (vhdlpp_dir == 0)
vhdlpp_dir = base;
if (tconfig_dir == 0)
tconfig_dir = base;
if (version_flag || verbose_flag) {
printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
@ -1341,7 +1398,7 @@ int main(int argc, char **argv)
/* Make a common conf file path to reflect the target. */
snprintf(iconfig_common_path, sizeof iconfig_common_path, "%s%c%s%s.conf",
base, sep, targ, synth_flag? "-s" : "");
tconfig_dir, sep, targ, synth_flag? "-s" : "");
/* Write values to the iconfig file. */
fprintf(iconfig_file, "basedir:%s\n", base);
@ -1351,11 +1408,13 @@ int main(int argc, char **argv)
fprintf(iconfig_file, "module:%s%cvhdl_sys.vpi\n", vpi_dir, sep);
fprintf(iconfig_file, "module:%s%cvhdl_textio.vpi\n", vpi_dir, sep);
/* If verilog-2005/09/12 is enabled or icarus-misc or verilog-ams,
/* If verilog-2005/09/12/17/23 is enabled or icarus-misc or verilog-ams,
* then include the v2005_math library. */
if (strcmp(generation, "2005") == 0 ||
strcmp(generation, "2009") == 0 ||
strcmp(generation, "2012") == 0 ||
strcmp(generation, "2017") == 0 ||
strcmp(generation, "2023") == 0 ||
strcmp(gen_icarus, "icarus-misc") == 0 ||
strcmp(gen_verilog_ams, "verilog-ams") == 0) {
fprintf(iconfig_file, "module:%s%cv2005_math.vpi\n", vpi_dir, sep);
@ -1370,7 +1429,9 @@ int main(int argc, char **argv)
v2009 module. */
if (strcmp(generation, "2005-sv") == 0 ||
strcmp(generation, "2009") == 0 ||
strcmp(generation, "2012") == 0) {
strcmp(generation, "2012") == 0 ||
strcmp(generation, "2017") == 0 ||
strcmp(generation, "2023") == 0) {
fprintf(iconfig_file, "module:%s%cv2009.vpi\n", vpi_dir, sep);
}
@ -1385,6 +1446,8 @@ int main(int argc, char **argv)
fprintf(iconfig_file, "generation:%s\n", gen_strict_expr_width);
fprintf(iconfig_file, "generation:%s\n", gen_shared_loop_index);
fprintf(iconfig_file, "generation:%s\n", gen_verilog_ams);
fprintf(iconfig_file, "generation:%s\n", gen_strict_net_var_declaration);
fprintf(iconfig_file, "generation:%s\n", gen_strict_parameter_declaration);
fprintf(iconfig_file, "generation:%s\n", gen_icarus);
fprintf(iconfig_file, "warnings:%s\n", warning_flags);
fprintf(iconfig_file, "ignore_missing_modules:%s\n", ignore_missing_modules ? "true" : "false");

View File

@ -235,7 +235,9 @@ NetESelect* NetESelect::dup_expr() const
NetESFunc* NetESFunc::dup_expr() const
{
NetESFunc*tmp = new NetESFunc(name_, type_, expr_width(), nparms(), is_overridden_);
NetESFunc*tmp = net_type()
? new NetESFunc(name_, net_type(), nparms())
: new NetESFunc(name_, type_, expr_width(), nparms(), is_overridden_);
ivl_assert(*this, tmp);
tmp->cast_signed(has_sign());

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2025 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2026 Stephen Williams (steve@icarus.com)
* Copyright CERN 2012-2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@ -133,11 +133,13 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
the compiler catch more errors. */
if (tmp == 0) continue;
if (tmp->expr_type() == IVL_VT_REAL) {
ivl_type_t tmp_type = tmp->net_type();
if (tmp_type && !tmp_type->packed()) {
cerr << parms_[idx]->get_fileline() << ": error: "
<< "concatenation operand can not be real: "
<< "concatenation operand must be packed: "
<< *parms_[idx] << endl;
des->errors += 1;
delete tmp;
continue;
}
@ -174,7 +176,10 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
}
symbol_search_results sr;
symbol_search(this, des, scope, path_, lexical_pos_, &sr);
symbol_search(this, des, scope, path_, lexical_pos(), &sr);
if (!sr.require_non_type(this, des, "as a procedural l-value"))
return nullptr;
NetNet *reg = sr.net;
const pform_name_t &member_path = sr.path_tail;
@ -296,6 +301,15 @@ NetAssign_*PEIdent::elaborate_lval_var_(Design *des, NetScope *scope,
// Past this point, we should have taken care of the cases
// where the name is a member/method of a struct/class.
// XXXX ivl_assert(*this, method_name.nil());
if (!tail_path.empty()) {
cerr << get_fileline() << ": error: Variable "
<< reg->name()
<< " does not have a field named: "
<< tail_path << "." << endl;
des->errors += 1;
return nullptr;
}
ivl_assert(*this, tail_path.empty());
bool need_const_idx = is_cassign || is_force;
@ -881,8 +895,10 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
calculate_up_do_width_(des, scope, wid);
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
if (!base)
return false;
if (base && base->expr_type() == IVL_VT_REAL) {
if (base->expr_type() == IVL_VT_REAL) {
cerr << get_fileline() << ": error: Indexed part select base "
"expression for ";
cerr << lv->sig()->name() << "[" << *base;
@ -1119,18 +1135,27 @@ NetAssign_* PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*scope
// part of the sig, as the l-value.
NetNet*psig = class_type->find_static_property(method_name);
ivl_assert(*this, psig);
if (psig->get_const()) {
cerr << get_fileline() << ": error: Assignment to const signal `"
<< psig->name() << "` is not allowed." << endl;
des->errors++;
return nullptr;
}
lv = new NetAssign_(psig);
return lv;
} else if (qual.test_const()) {
auto method_scope = find_method_containing_scope(*this, scope);
if (class_type->get_prop_initialized(pidx)) {
cerr << get_fileline() << ": error: "
<< "Property " << class_type->get_prop_name(pidx)
<< " is constant in this method."
<< " (scope=" << scope_path(scope) << ")" << endl;
des->errors++;
} else if (scope->basename() != "new" && scope->basename() != "new@") {
} else if (!method_scope ||
(method_scope->basename() != "new" &&
method_scope->basename() != "new@")) {
cerr << get_fileline() << ": error: "
<< "Property " << class_type->get_prop_name(pidx)
<< " is constant in this method."

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2025 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com)
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@ -83,16 +83,22 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
}
if (nets[idx] == 0) {
errors += 1;
} else if (nets[idx]->data_type() == IVL_VT_REAL) {
cerr << parms_[idx]->get_fileline() << ": error: "
<< "concatenation operand can no be real: "
<< *parms_[idx] << endl;
errors += 1;
continue;
} else {
width += nets[idx]->vector_width();
}
ivl_type_t tmp_type = nets[idx]->array_type();
if (!tmp_type)
tmp_type = nets[idx]->net_type();
if (tmp_type && !tmp_type->packed()) {
cerr << parms_[idx]->get_fileline() << ": error: "
<< "concatenation operand must be packed: "
<< *parms_[idx] << endl;
errors += 1;
continue;
}
width += nets[idx]->vector_width();
}
}
if (errors) {
@ -527,7 +533,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
ivl_assert(*this, scope);
symbol_search_results sr;
symbol_search(this, des, scope, path_.name, lexical_pos_, &sr);
symbol_search(this, des, scope, path_.name, lexical_pos(), &sr);
if (sr.eve != 0) {
cerr << get_fileline() << ": error: named events (" << path_
@ -557,6 +563,9 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
return 0;
}
if (!check_interface_modport_access(this, des, sr, true))
return 0;
if (debug_elaborate) {
cerr << get_fileline() << ": " << __func__ << ": "
<< "Found l-value path_=" << path_
@ -616,6 +625,9 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
// array word assignment.
bool widx_flag = false;
// Whether the signal is an array
const bool sig_is_array = sig->unpacked_dimensions() > 0;
// Detect the net is a structure and there was a method path
// detected. We have already broken the path_ into the path to
// the net, and the path of member names. For example, if the
@ -751,7 +763,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
}
}
} else if (gn_system_verilog() && sig->unpacked_dimensions() > 0 && path_tail.index.empty()) {
} else if (gn_system_verilog() && sig_is_array && path_tail.index.empty()) {
// In this case, we are doing a continuous assignment to
// an unpacked array. The NetNet representation is a
@ -761,15 +773,14 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
// This can come up from code like this:
// logic [...] data [0:3];
// assign data = ...;
// In this case, "sig" is "data", and sig->pin_count()
// is 4 to account for the unpacked size.
// In this case, "sig" is "data".
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: "
<< "Net assign to unpacked array \"" << sig->name()
<< "\" with " << sig->pin_count() << " elements." << endl;
}
} else if (sig->unpacked_dimensions() > 0) {
} else if (sig_is_array) {
list<long> unpacked_indices_const;
@ -931,7 +942,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
}
}
if (sig->pin_count() > 1 && widx_flag) {
if (sig_is_array && widx_flag) {
if (widx < 0 || widx >= (long) sig->pin_count())
return 0;
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
@ -941,7 +952,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
connect(sig->pin(widx), tmp->pin(0));
sig = tmp;
} else if (sig->pin_count() > 1) {
} else if (sig_is_array) {
// If this turns out to be an l-value unpacked array,
// then let the caller handle it. It will probably be
@ -1162,7 +1173,7 @@ NetNet* PEIdent::elaborate_subport(Design*des, NetScope*scope) const
NetNet*PEIdent::elaborate_unpacked_net(Design*des, NetScope*scope) const
{
symbol_search_results sr;
symbol_search(this, des, scope, path_, lexical_pos_, &sr);
symbol_search(this, des, scope, path_, lexical_pos(), &sr);
if (!sr.net) {
cerr << get_fileline() << ": error: Net " << path_
<< " is not defined in this context." << endl;
@ -1196,7 +1207,7 @@ bool PEIdent::is_collapsible_net(Design*des, NetScope*scope,
ivl_assert(*this, scope);
symbol_search_results sr;
symbol_search(this, des, scope, path_.name, lexical_pos_, &sr);
symbol_search(this, des, scope, path_.name, lexical_pos(), &sr);
if (sr.eve != 0)
return false;

View File

@ -355,7 +355,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
}
rc_flag = use_enum->insert_name(name_idx, cur->name, cur_value);
rc_flag &= scope->add_enumeration_name(use_enum, cur->name);
rc_flag &= scope->add_enumeration_name(use_enum, cur->name, *cur);
if (! rc_flag) {
cerr << use_enum->get_fileline()
@ -1322,6 +1322,10 @@ void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
collect_scope_signals(scope, wires);
elaborate_scope_enumerations(des, scope, enum_sets);
elaborate_scope_classes(des, scope, classes_lexical);
// Run through the defparams for this scope and save the result
// in a table for later final override.
@ -1636,7 +1640,6 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
void PEvent::elaborate_scope(Design*, NetScope*scope) const
{
NetEvent*ev = new NetEvent(name_);
ev->lexical_pos(lexical_pos_);
ev->set_line(*this);
scope->add_event(ev);
}
@ -1662,6 +1665,8 @@ void PFunction::elaborate_scope(Design*des, NetScope*scope) const
collect_scope_signals(scope, wires);
elaborate_scope_enumerations(des, scope, enum_sets);
// Scan through all the named events in this scope.
elaborate_scope_events_(des, scope, events);
@ -1682,6 +1687,8 @@ void PTask::elaborate_scope(Design*des, NetScope*scope) const
collect_scope_signals(scope, wires);
elaborate_scope_enumerations(des, scope, enum_sets);
// Scan through all the named events in this scope.
elaborate_scope_events_(des, scope, events);
@ -1732,6 +1739,8 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
collect_scope_signals(my_scope, wires);
elaborate_scope_enumerations(des, my_scope, enum_sets);
// Scan through all the named events in this scope.
elaborate_scope_events_(des, my_scope, events);
}

View File

@ -44,6 +44,7 @@
# include "netqueue.h"
# include "netscalar.h"
# include "util.h"
# include "parse_api.h"
# include "ivl_assert.h"
using namespace std;
@ -298,6 +299,12 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
if (pp == 0)
continue;
if (pp->is_interface_port()) {
interface_formal_port_t formal;
resolve_interface_formal_port(this, des, pp, formal, true);
continue;
}
// The port has a name and an array of expressions. The
// expression are all identifiers that should reference
// wires within the scope.
@ -397,11 +404,6 @@ void netclass_t::elaborate_sig(Design*des, PClass*pclass)
<< " type=" << *use_type << endl;
}
if (dynamic_cast<const netqueue_t *> (use_type)) {
cerr << cur->second.get_fileline() << ": sorry: "
<< "Queues inside classes are not yet supported." << endl;
des->errors++;
}
set_property(cur->first, cur->second.qual, use_type);
if (! cur->second.qual.test_static())
@ -414,8 +416,17 @@ void netclass_t::elaborate_sig(Design*des, PClass*pclass)
<< "." << endl;
}
/* NetNet*sig = */ new NetNet(class_scope_, cur->first, NetNet::REG,
use_type);
auto sig = new NetNet(class_scope_, cur->first, NetNet::REG,
use_type);
sig->set_line(cur->second);
sig->set_const(cur->second.qual.test_const());
if (cur->second.qual.test_const() &&
cur->second.has_initializer) {
int pidx = property_idx_from_name(cur->first);
ivl_assert(cur->second, pidx >= 0);
set_prop_initialized(pidx);
}
}
for (map<perm_string,PFunction*>::iterator cur = pclass->funcs.begin()
@ -456,6 +467,12 @@ bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
NetScope::scope_vec_t instance = scope->instance_arrays[get_name()];
vector<PExpr*>pins (rmod->port_count());
vector<bool>pins_fromwc (rmod->port_count(), false);
vector<bool>pins_is_explicitly_not_connected (rmod->port_count(), false);
flag &= match_module_ports_(des, rmod, scope, pins, pins_fromwc,
pins_is_explicitly_not_connected);
for (unsigned idx = 0 ; idx < instance.size() ; idx += 1) {
// I know a priori that the elaborate_scope created the scope
// already, so just look it up as a child of the current scope.
@ -471,6 +488,9 @@ bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
}
ivl_assert(*this, my_scope->parent() == scope);
if (!bind_interface_ports_(des, rmod, scope, my_scope, pins, pins_fromwc))
flag = false;
if (! rmod->elaborate_sig(des, my_scope))
flag = false;
@ -507,7 +527,7 @@ bool PGenerate::elaborate_sig(Design*des, NetScope*container) const
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; ++ cur ) {
PGenerate*item = *cur;
const PGenerate*item = *cur;
if (item->directly_nested || !item->scope_list_.empty()) {
flag &= item->elaborate_sig(des, container);
}
@ -555,7 +575,7 @@ bool PGenerate::elaborate_sig_direct_(Design*des, NetScope*container) const
if (item->scheme_type == PGenerate::GS_CASE) {
for (generate_it_t icur = item->generate_schemes.begin()
; icur != item->generate_schemes.end() ; ++ icur ) {
PGenerate*case_item = *icur;
const PGenerate*case_item = *icur;
if (case_item->directly_nested || !case_item->scope_list_.empty()) {
flag &= case_item->elaborate_sig(des, container);
}
@ -591,6 +611,7 @@ bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
elaborate_sig_funcs(des, scope, funcs);
elaborate_sig_tasks(des, scope, tasks);
elaborate_sig_classes(des, scope, classes);
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t cur = generate_schemes.begin()
@ -1181,8 +1202,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope)
pull = new NetLogic(scope, scope->local_symbol(),
1, pull_type, wid);
pull->set_line(*this);
pull->pin(0).drive0(IVL_DR_SUPPLY);
pull->pin(0).drive1(IVL_DR_SUPPLY);
pull->pin(0).drive(drive_strength_t(IVL_DR_SUPPLY,
IVL_DR_SUPPLY));
des->add_node(pull);
wtype = NetNet::WIRE;
}
@ -1215,7 +1236,6 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope)
if (wtype == NetNet::WIRE) sig->devirtualize_pins();
sig->set_line(*this);
sig->port_type(port_type_);
sig->lexical_pos(lexical_pos_);
if (ivl_discipline_t dis = get_discipline()) {
sig->set_discipline(dis);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2024 Stephen Williams (steve@icarus.com)
* Copyright (c) 2012-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -220,11 +220,13 @@ ivl_type_t struct_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
res->set_line(*this);
res->packed(packed_flag);
bool is_packed = packed_flag || (union_flag && soft_flag);
res->packed(is_packed);
res->set_signed(signed_flag);
if (union_flag)
res->union_flag(true);
if (union_flag) {
res->union_flag(true, soft_flag);
}
for (list<struct_member_t*>::iterator cur = members->begin()
; cur != members->end() ; ++ cur) {
@ -242,7 +244,7 @@ ivl_type_t struct_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
; cur_name != curp->names->end() ; ++ cur_name) {
decl_assignment_t*namep = *cur_name;
if (packed_flag && namep->expr) {
if (is_packed && namep->expr) {
cerr << namep->expr->get_fileline() << " error: "
<< "Packed structs must not have default member values."
<< endl;
@ -372,9 +374,8 @@ ivl_type_t elaborate_array_type(Design *des, NetScope *scope,
type = elaborate_darray_check_type(des, li, type, "Dynamic array");
type = new netdarray_t(type);
continue;
} else if (dynamic_cast<PENull*>(lidx)) {
// Special case: Detect the mark for a QUEUE declaration,
// which is the dimensions [null:max_idx].
} else if (dynamic_cast<PEQueueDimension*>(lidx)) {
// Special case: Detect the mark for a QUEUE declaration.
type = elaborate_static_array_type(des, li, type, dimensions);
type = elaborate_queue_type(des, scope, li, type, ridx);
continue;
@ -450,27 +451,7 @@ ivl_type_t typedef_t::elaborate_type(Design *des, NetScope *scope)
if (!elab_type)
return netvector_t::integer_type();
bool type_ok = true;
switch (basic_type) {
case ENUM:
type_ok = dynamic_cast<const netenum_t *>(elab_type);
break;
case STRUCT: {
const netstruct_t *struct_type = dynamic_cast<const netstruct_t *>(elab_type);
type_ok = struct_type && !struct_type->union_flag();
break;
}
case UNION: {
const netstruct_t *struct_type = dynamic_cast<const netstruct_t *>(elab_type);
type_ok = struct_type && struct_type->union_flag();
break;
}
case CLASS:
type_ok = dynamic_cast<const netclass_t *>(elab_type);
break;
default:
break;
}
bool type_ok = basic_type.matches(elab_type);
if (!type_ok) {
cerr << data_type->get_fileline() << " error: "

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,7 @@
# include <cmath>
# include "netlist.h"
# include "netclass.h"
# include "ivl_assert.h"
# include "netmisc.h"
@ -2182,6 +2183,25 @@ static bool get_array_info(const NetExpr*arg, long dim,
left = range.get_msb();
right = range.get_lsb();
return false;
}
/* Class property (e.g. queue field): size is dynamic; defer to runtime
* instead of folding to all-X in evaluate_array_funcs_. */
if (const NetEProperty*prop = dynamic_cast<const NetEProperty*>(arg)) {
const NetNet*obj = prop->get_sig();
const netclass_t*cls = dynamic_cast<const netclass_t*>(obj->net_type());
if (cls == 0) return true;
ivl_type_t ptype = cls->get_prop_type(prop->property_idx());
if (ptype == 0) return true;
switch (ptype->base_type()) {
case IVL_VT_DARRAY:
case IVL_VT_QUEUE:
case IVL_VT_STRING:
defer = true;
return true;
default:
break;
}
return true;
}
/* The argument must be a signal that has enough dimensions. */
const NetESignal*esig = dynamic_cast<const NetESignal*>(arg);

View File

@ -337,6 +337,7 @@ ivl_type_packed_width
ivl_type_prop_name
ivl_type_prop_type
ivl_type_properties
ivl_type_queue_max
ivl_type_signed
ivl_udp_init

View File

@ -1,7 +1,7 @@
#ifndef IVL_ivl_dlfcn_H
#define IVL_ivl_dlfcn_H
/*
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -21,7 +21,11 @@
#if defined(__MINGW32__)
# include <windows.h>
#if defined(__cplusplus)
# include <cstdio>
#else
# include <stdio.h>
#endif
typedef void * ivl_dll_t;
#elif defined(HAVE_DLFCN_H)
# include <dlfcn.h>
@ -32,7 +36,7 @@ typedef shl_t ivl_dll_t;
#endif
#if defined(__MINGW32__)
inline ivl_dll_t ivl_dlopen(const char *name, bool)
static inline ivl_dll_t ivl_dlopen(const char *name, bool global_flag)
{
static char full_name[4096];
unsigned long length = GetFullPathName(name, sizeof(full_name),
@ -40,16 +44,18 @@ inline ivl_dll_t ivl_dlopen(const char *name, bool)
if ((length == 0) || (length > sizeof(full_name)))
return 0;
(void)global_flag;
return (void *)LoadLibrary(full_name);
}
inline void *ivl_dlsym(ivl_dll_t dll, const char *nm)
static inline void *ivl_dlsym(ivl_dll_t dll, const char *nm)
{ return (void *)GetProcAddress((HINSTANCE)dll,nm);}
inline void ivl_dlclose(ivl_dll_t dll)
static inline void ivl_dlclose(ivl_dll_t dll)
{ (void)FreeLibrary((HINSTANCE)dll);}
inline const char *dlerror(void)
static inline const char *dlerror(void)
{
static char msg[256];
unsigned long err = GetLastError();
@ -66,10 +72,10 @@ inline const char *dlerror(void)
}
#elif defined(HAVE_DLFCN_H)
inline ivl_dll_t ivl_dlopen(const char*name, bool global_flag)
static inline ivl_dll_t ivl_dlopen(const char*name, bool global_flag)
{ return dlopen(name,RTLD_LAZY|(global_flag?RTLD_GLOBAL:0)); }
inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
static inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
{
void*sym = dlsym(dll, nm);
/* Not found? try without the leading _ */
@ -78,24 +84,28 @@ inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
return sym;
}
inline void ivl_dlclose(ivl_dll_t dll)
static inline void ivl_dlclose(ivl_dll_t dll)
{ dlclose(dll); }
#elif defined(HAVE_DL_H)
inline ivl_dll_t ivl_dlopen(const char*name)
{ return shl_load(name, BIND_IMMEDIATE, 0); }
static inline ivl_dll_t ivl_dlopen(const char*name, bool global_flag)
{
(void)global_flag;
inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
return shl_load(name, BIND_IMMEDIATE, 0);
}
static inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
{
void*sym;
int rc = shl_findsym(&dll, nm, TYPE_PROCEDURE, &sym);
return (rc == 0) ? sym : 0;
}
inline void ivl_dlclose(ivl_dll_t dll)
static inline void ivl_dlclose(ivl_dll_t dll)
{ shl_unload(dll); }
inline const char*dlerror(void)
static inline const char*dlerror(void)
{ return strerror( errno ); }
#endif

View File

@ -2400,6 +2400,10 @@ extern int ivl_type_properties(ivl_type_t net);
extern const char* ivl_type_prop_name(ivl_type_t net, int idx);
extern ivl_type_t ivl_type_prop_type(ivl_type_t net, int idx);
/* Maximum element count for a queue type (0 = unbounded). Only valid
* when ivl_type_base(net) == IVL_VT_QUEUE. */
extern unsigned ivl_type_queue_max(ivl_type_t net);
#if defined(__MINGW32__) || defined (__CYGWIN__)
# define DLLEXPORT __declspec(dllexport)

View File

@ -89,4 +89,4 @@ uninstall:
rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/ivlpp@EXEEXT@"
lexor.o: lexor.c globals.h
main.o: main.c globals.h $(srcdir)/../version_base.h ../version_tag.h
main.o: main.c globals.h ../version_base.h ../version_tag.h

View File

@ -1599,10 +1599,10 @@ static void macro_start_args(void)
* entry for arg 0. This will be used by macro_finish_arg() to
* calculate the buffer location for arg 1.
*/
if (def_buf) {
def_buf_free = def_buf_size - 1;
def_buf[0] = 0;
}
def_buf_grow_to_fit(1);
def_buf_free = def_buf_size - 1;
def_buf[0] = 0;
def_argo[0] = 0;
def_argl[0] = 0;
def_argc = 1;
@ -1692,7 +1692,6 @@ static void expand_using_args(void)
char* head;
char* tail;
char* dest;
int arg;
int length;
if (def_argc > cur_macro->argc) {
@ -1721,7 +1720,7 @@ static void expand_using_args(void)
if (*tail != ARG_MARK) {
tail++;
} else {
arg = tail[1]; assert(arg < def_argc);
int arg = tail[1]; assert(arg < def_argc);
const char*use_argv;
int use_argl;
@ -2369,6 +2368,8 @@ void reset_lexor(FILE* out, char* paths[])
isp->stringify_flag = 0;
isp->comment = NULL;
yyout = out;
if (isp->file == 0) {
perror(paths[0]);
error_count += 1;
@ -2383,8 +2384,6 @@ void reset_lexor(FILE* out, char* paths[])
}
}
yyout = out;
yyrestart(isp->file);
assert(istack == 0);

1
ivtest/.gitignore vendored
View File

@ -34,4 +34,5 @@ tmp_blif.vvp
dump.vcd
dump.lxt
dump.lx2
dump.fst
foo.vcd

70
ivtest/Makefile.in Normal file
View File

@ -0,0 +1,70 @@
#
# This source code is free software; you can redistribute it
# and/or modify it in source code form under the terms of the GNU
# Library General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
SHELL = /bin/sh
abs_srcdir=@abs_srcdir@
srcdir=@srcdir@
suffix = @install_suffix@
ifeq (@install_suffix@,)
opts =
else
opts = --suffix=$(suffix)
endif
all:
check:
check-installed:
@status=0; \
$(MAKE) check-installed-vvp || status=1; \
$(MAKE) check-installed-vvp-py || status=1; \
$(MAKE) check-installed-vpi || status=1; \
exit $$status
check-installed-vpi:
@echo "Running vpi_reg.pl"
ifeq (@LIBVERIUSER@,yes)
cd $(abs_srcdir); perl vpi_reg.pl --with-pli1 $(opts)
else
cd $(abs_srcdir); perl vpi_reg.pl $(opts)
endif
check-installed-vvp:
@echo "Running vvp_reg.pl"
cd $(abs_srcdir); perl vvp_reg.pl $(opts)
check-installed-vvp-py:
@echo "Running vvp_reg.py"
cd $(abs_srcdir); python3 vvp_reg.py $(opts)
clean:
rm -f $(srcdir)/*.vpi
rm -rf $(srcdir)/log $(srcdir)/vpi_log $(srcdir)/work
distclean: clean
rm -f Makefile
install:
uninstall:
Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; ./config.status --file=ivtest/$@
.PHONY: check-installed check-installed-vpi check-installed-vvp check-installed-vvp-py

View File

@ -1,5 +1,6 @@
#!/bin/sh
# Copyright (c) 1998-2026 Stephen Williams (steve@icarus.com)
#
# This source code is free software; you can redistribute it
# and/or modify it in source code form under the terms of the GNU

View File

@ -23,7 +23,7 @@
./ivltests/always_comb_warn.v:32: warning: A for statement step must be a simple binary +/- to be synthesized in an always_comb process.
./ivltests/always_comb_warn.v:32: warning: System task ($display) cannot be synthesized in an always_comb process.
./ivltests/always_comb_warn.v:33: warning: System task ($display) cannot be synthesized in an always_comb process.
./ivltests/always_comb_warn.v:34: warning: Dynamic array delete method cannot be synthesized in an always_comb process.
./ivltests/always_comb_warn.v:34: warning: Dynamic array ordering/delete method cannot be synthesized in an always_comb process.
./ivltests/always_comb_warn.v:35: warning: System task ($display) cannot be synthesized in an always_comb process.
./ivltests/always_comb_warn.v:14: warning: An event (tevt) cannot be synthesized in an always_comb process.
./ivltests/always_comb_warn.v:13: warning: A non-integral variable (trl) cannot be synthesized in an always_comb process.

View File

@ -21,7 +21,7 @@
./ivltests/always_ff_warn.v:33: warning: A for statement step must be a simple binary +/- to be synthesized in an always_ff process.
./ivltests/always_ff_warn.v:33: warning: System task ($display) cannot be synthesized in an always_ff process.
./ivltests/always_ff_warn.v:34: warning: System task ($display) cannot be synthesized in an always_ff process.
./ivltests/always_ff_warn.v:35: warning: Dynamic array delete method cannot be synthesized in an always_ff process.
./ivltests/always_ff_warn.v:35: warning: Dynamic array ordering/delete method cannot be synthesized in an always_ff process.
./ivltests/always_ff_warn.v:36: warning: System task ($display) cannot be synthesized in an always_ff process.
./ivltests/always_ff_warn.v:15: warning: An event (tevt) cannot be synthesized in an always_ff process.
./ivltests/always_ff_warn.v:14: warning: A non-integral variable (trl) cannot be synthesized in an always_ff process.

View File

@ -21,7 +21,7 @@
./ivltests/always_latch_warn.v:32: warning: A for statement step must be a simple binary +/- to be synthesized in an always_latch process.
./ivltests/always_latch_warn.v:32: warning: System task ($display) cannot be synthesized in an always_latch process.
./ivltests/always_latch_warn.v:33: warning: System task ($display) cannot be synthesized in an always_latch process.
./ivltests/always_latch_warn.v:34: warning: Dynamic array delete method cannot be synthesized in an always_latch process.
./ivltests/always_latch_warn.v:34: warning: Dynamic array ordering/delete method cannot be synthesized in an always_latch process.
./ivltests/always_latch_warn.v:35: warning: System task ($display) cannot be synthesized in an always_latch process.
./ivltests/always_latch_warn.v:14: warning: An event (tevt) cannot be synthesized in an always_latch process.
./ivltests/always_latch_warn.v:13: warning: A non-integral variable (trl) cannot be synthesized in an always_latch process.

View File

@ -1,18 +1,5 @@
./ivltests/br1005.v:2: sorry: Queues inside classes are not yet supported.
./ivltests/br1005.v:15: error: Enable of unknown task ``a.q.push_back''.
./ivltests/br1005.v:16: error: Enable of unknown task ``a.q.push_back''.
./ivltests/br1005.v:17: error: Enable of unknown task ``a.q.push_back''.
./ivltests/br1005.v:18: error: Enable of unknown task ``a.q.push_back''.
./ivltests/br1005.v:19: sorry: Method name nesting is not supported yet.
./ivltests/br1005.v:19: : method path: q.pop_front
./ivltests/br1005.v:19: error: Object test.a has no method "q.pop_front(...)".
./ivltests/br1005.v:22: sorry: Method name nesting is not supported yet.
./ivltests/br1005.v:22: : method path: q.pop_front
./ivltests/br1005.v:22: error: Object test.a has no method "q.pop_front(...)".
./ivltests/br1005.v:25: sorry: Method name nesting is not supported yet.
./ivltests/br1005.v:25: : method path: q.pop_front
./ivltests/br1005.v:25: error: Object test.a has no method "q.pop_front(...)".
./ivltests/br1005.v:28: sorry: Method name nesting is not supported yet.
./ivltests/br1005.v:28: : method path: q.pop_front
./ivltests/br1005.v:28: error: Object test.a has no method "q.pop_front(...)".
9 error(s) during elaboration.
1
2
3
4
PASSED

View File

@ -0,0 +1,9 @@
./ivltests/br_gh1140a.v:5: error: Dimensions must be a constant with no unknown or high-Z bits.
./ivltests/br_gh1140a.v:5 : This MSB expression violates the rule: LPX
./ivltests/br_gh1140a.v:6: error: Dimensions must be a constant with no unknown or high-Z bits.
./ivltests/br_gh1140a.v:6 : This MSB expression violates the rule: LPZ
./ivltests/br_gh1140a.v:7: error: Dimensions must be a constant with no unknown or high-Z bits.
./ivltests/br_gh1140a.v:7: : This LSB expression violates the rule: LPX
./ivltests/br_gh1140a.v:8: error: Dimensions must be a constant with no unknown or high-Z bits.
./ivltests/br_gh1140a.v:8: : This LSB expression violates the rule: LPZ
4 error(s) during elaboration.

View File

@ -0,0 +1,17 @@
./ivltests/br_gh1140b.v:10: error: Dimensions must be a constant with no unknown or high-Z bits.
./ivltests/br_gh1140b.v:10 : This MSB expression violates the rule: LPX
./ivltests/br_gh1140b.v:11: error: Dimensions must be a constant with no unknown or high-Z bits.
./ivltests/br_gh1140b.v:11 : This MSB expression violates the rule: LPZ
./ivltests/br_gh1140b.v:12: error: Dimensions must be a constant with no unknown or high-Z bits.
./ivltests/br_gh1140b.v:12: : This LSB expression violates the rule: LPX
./ivltests/br_gh1140b.v:13: error: Dimensions must be a constant with no unknown or high-Z bits.
./ivltests/br_gh1140b.v:13: : This LSB expression violates the rule: LPZ
./ivltests/br_gh1140b.v:5: error: Dimensions must be a constant with no unknown or high-Z bits.
./ivltests/br_gh1140b.v:5 : This MSB expression violates the rule: LPX
./ivltests/br_gh1140b.v:6: error: Dimensions must be a constant with no unknown or high-Z bits.
./ivltests/br_gh1140b.v:6 : This MSB expression violates the rule: LPZ
./ivltests/br_gh1140b.v:7: error: Dimensions must be a constant with no unknown or high-Z bits.
./ivltests/br_gh1140b.v:7: : This LSB expression violates the rule: LPX
./ivltests/br_gh1140b.v:8: error: Dimensions must be a constant with no unknown or high-Z bits.
./ivltests/br_gh1140b.v:8: : This LSB expression violates the rule: LPZ
8 error(s) during elaboration.

View File

@ -0,0 +1,9 @@
./ivltests/br_gh1140c.v:8: error: Dimensions must be a constant with no unknown or high-Z bits.
./ivltests/br_gh1140c.v:8 : This size expression violates the rule: LPX
./ivltests/br_gh1140c.v:9: error: Dimensions must be a constant with no unknown or high-Z bits.
./ivltests/br_gh1140c.v:9 : This size expression violates the rule: LPZ
./ivltests/br_gh1140c.v:5: error: Dimensions must be a constant with no unknown or high-Z bits.
./ivltests/br_gh1140c.v:5 : This size expression violates the rule: LPX
./ivltests/br_gh1140c.v:6: error: Dimensions must be a constant with no unknown or high-Z bits.
./ivltests/br_gh1140c.v:6 : This size expression violates the rule: LPZ
4 error(s) during elaboration.

View File

@ -1,4 +1,3 @@
./ivltests/br_gh1175c.v:3: syntax error
./ivltests/br_gh1175c.v:3: errors in UDP table
./ivltests/br_gh1175c.v:1: error: Invalid table for UDP primitive id_0.

View File

@ -1,4 +1,3 @@
./ivltests/br_gh1175d.v:3: syntax error
./ivltests/br_gh1175d.v:3: errors in UDP table
./ivltests/br_gh1175d.v:1: error: Invalid table for UDP primitive id_0.

View File

@ -1,4 +1,3 @@
./ivltests/br_gh1175e.v:3: syntax error
./ivltests/br_gh1175e.v:3: errors in UDP table
./ivltests/br_gh1175e.v:1: error: Invalid table for UDP primitive id_0.

View File

@ -0,0 +1 @@
FST info: dumpfile dump.fst opened for output.

View File

@ -3,4 +3,4 @@
./ivltests/br_gh72b_fail.v:8: error: too few arguments for `macro2
./ivltests/br_gh72b_fail.v:9: error: too few arguments for `macro2
./ivltests/br_gh72b_fail.v:10: error: too many arguments for `macro2
Preprocessor failed with 5 errors.
Preprocessor failed with 5 error(s).

View File

@ -0,0 +1,2 @@
ivltests/decl_before_use1.v:4: warning: net/variable `v` used before declaration.
ivltests/decl_before_use1.v:9: : the net/variable is declared here.

View File

@ -0,0 +1,2 @@
1
used before declaration

View File

@ -0,0 +1,2 @@
ivltests/decl_before_use2.v:3: warning: net/variable `w` used before declaration.
ivltests/decl_before_use2.v:10: : the net/variable is declared here.

View File

@ -0,0 +1,2 @@
00000001
used before declaration

View File

@ -0,0 +1,2 @@
ivltests/decl_before_use3.v:4: warning: event `e` used before declaration.
ivltests/decl_before_use3.v:8: : the event is declared here.

View File

@ -0,0 +1 @@
used before declaration

View File

@ -0,0 +1 @@
used before declaration

View File

@ -0,0 +1,2 @@
ivltests/decl_before_use5.v:4: warning: parameter `w` used before declaration.
ivltests/decl_before_use5.v:8: : the parameter is declared here.

View File

@ -0,0 +1,2 @@
10101010
used before declaration

View File

@ -0,0 +1,2 @@
10
FAILED

View File

@ -0,0 +1,3 @@
./ivltests/pr1909940.v:4: warning: net/variable `in` used before declaration.
./ivltests/pr1909940.v:5: : the net/variable is declared here.
PASSED

View File

@ -0,0 +1,3 @@
./ivltests/pr1909940b.v:4: warning: net/variable `in` used before declaration.
./ivltests/pr1909940b.v:5: : the net/variable is declared here.
PASSED

View File

@ -0,0 +1,3 @@
ivltests/sv_cast_indexed_target_fail.v:9: error: Dimensions after a type identifier are not allowed in a cast target.
ivltests/sv_cast_indexed_target_fail.v:5: : The type was declared here.
Elaboration failed

View File

@ -0,0 +1,4 @@
ivltests/sv_cast_type_error_once_fail.v:8: error: Unable to bind parameter `missing' in `test'
ivltests/sv_cast_type_error_once_fail.v:8: error: Dimensions must be a constant with no unknown or high-Z bits.
ivltests/sv_cast_type_error_once_fail.v:8 : This MSB expression violates the rule: missing
2 error(s) during elaboration.

View File

@ -0,0 +1 @@
ivltests/sv_class_method_call_nonvoid.v:14: warning: User function 'value' is being called as a task.

View File

@ -0,0 +1 @@
PASSED

View File

@ -0,0 +1,2 @@
ivltests/sv_enum_reference_order_relaxed.v:7: warning: enum named constant `VALUE` used before declaration.
ivltests/sv_enum_reference_order_relaxed.v:10: : the enum named constant is declared here.

View File

@ -0,0 +1 @@
PASSED

View File

@ -0,0 +1,2 @@
ivltests/sv_interface_port_array_modport_restrict_fail.v:10: error: Cannot assign to input modport member `value' through interface port `bus'.
1 error(s) during elaboration.

View File

@ -0,0 +1,2 @@
ivltests/sv_interface_port_array_size_mismatch_fail.v:12: error: Interface array port `bus' expects 2 element(s) but actual `buses' has 1 element(s).
Elaboration failed

Some files were not shown because too many files have changed in this diff Show More