Compare commits

..

1083 Commits

Author SHA1 Message Date
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
Cary R aec9fe98ab Development is now V14 2026-03-01 15:16:47 -08:00
Cary R 9d0f6fc995 Add CREATE_BRANCH.sh script 2026-03-01 14:48:46 -08:00
Cary R 68ba79eb7a Update the default suffix to be dev for master 2026-03-01 14:43:58 -08:00
Cary R 42d591d296 Update install docs and remove a doc build warning 2026-03-01 14:41:22 -08:00
Cary R f3506a8c92 Update the test scripts to print the suffix being used 2026-03-01 14:37:51 -08:00
Cary R 9a7d852782 Fix some documentation links 2026-02-28 07:28:27 -08:00
Cary R 5d8fcdd7bc Specify the documentation is in english 2026-02-28 07:18:08 -08:00
Cary R 9d3cd045ef Update vvp_reg.py to use env to find python3 2026-02-28 07:06:10 -08:00
Cary R 5beeeee3fa Update the development documentation to match reality 2026-02-28 07:06:01 -08:00
Cary R d736cffc11 The MAKE_* scripts are obsolete 2026-02-28 05:35:32 -08:00
Cary R 2302fa37d5 Add V13 release notes 2026-02-27 21:17:43 -08:00
Cary R 15d6e83f8d Cleanup cppcheck 2026-02-24 23:53:57 -08:00
Cary R 4af84bfaad Fix sdf_interconnect4 failure and reenable 2026-02-24 22:24:17 -08:00
Cary R 9b44d55e9a Make br_gh1248 SV safe 2026-02-20 01:23:27 -08:00
Cary R 935f92da05 Disable sdf_interconnect4 until vpi_handle_multi() is working properly 2026-02-20 00:54:53 -08:00
Cary R 71c8963922 Cleanup space issues 2026-02-19 23:48:10 -08:00
Cary R 8385b13356 Add test for br_gh1248 2026-02-19 23:46:15 -08:00
Cary R b46fbe0892 Another const declaration that can be added 2026-02-19 23:40:42 -08:00
Cary R 5e1f1055e1 Add more const declarations 2026-02-19 23:40:34 -08:00
Cary R. de3e50e486
Merge pull request #1249 from FlinkbaumFAU/improve_interconnect_handling
Improve INTERCONNECT handling for SDF Annotation
2026-02-19 23:06:28 -08:00
Cary R 7786fb67c3 Fix manual PDF generation 2026-02-08 23:07:56 -08:00
Cary R f071957736 New cppcheck cleanup 2026-02-08 22:41:47 -08:00
Cary R a838d5143d cleanup Makefile and add complete man PDF generation 2026-02-08 22:41:35 -08:00
Cary R 4cc6ae35dd Fix the valgrind cleanup of automatic array vars 2026-02-06 21:35:13 -08:00
Cary R 911a20c134 Update blif check script to work with python3 2026-02-06 15:06:42 -08:00
Cary R 9da5c1868f New cppcheck cleanup 2026-02-06 15:06:28 -08:00
Cary R 827e08f8d3 Switch blif test to support python3 and use common program name 2026-02-06 09:48:52 -08:00
Cary R 826672705e Move all simulation callback decls to the header 2026-02-06 09:48:41 -08:00
Cary R e9f26a2f11 Declare vpiPostsim() in a header file 2026-02-06 01:59:11 -08:00
Cary R 8f7b2a23eb pthread_exit() is no longer needed and fixes vvp return 2026-02-06 01:55:36 -08:00
Cary R 9df3cc3126 Skip allocating monitor structure until the start of simulation 2026-02-06 01:52:01 -08:00
Cary R 26ba3f62e3 Use "--keep-debuginfo=yes" for valgrind testing 2026-02-06 01:51:49 -08:00
Cary R dc1763bbf5 Add missing include of algorithm in PExpr.cc 2026-01-26 19:26:11 -08:00
Cary R 5b0ce2c6ca Waive last cppcheck message in vvp 2026-01-26 02:12:17 -08:00
Cary R 2f05c831c0 Add more windows get64 fixes 2026-01-25 18:17:59 -08:00
Cary R 8014c5cee2 Add missing declaration for vpi_get64 to vvp.def 2026-01-25 18:00:55 -08:00
Cary R ebf2dc1685 Add basic support for vpi_get64() to return the nexus pointer 2026-01-25 17:50:06 -08:00
Cary R 49fc24a798 Make main directory cppcheck clean 2026-01-25 13:17:18 -08:00
Cary R 33e28df834 Add final cppcheck waivers to get vpi clean 2026-01-25 12:47:16 -08:00
Cary R 7916ae3c49 Make blif cppcheck clean 2026-01-25 12:17:11 -08:00
Cary R 67e48188a9 Make driver-vpi cppcheck clean 2026-01-25 11:09:15 -08:00
Cary R 60b13d020c The sizer is -tsizer 2026-01-25 11:08:58 -08:00
Cary R f040d513a5 Add missing dump.lxt2 2026-01-22 23:05:08 -08:00
Cary R. dfa824c03e
Merge pull request #1259 from oscargus/viewerdocs
Fix issues with waveform viewer documentation and mention Surfer
2026-01-22 22:44:23 -08:00
Cary R. 6b276fa316
Merge pull request #1212 from gian21391/pthread-to-std-thread
Using C++11 threads instead of pthread
2026-01-22 22:42:10 -08:00
Cary R 128d970d60 Remove memory leak when checking if a package has any dumpable items 2026-01-21 20:50:44 -08:00
Cary R 068f33b35a Remove memory leak when multi-bit module path delays fail 2026-01-21 20:50:32 -08:00
Cary R e51ce2a8e9 Cleanup vhdl and most of vvp cppcheck issues 2026-01-19 22:54:45 -08:00
Cary R c3d550e03e More cppcheck cleanup 2026-01-19 19:50:10 -08:00
Cary R 2345c51478 Dosify needs to use CPPCHECK and LDFLAGS 2026-01-13 03:07:30 -08:00
Cary R. 964878382d
Merge pull request #1279 from aelmahmoudy/fix-missing-buildflags
Add CPPFLAGS & LDFLAGS for building version.exe & draw_tt build targets
2026-01-13 02:50:41 -08:00
Cary R 78fa7a5a10 Update program copyright to 2026 2026-01-13 02:04:37 -08:00
Cary R 4d0a277f3b Cleanup the python version of vlog95 2026-01-13 01:25:24 -08:00
Cary R 951ede0922 A bunch more cppcheck cleanup 2026-01-13 01:25:01 -08:00
Cary R 6651df6f2c Update the vlog95 python tests to pass more options 2026-01-08 01:36:30 -08:00
Cary R 385a0fb46a vlog95: remove check for dimensions in array pattern 2026-01-07 23:51:18 -08:00
Cary R 7dbaa67a02 vlgo95: add partial array pattern support and other cleanup 2026-01-07 23:32:16 -08:00
Cary R 918976651a Fixes for vlog95 generation and gold file updates 2026-01-06 23:02:55 -08:00
Cary R c3abb84ce6 Fix compile warning when long and int have the same width 2026-01-05 20:50:35 -08:00
Cary R 5708010a5c Fix warning in sys_fst.c 2026-01-05 19:12:11 -08:00
Cary R c172a0d3a7 More cppcheck cleanup 2026-01-05 18:59:08 -08:00
Cary R e5943047da Add preliminary support for Python vlog95 testing 2025-12-30 19:44:06 -08:00
Cary R aad14df3d7 Switch to std::round() and a common routine for real to uint64_t 2025-12-16 19:52:36 -08:00
Cary R eff75f8209 Update msys2 ARM LDFLAGS to not use msys strtod hack 2025-12-16 19:52:29 -08:00
Cary R 44611f8301 Add missing override in vhdlpp 2025-12-08 20:58:07 -08:00
Cary R 2b45f4c399 Python test cleanup 2025-12-08 20:57:56 -08:00
Cary R 95ffc97f5f Some cppcheck cleanup for vhdlpp 2025-12-08 20:57:44 -08:00
Cary R 4f31fec5c8 Fix any_of() return 2025-11-23 01:58:48 -08:00
Cary R d87dbb08cf cppcheck updates 2025-11-23 01:31:14 -08:00
Cary R 1c6f0e768a Update vvp_reg.py to support strict, force-sv and with-valgrind 2025-11-22 13:31:27 -08:00
Martin Whitaker 1b1def7f79 CI: update test runner to use macos-15-intel.
macos-13 is deprecated and will be unavailable after December 8th.
2025-11-11 22:53:04 +00:00
Martin Whitaker f5708a0322 Add regression test for issue #1286. 2025-11-11 22:00:06 +00:00
Martin Whitaker 28717b4de7 Don't include duplicate nodes in NetEvent objects (issue #1286).
Currently, when a constant bit/part select is found in the implicit
sensitivity list for an always_* construct, it is replaced by the
entire signal. If there is more than one bit/part select from the
same signal, that signal gets added to the list multiple times. This
breaks the algorithm used to detect duplicate events in the nodangle
functor, causing it to erroneously merge non-identical events in some
cases.

The proper fix is to support sensitivity at the bit/part level, as
required by IEEE 1800. But for now, just make sure we only include
the entire signal once, regardless of how many different bit/part
selects we find. Enhance the "sorry" message to report which signals
are contributing excessively to the process sensitivity.
2025-11-11 21:59:31 +00:00
Cary R 3b209301e2 More cppcheck cleanup 2025-11-11 01:22:11 -08:00
Cary R 87d9d0ac74 Cleanup python test script and add support for a suffix 2025-11-11 01:21:46 -08:00
Cary R a7502173d3 Fix MSYS2 builds after cleanup 2025-10-25 11:09:39 -07:00
Cary R d697312cf8 Cleanup ivt casting for cppcheck 2025-10-25 10:54:12 -07:00
Martin Whitaker efb0ea2ec7 Try a different way to disable PLI1 in MSYS2 CLANG CI. 2025-10-25 15:54:50 +01:00
Martin Whitaker 70094ce564 Disable PLI1 support in MSYS2/CLANG CI. 2025-10-25 15:49:11 +01:00
Martin Whitaker e32584f228 Remove spurious space in MSYS2 PKGBUILD. 2025-10-25 15:23:12 +01:00
Martin Whitaker 9bf45a85e2 Fix errors in MSYS2 PKGBUILD. 2025-10-25 15:15:51 +01:00
Martin Whitaker 97da696b5a Add missing gperf dependency in MSYS2 PKGBUILD. 2025-10-25 14:33:22 +01:00
Martin Whitaker d392dcf07f Fix syntax error in github workflow. 2025-10-25 14:22:51 +01:00
Martin Whitaker e4b3f1bc69 Make MSYS2 build instructions more prominent in the documentation. 2025-10-25 14:16:00 +01:00
Martin Whitaker b69cb8efda Update documentation to describe the --enable-libveriuser config option.
Also fix a typo in the --with-valgrind description.
2025-10-25 14:16:00 +01:00
Martin Whitaker d766248bc1 Update CI to also test ucrt64 and clang64 builds in MSYS2. 2025-10-25 14:16:00 +01:00
Martin Whitaker 587d87bb96 Update MSYS2 PKGBUILD to support ucrt64 and clang64 as well as mingw64.
Also allow extra configuration options to be passed via the
IVL_CONFIG_OPTIONS environment variable and add some missing
dependencies. Don't include --enable-libveriuser by default.
Update the README accordingly, with sensible line wrapping.
2025-10-25 14:16:00 +01:00
Martin Whitaker da853622e9 Don't delete vvp/libvvp.h when running 'make clean'. 2025-10-25 14:16:00 +01:00
Cary R cc496c3cf3 More ivl cppcheck cleanup 2025-10-23 10:01:06 -07:00
Martin Whitaker 3d4f1eb94b Improved run_program() in Perl regression test scripts.
This version works with the native Windows (mingw64 and clang64)
versions of Perl in MSYS2.

Note that warnings are disabled in the Environment.pm module because
Perl fails to notice that OLDOUT and OLDERR are used when restoring
the STDOUT and STDERR file handles.
2025-10-21 21:47:45 +01:00
Cary R 702189a948 Add correct C++ cast for the vpi_modules 2025-10-21 00:44:23 -07:00
Cary R b7292e0179 Another fix for msys CI 2025-10-21 00:27:35 -07:00
Cary R 0b7bd36960 Fix msys2 compile issue in CI 2025-10-21 00:16:35 -07:00
Cary R 860761f9c6 More cppcheck fixes - part 2 2025-10-20 23:54:15 -07:00
Cary R 08c8ee081a More cppcheck updates 2025-10-20 23:54:15 -07:00
Cary R. 929fbf3507
Merge pull request #1282 from steveicarus/msys2-clang-support
MSYS2 clang support
2025-10-20 19:42:30 -07:00
Martin Whitaker 5f651d944b Check that pointers returned by tf_getp are valid.
When the argument is a literal string, tf_getp returns a pointer to
the string. But the return type is a PLI_INT32, so on machines where
pointers are larger than 32 bits, the pointer value may get truncated.
Check for this at run time, and if it occurs, print a warning and
return 0.
2025-10-18 22:31:07 +01:00
Martin Whitaker 6210c307fa Update CI scripts to continue testing PLI 1 support. 2025-10-18 20:07:23 +01:00
Martin Whitaker 935910c3c9 Modify VPI test suite to make PLI 1 tests optional. 2025-10-18 20:05:58 +01:00
Martin Whitaker cf66c64e32 Make support for PLI 1 (libveriuser and cadpli) a config option.
PLI 1 was deprecated in 1364-2005, so disable by default and note that
it is deprecated in the help text.

This works round the problem that the clang linker (lld) in MSYS2 does
not support the -r option, so cannot be used to build libveriuser.a.
2025-10-18 20:02:48 +01:00
Martin Whitaker 8e2d543304 Rework makefiles to eliminate the use of dlltool in Windows builds.
The clang dlltool is not compatible with the binutils dlltool. However
both the clang and binutils linkers support reading the .def file and
creating the import library directly, so we no longer need to perform
the link in two stages.
2025-10-18 20:00:19 +01:00
Martin Whitaker 10770c9129 Optimise Perl regression test scripts.
When redirection operators are included in a command string passed to
the system() subroutine, it spawns an intermediate shell to handle the
redirection. This is particularly inefficient when running the tests
in MSYS2. Creating our own version of system() based on fork() and
exec() allows us to handle the redirection directly.
2025-10-17 20:58:05 +01:00
Martin Whitaker 884349caab Two compiler warning fixes. 2025-10-13 19:18:20 +01:00
Cary R 94dcd658c8 Update exe and manual pages to report @(C) 2025 2025-10-12 19:13:30 -07:00
Cary R fcb543d6e5 Some cppcheck cleanup 2025-10-12 17:37:50 -07:00
Cary R d79e49a372 Fix compile warning 2025-10-12 17:37:50 -07:00
Martin Whitaker 9c62154924 Fix some new compiler warnings seen when using GCC 15 and clang 21.
No functional changes.
2025-10-12 22:23:24 +01:00
Martin Whitaker 4372560290 Post-snapshot cleanup 2025-10-12 11:32:34 +01:00
Martin Whitaker 3e7cc4eac2 Creating snapshot s20251012 2025-10-12 11:32:34 +01:00
Cary R cc1ead51c7 Add a define for CC which is used by the iverilog-vpi script 2025-10-11 11:04:54 -07:00
Cary R 12b87da742 Update config.guess and config.sub to latest versions 2025-10-11 11:02:12 -07:00
Martin Whitaker fede5239ba Fix builds using both --enable-suffix and --enable-libvvp options.
We need to build libvvp with a suffix from the outset to ensure that
the vvp binary searches for the correct library file name once it is
installed.

Also Windows DLLs need to be stored in the same directory as the main
program, not in a separate lib directory.
2025-10-11 12:03:29 +01:00
Martin Whitaker 23b6f955d4 Fix suffixed vvp build under Windows.
Commit 95810b2f61 mistakenly added the suffix to the output file name
when linking the final vvp.exe binary. 'make check' and 'make install'
assume the suffix is only added when installing.
2025-10-11 10:39:46 +01:00
Martin Whitaker a4c90fb5f0 Add regression test for issue #1273. 2025-10-07 21:54:11 +01:00
Martin Whitaker 936f92ebe6 vvp: demangle identifiers when parsing the input file (issue #1273).
The tgt-vvp code generatpr outputs identifiers as quoted strings, and
because of this, escapes any " and \ characters (which may appear in
escaped indentifiers). We need to undo this when reading them into
vvp, so that the original name is seen by the VPI routines.
2025-10-07 21:53:11 +01:00
Martin Whitaker 1fdeb7b982 Add regression tests for $fmonitor tasks.
Also add a test for multiple $monitor task calls and $monitoron and
$monitoroff.
2025-10-05 12:37:30 +01:00
Martin Whitaker 753a52b56c Add support for $fmonitor tasks (issue #1280) 2025-10-05 12:34:25 +01:00
أحمد المحمودي (Ahmed El-Mahmoudy) 8de5e68e83 Add CPPFLAGS & LDFLAGS for building version.exe & draw_tt build targets
Those are needed to be able to add security hardening buold flags by
downstream package maintainers
2025-09-28 17:23:40 +02:00
Cary R. d67d3323ad
Merge pull request #1270 from wsnyder/pr1008_finish
Update pr1008.v test to $finish
2025-09-02 07:51:04 -07:00
Wilson Snyder d400fa21bd Update pr1008.v to $finish 2025-09-01 13:41:25 -04:00
Martin Whitaker dad78d5258 Move details of non-standard behaviour from README to Documentation.
Some of this was duplicated in the documentation, some of it was only
in the README. Let's have it all in one place, linked to from the
README.
2025-08-03 18:19:45 +01:00
Martin Whitaker 1be953cfa6 Move documentation of additional system tasks from quirks to extensions. 2025-08-03 17:38:24 +01:00
Martin Whitaker fa5fc0eca0 Copy portability notes from old Wiki to new documentation area.
From https://iverilog.fandom.com/wiki/Verilog_Portability_Notes

Also add formatting tags to $readmempath documentation to make style
consistent.
2025-08-03 17:32:55 +01:00
Martin Whitaker c0e44b4849 Update README to reflect current state of Verilog/SystemVerilog support.
Also
 - remove reference to mingw.txt, which no longer exists
 - extended types are now enabled/disabled by -gxtypes/-gno-xtypes
2025-08-03 15:47:53 +01:00
Cary R db82380cec Minor cppcheck updates in vvp and switch vvp to use override for virtual functions 2025-07-21 23:32:34 -07:00
Cary R 8bd9cb14e7 Cleanup cppcheck suppression file 2025-07-21 23:24:56 -07:00
Cary R 5a4cb616d1 Fix and cleanup tgt-vp based on cppcheck results 2025-07-21 23:21:57 -07:00
Cary R b979441de2 Improve error messages when bad code is passed to the parser 2025-07-21 14:46:56 -07:00
Cary R c7d37bcc21 Error when trying to elaborate a field of a simple variable 2025-07-16 23:37:14 -07:00
Cary R eceb48e5d6 Add better error messages for output port elaboration issues 2025-07-16 22:37:49 -07:00
Cary R e55d9454da Calling front() on an empty() list is undefined 2025-07-13 19:38:43 -07:00
Cary R 30f1de9062 Elaborate input port default value expressions in the correct scope 2025-07-09 09:19:42 -07:00
Cary R cfb8ec17d2 Remove space issues 2025-07-09 07:41:16 -07:00
Martin Whitaker 60e4023e6f Fix log output ordering for vpi_control test when running in Windows.
MSYS2 buffers stderr, so we need to flush the buffers to ensure the
log file matches the gold file.
2025-07-08 22:24:46 +01:00
Martin Whitaker a883f2afe6 Add regression test for vpi_control() return value (issue #1208). 2025-07-08 21:52:13 +01:00
Martin Whitaker 7161dc0ab1 Fix return type of vpi_control() and vpi_sim_control() (issue #1208).
These were implemented as returning nothing (void), and passing an
invalid operation value would trigger an assertion failure. The IEEE
standards define them as returning 1 on success and 0 on failure.

vpi_sim_control() is the name used in Verilog-AMS. Strictly speaking
it should return a bool, but to avoid polluting the namespace by
including stdbool.h, we return a PLI_INT32. As C is a weakly typed
language, this should make no practical difference.
2025-07-08 21:14:49 +01:00
Oscar Gustafsson afc1b2a51b Fix issues with waveform viewer documentation and mention Surfer 2025-07-06 12:47:35 +02:00
Martin Whitaker fd7029a299 Add regression tests for issue #1258. 2025-07-05 22:52:52 +01:00
Martin Whitaker dd714d78c4 Make -gno-specify suppress unsupported timing check warnings (issue #1258) 2025-07-05 22:44:59 +01:00
Martin Whitaker aec91c7754 Add regression tests for issue #1256. 2025-07-05 18:21:32 +01:00
Martin Whitaker 0ecb71625b Support assignment of parray slices (issue #1256)
The existing elaboration code only allowed assignments from/to individual
elements and either failed an assertion (when assigning the entire array)
or failed to compile (when assigning an array slice).
2025-07-05 18:02:40 +01:00
Cary R f82c6c7b3a Add missing gold and fix VHDL inout test 2025-07-01 00:04:09 -07:00
Cary R 66d57628bf Check what can drive a variable in SystemVerilog 2025-06-30 23:48:26 -07:00
Cary R a05da1ca08 Only synth when the R-value is valid 2025-06-30 16:25:16 -07:00
Cary R 46a5078a68 When optimizing the size of a case keep the sign of the condition 2025-06-25 00:11:22 -07:00
Cary R 6426afc8d0 Avoid overflow in genvar to make duplicate 2025-06-21 18:27:54 -07:00
Cary R a2ffbc307a Validate the generate "loop" expressions 2025-06-21 16:58:30 -07:00
Cary R adcb9f4e0d Add support for passing a real input to logic, mos and if gates 2025-06-21 10:04:12 -07:00
Cary R 26c01e7f0a Use preincrement instead of post in for loop incr 2025-06-20 12:48:01 -07:00
Michael Kupfer 7c60005d1a Improve INTERCONNECT handling for SDF Annotation
Improve path search between nets, so that paths containing
concats as well as part selects can be found.

Signed-off-by: Michael Kupfer <michael.kupfer@fau.de>
2025-06-06 17:34:09 +02:00
Cary R ea26587b5e The FST dump file is now a fstWriterContext 2025-05-11 22:53:29 -07:00
Cary R 1aec31ac27 Update to the latest FST files from GTKWave 2025-05-11 22:30:40 -07:00
Martin Whitaker b11749e04c Remove Ubuntu 20.04 from workflows as the runner has been retired. 2025-05-11 11:59:04 +01:00
Martin Whitaker b7f9be9370 Add regression test for issue #1242. 2025-05-11 11:39:29 +01:00
Martin Whitaker 2b01cf335c Increment line number when parsing "// synthesis" pragmas (issue #1242)
Thanks to Robert Lance for proposing the fix.
2025-05-11 11:38:28 +01:00
Cary R. 7e238e7ca5
Merge pull request #1229 from AndreasLoow/typo
Typo in `regress-vvp.list`
2025-03-31 13:00:05 -07:00
Andreas Lööw 4138fcf6c4 typo in regress-vvp.list 2025-03-31 08:44:22 +01:00
Lars-Peter Clausen f5decd471d
Merge pull request #1228 from AndreasLoow/typos
Typos in regress-sv.list
2025-03-30 21:03:06 -07:00
Andreas Lööw 7e95dfff5a remove trailing commas 2025-03-30 13:51:44 +01:00
Andreas Lööw bf45073359 typo: nornal -> normal 2025-03-30 13:51:20 +01:00
Cary R b0c57ab177 Update fstapi files to latest from GTKWave 2025-03-12 17:43:38 -07:00
Gianluca Martino 60f5026ae4 Fixed double join in lxt2 writer. 2025-02-25 16:06:32 +01:00
Gianluca Martino 25104ca2a8
work_queue_fill is an unsigned so we can simplify the condition variable predicate.
Co-authored-by: Lars-Peter Clausen <lars@metafoo.de>
2025-02-25 12:54:59 +01:00
Gianluca Martino 9afaf6f136 Removed pthread dependency in vcd_priv2.cc 2025-02-19 11:11:40 +01:00
Gianluca Martino cfa4a289ec Adding missing include. 2025-02-19 10:39:40 +01:00
Cary R 99580cd051 Fix warnings that toupper() takes an int 2025-02-17 09:37:18 -08:00
Cary R 6088a26d78 Update VPI example to not have warnings 2025-02-13 01:04:41 -08:00
Cary R 1b729831b7 Cast ispace()/isdigit() args to int to remove warning 2025-02-13 00:03:18 -08:00
Cary R 0ca26c95d8 Cygwin also does not have docopt by default 2025-02-13 00:03:09 -08:00
Cary R 7f4ff37ad0 For cygwin we need to use -std=gnu++11 to get strdup() 2025-02-13 00:02:54 -08:00
Lars-Peter Clausen 14375567c7
Merge pull request #1203 from larsclausen/cast-to-real
Reject invalid casts to real
2025-01-15 19:37:41 -08:00
Lars-Peter Clausen eb90bcf313 Add regression tests for invalid casts to real
Check that invalid casts to real are reported as an error.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2025-01-12 20:34:31 -08:00
Lars-Peter Clausen 4c03ac5b36 Reject invalid casts to real
Only vector types can be cast to real. Report an error when trying to cast
a different type instead of triggering an assert later on.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2025-01-12 19:51:59 -08:00
Cary R 30123f8945 Update fstapi.c to the latest from GTKWave 2025-01-08 19:37:13 -08:00
Lars-Peter Clausen 27bae7eab1
Merge pull request #1201 from larsclausen/nested-lvalue-types
tgt-vvp: Support nested lvalues for all property types
2025-01-07 19:51:37 -08:00
Lars-Peter Clausen e2008c9c0e Add regression tests for nested lvalue object properties
Check that nested object properties of different types are supported as
lvalues.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2025-01-05 16:55:16 -08:00
Lars-Peter Clausen 60b6435653 tgt-vvp: Support nested lvalues for all property types
Currently nested lvalues are only supported for vector typed properties.
Refactor the code to also support other types.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2025-01-05 16:54:18 -08:00
Lars-Peter Clausen b794b9cc26
Merge pull request #1199 from larsclausen/assignment-op
Add support for assignment ops on class properties and dynamic array or queue elements
2025-01-05 16:53:04 -08:00
Lars-Peter Clausen 9f8a8959a7 Add regression tests for assignment operators on queue and darray elements
Check that assignment operators work as expected on queue and dynamic array
elements.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2025-01-05 15:55:34 -08:00
Lars-Peter Clausen 7c970e91b9 Add regression tests for assignment operators on class properties
Check that assignment operators are supported for class properties.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2025-01-05 15:55:20 -08:00
Lars-Peter Clausen 43c138fdd3 tgt-vvp: Support assignment operators on queues and dynamic array elements
Currently assignment operators on queues and dynamic elements trigger an
assert.

Add support for handling this properly. Since the operation for loading an
element for an queue or dynamic array is identical most of the code can be
shared, only writing back the value has to be handled separately.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2025-01-05 15:55:01 -08:00
Lars-Peter Clausen 867c7d18b4 tgt-vvp: Support assignment operators on object properties
Currently assignment operators on object properties are silently
ignored. Make sure that they are handled.

To enable this refactor the code a bit so that the assignment
operator handling can be shared between object property assignments
and scalar value assignments.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2025-01-05 15:55:01 -08:00
Lars-Peter Clausen d0327c5eda
Merge pull request #1200 from larsclausen/class-property-logic-init
vvp: Fix logic class property initialization
2025-01-05 15:52:12 -08:00
Lars-Peter Clausen c22b375c86 Add regression test for logic class property default value
Check that class logic class properties get initialized to 'x.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2025-01-05 09:46:07 -08:00
Lars-Peter Clausen 4854de06ca vvp: Fix logic class property initialization
Logic type class properties use the wrong constructor resulting in a
default value of a vector with 0 width. Switch to the right constructor to
fix this.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2025-01-05 09:34:25 -08:00
Martin Whitaker 4471961ed4 Modify snapshot/release creation scripts to run autoconf.sh
Then temporarily add the resulting configure and lexor_keywords.cc
files to the repository so they will be included in the snapshot and
release tarballs that are automatically generated by GitHub. Remove
these files in the post-snapshot/post-release cleanup.
2025-01-05 13:53:22 +00:00
Lars-Peter Clausen 23a7c80dde
Merge pull request #1197 from larsclausen/tgt-vvp-remove-implict-cast
tgt-vvp: Remove implicit casts between vector and real
2025-01-03 10:41:37 -08:00
Cary R e3a5567ceb Document how to override a string parameter 2025-01-03 10:41:11 -08:00
Martin Whitaker 9e60be2946 Post-snapshot cleanup 2025-01-03 17:34:34 +00:00
Martin Whitaker 82ee4f6cd6 Creating snapshot s20250103 2025-01-03 17:34:34 +00:00
Martin Whitaker 471914b12d Add new scripts for creating snapshots and releases.
The old MAKE_SNAPSHOT.sh and MAKE_RELEASE.sh scripts created tarballs
that could be uploaded to icarus.com and SourceForge. Now we release
on GitHub, we need to make all the necessary changes in the git
repository, temporarily creating a release_tag.h file and deleting it
after we have created the snapshot or release tag. This allows GitHub
to automatically generate the tarballs for us.
2025-01-03 17:34:12 +00:00
Martin Whitaker fe2e89202e Modify verilog.spec to make it easier to update the version numbers. 2025-01-03 17:12:41 +00:00
Martin Whitaker b000a9cf29 Use release_tag.h instead of version_tag.h for snapshots/releases.
Now we publish releases on GitHub, we need to commit the file to the
repository when making a snapshot or release, so we need to use a
different filename to the one that is automatically generated by
'git describe' (which we still want git to ignore).
2025-01-03 17:09:29 +00:00
Lars-Peter Clausen 1e9cfc34c0 tgt-vvp: Remove implicit casts between vector and real
Remove implicit casts between vector and real in tgt-vvp. These are not
required since any implicit cast in the source will be converted to an
explicit cast in the elaboration stage.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2025-01-02 17:40:29 -08:00
Martin Whitaker 8cd7bb3584 Update gold files to match typo fix in previous commit. 2025-01-01 11:22:00 +00:00
Martin Whitaker 52b34e6d91 Fix typo in warning message (issue #1195) 2025-01-01 10:59:48 +00:00
Cary R 875828f862 Update to latest fstapi.c file 2024-12-31 13:50:39 -08:00
Martin Whitaker ee021dbce4 Fix whitespace in vvp flags on-line documentation. 2024-12-31 18:08:36 +00:00
Martin Whitaker f3abd94e9b Add regression test for issue #1184.
This checks the temporary fix of outputing a suitable "sorry" message.
2024-12-31 17:15:19 +00:00
Martin Whitaker 84848e8e04 vvp: fail gracefully on multi-bit modpath delays (issue #1184)
The code doesn't currently handle the case of different bits within
the vector needing different delays (e.g. when the rise and fall
delays are different and some bits are rising as other bits are
falling) and aborts with an assertion failure. For now, output a
suitable "sorry" message and exit gracefully.
2024-12-31 16:59:23 +00:00
Martin Whitaker 05d4e3fc73 Add reminder about vvp extended argument usage to on-line documention.
Although the introductory paragraph seems clear enough, add a reminder
at the start of the section on extended arguments that they must appear
after the input file name.
2024-12-31 15:28:55 +00:00
Martin Whitaker 88aae83bec Add missing vvp flags in the on-line documentation.
The -i, -n. -N, and -V flags were documented in the man page, but not
in vvp_flags.rst.
2024-12-31 15:22:28 +00:00
Martin Whitaker a3903c6cd3 Document the new vvp quiet flag. 2024-12-31 15:16:09 +00:00
Martin Whitaker 0119f0d1e8 Add regression test for vvp quiet flag. 2024-12-31 15:05:38 +00:00
Martin Whitaker adb6a2f454 Add vvp "quiet" flag (issue #1193)
This adds a "-q" option on the vvp command line and a vvp_set_quiet_flag()
function in the VVP library API. Setting this flag will cause all output
to standard output via MCD bit 0 to be suppressed. It will not prevent the
output being sent to a log file if the vvp "-l" option has been used, and
it will not affect output to the STDOUT file descriptor.
2024-12-31 13:05:36 +00:00
Cary R 03835c9d50 Report each line that has a var decl in an unnamed block 2024-12-28 20:51:30 -08:00
Cary R 788a94b310 Nested generate regions are illegal 2024-12-28 18:46:37 -08:00
Cary R d484cb63d6 Avoid seg fault when the range for a module/gate is empty 2024-12-28 17:16:16 -08:00
Cary R 47cf3707fc Fix some warnings from msys2 build 2024-12-28 10:09:01 -08:00
Cary R. abaa32f793
Merge pull request #1192 from larsclausen/fix-macos-ci
Use `-undefined dynamic_lookup` for linking loadable modules on MacOS
2024-12-27 10:42:36 -08:00
Lars-Peter Clausen 342ba62618 Use `-undefined dynamic_lookup` for linking loadable modules on MacOS
Newer version of the linker on MacOS provide a deprecation warning when
using the `-undefined` flag with the `suppress` value. This is cause CI to
fail to do logs not matching when building VPI modules.

Switch to using the `dynamic_lookup` value for the flag instead, which
resolves the warning and is the behavior we want when loading the module.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-12-26 18:08:24 -08:00
Cary R. 06077ed026
Update test.yml to switch back to macos-13 2024-12-09 08:48:26 -08:00
Cary R. 0914af4c6a
Update test.yml to try macos-14 large 2024-12-09 08:46:58 -08:00
Cary R. 0a671ea459
Update test.yml to use macos-13 2024-12-09 08:31:15 -08:00
Cary R 8edf14ae68 Check for primitive port mismatches and other error cleanup 2024-12-08 22:21:51 -08:00
Cary R b745119746 Update Makefile.in to install PDF correctly 2024-11-27 02:00:41 -08:00
Cary R 361e16bed2 Fix some valgrind compile warnings 2024-11-27 00:11:50 -08:00
Cary R a676078ffc Update config.guess and config.sub 2024-11-26 23:46:58 -08:00
Cary R 527b0daed6 Fix some clang warnings 2024-11-26 23:33:52 -08:00
Martin Whitaker 62727e8b2e Add regression tests for packed/unpacked array parameter declarations.
These are currently unsupported, so should result in a compiler error.
2024-11-15 21:10:51 +00:00
Martin Whitaker b2eaedfc94 Emit "sorry" message for unpacked array parameter declarations (issue #1180)
These aren't yet supported. Make it an error if not compiling fpr a
SystemVerilog generation.
2024-11-15 21:01:12 +00:00
Martin Whitaker aec18a6c19 Emit "sorry" message for packed array parameter declarations (issue #1180)
These aren't yet supported. Make it an error if not compiling fpr a
SystemVerilog generation.
2024-11-15 20:24:58 +00:00
Martin Whitaker 6c8ed62a5a Add regression test for issue #1181. 2024-11-10 19:34:36 +00:00
Martin Whitaker 2817bf59c5 tgt-vlog95: fix mixed-scope multiple constant assignments to a net (issue #1181)
The vlog95 code generator collects all the constant assignments to a net
within each scope and then emits them. The old code only recorded the
ivl_signal_t for each constant assignment, which meant it had to iterate
through the nexus pointers in the assicated nexus to find the constant.
When there were multiple constant assignments to the same net, it needed
to record which assignments had already been emitted, which it did by
keeping a count in the nexus private data and skipping that many constants
on each successive assignment. However the count did not get reset after
emitting all the assignments in that scope, so if there were assignments
to the same net made in another scope, the count would already be positive
and those assignments would also be skipped.

This could probably have been fixed by clearing the nexus private data
after processing the constant assignment list for each scope, but it is
more efficient to record the ivl_nexus_ptr_t for each constant along with
the ivl_signal_t, eliminating the need to search for the associated nexus
pointer.
2024-11-10 13:31:54 +00:00
Cary R 96d28250bd br_gh1178b uses inout which cannot be translated currently 2024-11-09 17:43:32 -08:00
Cary R 7a4e17661a Fix gold file for br_gh1178a (repeat concatenation) 2024-11-09 17:22:40 -08:00
Cary R 00fcd58fab A repeat concatenation cannot be used as a net l-value 2024-11-09 17:21:44 -08:00
Cary R 5e7e7622b4 Update to latest files from GTKWave 2024-11-09 14:07:06 -08:00
martinwhitaker ce7b26e3f9
Merge pull request #1106 from daglem/part-select-address-overflow
Guard against overflow / wrap around of internal bit address
2024-11-03 12:03:07 +00:00
Lars-Peter Clausen d8c3c51ab1
Merge pull request #1176 from HD787/hd787/typo-fixes
Some typo fixes in the developer docs,
2024-10-09 19:13:58 -07:00
henry 01d28ea277 typo fixes 2024-10-07 23:20:12 -05:00
Dag Lem ba7da9d5a5 Guard against overflow / wrap around of internal part-select bit address
Internally, the maximum address space of a vector is 31 bits + a sign bit
to signal invalid addresses (out of bounds or has one or more x or z bits).

This commit ensures that unsigned part-select bit addresses which would
otherwise overflow and wrap around within this address space are correctly
handled as out of bounds.
2024-09-16 23:50:24 +02:00
Dag Lem ff47e6bfbe Correct normalization of base address for bit- and part-selects
The required bit width for the address calculation should now be
exactly determined in all cases.

The normalization is also considerably simplified.
2024-09-16 23:05:43 +02:00
Martin Whitaker 25a84d5cfc Update vlog95 test list for tests containing incomplete for loops.
The for loop initialisation statement, termination condition, and step
statement were only made optional in IEEE 1800-2012. Commit 0695c1fe
enforced this. So we need to compile with -g2012. The vlog95 code
generator doesn't currently translate this, so the tests will fail
when compiling the translated code.
2024-09-07 18:08:44 +01:00
Martin Whitaker 2ab57a2b09 Add regression test for return type of $bits (issue #1163). 2024-09-07 17:56:15 +01:00
Martin Whitaker 0136db7ee7 Fix the return type of the $bits system function (issue #1163)
Early editions of the SystemVerilog standard did not specify the return
type for $bits, so we made it 32 bit unsigned 2-state. Later editions
state the return type is integer (32 bit signed 4-state), so make it so.
2024-09-07 17:52:28 +01:00
martinwhitaker 34ed6f6f97
Merge pull request #1168 from steveicarus/fix-vvp-cg-array-word-aliasing
Fix vvp cg array word aliasing
2024-09-07 17:04:57 +01:00
martinwhitaker 74ba42e2df
Merge pull request #1166 from larsclausen/fix-ix-load-sign
tgt-vvp: Use signedness of expression instead of signal for index load
2024-09-07 17:04:40 +01:00
martinwhitaker 07d5c6fb0c
Merge pull request #1164 from larsclausen/fix-undefined-delay
Fix vector assignment with undefined delay
2024-09-07 17:04:16 +01:00
Martin Whitaker ae78218c2f Add regression test for issue #1155. 2024-09-03 21:38:09 +01:00
Martin Whitaker d6abe59983 Improve annotation in vvp code generation. 2024-09-03 21:34:46 +01:00
Martin Whitaker f8947a6aab Fix indentation and white space. 2024-09-03 21:34:12 +01:00
Martin Whitaker d99add9dbe Fix vvp code generator for array word alias corner case (issue #1155)
When multiple words in one array were connected to the same nexus as a
single word array, the code generator was sometimes failing to generate
all the necessary aliases. This was highly dependent on the elaboration
order.

This fix should be more robust, but there are currently no tests in the
test suite that cause the compiler to generate whole-array aliases, and
I can't think of a way to make it do so as we don't yet support unpacked
arrays in module ports, so that branch of the code is currently untested.
2024-09-03 21:24:25 +01:00
Lars-Peter Clausen 841e5a9d9e ivtest: Add regression test to check that shift rhs is always unsigned
Add a regression test to check that the right-hand side of a shift
operation is always treated as unsigned, even if it is a signed registers
or a variation thereof.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-09-02 19:09:06 +02:00
Lars-Peter Clausen 50d9a32d56 tgt-vvp: Use signedness of expression instead of signal for index load
When loading a signal into into an index register currently the signedness
of the signal is used when deciding whether sign-extension should be
performed or not. But this can lead to incorrect results, instead the
signedness of the expression must be used as that might be different from
the signal. E.g.

```
reg signed [1:0] = 2'b10;
$display(1 << x[1:0]);
```

gives the wrong result without this.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-09-02 19:09:06 +02:00
Lars-Peter Clausen fa83f42cba ivtest: Add regression test for undefined intra-assignment delay
Check that assignments with undefined intra-assignment delay get executed
with zero delay. The assignment should not be skipped.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-09-02 14:11:29 +02:00
Lars-Peter Clausen 80fd301fc1 tgt-vvp: Fix vector assignment with undefined delay
Assignments with an undefined intra-assignment delay should be treated like
assignments with zero delay. For the most part this is implemented
correctly, except for assignments to a part of a vector where the offset
inside the vector is an immediate value. E.g.
```
reg [1:0] x;
integer d = 'x;
...
x[0] <= #d 1'b1
```

Here when loading the delay into the index register flag 4 is updated, but
never cleared afterwards. As a result, if the delay is undefined, the vector
assignment will be skipped. Fix this by making sure flag 4 is always
cleared before the vector assignment instruction.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-09-02 14:10:25 +02:00
Cary R. cbdaa865a1
Merge pull request #1162 from larsclausen/vvp-immediate
tgt-vvp: Replace `%pushi ...; %op` with `%opi`
2024-08-31 16:50:44 -07:00
Lars-Peter Clausen de9d5e98b1 tgt-vvp: Replace `%pushi ...; %op` with `%opi`
For sequences where the tgt-vvp backend generates `%pushi` followed by one
of the operations that have an immediate version replace it with the
immediate version. This is slightly more efficient.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-08-31 13:46:30 +02:00
Cary R 8c56b2d116 libbz2-dev is needed for Ubuntu 24.04 2024-08-16 22:27:27 -07:00
Cary R 99160f65b8 Add Ubuntu 24.04 to the test list 2024-08-16 22:10:49 -07:00
Cary R 6f743cd8db Only add -D__USE_MINGW_ANSI_STDIO=1 for MINGW64/32 2024-08-16 18:37:23 -07:00
Cary R cba2417db5 Update the test files to return the number of failures 2024-08-16 18:20:13 -07:00
Cary R ff9a520742 Updateing to latest files from GTKWave 2024-08-16 17:40:33 -07:00
Cary R 676b36e455 Fix space issues in the source code 2024-07-21 11:19:41 -07:00
Martin Whitaker 548010e36b Fix compiler generation option for br_gh801 tests.
These test null for-loop initialisation and step, so need -g2012.
2024-07-13 11:46:08 +01:00
Martin Whitaker 488fbfc412 Add regression tests for checking for-loops are fully specified in SV 2009-. 2024-07-13 11:37:23 +01:00
Martin Whitaker 0695c1fe9a Only allow null for-loop initialisation/termination/step for SV 2012+.
As discussed in issue #1143, the for loop initialisation statement,
termination condition, and step statement were only made optional in
IEEE 1800-2012. So check all three are present when compiling for
ealier generations.
2024-07-13 11:28:18 +01:00
Martin Whitaker cb6544fac3 Add regression tests for issue #1143. 2024-07-09 22:22:39 +01:00
Martin Whitaker 82a122372b Handle optional condition/step when evaluating for loops at compile time.
This fixes the compiler segfault seen in issue #1143.
2024-07-09 22:06:41 +01:00
Martin Whitaker a204af04a5 Support for loops with no loop condition.
SystemVerilog makes all of the initialisation, condition, and step
components of a for loop optional. We already support this for the
initialisation and step components.
2024-07-09 21:58:15 +01:00
Martin Whitaker 5cbdff202e Add regression tests for checking constant function call scopes. 2024-06-30 11:52:54 +01:00
Martin Whitaker f3092bba93 Correctly identify scopes for constant function calls (issue #1141)
A constant function call may be inside a named block, so we need to
search upwards to find the enclosing module before checking that the
called function is local to that module.

SystemVerilog allows constant function calls to reference functions
in (other) packages or in the $unit scope, so extend the checks to
permit that.
2024-06-30 11:50:59 +01:00
Cary R dc6f9f2049 make exit an alias for finish at the VVP command line 2024-06-17 10:19:44 -07:00
Cary R adb5731ace A package name must have more than three characters 2024-06-17 09:34:13 -07:00
Cary R 0937de3bee Update to the latest GTKWave files 2024-06-17 09:34:03 -07:00
Martin Whitaker 713b002138 vvp: fix regression in behaviour of -N option (issue #1138)
The -N option was broken by PR #1068. This fix modifies and simplifies
the libvvp API that was introduced in that PR.
2024-06-15 10:47:22 +01:00
Cary R 8ac44a38b3
Merge pull request #1136 from gatk555/actions_macos
Revive Action test.yml.
2024-06-13 06:40:20 -07:00
ga 1aa6a159d0 Fix test.yml for Mac by fixing docopt and using Macos-12 runner.
Update the versions of called Actions to prevent warnings.hi and add
"workflow_dispatch" to allow testing.
Unrelated: add "*.so" to .gitignore to hide built libvvp.so.
2024-06-13 10:36:11 +01:00
Martin Whitaker 94d9d19519 Add regression test for issue #1122. 2024-05-06 21:47:18 +01:00
Martin Whitaker 3b61c0088d vvp: handle tranif enable changes that result from island resolution.
The tran island resolution tests and caches the state of all branch
enable inputs before resolving the branch endpoint values. If a
branch enable is connected directly to a branch endpoint, we need
to update the cached stete and rerun the island resolution if any
enable state changed.

This fixes issue #1122.
2024-05-06 21:37:37 +01:00
Martin Whitaker 615a01c6cd Add libvvp.h to the files that are installed when libvvp is enabled. 2024-04-21 15:20:12 +01:00
martinwhitaker 35f344adf9
Merge pull request #1115 from grebe/single_element_array
Update handling of single-element arrays.
2024-04-16 22:00:19 +01:00
Paul Rigge 28187823ed
Update handling of single-element arrays.
Also, add a test. This fixes #1113.
2024-04-15 13:14:53 -07:00
Martin Whitaker ef7f0a8f38 Add regression tests for early signal elaboration. 2024-04-06 10:19:00 +01:00
Martin Whitaker ca307053f2 Allow nets & variables to be elaborated early on demand.
If a net or variable is referenced in another net or variable declaration
or in a value parameter definition (e.g. when using the $bits function)
and hasn't already been elaborated, we need to elaborate it early. So
during the scope elaboration phase, add placeholders in each NetScope
object to record the PWire objects that are yet to be elaborated. This
allows the symbol_search() function to find the unelaborated objects
and to trigger early elaboration.

Add a flag in the PWire object to indicate when we are elaborating it.
This allows us to detect circular references and avoid an infinite loop.

This fixes issue #483, issue #575, and issue #1097.
2024-04-06 10:10:54 +01:00
Martin Whitaker ff4cd2c5da Merge branch 'declare-before-use' 2024-04-06 09:13:07 +01:00
Martin Whitaker 52d049b513 Add additional regression tests for issue #1099. 2024-02-25 21:55:37 +00:00
Martin Whitaker fc29e51e41 Fix synthesis of signal and part select to keep signed/unsigned type.
If a signal has been cast to a different type, synthesis needs to
reflect the expression type, not the base signal type.

If a part select selects the entire signal, unless otherwise cast,
the expression is unsigned, regardless of the base signal type.

This fixes the additional issues reported in issue #1099.
2024-02-25 21:48:39 +00:00
Martin Whitaker f08ff895af Add informational messages that point to declaration after use. 2024-02-25 16:12:31 +00:00
Martin Whitaker 3624a54f7f Add regression test for issue #1104. 2024-02-24 13:36:25 +00:00
Martin Whitaker 2799799358 Make compiler return non-zero exit code when include file not found.
Most pre-processor errors are flagged to the main compiler by a comment
at the end of the pre-processed output. But certain errors, such as
failing to find or open an include file, cause the pre-processor to
exit immediately, which bypassed the generation of that comment. So
we need to also generate that comment for all early-exit cases.

This fixes issue #1104.
2024-02-24 13:30:27 +00:00
Martin Whitaker 0679d7c8cf Add regression test for issue #1099 2024-02-24 11:49:46 +00:00
Martin Whitaker 09a134d973 Fix synthesis of concatentation to always make result unsigned.
When there is only one operand, we elide the concatenation during
expression synthesis. But if that operand is signed, we need to
insert an intermediate local signel to cast it to unsigned.

This fixes issue #1099.
2024-02-24 11:39:22 +00:00
Martin Whitaker d043c1fa44 Add regression tests for declare before use. 2024-02-20 08:46:28 +00:00
Martin Whitaker f1bf6a7a55 Mark the vhdl_fa4_test4 as NI.
The VHDL pre-processor is generating illegal code for this test case
(using localparam values before they are declared).
2024-02-19 18:41:33 +00:00
Martin Whitaker 76a9d38d87 Add check for parameters used before they are declared. 2024-02-19 18:20:39 +00:00
Martin Whitaker 1c28948484 Pass lexical position information to PTrigger and PNBTrigger objects. 2024-02-19 18:20:14 +00:00
Martin Whitaker cd76bd2371 Fix tests that used variables/nets before declaring them.
The sdf_interconnect tests just need the code reordering. The
pr1909940 tests were written to test use before declaration, so
now need to be CE tests.
2024-02-19 18:20:04 +00:00
Martin Whitaker 649fbb9a59 Modify symbol_search() to only return declared nets and named events.
This only applies to simple identifiers. Only return a match if the
lexical position of the identifier being searched is later in the
source text than the lexical position of a matching symbol.
2024-02-19 18:19:55 +00:00
Martin Whitaker e22831553d Improve identifier lexical position accuracy in declarations.
Enhance the lists of identifiers and declaration assignments generated
by the parser to associate each identifier with its lexical_pos. Also do
this for single items in complex parser rules where the location passed
to the pform is not the location of the identifier.
2024-02-19 18:16:35 +00:00
Martin Whitaker 4159a6a6b1 Pass on lexical position information to NetNet and NetEvent objects. 2024-02-19 18:15:56 +00:00
Martin Whitaker bb80ee6905 Add lexical position information to PWire and PEvent objects. 2024-02-19 18:14:49 +00:00
Martin Whitaker 079108f32b Add lexical position information to PEIdent objects. 2024-02-19 18:13:29 +00:00
Martin Whitaker 8b3f0d63b4 Record the lexical order of identifiers whilst scanning the source files.
This is needed for detecting use before declaration. The lexical scanner
is the only place where we process the source text in strict lexical
order, so do it there.

As Verilog allows modules to span multiple source files, don't reset
the counter when we reset the lexor.
2024-02-19 18:13:05 +00:00
Cary R 61943c844d
Merge pull request #1068 from gatk555/libvvp
Configure option --enable-libvvp allows vvp to be used a shared library
2024-02-18 11:33:44 -08:00
Martin Whitaker ccf925a4f7 Remove the legacy version of symbol_search(). 2024-02-18 09:36:23 +00:00
martinwhitaker 202d41a60c
Merge pull request #1098 from steveicarus/vpi-callback-improvements
VPI callback improvements
2024-02-12 17:42:45 +00:00
Martin Whitaker 72e86d396c Add regression test for issue #703. 2024-02-09 22:38:32 +00:00
Martin Whitaker 855dd3a7e6 Fix new GCC warning when building ivlpp.
Using the old buffer pointer value after a realloc to adjust the pointers
into that buffer is technically undefined behaviour.
2024-02-09 11:52:38 +00:00
Martin Whitaker 616afdc4e7 Fix and improve sim_time_cb test.
cb_data.obj must be set to a valid handle when requesting vpiScaledRealTime.

Check the returned time value as well as the actual callback time. Zero
the requested cb_data after registering the callbacks to make sure it
is not used during the callback execution.
2024-02-09 11:07:08 +00:00
ga 9844212649 Add a check that an instance of libvvp is used only once. 2024-02-07 19:17:32 +00:00
Martin Whitaker 851aed6272 Rationalise new VPI callback test names. 2024-02-07 00:02:58 +00:00
Martin Whitaker 3433c92742 Add regression tests for VPI simulation time callbacks with both time types. 2024-02-06 23:42:12 +00:00
Martin Whitaker 8e754d180e vvp: Add support for vpiScaledRealTime in VPI simulation time callbacks.
Factor out the common code for the four different sync callback types
and extend it.
2024-02-06 23:35:05 +00:00
Martin Whitaker c363231b9c vvp: Add support for value change callback on 2-state array word. 2024-02-06 22:04:23 +00:00
Martin Whitaker 8b357d670d vvp: Comprehensively check the time type passed to vpi_register_cb.
NOTE: This removes the ability to request vpiSuppressTime for the
simulation time callbacks (other than cbNextSimTime). Requesting
this is clearly stated to be an error in IEEE 1364-2001 onwards.
2024-02-06 20:08:10 +00:00
Martin Whitaker ad400ac468 vvp: Remove restriction on time types for cbNextSimTime.
IEEE 1364-1995 has different wording to later versions of the standard,
stating "For reason cbNextSimTime, the time structure is ignored." So
it's possible old VPI code might not pass a valid time pointer or time
structure. So remove the checks that the time pointer is non-null and
that the time type is not vpiSuppressTime.

To allow a user to select the time type, we have to assume that if
the time pointer is non-null, it is a valid pointer and not just an
uninitialised field.
2024-02-06 18:47:54 +00:00
Martin Whitaker 9d04809280 libveriuser: Fix calls to vpi_register_cb that had invalid time types.
When registering a cbReadWriteSynch or cbReadOnlySynch callback,
the time type must be either vpiSimTime or vpiScaledRealTime.
vpiSuppressTime is illegal. The required behaviour is a delay of
zero, so use vpiSimTime with the high and low fields set to 0.
2024-02-06 18:12:32 +00:00
Martin Whitaker 5c1ca6eb93 Extend the VPI value change callback tests.
Cover the vpiSuppressTime and null time pointer cases.
2024-02-06 09:04:13 +00:00
Martin Whitaker 1d793ddba8 vvp: Fix time scaling when using vpiScaledRealTime in VPI callbacks.
The old code only worked for VPI objects that represented variables
and nets. For simulation time callbacks, the user might pass an
object that represents a scope.
2024-02-05 23:24:45 +00:00
Martin Whitaker f3f2dddf9a vvp: Factor out and extend code for finding timescale scope for a VPI object. 2024-02-05 23:23:12 +00:00
Martin Whitaker 872fcd13ae vvp: Factor out code to scale time using the timescale of a VPI object. 2024-02-05 23:21:19 +00:00
Martin Whitaker 0c61923636 Add regression tests for VPI value change callback with time reporting. 2024-02-05 22:04:29 +00:00
Martin Whitaker bb0502a827 vvp: Factor out common code for returning the time of a VPI callback.
This adds support for vpiScaledRealTime in various callbacks where it
wasn't previously supported. However this doesn't work properly when
the cb_data.obj field references a scope handle.
2024-02-05 19:41:23 +00:00
Martin Whitaker 5d40f6ecb2 Restructure and simplify the nextsimtime VPI tests.
Add support for properly testing the vpiScaledRealTime time type for
when it's implemented.
2024-02-05 18:17:53 +00:00
Martin Whitaker cae337231c vvp: Optimise the code for walking the NextSimTime callback list. 2024-02-05 17:53:01 +00:00
Martin Whitaker c0e9b73d1c vvp: Allocate time structures for cbNextSimTime and cbEndOfSimulation.
Previously they were reusing the pointer supplied when the callback
was registered, which is not guaranteed to still be valid.

Note that the IEEE standard states:

    The only fields in the s_cb_data structure that shall need to
    be set up for simulation action or feature callbacks are the
    reason, cb_rtn, and user_data (if desired) fields.

so for cbEndOfSimulation callbacks we cannot rely on the time pointer
being either valid or null. The standard does not require that the
time structure should be filled in when the callback occurs, but for
backwards compatibility continue to do so, returning a vpiSimTime
value.
2024-02-05 17:51:27 +00:00
Cary R 2948e9a89f Update cppcheck to use c++11 2024-02-05 02:21:24 -08:00
Martin Whitaker d364c5e903 Fix indentation and white space. 2024-02-05 08:51:30 +00:00
Jevin Sweval 53e8a139b0 VPI cbNextSimTime: Fill out time and don't call newly generated CBs
Fill out cb_data.time and require it is non-NULL.

Record the last NextSimTime CB so we don't call CBs added during this timestep.

(cherry picked from PR #740)
2024-02-05 08:33:12 +00:00
Martin Whitaker 2299fc1b2b Add regression tests for mixed procedural/continuous assignments. 2024-02-03 22:24:22 +00:00
Martin Whitaker 53b8220b9f Add extra regression tests for multiple drivers on uwires. 2024-02-03 22:23:45 +00:00
Martin Whitaker dd082b849b Improve error message for non-constant bit select in mixed assignment.
Report the conflict with the continuous assignment as the reason this
is not allowed.
2024-02-03 21:58:25 +00:00
Martin Whitaker 3a2a1fb93d Check for mixed assignment conflicts in procedural indexed part selects. 2024-02-03 21:16:57 +00:00
Martin Whitaker d4759e02aa Allow multiple procedural assignents to same part of mixed-mode variables.
If we have a variable which is part driven by a continuous assignment,
the parts that are not driven by that assignment can be the target of
more than one procedural assignment. So we need to only test the cassign
mask, not test and set it, when elaborating the procedural assignments.
2024-02-03 21:12:05 +00:00
Martin Whitaker abb9959339 Factor out code for reporting mixed assignment conflicts.
This makes the error reporting uniform.
2024-02-03 20:24:22 +00:00
Martin Whitaker 9faf8d6b09 Ignore force statements when checking for mixed assignment conflicts.
This was already done in some places. Do it everywhere.
2024-02-03 19:23:15 +00:00
Martin Whitaker 89bb86962f Allow mixed procedural/continuous assignment for array words.
This is legal if the procedural and continuous assignments target
different words.

NOTE: This is not fully compliant with the standard, because vvp
does not know that the nets were originally declared as variables,
so initialises to 'bz instead of 'bx and does not handle release
correctly.
2024-02-03 17:55:32 +00:00
Martin Whitaker cd2d4e9287 Improve error messages when multiple drivers are detected.
Distinguish between nets declared as uwires and variables.
2024-02-03 17:13:53 +00:00
Martin Whitaker 65f552aba3 Mark all words as driven when assigning to an entire uwire array.
This is needed to catch errors if individual words are also separately
driven.
2024-02-03 17:12:08 +00:00
Martin Whitaker 42c5174c8d Improve error messages for mixed procedural/continuous assignments.
We have already eliminated procedural assignments to uwires, so if
we find a l-value of type UNRESOLVED_WIRE, it must be a variable
that has a continuous assignment. Report it as such.
2024-02-03 17:08:44 +00:00
Martin Whitaker 11fc90faf7 Catch procedural assignments to uwires earlier in elaboration.
A uwire is never a valid l-value for a procedural assignment (other
than a force/release), so catch that error as soon as we can. We
then know that any remaining l-values with type UNRESOLVED_WIRE must
be variables which have been coerced by a continuous assignment.
2024-02-03 16:57:36 +00:00
Martin Whitaker a133ae5d9a Add check that entire array isn't both procedurally and continuously assigned.
This fixes issue #1090.
2024-02-03 16:19:22 +00:00
Martin Whitaker 73897b2af6 Refactor code to reduce indentation level.
In preparation for next commit. No functional change.
2024-02-02 22:30:17 +00:00
Martin Whitaker 4667927377 Add flag to NetNet class to indicate a variable has been converted to a uwire.
Internally we convert SystemVerilog variables that have a continuous
assignment into unresolved wires. But from a user's perspective they
are still variables, so we should refer to them as such in error
messages. This new flag lets us distinguish between such variables
and nets that were declared as uwires.
2024-02-02 22:00:57 +00:00
Martin Whitaker 5e139890b6 Add regression test for connecting module output port to array variable (issue #1001). 2024-01-30 23:31:56 +00:00
Martin Whitaker c9d87abc10 Convert unpacked array variable to net when connected to a module output port.
SystemVerilog allows variables to be driven by continuous assignments,
including port connections. Internally we handle this by converting
the NetNet from a REG to an UNRESOLVED_WIRE. Here we handle the case
of an unpacked array variable connected to a module output port.

This fixes issue #1001.
2024-01-30 23:18:03 +00:00
Martin Whitaker 836a9f675e Remove reference to the wiki in the iverilog man page.
The wiki is now obsolete. Use the new documentation site instead.
2024-01-28 23:46:21 +00:00
Martin Whitaker 18a5050c05 Update supported targets in the iverilog man page.
The fpga and vhdl targets are no longer maintained, and the fpga
target is no longer built by default. So best not to advertise
them.
2024-01-28 23:42:11 +00:00
Martin Whitaker e1ba2632d4 Document the -gicarus-misc option in the iverilog man page. 2024-01-28 23:05:21 +00:00
Martin Whitaker 39753da458 Add regression test for disabling binary NAND and NOR operators. 2024-01-28 22:47:46 +00:00
Martin Whitaker 2a2fa059e2 Enable binary NAND and NOR operators with -gicarus-misc (issue #552).
These operators are an Icarus Verilog extension.

Currently -gicarus-misc is enabled by default, so most users won't
see a difference.
2024-01-28 22:41:16 +00:00
Martin Whitaker 6826dbb9cb Fix the pr2966059 regression test.
This test uses 'wire real' but specified the '-gno-xtypes' option.
This is because it named a variable 'wreal' which is a keyword when
that option is enabled.
2024-01-28 19:03:32 +00:00
Martin Whitaker 79c644f550 Update and correct documentation of extended data types (xtypes). 2024-01-28 18:23:29 +00:00
Martin Whitaker 9cccd35e59 Move Icarus Verilog extensions documentation to the usage section.
Also fix the text in the usage section index.
2024-01-28 17:44:23 +00:00
Martin Whitaker 81d7abaf88 Add regression tests for checking wire data types (issue 1087). 2024-01-28 15:53:47 +00:00
Martin Whitaker a8144fd249 Require -gxtypes to use the Icarus extension for wire data types.
e.g. wire bool [1:0]; wire real;

Currently xtypes is enabled by default, so most users won't see a
difference.
2024-01-28 15:48:38 +00:00
Martin Whitaker 56f457d65e Allow force assignments on unresolved wire array words.
A force doesn't require resolution. We already allow this for
individual unresolved wires.
2024-01-28 14:33:17 +00:00
Martin Whitaker 82516c28e2 Enforce rules for non-4-state wires (issue #1087)
When using the Icarus extension for wire types, only logic (4-state)
wires may have multiple drivers (as documented in extensions.rst).
Other types of wire should be treated as unresolved wires.

When the Icarus extension is disabled, only 4-state wires are
allowed (IEEE 1800-2017 section 6.7.1).
2024-01-28 14:14:10 +00:00
Martin Whitaker 18720fe060 Enable the sv_literals test, now that it is fixed (issue #1082) 2024-01-28 12:23:45 +00:00
Martin Whitaker f31d0dcbc5 Zero-extend unsized signed based literal numbers when < integer_width bits.
Whilst the wording in the IEEE standards is ambiguous, discussions on
the standards committee mailing lists clarify that an unsized literal is
supposed to be the same size as an integer (as shown in IEEE 1364-2005
table 5-22). The token following the base format character is specified
to be an unsized number. So to maintain compatibility with the standards
and with other tools, if the unsigned number part of an unsized signed
based literal can be represented in less than integer_width bits and the
MSB is a '1', we need to add a leading zero to ensure it is zero-extended
when used in an expression.

This fixes issue #1082.
2024-01-28 11:51:42 +00:00
Martin Whitaker 8ee1d56e1a Enable the sv_parameter_type test, now it is fixed (issue #1083) 2024-01-27 16:23:40 +00:00
Martin Whitaker fbb2d91927 Add regression tests for issue #1074. 2024-01-27 16:17:31 +00:00
Martin Whitaker ab275a0841 Set undriven bits to zero when only driving one part of a 2-state net.
Arguably this should be done in the target code generator, as the code
generator can infer the value for undriven bits from the net type. But
in practice it is quite hard to do this in the vvp code generator. So
adapt the cprop functor that concatenates part selects to do this as
well.

This fixes issue #1047 and issue #1083.
2024-01-27 15:42:14 +00:00
Martin Whitaker b037d6aef9 Fix cprop merging of part selects to be 2-state aware.
When driving a 2-state net, any undriven bits in the concatenation
of part selects should be driven to '0', not 'z'. This saves having
to cast the result.
2024-01-27 13:34:36 +00:00
Martin Whitaker d0af41442b Add a make_const_0() function to create an all-zero constant net.
Factor out the common code with make_const_x() and make_const_z().
2024-01-27 13:18:40 +00:00
Cary R 01e64861da
Merge pull request #1086 from flaviens/patch-1
Fix typo in README.md
2024-01-24 19:13:11 -08:00
Flavien Solt 9e48bab746
Fix typo in README.md 2024-01-24 16:54:18 +01:00
ga 95810b2f61 Configure with --enable-libvvp builds a shared library containing
almost all of vvp that may be used by other programs.
The vvp program becomes a small client of libvvp.
2024-01-24 11:46:02 +00:00
ga e6ea9bee83 Restore main.cc, completing copy of main.cc to lib_main.cc. 2024-01-24 10:33:40 +00:00
ga 400bda8bed Copy main.cc to lib_main.cc to prepare for libvvp.so.
To examine older history use "git log --follow lib_main.cc".
2024-01-24 10:31:13 +00:00
Stephen Williams 0db1a0cc67
Merge pull request #1085 from steveicarus/steveicarus/readmempath-tests
Move tests pr2509349a/b to the new test format.
2024-01-21 16:13:59 -08:00
Stephen Williams 71b9c551df Move tests pr2509349a/b to the new test format.
This removes the regress-msys2.list file, fixes the output from the
pr2509349a.v test to not be different on different systems, and
documents the $readmempath task.
2024-01-21 15:49:09 -08:00
Stephen Williams ed7cac914c
Merge pull request #1077 from steveicarus/steveicarus/remove-sv-regress
Remove the sv_regress.list file
2024-01-21 13:37:59 -08:00
Stephen Williams 5e97884ccd Remove the sv_regress.list file
This file contained some SystemVerilog tests that are not yet supported.
Move the tests to the regress-vvp.list format, and mark them as NI so
that we know what's going on.
2024-01-20 18:51:43 -08:00
Cary R 38058400f7 Update docs Copyright 2024-01-20 18:10:30 -08:00
Cary R dc047799d6 Update displayed Copyright 2024-01-20 17:52:04 -08:00
Cary R 099e04ec16 Update man page dates 2024-01-20 17:46:02 -08:00
Cary R 33edcda800 Ignore new ivtest output files in git 2024-01-20 17:44:59 -08:00
Cary R b3e5337260 Update fstapi.c file from GTKWAve 2024-01-20 17:44:51 -08:00
Cary R 5c9ec105d9 Fix some compile issues 2024-01-20 12:42:55 -08:00
Cary R d42f97ecbe Cleanup space issues 2024-01-20 11:26:06 -08:00
Cary R f781940444 Update files from GTKWave 2024-01-20 11:18:35 -08:00
Lars-Peter Clausen 6d1a9181bb
Merge pull request #1066 from larsclausen/vvp-concat-performance
vvp: Improve concat performance
2024-01-20 10:49:20 -08:00
Lars-Peter Clausen 5b509e69f6 vvp: concat: Defer update to end of the current simulation cycle
A concat typically has multiple inputs. Whenever one of the input values
change the output value of the concat is updated and propagated to its
downstream consumers.

When multiple inputs change within the same cycle each input will cause a
update propagation. Depending of the overall structure of the design this
can cause a significant performance penalty.

E.g. the following synthetic structure has a exponential runtime increase
based on the value of N.

```
reg [N-1:0] x;
generate for (genvar i = 0; i < N - 1; i++)
  assign x[i+1] = ^{x[i],x[i]};
endgenerate
```

To improve this defer the value propagation of the concat to the end of the
current cycle, this allows multiple input updates to be included in a
single output update.

For the example in report #1052 this reduced the runtime from 2 minutes to
essentially 0.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-01-20 10:32:55 -08:00
Lars-Peter Clausen 4637b39953 vvp: concat: Avoid using individual bit access
The concat functors use individual bit access to initialize and copy
values.

For initialization pass the initial bit value to the constructor and for
coping use set_vec() instead. Both can be a fair bit faster since data is
copied word by word rather than bit by bit.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-01-20 10:32:55 -08:00
Lars-Peter Clausen bb1d3c9ac6 vvp: Implement concat `recv_vec()` using `recv_vec_pv()`
The implementation for partial receive for concat only differs from the
regular receive in that it takes an additional offset.

The regular receive can easily be implemented by calling the partial
receive with an offset of 0. This allows to remove some duplicated code.

The overhead of this is negligible, but to help the compiler to optimize this
a bit better mark the `recv_vec()` and `recv_vec_pv()` functions as final.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-01-20 10:32:55 -08:00
Lars-Peter Clausen 2d611c4347 ivtest: pr1002: Avoid race condition
The pr1002 test has a always block with the `dataout` in its sensitivity
list. It compares `dataout` to `expected_dataout`.

Both `dataout` and `expected_dataout` depend on `datain` and are updated in
the same cycle. This means there is no guarantee in which order they are
updated and the always block might get scheduled before `expected_dataout`
has been updated. This can lead to a test failure.

To avoid this slightly change the test to use a task to perform the
comparison and add an explicit delay before the task is executed so that
all updates have a chance to be fully resolved

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-01-20 10:32:55 -08:00
Lars-Peter Clausen 9b1ac6ab50 ivtest: Fix `assign` vs `initial` race condition in some tests
The first evaluation of an `assign` statement is scheduled at the same time as
`initial` statements.

There are some test cases that evaluate the result of an `assign` statement
in an `initial` statement. This is an inherent race condition and might
fail depending on the exact order of evaluation.

To fix this add an additional delay in the `initial` block. This will make
sure that all `assign` statements get fully resolved first.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-01-20 10:32:02 -08:00
Stephen Williams 192b6aec96
Merge pull request #1070 from larsclausen/ivl_run-escape-char
run_ivl.py: Properly escape `.` in regex
2024-01-19 18:25:46 -08:00
Stephen Williams 8f1fcc988e
Merge pull request #1065 from steveicarus/vvp-undriven-net-initialisation
vvp undriven net initialisation
2024-01-19 18:13:55 -08:00
Lars-Peter Clausen 151a14dfcc
Merge pull request #1072 from larsclausen/iverilog-vpi-fix
iverilog-vpi.sh: Put `IVCXX` in quotes to allow to pass arguments
2024-01-17 05:32:00 -08:00
Lars-Peter Clausen 39daac0d40 iverilog-vpi.sh: Put `IVCXX` in quotes to allow to pass arguments
`IVCXX` which contains the C++ compiler that will be invoked when building
an vpi module might contain additional arguments that get passed to the
compiler. E.g. such as the C++ version (`-std=c++11`). For this to work
properly `IVCXX` needs to be put in quotes.

This fixes intermittent CI failures for the MacOS target.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-01-14 19:03:26 -08:00
Lars-Peter Clausen c93e8334a2 run_ivl.py: Properly escape `.` in regex
To escape the `.` in the regex it needs to be prefixed with a `\`. But
since the `\` is a escape character in python strings it needs to be
escaped as well.

Without this some versions of python print the following warning:

      run_ivl.py:36: SyntaxWarning: invalid escape sequence '\.'
        match= re.search(b'Icarus Verilog version ([0-9]+)\.([0-9]+)', text)

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-01-14 17:33:23 -08:00
Lars-Peter Clausen b1e602d27c
Merge pull request #1069 from larsclausen/pr1963962-sv-gold
ivtest: Remove outdated pr1963962 SystemVerilog mode gold file
2024-01-14 17:01:07 -08:00
gatk555 fc9fcb0bf8 Regression test for vvp scheduler fix.
This is for the latent bug exposed when testing the original fix for
issue #1041. Contributed by gatk555 in PR #1065.
2024-01-14 22:23:15 +00:00
gatk555 b128508841 vvp: enable main event queue before executing cbStartOfSimulation callbacks.
Before the start of simulation, functor update events resulting from
initial value propagation are added to the initialisation event queue
(schedule_init_list). Once simulation has started, they are added to
the main event queue (sched_list). The cbStartOfSimulation callbacks
are executed after the initialisation event queue has been emptied.
Currently, if these callbacks generate further functor update events,
those events are added to the initialisation event queue, but that
queue is not looked at again. Instead, make sure any new events are
added to the main event queue.

This issue and proposed fix was reported by gatk555 in PR #1065.
2024-01-14 22:12:52 +00:00
Lars-Peter Clausen 26d5cca784 ivtest: Remove outdated pr1963962 SystemVerilog mode gold file
Starting with commit 96df251c95 ("Suppress unnecessary VCD/LXT/LXT2
warnings about packages.") there is no longer a warning printed that the
unit scope can't be printed if it is empty.

Remove the special SystemVerilog mode gold file for the pr1963962 test that
expects this warning.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-01-13 19:07:44 -08:00
Lars-Peter Clausen 155ed084b0
Merge pull request #1067 from larsclausen/vvp_part_state_remove_bitsr
vvp: Remove bitsr from struct vvp_fun_part_state_s
2024-01-07 17:55:17 -08:00
Lars-Peter Clausen 9853a5904c vvp: Remove bitsr from struct vvp_fun_part_state_s
The part functor has no real typed state and the bitsr field of the state
struct is unused. Remove it.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-01-07 17:38:33 -08:00
Martin Whitaker 7b99cd25ca Add regression tests for suppressed VCD/LXT/LXT2 warnings (issue #710) 2024-01-07 20:34:45 +00:00
Martin Whitaker 96df251c95 Suppress unnecessary VCD/LXT/LXT2 warnings about packages.
Only output a warning if a package contains dumpable items. This is
mainly to avoid the warning about the $unit scope when a design has
been compiled for a SV generation (issue #710).
2024-01-07 20:16:49 +00:00
Martin Whitaker fa2dfe690c Add regression test for synthesisable for loop check (issue #687) 2024-01-07 13:23:36 +00:00
Martin Whitaker 974d2b87ae Improve check for synthesisable for loop.
The condition expression may require the loop variable width to be
expanded. The compiler wraps the NetESignal with a NetESelect to
do this, so we need to handle that when checking that the condition
expression uses the loop variable.

Fixes issue #687 and issue #1004.
2024-01-07 13:14:48 +00:00
Martin Whitaker a9eed015c3 Add regression test for undriven net initialisation (issue #1041). 2024-01-07 09:34:50 +00:00
Martin Whitaker 435c9797b2 vvp: execute undriven net initialisation before time 0.
This ensures the initialisation is done before a VPI cbStartOfSimulation
callback is executed (issue #1041).
2024-01-07 09:34:44 +00:00
Martin Whitaker 94b443a7fe tgt-vvp: inform vvp about undriven constant values.
This causes tgt-vvp to use a lower case 'c' instead of an upper case
'C' as the prefix for constant values used to initialise undriven nets.

For use by the following commit.
2024-01-07 09:34:36 +00:00
Cary R af92bef64f
Merge pull request #1063 from larsclausen/vvp_net_ptr_t-default-destructor
vvp: Reduce overhead of passing vvp_net_ptr_t between functions
2024-01-06 22:14:41 -08:00
Cary R c53b1c0101
Merge pull request #1062 from larsclausen/replicate-for-concat-repeat
Use NetReplicate to implement replication for concat
2024-01-06 22:13:31 -08:00
Lars-Peter Clausen ddcac42b5f vvp: Reduce overhead of passing vvp_net_ptr_t between functions
vvp_net_ptr_t uses vvp_sub_pointer_t to implement a tagged pointer with the
tag containing the port number.

The size of the tagged pointer is that of a normal pointer and could easily
be passed in a register when passing it as an argument to a function.

But since the vvp_sub_pointer_t type has a non-standard destructor it is
instead passed on the stack with the register containing a pointer to the
stack location where the value is stored.

This creates extra boiler plate code when passing a vvp_net_ptr_t to a
function writing and reading the value to and from the stack.

Use the default destructor for vvp_sub_pointer_t to avoid this and have the
value passed in a register.

There isn't much of a performance gain but the change is simple enough to
do anyway.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-01-06 20:26:42 -08:00
Lars-Peter Clausen 2d22f43ba7 Use NetReplicate to implement replication for concat
Currently replication in a concatenation is implemented by simply
concatenating the input signals multiple times by the replication amount.

Replace this to use NetReplicate on the concatenation instead. In case
there is only one input vector to the concatenation the replication will directly
connect to the input vector.

This is slightly more efficient in vvp since the replication functor has
only one input while the concatenation has multiple inputs connected to the
same wire. When an update of the input occurs the replication functor will
only receive a single update, while the concatenation will receive multiple
update events, one for each replication.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-01-06 19:33:51 -08:00
Lars-Peter Clausen 60864ff1c7 vvp: repeat: Implement partial vector receive
The repeat functor can receive a partial vector. Make sure this is handled.
Since the expectation is that will only happen if the input wire is driven
by a single partial selection the default recv_vec4_pv_() can be used which
replaces the missing bits by `z`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2024-01-06 19:33:41 -08:00
Cary R 7c25e8506c
Merge pull request #1060 from larsclausen/ident-test-width
Correctly calculate width of nested path identifiers
2024-01-01 12:26:51 -08:00
Cary R 1712b2e8e8
Merge pull request #1059 from larsclausen/invalid-partsel
Detect reversed part select on inner dimensions
2024-01-01 12:25:07 -08:00
Cary R cec7a6452f
Merge pull request #1014 from proppy/add-array-test
ivtest: add array_slice_concat
2024-01-01 11:21:21 -08:00
Cary R 724a88f523
Update array_slice_concat.v
Add delay to avoid race in TB code and DUT code
2024-01-01 11:01:19 -08:00
Lars-Peter Clausen 9a563e9bab Add regression test for nested struct width
Check that expression width is correctly calculated for nested structs.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-12-30 18:30:24 -08:00
Lars-Peter Clausen ca69665b88 Correctly calculate width of nested path identifiers
The current `PEIdent::test_width()` method is only able to calculate width
of a path with up to two elements.

For more complex paths it will not be able to calculate the width. E.g.
 * Nested struct member access
 * function call of a enum member in a struct

To make nested structures work properly walk the whole path tail element
by element updating the type along the way. Also take the indices into
account and update the type if an arrays dimensions have been fully
consumed.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-12-30 18:30:24 -08:00
Johan Euphrosine 0a53b52ed0 ivtest/regress-vvp: add array_slice_concat 2023-12-30 10:57:24 +09:00
Johan Euphrosine 2e00a7d482 ivtests/array_slice_contact: add test manifest 2023-12-30 10:57:24 +09:00
Johan Euphrosine 0b22810a25 ivtests/array_slice_contact: add tb 2023-12-30 10:57:24 +09:00
Johan Euphrosine fbbff9646d ivtest: add array_slice_concat 2023-12-30 10:57:24 +09:00
Lars-Peter Clausen 57f8084d0c Add regression tests for reversed part select indices
Check that reversed part selects result in an error. Check this for both
right-hand and left-hand side expressions as well as for inner and outer
dimensions.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-12-29 16:34:46 -08:00
Lars-Peter Clausen 131e64c53c Detect reversed part select on inner dimensions
The order of the indices of a part select need to match the order in which
the dimension of a packed array has been declared. E.g. if the msb is less
than the lsb in the declaration it also has to be for the part select.

If the order of the part select is the opposite of the declaration this is
an error. This works as expected for part selects on the most outer
dimensions.

But for inner dimensions the current implementation just swaps the msb and
lsb of the part select if they are in the wrong order.

Refactor this so that an error is reported for both the outer and inner
dimensions.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-12-29 16:34:46 -08:00
Lars-Peter Clausen 9a0ce046c7
Merge pull request #1057 from larsclausen/fix-net-array
vvp: Don't schedule initial value propagation for net array ports
2023-12-28 20:18:16 -08:00
Lars-Peter Clausen 90880e86ad vvp: Don't schedule initial value propagation for net array ports
An initial value propagation should only be scheduled for variable array
ports, but not for net array port since those do not contain any values.

This got accidentally broken when fixing support for 2-state variable
array ports.

Add a check that only does the initial value propagation if the port is for
a variable array.

Fixes: 0eb01fff1e ("vvp: Fix initial value propagation for 2-state non-automatic arrays")
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-12-28 20:04:01 -08:00
Cary R b4b8006460 vpiFullname of a package should have a "::" after the name 2023-12-28 18:53:11 -08:00
Cary R 4251ea9553 Remove old V0.8 code in VPI tests 2023-12-28 16:02:47 -08:00
Cary R 1471e7d53d MModule elab should check elab tasks first 2023-12-28 15:26:59 -08:00
Cary R cc829031ff Elaborate system elab tasks in gen blocks 2023-12-28 15:07:37 -08:00
Lars-Peter Clausen 7fb1cabdbb
Merge pull request #1055 from larsclausen/invalid-index-base
Handle invalid vector slice base expressions
2023-12-28 13:38:28 -08:00
Cary R b14c4ca26c add suport for the shortreal conversion functions 2023-12-28 13:30:27 -08:00
Lars-Peter Clausen 8f006a22b4 Add regression tests for invalid part select base expressions
Check that a invalid part select base expression results in a compile
error.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-12-28 13:21:37 -08:00
Lars-Peter Clausen e7e663056a Handle invalid vector slice base expressions
The elaboration of the base expression of a vector slice index can fail and
return a nullptr. Currently this results in a nullptr deref. Handle that
case by exiting the function early.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-12-28 13:21:37 -08:00
Stephen Williams bc119f96a9
Merge pull request #1054 from larsclausen/fix-run_ivl_py
Fix run_ivl.py
2023-12-28 13:17:08 -08:00
Cary R 91b1759602 More test version cleanup 2023-12-28 12:14:44 -08:00
Cary R 57524836f1 Fix space issues 2023-12-28 11:21:09 -08:00
Cary R 691eeeef99 Update fstpi.c to the latest version from GTKWave 2023-12-28 11:20:31 -08:00
Lars-Peter Clausen 5be80046a9 Fix run_ivl.py
Commit 56c5bf1da1 ("ivtest: Remove regress v11, v12, and v13") removed the
`expected_fail` argument from the `check_run_outputs()` function, but did
not remove all references. This causes the run_ivl.py script to fail. The
script is part of the CI pipeline and causes all PRs to fail.

Remove the remaining references to `expected_fail` to make it work again.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-12-27 09:31:46 -08:00
Stephen Williams 734f2a076b
Merge pull request #1049 from steveicarus/steveicarus/remove-regress-v11
ivtest: Remove regress v11, v12, and v13
2023-12-17 20:26:14 -08:00
Stephen Williams 56c5bf1da1 ivtest: Remove regress v11, v12, and v13
These tests lists are no longer needed.
2023-12-17 20:13:00 -08:00
Stephen Williams 19f2cc7fcb
Merge pull request #1051 from steveicarus/steveicarus/remove-mingw32-from-ci
Remove MINGW32 from regression test scripts
2023-12-17 20:10:46 -08:00
Stephen Williams 68841d4670 Remove MINGW32 from regression test scripts
The MINGW32 test is failing randomly. It is not something that we
typically need anyhow, so give up and remove it.
2023-12-17 19:52:01 -08:00
Stephen Williams c6df820ff9
Merge pull request #1043 from steveicarus/steveicarus/remove-regress-vams
vams: Remove the regress-vams test
2023-12-10 20:40:34 -08:00
Stephen Williams d39e8cfc3c
Merge pull request #1042 from steveicarus/steveicarus/remove-regress-v10
ivtest: Remove the regress-v10 test list
2023-12-10 20:09:11 -08:00
Stephen Williams 3c65f5d750 vams: Remove the regress-vams test
Use the more sophisticated python based tests to run these tests, and
remove the verilog-vams list.
2023-12-10 20:06:46 -08:00
Stephen Williams 0be07afab3 ivtest: Remove the regress-v10 test list
This list is not needed with the new scheme. This means that some gold
files that are v10 specific are removed, as well as the list itself.
2023-12-10 19:05:12 -08:00
Cary R 987b7d1dc0 fread() support integral variables not just registers 2023-12-09 14:30:25 -08:00
Cary R 5d561f3ef1 Fix time issue in FreeBSD (pow() bug) 2023-12-09 12:51:13 -08:00
Stephen Williams 58dcf39db3
Merge pull request #1017 from steveicarus/steveicarus/ivtest-test-conversion-20231029
ivtest: reformat some regression tests
2023-11-25 17:43:12 -08:00
Stephen Williams bed166915f ivtest: reformat some regression tests
This empties out the revress-ivl2.list

This includes the tests:
* always4A
* always4B
* br_gh383a
* br_gh383b
* br_gh383c
* br_gh383d
* ca_time_real
* delayed_sfunc
* localparam_type
* parameter_type
* pr1701890
* pr1864110a
* pr1864110b
2023-11-17 15:00:25 -08:00
Cary R c9548f0332
Merge pull request #1034 from smunaut/fix-for-structs
Couple of fixes for struct supports
2023-11-16 03:37:18 -08:00
Sylvain Munaut 483de9a75b ivtest: Add test for partselect on enum inside pack struct
See issue #1033

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2023-11-16 09:26:04 +01:00
Sylvain Munaut e0b255f34f elab_expr: Support part select for enums inside of structs
Fixes #1033

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2023-11-16 09:26:04 +01:00
Sylvain Munaut d564cecfb9 ivtest: Add test for $left / $right on structure field
See issue #1032

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2023-11-16 09:26:01 +01:00
Sylvain Munaut 8ca387d6de eval_tree: Properly support struct fields in get_array_info
Fixes #1032

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2023-11-16 09:26:01 +01:00
Sylvain Munaut 37eba70ca4 eval_tree: Indent fixes
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2023-11-16 09:26:01 +01:00
Cary R 28987277ad
Merge pull request #1023 from marlonjames/fix-escaped-vpi_handle_by_name
Fix vpi_handle_by_name() for toplevel modules with escaped identifiers
2023-11-06 18:43:02 -08:00
Marlon James d4aef1e6d8 Fix vpi_handle_by_name() handling of escaped identifiers when finding a toplevel module
find_scope() requires the hierarchical path to use escaped identifiers;
without the leading '\' and trailing ' ', if there are any '.' characters,
the path will be broken up at the wrong point(s).
2023-11-06 15:48:31 -08:00
Marlon James 22b68ad24d ivtest/vpi/br_gh317: Update test for missing case of toplevel module with escaped identifier containing '.' 2023-11-06 15:48:07 -08:00
Cary R b1006b3848
Merge pull request #1020 from DeflateAwning/install-update-1
Update INSTALL to refer to better instructions for this project
2023-11-06 14:14:36 -08:00
DeflateAwning dc44a192e2 Update Hello World example 2023-11-03 15:09:14 -06:00
DeflateAwning 2cd94d4bcf Improve README code snippet formatting 2023-11-03 15:06:36 -06:00
DeflateAwning 73d8297c38 Update INSTALL to refer to better instructions for this project
* Update instructions to match README
* Update instructions to refer to README for simpler instructions
2023-11-03 14:59:42 -06:00
DeflateAwning b47b57e52f Fix code snippet formatting in INSTALL 2023-11-03 14:53:58 -06:00
Cary R 77d7f0b8f7
Merge pull request #1011 from DeflateAwning/readme-1
Update project URL, other tiny README fixes
2023-10-24 08:05:18 -07:00
DeflateAwning 95217830b4 Update URL http://iverilog.icarus.com/ -> https://steveicarus.github.io/iverilog/ 2023-10-15 19:29:40 -06:00
DeflateAwning 950d72c77d Tiny README fixes 2023-10-15 19:29:04 -06:00
Cary R a9ef00676f
Merge pull request #1008 from larsclausen/2state-net-array
vvp: Add parser rule for unsigned 2-state net arrays
2023-10-15 10:49:47 -07:00
Lars-Peter Clausen b7ef0b5d88 Add regression test for continuous assignment to 2-state arrays
Check that continuous assignments to both signed and unsigned 2-state
arrays are supported.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-10-15 10:07:24 -07:00
Lars-Peter Clausen 52a8b31ac3 vvp: Add parser rule for unsigned 2-state net arrays
vvp is missing a parser rule for unsigned 2-state net arrays. E.g.

```
  bit a[0:1];
  assign a[0] = 1'b0;
```

will synthesize fine, but when running it with vvp cause a syntax error.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-10-15 10:03:10 -07:00
Cary R c498d53d0d
Merge pull request #1006 from larsclausen/queue-darray-2state-oob
Return '0 for out-of-bounds access on 2-state queues and dynamic arrays.
2023-10-10 04:36:48 -07:00
Lars-Peter Clausen 3e58507e87 Enable regression tests for out-of-bounds on 2-state queues and dynamic arrays
Now that out-of-bounds access on 2-state queues and dynamic arrays yields
the right value move the tests from the "Not Implemented" list to the list
of tests that get run.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-10-01 09:09:31 -07:00
Lars-Peter Clausen 85bf2d11fa tgt-vvp: Cast reads from 2-state dynamic arrays/queues
vvp does not track whether the values stored in a dynamic array or queue
are 2-state or 4-state. Internally the data is always stored as 4-state.

To make sure that the read value is actually 2-state do a cast for 2-state
reads.

E.g. performing an out-of-bounds access on a 2-state dynamic array or queue
will yield a undefined value.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-10-01 09:09:31 -07:00
Lars-Peter Clausen 560800489d tests: sv_queue_vec: Change base type to 4-state
The sv_queue_vec test uses queues of 2-state vectors, but also checks if
certain operations on the queue yield 'X.

2-state queues should never yield 'X and the test only passes because of a
bug. In preparation for fixing the bug change the test to use a 4-state
base type instead.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-10-01 09:09:31 -07:00
Cary R d22bb3d250
Merge pull request #1003 from larsclausen/2state-array-init-prop
vvp: Fix initial value propagation for 2-state non-automatic arrays
2023-09-25 01:02:41 -07:00
Lars-Peter Clausen 6e81891de0 Add regression test for 2-state array initial value propagation
Check that the initial value that gets propagated for 2-state arrays is '0.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-09-23 06:19:09 -07:00
Lars-Peter Clausen 0eb01fff1e vvp: Fix initial value propagation for 2-state non-automatic arrays
For 2-state non-automatic arrays currently real 0.0 value is propagated as
the initial value. This will cause an assert at the downstream receivers
which expect a vector.

Make sure that the vector value 0 is propagated instead for 2-state
vectors.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-09-23 05:40:13 -07:00
Cary R 778b6d937e
Merge pull request #998 from esola-thomas/esola-thomas/Enhance_README
README file enhancements
2023-09-11 21:03:17 -07:00
Ernesto Sola-Thomas 93f916a67e Add table of contents and drop downs 2023-09-11 20:49:24 -04:00
Cary R 36a8a99177
Merge pull request #997 from larsclausen/netrange-cleanup
Small cleanups around netrange_t
2023-09-10 22:13:04 -07:00
Lars-Peter Clausen 484846ab3e NetNet: Pass unpacked dimensions as `std::vector` instead of `std::list`
Most places in the code use a std::vector for array dimensions.
The only exception is the constructor of NetNet, which uses
a `std::list` to pass the unpacked dimensions. But to store the
unpacked dimensions it also uses a `std::vector`.

There does not seem to be a good reason why the constructor
has to take a `std::list`, so switch it also to `std::vector`.

This allows to simplify the code and remove some special handling
for `std::list<netrange_t>`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-09-09 05:51:17 -07:00
Lars-Peter Clausen 763907b0e5 Add a typedef for `std::vector<netrange_t>`
`std::vector<netrange_t>` is used for signal array dimensions. As such it is
used in quite a few places.

Add a typedef that can be used as a shorthand to refer to it. This helps to
keep lines where this is used from growing to overly long.

The new type is called `netranges_t`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-09-09 05:50:40 -07:00
Lars-Peter Clausen d6d95c7c49 Use non-array `NetNet` constructor where appropriate
There are two `NetNet` constructors, one for arrays and one for non-arrays.
There are a few places where the array constructor is used for non-arrays,
but with an empty unpacked dimensions list. Switch this over to using the
non-array constructor.

This slightly reduces boiler-plate code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-09-09 05:50:25 -07:00
Lars-Peter Clausen bdbe74252c Use `netrange_width()` helper where appropriate
The `netrange_width()` helper function computes the total width of a set of
ranges. There are a few places where this is currently open-coded and
`netrange_width()` can be used. This removes a bit of duplicated code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-09-09 05:50:25 -07:00
Lars-Peter Clausen 4269388878 `netrange_width()`: Add a base_width parameter
There are sometimes cases where calculating the total width of a
`vector<netrange_t>` has to take into account an existing base width. E.g.
when chaining multiple `vector<netrange_t>`. Add support to the
`netrange_width()` function to be able to handle this case.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-09-09 05:49:46 -07:00
Lars-Peter Clausen 4b66d40d62 Remove unused `calculate_count()` function
The templatized version of `calculate_count()` that is used on a data type
is not used. Remove it.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-09-09 05:49:23 -07:00
Cary R f50cc35d2f Fix space issues 2023-09-04 14:15:11 -07:00
Cary R 807058e3a4 Add check for pragma name in ivlpp 2023-09-04 14:00:41 -07:00
Cary R 76a65d5958 Add error message for bad line directives to ivlpp 2023-09-04 14:00:41 -07:00
Cary R 7ce068fbdb
Merge pull request #994 from mole99/sdf-interconnect-vector
SDF: Interconnection delays for input/output vectors
2023-09-04 07:02:28 -07:00
mole99 d7c6d7ce76 Fix memory leak and add vpi_release_handle() 2023-09-04 15:20:31 +02:00
mole99 18f6dcb6ba Fix formatting in sdf_parse.y 2023-09-04 14:27:46 +02:00
mole99 d70ad015f2 Cleanup 2023-09-04 14:07:48 +02:00
mole99 b8ae6b1686 Fix port bit index 2023-09-04 11:31:35 +02:00
Cary R d03d4b3145 Update to the latest fstapi.c file 2023-09-04 00:21:30 -07:00
Cary R b497d362a7 Cleanup space issues 2023-09-04 00:21:23 -07:00
mole99 f9d658caeb Add more debug information 2023-09-04 09:20:19 +02:00
mole99 023c5f2754 Add testcase with input and output vectors 2023-09-04 09:20:19 +02:00
mole99 a1440ced86 Add support for annotation of input and output vectors 2023-09-04 09:20:19 +02:00
Cary R 7e62a1b848 Update the gold file for br1005 2023-09-03 21:46:15 -07:00
Cary R b12977d61a A macro can only have `" and add `\`" for pragma comments
We want to support `" and `\`" when a pragma comment is part of a macro
definition, but this cannot be part of a normal pragma comment.
2023-09-03 21:34:31 -07:00
Cary R d938654c36
Merge pull request #993 from ithinuel/escape-in-attribute
add double quote escapes from pragma comments.
2023-09-03 21:14:10 -07:00
Cary R e92caa05db br_gh979 cannot be converted to vlog95 2023-09-03 18:54:18 -07:00
Cary R 1cc6fe835b Update ufunc/e documentation 2023-09-03 18:45:54 -07:00
Cary R f229dfcb2b Fix the trigger for user functions with no args 2023-09-03 18:41:38 -07:00
Cary R c6fe0106cb Change empty function port list message 2023-09-03 18:41:06 -07:00
Cary R 64cfd681af
Merge pull request #980 from sifferman/argumentless-functions-fix
Argumentless functions fix
2023-09-03 17:31:10 -07:00
Cary R 369c01a765 Update action and specify python version in msys2 2023-09-02 10:44:21 -07:00
Cary R 8e0fa024d0
Merge pull request #973 from mole99/sdf-interconnect
Implement SDF INTERCONNECT
2023-09-02 09:08:22 -07:00
mole99 0c95493794 Add has_index flag to interconnect_port_s 2023-09-02 15:57:04 +02:00
mole99 665295ba00 Also enable -gspecify for interconnect tests 2023-08-30 15:13:18 +02:00
Wilfried Chauveau 873c2fecd4
add double quote escapes from pragma comments. 2023-08-29 22:37:14 +01:00
mole99 11c944f5e9 Cleanup 2023-08-29 09:54:39 +02:00
mole99 306e4cfa6b Add three tests to exercise interconnection delays in designs 2023-08-23 12:56:11 +02:00
mole99 37119b1504 Remove some unnecessary output 2023-08-23 12:56:11 +02:00
mole99 db068aa137 Correctly dump the delayed signal for output ports 2023-08-23 12:56:11 +02:00
mole99 423f88cce9 Fix annotation for special cases 2023-08-23 12:56:11 +02:00
mole99 6d3e2bf344 Improve SDF interconnect support, add -ginterconnect flag 2023-08-23 12:56:11 +02:00
mole99 adb40e7572 Annotate simple designs 2023-08-23 12:56:10 +02:00
mole99 3fe59b0c16 Add vpi_handle_multi to vpi_modules 2023-08-23 12:56:10 +02:00
mole99 cf19acd8ee Update vpip_routines_s 2023-08-23 12:56:10 +02:00
mole99 f6e4b6d381 Add vpi_handle_multi to libvpi 2023-08-23 12:56:10 +02:00
mole99 7beadb92f8 Framework of the INTERCONNECT implementation 2023-08-23 12:56:10 +02:00
mole99 78f8976c85 Parse port and index 2023-08-23 12:56:10 +02:00
Cary R 77f7609b67 Fix formatting of link routine 2023-08-22 20:41:30 -07:00
Cary R 2d41a43ae1 Spelling fixes 2023-08-22 20:41:17 -07:00
Cary R 70243b8163
Merge pull request #989 from mole99/fix-modpaths
Always evaluate `vvp_fun_modpath_src` first
2023-08-22 19:41:03 -07:00
Cary R e1f5dbcf17
Merge pull request #992 from larsclausen/tf-named-ports
Add support for binding function/task arguments by name
2023-08-20 20:39:51 -07:00
Lars-Peter Clausen 250c456f94 Add regression tests for binding task/function arguments by name
Check that binding task and function arguments by name works as expected.
Also check that is works for the various variations of invoking a class
constructor.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-20 08:20:54 -07:00
Lars-Peter Clausen f6a51bc9db Add support for binding function/task arguments by name
In addition to providing positional arguments for task and functions
SystemVerilog allows to bind arguments by name. This is similar to how
module ports can be bound by name.

```
task t(int a, int b); ... endtask
...
t(.b(1), .a(2));
```

Extend the parser and elaboration stage to be able to handle this. During
elaboration the named argument list is transformed into a purely positional
list so that later stages like synthesis do not have to care about the
names.

For system functions and tasks all arguments must be unnamed, otherwise an
error will be reported.

In addition to functions and tasks arguments can also be bound by name for
the various different ways of invoking a class constructor.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-20 08:20:54 -07:00
Lars-Peter Clausen 102d85c4e5 Attach line information to named items
Attach line information to named items. This allows to provide better
location information for messages involving named items. The location of
item itself can't always be used, since the item itself might be empty.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-19 10:12:00 -07:00
Lars-Peter Clausen 4036c77416 parser: Consolidate named expression parsing
There are a few different places in the parser that all parse named
expressions in the same way. Consolidate them into a single rule.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-19 10:12:00 -07:00
Lars-Peter Clausen e7f66fe7ac Use standard constructor to copy std::list to std::vector
There are a few places in the code where a std::list is copied to a
std::vector by iterating through the list and copying each element over to
the vector. The std::vector type has a iterator based constructor that can
do the same.

Update the code to use it instead. This removes a bit of boilerplate code
and also makes it easier to update the code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-19 10:12:00 -07:00
Lars-Peter Clausen ce243268d0 Use `named_pexpr_t` type instead of open-coding it
`named_pexpr_t` is a typedef for `named<PExpr*>`. There are a few places
where `named<PExpr*>` is used directly. Replace those with `named_pexpr_t`
for consistency.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-19 10:12:00 -07:00
Lars-Peter Clausen 2cef85f8a1 Add helper function for printing expression list
There are a few places where some sort of expression list is printed. Add
helper functions to consolidate this in a single place and reduce the
amount of code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-19 10:12:00 -07:00
Lars-Peter Clausen 520b00095c Remove unused `named_number_t` type
The last user of the named_number_t type was removed in commit 2f474358d9
("2f474358d99929ec625a46690d1be6939ed67064"). Remove the type as well.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-19 10:12:00 -07:00
Cary R 8bcdb5d862
Merge pull request #990 from masloyet/vvp-scope-search-typo
Fix Typo in vvp's scope search in interactive mode.
2023-08-18 07:07:58 -07:00
Mason Loyet dc1038c877 Fix Typo in vvp's scope search in interactive mode.
When vvp parses a command which it thinks is a system call it tries to
match the symbols to values in the scope. The typo uses the wrong index
variable to access the vpi table. This results in a failed dynamic cast
which goes unchecked until the value is dereferenced, resulting in a
segfault.
2023-08-17 05:44:31 +00:00
mole99 5a87d2fa38 Keep the order of other nodes 2023-08-15 10:18:12 +02:00
mole99 bd2b67961e Connect nodes with vvp_fun_modpath_src always to head of list 2023-08-14 15:37:53 +02:00
Cary R 09f3ebfc88
Merge pull request #984 from larsclausen/class-constructor-chain
Fix class constructor chaining corner cases
2023-08-06 04:25:40 -07:00
Lars-Peter Clausen 8ca8ad3c81 Add regression tests for chained constructors
Check that constructor chaining for various corner cases of mixing implicit
and explicit constructors are handled correctly.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-06 02:10:28 -07:00
Lars-Peter Clausen c512faa967 Make sure chained constructor is called when using `extends`
Currently when neither an explicit constructor is specified nor any
properties are present in the class that will create an implicit
constructor there will be no constructor for the class.

As a result a class that specifies the arguments for the base class
constructor as part of the `extends` clause will not have the base
constructor called with the right arguments.

E.g.
```
class C;
  function new(int a);
  endfunction
endclass

class D extends C(10);
endclass
```

To avoid this make sure that an implicit constructor is created when
passing arguments through the `extends` clause.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-06 02:10:28 -07:00
Lars-Peter Clausen 6ea01cbf7f Fix class constructor chaining corner cases
There are some corner cases around class constructor chaining that can
result in chained constructors not being called, or being called multiple
times.

This is primarily related to that a class can have either an explicit
constructor called `new` and an implicit constructor called `new@` and how
the lookup of them is done.

Lookup is currently done independently for the implicit and explicit
constructor using the `method_from_name()` method. `method_from_name()`
will search the whole class hierarchy for a class method. If a class
doesn't have a method by that name it will look in the parent class and so
on.

As a result the lookup for the explicit constructor can return the explicit
constructor of a parent class if the class itself only has an implicit
constructor and vice versa.

E.g. in the following example the constructor of D will not be called
because the implicit constructor for C is found when looking for a implicit
constructor in D.

```
class C;
  int x = 10;
endclass

class D extends C;
  function new;
    $display("D");
  endfunction
endclass

class E extends D;
  int y;
  function new;
    y = 20;
  endfunction
endclass

E e = new;
```

There is a similar case where the constructor of a base class can be called
multiple times if the base class has an explicit constructor and the
derived class has an implicit constructor. In that case the derived class
constructor will call the base class constructor, but the code that is
emitted for the `new` statement will call both of them.

To mitigate this introduce a new method to lookup the constructor that will
search for either the explicit or implicit constructor in the current class
and only continue to search in the base class if neither is found.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-08-06 02:10:28 -07:00
Cary R 0651e0be17
Merge pull request #982 from larsclausen/const-var-fix
Make sure `const var` variables are constant
2023-08-05 18:27:34 -07:00
Cary R d660ca7179
Merge pull request #981 from larsclausen/automatic-2state
vvp: Initialize automatic 2-state vectors to 0
2023-08-05 17:44:30 -07:00
Ethan Sifferman 470a3da703 removed wire and assign from test 2023-07-30 22:44:19 -07:00
Lars-Peter Clausen bdfd873dc4 Add regression test for `const var`
Check that variables declared with `const var` can not be modified.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-07-29 12:26:35 -07:00
Lars-Peter Clausen 06428f3d11 Make sure `const var` variables are constant
Commit 3daa2982ac ("Add support for `const` variables") added support for
constant variables, but had a small mistake and did propagate the constant
flag from the parser if the variable is declared with the `var` keyword.
Still allowing to modify those variables. Fix this.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-07-29 12:26:35 -07:00
Lars-Peter Clausen 6928b38720 Add regression tests for automatic 2-state variable default value
Check that automatic 2-state variables get initialized to 0.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-07-29 06:33:46 -07:00
Lars-Peter Clausen 0dfbcbdf47 vvp: Initialize automatic 2-state vectors to 0
Automatic 2-state vectors currently get initialized to 'hx, while their
default value should be 0.

Make sure the vector is initialized to 0 at the beginning of the automatic
context.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-07-29 06:17:47 -07:00
Ethan Sifferman de2f506644 improved test 2023-07-29 00:21:31 -07:00
Ethan Sifferman 44badf50de added test 2023-07-28 23:51:02 -07:00
Ethan Sifferman eb104a727e initial commit 2023-07-28 22:22:15 -07:00
Stephen Williams 999bcb6935
Merge pull request #975 from larsclausen/sv_const_var
Add support for `const` variables
2023-07-25 19:15:10 -07:00
Lars-Peter Clausen f092820599 Add regression tests for const variables
Check that const variables are supported and they can not be overridden by
type of assignment.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-07-23 15:14:04 -07:00
Lars-Peter Clausen 3daa2982ac Add support for `const` variables
SystemVerilog allows to declare const variables. These variables are
read-only and can not be assigned a value after their declaration. It is
only possible to assign an initial value as an initializer.

E.g.
```
const int x = 10;
x = 20; // Error
```

The LRM requires that for variable declarations with static storage the
initializer is a constant expression with the extension that other const
variables are also allowed. const variables with automatic storage can
be initialized by any expression.

Checking if an expression contains only const variables requires a bit more
work to implement. So for now be more lenient that what the standard
requires and allow arbitrary expressions to initialize const variables even
for those with static storage.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-07-23 15:08:39 -07:00
Cary R 9e4c4d5460 `line directive line number must be > 0 and can have arbitrary space 2023-07-19 01:51:36 -07:00
Cary R 3aafa1333b Update $ferror() and $fgets() to support SV strings 2023-07-19 00:30:50 -07:00
Cary R ceb07dc9db
Merge pull request #966 from mole99/delayed-signals
Handle delayed signals in timing checks as assignments
2023-07-14 06:33:37 -07:00
mole99 13fcf2d844 Remove checks for non-NULL before deleting 2023-07-14 08:06:06 +02:00
Stephen Williams f2621d88c1
Merge pull request #971 from larsclausen/arith-expr-type-fix-runtime
Avoid exponential execution time behavior in arith_expr_type()
2023-07-13 19:38:21 -07:00
mole99 e0d0dff8d6 Change timing check condition to expression for better compatibility 2023-07-13 10:15:52 +02:00
mole99 6b2990cfec Use more C++11 features 2023-07-12 15:10:23 +02:00
Lars-Peter Clausen 26d1c72e77 Avoid exponential execution time behavior in arith_expr_type()
arith_expr_type() queries the expression type of its two child nodes up to two
times. Since the child nodes might also need to query their child nodes
expression type to determine their own this can lead to an exponential runtime.

For complex expressions this can easily result in very long elaboration time.

Avoid this by querying the expression type only once for each child node.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-07-12 04:43:03 -07:00
mole99 7f5b8d49eb Fix timing_check_syntax 2023-07-10 16:12:27 +02:00
mole99 d46628b2f2 Improve parsing of timing checks 2023-07-10 15:59:14 +02:00
Cary R fdb9465329 Indexed part selects cannot use real values 2023-07-09 12:25:34 -07:00
Cary R 095e6daa0a Cannot use posedge, negedge or edge with a real expression 2023-07-09 05:02:01 -07:00
Cary R 2249d224de Bit/part selects cannot have real index expressions 2023-07-09 03:47:41 -07:00
mole99 e54ff22fce Fix wrong output 2023-07-05 16:50:10 +02:00
mole99 7aabcc113e Add test for delayed signals in timing checks 2023-07-05 16:24:04 +02:00
mole99 21b73eb187 Add test for parsing timing checks 2023-07-05 16:23:15 +02:00
mole99 87885dbd9b Handle delayed signals in timing checks as assignments 2023-07-05 16:22:08 +02:00
Cary R 272771d183
Merge pull request #965 from larsclausen/sv-partial-module-ports
Support SystemVerilog style partial ANSI port declarations
2023-06-30 07:25:16 -07:00
Lars-Peter Clausen c5f98fb671 Add regression tests for partial ANSI port declarations
Check that it is possible to declare module ports with only partial
attributes. Other attributes should be inherited from the previous port in
the list or use the default.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-30 06:09:45 -07:00
Lars-Peter Clausen 664a611e16 Support SystemVerilog style partial ANSI port declarations
In Verilog it is possible to declare multiple ports as part of the same
port declaration. Ports declared this way all have same direction, signal
kind and data type. E.g.

```
module M (input [3:0] a, b, c) ...
```

SystemVerilog extends this and allows to override on a per port basis
certain port attributes. E.g. redefine just the data type

```
module test (input [3:0] a, [1:0] b, int c) ...
```

Or to just redefine the port kind

```
module test(input [3:0] a, var b, wire c) ...
```

It is even possible to leave out the direction for the very first port. As
long as at least one other property of the port is specified. In that case
the direction will default to `inout`. E.g.

```
module test(integer a, b, c) ...
```

Furthermore it is possible to specify unpacked dimensions for each of the
ports. E.g.

```
module test(input integer a, b[1:0], c[3:0][1:0]) ...
```

If all port properties are omitted for the first port this indicates the
start of a non-ANSI port list.

Extend the parser to handle this.

If all three direction, port kind and data type are omitted they are
inherited from the previous port. Otherwise

 * If the direction is omitted it is inherited from the previous port.
 * If the data type is omitted it defaults to logic.
 * If the port kind is omitted the behavior depends on the direction.
   For output ports with an explicit data type it is a variable, for
   all others it is a net.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-30 05:58:19 -07:00
Lars-Peter Clausen 82a974a801 Add parser helper function for module port declaration
Add a helper function to the parser that handles module port declaration.
This allows to reduce a bit of duplicated code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-28 07:58:33 -07:00
Cary R 17461e02de
Merge pull request #964 from larsclausen/bits-array
Support $bits() for arrays and array slices
2023-06-28 07:50:43 -07:00
Lars-Peter Clausen 708f7bc651 Add regression test for $bits() on array identifiers
Check that for array identifiers $bits() includes the total size of the
signal.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-27 05:29:47 -07:00
Lars-Peter Clausen 7908e15093 Support $bits() for arrays and array slices
`$bits()` for array types is supposed to return the full size of the array
in bits. This currently works for data types that are passed to `$bits()`,
but not for array typed identifiers.

E.g.
```
typedef int T[1:0];
T x;
$display($bits(T)); // -> 64
$display(x); // -> 32
```

Since the `$bits()` implementation uses the expr_width of an expression
include the size of the unpacked dimensions in that for array identifiers
and array slices. Strictly speaking an array identifier does not have an
expression width, but this would be its expression with if it were for
example bitstream cast to a vector.

Special care needs to be take to not trying to pad array identifier
expressions.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-27 05:26:58 -07:00
Cary R a3f1aded7c
Merge pull request #961 from larsclausen/fix-bitsel-sign
Fix bit select on signed multi-dimensional packed array
2023-06-26 07:57:03 -07:00
Lars-Peter Clausen 2a17b06fc4 Add regression test for bit select on multi-dimensional signed packed array
Check that element and bit select on multi-dimensional signed packed arrays
are unsigned.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-26 06:27:52 -07:00
Lars-Peter Clausen 61381fd9cd Fix bit select on signed multi-dimensional packed array
Bit selects on packed arrays are always unsigned and have a width of 1.
Element selects on a multi-dimensional packed array are always unsigned and
have the width of the element.

At the moment a element or bit select on the last level element of a
multi-dimensional signed array will incorrectly yield a signed expression.

Commit 40b36337e2 ("Fix some bugs with packed array dimensions") added
some special checks to fix the width on multi-dimensional array element
selects. But this removed the unsigned attribute from bit selects.

Commit 81947edaa5 ("A bit select is not the same as selecting part of a
packed array") fixed this for single dimensional packed array, but left it
broken for multi-dimensional arrays.

Commit 7c024d6cab ("Fix width calculation for bit/part selects of
multi-dimensioned packed arrays.") added some additional fixes for the
width calculation, which make the special checks in the first commit
unnecessary.

We can now remove those checks which will give us the correct behavior in
terms of the signedness of bit and element selects on both single- and
multi-dimensional packed arrays.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-26 06:27:30 -07:00
Cary R a21be045a1 Translate a Verilog for loop correctly in tgt-vhdl 2023-06-25 23:33:46 -07:00
Cary R a1c8b33945 Cleanup some clang compile warnings 2023-06-25 21:53:10 -07:00
Cary R 017a68c193 Update SDF warnings to include SDF file/line information 2023-06-25 20:12:43 -07:00
Cary R bb39325fe9
Merge pull request #957 from larsclausen/module-array-initializer
Support initializer expression for unpacked array port declarations
2023-06-19 10:56:40 -07:00
Lars-Peter Clausen 79fc09717e Add regression test for module array port initializers
Check that initializers are supported for module array ports.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-19 08:08:41 -07:00
Lars-Peter Clausen 3576ba5faa Support initializer expression for unpacked array port declarations
At the moment there are two rules for port declarations. One that allows
the port to be declared as an unpacked array, the other that allows to
specify an initializer expression.

SystemVerilog allows both to be specified in the same port declaration. Add
support for this to the parser.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-19 08:08:41 -07:00
Lars-Peter Clausen 1ee189630b Fix module_output_port_list_def test
The module_output_port_list_def declares a output port with an implicit
data type and assigns an initial value to it. Since output ports with an
implicit data type are nets this test is not standard compliant.

This only works because at the moment the parser incorrectly flags all
output ports with an initial value as variables rather than following the
method defined by the standard to decide whether the port should be a net
or variable.

Make the test standard compliant by using an explicit data type for the
output port, in which case it will be a variable.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-19 05:25:02 -07:00
Cary R ffbcb30127
Merge pull request #954 from larsclausen/ci_checkout_v3
ci: Switch to checkout@v3
2023-06-19 00:42:21 -07:00
Cary R df8ac73bba
Merge pull request #953 from larsclausen/assign-pattern-uarray
Add initial support for array assignment patterns
2023-06-19 00:41:33 -07:00
Lars-Peter Clausen 766653bc27 ci: Switch to checkout@v3
The currently used checkout@v2 CI action shows the following deprecation
warning

```
Node.js 12 actions are deprecated. Please update the following actions to
use Node.js 16: actions/checkout@v2. For more information see:
https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/.
```

Github has announced that this will eventually stop working somewhen in mid
2023.

Switch to checkout@v3 which uses Node.js 16 to avoid the ci from breaking
in the near future.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-17 12:53:58 -07:00
Lars-Peter Clausen 6991b2d84f Add regression tests for assigning scalar value to array
Check that trying to assign a scalar value to an array results in an error.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-17 12:03:20 -07:00
Lars-Peter Clausen 90a1168086 Add regression tests for unpacked array assignment patterns
Check that basic assignment patterns are supported for unpacked arrays.
Check that all of packed types, reals and string arrays are supported.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-17 12:03:20 -07:00
Lars-Peter Clausen 9549156226 Add initial support for array assignment patterns
SystemVerilog allows to use assignment patterns to assign values to an
array. E.g. `int a[4] = '{1, 2, 3, 4}`.

Each value is evaluated in the context of the element type of the array.

Nested assignment patterns are supported. E.g. `int a[2][2] = '{'{1, 2},
'{1, 2}};`

Add initial support for array assignment patterns for both continuous as
well as procedural assignments.

For continuous assignments the assignment pattern is synthesized into an
array of nets. Each pin is connected to one of the assignment pattern
values and then the whole net array is connected to target array.

For procedural assignments it is unrolled in the vvp backend. E.g
effectively turning `a = '{1, 2};` into `a[0] = 1; a[1] = 2;`.

Not yet supported are indexed initializers or `default`.
E.g. `int a[10] = '{1:10, default: 20};`

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-17 11:50:23 -07:00
Lars-Peter Clausen 4defb9f51e Provide type for array signals
Types for array signals are currently handled as a special case. The type
that is associated with the signal is not the array type itself but rather
the element type.

There is a fair amount of existing code that depends on this behavior so it
is not trivial to change this.

But there are certain constructs such as assignment patterns or array
concatenation where the array type itself is required.

Add a new `NetNet::array_type()` method that will return the array type if
the signal is an array. This will allow to query the array type when
needed.

`NetAssign_::net_type()` is updated to use this new method to return the
array type if the assigned signal is an array.

Long term the special handling of arrays for signals should be removed.
This will for example allow to unify the handling of arrays for signals,
class properties and struct members.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-17 11:48:54 -07:00
Lars-Peter Clausen bc3cb04a41 Set correct type for indexed array properties
For indexed array properties the type of the expression is the type of the
element.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-17 11:43:05 -07:00
Cary R 44bc9cba03
Merge pull request #952 from larsclausen/2state-arith
Make result of binary operations 2-state if inputs are 2-state
2023-06-17 07:15:43 -07:00
Cary R a43e7e85b9
Merge pull request #951 from larsclausen/ivl_assert
Replace assert() with ivl_assert() where line information is available
2023-06-16 10:24:04 -07:00
Lars-Peter Clausen 17229f99c9 Make result of binary operations 2-state if inputs are 2-state
The are many binary operations where if the two operands are 2-state the
result is guaranteed to be 2-state.

This is true for all arithmetic operation with the exception of division
where division by 0 will always result in 'x even if the inputs are both
2-state.

The same is true for all binary bitwise operators as well as the binary
logical operators.

Having the expression type be 2-state avoids some unnecessary %cast2
instructions that would otherwise get inserted when assigning the result to
a 2-state variable.

E.g without this change the following will result in

```
  int a, b, c;
  b = a + b;
```

will result in

```
  %load/vec4 ...;
  %load/vec4 ...;
  %add;
  %cast2;
  %store/vec4 ...;
```

For binary comparison operators this is already handled.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-16 07:33:20 -07:00
Lars-Peter Clausen 872ccd32c4 tgt-vvp: Add resize for string element assignment where necessary
There are some cases where during an assignment the elaboration step can
generate constructs with the right-hand-side expression being wider than
the left-hand-side expression.

To handle this the tgt-vvp backend inserts a %pad operation when necessary.
One place where this is missing is when writing to an string element. Here
instead an assert is triggered requiring the right-hand-side expression to
be 8 bits wide.

E.g.
```
bit [7:0] x;
bit [8:0] y;
string s;

x = y; // tgt-vvp inserts %pad
s[0] = y; // tgt-vvp triggers assert
```

Long term this should be fixed at the elaboration stage and insert the
proper width cast. But for now solve this the same way as other places in
tgt-vvp and insert the %pad operation for string element assignments if the
width does not match.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-16 07:29:16 -07:00
Lars-Peter Clausen 3fc6ab5afc Replace assert() with ivl_assert() where line information is available
`ivl_assert()` is similar to `assert()` except that it will also include
source file and line information about the expression for which the assert
was triggered.

Use `ivl_assert()` instead of `assert()` where the line information is
available. This will generate better bug reports and make it easier to
diagnose why an assert is triggered.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-16 05:06:15 -07:00
Cary R 9dd99806ad
Merge pull request #948 from mole99/fix-crash-wildcard
SDF: Implement warning for wildcard cell instanciation
2023-06-15 08:01:49 -07:00
Cary R a815d0fecd
Merge pull request #944 from mole99/timingcheck-warning
SDF: Add TIMINGCHECK warning
2023-06-15 08:01:36 -07:00
mole99 34dc10d798 SDF: Implement warning for wildcard cell instanciation 2023-06-15 10:35:05 +02:00
mole99 340e6fa020 Update gold file 2023-06-15 10:06:03 +02:00
mole99 f1ca97f78f SDF: Add TIMINGCHECK warning 2023-06-15 09:19:18 +02:00
Cary R 560fbeeae4
Merge pull request #936 from larsclausen/trailing-module-port
Allow to omit trailing module ports in ordered list connection
2023-06-14 07:35:39 -07:00
Cary R 0643a3a1f0
Merge pull request #942 from larsclausen/implicit-named-port-connections
Fix line location and require SystemVerilog mode for implicit named port connections
2023-06-14 07:16:28 -07:00
Lars-Peter Clausen 9357a62dce Add regression test for implicit named port connection errors
Check that the file and line location is correct for errors
related to implicit named port connections.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-14 04:33:41 -07:00
Lars-Peter Clausen cc74c7f332 vvp_reg.py: Add support for gold files for CE tests
Some tests require a specific compiler error, rather than just failing. Add
support for this by allowing to check for gold files for CE tests.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-14 04:33:41 -07:00
Lars-Peter Clausen ee4476fed2 parser: Require SystemVerilog for implicit named port connections
Implicit named port connections are only supported by SystemVerilog. Add a
check to generate an error when trying to use it in Verilog mode.

Regression test br_gh315 is modified to run in SystemVerilog mode since it
makes use of implicit named port connections.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-14 04:33:10 -07:00
Lars-Peter Clausen d040804036 parser: Fix line location for implicit named port connections
The implicitly generated identifier for implicit named port connections
gets its file and line information from the optional attributes. If no
attribute list is specified this will just point to the beginning of the
file resulting in incorrect line information.

Use the file and line information from the identifier token instead to fix
this.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-13 19:28:53 -07:00
Cary R 75cd1a19f0
Merge pull request #938 from larsclausen/unit-scope-possible-imports
Handle implicit task/function imports in the unit scope
2023-06-11 10:07:29 -07:00
Cary R 3780cb2da2
Merge pull request #937 from larsclausen/continue-break-const-func
Support continue/break in constant functions
2023-06-11 09:38:31 -07:00
Lars-Peter Clausen 542d80b1b1 Add regression tests for implicit function/task import the unit scope
Check that implicit import of functions and tasks is supported if the
wildcard import statement is in the unit scope.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-11 09:21:00 -07:00
Lars-Peter Clausen c1c4c28313 Handle implicit task/function imports in the unit scope
SystemVerilog requires that functions and tasks are not implicitly imported
if a symbol with the same name appears in the scope, even if it the symbol
is declared after its usage.

To support this a list of potential imports is collected while parsing a
scope and only when the end of the scope is reached it is evaluated whether
the symbol should be imported or not based on whether it already exists in
the scope.

This currently works fine for all scopes except for the unit scope. Since
the unit scope might span multiple files it is never explicitly closed and
the potential imports are never checked.

Make sure that after parsing all files is done the potential imports for
the unit scope are checked.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-11 09:20:51 -07:00
Lars-Peter Clausen 946ded13c7 Add regression tests for continue/break in constant functions
Check that continue and break are supported in constant functions.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-11 08:56:06 -07:00
Lars-Peter Clausen ea3884fa1e Support continue/break in constant functions
Add support for `continue` and `break` in constant functions. This is done
in a similar way to how `disable` is implemented for constant functions.

Two new global flags are introduced `loop_break` and `loop_continue` that
get set when evaluating the corresponding statement. If either of these
flags are set all other statements are ignored until the end of a loop is
reached. At the end of the loop both `loop_break` and `loop_continue` get
cleared. If `loop_break` was set before clearing it the loop is exited.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-11 08:50:30 -07:00
Lars-Peter Clausen 37f7308f80 Add regression test for omitting trailing ports in ordered list connection
Check that it is possible to omit trailing ports in a module ordered list
connection list.

Also check that an error is generated if too many ports are specified in a
ordered list connection.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-11 08:45:34 -07:00
Lars-Peter Clausen b8eb21b3ac Allow to omit trailing module ports in ordered list connection
The current implementation expects that for a module instantiation with a
ordered list connection all ports are supplied.

But there doesn't seem to be such a requirement in the LRMs. The Verilog
LRM doesn't mention anything in this regard and the SystemVerilog LRM
mentions in section 23.3.2.1 that a blank or omitted port connection is
either left unconnected or uses the default value of the port.

Update the implementation so that it allows to omit trailing ports and only
generates an error message if too many ports are specified in the ordered
port list.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-11 08:45:34 -07:00
Cary R edaa6e6c76
Merge pull request #935 from larsclausen/do-while-continue-break
Handle continue/break in do-while loops
2023-06-11 07:59:01 -07:00
Lars-Peter Clausen 438e510764 Update regression tests for continue/break to cover do-while loops
Also check do-while loops in the regression tests for continue and break
statements.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-11 07:20:15 -07:00
Lars-Peter Clausen fb403c6266 tgt-vvp: Handle continue/break in do-while loops
Currently continue and break are supported in most loops. But not in
do-while loops. Add support for them in do-while loops as well.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-11 07:20:15 -07:00
Cary R 750ec01352 Update vlog95 immediate assert/assume gold files 2023-06-10 21:19:32 -07:00
Cary R 63bcb9601d
Merge pull request #906 from svenka3/svenka3/labelled_imm_sva
Added support for labels in immediate assert/assume
2023-06-10 20:59:41 -07:00
Cary R ee14cb0eb0 Update displayed Copyright dates 2023-06-10 20:33:08 -07:00
Cary R ed691d25f7 Add wget commands to update config.guess and config.sub 2023-06-10 20:32:50 -07:00
Cary R 6307057e8d Fix space issues 2023-06-10 19:44:10 -07:00
Cary R bff91566ab
Merge pull request #930 from larsclausen/fix-fn-partial-oob-write
Fix incorrect assert for partial oob write to function return value
2023-06-10 18:00:06 -07:00
Cary R bfba4bf6ca
Merge pull request #932 from mole99/overhaul-documentation
[WIP] Documentation Overhaul
2023-06-10 17:54:33 -07:00
Cary R 5bf44cc78d
Merge pull request #904 from a1ca7raz/master
Update config.guess and config.sub to add support for riscv64 platform
2023-06-10 17:54:11 -07:00
mole99 f4345e2d03 Add favicon 2023-06-09 14:07:28 +02:00
mole99 b0c1eab51e Move textfiles to documentation 2023-06-09 13:30:44 +02:00
mole99 41496040e8 Rename to .txt 2023-06-09 13:29:25 +02:00
mole99 265f585096 Document all targets 2023-06-09 13:28:14 +02:00
Cary R c74048a526
Merge pull request #908 from mole99/sdf-info
Move `SDF INFO`,  `SDF WARNING`, `SDF ERROR` to start of line
2023-06-04 21:13:22 -07:00
Cary R a37181ae95
Merge pull request #924 from aelmahmoudy/fix-typos
Fix typos
2023-06-04 21:12:07 -07:00
Cary R 13166092da
Merge pull request #919 from larsclausen/fix-real-format-arm
Fix formatting real to binary and hex strings on ARM
2023-06-04 21:10:49 -07:00
Cary R 9cb3d53633
Merge pull request #918 from larsclausen/fix-single-element-array-ports
Fix connecting single element array ports
2023-06-04 21:09:04 -07:00
Cary R cd293e17af
Merge pull request #895 from larsclausen/fork-in-final
vvp: Handle `%fork` in `final` procedures
2023-06-04 21:07:48 -07:00
Cary R f22c1a519b
Merge pull request #900 from larsclausen/task-return
Support return in tasks
2023-06-04 21:07:30 -07:00
Lars-Peter Clausen 4ab59dd55e Add regression tests for oob write to function return value
Check that partial and fully out-of-bound writes to a function's return
value are handled correctly. Check this for both 4-state and 2-state
vectors.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-04 16:27:24 -07:00
Lars-Peter Clausen 925f5fb608 Fix incorrect assert for partial oob write to function return value
Partial out-of-bounds write to a function's return value will trigger an
assert, even though the operation is valid.

The assert checks that the truncated value has the expected width, but
instead it should check that the non-truncated value has the expected with.

Move the assert before the truncation to fix this.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-06-04 16:04:16 -07:00
Cary R 2e84766e79
Merge pull request #893 from larsclausen/array-assign-order
Connect continuous array assignments in the right order
2023-06-02 13:57:18 -07:00
Cary R d3a0e9606f
Merge pull request #891 from larsclausen/init-netnet-port-index
Initialize NetNet::port_index_
2023-06-02 13:54:20 -07:00
Cary R 210ada0a5a Update Python test script to run using 3.5 or newer 2023-06-01 01:06:05 -07:00
Cary R 01c5e502bd Update tests so they can be converted to vlog95 2023-05-31 22:45:06 -07:00
Cary R ef931e2e0d Spelling and space cleanup 2023-05-31 22:44:13 -07:00
Cary R 5439fcd5c2 Update to latest fstapi.c 2023-05-31 20:02:54 -07:00
Cary R 7ac6182d4c Update to compile with older GCC versions 2023-05-31 20:02:36 -07:00
أحمد المحمودي (Ahmed El-Mahmoudy) 08aee81924 Fix typos 2023-05-17 07:08:00 +02:00
Martin Whitaker deeac2edfe Fix broken example code (discussion #922)
'output' is a keyword, so can't be used as a signal name.
2023-05-15 19:42:47 +01:00
Lars-Peter Clausen abe1099335 Fix formatting real to binary and hex strings on ARM
Directly casting a negative double to a unsigned integer type is undefined
behavior and has different results on x86 and ARM based platforms.

On x86 the behavior is similar to casting a signed int to an unsigned
integer, i.e. the sign bit will end up in the MSB. But on ARM the result
will be 0.

To get consistent behavior, first cast to signed integer and then cast the
signed integer value to an unsigned integer value.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-05-08 09:16:00 -07:00
Lars-Peter Clausen 99a9be25f0 Add regression test for single element module port array
Check that connections to a module port array with a single element are
supported.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-05-06 09:58:41 -07:00
Lars-Peter Clausen 829af9f438 Fix connecting single element array ports
The current check to decide whether a port is an array or a scalar signal
uses the number of pins on the NetNet. If it is larger than one the code
assumes that it is an array.

But for arrays with on a single element the number of pins will be 1 and
the port is incorrectly treated as a scalar signal which results in an
error.

Instead of using the number of pins check for the number of unpacked
dimensions to decide whether the port is an array.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-05-06 09:28:40 -07:00
mole99 691159a8fe Move SDF ERROR, SDF WARNING to start of line 2023-04-19 19:30:23 +02:00
mole99 a3bf61030d Move SDF_INFO to start of line 2023-04-19 18:35:32 +02:00
Srinivasan Venkataramanan 2eeedb193d Added support for labels in immediate assert/assume 2023-04-18 22:30:04 +01:00
a1ca7raz 20753ee6c5 Update config.guess and config.sub 2023-04-18 19:26:42 +08:00
Lars-Peter Clausen d1aecf452c Add regression test for return in tasks
Check support for using the return statement in a task.
 * That it is possible to exit form a task using the `return` statement
   without affecting other concurrently running instances of the same task
 * That it is possible to use return in a named block in a task
 * That using a return value in a task results in a elaboration error
 * Returning from inside a parallel block in a task results in a
   elaboration error

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-04-16 19:22:49 -07:00
Lars-Peter Clausen 730c9c28b2 Support return in tasks
SystemVerilog allows to use the `return` statement in a task to exit the
task before it reaches the end of its execution. This is defined in section
13.3 ("Tasks") of the LRM (1800-2017).

This is similar to using `disable` to stop a task from within itself with
the difference that `disable` will affect all concurrently running
executions of a task, while `return` will only affect the task from which
it has been called.

The `%disable/flow` vvp instruction allows to implement the required
behavior for task return.

There is one complication in that it is not allowed to call return from
inside a parallel block (fork-join). If a parallel block is unnamed and has
no variable declarations there won't be a NetScope for it. So it is not
possible to detect whether the return is inside a parallel block by
walking up the scope chain.

To solve this add a design global counter that gets incremented when
entering a fork block and decremented when exiting a parallel block. The
return implementation then checks if the counter is non 0 to determine
whether it is in a parallel block.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-04-16 19:22:29 -07:00
Lars-Peter Clausen e1691c48fe Add regression tests for reversed continuous array assignment
Check that assigning array that have opposite left-to-righto order for
their dimensions have their elements assigned in reversed order.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-04-16 09:21:27 -07:00
Lars-Peter Clausen cc962310bb Connect continuous array assignments in the right order
In SystemVerilog arrays assignments are supposed to be connected left to
right. This means if the left to right direction differs between the two
arrays they will be connected in reverse order.

E.g.
```
logic a[1:0];
logic b[0:1];
assign b = a;
```

should connect a[0] to b[1] and a[1] to b[0]. Things get a bit more tricky
for multi-dimensional arrays where some dimensions have a matching
direction and some do not.

The current implementation always connects them low to high, which results
in incorrect behavior.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-04-16 09:21:26 -07:00
Lars-Peter Clausen 7973b105ac Add regression test for sub-blocks in `final` procedures
Check that sub-blocks containing variables inside of `final` procedures do
get executed.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-04-16 09:20:39 -07:00
Lars-Peter Clausen df30eda3a3 vvp: Handle %fork in `final` procedures
In the current implementation a `%fork` instruction in a final block will
get scheduled, but never executed.

And while SystemVerilog requires a `final` procedure to execute in 0 time
and so no SystemVerilog `fork` is allowed inside of it, there are some
other scenarios where iverilog generates `%fork` statements.

For example when declaring variables in a sub-block a sub-scope with its
own thread is is used to allocate the storage for those variables and
`%fork` is used to execute the child thread.

E.g. the following, while being valid SystemVerilog, will never execute the
loop because the generated code will implement the loop as a child thread
being executed by a `%fork` statement.
```
  final for (int i = 0; i < 10; i++) $display(i);
```

To mitigate this treat final statements the same as functions and rather
than scheduling a child thread, execute it immediately when using the
`%fork` statement.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-04-16 09:20:31 -07:00
Stephen Williams b210eb8264
Merge pull request #880 from mole99/master
Print more information about the SDF header
2023-04-14 18:14:03 -07:00
Lars-Peter Clausen a68fe8ea0a Initialize NetNet::port_index_
The port_index_ member of the NetNet is not initialized which can lead to
undefined behavior. Make sure to initialize to -1 to indicate that the net
is not associated with any port.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-04-14 07:13:43 -07:00
mole99 fd9f0b3c75 Add divider to header output 2023-04-14 11:08:10 +02:00
mole99 cca7d15cc4 Add testcase for sdf header 2023-04-14 11:08:08 +02:00
mole99 286cb5a2b9 SDF: add more header output 2023-04-14 11:06:57 +02:00
Stephen Williams 9811c375a8
Merge pull request #882 from larsclausen/foreach-count-direction
Iterate static arrays $left to $right in foreach loops
2023-04-13 09:21:27 -07:00
Stephen Williams 7fc38a19e3
Merge pull request #877 from larsclausen/assign-pattern-continuous
Handle continuous assignment of assignment patterns to array elements
2023-04-13 09:18:04 -07:00
Lars-Peter Clausen 6fc6826822 Add regression test for foreach count direction
Check that foreach counts counts from $left to $right. This means it should
count up if $left is less than $right and count down otherwise.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-03-12 18:06:43 -07:00
Lars-Peter Clausen e19d077d44 Iterate static arrays $left to $right in foreach loops
foreach loops are supposed to iterate arrays $left to $right. E.g. `reg
x[3:0]` should be iterated from 3 to 0 and `y[1:4]` from 1 to 4.

The current implementation iterates them from $low to $high. Modify this to
either count up or down depending on whether $left or $right is the larger
of the two values.

Note that the same applies for dynamic arrays. But since for dynamic arrays
$left is always 0 and $right is always $high they always count up and we do
not need to differentiate between two different cases.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-03-12 18:04:31 -07:00
Stephen Williams 0144168723
Merge pull request #881 from larsclausen/empty-gold
vvp_reg.py: Allow to omit empty gold files
2023-03-12 18:00:57 -07:00
Lars-Peter Clausen 98a208d6be vvp_reg.py: Allow to omit empty gold files
vvp_reg.py requires 4 gold files. One for each of stdout and stderr of both
iverilog and vvp. Most of these log files will be empty for most test
cases. This will result in a lot of empty files being added to the
repository.

If a gold file for a specific output stream can not be found assume that
the output stream is supposed to empty. This allows to omit the empty gold
files.

Also remove all the existing empty gold files.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-03-12 16:23:29 -07:00
Stephen Williams e9646bbbd3
Merge pull request #875 from steveicarus/steveicarus/issue874-vvpreg_support_vlog95
ivtests: Add support for vlog95 tests
2023-03-05 15:31:03 -08:00
Stephen Williams 564304d20c ivtests: Add support for vlog95 tests
This adds the "normal-vlog95" test type, because we need to run a different
set of commands for this to work so a new test type makes sense. This also
moves a few of the existing tests to the new format in order to test the
new test rig.
2023-03-05 15:09:04 -08:00
Lars-Peter Clausen d4c35340e0 Add regression tests for continuous assignment of assignment patterns
Check that packed array assignment patterns and struct assignment patterns
are supported for continuous assignments.

Check for both assignment to variables as well as array elements.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-03-05 12:11:45 -08:00
Lars-Peter Clausen 79919e33a2 Handle continuous assignment of assignment patterns to array elements
Currently when creating the NetNet for a continuous assignment to an array
element the type of the element is flattened into a canonical 1 dimensional
form. This works for most cases because packed types are compatible if
their total packed with is the same.

But there are some contexts such as if the right-hand-side is an assignment
pattern where the actual type matters and flattening the type will result
in incorrect behavior.

Retain the original type of the array element when creating the NetNet for
the array element assignment.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-03-05 01:09:36 -08:00
Stephen Williams a4aade5d1a
Merge pull request #873 from steveicarus/steveicarus/issue202-dumpfile-cmdline
Add support for a command line dumpfile option
2023-02-26 15:08:33 -08:00
Stephen Williams 50722494b9 ivtest: Add the dumpfile.v test
Add a regression test to show that the proper dumpfile is selected, by
noting in the output from the vvp command what file name it is creating.

To make this work, I also needed to add some capabilities to the vvp_reg.py
regression test rig.
2023-02-26 14:43:01 -08:00
Stephen Williams 29ac33493e Add support for a command line dumpfile option
The -dumpfile=<path> vvp extended argument sets the default nanme to use
for the various dumpers. If this flag is not given, the default is "dump".
The $dumpfile system task overrides the default or this command line flag.

This commit also factors out all the dumpfile selection code for the various
dumper implementations.
2023-02-26 14:05:42 -08:00
Stephen Williams 8e5476227d
Merge pull request #870 from xobs/regenerate-config.sub
regenerate config.sub
2023-02-25 11:41:51 -08:00
Cary R 3612577b52 bbr_gh800 uses a string so cannot be translated to vlog95 2023-02-17 20:06:18 -08:00
Sean Cross 7782772e4c regenerate config.sub
This generates a fresh copy of config.sub.

The existing config.sub calls 64-bit ARM targets `aarch64`, which is
the official name for the target. However, Apple targets go by the
name `arm64-apple`. As a result, this platform was not recognized.

This gets iverilog building on Apple targets with 64-bit ARM processors.

Signed-off-by: Sean Cross <sean@xobs.io>
2023-02-15 17:51:12 +08:00
Stephen Williams 378c812fe2
Merge pull request #847 from steveicarus/steveicarus/ivtest-pythonify
ivtest: Rewrite the ivtest suite tests in python
2023-02-11 19:02:51 -08:00
Stephen Williams 3085bd6845 ivtest: Move some tests to the revress-vvp list
Move some tests from the old structure to the new more descriptive
test suite. Remove them from the old lists.
2023-02-11 18:35:41 -08:00
Stephen Williams 4ea442b2d9 ivtest: Create the vvp_reg.py test script
This creates a new test suite driver and infrastructure for going
forward. This cleans up the descriptions for tests, and is more
extensible.

Include documentation for the new engine, so that new tests can go
here instead of the old test suite.
2023-02-11 18:33:24 -08:00
Stephen Williams 418bbc14bc
Merge pull request #868 from larsclausen/assign-pattern
Add initial support for packed array and packed struct assignment patterns
2023-02-09 12:48:46 -08:00
Lars-Peter Clausen 6ae085812d Add regression tests for struct assignment patterns
Check that struct assignment patterns with only positional arguments are
supported. Also check that invalid assignment patterns for structs report
an error.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-02-04 14:32:51 -08:00
Lars-Peter Clausen 4fca564614 Add regression tests for packed array assignment patterns
Check that positional and nested positional assignment patterns are
supported for packed arrays. Also check that invalid assignment patterns
for packed arrays result in an error.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-02-04 14:32:51 -08:00
Lars-Peter Clausen 7f3621d47d Add initial support for struct assignment pattern
Structs can be initialized by an assignment pattern. E.g.

```
struct packed {
  int x;
  shortint y;
} S = '{ 1, 2};
```

is the same as

```
struct packed {
  int x;
  shortint y;
} S;
s.x = 1;
s.y = 2;
```

Add initial support for unnamed struct assignment patterns. Named struct
assignment patterns like

```
struct packed {
  int x;
  shortint y;
} S = '{x: 1, y: 2};
```

are still unsupported.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-02-04 14:32:51 -08:00
Lars-Peter Clausen 5547858372 Add initial support for packed arrays/vector assignment pattern
SystemVerilog allows to use assignment patterns to assign a value to a
packed array.

This is similar to using a concatenation, with the difference that for
concatenations the values are evaluated in a self-determined context and
for assignment patterns they are evaluated in a context defined by the
element type of the packed array. This means that the value is for example
automatically width expanded or truncated if it does not have the same size
as the element type. Automatic type conversion is also done when allowed. E.g.

```
bit [3:0][3:0] x = '{1'b1, 32'h2, 3.0, "TEST"};
$display("%x", x); // -> 1234
```

Nested assignment patterns are also supported. E.g.
```
bit [1:0][3:0][3:0] x = '{'{1, 2, 3, 4.0}, '{5, 6, 7, 8}};
$display("%x", x); // -> 12345678
```

Add support for using assignment patterns as the right hand side value.
Since the complete type of the target variable is required to correctly
evaluate the assignment pattern it is handled as a special case in
`elab_rval_expression()`. For other types of expressions for packed values
only the total width of the target value is provided to the rvalue
elaboration function.

SystemVerilog also supports assignment patterns for the left hand side in
assignments. This is not yet supported.

Also not yet supported is specifying array elements by index, including
`default`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-02-04 14:32:44 -08:00
Stephen Williams 4643f57edb
Merge pull request #863 from larsclausen/export
Add support for package export
2023-01-29 10:34:23 -08:00
Lars-Peter Clausen d868983b9c Add regression tests for package export
Check that package exports are supported. Also check for various scenarios
where package exports should fail.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-17 06:22:35 -08:00
Lars-Peter Clausen 78382e72d0 Add support for package export
By default an identifier that has been imported into a package is not
available for imports by other packages. Only imports that have been
exported can be imported again. E.g.

```
package P1;
  int x;
endpackage

package P2;
  import P1::x;
  export P1::x;
endpackage

module test;
  import P2::x; // This will only work if x has been exported.
endmodule
```

Exports follow the same syntax as imports and allow both export of specific
identifiers or wildcard export. Export supports the special `*::*` target,
which will export all imported items.

Add support for handling package exports.

There is one special cases that needs to be considered. Usually when using
wildcard imports from multiple packages it is an error if there multiple
import candidates for an identifier. With exports it is possible that there
are multiple candidates through different packets, but they all refer to
the same identifier. In this case it does not create a conflict. E.g.

```
package P1;
  int x;
endpackage

package P2;
  import P1::x;
  export P1::x;
endpackage

package P3;
   import P1::*;
   import P2::*;
   int y = x; // No import conflict
endpackage
```

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-17 06:14:07 -08:00
Stephen Williams da1cefe8ea
Merge pull request #810 from steveicarus/steveicarus/issue800-test
Add br_gh800 test
2023-01-16 21:12:33 -08:00
Stephen Williams b61b3814ec Add br_gh800 test
This is a test for github issue#800. This should work on all platforms,
but Windows seems weird. The issue seems to be with Windows comparing
gold files with CR-LF weirdly, so make all the tests internal.
2023-01-16 20:47:09 -08:00
Stephen Williams 18192fdba9
Merge pull request #862 from larsclausen/enum-compat-check
Improve enum compatbility checks
2023-01-16 19:34:05 -08:00
Stephen Williams b6644186a6
Merge pull request #861 from larsclausen/scoped-symbol-search
Add common implementation for scoped symbol search
2023-01-16 19:30:25 -08:00
Stephen Williams e740e4b3f3
Merge pull request #859 from larsclausen/func-empty-arg
Improvements for calling functions with empty arguments
2023-01-16 19:26:23 -08:00
Lars-Peter Clausen 300d00b4e2 Add additional enum compatibility tests
Add additional enum compatibility tests that check for compatibility in
different contexts.
 * Array element
 * Function return value
 * Function and task argument
 * struct member
 * class property

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 14:45:58 -08:00
Lars-Peter Clausen d1fb3f8925 Enforce enum type compatibility in more places
In SystemVerilog it is not allowed to assign a value to a enum variable
that is not of the same time as the enum variable.

This is currently enforced for assignment and continuous assignment. But
ignored in other places such as function parameter passing.

Move the enum type check into `elab_rval_expr()` to cover more cases.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 14:45:58 -08:00
Lars-Peter Clausen d0613f24b8 Allow to attach data type to lvalue part select
In most cases the type of an lvalue part select is the base type of the
lvalue with the width of the part select. But there are some exceptions.

1) An index into a `string` type is of type `byte`.

2) Packed structs are implemented as packed arrays under the hood. A lvalue
struct member is elaborated as a normal part select on a packed array. The
type of that select should be the type of the member.

For the case 1 there is some special handling for strings that accounts for
this. But for case 2 the type information of the member is lost.

This works fine for most things but there are a few constructs where the
type information is required.
 * Enum type compatibility check
 * Assignment pattern behavior depends on the type of the lvalue

Allow to attach a specific type to a lvalue part select to allow correct
behavior for constructs where the type is required.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 12:38:10 -08:00
Lars-Peter Clausen f9909562fd Provide data type for more lvalue expressions
The NetAssign_:net_type() function return the type of lvalue expression.
But it only does so for a limited amount of cases.

Refactor the function so that it works for the general case and always
returns the data type, if the data type of the lvalue expression is known.

This will allow to implement better type checking and other constructs such
as pattern assignments that require to know the type of the lvalue.

It also allows to remove some duplicated code in other methods of
NetAssign_ that want to lookup the type.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 12:38:10 -08:00
Lars-Peter Clausen 7429a948cc Add regression tests for package scope identifiers that cross the package boundary
Check that an error is reported when accessing a hierarchical identifier
through a package scoped identifier.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 12:27:04 -08:00
Lars-Peter Clausen 43fe03dc75 Don't allow package scoped identifiers to cross the package boundary
Package scoped identifiers should only be able to access identifiers that
are declared in the package, but not identifiers that are visible in the
package, but declared outside of it.

```
int x;
package P;
  int y;
endpackage

module test;
  initial begin
    $display(P::x); // Should fail
    $display(P::y); // OK
  end
endmodule
```

Make sure that the symbol search will not attempt to cross the package
boundary during identifier lookup.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 12:27:04 -08:00
Lars-Peter Clausen e24aa18a80 Add common implementation for scoped symbol search
In SystemVerilog identifiers can usually have an additional package scope
in which they should be resolved. At the moment there are many places in
the code base that handle the resolution of the package scope.

Add a common data type for package scoped paths as well as a
symbol_search() variant that works on package scoped identifiers. This
allows to handle package scope resolution in a central place.

Having the code in a central place makes it easier to ensure consistent and
correct behavior. E.g. there are currently some corner case bugs that are
common to all implementations. With the common implementation it only has
to be fixed in one place.

It will also make it easier to eventually implement class scoped
identifiers.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 12:26:24 -08:00
Lars-Peter Clausen f63a162329 Provide data type for more NetExpr subclasses
There are a few NetExpr subclasses where the data type of the expression
is known, but it not attached to the NetExpr and only kept as a private
member in the subclass.

Attaching the type directly to the NetExpr allows to query it externally
and implement better type checking.

It also allows to remove a bit of duplicated code in the subclasses and
rely on the default implementation in the NetExpr base class.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 11:31:22 -08:00
Lars-Peter Clausen 05d5c9b35f Provide default implementation of NetExpr::enumeration()
The current NetExpr::enumeration() always returns a nullptr.
The NetExpr class has a ivl_type_t member that represents
the type of the expression.

Provide a default implementation of NetExpr::enumeration() that
casts this type to the netenum_t type. This will allow
to share this implementation between subclasses and remove
a bit of duplicated code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 11:31:22 -08:00
Stephen Williams 0ac3997142
Merge pull request #858 from larsclausen/class-prop-shadow
Consolidate class property handling
2023-01-16 11:23:44 -08:00
Stephen Williams 46a11f4b67
Merge pull request #845 from wmlye/wmlye/assertion-issue823
Clean up assertions in #823 and #840
2023-01-16 10:35:00 -08:00
Lars-Peter Clausen fe5e60840f Add regression test for function calls with empty arguments
Check that function calls with empty arguments are supported. Check the
general case and special cases such as calling a function with empty
arguments as part of a module port binding or force statements in automatic
contexts.

Also check that calling a function with too many trailing empty arguments
as well as passing an empty argument for a port without a default value is
an error.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 08:07:03 -08:00
Lars-Peter Clausen 4cc3c7b08f Add regression tests for shadowing class properties
Check that class properties can be shadowed by local symbols in class
methods and also check that a package scoped identifier with the same name
as class property can be accessed in a class method.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 07:13:42 -08:00
Lars-Peter Clausen 07e20376d7 Consolidate class property handling
There are currently two mechanisms for handling class properties. One that
is used when a class property is accessed through an object and other when
a class property is used freestanding in a class method.

Both are very similar, but there are some small differences. E.g. one
supports arrays, the other supports nested properties.

```
class B;
  int x;
endclass

class C;
  B b;
  B ba[2];
  task t;
    ba[0] = new; // Does work
    this.ba[0] = new; // Does not work
    b.x = 10; // Does not work
    this.b.x = 10; // Does work
  endtask
```

There is another problem where free standing properties take precedence
over local variables. E.g.

```
class C;
  int x = 1;
  task t();
    int x = 2;
    $display(x); // Should print 2, will print 1
  endtask
endclass
```

The class property elaboration also ignores the package scope of the
identifier resulting in access to a class property being elaborated if
there is a property of the same name as the scoped identifier. E.g.

```
package P;
  int x = 2;
endpackage

class C;
  int x = 1;
  task t;
    $display(P::x); // Should print 2, will print 1
  endtask
endclass
```

Consolidate the two implementation to use the same code path. This is
mainly done by letting the symbol search return a result for free standing
properties as if the property had been specified on the `this` object. I.e.
`prop` and `this.prop` will return the same result from the symbol search.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 07:13:42 -08:00
Lars-Peter Clausen 6cf19ec964 Fixup empty function/task argument lists in a consistent way
As a quirk of the (System)Verilog grammar a function or task argument list
with no arguments can not be distinguished from a argument list with a
single empty argument. The iverilog parses it as the latter. There are
currently many places in the code base where this is fixed up in slightly
different ways.

Fix this up in the parser in a central way before passing the arguments to
the elaboration stage.

The existing implementation in some cases removes all empty trailing
arguments. While this works to handle the case for zero arguments it also
hides some errors that should be detected. E.g. in the following 3
arguments are passed to a function which only takes two arguments. But no
error is reported since the explicitly specified empty arguments are
removed.

```
function f(integer a, integer b = 2); ... endfunction
f(1,,);
```

In the new implementation the empty argument will only be removed if there
is exactly one empty argument in the argument list.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 04:01:49 -08:00
Lars-Peter Clausen aea202b2e9 PECallFunction: Handle empty parameters in has_aa_term() and declare_implicit_nets()
A function parameter can be an empty value, in which case its expression is
a nullptr and can not be dereferenced. Make sure this case is handled in
the has_aa_term() and declare_implicit_nets() methods.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 04:00:13 -08:00
Lars-Peter Clausen c90265351b Duplicate default function/task argument expressions
The default value for a function or task argument is elaborated once and
then used for each function invocation where no actual value is provided.

This means if a function or task is called multiple times the same NetExpr
is passed as a sub-expression to multiple statements or expressions such as
the function call.

This is causing problems because each expression or statement expects to
have exclusive ownership over its sub-expressions. It can for example
result in a double free or other undefined behavior.

To mitigate this duplicate the default argument expression before it is
given as a sub-expression to another expression or statement.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-16 04:00:13 -08:00
Lars-Peter Clausen dc10710198 Remove cls_val parameter from old symbol_search
There are no users of the old symbol_search that need the cls_val result.
Remove it as a output parameter of the function.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-15 22:55:57 -08:00
Stephen Williams b74059eaa9
Merge pull request #855 from steveicarus/steveicarus/loop-control-support
Add break and continue loop control statements support
2023-01-15 22:21:55 -08:00
Stephen Williams 7b105a696d
Merge pull request #857 from larsclausen/import-hier-fail
Don't allow access to imported identifiers through hierarchical names
2023-01-15 22:18:46 -08:00
Stephen Williams d25af1451c
Merge pull request #856 from larsclausen/ps-method-call
Support method calls on package scoped signals
2023-01-15 22:17:49 -08:00
Stephen Williams 557bb61d10 ivtest: add br_gh191_break and br_gh191_continue tests 2023-01-15 21:47:52 -08:00
Stephen Williams 47283bdad7 Fix pform dump of GE expression. 2023-01-15 21:47:52 -08:00
Stephen Williams 6c9c876c83 Add compiler support for break and continue
This includes support at the parser (pform) through enaboration
and the netlist format for the break and continue statements.

Elaboration actually already worked for for-loops, but since the code
generators need more information, this is a rewire of that support to
be explicit about for-loops. This means they are not rewritten as fancy
while loops. The code generators will have to handle that.

Given the elaboration of for-loops now work, write the vvp code generator
support needed to implement it.

Now that for-loops are presented as for-loops to the code generator, the
vlog95 code generator doesn't need to infer them anymore. Generate the code
more directly.

Also update the tests list so that the vlog95_reg tests all pass.
2023-01-15 21:46:20 -08:00
Lars-Peter Clausen 535c09db62 Add regression test for package scoped method call
Check that it is possible to call a method on a package scoped identifier.
Both for built-in types as well as class objects.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-08 07:59:20 -08:00
Lars-Peter Clausen c1f2e0c21f Support method calls on package scoped signals
Currently package scoped function calls are supported. Update the parser
and elaboration to also allow method calls on packaged scoped variables.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-08 07:59:20 -08:00
Lars-Peter Clausen f9a0e2f401 Add regression tests for accessing imported identifiers through hierarchical names
Check that an error is reported when trying to access an imported
identifier through a hierarchical name.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-07 10:31:02 -08:00
Lars-Peter Clausen f4d55081ed Don't allow access to imported identifiers through hierarchical names
Imported identifiers should only be visible in the scope they have been
imported too. They should not be accessible through hierarchical names into
that scope. This is defined in section 26.3 ("Referencing data in
packages") of the LRM (1800-2017).

Modify the symbol search to not look at imports if the name is part of a
hierarchical path.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-07 10:30:55 -08:00
Stephen Williams 45bd0968c3
Merge pull request #853 from larsclausen/ci-parallel
ci: Use parallel build
2023-01-06 20:22:25 -08:00
Stephen Williams 08f2c88fcf
Merge pull request #852 from larsclausen/vvp-string-vpi
vvp: Handle null-bytes in a conistent way when reading through VPI
2023-01-06 20:21:03 -08:00
Stephen Williams 97b897cb38
Merge pull request #851 from larsclausen/str-literal-to-str-remove-null-byte
vvp: Remove null-bytes when converting string literals to SV strings
2023-01-06 20:19:33 -08:00
Stephen Williams 9931d92c70
Merge pull request #843 from larsclausen/ps-array-cassign
Handle continuous array assignments from package scoped indentifiers
2023-01-06 20:18:44 -08:00
Stephen Williams 53854bb064
Merge pull request #842 from larsclausen/class-static-prop-base
Allow access to static properties of base classes
2023-01-06 20:17:31 -08:00
Stephen Williams 09e841eee2
Merge pull request #841 from larsclausen/ps-func-call-error-handling
Improve error handling for package scoped function calls
2023-01-06 20:16:20 -08:00
Lars-Peter Clausen 9fcec0186c ci: Use parallel build
The github CI VM has multiple CPUs. 2 for Linux and Windows, 3 for macOS.
Make use of parallel build to speed up the CI tests a bit.

For Windows the `makepkg-mingw` command already schedules a parallel
build, so no changes are made to the Windows build.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-02 16:53:33 -08:00
Lars-Peter Clausen 71bb011597 Add regression tests for string formatting of null-bytes through VPI
Check that null-bytes get removed when reading a value through the VPI API
as a vpiStringVal. Also check that null-bytes are not removed from string
literals when string literals are read through the VPI API as a non
vpiStringVal.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-02 16:22:46 -08:00
Lars-Peter Clausen 56efec8ed1 tgt-vlog95: Don't strip null-bytes from string literals in structural elements
The vlog95 backend currently strips null-bytes from strings in structural
elements. E.g. `assign y = "a\000b"` gets translated to `assign y = "ab"`.

This changes the behavior of the generated output compared to the input.
Don't ignore the null-bytes to make sure the behavior stays the same.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-02 16:22:46 -08:00
Lars-Peter Clausen 2e12e47a2b tgt-vlog95: Don't strip leading null-bytes from string literals
When a string literal is used in a context where it needs to be wider than
it is it will get left-padded with null-bytes. When the vlog95 backend
emits the string literal it will strip the leading null-bytes as it results
in much more legible code.

Unfortunately there are some corner cases where this results in a change of
behavior of the generated code compared to the original. E.g. if the
context that caused the width expansion has been removed by optimization.
`$display(0 ? "Yes" : "No")` should print " No" due to width expansion, but
when running through the vlog95 backend it will print "No".

Another scenario where there is a change in behavior is when a null byte
was explicitly added at the front of a string literal. E.g. $bits("\000ab")
should print 24, but will print 16 when running through the vlog95 backend.

To mitigate this remove the stripping of the leading null-bytes from the
vlog95 backend. This results in slightly less legible code being generated
in some cases, but makes sure that the code is always correct.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-02 16:22:33 -08:00
Lars-Peter Clausen 3cfbd7345f vvp: Only ignore leading null-bytes when reading as string through VPI
Currently when reading a number literal through the VPI API as a
vpiStringVal all null-bytes in the literal get ignored. This behavior is
different from when reading a signal through the VPI API as a vpiStringVal.
The latter will only ignore leading null-bytes and replace other null-bytes
with a space. E.g. the following two will print different values.

```
$display("%s", "a\000b"); // -> " ab"
reg [23:0] x = "a\000b";
$display("%s", x); // -> "a b"
```

For consistency modify the number literal formatting code so that it has
the same behavior as the signal value formatting code and only replaces
leading null-bytes.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-02 15:36:02 -08:00
Lars-Peter Clausen b8ddeb8848 vvp: Handle null-bytes in the string literal VPI support
The VPI API for string literals does not correctly handle the case where a
null-byte ('\0') appears in the string literal. It uses strlen() to
calculate the length of the literal, which will give the wrong result if
there is a null-byte in the string literal. Instead of using strlen() use
the stored length to fix this.

In addition when formatting a string literal as a string ignore any
null-bytes. The LRM is not entirely clear what should happen to null-bytes
when formatting a value as a string. But the behavior of ignoring the
null-bytes is consistent with the rules of SystemVerilog for converting a
string literal to a SV string.

This problem can occur when a string literal gets null-byte left-padded due
to width of its context of its expression, but then optimization removes
part of the expression and only leaves the padded string literal.

E.g.
```
$display(0 ? "Yes" : "No");
```

will be transformed into

```
$display("\000No");
```

There is also one subtle change in behavior associated with this. The empty
string ("") is supposed to be equivalent to 8'h00. So e.g.
`$display(":%s:", "")` should print ": :" since the width of the empty
string is 1 byte and the %s modifier prints a string with the width of the
value, left-padding with spaces if necessary. The current implementation
will print "::" though. This change requires to update the marco_with_args
gold file.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-02 15:35:34 -08:00
Lars-Peter Clausen 56baae11cc Add regression tests for null-byte handling when assigning to SV strings
Check that when assigning or casting a string literal or vector to a SV
string type that null-bytes are removed.

Also check that writing a null-byte to an element of a string variable is
ignored.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-02 13:20:11 -08:00
Lars-Peter Clausen 4ddf234c32 vvp: Remove null-bytes when converting string literals to SV strings
The `%pushi/str` and `%concati/str` instructions should remove null-bytes
from the string literal when converting it to a string. This is defined in
section 6.16 ("String data type") of the LRM (1800-2017).

This is already handled correctly when converting a vector from the stack
to a SV string, just not when converting a string literal to SV string.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2023-01-02 13:19:40 -08:00
Bill Lye 66f5db1fb8
Merge branch 'steveicarus:master' into wmlye/assertion-issue823 2023-01-02 12:13:59 -08:00
Bill Lye b277f07b3a Typo 2022-12-31 13:39:58 -08:00
Bill Lye 696c5d5d12 Renamed testcases from "*.sv" to "*.v" 2022-12-31 13:37:45 -08:00
Bill Lye 6f1165a628 Added regression tests for issues #823 and #840 2022-12-31 11:57:33 -08:00
Martin Whitaker 23e51ef7a8 Fix compilation with -Werror=format-security. 2022-12-31 16:51:28 +00:00
Bill Lye 56eb91ea9e Fix for assertion failure in Issue #823 2022-12-30 11:12:29 -08:00
Bill Lye ee0c6bb5e4 Modifications to give error messages rather than assertions 2022-12-30 10:36:38 -08:00
Lars-Peter Clausen f42bb35c3e Add regression tests for packed scoped continuous array assign
Check that continuous array assignments from package scoped identifiers are
supported.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-30 10:35:35 -08:00
Lars-Peter Clausen e88f9c52ea Handle continuous array assignments from package scoped indentifiers
Make sure the package scope is considered when elaborating identifiers for
continuous unpacked array assignments.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-30 10:35:28 -08:00
Lars-Peter Clausen c8044bddf0 Add regression test for access to static property of base class
Check that it is possible to access a static property of a base class.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-29 11:17:43 -08:00
Lars-Peter Clausen 8a807695e5 Allow access to static properties of base classes
Classes are allowed to access properties of the base class. This also
includes static properties. Currently when looking up a static property
only those of the class itself are considered. Extend this to also consider
properties of the base classes.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-29 11:17:43 -08:00
Lars-Peter Clausen 5563dc6250 Add regression tests for package scoped function call errors
Check that an error is reported, rather than crashing, when trying to do a
package scoped function call when the function does not exist in the
package or is not a function.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-29 10:54:42 -08:00
Lars-Peter Clausen 43443dd7d1 Improve error handling for package scoped function calls
Currently a package scoped function call will result in an assert if the
function does not exist in the package scope.

For non-package scoped function calls instead a proper error is reported.

Refactor the code to share the same code paths between package scoped and
non-package scoped function calls. This makes sure that errors are reported
in both cases. It also makes the code slightly smaller.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-29 10:53:16 -08:00
Stephen Williams 0958621ad1
Merge pull request #839 from larsclausen/package-scope-member-sel
Elaborate member selects in the scope where they are used
2022-12-29 10:30:23 -08:00
Lars-Peter Clausen b07a66b8a3 Add regression tests for member selects on package scoped identifiers
Check that indices to package scoped identifiers are evaluated in the scope
where the identifier is accessed and not in the scope where the identifier
is declared.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-28 17:54:59 -08:00
Lars-Peter Clausen 710267e9bb Elaborate member selects in the scope where they are used
There are a few cases where a member select on a package scoped identifier
is evaluated in the scope of the package rather than the scope where the
identifier is referenced.

This leads to incorrect behavior if a local symbol is used as an index in a
part select of the referenced member select. E.g.

```
package P;
  localparam N = 1;
  struct packed {
    logic [3:0] x;
  } s = 4'b0101;
endpackage

module test;
  localparam N = 2;
  initial $display(P::s.x[N]); // Will print 0, should print 1
endmodule
```

Use the scope where the member select is used, rather than the scope where
the identifier is defined, to fix this.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-28 17:54:48 -08:00
Stephen Williams a582f66089
Merge pull request #838 from larsclausen/ps-func-call-fix-width
Fix width and sign determination for package scoped function calls
2022-12-28 17:38:35 -08:00
Stephen Williams 1b6e35d6e1
Merge pull request #837 from larsclausen/ivtest-fix-parameter-no-default-result
regress-sv: Fix expected result for parameter_no_default test
2022-12-28 17:35:57 -08:00
Cary R dc8b7d0184 Cleanup some cppcheck warnings 2022-12-28 00:00:31 -08:00
Lars-Peter Clausen 7df00d3070 Add additional regression for package scoped function calls
Check that width and sign determination works correctly for package scoped
function calls.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-27 20:01:29 -08:00
Lars-Peter Clausen 5634dc6915 Fix width and sign determination for package scoped function calls
`PECallFunction::test_width()` does not consider the package scope and will
not return any information for package scoped function calls.

As a result in contexts where the width or sign of a expression must be
known produces the wrong result when using a package scoped function.

Make sure to search for the function name in the package scope if a package
is specified.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-27 19:59:10 -08:00
Lars-Peter Clausen 50d7d66043 tgt-vlog95: Handle signed return types
The vlog95 backend currently ignores the sign of a function return value.

Check for it and if `-pallowsigned=1` was specified emit the `signed`
keyword. Otherwise report an error.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-27 19:54:44 -08:00
Lars-Peter Clausen 74eaaa7f10 regress-sv: Fix expected result for parameter_no_default test
The parameter_no_default test is expected to pass in SystemVerilog mode.
Make sure the expected result is correctly annotated in the results file.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-27 19:10:43 -08:00
Cary R 5cd8bb3a88 Merge branch 'master' of github.com:steveicarus/iverilog 2022-12-27 16:30:42 -08:00
Cary R 18f8e00f9f Cleanup the force SystemVerilog tests 2022-12-27 16:29:08 -08:00
Stephen Williams 59df5f7d01
Merge pull request #836 from larsclausen/struct-packed-init
Report error for packed struct default member values
2022-12-27 13:57:30 -08:00
Stephen Williams 7c866b2590
Merge pull request #833 from larsclausen/ivlpp-multiline-comment
ivlpp: Improve handling of comments in macros
2022-12-27 13:56:33 -08:00
Stephen Williams 4ce8fa255a
Merge pull request #831 from larsclausen/void-func-always-comb
Let void functions in always_comb block contribute to sensitivity list
2022-12-27 13:52:27 -08:00
Stephen Williams 48bc316f1d
Merge pull request #830 from larsclausen/negative-size-cast
Report an error for size casts with a negative value
2022-12-27 13:45:57 -08:00
Cary R 8a0f395c76 Cleanup the vlog95 results 2022-12-27 12:54:29 -08:00
Cary R f5865f33f6 Update to latest FST files 2022-12-27 11:42:07 -08:00
Lars-Peter Clausen e83c0211b2 Add regression test for default member values in packed structs
Default member values are not allowed in packed structs. Check that an
error is reported for them.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-27 09:02:36 -08:00
Lars-Peter Clausen 6713b343cc Report error for packed struct default member values
SystemVerilog allows struct members to have default values specified as
part of the struct declaration. But this is only allowed for unpacked
structs. For packed structs an error should be reported. This is defined in
section 7.2.2 ("Assigning to structures") of the LRM (1800-2017).

Currently default member values are just silently discarded if specified
for a packed struct. Make sure to report an error instead.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-27 08:46:53 -08:00
Stephen Williams 7d57acc106
Merge pull request #834 from steveicarus/steveicarus/document-ivtests-vxx-list
ivtest: Document the ivest/regress-vNN.list file.
2022-12-26 17:43:02 -08:00
Stephen Williams a7c5eceeea ivtest: Document the ivest/regress-vNN.list file.
This is another bit that needs to be accounted for when changing versions.
2022-12-26 20:10:56 -05:00
Lars-Peter Clausen 8187bf58f7 Add regression test for macros with multi-line comments
Check that multi-line comments are supported in macros.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-26 16:12:01 -08:00
Lars-Peter Clausen 109b794253 Add regression tests for comments in macros
Add regression tests for some corner cases for handling comments in macros.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-26 16:12:01 -08:00
Lars-Peter Clausen c4daf11fac ivlpp: Handle multi-line comments in macros
Make sure that comments spanning multiple lines are supported in multi-line
macros. Since the lexer parses line by line we need a flag to track whether
a multi-line comment is currently active.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-26 16:12:01 -08:00
Lars-Peter Clausen d12a74beec ivlpp: Handle '*' or '/' following C-style comment in macro
A '*' or '/' directly following a C-style comment in a macro currently
triggers the detection of the start of another comment. Fix this by first
looking for a '/' that should start the comment.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-26 16:08:28 -08:00
Lars-Peter Clausen 9a96ba62e4 Add regression test for using void function in always_comb block
Check that variables used in void functions contribute to the sensitivity
list in a always_comb block.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-26 16:08:03 -08:00
Lars-Peter Clausen a659ca09ce Let void functions in always_comb block contribute to sensitivity list
Internally void function calls are modeled as task calls. But unlike task
calls, access to a signal inside a void function is supposed to contribute
to the sensitivity list of an always_comb block.

Make sure that the same logic applied for non-void functions is also
applied for void functions.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-26 16:08:03 -08:00
Lars-Peter Clausen 5685eac1be Add regression tests for invalid size casts
Check that an error is reported for size casts with either a value of 0, a
negative value or an undefined value.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-26 16:07:22 -08:00
Lars-Peter Clausen 4436dc41ab Report an error for size casts with a negative value
Size casts are only allowed if the value is positive. For cases where it is
0 negative or undefined an error should be reported. Currently the negative
case is not handled. Extend the test to also check for negative values.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-26 16:07:22 -08:00
Stephen Williams e088bee091
Merge pull request #832 from larsclausen/fix-windows-ci
ci: Windows: Add gperf to dependency list
2022-12-26 16:02:03 -08:00
Lars-Peter Clausen 8b0ace3726 ci: Windows: Add gperf to dependency list
msys2 removed the gperf package from the base-devel package collection[1].

Add gperf explicitly to the dependency list, without this the Windows
CI will fail.

[1] 085698dce3

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-26 15:07:34 -08:00
Lars-Peter Clausen 13ba780fe8 ci: Windows: Replace `MINGW_INSTALLS` with `MINGW_ARCH`
Currently the Windows build generates a warning

   => WARNING: MINGW_INSTALLS is deprecated, use MINGW_ARCH instead

Make this change to the CI workflow file.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-26 15:07:34 -08:00
Lars-Peter Clausen 42212cfb58 Add `regress-v13.list`
With the development version bumped to v13 the regression tests runner
expects a `regress-v13.list`. Provide one, which is just a copy of the
`regress-v12.list` for now.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-26 15:07:34 -08:00
Stephen Williams 43c85529af devel: Fix ci build vvp test
The vvp test expects a proper version stamp in the examples/hello.vvp file.
2022-12-26 17:16:26 -05:00
Stephen Williams 8a290830df devel: Step devel past v12 to v13 2022-12-26 12:56:19 -05:00
1930 changed files with 61680 additions and 25539 deletions

14
.github/test.sh vendored
View File

@ -1,14 +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
perl vpi_reg.pl || status=1
exit $status

View File

@ -19,10 +19,15 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt update -qq 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 - name: Make Documentation
run: | run: |
. .venv/bin/activate
cd Documentation cd Documentation
make html make html

View File

@ -1,24 +1,27 @@
name: test name: test
on: on:
# Every push onto the main branch and releases triggers a retest. # Every push onto the main branch triggers a retest.
push: push:
branches: branches:
- master - master
- v12-branch
# All pull_requests trigger a retest. # All pull_requests trigger a retest.
pull_request: pull_request:
workflow_dispatch:
jobs: jobs:
mac: mac:
strategy: strategy:
fail-fast: false fail-fast: false
runs-on: macos-latest matrix:
name: '🍏 macOS' libvvp: [true]
suffix: [true]
runs-on: macos-15-intel
name: 🍏 macOS${{ matrix.libvvp && ' +libvvp' || '' }}${{ matrix.suffix && ' +suffix' || '' }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v6
- name: Install dependencies - name: Install dependencies
run: | run: |
@ -27,46 +30,66 @@ jobs:
- name: Build, check and install - name: Build, check and install
run: | run: |
export PATH="/usr/local/opt/bison/bin:$PATH" 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 autoconf
./configure ./configure $CONFIG_OPTS
make check make -j$(nproc) check
sudo make install sudo make install
- name: Test - name: Test
run: ./.github/test.sh run: |
make check-installed
lin: lin:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ os: ['22.04', '24.04']
'20.04', # libvvp: [false, true]
'22.04' # suffix: [false, true]
]
runs-on: ubuntu-${{ matrix.os }} runs-on: ubuntu-${{ matrix.os }}
name: '🐧 Ubuntu ${{ matrix.os }}' name: 🐧 Ubuntu ${{ matrix.os }}${{ matrix.libvvp && ' +libvvp' || '' }}${{ matrix.suffix && ' +suffix' || '' }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v6
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt update -qq sudo apt update -qq
sudo apt install -y make g++ git bison flex gperf libreadline-dev autoconf python3-sphinx 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 - name: Build, check and install
run: | 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 autoconf
./configure ./configure $CONFIG_OPTS
make check make -j$(nproc) check
sudo make install sudo make install
- name: Test - name: Test
run: ./.github/test.sh run:
make check-installed
- name: Documentation - name: Documentation
run: | run: |
. .venv/bin/activate
cd Documentation cd Documentation
make html make html
@ -75,11 +98,14 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
include: [ msystem: [MINGW64, UCRT64, CLANG64]
{ msystem: MINGW64, arch: x86_64 }, # libvvp: [false, true]
{ msystem: MINGW32, arch: i686 } # suffix: [false, true]
] include:
name: 🟪 ${{ matrix.msystem}} · ${{ matrix.arch }} - { msystem: MINGW64, env: x86_64 }
- { msystem: UCRT64, env: ucrt-x86_64 }
- { msystem: CLANG64, env: clang-x86_64 }
name: 🟪 ${{ matrix.msystem }}${{ matrix.libvvp && ' +libvvp' || '' }}${{ matrix.suffix && ' +suffix' || '' }}
defaults: defaults:
run: run:
shell: msys2 {0} shell: msys2 {0}
@ -90,7 +116,7 @@ jobs:
- run: git config --global core.autocrlf input - run: git config --global core.autocrlf input
shell: bash shell: bash
- uses: actions/checkout@v2 - uses: actions/checkout@v6
- uses: msys2/setup-msys2@v2 - uses: msys2/setup-msys2@v2
with: with:
@ -99,21 +125,37 @@ jobs:
install: > install: >
git git
base-devel base-devel
gperf python-pip
mingw-w64-${{ matrix.arch }}-toolchain mingw-w64-${{ matrix.env }}-perl
- uses: actions/setup-python@v6
with:
python-version: '>=3.5'
- name: Build and check - name: Build and check
run: | run: |
cd msys2 cd msys2
CONFIG_OPTS=""
if [ ${{ matrix.msystem }} != "CLANG64" ] ; then
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 makepkg-mingw --noconfirm --noprogressbar -sCLf
- name: Install - name: Install
run: pacman -U --noconfirm msys2/*.zst run: pacman -U --noconfirm msys2/*.zst
- name: Test - name: Test
run: ./.github/test.sh run: |
make check-installed
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v7
with: with:
name: ${{ matrix.msystem }}-${{ matrix.arch }} name: 🟪 ${{ matrix.msystem }}${{ matrix.libvvp && ' +libvvp' || '' }}
path: msys2/*.zst path: msys2/*.zst

48
.gitignore vendored
View File

@ -8,6 +8,10 @@
*.swp *.swp
*~ *~
# Virtual environments
.conda/
.venv/
# Top level generic files # Top level generic files
tags tags
TAGS TAGS
@ -17,6 +21,7 @@ cscope.*
# Object files and libraries # Object files and libraries
*.[oa] *.[oa]
*.so
gmon*.out gmon*.out
gmon*.txt gmon*.txt
@ -30,16 +35,19 @@ Makefile
/_pli_types.h /_pli_types.h
config.h config.h
/tgt-pcb/pcb_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-vvp/vvp_config.h
/tgt-vhdl/vhdl_config.h /tgt-vhdl/vhdl_config.h
/vhdlpp/vhdlpp_config.h
/vpi/vpi_config.h /vpi/vpi_config.h
stamp-*-h stamp-*-h
/version.h
/version_tag.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 # Directories
autom4te.cache autom4te.cache
@ -51,8 +59,6 @@ dep
*.vpi *.vpi
/cadpli/cadpli.vpl /cadpli/cadpli.vpl
/tgt-blif/Makefile
# lex, yacc and gperf output # lex, yacc and gperf output
/driver/cflexor.c /driver/cflexor.c
/driver/cfparse.c /driver/cfparse.c
@ -61,14 +67,6 @@ dep
/ivlpp/lexor.c /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.cc
/lexor_keyword.cc /lexor_keyword.cc
/parse.cc /parse.cc
@ -77,6 +75,17 @@ dep
/syn-rules.cc /syn-rules.cc
/syn-rules.output /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_lexor.c
/vpi/sdf_parse.c /vpi/sdf_parse.c
/vpi/sdf_parse.h /vpi/sdf_parse.h
@ -96,17 +105,13 @@ dep
# Program created files # Program created files
/vvp/tables.cc /vvp/tables.cc
/iverilog-vpi.man
/driver-vpi/res.rc
/driver/iverilog.man
/vvp/vvp.man
# The executables. # The executables.
*.exe *.exe
/driver/iverilog /driver/iverilog
/iverilog-vpi /driver-vpi/iverilog-vpi
/ivl /ivl
/ivlpp/ivlpp /ivlpp/ivlpp
/vhdlpp/vhdlpp
/vvp/vvp /vvp/vvp
/ivl.exp /ivl.exp
@ -114,3 +119,4 @@ dep
# Check output # Check output
/check.vvp /check.vvp
/driver/top.vvp

View File

@ -1,7 +1,7 @@
#ifndef IVL_AStatement_H #ifndef IVL_AStatement_H
#define IVL_AStatement_H #define IVL_AStatement_H
/* /*
* Copyright (c) 2008-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 2008-2026 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -40,10 +40,13 @@ class AContrib : public Statement {
public: public:
AContrib(PExpr*lval, PExpr*rval); AContrib(PExpr*lval, PExpr*rval);
~AContrib(); ~AContrib() override;
virtual void dump(std::ostream&out, unsigned ind) const; AContrib(const AContrib&) = delete;
virtual NetProc* elaborate(Design*des, NetScope*scope) const; AContrib& operator=(const AContrib&) = delete;
virtual void dump(std::ostream&out, unsigned ind) const override;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
private: private:
PExpr*lval_; PExpr*lval_;
@ -61,7 +64,7 @@ class AProcess : public LineInfo {
AProcess(ivl_process_type_t t, Statement*st) AProcess(ivl_process_type_t t, Statement*st)
: type_(t), statement_(st) { } : type_(t), statement_(st) { }
~AProcess(); ~AProcess() override;
bool elaborate(Design*des, NetScope*scope) const; bool elaborate(Design*des, NetScope*scope) const;

174
BUGS.txt
View File

@ -1,174 +0,0 @@
HOW TO REPORT BUGS
Before I can fix an error, I need to understand what the problem
is. Try to explain what is wrong and why you think it is wrong. Please
try to include sample code that demonstrates the problem. Include a
description of what Icarus Verilog does that is wrong, and what you
expect should happen. And include the command line flags passed to the
compiler to make the error happen. (This is often overlooked, and
sometimes important.)
* The Compiler Doesn't Compile
If Icarus Verilog doesn't compile, I need to know about the
compilation tools you are using. Specifically, I need to know:
- Operating system and processor type,
- Compiler w/ version,
- Versions of any libraries being linked, and
- anything else you think relevant.
Be aware that I do not have at my disposal a porting lab. I have the
workstation on my desk, a Mac laptop, and the Linux/Intel box with a
logic analyzer and 'scope hanging off it.
* The Compiler Crashes
No compiler should crash, no matter what kind of garbage is fed to
it. If the compiler crashes, you definitely found a bug and I need to
know about it.
Icarus Verilog internally checks its state while it works, and if it
detects something wrong that it cannot recover from, it will abort
intentionally. The "assertion failure" message that the program
prints in the process of dying is very important. It tells me where in
the source the bad thing happened. Include that message in the bug
report.
If there are no assertion messages, I need to know that as well.
I also need a complete test program that demonstrates the crash.
* It Doesn't Like My Perfectly Valid Program(tm)
I need to know what you think is right that Icarus Verilog gets
wrong. Does it reject your "Perfectly Valid Program(tm)" or does it
compile it but give incorrect results? The latter is the most
insidious as it doesn't scream out to be fixed unless someone is
watching closely. However, if I get a sample program from you, and I
can compile it, and I run it and nuclear junk doesn't fall from the
sky, I'm moving on to the next problem.
So, if your program doesn't compile, tell me so, tell me where the
error occurs, and include a complete Perfectly Valid Test Program(tm).
You tell me that it fails to compile for you, and I find that it
compiles for me, then hooray I fixed it. It can happen, you
know. What's on my disk is more recent than the latest snapshot.
If your program does compile, but generates incorrect output, I need
to know what it says and what you think it should say. From this I can
take your sample program and work on Icarus Verilog until it gets the
proper results. For this to work, of course, I first need to know what
is wrong with the output. Spell it out, because I've been known to
miss the obvious. Compiler writers often get buried in the details of
the wrong problem.
* It Generates Incorrect Target Code
As Icarus Verilog adds target code generators, there will be cases
where errors in the output netlist format occur. This is a tough nut
because I might not have all the tools to test the target format you
are reporting problems with. However, if you clearly explain what is
right and wrong about the generated output, I will probably be able
to fix the problem. It may take a few iterations.
In this case, if possible include not only the sample Verilog program,
but the generated netlist file(s) and a clear indication of what went
wrong or what is expected. If it is not clear to me, I will ask for
clarification.
* The Output is Correct, But Less Than Ideal
If the output is strictly correct, but just not good enough for
practical use, I would like to know. These sorts of problems are
likely to be more subjective than a core dump, but are worthy of
consideration. However, realize that outright errors will get more
attention than missed optimizations.
THE MAKING OF A GOOD TEST PROGRAM
If at all possible, please submit a complete source file that
demonstrates the problem. If the error occurs after elaboration,
please include a top level module in the program that is suitable for
the target format. If I have to write the module myself, I might not
write it in a way that tickles the bug. So please, send all the
Verilog source that I need to invoke the error.
Also, include the command line you use to invoke the compiler. For
example:
iverilog -o foo.out -tvvp foo.v
iverilog foo.vl -s starthere
If the error occurs with the null target (``-tnull'') then a top level
module may not be needed as long as the ``-s <name>'' switch is
given.
So when you send a test case, ask yourself "Can poor overworked Steve
invoke the error without any Verilog other than what is included?" And
while we are at it, please place a copyright notice in your test
program and include a GPL license statement if you can. Your test
program may find its way into the test suite, and the notices will
make it all nice and legal. Please look at the existing tests in the
test suite <http://sourceforge.net/ivtest> for examples of good test
programs.
RESEARCHING EXISTING/PAST BUGS, AND FILING REPORTS
The URL <https://sourceforge.net/p/iverilog/bugs/> is the main
bug tracking system, although some users have reported bugs at
<https://github.com/steveicarus/iverilog/issues/>. Once you believe
you have found a bug, you may browse the bugs database for existing
bugs that may be related to yours. You might find that your bug has
already been fixed in a later release or snapshot. If that's the case,
then you are set. Also, consider if you are reporting a bug or really
asking for a new feature, and use the appropriate tracker.
system (although you will also find bug rep
The bug database supports basic keyword searches, and you can
optionally limit your search to active bugs, or fixed bugs. You may
also browse the bug database, just to get an idea what is still
broken. You may for example find a related bug that explains your
symptom.
The root page of the bug report database describes how to submit your
completed bug report.
HOW TO SEND PATCHES
Bug reports with patches are very welcome, especially if they are
formatted such that I can inspect them, decide that they are obviously
correct, and apply them without worry.
I prefer patches generated by the git source code tracking system. If
you are editing the source, you really should be using the latest
version from git. Please see the developer documentation for more
detailed instructions -- <http://iverilog.wikia.com/wiki/>.
When you make a patch, submit it to the "Patches" tracker at
<https://sourceforge.net/p/iverilog/patches/>. Patches added to
the "Patches" tracker enter the developer workflow, are checked,
applied to the appropriate git branch, and are pushed. Then the
tracker item is closed.
If you send patches, *please* tell me what this patch is supposed to
accomplish, which branch you intended to be patched, and if
appropriate include a test program that demonstrates the efficacy of
the patch. (If I have no idea what the patch is for, I will ask for
clarification before applying it.)
COPYRIGHT ISSUES
Icarus Verilog is Copyright (c) 1998-2018 Stephen Williams except
where otherwise noted. Minor patches are covered as derivative works
(or editorial comment or whatever the appropriate legal term is) and
folded into the rest of ivl. However, if a submission can reasonably
be considered independently copyrightable, it's yours and I encourage
you to claim it with appropriate copyright notices. This submission
then falls under the "otherwise noted" category.
I must insist that any copyright material submitted for inclusion
include the GPL license notice as shown in the rest of the source.

View File

@ -20,7 +20,7 @@
# -- Project information ----------------------------------------------------- # -- Project information -----------------------------------------------------
project = 'Icarus Verilog' project = 'Icarus Verilog'
copyright = '2022, Stephen Williams' copyright = '2024-2026, Stephen Williams'
author = 'Stephen Williams' author = 'Stephen Williams'
# The short X.Y version # The short X.Y version
@ -58,7 +58,7 @@ master_doc = 'index'
# #
# This is also used if you do content translation via gettext catalogs. # This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases. # Usually you set "language" from the command line for these cases.
language = None language = 'en'
# List of patterns, relative to source directory, that match files and # List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files. # directories to ignore when looking for source files.
@ -68,24 +68,40 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use. # The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx' pygments_style = 'sphinx'
# If no language is specified, use none
highlight_language = 'none'
# -- Options for HTML output ------------------------------------------------- # -- 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 # The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes. # 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 # 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 # further. For a list of options available for each theme, see the
# documentation. # 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, # 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, # relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css". # so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static'] #html_static_path = ['_static']
html_static_path = []
# Custom sidebar templates, must be a dictionary that maps document names # Custom sidebar templates, must be a dictionary that maps document names
# to template names. # to template names.
@ -97,6 +113,7 @@ html_static_path = ['_static']
# #
# html_sidebars = {} # html_sidebars = {}
html_favicon = 'favicon.ico'
# -- Options for HTMLHelp output --------------------------------------------- # -- Options for HTMLHelp output ---------------------------------------------
@ -138,7 +155,7 @@ latex_documents = [
# One entry per manual page. List of tuples # One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section). # (source start file, name, description, authors, manual section).
man_pages = [ man_pages = [
(master_doc, 'icarusverilog', 'Icarus Verilog Documentation', (master_doc, 'iverilog-docs', 'Icarus Verilog Documentation',
[author], 1) [author], 1)
] ]
@ -152,4 +169,4 @@ texinfo_documents = [
(master_doc, 'IcarusVerilog', 'Icarus Verilog Documentation', (master_doc, 'IcarusVerilog', 'Icarus Verilog Documentation',
author, 'IcarusVerilog', 'One line description of project.', author, 'IcarusVerilog', 'One line description of project.',
'Miscellaneous'), 'Miscellaneous'),
] ]

View File

@ -1,5 +1,5 @@
Getting Started as a Contributer Getting Started as a Contributor
================================ ================================
Icarus Verilog development is centered around the github repository at Icarus Verilog development is centered around the github repository at
@ -103,6 +103,22 @@ reference the correct run time files and directories. The run time will check
that it is running a file with a compatible version e.g.(you can not run a that it is running a file with a compatible version e.g.(you can not run a
V0.9 file with the V0.8 run time). V0.9 file with the V0.8 run time).
.. code-block:: none
--enable-libvvp
The vvp program is built as a small stub linked to a shared library,
libvvp.so, that may be linked with other programs so that they can host
a vvp simulation.
.. code-block:: none
--enable-libveriuser
PLI version 1 (the ACC and TF routines) were deprecated in IEEE 1364-2005.
These are supported in Icarus Verilog by the libveriuser library and cadpli
module. Starting with v13, these will only be built if this option is used.
A debug options is: A debug options is:
.. code-block:: none .. code-block:: none
@ -111,7 +127,7 @@ A debug options is:
This option adds extra memory cleanup code and pool management code to allow This option adds extra memory cleanup code and pool management code to allow
better memory leak checking when valgrind is available. This option is not better memory leak checking when valgrind is available. This option is not
need when checking for basic errors with valgrind. needed when checking for basic errors with valgrind.
Compiling on Linux Compiling on Linux
------------------ ------------------
@ -163,13 +179,21 @@ example:
.. code-block:: console .. code-block:: console
% cd ivtest % cd ivtest
% ./vvp_reg.pl --strict % ./vvp_reg.pl
% ./vvp_reg.py
% ./vpi_reg.pl
will run all the regression tests for the simulation engine. (This is what will run all the regression tests for the simulation engine. (This is what
most people will want to do.) You should rerun this test before submitting most people will want to do.) You should rerun these tests before submitting
patches to the developers. Also, if you are adding a new feature, you should patches to the developers. Also, if you are adding a new feature, you should
add test programs to the regression test suite to validate your new feature add test programs to the regression test suite to validate your new feature
(or bug fix.) (or bug fix.). The python script is the preferred method to add new tests.
All of these scripts take other options to test various configurations. What
options are supported can be found by using the ``-h/--help`` argument. There
is also a separate ``vlog95_reg.pl`` script for testing the vlog95 translation
of the original tests. This is integrated into the existing Python test script
for the new tests.
Note that pull requests will be required to pass these regression tests before Note that pull requests will be required to pass these regression tests before
being merged. being merged.
@ -218,8 +242,7 @@ first push the branch up to github:
Then go to github.com to create your pull request. `Create your pull request Then go to github.com to create your pull request. `Create your pull request
against the "master" branch of the upstream repository against the "master" branch of the upstream repository
<https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork>`_, <https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork>`_,
or the version branch that you are working on. Your pull reuqest will be run or the version branch that you are working on. Your pull request will be run
through continuous integration, and reviewed by one of the main through continuous integration, and reviewed by one of the main
authors. Feedback may be offered to your PR, and once accepted, an approved authors. Feedback may be offered to your PR, and once accepted, an approved
individual will merge it for you. Then you are done. individual will merge it for you. Then you are done.

View File

@ -1,4 +1,7 @@
Glossary
========
Throughout Icarus Verilog descriptions and source code, I use a Throughout Icarus Verilog descriptions and source code, I use a
variety of terms and acronyms that might be specific to Icarus variety of terms and acronyms that might be specific to Icarus
Verilog, have an Icarus Verilog specific meaning, or just aren't Verilog, have an Icarus Verilog specific meaning, or just aren't
@ -22,7 +25,7 @@ UDP - User Defined Primitive
syntax for defining them is described in the LRM. syntax for defining them is described in the LRM.
VPI - VPI - Verilog Procedural Interface
This is the C API that is defined by the Verilog standard, and This is the C API that is defined by the Verilog standard, and
that Icarus Verilog partially implements. See also PLI. that Icarus Verilog partially implements. See also PLI.
@ -34,6 +37,12 @@ VVM - Verilog Virtual Machine
VVP - Verilog Virtual Processor VVP - Verilog Virtual Processor
This is the Icarus Verilog runtime that reads in custom code in a This is the Icarus Verilog runtime that reads in custom code in a
form that I call "VVP Assembly". See the vvp/ directory for form that I call "VVP Assembly".
documentation on that.
LPM - Library of Parameterized Modules
LPM (Library of Parameterized Modules) is EIS-IS standard 103-A. It is
a standard library of abstract devices that are designed to be close
enough to the target hardware to be easily translated, yet abstract
enough to support a variety of target technologies without excessive
constraints. Icarus Verilog uses LPM internally to represent idealized
hardware, especially when doing target neutral synthesis.

View File

@ -1,7 +1,6 @@
CADENCE PLI1 MODULES Cadence PLI1 Modules
====================
Copyright 2003 Stephen Williams
With the cadpli module, Icarus Verilog is able to load PLI1 With the cadpli module, Icarus Verilog is able to load PLI1
applications that were compiled and linked to be dynamic loaded by applications that were compiled and linked to be dynamic loaded by
@ -17,7 +16,7 @@ is invoked by the usual -m flag to iverilog or vvp. This module in
turn scans the extended arguments, looking for +cadpli= arguments. The turn scans the extended arguments, looking for +cadpli= arguments. The
latter specify the share object and bootstrap function for running the latter specify the share object and bootstrap function for running the
module. For example, to run the module product.so, that has the module. For example, to run the module product.so, that has the
bootstrap function "my_boot": bootstrap function "my_boot"::
vvp -mcadpli a.out -cadpli=./product.so:my_boot vvp -mcadpli a.out -cadpli=./product.so:my_boot

View File

@ -1,21 +1,24 @@
Developer Quick Start for Icarus Verilog Developer Guide
===============
The documentation for getting, building and installing Icarus Verilog The developer guide is intended to give you a gross structure of the
is kept and maintained at the iverilog documentation wiki at
<http://iverilog.wikia.com>. 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 for instructions on
participating in the Icarus Verilog development process. That
information will not be repeated here.
What this documentation *will* cover is the gross structure of the
Icarus Verilog compiler source. This will help orient you to the Icarus Verilog compiler source. This will help orient you to the
source code itself, so that you can find the global parts where you source code itself, so that you can find the global parts where you
can look for even better detail. 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 Contributor <../getting_started>`
* Compiler Components 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
for instructions on participating in the Icarus Verilog development process.
That information will not be repeated here.
Scroll down to a listing with further readings.
Compiler Components
-------------------
- The compiler driver (driver/) - The compiler driver (driver/)
@ -26,28 +29,29 @@ subcommands to perform the steps of compilation.
- The preprocessor (ivlpp/) - The preprocessor (ivlpp/)
This implements the Verilog pre-processor. In Icarus Verilog, the This implements the Verilog pre-processor. In Icarus Verilog, the
compiler directives `define, `include, `ifdef and etc. are implemented compiler directives \`define, \`include, \`ifdef and etc. are implemented
in an external program. The ivlpp/ directory contains the source for in an external program. The ivlpp/ directory contains the source for
this program. this program.
- The core compiler (this directory) - The core compiler (root directory)
The "ivl" program is the core that does all the Verilog compiler The "ivl" program is the core that does all the Verilog compiler
processing that is not handled elsewhere. This is the main core of the processing that is not handled elsewhere. This is the main core of the
Icarus Verilog compiler, not the runtime. See below for more details Icarus Verilog compiler, not the runtime. See below for more details
on the core itself. on the core itself.
- The loadable code generators (tgt-*/) - The loadable code generators (tgt-\*/)
This core compiler, after it is finished with parsing and semantic This core compiler, after it is finished with parsing and semantic
analysis, uses loadable code generators to emit code for supported analysis, uses loadable code generators to emit code for supported
targets. The tgt-*/ directories contains the source for the target targets. The tgt-\*/ directories contains the source for the target
code generators that are bundled with Icarus Verilog. The tgt-vvp/ code generators that are bundled with Icarus Verilog. The tgt-vvp/
directory in particular contains the code generator for the vvp directory in particular contains the code generator for the vvp
runtime. runtime.
* Runtime Components Runtime Components
------------------
- The vvp runtime (vvp/) - The vvp runtime (vvp/)
@ -75,7 +79,8 @@ PLI-1 code written for Verilog-XL. This directory contains the source
for the module that provides the Cadence PLI interface. for the module that provides the Cadence PLI interface.
* The Core Compiler The Core Compiler
-----------------
The "ivl" binary is the core compiler that does the heavy lifting of The "ivl" binary is the core compiler that does the heavy lifting of
compiling the Verilog source (including libraries) and generating the compiling the Verilog source (including libraries) and generating the
@ -147,3 +152,18 @@ parameters must be intermingled with the elaboration of scopes because
the exact values of parameters may impact the scopes created (imagine the exact values of parameters may impact the scopes created (imagine
generate schemes and instance arrays) and the created scopes in turn generate schemes and instance arrays) and the created scopes in turn
create new parameters that need override and evaluation. create new parameters that need override and evaluation.
Further Reading
---------------
For further information on the individual parts of Icarus Verilog, see this listing:
.. toctree::
:maxdepth: 2
ivl/index
vvp/index
tgt-vvp/tgt-vvp
vpi/index
cadpli/cadpli
misc/index

View File

@ -1,14 +1,19 @@
ATTRIBUTE NAMING CONVENTIONS Icarus Verilog Attributes
=========================
Attribute Naming Conventions
----------------------------
Attributes that are specific to Icarus Verilog, and are intended to be Attributes that are specific to Icarus Verilog, and are intended to be
of use to programmers, start with the prefix "ivl_". of use to programmers, start with the prefix "ivl\_".
Attributes with the "_ivl_" prefix are set aside for internal Attributes with the "_ivl_" prefix are set aside for internal
use. They may be generated internally by the compiler. They need not use. They may be generated internally by the compiler. They need not
be documented here. be documented here.
ATTRIBUTES TO CONTROL SYNTHESIS Attributes To Control Synthesis
-------------------------------
The following is a summary of Verilog attributes that Icarus Verilog The following is a summary of Verilog attributes that Icarus Verilog
understands within Verilog source files to control synthesis understands within Verilog source files to control synthesis
@ -23,7 +28,7 @@ warning.)
* Attributes for "always" and "initial" statements * Attributes for "always" and "initial" statements
(* ivl_combinational *) (\* ivl_combinational \*)
This attribute tells the compiler that the statement models This attribute tells the compiler that the statement models
combinational logic. If the compiler finds that it cannot make combinational logic. If the compiler finds that it cannot make
@ -34,14 +39,14 @@ warning.)
latches or flip-flops where the user intended combinational latches or flip-flops where the user intended combinational
logic. logic.
(* ivl_synthesis_on *) (\* ivl_synthesis_on \*)
This attribute tells the compiler that the marked always statement This attribute tells the compiler that the marked always statement
is synthesizable. The compiler will attempt to synthesize the is synthesizable. The compiler will attempt to synthesize the
code in the marked "always" statement. If it cannot in any way code in the marked "always" statement. If it cannot in any way
synthesize it, then it will report an error. synthesize it, then it will report an error.
(* ivl_synthesis_off *) (\* ivl_synthesis_off \*)
If this value is attached to an "always" statement, then the If this value is attached to an "always" statement, then the
compiler will *not* synthesize the "always" statement. This can be compiler will *not* synthesize the "always" statement. This can be
@ -50,7 +55,7 @@ warning.)
* Attributes for modules * Attributes for modules
(* ivl_synthesis_cell *) (\* ivl_synthesis_cell \*)
If this value is attached to a module during synthesis, that If this value is attached to a module during synthesis, that
module will be considered a target architecture primitive, and module will be considered a target architecture primitive, and
@ -60,7 +65,7 @@ warning.)
* Attributes for signals (wire/reg/integer/tri/etc.) * Attributes for signals (wire/reg/integer/tri/etc.)
(* PAD = "<pad assignment list>" *) (\* PAD = "<pad assignment list>" \*)
If this attribute is attached to a signal that happens to be a If this attribute is attached to a signal that happens to be a
root module port, then targets that support it will use the string root module port, then targets that support it will use the string
@ -73,9 +78,10 @@ warning.)
[ none defined yet ] [ none defined yet ]
MISC Misc
----
(* _ivl_schedule_push *) (\* _ivl_schedule_push \*)
If this attribute is attached to a thread object (always or If this attribute is attached to a thread object (always or
initial statement) then the vvp code generator will generate code initial statement) then the vvp code generator will generate code

View File

@ -0,0 +1,12 @@
IVL - The Core Compiler
=======================
.. toctree::
:maxdepth: 1
netlist
attributes
ivl_target
lpm
t-dll

View File

@ -1,6 +1,6 @@
Loadable Target API (ivl_target.h) Loadable Target API (ivl_target)
================================== ================================
In addition to the standard VPI API, Icarus Verilog supports a non-standard In addition to the standard VPI API, Icarus Verilog supports a non-standard
loadable target module API. This API helps C programmers write modules that loadable target module API. This API helps C programmers write modules that
@ -104,3 +104,28 @@ Installing the Target Module
Finally, the "empty.conf", the "empty-s.conf" and the "empty.tgt" files need Finally, the "empty.conf", the "empty-s.conf" and the "empty.tgt" files need
to be installed. Where they go depends on your system, but in Linux they are to be installed. Where they go depends on your system, but in Linux they are
normally installed in "/usr/lib/ivl". normally installed in "/usr/lib/ivl".
LPM Devices
-----------
All LPM devices support a small set of common LPM functions, as
described in the ivl_target header file. The ivl_lpm_t object has a
type enumerated by ivl_lpm_type_t, and that type is accessible via the
ivl_lpm_type function.
The following are type specific aspects of LPM devices.
* IVL_LPM_UFUNC
This LPM represents a user defined function. It is a way to connect
behavioral code into a structural network. The UFUNC device has a
vector output and a set of inputs. The ivl_lpm_define function returns
the definition as an ivl_scope_t object.
The output vector is accessible through the ivl_lpm_q, and the output
has the width defined by ivl_lpm_width. This similar to most every
other LPM device with outputs.
There are ivl_lpm_size() input ports, each with the width
ivl_lpm_data2_width(). The actual nexus is indexed by ivl_lpm_data2().

View File

@ -1,5 +1,6 @@
WHAT IS LPM What Is LPM
===========
LPM (Library of Parameterized Modules) is EIS-IS standard 103-A. It is LPM (Library of Parameterized Modules) is EIS-IS standard 103-A. It is
a standard library of abstract devices that are designed to be close a standard library of abstract devices that are designed to be close
@ -13,11 +14,12 @@ generates, because the LPM devices are translated into technology
specific devices by the final code generator or target specific specific devices by the final code generator or target specific
optimizers. optimizers.
INTERNAL USES OF LPM Internal Uses Of LPM
--------------------
Internally, Icarus Verilog uses LPM devices to represent the design in Internally, Icarus Verilog uses LPM devices to represent the design in
abstract, especially when synthesizing such functions as addition, abstract, especially when synthesizing such functions as addition,
flip-flops, etc. The ``synth'' functor generates LPM modules when flip-flops, etc. The `synth` functor generates LPM modules when
interpreting procedural constructs. The functor generates the LPM interpreting procedural constructs. The functor generates the LPM
objects needed to replace a behavioral description, and uses objects needed to replace a behavioral description, and uses
attributes to tag the devices with LPM properties. attributes to tag the devices with LPM properties.

View File

@ -1,27 +1,6 @@
/*
* Copyright (c) 1998-1999 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.
*/
Netlist Format
Note that the netlist.h header contains detailed descriptions of how ==============
things work. This is just an overview.
NETLIST FORMAT
The output from the parse and elaboration steps is a "netlist" rooted The output from the parse and elaboration steps is a "netlist" rooted
in a Design object. Parsing translates the design described in the in a Design object. Parsing translates the design described in the
@ -35,7 +14,8 @@ translating it to a (hopefully) better netlist after each step. The
complete netlist is then passed to the code generator, the emit complete netlist is then passed to the code generator, the emit
function, where the final code (in the target format) is produced. function, where the final code (in the target format) is produced.
STRUCTURAL ITEMS: NetNode and NetNet Structural Items: NetNode and NetNet
------------------------------------
Components and wires, memories and registers all at their base are Components and wires, memories and registers all at their base are
either NetNode objects or NetNet objects. Even these classes are either NetNode objects or NetNet objects. Even these classes are
@ -56,7 +36,8 @@ destructors for nets and nodes automatically arrange for pins to be
disconnected when the item is deleted, so that the netlist can be disconnected when the item is deleted, so that the netlist can be
changed during processing. changed during processing.
STRUCTURAL LINKS Structural Links
----------------
The NetNode and NetNet classes contain arrays of Link objects, one The NetNode and NetNet classes contain arrays of Link objects, one
object per pin. Each pin is a single bit. The Link objects link to all object per pin. Each pin is a single bit. The Link objects link to all
@ -88,12 +69,13 @@ Currently, a link has 3 possible direction properties:
three-state.) three-state.)
BEHAVIORAL ITEMS: NetProcTop, NetProc and derived classes Behavioral Items: NetProcTop, NetProc and derived classes
---------------------------------------------------------
Behavioral items are not in general linked to the netlist. Instead, Behavioral items are not in general linked to the netlist. Instead,
they represent elaborated behavioral statements. The type of the object they represent elaborated behavioral statements. The type of the object
implies what the behavior of the statement does. For example, a implies what the behavior of the statement does. For example, a
NetCondit object represents an ``if'' statement, and carries a NetCondit object represents an `if` statement, and carries a
condition expression and up to two alternative sub-statements. condition expression and up to two alternative sub-statements.
At the root of a process is a NetProcTop object. This class carries a At the root of a process is a NetProcTop object. This class carries a
@ -104,7 +86,8 @@ tree is the NetProcTop object. The Design class keeps a list of the
elaborated NetProcTop objects. That list represents the list of elaborated NetProcTop objects. That list represents the list of
processes in the design. processes in the design.
INTERACTION OF BEHAVIORAL AND STRUCTURAL: NetAssign_ Interaction Of Behavioral And Structural: NetAssign\_
-----------------------------------------------------
The behavioral statements in a Verilog design effect the structural The behavioral statements in a Verilog design effect the structural
aspects through assignments to registers. Registers are structural aspects through assignments to registers. Registers are structural
@ -113,26 +96,27 @@ statement through pins. This implies that the l-value of an assignment
is structural. It also implies that the statement itself is is structural. It also implies that the statement itself is
structural, and indeed it is derived from NetNode. structural, and indeed it is derived from NetNode.
The NetAssign_ class is also derived from the NetProc class because The NetAssign\_ class is also derived from the NetProc class because
what it does is brought on by executing the process. By multiple what it does is brought on by executing the process. By multiple
inheritance we have therefore that the assignment is both a NetNode inheritance we have therefore that the assignment is both a NetNode
and a NetProc. The NetAssign_ node has pins that represent the l-value and a NetProc. The NetAssign\_ node has pins that represent the l-value
of the statement, and carries behavioral expressions that represent of the statement, and carries behavioral expressions that represent
the r-value of the assignment. the r-value of the assignment.
MEMORIES Memories
--------
The netlist form includes the NetMemory type to hold the content of a The netlist form includes the NetMemory type to hold the content of a
memory. Instances of this type represent the declaration of a memory, memory. Instances of this type represent the declaration of a memory,
and occur once for each memory. References to the memory are managed and occur once for each memory. References to the memory are managed
by the NetEMemory and NetAssignMem_ classes. by the NetEMemory and NetAssignMem\_ classes.
An instance of the NetEMemory class is created whenever a procedural An instance of the NetEMemory class is created whenever a procedural
expression references a memory element. The operand is the index to expression references a memory element. The operand is the index to
use to address (and read) the memory. use to address (and read) the memory.
An instance of the NetAssignMem_ class is created when there is a An instance of the NetAssignMem\_ class is created when there is a
procedural assignment to the memory. The NetAssignMem_ object procedural assignment to the memory. The NetAssignMem\_ object
represents the l-value reference (a write) to the memory. As with the represents the l-value reference (a write) to the memory. As with the
NetEMemory class, this is a procedural reference only. NetEMemory class, this is a procedural reference only.
@ -143,13 +127,14 @@ unconnected for now, because memories cannot appear is l-values of
continuous assignments. However, the synthesis functor may connect continuous assignments. However, the synthesis functor may connect
signals to the write control lines to get a fully operational RAM. signals to the write control lines to get a fully operational RAM.
By the time elaboration completes, there may be many NetAssignMem_, By the time elaboration completes, there may be many NetAssignMem\_,
NetEMemory and NetRamDq objects referencing the same NetMemory NetEMemory and NetRamDq objects referencing the same NetMemory
object. Each represents a port into the memory. It is up to the object. Each represents a port into the memory. It is up to the
synthesis steps (and the target code) to figure out what to do with synthesis steps (and the target code) to figure out what to do with
these ports. these ports.
EXPRESSIONS Expressions
-----------
Expressions are represented as a tree of NetExpr nodes. The NetExpr Expressions are represented as a tree of NetExpr nodes. The NetExpr
base class contains the core methods that represent an expression base class contains the core methods that represent an expression
@ -168,7 +153,8 @@ However, typical expressions the behavioral description are
represented as a tree of NetExpr nodes. The derived class of the node represented as a tree of NetExpr nodes. The derived class of the node
encodes what kind of operator the node represents. encodes what kind of operator the node represents.
EXPRESSION BIT WIDTH Expression Bit Width
--------------------
The expression (represented by the NetExpr class) has a bit width that The expression (represented by the NetExpr class) has a bit width that
it either explicitly specified, or implied by context or contents. it either explicitly specified, or implied by context or contents.
@ -200,14 +186,17 @@ determined and please adapt. If the expression cannot reasonably
adapt, it will return false. Otherwise, it will adjust bit widths and adapt, it will return false. Otherwise, it will adjust bit widths and
return true. return true.
XXXX I do not yet properly deal with cases where elaboration knows for ::
XXXX certain that the bit width does not matter. In this case, I
XXXX really should tell the expression node about it so that it can
XXXX pick a practical (and optimal) width.
INTERACTION OF EXPRESSIONS AND STRUCTURE: NetESignal I do not yet properly deal with cases where elaboration knows for
certain that the bit width does not matter. In this case, I
really should tell the expression node about it so that it can
pick a practical (and optimal) width.
The NetAssign_ class described above is the means for processes to Interaction Of Expressions And Structure: NetESignal
----------------------------------------------------
The NetAssign\_ class described above is the means for processes to
manipulate the net, but values are read from the net by NetESignal manipulate the net, but values are read from the net by NetESignal
objects. These objects are class NetExpr because they can appear in objects. These objects are class NetExpr because they can appear in
expressions (and have width). They are not NetNode object, but hold expressions (and have width). They are not NetNode object, but hold
@ -215,7 +204,8 @@ pointers to a NetNet object, which is used to retrieve values with the
expression is evaluated. expression is evaluated.
HIERARCHY IN NETLISTS Hierarchy In Netlists
---------------------
The obvious hierarchical structure of Verilog is the module. The The obvious hierarchical structure of Verilog is the module. The
Verilog program may contain any number of instantiations of modules in Verilog program may contain any number of instantiations of modules in
@ -236,7 +226,8 @@ boundaries. This makes coding of netlist transform functions such as
constant propagation more effective and easier to write. constant propagation more effective and easier to write.
SCOPE REPRESENTATION IN NETLISTS Scope Representation In Netlists
--------------------------------
In spite of the literal flattening of the design, scope information is In spite of the literal flattening of the design, scope information is
preserved in the netlist, with the NetScope class. The Design class preserved in the netlist, with the NetScope class. The Design class
@ -258,7 +249,8 @@ scope. Overrides are managed during the scan, and once the scan is
complete, defparam overrides are applied. complete, defparam overrides are applied.
TASKS IN NETLISTS Tasks In Netlists
-----------------
The flattening of the design does not include tasks and named The flattening of the design does not include tasks and named
begin-end blocks. Tasks are behavioral hierarchy (whereas modules are begin-end blocks. Tasks are behavioral hierarchy (whereas modules are
@ -268,7 +260,8 @@ recurse. (The elaboration process does reserve the right to flatten
some task calls. C++ programmers recognize this as inlining a task.) some task calls. C++ programmers recognize this as inlining a task.)
TIME SCALE IN NETLISTS Time Scale In Netlists
----------------------
The Design class and the NetScope classes carry time scale and The Design class and the NetScope classes carry time scale and
resolution information of the elaborated design. There is a global resolution information of the elaborated design. There is a global

View File

@ -1,5 +1,6 @@
LOADABLE TARGETS Loadable Targets
================
Icarus Verilog supports dynamically loading code generator modules to Icarus Verilog supports dynamically loading code generator modules to
perform the back-end processing of the completed design. The user perform the back-end processing of the completed design. The user
@ -12,24 +13,28 @@ compiler calls to pass the design to it, and the module in turn uses a
collection of functions in the core (the API) to access details of the collection of functions in the core (the API) to access details of the
design. design.
LOADING TARGET MODULES Loading Target Modules
----------------------
The target module loader is invoked with the ivl flag "-tdll". That The target module loader is invoked with the ivl flag "-tdll". That
is, the DLL loader is a linked in target type. The name of the target is, the DLL loader is a linked in target type. The name of the target
module to load is then specified with the DLL flag, i.e. "-fDLL=<path>". module to load is then specified with the DLL flag, i.e. "-fDLL=<path>".
COMPILING TARGET MODULES Compiling Target Modules
------------------------
<write me> <write me>
LOADABLE TARGET MODULE API Loadable Target Module Api
--------------------------
The target module API is defined in the ivl_target.h header file. This The target module API is defined in the ivl_target.h header file. This
declares all the type and functions that a loadable module needs to declares all the type and functions that a loadable module needs to
access the design. access the design.
ABOUT SPECIFIC EXPRESSION TYPES About Specific Expression Types
-------------------------------
In this section find notes about the various kinds of expression In this section find notes about the various kinds of expression
nodes. The notes here are in addition to the more general nodes. The notes here are in addition to the more general

View File

@ -1,9 +1,6 @@
NOTE: THE CONTENTS OF THIS FILE ARE BEING MOVED TO THE DOCUMENTATION IEEE1364 Notes
WIKI AT http://iverilog.wikia.com. PLEASE ADD NEW ENTRIES THERE. ==============
Icarus Verilog vs. IEEE1364
Copyright 2000 Stephen Williams
The IEEE1364 standard is the bible that defines the correctness of the The IEEE1364 standard is the bible that defines the correctness of the
Icarus Verilog implementation and behavior of the compiled Icarus Verilog implementation and behavior of the compiled
@ -19,7 +16,8 @@ and common to write programs that produce different results when run
by different Verilog implementations. by different Verilog implementations.
STANDARDIZATION ISSUES Standardization Issues
----------------------
These are some issues where the IEEE1364 left unclear, unspecified or These are some issues where the IEEE1364 left unclear, unspecified or
simply wrong. I'll try to be precise as I can, and reference the simply wrong. I'll try to be precise as I can, and reference the
@ -29,19 +27,19 @@ affect the language.
* OBJECTS CAN BE DECLARED ANYWHERE IN THE MODULE * OBJECTS CAN BE DECLARED ANYWHERE IN THE MODULE
Consider this module: Consider this module::
module sample1; module sample1;
initial foo = 1; initial foo = 1;
reg foo; reg foo;
wire tmp = bar; wire tmp = bar;
initial #1 $display("foo = %b, bar = %b", foo, tmp); initial #1 $display("foo = %b, bar = %b", foo, tmp);
endmodule endmodule
Notice that the ``reg foo;'' declaration is placed after the first Notice that the `reg foo;` declaration is placed after the first
initial statement. It turns out that this is a perfectly legal module initial statement. It turns out that this is a perfectly legal module
according to the -1995 and -2000 versions of the standard. The according to the -1995 and -2000 versions of the standard. The
statement ``reg foo;'' is a module_item_declaration which is in turn a statement `reg foo;` is a module_item_declaration which is in turn a
module_item. The BNF in the appendix of IEEE1364-1995 treats all module_item. The BNF in the appendix of IEEE1364-1995 treats all
module_item statements equally, so no order is imposed. module_item statements equally, so no order is imposed.
@ -53,12 +51,12 @@ textually before they are referenced." Such statements simply do not
exist. (Personally, I think it is fine that they don't.) exist. (Personally, I think it is fine that they don't.)
The closest is the rules for implicit declarations of variables that The closest is the rules for implicit declarations of variables that
are otherwise undeclared. In the above example, ``bar'' is implicitly are otherwise undeclared. In the above example, `bar` is implicitly
declared and is therefore a wire. However, although ``initial foo = 1;'' declared and is therefore a wire. However, although `initial foo = 1;`
is written before foo is declared, foo *is* declared within the is written before foo is declared, foo *is* declared within the
module, and declared legally by the BNF of the standard. module, and declared legally by the BNF of the standard.
Here is another example: Here is another example::
module sample2; module sample2;
initial x.foo = 1; initial x.foo = 1;
@ -80,7 +78,7 @@ Icarus Verilog interprets both of these examples according to "The
Standard As I Understand It." However, commercial tools in general Standard As I Understand It." However, commercial tools in general
break down with these programs. In particular, the first example break down with these programs. In particular, the first example
may generate different errors depending on the tool. The most common may generate different errors depending on the tool. The most common
error is to claim that ``foo'' is declared twice, once (implicitly) as error is to claim that `foo` is declared twice, once (implicitly) as
a wire and once as a reg. a wire and once as a reg.
So the question now becomes, "Is the standard broken, or are the tools So the question now becomes, "Is the standard broken, or are the tools
@ -107,7 +105,7 @@ ordering, by requiring that modules that are used be first defined.
* TASK AND FUNCTION PARAMETERS CANNOT HAVE EXPLICIT TYPES * TASK AND FUNCTION PARAMETERS CANNOT HAVE EXPLICIT TYPES
Consider a function negate that wants to take a signed integer value Consider a function negate that wants to take a signed integer value
and return its negative: and return its negative::
function integer negate; function integer negate;
input [15:0] val; input [15:0] val;
@ -123,7 +121,7 @@ the bit pattern of a 16bit number, but that is not the point. What's
needed is clarification on whether an input can be declared in the needed is clarification on whether an input can be declared in the
port declaration as well as in the contained block declaration. port declaration as well as in the contained block declaration.
As I understand the situation, this should be allowed: As I understand the situation, this should be allowed::
function integer negate; function integer negate;
input [15:0] val; input [15:0] val;
@ -152,10 +150,10 @@ commercial tools seem to work similarly.
* ROUNDING OF TIME * ROUNDING OF TIME
When the `timescale directive is present, the compiler is supposed to When the \`timescale directive is present, the compiler is supposed to
round fractional times (after scaling) to the nearest integer. The round fractional times (after scaling) to the nearest integer. The
confusing bit here is that it is apparently conventional that if the confusing bit here is that it is apparently conventional that if the
`timescale directive is *not* present, times are rounded towards zero \`timescale directive is *not* present, times are rounded towards zero
always. always.
@ -173,12 +171,12 @@ take it that x is allowed, as that is what Verilog-XL does.
* REPEAT LOOPS vs. REPEAT EVENT CONTROL * REPEAT LOOPS vs. REPEAT EVENT CONTROL
There seems to be ambiguity in how code like this should be parsed: There seems to be ambiguity in how code like this should be parsed::
repeat (5) @(posedge clk) <statement>; repeat (5) @(posedge clk) <statement>;
There are two valid interpretations of this code, from the There are two valid interpretations of this code, from the
IEEE1364-1995 standard. One looks like this: IEEE1364-1995 standard. One looks like this::
procedural_timing_control_statement ::= procedural_timing_control_statement ::=
delay_or_event_control statement_or_null delay_or_event_control statement_or_null
@ -189,7 +187,7 @@ IEEE1364-1995 standard. One looks like this:
If this interpretation is used, then the statement <statement> should If this interpretation is used, then the statement <statement> should
be executed after the 5th posedge of clk. However, there is also this be executed after the 5th posedge of clk. However, there is also this
interpretation: interpretation::
loop_statement ::= loop_statement ::=
repeat ( expression ) statement repeat ( expression ) statement
@ -218,7 +216,7 @@ compiler may just as easily choose another width limit, for example
However, it is not *required* that an implementation truncate at 32 However, it is not *required* that an implementation truncate at 32
bits, and in fact Icarus Verilog does not truncate at all. It will bits, and in fact Icarus Verilog does not truncate at all. It will
make the unsized constant as big as it needs to be to hold the value make the unsized constant as big as it needs to be to hold the value
accurately. This is especially useful in situations like this; accurately. This is especially useful in situations like this::
reg [width-1:0] foo = 17179869183; reg [width-1:0] foo = 17179869183;
@ -237,7 +235,7 @@ truncation point.
* UNSIZED EXPRESSIONS AS PARAMETERS TO CONCATENATION {} * UNSIZED EXPRESSIONS AS PARAMETERS TO CONCATENATION {}
The Verilog standard clearly states in 4.1.14: The Verilog standard clearly states in 4.1.14::
"Unsized constant numbers shall not be allowed in "Unsized constant numbers shall not be allowed in
concatenations. This is because the size of each concatenations. This is because the size of each
@ -257,7 +255,7 @@ simple unsized constant is accepted there, even if all the operands of
all the operators that make up the expression are unsized integers. all the operators that make up the expression are unsized integers.
This is a semantic problem. Icarus Verilog doesn't limit the size of This is a semantic problem. Icarus Verilog doesn't limit the size of
integer constants. This is valid as stated in 2.5.1 Note 3: integer constants. This is valid as stated in 2.5.1 Note 3::
"The number of bits that make up an unsized number "The number of bits that make up an unsized number
(which is a simple decimal number or a number without (which is a simple decimal number or a number without
@ -268,6 +266,8 @@ Icarus Verilog will hold any integer constant, so the size will be as
large as it needs to be, whether that is 64bits, 128bits, or large as it needs to be, whether that is 64bits, 128bits, or
more. With this in mind, what is the value of these expressions? more. With this in mind, what is the value of these expressions?
::
{'h1_00_00_00_00} {'h1_00_00_00_00}
{'h1 << 32} {'h1 << 32}
{'h0_00_00_00_01 << 32} {'h0_00_00_00_01 << 32}
@ -301,7 +301,7 @@ generate appropriate error messages.
* MODULE INSTANCE WITH WRONG SIZE PORT LIST * MODULE INSTANCE WITH WRONG SIZE PORT LIST
A module declaration like this declares a module that takes three ports: A module declaration like this declares a module that takes three ports::
module three (a, b, c); module three (a, b, c);
input a, b, c; input a, b, c;
@ -309,7 +309,7 @@ A module declaration like this declares a module that takes three ports:
endmodule endmodule
This is fine and obvious. It is also clear from the standard that This is fine and obvious. It is also clear from the standard that
these are legal instantiations of this module: these are legal instantiations of this module::
three u1 (x,y,z); three u1 (x,y,z);
three u2 ( ,y, ); three u2 ( ,y, );
@ -320,7 +320,7 @@ In some of the above examples, there are unconnected ports. In the
case of u4, the pass by name connects only port b, and leaves a and c case of u4, the pass by name connects only port b, and leaves a and c
unconnected. u2 and u4 are the same thing, in fact, but using unconnected. u2 and u4 are the same thing, in fact, but using
positional or by-name syntax. The next example is a little less positional or by-name syntax. The next example is a little less
obvious: obvious::
three u4 (); three u4 ();
@ -331,7 +331,7 @@ positional list, then the wrong number of ports is given, but if it is
an empty by-name list, it is an obviously valid instantiation. So it an empty by-name list, it is an obviously valid instantiation. So it
is fine to accept this case as valid. is fine to accept this case as valid.
These are more doubtful: These are more doubtful::
three u5(x,y); three u5(x,y);
three u6(,); three u6(,);
@ -351,7 +351,7 @@ other.
* UNKNOWN VALUES IN L-VALUE BIT SELECTS * UNKNOWN VALUES IN L-VALUE BIT SELECTS
Consider this example: Consider this example::
reg [7:0] vec; reg [7:0] vec;
wire [4:0] idx = <expr>; wire [4:0] idx = <expr>;
@ -375,7 +375,7 @@ assignment will have no effect.
The interaction between blocking assignments in procedural code and The interaction between blocking assignments in procedural code and
logic gates in gate-level code and expressions is poorly defined in logic gates in gate-level code and expressions is poorly defined in
Verilog. Consider this example: Verilog. Consider this example::
reg a; reg a;
reg b; reg b;
@ -438,7 +438,7 @@ bit and part selects.
* EDGES OF VECTORS * EDGES OF VECTORS
Consider this example: Consider this example::
reg [ 5:0] clock; reg [ 5:0] clock;
always @(posedge clock) [do stuff] always @(posedge clock) [do stuff]
@ -446,7 +446,7 @@ Consider this example:
The IEEE1364 standard clearly states that the @(posedge clock) looks The IEEE1364 standard clearly states that the @(posedge clock) looks
only at the bit clock[0] (the least significant bit) to search for only at the bit clock[0] (the least significant bit) to search for
edges. It has been pointed out by some that Verilog XL instead edges. It has been pointed out by some that Verilog XL instead
implements it as "@(posedge |clock)": it looks for a rise in the implements it as `@(posedge |clock)`: it looks for a rise in the
reduction or of the vector. Cadence Design Systems technical support reduction or of the vector. Cadence Design Systems technical support
has been rumored to claim that the IEEE1364 specification is wrong, has been rumored to claim that the IEEE1364 specification is wrong,
but NC-Verilog behaves according to the specification, and thus but NC-Verilog behaves according to the specification, and thus
@ -462,7 +462,7 @@ matter.
The IEEE1364 standard clearly states that in VCD files, the $dumpoff The IEEE1364 standard clearly states that in VCD files, the $dumpoff
section checkpoints all the dumped variables as X values. For reg and section checkpoints all the dumped variables as X values. For reg and
wire bits/vectors, this obviously means 'bx values. Icarus Verilog wire bits/vectors, this obviously means 'bx values. Icarus Verilog
does this, for example: does this, for example::
$dumpoff $dumpoff
x! x!
@ -475,7 +475,7 @@ section of the VCD file. Verilog-XL dumps "r0 !" to set the real
variables to the dead-zone value of 0.0, whereas other tools, such as variables to the dead-zone value of 0.0, whereas other tools, such as
ModelTech, ignore real variables in this section. ModelTech, ignore real variables in this section.
For example (from XL): For example (from XL)::
$dumpoff $dumpoff
r0 ! r0 !
@ -485,7 +485,7 @@ For example (from XL):
Icarus Verilog dumps NaN values for real variables in the Icarus Verilog dumps NaN values for real variables in the
$dumpoff-$end section of the VCD file. The NaN value is the IEEE754 $dumpoff-$end section of the VCD file. The NaN value is the IEEE754
equivalent of an unknown value, and so better reflects the unknown equivalent of an unknown value, and so better reflects the unknown
(during the dead zone) status of the variable, like this: (during the dead zone) status of the variable, like this::
$dumpoff $dumpoff
rNaN ! rNaN !

View File

@ -0,0 +1,10 @@
Miscellaneous
=============
.. toctree::
:maxdepth: 1
ieee1364-notes
swift
xilinx-hint

View File

@ -1,7 +1,8 @@
SWIFT MODEL SUPPORT FOR Icarus Verilog (PRELIMINARY) Swift Model Support (Preliminary)
=================================
Copyright 2003 Stephen Williams Copyright 2003-2024 Stephen Williams
NOTE: SWIFT support does not work yet, these are provisional NOTE: SWIFT support does not work yet, these are provisional
instructions, intended to show what's supposed to happen when I get instructions, intended to show what's supposed to happen when I get
@ -24,7 +25,7 @@ When compiling your Verilog design to include a SWIFT model, you need
to include wrappers for the model you intend to use. You may choose to to include wrappers for the model you intend to use. You may choose to
use ncverilog or verilogxl compatible wrappers, they work the use ncverilog or verilogxl compatible wrappers, they work the
same. Locate your smartmodel directory, and include it in your command same. Locate your smartmodel directory, and include it in your command
file like so: file like so::
+libdir+.../smartmodel/sol/wrappers/verilogxl +libdir+.../smartmodel/sol/wrappers/verilogxl
@ -42,11 +43,11 @@ support for your model.
* Execution * Execution
After your simulation is compiled, run the simulation with the vvp After your simulation is compiled, run the simulation with the vvp
command, like this: command, like this::
% vvp -mcadpli a.out -cadpli=$LMC_HOME/lib/x86_linux.lib/swiftpli.so:swift_boot % vvp -mcadpli a.out -cadpli=$LMC_HOME/lib/x86_linux.lib/swiftpli.so:swift_boot
What this command line means is: What this command line means is::
-mcadpli -mcadpli
Include the cadpli compatibility module Include the cadpli compatibility module

View File

@ -0,0 +1,113 @@
Xilinx Hint
===========
For those of you who wish to use Icarus Verilog, in combination with
the Xilinx back end (Foundation or Alliance), it can be done. I have
run some admittedly simple (2300 equivalent gates) designs through this
setup, targeting a Spartan XCS10.
Verilog:
--------
Older versions of Icarus Verilog (like 19990814) couldn't synthesize
logic buried in procedural (flip-flop) assignment. Newer versions
(like 20000120) don't have this limitation.
Procedural assignments have to be given one at a time, to be
"found" by xnfsyn. Say
::
always @ (posedge Clk) Y = newY;
always @ (posedge Clk) Z = newZ;
rather than
::
always @ (posedge Clk) begin
Y = newY;
Z = newZ;
end
Steve's xnf.txt covers most buffer and pin constructs, but I had reason
to use a global clock net not connected to an input pin. The standard
Verilog for a buffer, combined with a declaration to turn that into a
BUFG, is::
buf BUFG( your_output_here, your_input_here );
$attribute(BUFG,"XNF-LCA","BUFG:O,I")
I use post-processing on my .xnf files to add "FAST" attributes to
output pins.
Running ivl:
------------
The -F switches are important. The following order seems to robustly
generate valid XNF files, and is used by "verilog -X"::
-Fsynth -Fnodangle -Fxnfio
Generating .pcf files:
----------------------
The ngdbuild step seems to lose pin placement information that ivl
puts in the XNF file. Use xnf2pcf to extract this information to
a .pcf file, which the Xilinx place-and-route software _will_ pay
attention to. Steve says he now makes that information available
in an NCF file, with -fncf=<path>, but I haven't tested that.
Running the Xilinx back end:
You can presumably use the GUI, but that doesn't fit in Makefiles :-).
Here is the command sequence in pseudo-shell-script::
ngdbuild -p $part $1.xnf $1.ngd
map -p $part -o map.ncd $1.ngd
xnf2pcf <$1.xnf >$1.pcf # see above
par -w -ol 2 -d 0 map.ncd $1.ncd $1.pcf
bitgen_flags = -g ConfigRate:SLOW -g TdoPin:PULLNONE -g DonePin:PULLUP \
-g CRC:enable -g StartUpClk:CCLK -g SyncToDone:no \
-g DoneActive:C1 -g OutputsActive:C3 -g GSRInactive:C4 \
-g ReadClk:CCLK -g ReadCapture:enable -g ReadAbort:disable
bitgen $1.ncd -l -w $bitgen_flags
The Xilinx software has diarrhea of the temp files (14, not including
.xnf, .pcf, .ngd, .ncd, and .bit), so this sequence is best done in a
dedicated directory. Note in particular that map.ncd is a generic name.
I had reason to run this remotely (and transparently within a Makefile)
via ssh. I use the gmake rule::
%.bit : %.xnf
ssh -x -a -o 'BatchMode yes' ${ALLIANCE_HOST} \
remote_alliance ${REMOTE_DIR} $(basename $@) 2>&1 < $<
scp ${ALLIANCE_HOST}:${REMOTE_DIR}/$@ .
and the remote_alliance script (on ${ALLIANCE_HOST})::
/bin/csh
cd $1
cat >! $2.xnf
xnf2pcf <$2.xnf >! $2.pcf
./backend $2
There is now a "Xilinx on Linux HOWTO" at http://www.polybus.com/xilinx_on_linux.html
I haven't tried this yet, it looks interesting.
Downloading:
------------
I use the XESS (http://www.xess.com/) XSP-10 development board, which
uses the PC parallel (printer) port for downloading and interaction
with the host. They made an old version of their download program
public domain, posted it at http://www.xess.com/FPGA/xstools.zip ,
and now there is a Linux port at ftp://ftp.microux.com/pub/pilotscope/xstools.tar.gz .
The above hints are based on my experience with Foundation 1.5 on NT
(gack) and Alliance 2.1i on Solaris. Your mileage may vary. Good luck!
- Larry Doolittle <LRDoolittle@lbl.gov> August 19, 1999
updated February 1, 2000

View File

@ -1,7 +1,9 @@
THE VVP TARGET The VVP Target
==============
SYMBOL NAME CONVENTIONS Symbol Name Conventions
-----------------------
There are some naming conventions that the vvp target uses for There are some naming conventions that the vvp target uses for
generating symbol names. generating symbol names.
@ -18,7 +20,8 @@ this case the symbol is attached to a functor that is the output of
the logic device. the logic device.
GENERAL FUNCTOR WEB STRUCTURE General Functor Web Structure
-----------------------------
The net of gates, signals and resolvers is formed from the input The net of gates, signals and resolvers is formed from the input
design. The basic structure is wrapped around the nexus, which is design. The basic structure is wrapped around the nexus, which is

View File

@ -0,0 +1,9 @@
VPI in Icarus Verilog
=====================
.. toctree::
:maxdepth: 1
vpi
va_math

View File

@ -1,17 +1,14 @@
The following is from the README.va_math that was included with the Verilog-A math library
initial contribution of the va_math module. I've removed the parts ======================
that are obviously not applicable, i.e. how to compile the library, to
this bundled version of the library.
--------
License. License.
-------- --------
Verilog-A math library built for Icarus Verilog Verilog-A math library built for Icarus Verilog
http://www.icarus.com/eda/verilog/ https://github.com/steveicarus/iverilog/
Copyright (C) 2007-2010 Cary R. (cygcary@yahoo.com) Copyright (C) 2007-2024 Cary R. (cygcary@yahoo.com)
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -27,15 +24,13 @@ License.
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
------------------------------------------
Standard Verilog-A Mathematical Functions. Standard Verilog-A Mathematical Functions.
------------------------------------------ ------------------------------------------
The va_math VPI module implements all the standard math functions provided The va_math VPI module implements all the standard math functions provided
by Verilog-A as Verilog-D system functions. The names are the same except by Verilog-A as Verilog-D system functions. The names are the same except
like all Verilog-D system functions the name must be prefixed with a '$'. like all Verilog-D system functions the name must be prefixed with a '$'.
For reference the functions are: For reference the functions are::
$ln(x) -- Natural logarithm $ln(x) -- Natural logarithm
$log10(x) -- Decimal logarithm $log10(x) -- Decimal logarithm
@ -68,8 +63,6 @@ any other limits placed on the arguments. Most libraries return +-Inf or
NaN for results that cannot be represented with real numbers. All functions NaN for results that cannot be represented with real numbers. All functions
return a real result. return a real result.
------------------------------------------
Standard Verilog-A Mathematical Constants. Standard Verilog-A Mathematical Constants.
------------------------------------------ ------------------------------------------
@ -77,7 +70,7 @@ The Verilog-A mathematical constants can be accessed by including the
"constants.vams" header file. It is located in the standard include "constants.vams" header file. It is located in the standard include
directory. Recent version of Icarus Verilog (0.9.devel) automatically directory. Recent version of Icarus Verilog (0.9.devel) automatically
add this directory to the end of the list used to find include files. add this directory to the end of the list used to find include files.
For reference the mathematical constants are: For reference the mathematical constants are::
`M_PI -- Pi `M_PI -- Pi
`M_TWO_PI -- 2*Pi `M_TWO_PI -- 2*Pi
@ -94,22 +87,14 @@ For reference the mathematical constants are:
`M_SQRT2 -- sqrt(2) `M_SQRT2 -- sqrt(2)
`M_SQRT1_2 -- 1/sqrt(2) `M_SQRT1_2 -- 1/sqrt(2)
------------------
Using the Library. Using the Library.
------------------ ------------------
Just add "-m va_math" to your iverilog command line/command file and Just add "-m va_math" to your iverilog command line/command file and
`include the "constants.vams" file as needed. \`include the "constants.vams" file as needed.
------
Thanks Thanks
------ ------
I would like to thank Larry Doolittle for his suggestions and I would like to thank Larry Doolittle for his suggestions and
Stephen Williams for developing Icarus Verilog. Stephen Williams for developing Icarus Verilog.
--------
The End.
--------

View File

@ -1,5 +1,6 @@
HOW IT WORKS VPI Modules in Icarus Verilog
================================
The VPI interface for Icarus Verilog works by creating from a The VPI interface for Icarus Verilog works by creating from a
collection of PLI applications a single vpi module. The vpi module collection of PLI applications a single vpi module. The vpi module
@ -28,16 +29,18 @@ include implementations of the standard system tasks/functions. The
additional special module names "vhdl_sys.vpi" and "vhdl_textio.vpi" additional special module names "vhdl_sys.vpi" and "vhdl_textio.vpi"
include implementations of private functions used to support VHDL. include implementations of private functions used to support VHDL.
COMPILING A VPI MODULE Compiling A VPI Module
----------------------
See the iverilog-vpi documentation. See the documentation under: :doc:`Using VPI <../../../usage/vpi>`
TRACING VPI USE Tracing VPI Use
---------------
The vvp command includes the ability to trace VPI calls. This is The vvp command includes the ability to trace VPI calls. This is
useful if you are trying to debug a problem with your code. To useful if you are trying to debug a problem with your code. To
activate tracing simply set the VPI_TRACE environment variable, with activate tracing simply set the VPI_TRACE environment variable, with
the path to a file where trace text gets written. For example: the path to a file where trace text gets written. For example::
setenv VPI_TRACE /tmp/foo.txt setenv VPI_TRACE /tmp/foo.txt

View File

@ -1,5 +1,6 @@
DEBUG AIDS FOR VVP Debug Aids For VVP
==================
Debugging vvp can be fiendishly difficult, so there are some built in Debugging vvp can be fiendishly difficult, so there are some built in
debugging aids. These are enabled by setting the environment variable debugging aids. These are enabled by setting the environment variable
@ -9,7 +10,7 @@ tools can be enabled as described below.
* .resolv * .resolv
The .resolv can print debug information along with a label by The .resolv can print debug information along with a label by
specifying the debug output label on the .resolv line: specifying the debug output label on the .resolv line::
.resolv tri$<label> .resolv tri$<label>

View File

@ -0,0 +1,13 @@
VVP - Verilog Virtual Processor
===============================
.. toctree::
:maxdepth: 1
vvp
opcodes
vpi
vthread
debug

View File

@ -1,11 +1,5 @@
/* Executable Instruction Opcodes
* Copyright (c) 2001-2021 Stephen Williams (steve@icarus.com) ==============================
*
*/
EXECUTABLE INSTRUCTION OPCODES
Instruction opcodes all start with a % character and have 0 or more Instruction opcodes all start with a % character and have 0 or more
operands. In no case are there more than 3 operands. This chapter operands. In no case are there more than 3 operands. This chapter
@ -32,7 +26,8 @@ experience of implementing it for strings, I'll want to change other
types around to using this method as well. Keep this in mind whenever types around to using this method as well. Keep this in mind whenever
considering adding new instructions to vvp. considering adding new instructions to vvp.
FLAGS Flags
-----
There are up to 16 bits in each thread that are available for There are up to 16 bits in each thread that are available for
flags. These are used as destinations for operations that return flags. These are used as destinations for operations that return
@ -302,7 +297,7 @@ The results of the comparison go into flags 4, 5, 6 and 7:
The eeq bit is set to 1 if all the bits in the vectors are exactly the The eeq bit is set to 1 if all the bits in the vectors are exactly the
same, or 0 otherwise. The eq bit is true if the values are logically same, or 0 otherwise. The eq bit is true if the values are logically
the same. That is, x and z are considered equal. In other words the eq the same. That is, x and z are considered equal. In other words the eq
bit is the same as ``=='' and the eeq bit ``===''. bit is the same as `==` and the eeq bit `===`.
The lt bit is 1 if the left vector is less than the right vector, or 0 The lt bit is 1 if the left vector is less than the right vector, or 0
if greater than or equal to the right vector. It is the equivalent of if greater than or equal to the right vector. It is the equivalent of
@ -534,7 +529,9 @@ an arbitrary value to the event to trigger the event.
This command emits the provided file and line information along with This command emits the provided file and line information along with
the description when it is executed. The output is sent to stderr and the description when it is executed. The output is sent to stderr and
the format of the output is: the format of the output is:
<file>:<line>: <description> <file>:<line>: <description>
<file> is the unsigned numeric file index. <file> is the unsigned numeric file index.
<line> is the unsigned line number. <line> is the unsigned line number.
<description> is a string, if string is 0 then the following default <description> is a string, if string is 0 then the following default
@ -815,6 +812,10 @@ result is pushed back on the vec4 stack.
This opcode multiplies two real words together. This opcode multiplies two real words together.
* %neg/wr
This opcode negates the real value on top of the real stack.
* %nand * %nand
Perform the bitwise NAND of two vec4 vectors, and push the result. Each Perform the bitwise NAND of two vec4 vectors, and push the result. Each
@ -1338,22 +1339,23 @@ table for the xor is:
1 xor 1 --> 0 1 xor 1 --> 0
otherwise x otherwise x
::
/* /*
* Copyright (c) 2001-2017 Stephen Williams (steve@icarus.com) * Copyright (c) 2001-2024 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software * General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) * Foundation; either version 2 of the License, or (at your option)
* any later version. * any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */

View File

@ -1,10 +1,6 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
*/
VPI Within VVP
VPI WITHIN VVP ==============
System tasks and functions in Verilog are implemented in Icarus System tasks and functions in Verilog are implemented in Icarus
Verilog by C routines written with VPI. This implies that the vvp Verilog by C routines written with VPI. This implies that the vvp
@ -19,7 +15,8 @@ vvp only implements the ones it needs. The VPI web is added into the
design using special pseudo-ops that create the needed objects. design using special pseudo-ops that create the needed objects.
LOADING VPI MODULES Loading VPI Modules
-------------------
The vvp runtime loads VPI modules at runtime before the parser reads The vvp runtime loads VPI modules at runtime before the parser reads
in the source files. This gives the modules a chance to register tasks in the source files. This gives the modules a chance to register tasks
@ -38,7 +35,8 @@ the system tasks and functions. The %vpi_call instruction, once compiled,
carries the vpiHandle of the system task. carries the vpiHandle of the system task.
SYSTEM TASK CALLS System Task Calls
-----------------
A system task call invokes a VPI routine, and makes available to that A system task call invokes a VPI routine, and makes available to that
routine the arguments to the system task. The called routine gets routine the arguments to the system task. The called routine gets
@ -61,7 +59,8 @@ instruction then only needs to be a %vpi_call with the single parameter
that is the vpiHandle for the call. that is the vpiHandle for the call.
SYSTEM FUNCTION CALLS System Function Calls
---------------------
System function calls are similar to system tasks. The only System function calls are similar to system tasks. The only
differences are that all the arguments are input only, and there is a differences are that all the arguments are input only, and there is a
@ -75,7 +74,8 @@ writing a wrapper thread that calls the function when inputs change,
and that writes the output into the containing expression. and that writes the output into the containing expression.
SYSTEM TASK/FUNCTION ARGUMENTS System Task/Function Arguments
------------------------------
The arguments to each system task or call are not stored in the The arguments to each system task or call are not stored in the
instruction op-code, but in the vpiSysTfCall object that the compiler instruction op-code, but in the vpiSysTfCall object that the compiler
@ -91,7 +91,8 @@ all this is done, an array of vpiHandles is passed to code to create a
vpiSysTfCall object that has all that is needed to make the call. vpiSysTfCall object that has all that is needed to make the call.
SCOPES Scopes
------
VPI can access scopes as objects of type vpiScope. Scopes have names VPI can access scopes as objects of type vpiScope. Scopes have names
and can also contain other sub-scopes, all of which the VPI function and can also contain other sub-scopes, all of which the VPI function
@ -99,7 +100,7 @@ can access by the vpiInternalScope reference. Therefore, the run-time
needs to form a tree of scopes into which other scoped VPI objects are needs to form a tree of scopes into which other scoped VPI objects are
placed. placed.
A scope is created with a .scope directive, like so: A scope is created with a .scope directive, like so::
<label> .scope "name" [, <parent>]; <label> .scope "name" [, <parent>];
.timescale <units>; .timescale <units>;
@ -122,7 +123,7 @@ Objects that place themselves in a scope place themselves in the
current scope. The current scope is the one that was last mentioned by current scope. The current scope is the one that was last mentioned by
a .scope directive. If the wrong scope is current, the label on a a .scope directive. If the wrong scope is current, the label on a
scope directive can be used to resume a scope. The syntax works like scope directive can be used to resume a scope. The syntax works like
this: this::
.scope <symbol>; .scope <symbol>;
@ -131,7 +132,8 @@ and is used to identify the scope to be resumed. A scope resume
directive cannot have a label. directive cannot have a label.
VARIABLES Variables
---------
Reg vectors (scalars are vectors of length 1) are created by .var Reg vectors (scalars are vectors of length 1) are created by .var
statements in the source. The .var statement includes the declared statements in the source. The .var statement includes the declared
@ -145,21 +147,23 @@ The VPI interface to variable (vpiReg objects) uses the MSB and LSB
values that the user defined to describe the dimensions of the values that the user defined to describe the dimensions of the
object. object.
/* ::
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
* /*
* This source code is free software; you can redistribute it * Copyright (c) 2001-2024 Stephen Williams (steve@icarus.com)
* and/or modify it in source code form under the terms of the GNU *
* General Public License as published by the Free Software * This source code is free software; you can redistribute it
* Foundation; either version 2 of the License, or (at your option) * and/or modify it in source code form under the terms of the GNU
* any later version. * General Public License as published by the Free Software
* * Foundation; either version 2 of the License, or (at your option)
* This program is distributed in the hope that it will be useful, * any later version.
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * This program is distributed in the hope that it will be useful,
* GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* You should have received a copy of the GNU General Public License * GNU General Public License for more details.
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 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.
*/

View File

@ -1,13 +1,8 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
*/
Thread Details
==============
Thread objects in vvp are created by `.thread` statements in the
THREAD DETAILS
Thread objects in vvp are created by ``.thread'' statements in the
input source file. input source file.
A thread object includes a program counter and private bit A thread object includes a program counter and private bit
@ -47,21 +42,23 @@ that use these registers document which register is used, and what the
numeric value is used for. Registers 0-3 are often given fixed numeric value is used for. Registers 0-3 are often given fixed
meanings to instructions that need an integer value. meanings to instructions that need an integer value.
/* ::
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
* /*
* This source code is free software; you can redistribute it * Copyright (c) 2001-2024 Stephen Williams (steve@icarus.com)
* and/or modify it in source code form under the terms of the GNU *
* General Public License as published by the Free Software * This source code is free software; you can redistribute it
* Foundation; either version 2 of the License, or (at your option) * and/or modify it in source code form under the terms of the GNU
* any later version. * General Public License as published by the Free Software
* * Foundation; either version 2 of the License, or (at your option)
* This program is distributed in the hope that it will be useful, * any later version.
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * This program is distributed in the hope that it will be useful,
* GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* You should have received a copy of the GNU General Public License * GNU General Public License for more details.
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 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.
*/

View File

@ -1,9 +1,6 @@
/*
* Copyright (c) 2001-2021 Stephen Williams (steve@icarus.com)
*
*/
VVP SIMULATION ENGINE VVP Simulation Engine
=====================
The VVP simulator takes as input source code not unlike assembly The VVP simulator takes as input source code not unlike assembly
language for a conventional processor. It is intended to be machine language for a conventional processor. It is intended to be machine
@ -12,7 +9,8 @@ compiler, so the syntax, though readable, is not necessarily
convenient for humans. convenient for humans.
GENERAL FORMAT General Format
--------------
The source file is a collection of statements. Each statement may have The source file is a collection of statements. Each statement may have
a label, an opcode, and operands that depend on the opcode. For some a label, an opcode, and operands that depend on the opcode. For some
@ -21,7 +19,7 @@ required.
Every statement is terminated by a semicolon. The semicolon is also Every statement is terminated by a semicolon. The semicolon is also
the start of a comment line, so you can put comment text after the the start of a comment line, so you can put comment text after the
semicolon that terminates a statement. Like so: semicolon that terminates a statement. Like so::
Label .functor and, 0x5a, x, y ; This is a comment. Label .functor and, 0x5a, x, y ; This is a comment.
@ -31,7 +29,8 @@ Statements may span multiple lines, as long as there is no text (other
then the first character of a label) in the first column of the then the first character of a label) in the first column of the
continuation line. continuation line.
HEADER SYNTAX Header Syntax
-------------
Before any other non-commentary code starts, the source may contain Before any other non-commentary code starts, the source may contain
some header statements. These are used for passing parameters or some header statements. These are used for passing parameters or
@ -57,9 +56,10 @@ expressed as a power of 10. For example, +0 is 1 second, and -9 is 1
nanosecond. If the record is left out, then the precision is taken to nanosecond. If the record is left out, then the precision is taken to
be +0. be +0.
LABELS AND SYMBOLS Labels and Symbols
------------------
Labels and symbols consist of the characters: Labels and symbols consist of the characters::
a-z a-z
A-Z A-Z
@ -88,14 +88,16 @@ There are some special symbols that in certain contexts have special
meanings. As inputs to functors, the symbols "C<0>", "C<1>", "C<x>" meanings. As inputs to functors, the symbols "C<0>", "C<1>", "C<x>"
and "C<z>" represent a constant driver of the given value. and "C<z>" represent a constant driver of the given value.
NUMBERS: Numbers
-------
decimal number tokens are limited to 64bits, and are unsigned. Some decimal number tokens are limited to 64bits, and are unsigned. Some
contexts may constrain the number size further. contexts may constrain the number size further.
SCOPE STATEMENTS: Scope Statements
----------------
The syntax of a scope statement is: The syntax of a scope statement is::
<label> .scope <type>, <name> <type-name> <file> <lineno> ; <label> .scope <type>, <name> <type-name> <file> <lineno> ;
@ -125,13 +127,14 @@ The <is-cell> flag is only useful for module instances. It is true
The short form of the scope statement is only used for root scopes. The short form of the scope statement is only used for root scopes.
PARAMETER STATEMENTS: Parameter Statements
--------------------
Parameters are named constants within a scope. These parameters have a Parameters are named constants within a scope. These parameters have a
type and value, and also a label so that they can be referenced as VPI type and value, and also a label so that they can be referenced as VPI
objects. objects.
The syntax of a parameter is: The syntax of a parameter is::
<label> .param/str <name> <local-flag> <file-idx> <lineno>, <value>; <label> .param/str <name> <local-flag> <file-idx> <lineno>, <value>;
<label> .param/l <name> <local-flag> <file-idx> <lineno>, <value>; <label> .param/l <name> <local-flag> <file-idx> <lineno>, <value>;
@ -139,13 +142,13 @@ The syntax of a parameter is:
The <name> is a string that names the parameter. The name is placed in The <name> is a string that names the parameter. The name is placed in
the current scope as a vpiParameter object. The .param suffix the current scope as a vpiParameter object. The .param suffix
specifies the parameter type. specifies the parameter type::
.param/str -- The parameter has a string value .param/str -- The parameter has a string value
.param/l -- The parameter has a logic vector value .param/l -- The parameter has a logic vector value
.param/r -- The parameter has a real value .param/r -- The parameter has a real value
The value, then, is appropriate for the data type. For example: The value, then, is appropriate for the data type. For example::
P_123 .param/str "hello", "Hello, World."; P_123 .param/str "hello", "Hello, World.";
@ -153,14 +156,15 @@ The boolean and logic values can also be signed or not. If signed, the
value is preceded by a '+' character. (Note that the value is 2s value is preceded by a '+' character. (Note that the value is 2s
complement, so the '+' says only that it is signed, not positive.) complement, so the '+' says only that it is signed, not positive.)
FUNCTOR STATEMENTS: Functor Statements
------------------
A functor statement is a statement that uses the ``.functor'' A functor statement is a statement that uses the `.functor`
opcode. Functors are the basic structural units of a simulation, and opcode. Functors are the basic structural units of a simulation, and
include a type (in the form of a truth table) and up to four inputs. A include a type (in the form of a truth table) and up to four inputs. A
label is required for functors. label is required for functors.
The general syntax of a functor is: The general syntax of a functor is::
<label> .functor <type>, symbol_list ; <label> .functor <type>, symbol_list ;
<label> .functor <type> [<drive0> <drive1>], symbol_list ; <label> .functor <type> [<drive0> <drive1>], symbol_list ;
@ -187,17 +191,20 @@ combining up to four inputs down to one output.
- MUXZ - MUXZ
::
Q | A B S n/a Q | A B S n/a
--+------------- --+-------------
A | * * 0 A | * * 0
B | * * 1 B | * * 1
DFF AND LATCH STATEMENTS: DFF and Latch Statements
------------------------
The Verilog language itself does not have a DFF primitive, but post The Verilog language itself does not have a DFF primitive, but post
synthesis readily creates DFF devices that are best simulated with a synthesis readily creates DFF devices that are best simulated with a
common device. Thus, there is the DFF statement to create DFF devices: common device. Thus, there is the DFF statement to create DFF devices::
<label> .dff/p <width> <d>, <clk>, <ce>; <label> .dff/p <width> <d>, <clk>, <ce>;
<label> .dff/n <width> <d>, <clk>, <ce>; <label> .dff/n <width> <d>, <clk>, <ce>;
@ -218,7 +225,7 @@ propagate, and disables the clock until the aynchronous input is
deasserted. Thus, they implement DFF with asynchronous clr or set. deasserted. Thus, they implement DFF with asynchronous clr or set.
Similarly, synthesis creates D-type latches, so there is the LATCH Similarly, synthesis creates D-type latches, so there is the LATCH
statement to support this: statement to support this::
<label> .latch <width> <d>, <en>; <label> .latch <width> <d>, <en>;
@ -227,7 +234,8 @@ type of datum at all. The device will transfer the input to the output
whenever <en> is a logic 1. whenever <en> is a logic 1.
UDP STATEMENTS: UDP Statements
--------------
A UDP statement either defines a User Defined Primitive, or A UDP statement either defines a User Defined Primitive, or
instantiates a previously defined UDP by creating a UDP functor. A instantiates a previously defined UDP by creating a UDP functor. A
@ -254,6 +262,8 @@ UDPs may also have "-": no change.
An input or current output state can be An input or current output state can be
::
"1": 1 "1": 1
"0": 0 "0": 0
"x": x "x": x
@ -265,6 +275,8 @@ An input or current output state can be
For Sequential UDPs, at most one input state specification may be For Sequential UDPs, at most one input state specification may be
replaced by an edge specification. Valid edges are: replaced by an edge specification. Valid edges are:
::
"*": (??) "_": (?0) "+": (?1) "%": (?x) "*": (??) "_": (?0) "+": (?1) "%": (?x)
"P": (0?) "r": (01) "Q": (0x) "P": (0?) "r": (01) "Q": (0x)
"N": (1?) "f": (10) "M": (1x) "N": (1?) "f": (10) "M": (1x)
@ -273,13 +285,13 @@ replaced by an edge specification. Valid edges are:
"n": (1?) | (?0) "n": (1?) | (?0)
"p": (0?) | (?1) "p": (0?) | (?1)
A combinatorial UDP is defined like this: A combinatorial UDP is defined like this::
<type> .udp/comb "<name>", <number>, "<row0>", "<row1>", ... ; <type> .udp/comb "<name>", <number>, "<row0>", "<row1>", ... ;
<type> is a label that identifies the UDP. <number> is the number of <type> is a label that identifies the UDP. <number> is the number of
inputs. "<name>" is there for public identification. Sequential UDPs inputs. "<name>" is there for public identification. Sequential UDPs
need an additional initialization value: need an additional initialization value::
<type> .udp/sequ "<name>", <number>, <init>, "<row0>", "<row1>", ... ; <type> .udp/sequ "<name>", <number>, <init>, "<row0>", "<row1>", ... ;
@ -287,7 +299,7 @@ need an additional initialization value:
provide initial values for individual instances. <init> must be a provide initial values for individual instances. <init> must be a
number 0, 1, or 2 (for 1'bx). number 0, 1, or 2 (for 1'bx).
A UDP functor instance is created so: A UDP functor instance is created so::
<label> .udp <type>, <symbol_list> ; <label> .udp <type>, <symbol_list> ;
@ -296,11 +308,12 @@ defined earlier, and <symbol_list> is a list of symbols, one for each
input of the UDP. input of the UDP.
VARIABLE STATEMENTS: Variable Statements
-------------------
A variable is a bit vector that can be written by behavioral code (so A variable is a bit vector that can be written by behavioral code (so
has no structural input) and propagates its output to a functor. The has no structural input) and propagates its output to a functor. The
general syntax of a variable is: general syntax of a variable is::
<label> .var "name", <msb> <lsb>; Unsigned logic variable <label> .var "name", <msb> <lsb>; Unsigned logic variable
<label> .var/s "name", <msb> <lsb>; Signed logic variable <label> .var/s "name", <msb> <lsb>; Signed logic variable
@ -336,12 +349,13 @@ Behavioral code may also invoke %force/v statements that write to port-2
to invoke force mode. This overrides continuous assign mode until a to invoke force mode. This overrides continuous assign mode until a
long(2) is written to port-3 to disable force mode. long(2) is written to port-3 to disable force mode.
NET STATEMENTS: Net Statements
--------------
A net is similar to a variable, except that a thread cannot write to A net is similar to a variable, except that a thread cannot write to
it (unless it uses a force) and it is given a different VPI type it (unless it uses a force) and it is given a different VPI type
code. The syntax of a .net statement is also similar to but not code. The syntax of a .net statement is also similar to but not
exactly the same as the .var statement: exactly the same as the .var statement::
<label> .net "name", <msb>, <lsb>, <symbol>; <label> .net "name", <msb>, <lsb>, <symbol>;
<label> .net/s "name", <msb>, <lsb>, <symbol>; <label> .net/s "name", <msb>, <lsb>, <symbol>;
@ -375,11 +389,12 @@ The .alias statements do not create new nodes, but instead create net
names that are aliases of an existing node. This handles special cases names that are aliases of an existing node. This handles special cases
where a net has different names, possibly in different scopes. where a net has different names, possibly in different scopes.
CAST STATEMENTS: Cast Statements
---------------
Sometimes nets need to be cast from a real valued net to a bit based Sometimes nets need to be cast from a real valued net to a bit based
net or from a bit based net to a real valued net. These statements net or from a bit based net to a real valued net. These statements
are used to perform that operation: are used to perform that operation::
<label> .cast/int <width>, <symbol>; <label> .cast/int <width>, <symbol>;
<label> .cast/2 <width>, <symbol>; <label> .cast/2 <width>, <symbol>;
@ -394,7 +409,8 @@ For .cast/real the output <label> is a real valued net. The input
<symbol> is expected to put bit based values and for .cast/real.s <symbol> is expected to put bit based values and for .cast/real.s
the bits will be interpreted as a signed value. the bits will be interpreted as a signed value.
DELAY STATEMENTS: Delay Statements
----------------
Delay nodes are structural net delay nodes that carry and manage Delay nodes are structural net delay nodes that carry and manage
propagation delays. Delay nodes can have fixed delays or variable propagation delays. Delay nodes can have fixed delays or variable
@ -403,6 +419,8 @@ delayed. The delay amount is given on the node line. Variable delay
nodes have three extra inputs to receive the rise, fall and decay nodes have three extra inputs to receive the rise, fall and decay
times that are used for delay. times that are used for delay.
::
.delay <width> ( <rise>, <fall>, <decay> ) <input> ; .delay <width> ( <rise>, <fall>, <decay> ) <input> ;
.delay <width> <input>, <rise>, <fall>, <decay> ; .delay <width> <input>, <rise>, <fall>, <decay> ;
@ -412,20 +430,24 @@ inputs, with the first being the value to delay, and the remaining to
be the delay values to use. <width> specifies the bit width of the be the delay values to use. <width> specifies the bit width of the
input net, with a width of 0 used to identify a real valued net. input net, with a width of 0 used to identify a real valued net.
MODULE PATH DELAY STATEMENTS: Module Path Delay Statements
----------------------------
A module path delay takes data from its input, then a list of module A module path delay takes data from its input, then a list of module
path delays. The <src> for each possible delay set is a trigger that path delays. The <src> for each possible delay set is a trigger that
activates the delay. activates the delay.
::
.modpath <width> <input> , [ <src> (<delays> [? <condition>]) ] ; .modpath <width> <input> , [ <src> (<delays> [? <condition>]) ] ;
<width> specifies the bit width of the input net. <width> specifies the bit width of the input net.
ARRAY INDEX STATEMENTS: Array Index Statements
----------------------
Variables can be collected into arrays. The words of the array are Variables can be collected into arrays. The words of the array are
declared separately, this statement collects them together: declared separately, this statement collects them together::
<label> .array "name", <last> <first> ; <label> .array "name", <last> <first> ;
@ -436,15 +458,18 @@ The syntax below is different, in that it creates an alias for an
existing array. The dimensions and storage are taken from the .array existing array. The dimensions and storage are taken from the .array
at <src>. at <src>.
::
<label> .array "name", <src> ; <label> .array "name", <src> ;
EVENT STATEMENTS Event Statements
----------------
Threads need to interact with the functors of a netlist synchronously, Threads need to interact with the functors of a netlist synchronously,
as well as asynchronously. There are cases where the web of functors as well as asynchronously. There are cases where the web of functors
needs to wake up a waiting thread. The web of functors signals threads needs to wake up a waiting thread. The web of functors signals threads
through .event objects, that are declared like so: through .event objects, that are declared like so::
<label> .event <type>, <symbols_list>; <label> .event <type>, <symbols_list>;
<label> .event "name"; <label> .event "name";
@ -470,7 +495,7 @@ events of the same edge in an event OR expression, the compiler may
combine up to 4 into a single event. combine up to 4 into a single event.
If many more events need to be combined together (for example due to If many more events need to be combined together (for example due to
an event or expression in the Verilog) then this form can be used: an event or expression in the Verilog) then this form can be used::
<label> .event/or <symbols_list>; <label> .event/or <symbols_list>;
@ -479,13 +504,16 @@ to trigger this event. Only one of the input events needs to trigger
to make this one go. to make this one go.
RESOLVER STATEMENTS: Resolver Statements
-------------------
Resolver statements are strength-aware functors with 4 inputs, but Resolver statements are strength-aware functors with 4 inputs, but
their job typically is to calculate a resolved output using strength their job typically is to calculate a resolved output using strength
resolution. The type of the functor is used to select a specific resolution. The type of the functor is used to select a specific
resolution function. resolution function.
::
<label> .resolv tri, <symbols_list>; <label> .resolv tri, <symbols_list>;
<label> .resolv tri0, <symbols_list>; <label> .resolv tri0, <symbols_list>;
<label> .resolv tri1, <symbols_list>; <label> .resolv tri1, <symbols_list>;
@ -494,13 +522,16 @@ The output from the resolver is vvp_vector8_t value. That is, the
result is a vector with strength included. result is a vector with strength included.
PART SELECT STATEMENTS: Part Select Statements
----------------------
Part select statements are functors with three inputs. They take in at Part select statements are functors with three inputs. They take in at
port-0 a vector, and output a selected (likely smaller) part of that port-0 a vector, and output a selected (likely smaller) part of that
vector. The other inputs specify what those parts are, as a canonical vector. The other inputs specify what those parts are, as a canonical
bit number, and a width. Normally, those bits are constant values. bit number, and a width. Normally, those bits are constant values.
::
<label> .part <symbol>, <base>, <wid>; <label> .part <symbol>, <base>, <wid>;
<label> .part/pv <symbol>, <base>, <wid>, <vector_wid>; <label> .part/pv <symbol>, <base>, <wid>, <vector_wid>;
<label> .part/v <symbol>, <symbol>, <wid>; <label> .part/v <symbol>, <symbol>, <wid>;
@ -520,13 +551,16 @@ The .part/v variation takes a vector (or long) input on port-1 as the
base of the part select. Thus, the part select can move around. The base of the part select. Thus, the part select can move around. The
.part/v.s variation treats the vector as a signed value. .part/v.s variation treats the vector as a signed value.
PART CONCATENATION STATEMENTS: Part Concatenation Statements
-----------------------------
The opposite of the part select statement is the part concatenation The opposite of the part select statement is the part concatenation
statement. The .concat statement is a functor node that takes at input statement. The .concat statement is a functor node that takes at input
vector values and produces a single vector output that is the vector values and produces a single vector output that is the
concatenation of all the inputs. concatenation of all the inputs.
::
<label> .concat [W X Y Z], <symbols_list> ; <label> .concat [W X Y Z], <symbols_list> ;
The "[" and "]" tokens surround a set of 4 numbers that are the The "[" and "]" tokens surround a set of 4 numbers that are the
@ -541,11 +575,12 @@ propagated, the bits are placed in the correct place in the output
vector value, and a new output value is propagated. vector value, and a new output value is propagated.
REPEAT VECTOR STATEMENTS: Repeat Vector Statements
------------------------
The repeat vector statement is similar to the concatenation statement, The repeat vector statement is similar to the concatenation statement,
expect that the input is repeated a constant number of times. The expect that the input is repeated a constant number of times. The
format of the repeat vector statement is: format of the repeat vector statement is::
<label> .repeat <wid>, <rept count>, <symbol> ; <label> .repeat <wid>, <rept count>, <symbol> ;
@ -554,15 +589,16 @@ the *output* vector. The <rept count> is the number of time the input
vector value is repeated to make the output width. The input width is vector value is repeated to make the output width. The input width is
implicit from these numbers. The <symbol> is then the input source. implicit from these numbers. The <symbol> is then the input source.
SUBSTITUTION STATEMENTS: Substitution Statements
-----------------------
The substitution statement doesn't have a direct analog in Verilog, it The substitution statement doesn't have a direct analog in Verilog, it
only turns up in synthesis. It is a shorthand for forms like this: only turns up in synthesis. It is a shorthand for forms like this::
foo = <a>; foo = <a>;
foo[n] = <s>; foo[n] = <s>;
The format of the substitute statement is: The format of the substitute statement is::
<label> .substitute <wid>, <soff> <swid>, <symbol>, <symbol> ; <label> .substitute <wid>, <soff> <swid>, <symbol>, <symbol> ;
@ -570,11 +606,14 @@ The first <symbol> must have the width <wid>, and is passed through,
except for the bits within [<soff> +: <swid>]. The second <symbol> except for the bits within [<soff> +: <swid>]. The second <symbol>
collects a vector that goes into that part. collects a vector that goes into that part.
REDUCTION LOGIC Reduction Logic
---------------
The reduction logic statements take in a single vector, and propagate The reduction logic statements take in a single vector, and propagate
a single bit. a single bit.
::
<label> .reduce/and <symbol> ; <label> .reduce/and <symbol> ;
<label> .reduce/or <symbol> ; <label> .reduce/or <symbol> ;
<label> .reduce/xor <symbol> ; <label> .reduce/xor <symbol> ;
@ -586,22 +625,28 @@ the device has a single input, which is a vector of any width. The
device performs the logic on all the bits of the vector (a la Verilog) device performs the logic on all the bits of the vector (a la Verilog)
and produces and propagates a single bit width vector. and produces and propagates a single bit width vector.
EXPANSION LOGIC Expansion Logic
---------------
Sign extension nodes are the opposite of reduction logic, in that they Sign extension nodes are the opposite of reduction logic, in that they
take a narrow vector, or single bit, and pad it out to a wider take a narrow vector, or single bit, and pad it out to a wider
vector. vector.
::
<label> .expand/s <wid>, <symbol> ; <label> .expand/s <wid>, <symbol> ;
The .expand/s node takes an input symbol and sign-extends it to the The .expand/s node takes an input symbol and sign-extends it to the
given width. given width.
FORCE STATEMENTS (old method - remove me): Force Statements (old method - remove me)
-----------------------------------------
A force statement creates functors that represent a Verilog force A force statement creates functors that represent a Verilog force
statement. statement.
::
<label> .force <signal>, <symbol_list>; <label> .force <signal>, <symbol_list>;
The symbol <signal> represents the signal which is to be forced. The The symbol <signal> represents the signal which is to be forced. The
@ -610,7 +655,7 @@ forced on the <signal>. The <label> identifies the force functors.
There will be as many force functors as there are symbols in the There will be as many force functors as there are symbols in the
<symbol_list>. <symbol_list>.
To activate and deactivate a force on a single bit, use: To activate and deactivate a force on a single bit, use::
%force <label>, <width>; %force <label>, <width>;
%release <signal>; %release <signal>;
@ -619,13 +664,14 @@ To activate and deactivate a force on a single bit, use:
<signal> is the label of the functor that drives the signal that is <signal> is the label of the functor that drives the signal that is
being forced. being forced.
FORCE STATEMENTS (new method - implement me): Force Statements (new method - implement me)
--------------------------------------------
A %force instruction, as described in the .var section, forces a A %force instruction, as described in the .var section, forces a
constant value onto a .var or .net, and the matching %release releases constant value onto a .var or .net, and the matching %release releases
that value. However, there are times when the value of a functor that value. However, there are times when the value of a functor
(i.e. another .net) needs to be forced onto a .var or .net. For this (i.e. another .net) needs to be forced onto a .var or .net. For this
task, the %force/link instruction exists: task, the %force/link instruction exists::
%force/link <dst>, <src> ; %force/link <dst>, <src> ;
%release/link <dst> ; %release/link <dst> ;
@ -638,20 +684,23 @@ node. The matching %release/link instruction removes the link (a
releases the last %force/link, no matter where the link is from. A new releases the last %force/link, no matter where the link is from. A new
%force/link will remove a previous link. %force/link will remove a previous link.
The instructions: The instructions::
%cassign/link <dst>, <src> ; %cassign/link <dst>, <src> ;
%deassign/link <dst> ; %deassign/link <dst> ;
are the same concept, but for the continuous assign port. are the same concept, but for the continuous assign port.
STRUCTURAL ARITHMETIC STATEMENTS: Structural Arithmetic Statements
--------------------------------
The various Verilog arithmetic operators (+-*/%) are available to The various Verilog arithmetic operators (`+-*/%`) are available to
structural contexts as two-input functors that take in vectors. All of structural contexts as two-input functors that take in vectors. All of
these operators take two inputs and generate a fixed width output. The these operators take two inputs and generate a fixed width output. The
input vectors will be padded if needed to get the desired output width. input vectors will be padded if needed to get the desired output width.
::
<label> .arith/sub <wid>, <A>, <B>; <label> .arith/sub <wid>, <A>, <B>;
<label> .arith/sum <wid>, <A>, <B>; <label> .arith/sum <wid>, <A>, <B>;
<label> .arith/mult <wid>, <A>, <B>; <label> .arith/mult <wid>, <A>, <B>;
@ -667,12 +716,13 @@ output. I have not decided how to handle this.
These devices support .s and .r suffixes. The .s means the node is a These devices support .s and .r suffixes. The .s means the node is a
signed vector device, the .r a real valued device. signed vector device, the .r a real valued device.
STRUCTURAL COMPARE STATEMENTS: Structural Compare Statements
-----------------------------
The arithmetic statements handle various arithmetic operators that The arithmetic statements handle various arithmetic operators that
have wide outputs, but the comparators have single bit output, so they have wide outputs, but the comparators have single bit output, so they
are implemented a bit differently. The syntax, however, is very are implemented a bit differently. The syntax, however, is very
similar: similar::
<label> .cmp/eeq <wid>, <A>, <B>; <label> .cmp/eeq <wid>, <A>, <B>;
<label> .cmp/nee <wid>, <A>, <B>; <label> .cmp/nee <wid>, <A>, <B>;
@ -691,10 +741,11 @@ versions do unsigned comparison, but the ".s" versions to signed
comparisons. (Equality doesn't need to care about sign.) comparisons. (Equality doesn't need to care about sign.)
STRUCTURAL SHIFTER STATEMENTS: Structural Shifter Statements
-----------------------------
Variable shifts in structural context are implemented with .shift Variable shifts in structural context are implemented with .shift
statements: statements::
<label> .shift/l <wid>, <data symbol>, <shift symbol>; <label> .shift/l <wid>, <data symbol>, <shift symbol>;
<label> .shift/r <wid>, <data symbol>, <shift symbol>; <label> .shift/r <wid>, <data symbol>, <shift symbol>;
@ -706,15 +757,18 @@ data to be shifted and must have exactly the width of the output. The
input to port 1 is the amount to shift. input to port 1 is the amount to shift.
STRUCTURAL FUNCTION CALLS: Structural Function Calls
-------------------------
The .ufunc statements define a call to a user defined function. The .ufunc statements define a call to a user defined function.
::
<label> .ufunc/real <flabel>, <wid>, <label> .ufunc/real <flabel>, <wid>,
<isymbols> ( <psymbols> ) <ssymbol>; [<isymbols> ( <psymbols> )] <ssymbol>;
<label> .ufunc/vec4 <flabel>, <wid>, <label> .ufunc/vec4 <flabel>, <wid>,
<isymbols> ( <psymbols> ) <ssymbol>; [<isymbols> ( <psymbols> )] <ssymbol>;
<label> .ufunc/e <flabel>, <wid>, <trigger>, <label> .ufunc/e <flabel>, <wid>, <trigger>,
<isymbols> ( <psymbols> ) <ssymbol>; <isymbols> ( <psymbols> ) <ssymbol>;
@ -742,12 +796,15 @@ before calling the function.
The <ssymbol> is the function scope name. The <ssymbol> is the function scope name.
THREAD STATEMENTS: Thread Statements
-----------------
Thread statements create the initial threads for a simulation. These Thread statements create the initial threads for a simulation. These
represent the initial and always blocks, and possibly other causes to represent the initial and always blocks, and possibly other causes to
create threads at startup. create threads at startup.
::
.thread <symbol> [, <flag>] .thread <symbol> [, <flag>]
This statement creates a thread with a starting address at the This statement creates a thread with a starting address at the
@ -756,7 +813,7 @@ created for the .thread statement, and it starts at the <symbol>
addressed instruction. addressed instruction.
The <flag> modifies the creation/execution behavior of the The <flag> modifies the creation/execution behavior of the
thread. Supported flags are: thread. Supported flags are::
$push -- Cause the thread to be pushed in the scheduler. This $push -- Cause the thread to be pushed in the scheduler. This
only effects startup (time 0) by arranging for pushed only effects startup (time 0) by arranging for pushed
@ -766,7 +823,7 @@ thread. Supported flags are:
* Threads in general * Threads in general
Thread statements create the initial threads of a design. These Thread statements create the initial threads of a design. These
include the ``initial'' and ``always'' statements of the original include the `initial` and `always` statements of the original
Verilog, and possibly some other synthetic threads for various Verilog, and possibly some other synthetic threads for various
purposes. It is also possible to create transient threads from purposes. It is also possible to create transient threads from
behavioral code. These are needed to support such constructs as behavioral code. These are needed to support such constructs as
@ -815,7 +872,7 @@ words have a distinct address space from the bits.
* Threads and scopes * Threads and scopes
The Verilog ``disable'' statement deserves some special mention The Verilog `disable` statement deserves some special mention
because of how it interacts with threads. In particular, threads because of how it interacts with threads. In particular, threads
throughout the design can affect (end) other threads in the design throughout the design can affect (end) other threads in the design
using the disable statement. using the disable statement.
@ -838,10 +895,11 @@ by the fork atomically joins that scope. Once the transient thread
joins the scope, it stays there until it ends. Threads never change joins the scope, it stays there until it ends. Threads never change
scopes, not even transient threads. scopes, not even transient threads.
VPI TASK/FUNCTION CALLS Vpi Task/Function Calls
-----------------------
Threads call vpi tasks with the %vpi_call or %vpi_func Threads call vpi tasks with the %vpi_call or %vpi_func
instructions. The formats are: instructions. The formats are::
%vpi_call <file-index> <lineno> <name>, <args>... ; %vpi_call <file-index> <lineno> <name>, <args>... ;
%vpi_call/w <file-index> <lineno> <name>, <args>... ; %vpi_call/w <file-index> <lineno> <name>, <args>... ;
@ -870,7 +928,7 @@ value returned by a system function called as a task.
* The &A<> argument * The &A<> argument
The &A<> argument is a reference to the word of a variable array. The The &A<> argument is a reference to the word of a variable array. The
syntax is: syntax is::
&A '<' <symbol> , <number> '>' &A '<' <symbol> , <number> '>'
&A '<' <symbol> , <base_symbol> '>' &A '<' <symbol> , <base_symbol> '>'
@ -884,7 +942,7 @@ starting at <base>). The base value may be signed or unsigned.
* The &PV<> argument * The &PV<> argument
The &PV<> argument is a reference to part of a signal. The syntax is: The &PV<> argument is a reference to part of a signal. The syntax is::
&PV '<' <symbol> , <base> , <width> '>' &PV '<' <symbol> , <base> , <width> '>'
&PV '<' <symbol> , <base_symbol> , <width> '>' &PV '<' <symbol> , <base_symbol> , <width> '>'
@ -897,7 +955,8 @@ or &A<>/&PV<> select. The third form retrieves the <base> from thread
space using <twid> bits starting at <tbase>. The base value may be space using <twid> bits starting at <tbase>. The base value may be
signed or unsigned. signed or unsigned.
TRUTH TABLES Truth Tables
------------
The logic that a functor represents is expressed as a truth table. The The logic that a functor represents is expressed as a truth table. The
functor has four inputs and one output. Each input and output has one functor has four inputs and one output. Each input and output has one
@ -910,7 +969,7 @@ implement the logic.
To implement the truth table, we need to assign 2-bit encodings for To implement the truth table, we need to assign 2-bit encodings for
the 4-value signals. I choose, pseudo-randomly, the following the 4-value signals. I choose, pseudo-randomly, the following
encoding: encoding::
1'b0 : 00 1'b0 : 00
1'b1 : 01 1'b1 : 01
@ -919,11 +978,12 @@ encoding:
The table is an array of 64 bytes, each byte holding 4 2-bit The table is an array of 64 bytes, each byte holding 4 2-bit
outputs. Construct a 6-bit byte address with inputs 1, 2 and 3 like outputs. Construct a 6-bit byte address with inputs 1, 2 and 3 like
so: so::
332211 332211
The input 0 2-bits can then be used to select which of the 4 2-bit The input 0 2-bits can then be used to select which of the 4 2-bit
pairs in the 8-bit byte are the output: pairs in the 8-bit byte are the output::
MSB -> zzxx1100 <- LSB MSB -> zzxx1100 <- LSB
@ -934,7 +994,8 @@ none needs to be given by the programmer. It is sufficient to name the
type to get that truth table. type to get that truth table.
EXECUTABLE INSTRUCTIONS Executable Instructions
-----------------------
Threads run executable code, much like a processor executes machine Threads run executable code, much like a processor executes machine
code. VVP has a variety of opcodes for executable instructions. All of code. VVP has a variety of opcodes for executable instructions. All of
@ -947,7 +1008,8 @@ The opcodes.txt file has a more detailed description of all the
various instructions. various instructions.
THE RELATIONSHIP BETWEEN FUNCTORS, THREADS AND EVENTS The Relationship Between Functors, Threads And Events
-----------------------------------------------------
Given the above summary of the major components of vvp, some Given the above summary of the major components of vvp, some
description of their relationship is warranted. Functors provide a description of their relationship is warranted. Functors provide a
@ -966,7 +1028,7 @@ it is connected to, and those functors in turn create new events if
needed. needed.
Assignment events (the second of three types of events) are created Assignment events (the second of three types of events) are created
by non-blocking assignments in behavioral code. When the ``<='' is by non-blocking assignments in behavioral code. When the `<=` is
executed (a %assign in vvp) an assign event is created, which includes executed (a %assign in vvp) an assign event is created, which includes
the vvp_ipoint_t pointer to the functor input to receive the value, the vvp_ipoint_t pointer to the functor input to receive the value,
as well as the value. These are distinct from propagation events because: as well as the value. These are distinct from propagation events because:
@ -991,7 +1053,7 @@ the right kind of code to cause things to happen in the design. If the
event is a propagate or assignment event, the network of functors is event is a propagate or assignment event, the network of functors is
tickled; if the event is a thread schedule, then a thread is run. The tickled; if the event is a thread schedule, then a thread is run. The
implementation of the event queue is not important, but currently is implementation of the event queue is not important, but currently is
implemented as a ``skip list''. That is, it is a sorted singly linked implemented as a `skip list`. That is, it is a sorted singly linked
list with skip pointers that skip over delta-time events. list with skip pointers that skip over delta-time events.
The functor net and the threads are distinct. They communicate through The functor net and the threads are distinct. They communicate through
@ -1000,7 +1062,8 @@ is concerned, the functor net is a blob of structure that it pokes and
prods via certain functor access instructions. prods via certain functor access instructions.
VVP COMPILATION AND EXECUTION VVP Compilation And Execution
-----------------------------
The vvp program operates in a few steps: The vvp program operates in a few steps:
@ -1023,7 +1086,7 @@ The vvp program operates in a few steps:
The initialization step is performed by the compile_init() function in The initialization step is performed by the compile_init() function in
compile.cc. This function in turn calls all the *_init() functions in compile.cc. This function in turn calls all the \*_init() functions in
other parts of the source that need initialization for compile. All other parts of the source that need initialization for compile. All
the various sub-init functions are called <foo>_init(). the various sub-init functions are called <foo>_init().
@ -1044,7 +1107,8 @@ the schedule_simulate() function. This does any final setup and starts
the simulation running and the event queue running. the simulation running and the event queue running.
HOW TO GET FROM THERE TO HERE How To Get From There To Here
-----------------------------
The vvp simulation engine is designed to be able to take as input a The vvp simulation engine is designed to be able to take as input a
compiled form of Verilog. That implies that there is a compiler that compiled form of Verilog. That implies that there is a compiler that
@ -1055,22 +1119,22 @@ compiles Verilog into a form that the vvp engine can read.
Gates like AND, OR and NAND are implemented simply and obviously by Gates like AND, OR and NAND are implemented simply and obviously by
functor statements. Any logic up to 4 inputs can be implemented with a functor statements. Any logic up to 4 inputs can be implemented with a
single functor. For example: single functor. For example::
and gate (out, i1, i2, i3); and gate (out, i1, i2, i3);
becomes: becomes::
gate .functor and, i1, i2, i3; gate .functor and, i1, i2, i3;
Notice the first parameter of the .functor is the type. The type Notice the first parameter of the .functor is the type. The type
includes a truth table that describes the output with a given includes a truth table that describes the output with a given
input. If the gate is wider than four inputs, then cascade input. If the gate is wider than four inputs, then cascade
functors. For example: functors. For example::
and gate (out, i1, i2, i3, i4, i5, i6, i7, i8); and gate (out, i1, i2, i3, i4, i5, i6, i7, i8);
becomes: becomes::
gate.0 .functor and, i1, i2, i3, i4; gate.0 .functor and, i1, i2, i3, i4;
gate.1 .functor and, i5, i6, i7, i8; gate.1 .functor and, i5, i6, i7, i8;
@ -1079,16 +1143,16 @@ becomes:
* reg and other variables * reg and other variables
Reg and integer are cases of what Verilog calls ``variables.'' Reg and integer are cases of what Verilog calls `variables`.
Variables are, simply put, things that behavioral code can assign Variables are, simply put, things that behavioral code can assign
to. These are not the same as ``nets,'' which include wires and the to. These are not the same as `nets`, which include wires and the
like. like.
Each bit of a variable is created by a ``.var'' statement. For example: Each bit of a variable is created by a `.var` statement. For example::
reg a; reg a;
becomes: becomes::
a .var "a", 0, 0; a .var "a", 0, 0;
@ -1097,16 +1161,17 @@ becomes:
Events in general are implemented as functors, but named events in Events in general are implemented as functors, but named events in
particular have no inputs and only the event output. The way to particular have no inputs and only the event output. The way to
generate code for these is like so: generate code for these is like so::
a .event "name"; a .event "name";
This creates a functor and makes it into a mode-2 functor. Then the This creates a functor and makes it into a mode-2 functor. Then the
trigger statement, "-> a", cause a ``%set a, 0;'' statement be trigger statement, "-> a", cause a `%set a, 0;` statement be
generated. This is sufficient to trigger the event. generated. This is sufficient to trigger the event.
AUTOMATICALLY ALLOCATED SCOPES Automatically Allocated Scopes
------------------------------
If a .scope statement has a <type> of autofunction or autotask, the If a .scope statement has a <type> of autofunction or autotask, the
scope is flagged as being an automatically allocated scope. The functor scope is flagged as being an automatically allocated scope. The functor
@ -1159,21 +1224,23 @@ variable or event, the associated functor indirects through the
current read or write context of the running thread, using its current read or write context of the running thread, using its
stored context index. stored context index.
/* ::
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
* /*
* This source code is free software; you can redistribute it * Copyright (c) 2001-2024 Stephen Williams (steve@icarus.com)
* and/or modify it in source code form under the terms of the GNU *
* General Public License as published by the Free Software * This source code is free software; you can redistribute it
* Foundation; either version 2 of the License, or (at your option) * and/or modify it in source code form under the terms of the GNU
* any later version. * General Public License as published by the Free Software
* * Foundation; either version 2 of the License, or (at your option)
* This program is distributed in the hope that it will be useful, * any later version.
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * This program is distributed in the hope that it will be useful,
* GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* You should have received a copy of the GNU General Public License * GNU General Public License for more details.
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 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.
*/

View File

@ -9,5 +9,7 @@ Icarus Verilog.
:maxdepth: 1 :maxdepth: 1
getting_started getting_started
regression_tests
version_stamps version_stamps
guide/index
glossary

View File

@ -0,0 +1,129 @@
The Regression Test Suite
=========================
Icarus Verilog development includes a regression test suite that is included
along with the source. The "ivtest" directory contains the regression test
suite, and this suite is used by the github actions as continuous integration
to make sure the code is always going forward.
NOTE: There are scripts written in perl to run the regression tests, but they
are being gradually replaced with a newer set of scripts. It is the newer
method that is described here.
Test Descriptions
-----------------
Regression tests are listed in the regress-vvp.list file. Each line lists the
name of the test and the path to the dest description. The list file is
therefore pretty simple, and all the description of the test is in the
description file:
.. code-block:: console
macro_str_esc vvp_tests/macro_str_esc.json
The "name" is a simple name, and the test-description-file is the path (relative
the ivtest directory) to the description file. A simple test description file
is a JSON file, like this:
.. code-block:: java
{
"type" : "normal",
"source" : "macro_str_esc.v",
"gold" : "macro_str_esc"
}
This description file contains all the information that the vvp_reg.py script
needs to run the regression test. The sections below describe the keys and
values in the description file dictionary.
source (required)
^^^^^^^^^^^^^^^^^
This specifies the name of the source file. The file is actually to be found
in the ivltests/ directory.
type (required)
^^^^^^^^^^^^^^^
This describes the kind of test to run. The valid values are:
* **normal** - Compile the source using the iverilog compiler vvp target, and if
that succeeds execute it using the vvp command. If there is no gold file
specified, then look for an output line with the "PASSED" string.
* **NI** - Mark the test as not implemented. The test will be skipped without
running or reporting an error.
* **CE** - Compile, but expect the compiler to fail. This means the compiler
command process must return an error exit.
* **EF** - Compile and run, but expect the run time to fail. This means the
run time program must return an error exit.
* **TE** - This is specific to testing the vlog95 conversion and indicates the
translated code failed to compile.
gold (optional)
^^^^^^^^^^^^^^^
If this is specified, it replaces the "Passed" condition with a comparison of
the output with a gold file. The argument is the name of the gold file set,
which will be found in the "gold/" directory. The name here is actually the
basename of the gold files, with separate actual gold files for the iverilog
and vvp stderr and stdout. For example, if a "normal" test includes a gold
file, then the program is compiled and run, and the outputs are compared with
the gold file to make sure it ran properly.
The way the regression suite works, there are 4 log files created for each
test:
* foo-iverilog-stdout.log
* foo-iverilog-stderr.log
* foo-vvp-stdout.log
* foo-vvp-stderr.log
The "gold" value is the name of the gold file set. If the gold value is "foo",
Then the actual gold files are called:
* gold/foo-iverilog-stdout.gold
* gold/foo-iverilog-stderr.gold
* gold/foo-vvp-stdout.gold
* gold/foo/vvp-stderr.gold
If any of those files is empty, then the gold file doesn't need to be
present at all. The log files and the gold files are compared byte for
byte, so if the output you are getting is correct, then copy the log to
the corresponding gold, and you're done.
If the run type is "CE" or "RE", then the gold files still work, and can
be used to check that the error message is correct. If the gold file setting
is present, the error return is required, and also the gold files must match.
iverilog-args (optional)
^^^^^^^^^^^^^^^^^^^^^^^^
If this is specified, it is a list of strings that are passed as arguments to
the iverilog command line.
vvp-args (optional)
^^^^^^^^^^^^^^^^^^^^
If this is specified, it is a list of strings that are passed as arguments to
the vvp command. These arguments go before the vvp input file that is to be
run.
vvp-args-extended (optional)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If this is specified, it is a lost of strings that are passed as arguments to
the vvp command. These are extended arguments, and are placed after the vvp
input file that is being run. This is where you place things like plusargs.
strict, force-sv or vlog95 (optional)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Any of these can be used to create overrides for the type, gold or
iverilog-args when the given test type is run.

View File

@ -9,21 +9,24 @@ These are the only files that have version information in them:
* verilog.spec -- Used to stamp RPM packages * verilog.spec -- Used to stamp RPM packages
When versions are changed, the above files need to be edited to account for When versions are changed, the above files need to be edited to account for
the new version information. The following used to have verion information in the new version information. The following used to have version information in
them, but now their version information is generated: them, but now their version information is generated:
Replaced with version_base.h, which is edited manually, and The version_tag.h file is generated from git tag information using
version_tag.h which is generated from git tag information. 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.
* version-base.in -- Most compiled code gets version from here The files below are now edited by the Makefile:
These are now edited by the makefile and the version.exe program.
* iverilog-vpi.man -- The .TH tag has a version string * iverilog-vpi.man -- The .TH tag has a version string
* driver/iverilog.man -- The .TH tag has a version string * driver/iverilog.man -- The .TH tag has a version string
* driver-vpi/res.rc -- Used to build Windows version stamp * driver-vpi/res.rc -- Used to build Windows version stamp
* vvp/vvp.man -- The .TH tag has a version string * vvp/vvp.man -- The .TH tag has a version string
This now includes version_base.h to get the version This now includes version_base.h to get the version:
* vpi/vams_simparam.c -- Hard coded result to simulatorVersion query * vpi/vams_simparam.c -- Hard coded result to simulatorVersion query
The test suite no longer has version specific files since it tracks along with
the code/branch.

BIN
Documentation/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -12,6 +12,7 @@ Welcome to the documentation for Icarus Verilog.
:maxdepth: 2 :maxdepth: 2
:caption: Contents: :caption: Contents:
releases/index
usage/index usage/index
targets/index targets/index
developer/index developer/index

View File

@ -0,0 +1,10 @@
Icarus Verilog Release Notes
============================
This section contains the release notes for all releases after and including
V13.0. Older release notes can be found here: `<https://iverilog.fandom.com/wiki/User_Guide>`__
.. toctree::
:maxdepth: 1
v13-0-release-note

View File

@ -0,0 +1,98 @@
🎉 Release V13.0
================
The Icarus Verilog development team is pleased to announce **Release V13** of Icarus Verilog.
Release V13 builds on the V12 series with a focus on correctness, runtime stability, improved
diagnostics, and incremental standard conformance improvements.
----
🐞 Bug Fix Summary
------------------
Release V13 resolves numerous issues reported against V12, including:
* Incorrect signed constant handling.
* Generate block naming collisions.
* Elaboration-time assertion failures.
* Runtime crashes in malformed corner cases.
* Memory management issues during elaboration and simulation.
----
🔄 Major Changes in V13
=======================
🧠 Language & Elaboration Fixes
-------------------------------
Release V13 includes multiple fixes to elaboration and expression handling:
* Resolved generate block scope resolution issues affecting nested and conditional generate constructs.
* Corrected signed arithmetic corner cases, including shift and width propagation behavior.
* Fixed constant expression evaluation inconsistencies during parameter elaboration.
* Improved handling of packed and unpacked arrays in assignments and port binding corner cases.
* Addressed elaboration-time assertion failures triggered by malformed or ambiguous constructs.
* Corrected several source-location reporting issues for elaboration errors.
These changes improve standards conformance and eliminate behavioral inconsistencies observed in the V12 series.
----
⚙️ Simulator (vvp) Improvements
-------------------------------
The `vvp` runtime engine has received internal stability and correctness updates:
* Improved event scheduling behavior in zero-delay and non-blocking assignment scenarios.
* Fixed race-condition corner cases uncovered by expanded regression testing.
* Eliminated memory leaks affecting long-running or large simulations.
* Resolved crash conditions caused by invalid internal state transitions.
* Improved robustness of `$dumpvars` handling in large hierarchical designs.
* General runtime consistency and determinism improvements.
`vvp` continues to enforce version matching between the runtime and generated bytecode. Designs
must be recompiled after upgrading.
----
🔌 VPI Updates
--------------
Fixes improve VPI reliability and conformance:
* Corrected hierarchical object lookup behavior in specific corner cases.
* Improved stability of callback registration during startup and shutdown.
* Fixed invalid handle dereference scenarios that could result in segmentation faults.
* Addressed inconsistencies in VPI object property reporting.
----
🛠 Diagnostics & Toolchain
--------------------------
* Improved clarity and consistency of error and warning messages.
* Better reporting of width mismatches and implicit net declarations.
* More accurate diagnostic source locations.
* Build system updates for compatibility with modern compiler toolchains.
* Regression suite expansion and CI validation improvements.
----
📦 Upgrade Notes
----------------
* Recompile all designs when upgrading from V12 or any other prior version.
* Review warnings carefully; improved diagnostics may expose previously silent issues.
* The only known breaking change is that wires must now be declared before use; which is required in the standard (see `gh1287 <https://github.com/steveicarus/iverilog/issues/1287>`__).
----
🙏 Acknowledgments
------------------
We thank all contributors who reported issues, submitted patches, expanded regression coverage, and
improved documentation. Release 13 reflects continued community effort toward improving correctness,
stability, and maintainability.

View File

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

View File

@ -3,16 +3,21 @@ The Icarus Verilog Targets
========================== ==========================
Icarus Verilog elaborates the design, then sends to the design to code Icarus Verilog elaborates the design, then sends to the design to code
generates (targets) for processing. new code generators can be added by generates (targets) for processing. New code generators can be added by
external packages, but these are the code generators that are bundled with external packages, but these are the code generators that are bundled with
Icarus Verilog. The code generator is selected by the "-t" command line flag. Icarus Verilog. The code generator is selected by the "-t" command line flag.
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
vvp tgt-vvp
stub tgt-stub
null tgt-null
vhdl tgt-vhdl
verilog95 tgt-vlog95
pcb tgt-pcb
tgt-fpga
tgt-pal
tgt-sizer
tgt-verilog
tgt-blif

View File

@ -1,7 +0,0 @@
The stub Code Generator (-tstub)
================================
The stub code generator is a debugging aid for the Icarus Verilog compiler
itself. It outputs a text dump of the elaborated design as it is passed to
code generators.

View File

@ -1,6 +1,6 @@
BLIF TARGET The BLIF Code Generator (-tblif)
----------- ================================
The BLIF code generator supports emitting the design to a blif format The BLIF code generator supports emitting the design to a blif format
file as accepted by: file as accepted by:
@ -17,9 +17,9 @@ USAGE
----- -----
This code generator is intended to process structural Verilog source This code generator is intended to process structural Verilog source
code. To convert a design to blif, use this command: code. To convert a design to blif, use this command::
iverilog -tblif -o<path>.blif <source files>... % iverilog -tblif -o<path>.blif <source files>...
The source files can be Verilog, SystemVerilog, VHDL, whatever Icarus The source files can be Verilog, SystemVerilog, VHDL, whatever Icarus
Verilog supports, so long as it elaborates down to the limited subset Verilog supports, so long as it elaborates down to the limited subset

View File

@ -1,7 +1,9 @@
FPGA LOADABLE CODE GENERATOR FOR Icarus Verilog The FPGA Code Generator (-tfpga)
================================
Copyright 2001 Stephen Williams .. warning::
This code generator is currently not included in Icarus Verilog.
The FPGA code generator supports a variety of FPGA devices, writing The FPGA code generator supports a variety of FPGA devices, writing
XNF or EDIF depending on the target. You can select the architecture XNF or EDIF depending on the target. You can select the architecture
@ -10,6 +12,7 @@ select library primitives, and the detailed part name is written into
the generated file for the use of downstream tools. the generated file for the use of downstream tools.
INVOKING THE FPGA TARGET INVOKING THE FPGA TARGET
------------------------
The code generator is invoked with the -tfpga flag to iverilog. It The code generator is invoked with the -tfpga flag to iverilog. It
understands the part= and the arch= parameters, which can be set with understands the part= and the arch= parameters, which can be set with
@ -61,6 +64,7 @@ Virtex-II and Virtex-II Pro devices. It uses the VIRTEX2 library, but
is very similar to the Virtex target. is very similar to the Virtex target.
XNF ROOT PORTS XNF ROOT PORTS
--------------
NOTE: As parts are moved over to EDIF format, XNF support will be NOTE: As parts are moved over to EDIF format, XNF support will be
phased out. Current Xilinx implementation tools will accept EDIF phased out. Current Xilinx implementation tools will accept EDIF
@ -76,6 +80,8 @@ signal. If the signal is one bit wide, then the pin name is exactly
the module port name. If the port is a vector, then the pin number is the module port name. If the port is a vector, then the pin number is
given as a vector. For example, the module: given as a vector. For example, the module:
.. code-block::
module main(out, in); module main(out, in);
output out; output out;
input [2:0] in; input [2:0] in;
@ -84,6 +90,8 @@ given as a vector. For example, the module:
leads to these SIG, records: leads to these SIG, records:
.. code-block::
SIG, main/out, PIN=out SIG, main/out, PIN=out
SIG, main/in<2>, PIN=in2 SIG, main/in<2>, PIN=in2
SIG, main/in<1>, PIN=in1 SIG, main/in<1>, PIN=in1
@ -91,6 +99,7 @@ leads to these SIG, records:
EDIF ROOT PORTS EDIF ROOT PORTS
---------------
The EDIF format is more explicit about the interface into an EDIF The EDIF format is more explicit about the interface into an EDIF
file. The code generator uses that control to generate an explicit file. The code generator uses that control to generate an explicit
@ -108,6 +117,7 @@ However, since the ports are single bit ports, the name of vectors
includes the string "[0]" where the number is the bit number. For includes the string "[0]" where the number is the bit number. For
example, the module: example, the module:
.. code-block::
module main(out, in); module main(out, in);
output out; output out;
@ -117,6 +127,8 @@ example, the module:
creates these ports: creates these ports:
.. code-block::
out OUTPUT out OUTPUT
in[0] INPUT in[0] INPUT
in[1] INPUT in[1] INPUT
@ -128,6 +140,7 @@ when presenting the vector to the user.
PADS AND PIN ASSIGNMENT PADS AND PIN ASSIGNMENT
-----------------------
The ports of a root module may be assigned to specific pins, or to a The ports of a root module may be assigned to specific pins, or to a
generic pad. If a signal (that is a port) has a PAD attribute, then generic pad. If a signal (that is a port) has a PAD attribute, then
@ -135,14 +148,14 @@ the value of that attribute is a list of locations, one for each bit
of the signal, that specifies the pin for each bit of the signal. For of the signal, that specifies the pin for each bit of the signal. For
example: example:
.. code-block::
module main( (* PAD = "P10" *) output out, module main( (* PAD = "P10" *) output out,
(* PAD = "P20,P21,P22" *) input [2:0] in); (* PAD = "P20,P21,P22" *) input [2:0] in);
[...] [...]
endmodule endmodule
In this example, port ``out'' is assigned to pin 10, and port ``in'' In this example, port `out` is assigned to pin 10, and port `in`
is assigned to pins 20-22. If the architecture supports it, a pin is assigned to pins 20-22. If the architecture supports it, a pin
number of 0 means let the back end tools choose a pin. The format of number of 0 means let the back end tools choose a pin. The format of
the pin number depends on the architecture family being targeted, so the pin number depends on the architecture family being targeted, so
@ -156,6 +169,7 @@ driver to the port. An error.
SPECIAL DEVICES SPECIAL DEVICES
---------------
The code generator supports the "cellref" attribute attached to logic The code generator supports the "cellref" attribute attached to logic
devices to cause specific device types be generated, instead of the devices to cause specific device types be generated, instead of the
@ -176,12 +190,12 @@ device pins are connected.
COMPILING WITH XILINX FOUNDATION COMPILING WITH XILINX FOUNDATION
--------------------------------
Compile a single-file design with command line tools like so: Compile a single-file design with command line tools like so::
% iverilog -parch=virtex -o foo.edf foo.vl
% edif2ngd foo.edf foo.ngo
% ngdbuild -p v50-pq240 foo.ngo foo.ngd
% map -o map.ncd foo.ngd
% par -w map.ncd foo.ncd
% iverilog -parch=virtex -o foo.edf foo.vl
% edif2ngd foo.edf foo.ngo
% ngdbuild -p v50-pq240 foo.ngo foo.ngd
% map -o map.ncd foo.ngd
% par -w map.ncd foo.ncd

View File

@ -0,0 +1,8 @@
The PAL Code Generator (-tpal)
==============================
.. warning::
This code generator is currently not included in Icarus Verilog.
The PAL target generates JEDEC output for a Programmable Array Logic.

View File

@ -1,6 +1,6 @@
Using the PCB code generator The PCB Code Generator (-tpcb)
============================ ==============================
The PCB target code generator is designed to allow a user to enter a netlist The PCB target code generator is designed to allow a user to enter a netlist
in Verilog format, then generate input files for the GNU PCB layout program. in Verilog format, then generate input files for the GNU PCB layout program.
@ -55,7 +55,7 @@ Verilog parameter override syntax. Parameters have preferred types.
is written into the description field of the PCB Element. is written into the description field of the PCB Element.
* value (string, default="") * value (string, default="")
The "value" is a text tring that describes some value for the black The "value" is a text tring that describes some value for the black
box. Like the description, the code generator does not interpret this value, box. Like the description, the code generator does not interpret this value,
other then to write it to the appropriate field in the PCB Element." other then to write it to the appropriate field in the PCB Element."

View File

@ -0,0 +1,49 @@
The sizer Code Analyzer (-tsizer)
=================================
The sizer target does not generate any code. Instead it will print statistics about the Verilog code.
It is important to synthesize the Verilog code before invoking the sizer. This can be done with the `-S` flag passed to iverilog. Note, that behavioral code can not be synthesized and will generate a warning when passed to the sizer.
Example command::
% iverilog -o sizer.txt -tsizer -S -s top input.v
With this example code:
.. code-block:: verilog
module top (
input clock,
input reset,
output blink
);
reg out;
always @(posedge clock) begin
if (reset) begin
out = 1'b0;
end else begin
out <= !out;
end
end
assign blink = out;
endmodule
The resulting `sizer.txt` will contain::
**** module/scope: top
Flip-Flops : 1
Logic Gates : 3
MUX[2]: 1 slices
LOG[13]: 1 unaccounted
LOG[14]: 1 unaccounted
**** TOTALS
Flip-Flops : 1
Logic Gates : 3
MUX[2]: 1 slices
LOG[13]: 1 unaccounted
LOG[14]: 1 unaccounted

View File

@ -0,0 +1,30 @@
The stub Code Generator (-tstub)
================================
The stub code generator is a debugging aid for the Icarus Verilog compiler
itself. It outputs a text dump of the elaborated design as it is passed to
code generators.
Example command::
% iverilog -o stub.txt -tstub -s top input.v
With this example code:
.. code-block:: verilog
module top;
initial $display("Hello World!");
endmodule
The resulting `stub.txt` will contain::
root module = top
scope: top (0 parameters, 0 signals, 0 logic) module top time units = 1e0
time precision = 1e0
end scope top
# There are 0 constants detected
initial
Call $display(1 parameters); /* hello_world.v:2 */
<string="Hello World!", width=96, type=bool>

View File

@ -0,0 +1,6 @@
The Verilog Code Generator (-tverilog)
======================================
.. warning::
This code generator is currently not included in Icarus Verilog.

View File

@ -1,6 +1,6 @@
Using The Verilog '95 Code Generator The Verilog '95 Code Generator (-tvlog95)
==================================== =========================================
Icarus Verilog contains a code generator to emit 1995 compliant Verilog from Icarus Verilog contains a code generator to emit 1995 compliant Verilog from
the input Verilog netlist. This allows Icarus Verilog to function as a Verilog the input Verilog netlist. This allows Icarus Verilog to function as a Verilog
@ -42,21 +42,21 @@ Structures that cannot be converted to 1995 compatible Verilog
The following Verilog constructs are not translatable to 1995 compatible Verilog: The following Verilog constructs are not translatable to 1995 compatible Verilog:
* Automatic tasks or functions. * Automatic tasks or functions.
* The power operator (**). Expressions of the form (2**N)**<variable> (where N * The power operator (**). Expressions of the form (2**N)**<variable> (where N
is a constant) can be converter to a shift. is a constant) can be converter to a shift.
* Some System Verilog constructs (e.g. final blocks, ++/-- operators, * Some System Verilog constructs (e.g. final blocks, ++/-- operators,
etc.). 2-state variables are converted to 4-state variables. etc.). 2-state variables are converted to 4-state variables.
Icarus extensions that cannot be translated: Icarus extensions that cannot be translated:
* Integer constants greater than 32 bits. * Integer constants greater than 32 bits.
* Real valued nets. * Real valued nets.
* Real modulus. * Real modulus.
* Most Verilog-A constructs. * Most Verilog-A constructs.

View File

@ -0,0 +1,63 @@
The vvp Code Generator (-tvvp)
==============================
The vvp target generates code for the "vvp" run time. This is the most
commonly used target for Icarus Verilog, as it is the main simulation engine.
Example command::
% iverilog -o top.vvp -s top hello_world.v
Equivalent command::
% iverilog -o top.vvp -tvvp -s top hello_world.v
With this example code in `hello_world.v`:
.. code-block:: verilog
module top;
initial $display("Hello World!");
endmodule
The resulting `top.vvp` will contain something similar to::
#! /usr/local/bin/vvp
:ivl_version "13.0 (devel)" "(s20221226-119-g8cb2e1a05-dirty)";
:ivl_delay_selection "TYPICAL";
:vpi_time_precision + 0;
:vpi_module "/usr/local/lib/ivl/system.vpi";
:vpi_module "/usr/local/lib/ivl/vhdl_sys.vpi";
:vpi_module "/usr/local/lib/ivl/vhdl_textio.vpi";
:vpi_module "/usr/local/lib/ivl/v2005_math.vpi";
:vpi_module "/usr/local/lib/ivl/va_math.vpi";
S_0x563c3c5d1540 .scope module, "top" "top" 2 1;
.timescale 0 0;
.scope S_0x563c3c5d1540;
T_0 ;
%vpi_call 2 2 "$display", "Hello World!" {0 0 0};
%end;
.thread T_0;
# The file index is used to find the file name in the following table.
:file_names 3;
"N/A";
"<interactive>";
"hello_world.v";
The first line contains the shebang. If this file is executed, the shebang tells the shell to use vvp for the execution of this file.
To run the simulation, execute::
% ./top.vvp
Or you can call vvp directly::
% vvp top.vvp
Next are some directives. The first one, `:ivl_version` specifies which version of iverilog this file was created with. Next is the delay selection with "min:typical:max" values and the time precision, which we did not set specifically, so the default value is used. The next lines tell vvp which VPI modules to load and in which order. The next lines tell vvp which VPI modules to load and in what order. Next, a new scope is created with the `.scope` directive and the timescale is set with `.timescale`. A thread `T_0` is created that contains two instructions: `%vpi_call` executes the VPI function `$display` with the specified arguments, and `%end` terminates the simulation.
Opcodes
-------
The various available opcodes can be seen in :doc:`Opcodes <../developer/guide/vvp/opcodes>`

View File

@ -1,6 +0,0 @@
The vvp Code Generator (-tvvp)
==============================
The vvp target generates code for the "vvp" run time. This is the most
commonly used target for Icarus Verilog, as it is the main simulation engine.

View File

@ -124,7 +124,7 @@ list of the special records with their meaning.
have multiple directories, separated by "+" characters. have multiple directories, separated by "+" characters.
* +libdir-nocase+dir-path * +libdir-nocase+dir-path
This is the same as "+libdir+", but when searching "nocase" libraries for This is the same as "+libdir+", but when searching "nocase" libraries for
module files, case will not be taken as significant. This is useful when the module files, case will not be taken as significant. This is useful when the
library is on a case insensitive file system. library is on a case insensitive file system.
@ -136,7 +136,7 @@ list of the special records with their meaning.
variety of naming conventions. variety of naming conventions.
* -y dir-path * -y dir-path
This is like "+libdir+" but each line takes only one path. Like "+libdir+" This is like "+libdir+" but each line takes only one path. Like "+libdir+"
there can be multiple "-y" records to declare multiple library there can be multiple "-y" records to declare multiple library
directories. This is similar to the "-y" flag on the iverilog command line. directories. This is similar to the "-y" flag on the iverilog command line.
@ -151,19 +151,19 @@ list of the special records with their meaning.
in releases and snapshots made after that date. in releases and snapshots made after that date.
* +incdir+*include-dir-path* * +incdir+*include-dir-path*
Declare a directory or list of directories to search for files included by Declare a directory or list of directories to search for files included by
the "include" compiler directive. The directories are searched in the "include" compiler directive. The directories are searched in
order. This is similar to the "-I" flag on the iverilog command line. order. This is similar to the "-I" flag on the iverilog command line.
* +define+*name=value* * +define+*name=value*
Define the preprocessor symbol "name" to have the string value "value". If Define the preprocessor symbol "name" to have the string value "value". If
the value (and the "=") are omitted, then it is assumed to be the string the value (and the "=") are omitted, then it is assumed to be the string
"1". This is similar to the "-D" on the iverilog command line. "1". This is similar to the "-D" on the iverilog command line.
* +timescale+*units/precision* * +timescale+*units/precision*
Define the default timescale. This is the timescale that is used if there is Define the default timescale. This is the timescale that is used if there is
no other timescale directive in the Verilog source. The compiler default no other timescale directive in the Verilog source. The compiler default
default is "+timescale+1s/1s", which this command file setting can default is "+timescale+1s/1s", which this command file setting can
@ -171,7 +171,7 @@ list of the special records with their meaning.
timescale directive in the verilog source. timescale directive in the verilog source.
* +toupper-filename * +toupper-filename
This token causes file names after this in the command file to be translated This token causes file names after this in the command file to be translated
to uppercase. this helps with situations where a directory has passed to uppercase. this helps with situations where a directory has passed
through a DOS machine (or a FAT file system) and in the process the file through a DOS machine (or a FAT file system) and in the process the file
@ -179,11 +179,11 @@ list of the special records with their meaning.
emergencies. emergencies.
* +tolower-filename * +tolower-filename
The is the lowercase version of "+toupper-filename". The is the lowercase version of "+toupper-filename".
* +parameter+*name=value* * +parameter+*name=value*
This token causes the compiler to override a parameter value for a top-level This token causes the compiler to override a parameter value for a top-level
module. For example, if the module main has the parameter WIDTH, set the module. For example, if the module main has the parameter WIDTH, set the
width like this "+parameter+main.WIDTH=5". Note the use of the complete width like this "+parameter+main.WIDTH=5". Note the use of the complete
@ -191,7 +191,7 @@ list of the special records with their meaning.
(top level) modules and a defparam may override the command file value. (top level) modules and a defparam may override the command file value.
* +vhdl-work+*path* * +vhdl-work+*path*
When compiling VHDL, this token allows control over the directory to use for When compiling VHDL, this token allows control over the directory to use for
holding working package declarations. For example, "+vhdl-work+workdir" will holding working package declarations. For example, "+vhdl-work+workdir" will
cause the directory "workdir" to be used as a directory for holding working cause the directory "workdir" to be used as a directory for holding working

View File

@ -14,17 +14,17 @@ General
These flags affect the general behavior of the compiler. These flags affect the general behavior of the compiler.
* -c <cmdfile> * -c <cmdfile>
This flag selects the command file to use. The command file is an This flag selects the command file to use. The command file is an
alternative to writing a long command line with a lot of file names and alternative to writing a long command line with a lot of file names and
compiler flags. See the Command File Format page for more information. compiler flags. See the Command File Format page for more information.
* -d <flag> * -d <flag>
Enable compiler debug output. These are aids for debugging Icarus Verilog, Enable compiler debug output. These are aids for debugging Icarus Verilog,
and this flag is not commonly used. and this flag is not commonly used.
The flag is one of these debug classes: The flag is one of these debug classes:
* scope * scope
* eval_tree * eval_tree
* elaborate * elaborate
@ -40,15 +40,15 @@ These flags affect the general behavior of the compiler.
The supported flags are: The supported flags are:
* 1995 * 1995
This flag enables the IEEE1364-1995 standard. This flag enables the IEEE1364-1995 standard.
* 2001 * 2001
This flag enables the IEEE1364-2001 standard. This flag enables the IEEE1364-2001 standard.
* 2001-noconfig * 2001-noconfig
This flag enables the IEEE1364-2001 standard with config file support This flag enables the IEEE1364-2001 standard with config file support
disabled. This eliminates the config file keywords from the language and disabled. This eliminates the config file keywords from the language and
so helps some programs written to older 2001 support compile. so helps some programs written to older 2001 support compile.
@ -64,17 +64,27 @@ These flags affect the general behavior of the compiler.
support is ongoing. support is ongoing.
* 2012 * 2012
This flag enables the IEEE1800-2012 standard, which includes This flag enables the IEEE1800-2012 standard, which includes
SystemVerilog. 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 * verilog-ams
This flag enables Verilog-AMS features that are supported by Icarus This flag enables Verilog-AMS features that are supported by Icarus
Verilog. (This is new as of 5 May 2008.) Verilog. (This is new as of 5 May 2008.)
* assertions/supported-assertions/no-assertions * assertions/supported-assertions/no-assertions
Enable or disable SystemVerilog assertions. When enabled, assertion Enable or disable SystemVerilog assertions. When enabled, assertion
statements are elaborated. When disabled, assertion statements are parsed statements are elaborated. When disabled, assertion statements are parsed
but ignored. The supported-assertions option only enables assertions that but ignored. The supported-assertions option only enables assertions that
@ -131,6 +141,18 @@ These flags affect the general behavior of the compiler.
containing an unsized constant number, and unsized constant numbers are containing an unsized constant number, and unsized constant numbers are
not truncated to integer width. 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 * shared-loop-index/no-shared-loop-index
Enable or disable the exclusion of for-loop control variables from 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 -Wanachronisms
-Wimplicit -Wimplicit
-Wimplicit-dimensions -Wimplicit-dimensions
-Wdeclaration-after-use
-Wmacro-replacement -Wmacro-replacement
-Wportbind -Wportbind
-Wselect-range -Wselect-range
@ -278,7 +301,7 @@ These flags affect the general behavior of the compiler.
will print a warning at its first use. will print a warning at its first use.
* implicit-dimensions * implicit-dimensions
This enables warnings for the case where a port declaration or a var/net This enables warnings for the case where a port declaration or a var/net
declaration for the same name is missing dimensions. Normally, Verilog declaration for the same name is missing dimensions. Normally, Verilog
allows you to do this (the undecorated declaration gets its dimensions allows you to do this (the undecorated declaration gets its dimensions
@ -288,41 +311,50 @@ These flags affect the general behavior of the compiler.
This flag is supported in release 10.1 or master branch snapshots after This flag is supported in release 10.1 or master branch snapshots after
2016-02-06. 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 * macro-redefinition
This enables warnings when a macro is redefined, even if the macro text This enables warnings when a macro is redefined, even if the macro text
remains the same. remains the same.
NOTE: The "macro-redefinition" flag was added in v11.0. NOTE: The "macro-redefinition" flag was added in v11.0.
* macro-replacement * macro-replacement
This enables warnings when a macro is redefined and the macro text This enables warnings when a macro is redefined and the macro text
changes. Use no-macro-redefinition to disable this, changes. Use no-macro-redefinition to disable this,
NOTE: The "macro-replacement" flag was added in v11.0. NOTE: The "macro-replacement" flag was added in v11.0.
* portbind * portbind
This enables warnings for ports of module instantiations that are not This enables warnings for ports of module instantiations that are not
connected properly, but probably should be. Dangling input ports, for connected properly, but probably should be. Dangling input ports, for
example, will generate a warning. example, will generate a warning.
* select-range * select-range
This enables warnings for constant out-of-bound selects. This includes This enables warnings for constant out-of-bound selects. This includes
partial or fully out-of-bound select as well as a select containing a 'bx partial or fully out-of-bound select as well as a select containing a 'bx
or 'bz in the index. or 'bz in the index.
* timescale * timescale
This enables warnings for inconsistent use of the timescale directive. It This enables warnings for inconsistent use of the timescale directive. It
detects if some modules have no timescale, or if modules inherit timescale detects if some modules have no timescale, or if modules inherit timescale
from another file. Both probably mean that timescales are inconsistent, from another file. Both probably mean that timescales are inconsistent,
and simulation timing can be confusing and dependent on compilation order. and simulation timing can be confusing and dependent on compilation order.
* infloop * infloop
This enables warnings for always statements that may have runtime infinite This enables warnings for always statements that may have runtime infinite
loops (i.e. has paths with zero or no delay). This class of warnings is loops (i.e. has paths with zero or no delay). This class of warnings is
not included in -Wall and hence does not have a no- variant. A fatal error not included in -Wall and hence does not have a no- variant. A fatal error
@ -352,7 +384,7 @@ These flags affect the general behavior of the compiler.
is large. is large.
* floating-nets * floating-nets
This enables warnings for nets that are present but have no drivers. This enables warnings for nets that are present but have no drivers.
This flag was added in version 11.0 or later (and is in the master branch This flag was added in version 11.0 or later (and is in the master branch
@ -389,7 +421,7 @@ flags for the typical "C" compiler, so C programmers will find them familiar.
for other tools. For example, this command:: for other tools. For example, this command::
% iverilog -E -ofoo.v -DKEY=10 src1.v src2.v % iverilog -E -ofoo.v -DKEY=10 src1.v src2.v
runs the preprocessor on the source files src1.v and src2.v and produces the runs the preprocessor on the source files src1.v and src2.v and produces the
single output file foo.v that has all the preprocessing (including header single output file foo.v that has all the preprocessing (including header
includes and ifdefs) processed. includes and ifdefs) processed.
@ -421,7 +453,7 @@ Elaboration Flags
These are flags that pass information to the elaboration steps. These are flags that pass information to the elaboration steps.
* -P<symbol>=<value> * -P<symbol>=<value>
Define a parameter using the defparam behavior to override a parameter Define a parameter using the defparam behavior to override a parameter
values. This can only be used for parameters of root module instances. values. This can only be used for parameters of root module instances.

View File

@ -23,7 +23,7 @@ World program.
.. code-block:: verilog .. code-block:: verilog
module hello; module hello;
initial initial
begin begin
$display("Hello, World"); $display("Hello, World");
$finish ; $finish ;
@ -65,21 +65,21 @@ example, the counter model in counter.v
.. code-block:: verilog .. code-block:: verilog
module counter(output, clk, reset); module counter(out, clk, reset);
parameter WIDTH = 8; parameter WIDTH = 8;
output [WIDTH-1 : 0] output; output [WIDTH-1 : 0] out;
input clk, reset; input clk, reset;
reg [WIDTH-1 : 0] out; reg [WIDTH-1 : 0] out;
wire clk, reset; wire clk, reset;
always @(posedge clk or posedge reset) always @(posedge clk or posedge reset)
if (reset) if (reset)
output <= 0; out <= 0;
else else
output <= output + 1; out <= out + 1;
endmodule // counter endmodule // counter

View File

@ -0,0 +1,173 @@
Icarus Verilog Extensions
=========================
Icarus Verilog supports certain extensions to the baseline IEEE 1364
standard. Some of these are picked from extended variants of the
language, such as SystemVerilog, and some are expressions of internal
behavior of Icarus Verilog, made available as a tool debugging aid.
Don't use any of these extensions if you want to keep your code portable
across other Verilog compilers.
System Functions
----------------
``$is_signed(<expr>)``
^^^^^^^^^^^^^^^^^^^^^^
This function returns 1 if the expression contained is signed, or 0 otherwise.
This is mostly of use for compiler regression tests.
``$bits(<expr>)``, ``$sizeof(<expr>)``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The ``$bits`` system function returns the size in bits of the expression that
is its argument. The result of this function is undefined if the argument
doesn't have a self-determined size.
The ``$sizeof`` system function is deprecated in favour of ``$bits``, which is
the same thing, but included in the SystemVerilog definition.
``$simtime()``
^^^^^^^^^^^^^^
This returns as a 64bit value the simulation time, unscaled by the time units
of the local scope. This is different from the ``$time`` and ``$stime``
functions which return the scaled times. This function is added for regression
testing of the compiler and run time, but can be used by applications who
really want the simulation time.
Note that the simulation time can be confusing if there are lots of different
```timescales`` within a design. It is not in general possible to predict
what the simulation precision will turn out to be.
``$mti_random()``, ``$mti_dist_uniform``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
These functions are similar to the IEEE 1364 standard ``$random`` functions,
but they use the Mersenne Twister (MT19937) algorithm. This is considered an
excellent random number generator, but does not generate the same sequence as
the standardized ``$random``.
System Tasks
------------
``$readmempath``
^^^^^^^^^^^^^^^^
The ``$readmemb`` and ``$readmemh`` system tasks read text files that contain
data values to populate memories. Normally, those files are found in a current
working directory. The ``$readmempath()`` system task can be used to create a
search path for those files. For example:
.. code-block:: verilog
reg [7:0] mem [0:7];
initial begin
$readmemh("datafile.txt", mem);
end
This assumes that "datafile.txt" is in the current working directory where
the ``vvp`` command is running. But with the ``$readmempath``, one can specify
a search path:
.. code-block:: verilog
reg [7:0] mem [0:7];
initial begin
$readmempath(".:alternative:/global/defaults");
$readmemh("datafile.txt", mem);
end
In this example, "datafile.txt" is searched for in each of the directories
in the above list (separated by ":" characters). The first located instance
is the one that is used. So for example, if "./datafile.txt" exists, then it
is read instead of "/global/defaults/datafile.txt" even if the latter exists.
``$finish_and_return(code)``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This task operates the same as the ``$finish`` system task, but adds the
feature of specifying an exit code for the interpreter. This can be useful in
automated test environments to indicate whether the simulation finished with
or without errors.
Extended Verilog Data Types
---------------------------
This feature is turned on by the generation flag "-gxtypes" and turned
off by the generation flag "-gno-xtypes". It is turned on by default.
Icarus Verilog adds support for extended data types. This extended
type syntax is based on a proposal by Cadence Design Systems,
originally as an update to the IEEE 1364 standard. Icarus Verilog
currently only takes the new primitive types from the proposal.
SystemVerilog provides the same functionality using somewhat different
syntax. This extension is maintained for backwards compatibility.
- Types
Extended data types separates the concept of net/variable from the
data type. Both nets and variables can declared with any data
type. The primitive types available are::
logic - The familiar 0, 1, x and z, optionally with strength.
bool - Limited to only 0 and 1
real - 64-bit real values
Nets with logic type may have multiple drivers with strength, and the
value is resolved the usual way. Only logic values may be driven to
logic nets, so bool values driven onto logic nets are implicitly
converted to logic.
Nets with any other type may not have multiple drivers. The compiler
should detect the multiple drivers and report an error.
- Declarations
The declaration of a net is extended to include the type of the wire,
with the syntax::
wire <type> <wire-assignment-list>... ;
The <type>, if omitted, is taken to be logic. The "wire" can be any of
the net keywords. Wires can be logic, bool, real, or vectors of logic
or bool. Some valid examples::
wire real foo = 1.0;
tri logic bus[31:0];
wire bool addr[23:0];
... and so on.
The declarations of variables is similar. The "reg" keyword is used to
specify that this is a variable. Variables can have the same data
types as nets.
- Ports
Module and task ports in standard Verilog are restricted to logic
types. This extension removes that restriction, allowing any of
the above types to pass through the port consistent with the
continuous assignment connectivity that is implied by the type.
- Expressions
Expressions in the face of real values is covered by the baseline
Verilog standard.
The bool type supports the same operators as the logic type, with the
obvious differences imposed by the limited domain.
Comparison operators (not case compare) return logic if either of
their operands is logic. If both are bool or real (including mix of
bool and real) then the result is bool. This is because comparison of
bools and reals always return exactly true or false.
Case comparison returns bool. This differs from baseline Verilog,
which strictly speaking returns a logic, but only 0 or 1 values.
Arithmetic operators return real if either of their operands is real,
otherwise they return logic if either of their operands is logic. If
both operands are bool, they return bool.

View File

@ -0,0 +1,438 @@
Icarus Verilog Quirks
=====================
This is a list of known quirks that are presented by Icarus Verilog. The idea
of this chapter is to call out ways that Icarus Verilog differs from the
standard, or from other implementations.
This is NOT AN EXHAUSTIVE LIST. If something is missing from this list, let us
know and we can add documentation.
Unsized Numeric Constants are Not Limited to 32 Bits
----------------------------------------------------
The Verilog standard allows Verilog implementations to limit the size of
unsized constants to a bit width of at least 32. That means that a constant
17179869183 (``36'h3_ffff_ffff``) may overflow some compilers. In fact, it
is common to limit these values to 32 bits. However, a compiler may just as
easily choose another width limit, for example 64 bits. That value is
equally good.
However, it is not required that an implementation truncate at 32 bits, and
in fact Icarus Verilog does not truncate at all. It will make the unsized
constant as big as it needs to be to hold the value accurately. This is
especially useful in situations like this;
.. code-block:: verilog
reg [width-1:0] foo = 17179869183;
The programmer wants the constant to take on the width of the reg, which in
this example is parameterized. Since constant sizes cannot be parameterized,
the programmer ideally gives an unsized constant, which the compiler then
expands/contracts to match the l-value.
Also, by choosing to not ever truncate, Icarus Verilog can handle code written
for a 64 bit compiler as easily as for a 32 bit compiler. In particular, any
constants that the user does not expect to be arbitrarily truncated by their
compiler will also not be truncated by Icarus Verilog, no matter what that
other compiler chooses as a truncation point.
Unsized Expressions
-------------------
Icarus Verilog classes any expression containing an unsized numeric constant
or unsized parameter value that is not part of a self-determined operand as
an unsized expression. When calculating the bit width of an unsized expression,
it extends the width of the expression to avoid arithmetic overflow or
underflow; in other words, the expression width will be made large enough to
represent any possible arithmetic result of the expression. If the expression
contains operations that do not follow the normal rules of arithmetic (e.g. an
explicit or implicit cast between signed and unsigned values), the expression
width will be extended to at least the width of an integer.
An exception to the above is made if the expression contains a shift or power
operator with a right hand operand that is a non-constant unsized expression.
In this case any expansion of the expression width due to that operation is
limited to the width of an integer, to avoid excessive expression widths
(without this, an expression such as ``2**(i-1)``, where ``i`` is an integer,
would be expanded to 2\**33 bits).
The above behaviour is a deviation from the Verilog standard, which states
that when calculating an expression width, the width of an unsized constant
number is the same as the width of an integer. If you need strict standard
compliance (for compatibility with other EDA tools), then the compiler has
a command line option, ``-gstrict-expr-width``, which disables the special
treatment of unsized expressions. With this option, the compiler will output
a warning message if an unsized numeric constant is encountered that cannot
be represented in integer-width bits and will truncate the value.
If you are simulating synthesisable code, it is recommended that the
``-gstrict-expr-width`` option is used, as this eliminates a potential
source of synthesis vs. simulation mismatches.
Unsized Parameters
------------------
Icarus Verilog classes any parameter declaration that has no explicit or
implicit range specification as an unsized parameter declaration. When
calculating the bit width of the final value expression for the parameter,
it follows the same rules as it does for unsized expressions, regardless of
whether or not the expression contains any unsized numeric constants.
If the final value expression for an unsized parameter is an unsized
expression (i.e. does contain unsized numeric constants), any subsequent use
of that parameter will be treated as if it was an unsized numeric constant.
If not, it will be treated as if it was a numeric constant of the appropriate
size. For example, with the declarations:
.. code-block:: verilog
localparam Value1 = 'd3 + 'd2;
localparam Value2 = 2'd3 + 2'd2;
any subsequent use of ``Value1`` will be treated as if the programmer had
written ``'d5`` and any subsequent use of ``Value2`` will be treated as if
the programmer had written ``3'd5``. In particular, note that ``Value2`` can
be used as a concatenation operand, but ``Value1`` cannot.
The above behaviour is a deviation from the Verilog standard. As for
unsized expressions, if you need strict standard compliance. use the
``-gstrict-expr-width`` compiler option.
Unsized Expressions as Arguments to Concatenation
-------------------------------------------------
The Verilog standard clearly states in 4.1.14:
"Unsized constant numbers shall not be allowed in concatenations. This
is because the size of each operand in the concatenation is needed to
calculate the complete size of the concatenation."
So for example the expression ``{1'b0, 16}`` is clearly illegal. It also stands
to reason that ``{1'b0, 15+1}`` is illegal, for exactly the same justification.
What is the size of the expression (15+1)? Furthermore, it is reasonable to
expect that (16) and (15+1) are exactly the same so far as the compiler is
concerned.
Unfortunately, Cadence seems to feel otherwise. In particular, it has been
reported that although ``{1'b0, 16}`` causes an error, ``{1'b0, 15+1}`` is
accepted. Further testing shows that any expression other than a simple
unsized constant is accepted there, even if all the operands of all the
operators that make up the expression are unsized integers.
This is a semantic problem. Icarus Verilog doesn't limit the size of integer
constants. This is valid as stated in 2.5.1 Note 3:
"The number of bits that make up an unsized number (which is a simple
decimal number or a number without the size specification) shall be
**at least** 32." [emphasis added]
Icarus Verilog will hold any integer constant, so the size will be as large as
it needs to be, whether that is 64 bits, 128 bits, or more. With this in mind,
what is the value of these expressions?
.. code-block:: verilog
{'h1_00_00_00_00}
{'h1 << 32}
{'h0_00_00_00_01 << 32}
{'h5_00_00_00_00 + 1}
These examples show that the standard is justified in requiring that the
operands of concatenation have size. The dispute is what it takes to cause
an expression to have a size, and what that size is. Verilog-XL claims that
(16) does not have a size, but (15+1) does. The size of the expression (15+1)
is the size of the adder that is created, but how wide is the adder when
adding unsized constants?
One might note that the quote from section 4.1.14 says "Unsized constant
numbers shall not be allowed." It does not say "Unsized expressions...", so
arguably accepting (15+1) or even (16+0) as an operand to a concatenation is
not a violation of the letter of the law. However, the very next sentence of
the quote expresses the intent, and accepting (15+1) as having a more defined
size then (16) seems to be a violation of that intent.
Whatever a compiler decides the size is, the user has no way to predict it,
and the compiler should not have the right to treat (15+1) any differently
then (16). Therefore, Icarus Verilog takes the position that such expressions
are unsized and are not allowed as operands to concatenations. Icarus Verilog
will in general assume that operations on unsized numbers produce unsized
results. There are exceptions when the operator itself does define a size,
such as the comparison operators or the reduction operators. Icarus Verilog
will generate appropriate error messages.
Scope of Macro Defines Doesn't Extend into Libraries
----------------------------------------------------
Icarus Verilog does preprocess modules that are loaded from libraries via the
``-y`` mechanism to substitute macros and load includes. However, the only
macros defined during compilation of an automatically loaded library module
file are those that it defines itself (or includes) or that are defined on the
command line or in the command file. Specifically, macros defined in the non-
library source files are not remembered when the library module is loaded, and
macros defined in a library module do not escape into the rest of the design.
This is intentional. If it were otherwise, then compilation results might vary
depending on the order that libraries are loaded, and that is unacceptable.
For example, given sample library module ``a.v``:
.. code-block:: verilog
`define MACRO_A 1
module a(input x);
always @(x) $display("x=",x);
endmodule
and sample library module ``b.v``:
.. code-block:: verilog
module b(input y);
`ifdef MACRO_A
always @(y) $display("MACRO_A is defined",,y);
`else
always @(y) $display("MACRO_A is NOT defined",,y);
`endif
endmodule
If a program instantiates both of these modules, there is no way to know
which will be loaded first by the compiler, so if the definition of
``MACRO_A`` in ``a.v`` were to escape, then there is no way to predict or
control whether ``MACRO_A`` is defined when ``b.v`` is processed. So the
preprocessor processes automatic library module files as if they are in
their own compilation unit, and you can know that ``MACRO_A`` will not be
defined in ``b.v`` unless it is defined on the command line (a ``-D`` flag)
or in the command file (a ``+define+`` record.)
Of course if ``a.v`` and ``b.v`` were listed in the command file or on the
command line, then the situation is different; the order is clear. The files
are processed as if they were concatenated in the order that they are listed
on the command line. The non-library modules are all together in a main
compilation unit, and they are all processed before any library modules are
loaded.
It is said that some commercial compilers do allow macro definitions to span
library modules. That's just plain weird. However, there is a special case
that Icarus Verilog does handle. Preprocessor definitions that are made in
files explicitly listed on the command line or in the command file, do pass
into implicitly loaded library files. For example, given the source file
``x.v``:
.. code-block:: verilog
module main;
reg foo;
b dut(foo);
endmodule
`define MACRO_A
and the library module file ``b.v`` described above, the situation is well
defined, assuming the ``x.v`` file is listed on the command line or in the
command file. The library module will receive the ``MACRO_A`` definition
from the last explicitly loaded source file. The position of the define of
``MACRO_A`` in the explicitly loaded source files does not matter, as all
explicitly loaded source files are preprocessed before any library files
are loaded.
Continuous Assign L-Values Can Implicit-Define Wires
----------------------------------------------------
The IEEE 1364-2001 standard, Section 3.5, lists the cases where nets may be
implicitly created. These include:
- identifier is a module port
- identifier is passed as a port to a primitive or module
This does not seem to include continuous assignment l-values (or r-values)
so the standard does not justify allowing implicit declarations of nets by
continuous assignment.
However, it has been reported that many Verilog compilers, including the big
name tools, do allow this. So, Icarus Verilog will allow it as well, as an
extension. If ``-gxtypes`` (the default) is used, this extension is enabled.
To turn off this behavior, use the ``-gno-xtypes`` flag.
Dumping Array Words (``$dumpvars``)
-----------------------------------
Icarus has the ability to dump individual array words. They are only dumped
when explicitly passed to $dumpvars. They are not dumped by default. For
example given the following:
.. code-block:: verilog
module top;
reg [7:0] array [2:0];
initial begin
$dumpvars(0, array[0], array[1]);
...
end
endmodule
``array[0]`` and ``array[1]`` will be dumped whenever they change value. They
will be displayed as an escaped identifier and GTKWave fully supports this.
Note that this is an implicitly created escaped identifier that could conflict
with an explicitly created escaped identifier. You can automate adding the
array word by adding an index definition
.. code-block:: verilog
integer idx;
and replacing the previous $dumpvars statement with
.. code-block:: verilog
for (idx = 0; idx < 2; idx = idx + 1) $dumpvars(0, array[idx]);
This will produce the same results as the previous example, but it is much
easier to specify/change which elements are to be dumped. One important note
regarding this syntax. Most system tasks/functions keep the variable selection
(for this case it is a variable array word selection) context. If ``$dumpvars``
did this then all callback created would point to this element and would use
the same index which for the example above would have the value 2. This is
certainly not what is desired and for this special case when ``$dumpvars``
executes it uses the current index value to create a constant array selection
and that is monitored instead of the original variable selection.
Referencing Declarations Within an Unnamed Generate Block
---------------------------------------------------------
The IEEE 1364-2005 standard permits generate blocks to be unnamed, but states:
"If the generate block selected for instantiation is not named, it still
creates a scope; but the declarations within it cannot be referenced using
hierarchical names other than from within the hierarchy instantiated by the
generate block itself."
The standard later defines a scheme for automatically naming the unnamed
scopes for use with external interfaces.
Icarus Verilog implements the defined automatic naming scheme, but does not
prevent the automatically generated names being used in a hierarchical
reference. This behaviour is harmless - the automatically generated names are
guaranteed to be unique within the enclosing scope, so there is no possibility
of confusion with explicit scope names. However, to maintain code portability,
it is recommended that this behavior is not exploited.
``%g/%G`` Format Specifiers
---------------------------
In the IEEE 1364-2001 standard there is a general statement that the real
number format specifiers will use the full formatting capabilities of C.
This is then followed by an example that describes ``%10.3g``. The example
description would be correct for the ``%e`` format specifier which should
always have three fractional digits, but the ``%g`` format specifier does
not work that way. For it the ``.3`` specifies that there will be three
significant digits. What this means is that ``%g`` will always produce one
less significant digit than ``%e`` and will only match the output from ``%f``
for certain values. For example:
.. code-block:: verilog
module top_level;
real rval;
initial begin
rval = 1234567890;
$display("This is g and e: %10.3g, %10.3e.", rval, rval);
rval = 0.1234567890;
$display("This is g and f: %10.3g, %10.3f.", rval, rval);
rval = 1.234567890;
$display("This is more g and f: %10.3g, %10.3f.", rval, rval);
end
endmodule // top_level
will produce the following output:
.. code-block:: verilog
This is g and e: 1.23e+09, 1.235e+09.
This is g and f: 0.123, 0.123.
This is more g and f: 1.23, 1.235.
``%t`` Time Format Specifier Can Specify Width
----------------------------------------------
Standard Verilog does not allow width fields in the ``%t`` formats of display
strings. For example, this is illegal:
.. code-block:: verilog
$display("Time is %0t", $time);
Standard Verilog instead relies on the ``$timeformat`` to completely specify
the format.
Icarus Verilog allows the programmer to specify the field width. The ``%t``
format in Icarus Verilog works exactly as it does in standard Verilog.
However, if the programmer chooses to specify a minimum width (i.e., ``%5t``),
then for that display Icarus Verilog will override the ``$timeformat`` minimum
width and use the explicit minimum width.
``%v`` Format Specifier Can Display Vectors
-------------------------------------------
The IEEE 1364-2005 standard limits the ``%v`` specifier in display strings to
work only with a single bit. Icarus Verilog extends that to support displaying
the strength of vectors. The output is a strength specifier for each bit of the
vector, with underscore characters separating each bit, e.g. ``St0_St1_Pu1_HiZ``.
Most other tools will just print the strength of the least significant bit of
a vector, so this may give different output results for code that otherwise
works fine.
Assign/Deassign and Force/Release of Bit/Part Selects
-----------------------------------------------------
Icarus Verilog allows as an extension the assign/deassign and force/release
of variable bit and part selects in certain cases. This allows the Verilog
test bench writer to assign/deassign for example single bits of a variable
(register, etc.). Other tools will report this as an error.
``repeat`` Statement is Sign Aware
----------------------------------
The standard does not specify what to do for this case, but it does say what
a repeat event control should do. In Icarus Verilog the ``repeat`` statement
is consistent with the repeat event control definition. If the argument is
signed and is a negative value this will be treated the same as an argument
value of 0.
Built-in System Functions May Be Evaluated at Compile Time
----------------------------------------------------------
Certain of the system functions have well-defined meanings, so can
theoretically be evaluated at compile-time, instead of using runtime VPI
code. Doing so means that VPI cannot override the definitions of functions
handled in this manner. On the other hand, this makes them synthesizable,
and also allows for more aggressive constant propagation. The functions
handled in this manner are:
- ``$bits``
- ``$signed``
- ``$sizeof``
- ``$unsigned``
Implementations of these system functions in VPI modules will be ignored.
``vpiScope`` Iterator on ``vpiScope`` Objects
---------------------------------------------
In the VPI, the normal way to iterate over ``vpiScope`` objects contained
within a ``vpiScope`` object, is the ``vpiInternalScope`` iterator. Icarus
Verilog adds support for the ``vpiScope`` iterator of a ``vpiScope`` object,
that iterates over *everything* that is contained in the current scope. This
is useful in cases where one wants to iterate over all the objects in a scope
without iterating over all the contained types explicitly.
Time 0 Race Resolution
----------------------
Combinational logic is routinely modelled using always blocks. However, this
can lead to race conditions if the inputs to the combinational block are
initialized in initial statements. Icarus Verilog slightly modifies time 0
scheduling by arranging for always statements with ANYEDGE sensitivity lists
to be scheduled before any other threads. This causes combinational always
blocks to be triggered when the values in the sensitivity list are initialized
by initial threads.

View File

@ -2,8 +2,7 @@
Icarus Verilog Usage Icarus Verilog Usage
==================== ====================
This section contains documents to help support developers who contribute to This section contains documents to help support Icarus Verilog users.
Icarus Verilog.
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
@ -14,9 +13,13 @@ Icarus Verilog.
command_line_flags command_line_flags
command_files command_files
verilog_attributes verilog_attributes
ivlpp_flags
vvp_flags vvp_flags
gtkwave
vvp_debug vvp_debug
vvp_library
vhdlpp_flags
waveform_viewer
vpi vpi
ivl_target icarus_verilog_extensions
icarus_verilog_quirks
reporting_issues reporting_issues

View File

@ -2,34 +2,36 @@
Installation Guide Installation Guide
================== ==================
Icarus Verilog may be installed from source code, or from pre-packaged binary Icarus Verilog may be installed from source code (either from ``git`` or a
distributions. If you don't have need for the very latest, and prepackaged released `tar/zip` file), or from pre-packaged binary distributions. If you
binaries are available, that would be the best place to start. don't have a need for the very latest, and prepackaged binaries are available,
that is the easiest place to start.
Installation From Source Installation From Source
------------------------ ------------------------
Icarus is developed for Unix-like environments but can also be compiled on Icarus is developed for Unix-like environments but can also be compiled on
Windows systems using the Cygwin environment or MinGW compilers. The following Windows systems using the `Cygwin/MSYS2` environments or `MinGW` compilers. The
instructions are the common steps for obtaining the Icarus Verilog source, following instructions are the common steps for obtaining the Icarus Verilog
compiling and installing. Note that there are precompiled and/or prepackaged source code, compiling, installing, and checking the compiled code is working
versions for a variety of systems, so if you find an appropriate packaged properly. Note that there are pre-compiled and/or prepackaged versions for a
version, then that is the easiest way to install. variety of systems, so if you find an appropriate packaged version, then that
is the easiest way to install.
The source code for Icarus is stored under the git source code control The source code for Icarus is stored under the `git` source code control
system. You can use git to get the latest development head or the latest of a system. You can use ``git`` to get the latest development head or the latest of
specific branch. Stable releases are placed on branches, and in particular v11 a specific branch. Stable releases are placed on branches, and in particular V12
stable releases are on the branch "v11-branch" To get the development version stable releases are on the branch "v12-branch" To get the development version
of the code follow these steps:: of the code follow these steps::
% git config --global user.name "Your Name Goes Here" % git config --global user.name "Your Name Goes Here"
% git config --global user.email you@yourpublicemail.example.com % git config --global user.email you@yourpublicemail.example.com
% git clone https://github.com/steveicarus/iverilog.git % git clone https://github.com/steveicarus/iverilog.git
The first two lines are optional and are used to tell git who you are. This The first two lines are optional and are used to tell git who you are. This
information is important if/when you submit a patch. We suggest that you add information is important if/when you submit a patch. We suggest that you add
this information now so you don't forget to do it later. The clone will create this information now so you don't forget to do it later. The clone will create
a directory, named iverilog, containing the source tree, and will populate a directory, named `iverilog`, containing the source tree, and will populate
that directory with the most current source from the HEAD of the repository. that directory with the most current source from the HEAD of the repository.
Change into this directory using:: Change into this directory using::
@ -37,19 +39,26 @@ Change into this directory using::
% cd iverilog % cd iverilog
Normally, this is enough as you are now pointing at the most current Normally, this is enough as you are now pointing at the most current
development code, and you have implicitly created a branch "master" that development code, and you have implicitly created a branch `master` that
tracks the development head. However, If you want to actually be working on tracks the development head. However, If you want to actually be working on
the v11-branch (the branch where the latest v11 patches are) then you checkout the `v12-branch` (the branch where the latest V12 patches are) then you
that branch with the command:: checkout that branch with the command::
% git checkout --track -b v11-branch origin/v11-branch % git checkout --track -b v12-branch origin/v12-branch
This creates a local branch that tracks the v11-branch in the repository, and This creates a local branch that tracks the `v12-branch` in the repository, and
switches you over to your new v11-branch. The tracking is important as it switches you over to your new `v12-branch`. The tracking is important as it
causes pulls from the repository to re-merge your local branch with the remote causes pulls from the repository to re-merge your local branch with the remote
v11-branch. You always work on a local branch, then merge only when you `v12-branch`. You always work on a local branch, then merge only when you
push/pull from the remote repository. push/pull from the remote repository.
The choice between the development branch and the latest released branch
depends on your stability requirements. The released branch will only get bug
fixes. It will not get any enhancements or changes in the compiler output
format. Unlike many project the development branch is fairly stable with only
occasional periods of instability. We do most of our big changes in side
branches and only merge them into the development branch when they are clean.
Now that you've cloned the repository and optionally selected the branch you Now that you've cloned the repository and optionally selected the branch you
want to work on, your local source tree may later be synced up with the want to work on, your local source tree may later be synced up with the
development source by using the git command:: development source by using the git command::
@ -59,22 +68,33 @@ development source by using the git command::
The git system remembers the repository that it was cloned from, so you don't The git system remembers the repository that it was cloned from, so you don't
need to re-enter it when you pull. need to re-enter it when you pull.
Finally, configuration files are built by the extra step:: To build the `configure` script and hash files you need to run the
following::
% sh autoconf.sh % sh autoconf.sh
% cd ..
The source is then compiled as appropriate for your system. See the specific This is not need for the released `tar/zip` files since they already contain
build instructions below for your operation system for what to do next. these files. You only need to run this once after cloning. If you are missing
``autoconf`` or ``gperf`` then the script will fail::
You will need autoconf and gperf installed in order for the script to work. Autoconf in root...
If you get errors such as:: autoconf.sh: 10: autoconf: not found
Precompiling lexor_keyword.gperf
Autoconf in root...
autoconf.sh: 10: autoconf: not found
Precompiling lexor_keyword.gperf
autoconf.sh: 13: gperf: not found. autoconf.sh: 13: gperf: not found.
You will need to install download and install the autoconf and gperf tools. You will need to install the ``autoconf`` and ``gperf`` tools before you can
continue.
The other way to get the source code is to download a released `tar/zip` file::
% tar -xvzf v13_0.tar.gz
or
% unzip v13_0.zip
See the build instructions for your operation system below to know what to do
next. Though first determine if there are any extra configuration option you
may need.
Icarus Specific Configuration Options Icarus Specific Configuration Options
------------------------------------- -------------------------------------
@ -93,37 +113,215 @@ All programs or directories are tagged with this suffix. e.g.(iverilog-0.8,
vvp-0.8, etc.). The output of iverilog will reference the correct run time vvp-0.8, etc.). The output of iverilog will reference the correct run time
files and directories. The run time will check that it is running a file with files and directories. The run time will check that it is running a file with
a compatible version e.g.(you can not run a V0.9 file with the V0.8 run a compatible version e.g.(you can not run a V0.9 file with the V0.8 run
time). :: time).::
--with-valgrind --with-valgrind
This option adds extra memory cleanup code and pool management code to allow This option adds extra memory cleanup code and pool management code to allow
better memory leak checking when valgrind is available. This option is not better memory leak checking when valgrind is available. This option is not
need when checking for basic errors with valgrind. needed when checking for basic errors with valgrind and should not be used if
you just intend to use ``iverilog`` as a simulator. ::
--enable-libvvp
The vvp program is built as a small stub linked to a shared library,
libvvp.so, that may be linked with other programs so that they can host
a vvp simulation. ::
--enable-libveriuser
PLI version 1 (the ACC and TF routines) were deprecated in IEEE 1364-2005.
These are supported in Icarus Verilog by the libveriuser library and cadpli
module. Starting with V13, these will only be built if this option is used.
Compiling on Linux/Unix Compiling on Linux/Unix
----------------------- -----------------------
(Note: You will need to install bison, flex, g++ and gcc) This is probably the Note: For a gcc compile you will need to install ``bison``, ``flex``, ``g++``,
easiest case. Given that you have the source tree from the above instructions, ``gcc`` and preferably `bz2`, `zlib` and `readline` development packages. The
the compile and install is generally as simple as:: `bz2` and `zlib` development packages are required for the non-VCD waveform
dumpers and the `readline` development package is needed to enable better
terminal control in the ``vvp`` interactive mode.
% ./configure If you are only compiling one variant then you can compile directly in the
% make source tree. If you need multiple variants (optimized, debugging, multiple
(su to root) compilers) then it is recommended you compile each in their own directory.
# make install
The "make install" typically needs to be done as root so that it can install For multiple variants create a directory for each of the variants you intend
in directories such as "/usr/local/bin" etc. You can change where you want to to create and in each run the following steps, adjusting the options in the
install by passing a prefix to the "configure" command:: configure stage to get the functionality you want. For a single build you can
either build it with the source or in a separate build directory.
% ./configure --prefix=/my/special/directory The following is from a Ubuntu 22.04 machine using gcc (version 11.4)::
This will configure the source for eventual installation in the directory that % mkdir gcc
you specify. Note that "rpm" packages of binaries for Linux are typically % cd gcc
configured with "--prefix=/usr" per the Linux File System Standard. or
% cd iverilog
Make sure you have the latest version of flex otherwise you will get an error You can also use ``clang/clang++``. I usual build optimized version for
normal use and reserve debugging options for a valgrind or a separate
debugging build. Make sure you have `sudo` permission if you are using a
system prefix area, otherwise you need to use some place you have
permission to install (e.g. ~/).::
% env CFLAGS=-O2 CXXFLAGS=-O2 LDFLAGS=-s CC=gcc CXX=g++ ../iverilog/configure --enable-suffix=-gcc --prefix=/usr/local
This will generate the following (with some inline comments)::
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking for gcc... gcc
checking whether the C compiler works... yes
...
checking for gperf... gperf # required for git builds
checking for man... man # you likely want manual pages
checking for ps2pdf... ps2pdf
checking for groff... groff
checking for git... git # required for git builds
checking for flex... flex # required
checking for bison... bison # required
...
checking for tputs in -ltermcap... yes
checking for readline in -lreadline... yes
checking for add_history in -lreadline... yes
checking for readline/readline.h... yes
checking for readline/history.h... yes # you likely want this
...
checking for pthread_create in -lpthread... yes
checking for gzwrite in -lz... yes
checking for gzwrite in -lz... (cached) yes
checking for BZ2_bzdopen in -lbz2... yes
checking for BZ2_bzdopen in -lbz2... (cached) yes # you want these for fst dumping
...
<Create all the parameterized Makefile and header files>
Usually if ``configure`` fails there is some required dependency missing. I
usually review all the output to make sure it makes sense (e.g. I requested
``gcc`` and that's what is being used, other things match my expectation). If
all the waveform dumpers are not enabled there could be a few test failures.
Next we need to compile the code. Note: make sure you are using GNU make.
It may be named gmake (e.g. GhostBSD)::
% make check >& make.log
This is for a tcsh/csh shell. Bash/fish/zsh use ``&>`` instead of ``>&``.
Once this has completed check the make.log for any errors. There should not
be any! I also check for warnings. There are often some related to the
output from bison. For example::
From: ./parse.cc
parse.cc:9462:18: warning: missing initializer for member vlltype::lexical_pos [-Wmissing-field-initializers]
9462 | = { 1, 1, 1, 1 }
| ^
parse.cc:9462:18: warning: missing initializer for member vlltype::text [-Wmissing-field-initializers]
and::
From: ./vvp/parse.cc
parse.cc:3242: warning: suspicious sequence in the output: m4_type [-Wother]
parse.cc:3248: warning: suspicious sequence in the output: m4_type [-Wother]
Are common, but benign warnings. Different compilers or compiler versions may
have other warnings.
The expected last few lines of the make.log file and these indicate everything
should be working as expected are::
...
driver/iverilog -B. -BMvpi -BPivlpp -tcheck -ocheck.vvp ../iverilog/examples/hello.vl
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
Hello, World
If everything is good to this point and you are installing into a system
prefix; install using ``sudo`` as shown below. If you are installing into a
personal location skip the ``sudo``::
% sudo make install
Now you should verify the regression test suite is working as expected::
% cd ../iverilog/ivtest
% ./vvp_reg.pl --suffix=-gcc
This is the original test script and should give no failures::
Running compiler/VVP tests for Icarus Verilog version: 13, suffix: -gcc.
----------------------------------------------------------------------------
macro_with_args: Passed.
mcl1: Passed.
pr622: Passed.
pr639: Passed.
...
ssetclr2: Passed.
ssetclr3: Passed.
synth_if_no_else: Passed.
ufuncsynth1: Passed.
============================================================================
Test results:
Total=3018, Passed=3013, Failed=0, Not Implemented=2, Expected Fail=3
Next run the new test script::
% ./vvp_reg.py --suffix=-gcc
This should also give no failures::
Running compiler/VVP tests for Icarus Verilog version: 13, suffix: -gcc
Using list(s): regress-vvp.list
----------------------------------------------------------------------------
always4A: Passed - CE.
always4B: Passed - CE.
analog1: Not Implemented.
analog2: Not Implemented.
...
vvp_quiet_mode: Passed.
warn_opt_sys_tf: Passed - EF.
wreal: Passed.
writemem-invalid: Passed - EF.
============================================================================
Test results: Ran 284, Failed 0.
Finally you can check that the VPI is working properly using::
% ./vpi_reg.pl --suffix=-gcc
The output for this should have no failures::
Running VPI tests for Icarus Verilog version: 13, suffix: -gcc.
----------------------------------------------------------------------------
br_gh59: Passed.
br_gh73a: Passed.
br_gh73b: Passed.
br_gh117: Passed.
...
value_change_cb2: Passed.
value_change_cb3: Passed.
value_change_cb4: Passed.
vpi_control: Passed.
============================================================================
Test results: Total=77, Passed=77, Failed=0, Not Implemented=0
You can uninstall everything using the following. If needed skip the ``sudo``
as described in the install description above.::
% sudo make uninstall
You can cleanup the compile directory using::
% make clean
or
% make distclean
The first just cleans up just the compiled files, etc. The later cleans up
the compiled file along with all the files generated in the ``configure``
phase.
Note that "rpm" packages of binaries for Linux are typically configured with
"--prefix=/usr" per the Linux File System Standard.
Make sure you have a recent version of flex otherwise you will get an error
when parsing lexor.lex. when parsing lexor.lex.
Compiling on Macintosh OS X Compiling on Macintosh OS X
@ -144,3 +342,36 @@ be updated to version 3. ::
Icarus Verilog is also available through the Homebrew package manager: "brew Icarus Verilog is also available through the Homebrew package manager: "brew
install icarus-verilog". install icarus-verilog".
Cross-Compiling for Windows
---------------------------
The `Cygwin` and `MSYS2` environments can compile Icarus Verilog as described
above for `Linux/Unix`. There is a `MSYS2` build recipe which can be found in
the `msys2/` directory. The accompanying README file provides further details.
`MSYS2` is typically preferred over `Cygwin` since ``GTKWave`` and Icarus
Verilog are both provided as pre-compiled packages.
What follows are older instructions for building Icarus Verilog binaries for
Windows using mingw cross compiler tools on Linux.
To start with, you need the mingw64-cross-* packages for your linux
distribution, which gives you the x86_64-w64-mingw32-* commands
installed on your system. Installing the cross environment is outside
the scope of this writeup.
First, configure with this command::
$ ./configure --host=x86_64-w64-mingw32
This generates the Makefiles needed to cross compile everything with
the mingw32 compiler. The configure script will generate the command
name paths, so long as commands line x86_64-w64-mingw32-gcc
et. al. are in your path.
Next, compile with the command::
$ make
The configure generated the cross compiler flags. The
configure script should have gotten all that right.

View File

@ -1,23 +1,6 @@
Copyright (c) 1999 Stephen Williams (steve@icarus.com) IVLPP - IVL Preprocessor
========================
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.
THE IVL PREPROCESSOR
The ivlpp command is a Verilog preprocessor that handles file The ivlpp command is a Verilog preprocessor that handles file
inclusion and macro substitution. The program runs separate from the inclusion and macro substitution. The program runs separate from the
@ -33,49 +16,58 @@ The <file> parameter is the name of the file to be read and
preprocessed. The resulting output is sent to standard output. The preprocessed. The resulting output is sent to standard output. The
valid options include: valid options include:
-Dname[=value] * -Dname[=value]
Predefine the symbol ``name'' to have the specified
value. If the value is not specified, then ``1'' is Predefine the symbol `name` to have the specified
value. If the value is not specified, then `1` is
used. This is mostly of use for controlling conditional used. This is mostly of use for controlling conditional
compilation. compilation.
This option does *not* override existing `define This option does *not* override existing \`define
directives in the source file. directives in the source file.
-F <path> * -F <path>
Read ivlpp options from a FLAGS FILE. This is not the same Read ivlpp options from a FLAGS FILE. This is not the same
as a file list. This file contains flags, not source as a file list. This file contains flags, not source
files. There may be multiple flags files. files. There may be multiple flags files.
-f <path> * -f <path>
Read ivlpp input files from a file list. There can be no Read ivlpp input files from a file list. There can be no
more than one file list. more than one file list.
-I <dir> * -I <dir>
Add a directory to the include path. Normally, only "." is Add a directory to the include path. Normally, only "." is
in the search path. The -I flag causes other directories in the search path. The -I flag causes other directories
to be searched for a named file. There may be as many -I to be searched for a named file. There may be as many -I
flags as needed. flags as needed.
-L * -L
Generate `line directives. The ivl compiler understands
Generate \`line directives. The ivl compiler understands
these directives and uses them to keep track of the these directives and uses them to keep track of the
current line of the original source file. This makes error current line of the original source file. This makes error
messages more meaningful. messages more meaningful.
-o <file> * -o <file>
Send the output to the named file, instead of to standard Send the output to the named file, instead of to standard
output. output.
-v * -v
Print version and copyright information before processing Print version and copyright information before processing
input files. input files.
-V * -V
Print version and copyright information, then exit WITHOUT Print version and copyright information, then exit WITHOUT
processing any input files. processing any input files.
FLAGS FILE Flags File
----------
A flags file contains flags for use by ivlpp. This is a convenient way A flags file contains flags for use by ivlpp. This is a convenient way
for programs to pass complex sets of flags to the ivlpp program. for programs to pass complex sets of flags to the ivlpp program.
@ -84,44 +76,50 @@ Blank lines and lines that start with "#" are ignored. The latter can
be used as comment lines. All other lines are flag lines. Leading and be used as comment lines. All other lines are flag lines. Leading and
trailing white space are removed before the lines are interpreted. trailing white space are removed before the lines are interpreted.
Other lines have the simple format: Other lines have the simple format::
<key>:<value> <key>:<value>
The colon character separates a key from the value. The supported The colon character separates a key from the value. The supported
keys, with their corresponding values, are: keys, with their corresponding values, are:
D:name=<value> * D:name=<value>
This is exactly the same as the "-Dname=<value>" described above. This is exactly the same as the "-Dname=<value>" described above.
I:<dir> * I:<dir>
This is exactly the same as "-I<dir>". This is exactly the same as "-I<dir>".
relative include:<flag> * relative include:<flag>
The <flag> can be "true" or "false". This enables "relative The <flag> can be "true" or "false". This enables "relative
includes" nesting behavior. includes" nesting behavior.
vhdlpp:<path> * vhdlpp:<path>
Give the path to the vhdlpp program. This program is used to Give the path to the vhdlpp program. This program is used to
process VHDL input files. process VHDL input files.
LOCATING INCLUDED FILES Locating Included Files
-----------------------
The ivlpp preprocessor implements the `include directives by The ivlpp preprocessor implements the \`include directives by
substituting the contents of the included file in place of the line substituting the contents of the included file in place of the line
with the `include directive. The name that the programmer specifies is with the \`include directive. The name that the programmer specifies is
a file name. Normally, the preprocessor looks in the current working a file name. Normally, the preprocessor looks in the current working
directory for the named file. However, the ``-I'' flags can be used to directory for the named file. However, the `-I` flags can be used to
specify a path of directories to search for named include files. The specify a path of directories to search for named include files. The
current directory will be searched first, followed by all the include current directory will be searched first, followed by all the include
directories in the order that the -I flag appears. directories in the order that the -I flag appears.
The exception to this process is include files that have a name that The exception to this process is include files that have a name that
starts with the '/' character. These file names are ``rooted names'' starts with the '/' character. These file names are `rooted names`
and must be in the rooted location specified. and must be in the rooted location specified.
GENERATED LINE DIRECTIVES Generated Line Directives
-------------------------
Compilers generally try to print along with their error messages the Compilers generally try to print along with their error messages the
file and line number where the error occurred. Icarus Verilog is no file and line number where the error occurred. Icarus Verilog is no
@ -130,19 +128,19 @@ and opening files, then the line numbers counted by the compiler
proper will not reflect the actual line numbers in the source file. proper will not reflect the actual line numbers in the source file.
To handle this situation, the preprocessor can generate line To handle this situation, the preprocessor can generate line
directives. These directives are lines of the form: directives. These directives are lines of the form::
`line <num> <name> <level> `line <num> <name> <level>
where <name> is the file name in double-quotes and <num> is the line where <name> is the file name in double-quotes and <num> is the line
number in the file. The parser changes the filename and line number number in the file. The parser changes the filename and line number
counters in such a way that the next line is line number <num> in counters in such a way that the next line is line number <num> in
the file named <name>. For example: the file named <name>. For example::
`line 6 "foo.vl" 0 `line 6 "foo.vl" 0
// I am on line 6 in file foo.vl. // I am on line 6 in file foo.vl.
The preprocessor generates a `line directive every time it switches The preprocessor generates a \`line directive every time it switches
files. That includes starting an included file (`line 1 "foo.vlh" 1) or files. That includes starting an included file (\`line 1 "foo.vlh" 1) or
returning to the including file. returning to the including file.

View File

@ -2,25 +2,43 @@
Reporting Issues 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 issues and to create patches for the product. If you believe you have found a
problem, use the Issues tracker at the problem, use the Issues tracker at the
`Icarus Verilog github page <https://github.com/steveicarus/iverilog>`_. `Icarus Verilog github page <https://github.com/steveicarus/iverilog>`__.
You may browse the bugs database for existing
bugs that may be related to yours. You might find that your bug has
already been fixed in a later release or snapshot. If that's the case,
then you are set.
On the main page, you will find a row of selections near the top. Click the On the main page, you will find a row of selections near the top. Click the
`Issues <https://github.com/steveicarus/iverilog/issues>`_ link to get to the `Issues <https://github.com/steveicarus/iverilog/issues>`__ link to get to the
list of issues, open and closed. You will find a friendly green button where list of issues, open and closed. You will find a friendly green button where
you can create a new issue. You will be asked to create a title for your you can create a new issue. You will be asked to create a title for your
issue, and to write a detailed description of your issue. Please include issue, and to write a detailed description of your issue. Please include
enough information that anyone who sees your issue can understand and enough information that anyone who sees your issue can understand and
reproduce it. reproduce it.
Good Issue Reporting
--------------------
Before an error can be fixed, one needs to understand what the problem
is. Try to explain what is wrong and why you think it is wrong. Please
try to include sample code that demonstrates the problem.
One key characteristic of a well reported issue is a small sample program that One key characteristic of a well reported issue is a small sample program that
demonstrates the issue. The smaller the better. No developer wants to wade demonstrates the issue. The smaller the better. No developer wants to wade
through hundreds of lines of working Verilog to find the few lines that cause through hundreds of lines of working Verilog to find the few lines that cause
trouble, so if you can get it down to a 10 line sample program, then your trouble, so if you can get it down to a 10 line sample program, then your
issue will be far more likely to be addressed. issue will be far more likely to be addressed.
Also, include the command line you use to invoke the compiler. For
example::
iverilog -o foo.out -tvvp foo.v
iverilog foo.vl -s starthere
Be prepared to have a conversation about your issue. More often then you would Be prepared to have a conversation about your issue. More often then you would
expect, the issue turns out to be a bug in your program, and the person expect, the issue turns out to be a bug in your program, and the person
looking into your issue may point out a bug in your code. You learn something, looking into your issue may point out a bug in your code. You learn something,
@ -35,3 +53,24 @@ the regression test suite to see how they are structured. If you have a
complete test that can go into the test suite, then that saves everyone a lot complete test that can go into the test suite, then that saves everyone a lot
of grief, and again you increase the odds that your issue will be addressed. of grief, and again you increase the odds that your issue will be addressed.
How To Create A Pull Request
----------------------------
Bug reports with patches/PRs are very welcome. Please also add a new test case in the regression test suite to prevent the bug from reappearing.
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 Contributor <getting_started>` .
COPYRIGHT ISSUES
Icarus Verilog is Copyright (c) 1998-2024 Stephen Williams except
where otherwise noted. Minor patches are covered as derivative works
(or editorial comment or whatever the appropriate legal term is) and
folded into the rest of ivl. However, if a submission can reasonably
be considered independently copyrightable, it's yours and I encourage
you to claim it with appropriate copyright notices. This submission
then falls under the "otherwise noted" category.
I must insist that any copyright material submitted for inclusion
include the GPL license notice as shown in the rest of the source.

View File

@ -295,8 +295,8 @@ Consider this running example of a square root calculator
bitl = 15; bitl = 15;
end end
endtask endtask
initial clear; initial clear;
always @(reset or posedge clk) always @(reset or posedge clk)
if (reset) if (reset)
@ -373,7 +373,7 @@ be modified as follows
module main; module main;
reg clk, reset; reg clk, reset;
reg [31:0] x; reg [31:0] x;
reg [31:0] z; reg [31:0] z;
wire [15:0] y1,y2; wire [15:0] y1,y2;
wire rdy1,rdy2; wire rdy1,rdy2;

View File

@ -13,7 +13,7 @@ Optimizations
------------- -------------
* ivl_do_not_elide (snapshot 20140619 or later) * ivl_do_not_elide (snapshot 20140619 or later)
This applies to signals (i.e. reg, wire, etc.) and tells the optimizer to This applies to signals (i.e. reg, wire, etc.) and tells the optimizer to
not elide the signal, even if it is not referenced anywhere in the not elide the signal, even if it is not referenced anywhere in the
design. This is useful if the signal is for some reason only accessed by design. This is useful if the signal is for some reason only accessed by
@ -23,13 +23,13 @@ Synthesis
--------- ---------
* ivl_synthesis_cell * ivl_synthesis_cell
Applied to a module definition, this tells the synthesizer that the module Applied to a module definition, this tells the synthesizer that the module
is a cell. The synthesizer does not descend into synthesis cells, as they is a cell. The synthesizer does not descend into synthesis cells, as they
are assumed to be primitives in the target technology. are assumed to be primitives in the target technology.
* ivl_synthesis_off * ivl_synthesis_off
Attached to an "always" statement, this tells the synthesizer that the Attached to an "always" statement, this tells the synthesizer that the
statement is not to be synthesized. This may be useful, for example, to tell statement is not to be synthesized. This may be useful, for example, to tell
the compiler that a stretch of code is test-bench code. the compiler that a stretch of code is test-bench code.

View File

@ -1,34 +1,41 @@
vhdlpp COMMAND LINE FLAGS: vhdlpp Command Line Flags
=========================
* -D <token>
-D <token>
Debug flags. The token can be: Debug flags. The token can be:
* yydebug | no-yydebug * yydebug | no-yydebug
* entities=<path> * entities=<path>
-L <path> * -L <path>
Library path. Add the directory name to the front of the library Library path. Add the directory name to the front of the library
search path. The library search path is initially empty. search path. The library search path is initially empty.
-V * -V
Display version on stdout Display version on stdout
-v * -v
Verbose: Display version on stderr, and enable verbose messages to Verbose: Display version on stderr, and enable verbose messages to
stderr. stderr.
-w <path> * -w <path>
Work path. This is the directory where the working directory is. Work path. This is the directory where the working directory is.
LIBRARY FORMAT: Library Format
--------------
The vhdlpp program stores libraries as directory that contain The vhdlpp program stores libraries as directory that contain
packages. The name of the directory (in lower case) is the name of the packages. The name of the directory (in lower case) is the name of the
library as used on the "import" statement. Within that library, there library as used on the "import" statement. Within that library, there
are packages in files named <foo>.pkg. For example: are packages in files named <foo>.pkg. For example::
<directory>/... <directory>/...
sample/... sample/...
@ -39,14 +46,14 @@ are packages in files named <foo>.pkg. For example:
Use the "+vhdl-libdir+<directory>" record in a config file to tell Use the "+vhdl-libdir+<directory>" record in a config file to tell
Icarus Verilog that <directory> is a place to look for libraries. Then Icarus Verilog that <directory> is a place to look for libraries. Then
in your VHDL code, access packages like this: in your VHDL code, access packages like this::
library sample; library sample;
library bar; library bar;
use sample.test1.all; use sample.test1.all;
use bar.test3.all; use bar.test3.all;
The *.pkg files are just VHDL code containing only the package with The \*.pkg files are just VHDL code containing only the package with
the same name. When Icarus Verilog encounters the "use <lib>.<name>.*;" the same name. When Icarus Verilog encounters the "use <lib>.<name>.*;"
statement, it looks for the <name>.pkg file in the <lib> library and statement, it looks for the <name>.pkg file in the <lib> library and
parses that file to get the package header declared therein. parses that file to get the package header declared therein.

View File

@ -42,7 +42,7 @@ module, is a null terminated table of function pointers. The simulator calls
each of the functions in the table in order. The following simple C definition each of the functions in the table in order. The following simple C definition
defines a sample table:: defines a sample table::
void (*vlog_startup_routines[])() = { void (*vlog_startup_routines[])(void) = {
hello_register, hello_register,
0 0
}; };
@ -89,16 +89,18 @@ file hello.c::
static int hello_compiletf(char*user_data) static int hello_compiletf(char*user_data)
{ {
(void)user_data; // Avoid a warning since user_data is not used.
return 0; return 0;
} }
static int hello_calltf(char*user_data) static int hello_calltf(char*user_data)
{ {
(void)user_data; // Avoid a warning since user_data is not used.
vpi_printf("Hello, World!\n"); vpi_printf("Hello, World!\n");
return 0; return 0;
} }
void hello_register() void hello_register(void)
{ {
s_vpi_systf_data tf_data; s_vpi_systf_data tf_data;
@ -111,7 +113,7 @@ file hello.c::
vpi_register_systf(&tf_data); vpi_register_systf(&tf_data);
} }
void (*vlog_startup_routines[])() = { void (*vlog_startup_routines[])(void) = {
hello_register, hello_register,
0 0
}; };

View File

@ -1,4 +1,4 @@
Vvp Interactive Mode VVP Interactive Mode
==================== ====================
The vvp command has an interactive debug mode, where you can stop the The vvp command has an interactive debug mode, where you can stop the
@ -78,7 +78,7 @@ terminal interrupt and drops you into the interactive prompt::
^C** VVP Stop(0) ** ^C** VVP Stop(0) **
** Flushing output streams. ** Flushing output streams.
** Current simulation time is 533928600 ticks. ** Current simulation time is 533928600 ticks.
> >
This could be useful if you suspect that your simulation is stuck in This could be useful if you suspect that your simulation is stuck in
an infinite loop and you want to rummage around and see what's going on. an infinite loop and you want to rummage around and see what's going on.

View File

@ -14,6 +14,10 @@ These options/flags go before the path to the vvp-executable program. They
effect behavior of the vvp runtime engine, including preparation for effect behavior of the vvp runtime engine, including preparation for
simulation. simulation.
* -i
This flag causes all output to <stdout> to be unbuffered.
* -l<logfile> * -l<logfile>
This flag specifies a logfile where all MCI <stdlog> output goes. Specify This flag specifies a logfile where all MCI <stdlog> output goes. Specify
@ -41,6 +45,25 @@ simulation.
determine the return types of user-defined system functions. If specified at determine the return types of user-defined system functions. If specified at
compile-time, there is no need to specify them again here. compile-time, there is no need to specify them again here.
* -n
This flag makes $stop or a <Control\-C> a synonym for $finish. It can be
used to give the program a more meaningful interface when running in a
non-interactive environment.
* -N
This flag does the same thing as "-n", but results in an exit code of 1
if the stimulation calls $stop. It can be used to indicate a simulation
failure when running a testbench.
* -q
Enable quiet mode. This suppresses all output to <stdout> sent via MCD
bit 0 (e.g. all output from $display and friends). It does not affect
output to the log file, nor does it affect output to <stdout> sent via
the STDOUT file descriptor.
* -s * -s
$stop right away, in the beginning of the simulation. This kicks the $stop right away, in the beginning of the simulation. This kicks the
@ -51,6 +74,10 @@ simulation.
Show verbose progress while setting up or cleaning up the runtime Show verbose progress while setting up or cleaning up the runtime
engine. This also displays some performance information. engine. This also displays some performance information.
* -V
Print the version of the runtime, and exit.
Extended Arguments Extended Arguments
------------------ ------------------
@ -59,6 +86,9 @@ system tasks, system functions and any VPI/PLI code. Extended arguments that
start with a "+" character are left for use by the user via the $plus$flag and start with a "+" character are left for use by the user via the $plus$flag and
$plus$value functions. $plus$value functions.
NOTE: The extended arguments must appear *after* the input file name on the
command line.
VCD/FST/LXT Arguments VCD/FST/LXT Arguments
^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
@ -73,15 +103,22 @@ behavior.
synonyms for turning of dumping. synonyms for turning of dumping.
* -fst * -fst
Generate FST format outputs instead of VCD format waveform dumps. This is Generate FST format outputs instead of VCD format waveform dumps. This is
the preferred output format if using GTKWave for viewing waveforms. the preferred output format if using GTKWave or Surfer for viewing waveforms.
* -lxt/-lxt2 * -lxt/-lxt2
Generate LXT or LXT2format instead of VCD format waveform dumps. The LXT2 Generate LXT or LXT2format instead of VCD format waveform dumps. The LXT2
format is more advanced. format is more advanced.
* -dumpfile=<name>
Set the default dumpfile. If unspecified, the default is "dump". This
command line flag allows you do change it. If no suffix is specified,
then the suffix will be chosen based on the dump type. In any case, the
$dumpfile system task overrides this flag.
SDF Support SDF Support
^^^^^^^^^^^ ^^^^^^^^^^^
@ -89,15 +126,15 @@ The Icarus Verilog support for SDF back-annotation can take some extended
arguments to control aspects of SDF support. arguments to control aspects of SDF support.
* -sdf-warn * -sdf-warn
Print warnings during load of/annotation from an SDF file. Print warnings during load of/annotation from an SDF file.
* -sdf-info * -sdf-info
Print interesting information about an SDF file while parsing it. Print interesting information about an SDF file while parsing it.
* -sdf-verbose * -sdf-verbose
Print warnings and info messages. Print warnings and info messages.
Environment Variables Environment Variables
@ -106,4 +143,3 @@ Environment Variables
The vvp program pays attention to certain environment variables. The vvp program pays attention to certain environment variables.
* IVERILOG_DUMPER * IVERILOG_DUMPER

View File

@ -0,0 +1,29 @@
VVP as a library
================
If configured with ::
--enable-libvvp
the vvp program will be built as a small stub that
depends on a shared library, libvvp.so.
The library may also be used to include a vvp simulation
in a larger program. Typically, the simulation communicates
with its host program using VPI, but since
almost all the functions of vvp are included in the library
it may be possible to use text output and interactive mode.
The accessible functions of the library are defined and documented
in the header file, vvp/libvvp.h. Although vvp is a C++ program, the
header file presents a C interface.
Note that the vvp software was not designed to be used this way
and the library is a straightforward recompilation of the program code.
That imposes some restrictions, mostly arising from the use
of static variables: only a single run of a single simulation instance
can be expected to work without special actions.
To mitigate these restrictions, the library may by loaded dynamically
and unloaded at the end of each simulation run.
Parallel simulation should be possible by making multiple copies
of the library with different names.

View File

@ -1,22 +1,32 @@
Viewing Waveforms
=================
Waveforms With GTKWave To view waveforms, either GTKWave or Surfer can be used.
======================
GTKWave is a VCD waveform viewer based on the GTK library. This viewer support GTKWave is a waveform viewer based on the GTK library. This viewer supports
VCD and LXT formats for signal dumps. GTKWAVE is available on github VCD, FST, LXT, and LXT2 formats for waveform dumps. GTKWave is available on GitHub
`here <https://github.com/gtkwave/gtkwave>`_. Most Linux distributions already `here <https://github.com/gtkwave/gtkwave>`__. Most Linux distributions already
include gtkwave prepackaged. include gtkwave prepackaged and there are binaries for Windows available.
.. image:: GTKWave_Example2.png .. image:: GTKWave_Example2.png
Generating VCD/FST files for GTKWAVE ------------------------------------ Surfer is a waveform viewer based on the Rust egui library. This viewer supports
VCD and FST formats for waveform dumps. Surfer is available on GitLab
`here <https://gitlab.com/surfer-project/surfer>`__. It runs on Windows, Linux,
and MacOS, but can also run in a `web browser <https://app.surfer-project.org/>`__
and there is a VS Code
`extension <https://marketplace.visualstudio.com/items?itemName=surfer-project.surfer>`__.
Generating waveform dump files for viewing
------------------------------------------
Waveform dumps are written by the Icarus Verilog runtime program vvp. The user Waveform dumps are written by the Icarus Verilog runtime program vvp. The user
uses $dumpfile and $dumpvars system tasks to enable waveform dumping, then the uses $dumpfile and $dumpvars system tasks to enable waveform dumping, then the
vvp runtime takes care of the rest. The output is written into the file vvp runtime takes care of the rest. The output is written into the file
specified by the $dumpfile system task. If the $dumpfile call is absent, the specified by the $dumpfile system task. If the $dumpfile call is absent, the
compiler will choose the file name dump.vcd or dump.lxt or dump.fst, depending compiler will choose the file name dump.vcd, dump.lxt, dump.lxt2, or dump.fst,
on runtime flags. The example below dumps everything in and below the test depending on runtime flags. The example below dumps everything in and below
module: the test module:
.. code-block:: verilog .. code-block:: verilog
@ -30,9 +40,9 @@ module:
By default, the vvp runtime will generate VCD dump output. This is the default By default, the vvp runtime will generate VCD dump output. This is the default
because it is the most portable. However, when using gtkwave, the FST output because it is the most portable. However, when using gtkwave, the FST output
format is faster and most compact. Use the "-fst" extended argument to format is faster and most compact. Use the "-fst", "-lxt", or "-lxt2" extended
activate LXT output. For example, if your compiled output is written into the argument to activate FST, LXT, or LXT2 output, respectively. For example, if
file "foo.vvp", the command: your compiled output is written into the file "foo.vvp", the command:
.. code-block:: console .. code-block:: console
@ -40,7 +50,7 @@ file "foo.vvp", the command:
will cause the dumpfile output to be written in FST format. Absent any will cause the dumpfile output to be written in FST format. Absent any
specific $dumpfile command, this file will be called dump.fst, which can be specific $dumpfile command, this file will be called dump.fst, which can be
viewed with the command: viewed with GTKWave using the command:
.. code-block:: console .. code-block:: console
@ -105,7 +115,7 @@ Then the simulation file:
$time, value, value); $time, value, value);
endmodule // test endmodule // test
Compile, run, and view waveforms with these commands: Compile, run, and view waveforms with GTKWave using these commands:
.. code-block:: console .. code-block:: console
@ -113,6 +123,6 @@ Compile, run, and view waveforms with these commands:
% vvp dsn % vvp dsn
% gtkwave test.vcd & % gtkwave test.vcd &
Click on the 'test', then 'c1' in the top left box on GTKWAVE, then drag the Click on the 'test', then 'c1' in the top left box of GTKWave, then drag the
signals to the Signals box. You will be able to add signals to display, signals to the Signals box. You will be able to add signals to display,
scanning by scope. scanning by scope.

182
INSTALL
View File

@ -1,52 +1,59 @@
Basic Installation Basic Installation
================== ==================
These are generic installation instructions. These are generic installation instructions, with minor updates
for the `iverilog` project.
The `configure' shell script attempts to guess correct values for Instructions in the `README` are more concise for this project.
The `configure` shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package. those values to create a `Makefile` in each directory of the package.
It may also create one or more `.h' files containing system-dependent It may also create one or more `.h` files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that definitions. Finally, it creates a shell script `config.status` that
you can run in the future to recreate the current configuration, a file you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up `config.cache` that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output reconfiguring, and a file `config.log` containing compiler output
(useful mainly for debugging `configure'). (useful mainly for debugging `configure`).
If you need to do unusual things to compile the package, please try If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail to figure out how `configure` could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can diffs or instructions to the address given in the `README` so they can
be considered for the next release. If at some point `config.cache' be considered for the next release. If at some point `config.cache`
contains results you don't want to keep, you may remove or edit it. contains results you don't want to keep, you may remove or edit it.
The file `configure.ac' is used to create `configure' by a program The file `configure.ac` is used to create `configure` by a program
called `autoconf'. You only need `configure.ac' if you want to change called `autoconf`. You only need `configure.ac` if you want to change
it or regenerate `configure' using a newer version of `autoconf'. it or regenerate `configure` using a newer version of `autoconf`.
The simplest way to compile this package is: The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type 1. `cd` to the directory containing the package's source code.
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some 2. Run `sh autoconf.sh`, if building from source (and not a release).
If you're building from a release, skip this step.
3. Run `./configure` to configure the package for your system. If you're
using `csh` on an old version of System V, you might need to type
`sh ./configure` instead to prevent `csh` from trying to execute
`configure` itself.
Running `configure` takes awhile. While running, it prints some
messages telling which features it is checking for. messages telling which features it is checking for.
2. Type `make' to compile the package. 4. Type `make` to compile the package.
3. Optionally, type `make check' to run any self-tests that come with 5. Optionally, type `make check` to run any self-tests that come with
the package. the package.
4. Type `make install' to install the programs and any data files and 6. Type `make install` to install the programs and any data files and
documentation. documentation. You may need to use `sudo`.
5. You can remove the program binaries and object files from the 7. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the source code directory by typing `make clean`. To also remove the
files that `configure' created (so you can compile the package for files that `configure` created (so you can compile the package for
a different kind of computer), type `make distclean'. There is a different kind of computer), type `make distclean`. There is
also a `make maintainer-clean' target, but that is intended mainly also a `make maintainer-clean` target, but that is intended mainly
for the package's developers. If you use it, you may have to get for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came all sorts of other programs in order to regenerate files that came
with the distribution. with the distribution.
@ -55,126 +62,131 @@ Compilers and Options
===================== =====================
Some systems require unusual options for compilation or linking that Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure' the `configure` script does not know about. You can give `configure`
initial values for variables by setting them in the environment. Using initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like a Bourne-compatible shell, you can do that on the command line like
this: this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this: ```bash
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
```
Or on systems that have the `env` program, you can do it like this:
```bash
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
```
Compiling For Multiple Architectures Compiling For Multiple Architectures
==================================== ====================================
You can compile the package for more than one kind of computer at the You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that own directory. To do this, you must use a version of `make` that
supports the `VPATH' variable, such as GNU `make'. `cd' to the supports the `VPATH` variable, such as GNU `make`. `cd` to the
directory where you want the object files and executables to go and run directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the the `configure` script. `configure` automatically checks for the
source code in the directory that `configure' is in and in `..'. source code in the directory that `configure` is in and in `..`.
If you have to use a `make' that does not supports the `VPATH' If you have to use a `make` that does not supports the `VPATH`
variable, you have to compile the package for one architecture at a time variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another one architecture, use `make distclean` before reconfiguring for another
architecture. architecture.
Installation Names Installation Names
================== ==================
By default, `make install' will install the package's files in By default, `make install` will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an `/usr/local/bin`, `/usr/local/man`, etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the installation prefix other than `/usr/local` by giving `configure` the
option `--prefix=PATH'. option `--prefix=PATH`.
You can specify separate installation prefixes for You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use give `configure` the option `--exec-prefix=PATH`, the package will use
PATH as the prefix for installing programs and libraries. PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix. Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular options like `--bindir=PATH` to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories kinds of files. Run `configure --help` for a list of the directories
you can set and what kinds of files go in them. you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the with an extra prefix or suffix on their names by giving `configure` the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. option `--program-prefix=PREFIX` or `--program-suffix=SUFFIX`.
Optional Features Optional Features
================= =================
Some packages pay attention to `--enable-FEATURE' options to Some packages pay attention to `--enable-FEATURE` options to
`configure', where FEATURE indicates an optional part of the package. `configure`, where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE They may also pay attention to `--with-PACKAGE` options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The is something like `gnu-as` or `x` (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the `README` should mention any `--enable-` and `--with-` options that the
package recognizes. package recognizes.
For packages that use the X Window System, `configure' can usually For packages that use the X Window System, `configure` can usually
find the X include and library files automatically, but if it doesn't, find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and you can use the `configure` options `--x-includes=DIR` and
`--x-libraries=DIR' to specify their locations. `--x-libraries=DIR` to specify their locations.
Specifying the System Type Specifying the System Type
========================== ==========================
There may be some features `configure' can not figure out There may be some features `configure` can not figure out
automatically, but needs to determine by the type of host the package automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints will run on. Usually `configure` can figure that out, but if it prints
a message saying it can not guess the host type, give it the a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system `--host=TYPE` option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields: type, such as `sun4`, or a canonical name with three fields:
CPU-COMPANY-SYSTEM `CPU-COMPANY-SYSTEM`
See the file `config.sub' for the possible values of each field. If See the file `config.sub` for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't `config.sub` isn't included in this package, then this package doesn't
need to know the host type. need to know the host type.
If you are building compiler tools for cross-compiling, you can also If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will use the `--target=TYPE` option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of produce code for and the `--build=TYPE` option to select the type of
system on which you are compiling the package. system on which you are compiling the package.
Sharing Defaults Sharing Defaults
================ ================
If you want to set default values for `configure' scripts to share, If you want to set default values for `configure` scripts to share,
you can create a site shell script called `config.site' that gives you can create a site shell script called `config.site` that gives
default values for variables like `CC', `cache_file', and `prefix'. default values for variables like `CC`, `cache_file`, and `prefix`.
`configure' looks for `PREFIX/share/config.site' if it exists, then `configure` looks for `PREFIX/share/config.site` if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the `PREFIX/etc/config.site` if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script. `CONFIG_SITE` environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script. A warning: not all `configure` scripts look for a site script.
Operation Controls Operation Controls
================== ==================
`configure' recognizes the following options to control how it `configure` recognizes the following options to control how it
operates. operates.
`--cache-file=FILE' `--cache-file=FILE`
Use and save the results of the tests in FILE instead of Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for `./config.cache`. Set FILE to `/dev/null` to disable caching, for
debugging `configure'. debugging `configure`.
`--help' `--help`
Print a summary of the options to `configure', and exit. Print a summary of the options to `configure`, and exit.
`--quiet' `--quiet`
`--silent' `--silent`
`-q' `-q`
Do not print messages saying which checks are being made. Do not print messages saying which checks are being made.
`--srcdir=DIR' `--srcdir=DIR`
Look for the package's source code in directory DIR. Usually Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically. `configure` can determine that directory automatically.
`--version' `--version`
Print the version of Autoconf used to generate the `configure' Print the version of Autoconf used to generate the `configure`
script, and exit. script, and exit.
`configure' also accepts some other, not widely useful, options. `configure` also accepts some other, not widely useful, options.

View File

@ -36,18 +36,23 @@ prefix = @prefix@
exec_prefix = @exec_prefix@ exec_prefix = @exec_prefix@
srcdir = @srcdir@ srcdir = @srcdir@
datarootdir = @datarootdir@ datarootdir = @datarootdir@
VERSION_MAJOR = @VERSION_MAJOR@
VERSION_MINOR = @VERSION_MINOR@
SUBDIRS = ivlpp vhdlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \ 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. # Only run distclean for these directories.
NOTUSED = tgt-fpga tgt-pal tgt-verilog NOTUSED = tgt-fpga tgt-pal tgt-verilog
ifeq (@MINGW32@,yes) ifeq (@LIBVERIUSER@,yes)
SUBDIRS += driver-vpi SUBDIRS += libveriuser cadpli
else else
NOTUSED += driver-vpi NOTUSED += libveriuser cadpli
endif endif
SUBDIRS += driver-vpi
# To get the version headers to build correctly we only want to look # 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 # for C++ files in the source directory. All other files will require
# an explicit $(srcdir). The one exception to this is if we need to # an explicit $(srcdir). The one exception to this is if we need to
@ -61,8 +66,7 @@ bindir = @bindir@
libdir = @libdir@ libdir = @libdir@
# This is actually the directory where we install our own header files. # This is actually the directory where we install our own header files.
# It is a little different from the generic includedir. # It is a little different from the generic includedir.
includedir = @includedir@/iverilog$(suffix) ivl_includedir = @includedir@/iverilog$(suffix)
mandir = @mandir@
dllib=@DLLIB@ dllib=@DLLIB@
@ -72,16 +76,19 @@ HOSTCFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
BUILDCC = @CC_FOR_BUILD@ BUILDCC = @CC_FOR_BUILD@
BUILDEXT = @BUILD_EXEEXT@ BUILDEXT = @BUILD_EXEEXT@
CC = @CC@
CXX = @CXX@ CXX = @CXX@
DLLTOOL = @DLLTOOL@ ENV_VVP=@ENV_VVP@
INSTALL = @INSTALL@ INSTALL = @INSTALL@
INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
LEX = @LEX@ LEX = @LEX@
YACC = @YACC@ YACC = @YACC@
YACC_CONFLICT_FLAGS = -Werror=conflicts-sr -Werror=conflicts-rr
MAN = @MAN@ MAN = @MAN@
PS2PDF = @PS2PDF@ PS2PDF = @PS2PDF@
GROFF = @GROFF@
GIT = @GIT@ GIT = @GIT@
ifeq (@srcdir@,.) ifeq (@srcdir@,.)
@ -114,15 +121,16 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
net_event.o net_expr.o net_func.o \ net_event.o net_expr.o net_func.o \
net_func_eval.o net_link.o net_modulo.o \ net_func_eval.o net_link.o net_modulo.o \
net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \ net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \
net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \ net_udp.o map_named_args.o \
pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \
pform_disciplines.o pform_dump.o pform_package.o pform_pclass.o \ pform_disciplines.o pform_dump.o pform_package.o pform_pclass.o \
pform_types.o \ pform_types.o \
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o vpi_modules.o target.o \ symbol_search.o sync.o sys_funcs.o verinum.o verireal.o vpi_modules.o target.o \
Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PFunction.o \ Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PFunction.o \
PGate.o PGenerate.o PModport.o PNamedItem.o PPackage.o PScope.o PSpec.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) 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 $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
# In the windows world, the installer will need a dosify program to # In the windows world, the installer will need a dosify program to
@ -130,37 +138,29 @@ all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vp
ifeq (@MINGW32@,yes) ifeq (@MINGW32@,yes)
all: dosify$(BUILDEXT) all: dosify$(BUILDEXT)
dosify$(BUILDEXT): $(srcdir)/dosify.c dosify$(BUILDEXT): $(srcdir)/dosify.c
$(BUILDCC) $(CFLAGS) -o dosify$(BUILDEXT) $(srcdir)/dosify.c $(BUILDCC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o dosify$(BUILDEXT) $(srcdir)/dosify.c
endif endif
# This rule rules the compiler in the trivial hello.vl program to make # This rule runs the compiler using the trivial hello.vl program to make sure
# sure the basics were compiled properly. # the base programs are compiled properly.
check: all check: all
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
rm -f check.vvp
test -r check.conf || cp $(srcdir)/check.conf . test -r check.conf || cp $(srcdir)/check.conf .
driver/iverilog -B. -BMvpi -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl driver/iverilog@EXEEXT@ -B. -BMvpi -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl && \
ifeq (@WIN32@,yes) $(ENV_VVP) vvp/vvp$(suffix)@EXEEXT@ -M- -M./vpi ./check.vvp | grep 'Hello, World'
ifeq (@install_suffix@,)
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World' check-installed check-installed-vpi check-installed-vvp check-installed-vvp-py:
else $(MAKE) -C ivtest $@
# 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
clean: clean:
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
rm -f *.o parse.cc parse.h lexor.cc 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 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 -rf dep
rm -f version.exe
distclean: clean distclean: clean
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
@ -168,14 +168,17 @@ distclean: clean
rm -f Makefile config.status config.log config.cache rm -f Makefile config.status config.log config.cache
rm -f stamp-config-h config.h rm -f stamp-config-h config.h
rm -f stamp-_pli_types-h _pli_types.h rm -f stamp-_pli_types-h _pli_types.h
rm -f stamp-version_base-h version_base.h
ifneq (@srcdir@,.) ifneq (@srcdir@,.)
rm -f version_tag.h check.conf rm -f version_tag.h check.conf
rmdir $(SUBDIRS) $(NOTUSED) rmdir $(SUBDIRS) $(NOTUSED)
endif endif
rm -rf autom4te.cache 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++03 -f \ cppcheck --enable=all --std=c99 --std=c++11 -f \
--check-level=exhaustive \
--suppressions-list=$(srcdir)/cppcheck-global.sup \
--suppressions-list=$(srcdir)/cppcheck.sup \ --suppressions-list=$(srcdir)/cppcheck.sup \
-UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \ -UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \ -UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \
@ -203,6 +206,11 @@ stamp-_pli_types-h: $(srcdir)/_pli_types.h.in config.status
./config.status _pli_types.h ./config.status _pli_types.h
_pli_types.h: stamp-_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 $(srcdir)/configure: $(srcdir)/configure.ac $(srcdir)/aclocal.m4
cd $(srcdir) && autoconf cd $(srcdir) && autoconf
@ -211,40 +219,17 @@ config.status: $(srcdir)/configure
./config.status ./config.status
ifeq (@WIN32@,yes) ifeq (@WIN32@,yes)
# Under Windows (mingw) I need to make the ivl.exe in two steps. # Under Windows we need to create an import library to allow the target code
# The first step makes an ivl.exe that dlltool can use to make an # generators to access the items exported by ivl.exe. The .def file controls
# export and import library, and the last link makes a, ivl.exe # what is visible in the import library.
# that really exports the things that the import library imports.
ivl@EXEEXT@: $O $(srcdir)/ivl.def ivl@EXEEXT@: $O $(srcdir)/ivl.def
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@ $(CXX) $(LDFLAGS) -o ivl@EXEEXT@ -Wl,--out-implib=libivl.a $(srcdir)/ivl.def $O $(dllib) @EXTRALIBS@
$(DLLTOOL) --dllname ivl@EXEEXT@ --def $(srcdir)/ivl.def \
--output-lib libivl.a --output-exp ivl.exp
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
else else
ivl@EXEEXT@: $O ivl@EXEEXT@: $O
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib) $(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
endif endif
ifeq (@MINGW32@,no) %.o: %.cc config.h | dep
all: iverilog-vpi
iverilog-vpi: $(srcdir)/iverilog-vpi.sh Makefile
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
-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) $(CFLAGS) -o version.exe -I. -I$(srcdir) $(srcdir)/version.c
%.o: %.cc config.h
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o $(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
mv $*.d dep/$*.d mv $*.d dep/$*.d
@ -257,10 +242,10 @@ parse.o: parse.cc
# Use pattern rules to avoid parallel build issues (see pr3462585) # Use pattern rules to avoid parallel build issues (see pr3462585)
parse%cc parse%h: $(srcdir)/parse%y 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 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 lexor.cc: $(srcdir)/lexor.lex
$(LEX) -s -t $< > $@ $(LEX) -s -t $< > $@
@ -268,20 +253,17 @@ lexor.cc: $(srcdir)/lexor.lex
lexor_keyword.o: lexor_keyword.cc parse.h lexor_keyword.o: lexor_keyword.cc parse.h
lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf
gperf -o -i 7 -C -k 1-4,6,9,$$ -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false) 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 iverilog_man.ps: driver/iverilog.man vvp/vvp.man driver-vpi/iverilog-vpi.man
./version.exe `head -1 $(srcdir)/iverilog-vpi.man.in`'\n' > $@ $(GROFF) -man -rC1 -rD1 -T ps $^ > $@
tail -n +2 $(srcdir)/iverilog-vpi.man.in >> $@
iverilog-vpi.ps: iverilog-vpi.man iverilog_man.pdf: iverilog_man.ps
$(MAN) -t ./iverilog-vpi.man > iverilog-vpi.ps $(PS2PDF) $< $@
cp $@ iverilog_man_$(VERSION_MAJOR)_$(VERSION_MINOR).pdf
iverilog-vpi.pdf: iverilog-vpi.ps
$(PS2PDF) iverilog-vpi.ps iverilog-vpi.pdf
# For VERSION_TAG in driver/main.c, first try git-describe, then look for a # For VERSION_TAG in driver/main.c, first try git-describe, then look for a
# version_tag.h file in the source tree (included in snapshots and releases), # release_tag.h file in the source tree (included in snapshots and releases),
# and finally use nothing. # and finally use nothing.
# "true" and "false" in the next few lines are Unix shell command names # "true" and "false" in the next few lines are Unix shell command names
@ -296,37 +278,14 @@ version_tag.h version:
tmp=`(cd $(srcdir) && $(GIT) describe --always --dirty) \ tmp=`(cd $(srcdir) && $(GIT) describe --always --dirty) \
| sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \ | sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \
echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \ echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
elif test -r $(srcdir)/version_tag.h; then \ elif test -r $(srcdir)/release_tag.h; then \
echo "Using $(srcdir)/version_tag.h for VERSION_TAG"; \ echo "Using $(srcdir)/release_tag.h for VERSION_TAG"; \
diff $(srcdir)/version_tag.h version_tag.h > /dev/null 2>&1 || cp $(srcdir)/version_tag.h version_tag.h; \ diff $(srcdir)/release_tag.h version_tag.h > /dev/null 2>&1 || cp $(srcdir)/release_tag.h version_tag.h; \
else \ else \
echo "Using empty VERSION_TAG"; \ echo "Using empty VERSION_TAG"; \
echo '#define VERSION_TAG ""' > version_tag.h; \ echo '#define VERSION_TAG ""' > version_tag.h; \
fi fi
ifeq (@MINGW32@,yes)
ifeq ($(MAN),none)
INSTALL_DOC = installman
else
ifeq ($(PS2PDF),none)
INSTALL_DOC = installman
else
INSTALL_DOC = installpdf installman
all: dep iverilog-vpi.pdf
endif
endif
INSTALL_DOCDIR = $(mandir)/man1
else
INSTALL_DOC = installman
INSTALL_DOCDIR = $(mandir)/man1
endif
ifeq (@MINGW32@,yes)
WIN32_INSTALL =
else
WIN32_INSTALL = installwin32
endif
install: all installdirs installfiles install: all installdirs installfiles
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
@ -338,37 +297,24 @@ F = ./ivl@EXEEXT@ \
$(srcdir)/sv_vpi_user.h \ $(srcdir)/sv_vpi_user.h \
$(srcdir)/vpi_user.h \ $(srcdir)/vpi_user.h \
$(srcdir)/acc_user.h \ $(srcdir)/acc_user.h \
$(srcdir)/veriuser.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)$(prefix)/iverilog-vpi$(suffix).pdf"
installfiles: $(F) | installdirs installfiles: $(F) | installdirs
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/ivl@EXEEXT@" $(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)/constants.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/constants.vams"
$(INSTALL_DATA) $(srcdir)/disciplines.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/disciplines.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) $(srcdir)/ivl_target.h "$(DESTDIR)$(ivl_includedir)/ivl_target.h"
$(INSTALL_DATA) ./_pli_types.h "$(DESTDIR)$(includedir)/_pli_types.h" $(INSTALL_DATA) ./_pli_types.h "$(DESTDIR)$(ivl_includedir)/_pli_types.h"
$(INSTALL_DATA) $(srcdir)/sv_vpi_user.h "$(DESTDIR)$(includedir)/sv_vpi_user.h" $(INSTALL_DATA) $(srcdir)/sv_vpi_user.h "$(DESTDIR)$(ivl_includedir)/sv_vpi_user.h"
$(INSTALL_DATA) $(srcdir)/vpi_user.h "$(DESTDIR)$(includedir)/vpi_user.h" $(INSTALL_DATA) $(srcdir)/vpi_user.h "$(DESTDIR)$(ivl_includedir)/vpi_user.h"
$(INSTALL_DATA) $(srcdir)/acc_user.h "$(DESTDIR)$(includedir)/acc_user.h" $(INSTALL_DATA) $(srcdir)/acc_user.h "$(DESTDIR)$(ivl_includedir)/acc_user.h"
$(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(includedir)/veriuser.h" $(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(ivl_includedir)/veriuser.h"
installdirs: $(srcdir)/mkinstalldirs installdirs: $(srcdir)/mkinstalldirs
$(srcdir)/mkinstalldirs "$(DESTDIR)$(bindir)" \ $(srcdir)/mkinstalldirs "$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(includedir)" \ "$(DESTDIR)$(ivl_includedir)" \
"$(DESTDIR)$(libdir)/ivl$(suffix)" \ "$(DESTDIR)$(libdir)/ivl$(suffix)" \
"$(DESTDIR)$(libdir)/ivl$(suffix)/include" \ "$(DESTDIR)$(libdir)/ivl$(suffix)/include"
"$(DESTDIR)$(mandir)" \
"$(DESTDIR)$(mandir)/man1"
uninstall: uninstall:
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
@ -376,12 +322,13 @@ uninstall:
do rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/$$f"; done do rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/$$f"; done
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)/include" -rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)/include"
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)" -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 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; \ 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 do rm -f "$(DESTDIR)$(ivl_includedir)/$$f"; done
-test X$(suffix) = X || rmdir "$(DESTDIR)$(includedir)" -test X$(suffix) = X || rmdir "$(DESTDIR)$(ivl_includedir)"
rm -f "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1" "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"
-include $(patsubst %.o, dep/%.d, $O) -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-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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -21,13 +21,65 @@
# include "Module.h" # include "Module.h"
# include "PGate.h" # include "PGate.h"
# include "PModport.h"
# include "PWire.h" # include "PWire.h"
# include <cassert> # include "parse_api.h"
# include "ivl_assert.h"
# include <iostream>
using namespace std; using namespace std;
list<Module::named_expr_t> Module::user_defparms; 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. */ /* n is a permallocated string. */
Module::Module(LexicalScope*parent, perm_string n) Module::Module(LexicalScope*parent, perm_string n)
: PScopeExtra(n, parent) : PScopeExtra(n, parent)
@ -60,18 +112,24 @@ unsigned Module::port_count() const
*/ */
const vector<PEIdent*>& Module::get_port(unsigned idx) const const vector<PEIdent*>& Module::get_port(unsigned idx) const
{ {
assert(idx < ports.size()); ivl_assert(*this, idx < ports.size());
static const vector<PEIdent*> zero; static const vector<PEIdent*> zero;
if (ports[idx]) if (ports[idx] && !ports[idx]->is_interface_port())
return ports[idx]->expr; return ports[idx]->expr;
else else
return zero; 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 unsigned Module::find_port(const char*name) const
{ {
assert(name != 0); ivl_assert(*this, name != 0);
for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) { for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) {
if (ports[idx] == 0) { if (ports[idx] == 0) {
/* It is possible to have undeclared ports. These /* It is possible to have undeclared ports. These
@ -81,7 +139,7 @@ unsigned Module::find_port(const char*name) const
inaccessible to binding by name. */ inaccessible to binding by name. */
continue; continue;
} }
assert(ports[idx]); ivl_assert(*this, ports[idx]);
if (ports[idx]->name == name) if (ports[idx]->name == name)
return idx; return idx;
} }
@ -92,7 +150,7 @@ unsigned Module::find_port(const char*name) const
perm_string Module::get_port_name(unsigned idx) const perm_string Module::get_port_name(unsigned idx) const
{ {
assert(idx < ports.size()); ivl_assert(*this, idx < ports.size());
if (ports[idx] == 0 || ports[idx]->name.str() == 0) { if (ports[idx] == 0 || ports[idx]->name.str() == 0) {
/* It is possible to have undeclared ports. These /* It is possible to have undeclared ports. These
are ports that are skipped in the declaration, are ports that are skipped in the declaration,
@ -108,7 +166,7 @@ perm_string Module::get_port_name(unsigned idx) const
PExpr* Module::get_port_default_value(unsigned idx) const PExpr* Module::get_port_default_value(unsigned idx) const
{ {
assert(idx < ports.size()); ivl_assert(*this, idx < ports.size());
return ports[idx] ? ports[idx]->default_value : 0; return ports[idx] ? ports[idx]->default_value : 0;
} }
@ -148,7 +206,7 @@ bool Module::can_be_toplevel() const
// Don't choose modules with parameters without default value // Don't choose modules with parameters without default value
for (std::map<perm_string,param_expr_t*>::const_iterator cur = for (std::map<perm_string,param_expr_t*>::const_iterator cur =
parameters.begin(); cur != parameters.end(); cur++) { parameters.begin(); cur != parameters.end(); ++cur) {
if (cur->second->expr == 0) if (cur->second->expr == 0)
return false; return false;
} }

View File

@ -1,7 +1,7 @@
#ifndef IVL_Module_H #ifndef IVL_Module_H
#define IVL_Module_H #define IVL_Module_H
/* /*
* 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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -37,11 +37,13 @@ class PGate;
class PGenerate; class PGenerate;
class PModport; class PModport;
class PSpecPath; class PSpecPath;
class PTimingCheck;
class PTask; class PTask;
class PFunction; class PFunction;
class PWire; class PWire;
class PProcess; class PProcess;
class Design; class Design;
class LineInfo;
class NetScope; class NetScope;
/* /*
@ -64,16 +66,32 @@ class Module : public PScopeExtra, public PNamedItem {
default value. */ default value. */
public: public:
struct port_t { struct port_t {
enum port_kind_t { P_SIGNAL, P_INTERFACE };
port_t();
port_kind_t port_kind;
perm_string name; perm_string name;
std::vector<PEIdent*> expr; std::vector<PEIdent*> expr;
PExpr*default_value; 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: public:
/* The name passed here is the module name, not the instance /* The name passed here is the module name, not the instance
name. This name must be a permallocated string. */ name. This name must be a permallocated string. */
explicit Module(LexicalScope*parent, perm_string name); explicit Module(LexicalScope*parent, perm_string name);
~Module(); ~Module() override;
/* Initially false. This is set to true if the module has been /* Initially false. This is set to true if the module has been
declared as a library module. This makes the module declared as a library module. This makes the module
@ -136,7 +154,9 @@ class Module : public PScopeExtra, public PNamedItem {
program blocks. */ program blocks. */
std::map<perm_string,PModport*> modports; std::map<perm_string,PModport*> modports;
/* List for specify paths and timing checks */
std::list<PSpecPath*> specify_paths; std::list<PSpecPath*> specify_paths;
std::list<PTimingCheck*> timing_checks;
// The mod_name() is the name of the module type. // The mod_name() is the name of the module type.
perm_string mod_name() const { return pscope_name(); } perm_string mod_name() const { return pscope_name(); }
@ -145,6 +165,7 @@ class Module : public PScopeExtra, public PNamedItem {
unsigned port_count() const; unsigned port_count() const;
const std::vector<PEIdent*>& get_port(unsigned idx) 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; unsigned find_port(const char*name) const;
// Return port name ("" for undeclared port) // Return port name ("" for undeclared port)
@ -164,12 +185,13 @@ class Module : public PScopeExtra, public PNamedItem {
bool elaborate_sig(Design*, NetScope*scope) const; bool elaborate_sig(Design*, NetScope*scope) const;
SymbolType symbol_type() const; SymbolType symbol_type() const override;
bool can_be_toplevel() const; bool can_be_toplevel() const;
private: private:
void dump_specparams_(std::ostream&out, unsigned indent) const; void dump_specparams_(std::ostream&out, unsigned indent) const;
void dump_timingchecks_(std::ostream&out, unsigned indent) const;
std::list<PGate*> gates_; std::list<PGate*> gates_;
private: // Not implemented private: // Not implemented
@ -177,4 +199,16 @@ class Module : public PScopeExtra, public PNamedItem {
Module& operator= (const Module&); 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 */ #endif /* IVL_Module_H */

View File

@ -1,7 +1,7 @@
#ifndef IVL_PClass_H #ifndef IVL_PClass_H
#define IVL_PClass_H #define IVL_PClass_H
/* /*
* Copyright (c) 2012-2019 Stephen Williams (steve@icarus.com) * Copyright (c) 2012-2025 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -36,11 +36,11 @@ class PClass : public PScopeExtra, public PNamedItem {
public: public:
explicit PClass (perm_string name, LexicalScope*parent); explicit PClass (perm_string name, LexicalScope*parent);
~PClass(); ~PClass() override;
void dump(std::ostream&out, unsigned indent) const; void dump(std::ostream&out, unsigned indent) const;
SymbolType symbol_type() const; SymbolType symbol_type() const override;
public: public:
class_type_t*type; class_type_t*type;

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2004-2019 Stephen Williams (steve@icarus.com) * Copyright (c) 2004-2024 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -21,8 +21,8 @@
# include "PEvent.h" # include "PEvent.h"
PEvent::PEvent(perm_string n) PEvent::PEvent(perm_string n, unsigned lexical_pos)
: name_(n) : name_(n), lexical_pos_(lexical_pos)
{ {
} }

View File

@ -1,7 +1,7 @@
#ifndef IVL_PEvent_H #ifndef IVL_PEvent_H
#define IVL_PEvent_H #define IVL_PEvent_H
/* /*
* Copyright (c) 2000-2019 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2025 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -36,17 +36,20 @@ class PEvent : public PNamedItem {
public: public:
// The name is a perm-allocated string. It is the simple name // The name is a perm-allocated string. It is the simple name
// of the event, without any scope. // of the event, without any scope.
explicit PEvent(perm_string name); explicit PEvent(perm_string name, unsigned lexical_pos);
~PEvent(); ~PEvent() override;
perm_string name() const; perm_string name() const;
unsigned lexical_pos() const { return lexical_pos_; }
void elaborate_scope(Design*des, NetScope*scope) const; void elaborate_scope(Design*des, NetScope*scope) const;
SymbolType symbol_type() const; SymbolType symbol_type() const override;
private: private:
perm_string name_; perm_string name_;
unsigned lexical_pos_;
private: // not implemented private: // not implemented
PEvent(const PEvent&); PEvent(const PEvent&);

173
PExpr.cc
View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2021 Stephen Williams <steve@icarus.com> * Copyright (c) 1998-2026 Stephen Williams <steve@icarus.com>
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
@ -20,12 +20,14 @@
# include "config.h" # include "config.h"
# include <algorithm>
# include <iostream> # include <iostream>
# include "compiler.h" # include "compiler.h"
# include "PExpr.h" # include "PExpr.h"
# include "PWire.h" # include "PWire.h"
# include "Module.h" # include "Module.h"
# include "ivl_assert.h"
# include "netmisc.h" # include "netmisc.h"
# include "util.h" # include "util.h"
# include <typeinfo> # include <typeinfo>
@ -53,7 +55,7 @@ bool PExpr::has_aa_term(Design*, NetScope*) const
return false; return false;
} }
NetNet* PExpr::elaborate_lnet(Design*, NetScope*) const NetNet* PExpr::elaborate_lnet(Design*, NetScope*, bool) const
{ {
cerr << get_fileline() << ": error: " cerr << get_fileline() << ": error: "
<< "expression not valid in assign l-value: " << "expression not valid in assign l-value: "
@ -61,7 +63,7 @@ NetNet* PExpr::elaborate_lnet(Design*, NetScope*) const
return 0; return 0;
} }
NetNet* PExpr::elaborate_bi_net(Design*, NetScope*) const NetNet* PExpr::elaborate_bi_net(Design*, NetScope*, bool) const
{ {
cerr << get_fileline() << ": error: " cerr << get_fileline() << ": error: "
<< "expression not valid as argument to inout port: " << "expression not valid as argument to inout port: "
@ -98,20 +100,24 @@ PEAssignPattern::PEAssignPattern()
} }
PEAssignPattern::PEAssignPattern(const list<PExpr*>&p) PEAssignPattern::PEAssignPattern(const list<PExpr*>&p)
: parms_(p.size()) : parms_(p.begin(), p.end())
{ {
size_t idx = 0;
for (list<PExpr*>::const_iterator cur = p.begin()
; cur != p.end() ; ++cur) {
parms_[idx] = *cur;
idx += 1;
}
} }
PEAssignPattern::~PEAssignPattern() 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) PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
: op_(op), left_(l), right_(r) : op_(op), left_(l), right_(r)
{ {
@ -129,7 +135,7 @@ void PEBinary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
bool PEBinary::has_aa_term(Design*des, NetScope*scope) const bool PEBinary::has_aa_term(Design*des, NetScope*scope) const
{ {
assert(left_ && right_); ivl_assert(*this, left_ && right_);
return left_->has_aa_term(des, scope) || right_->has_aa_term(des, scope); return left_->has_aa_term(des, scope) || right_->has_aa_term(des, scope);
} }
@ -150,6 +156,7 @@ bool PECastSize::has_aa_term(Design *des, NetScope *scope) const
PECastType::PECastType(data_type_t*t, PExpr*b) PECastType::PECastType(data_type_t*t, PExpr*b)
: target_(t), base_(b) : target_(t), base_(b)
{ {
target_type_ = nullptr;
} }
PECastType::~PECastType() PECastType::~PECastType()
@ -186,7 +193,7 @@ PEBComp::~PEBComp()
PEBLogic::PEBLogic(char op, PExpr*l, PExpr*r) PEBLogic::PEBLogic(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r) : PEBinary(op, l, r)
{ {
assert(op == 'a' || op == 'o' || op == 'q' || op == 'Q'); ivl_assert(*this, op == 'a' || op == 'o' || op == 'q' || op == 'Q');
} }
PEBLogic::~PEBLogic() PEBLogic::~PEBLogic()
@ -220,13 +227,13 @@ PEBShift::~PEBShift()
{ {
} }
PECallFunction::PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms) PECallFunction::PECallFunction(const pform_name_t &n, const vector<named_pexpr_t> &parms)
: package_(0), path_(n), parms_(parms), is_overridden_(false) : path_(n), parms_(parms), is_overridden_(false)
{ {
} }
PECallFunction::PECallFunction(PPackage*pkg, const pform_name_t&n, const vector<PExpr *> &parms) PECallFunction::PECallFunction(PPackage *pkg, const pform_name_t &n, const vector<named_pexpr_t> &parms)
: package_(pkg), path_(n), parms_(parms), is_overridden_(false) : path_(pkg, n), parms_(parms), is_overridden_(false)
{ {
} }
@ -238,76 +245,78 @@ static pform_name_t pn_from_ps(perm_string n)
return tmp; return tmp;
} }
PECallFunction::PECallFunction(PPackage*pkg, perm_string n, const list<PExpr *> &parms) PECallFunction::PECallFunction(PPackage *pkg, const pform_name_t &n, const list<named_pexpr_t> &parms)
: package_(pkg), path_(pn_from_ps(n)), parms_(parms.size()), is_overridden_(false) : path_(pkg, n), parms_(parms.begin(), parms.end()), is_overridden_(false)
{ {
int tmp_idx = 0;
assert(parms_.size() == parms.size());
for (list<PExpr*>::const_iterator idx = parms.begin()
; idx != parms.end() ; ++idx)
parms_[tmp_idx++] = *idx;
} }
PECallFunction::PECallFunction(perm_string n, const vector<PExpr*>&parms) PECallFunction::PECallFunction(perm_string n, const vector<named_pexpr_t> &parms)
: package_(0), path_(pn_from_ps(n)), parms_(parms), is_overridden_(false) : path_(pn_from_ps(n)), parms_(parms), is_overridden_(false)
{ {
} }
PECallFunction::PECallFunction(perm_string n) PECallFunction::PECallFunction(perm_string n)
: package_(0), path_(pn_from_ps(n)), is_overridden_(false) : path_(pn_from_ps(n)), is_overridden_(false)
{ {
} }
// NOTE: Anachronism. Try to work all use of svector out. // NOTE: Anachronism. Try to work all use of svector out.
PECallFunction::PECallFunction(const pform_name_t&n, const list<PExpr *> &parms) PECallFunction::PECallFunction(const pform_name_t &n, const list<named_pexpr_t> &parms)
: package_(0), path_(n), parms_(parms.size()), is_overridden_(false) : path_(n), parms_(parms.begin(), parms.end()), is_overridden_(false)
{ {
int tmp_idx = 0;
assert(parms_.size() == parms.size());
for (list<PExpr*>::const_iterator idx = parms.begin()
; idx != parms.end() ; ++idx)
parms_[tmp_idx++] = *idx;
} }
PECallFunction::PECallFunction(perm_string n, const list<PExpr*>&parms) PECallFunction::PECallFunction(perm_string n, const list<named_pexpr_t> &parms)
: package_(0), path_(pn_from_ps(n)), parms_(parms.size()), is_overridden_(false) : path_(pn_from_ps(n)), parms_(parms.begin(), parms.end()), is_overridden_(false)
{
}
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)
{ {
int tmp_idx = 0;
assert(parms_.size() == parms.size());
for (list<PExpr*>::const_iterator idx = parms.begin()
; idx != parms.end() ; ++idx)
parms_[tmp_idx++] = *idx;
} }
PECallFunction::~PECallFunction() PECallFunction::~PECallFunction()
{ {
delete chain_prefix_;
} }
void PECallFunction::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) void PECallFunction::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{ {
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { if (chain_prefix_) {
parms_[idx]->declare_implicit_nets(scope, type); chain_prefix_->declare_implicit_nets(scope, type);
}
for (const auto &parm : parms_) {
if (parm.parm) {
parm.parm->declare_implicit_nets(scope, type);
}
} }
} }
bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const
{ {
bool flag = false; if (chain_prefix_ && chain_prefix_->has_aa_term(des, scope)) {
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { return true;
flag = parms_[idx]->has_aa_term(des, scope) || flag; }
for (const auto &parm : parms_) {
if (parm.parm && parm.parm->has_aa_term(des, scope)) {
return true;
}
} }
return flag; return false;
} }
PEConcat::PEConcat(const list<PExpr*>&p, PExpr*r) PEConcat::PEConcat(const list<PExpr*>&p, PExpr*r)
: parms_(p.size()), width_modes_(SIZED, p.size()), repeat_(r) : parms_(p.begin(), p.end()), width_modes_(SIZED, p.size()), repeat_(r)
{ {
int tmp_idx = 0;
assert(parms_.size() == p.size());
for (list<PExpr*>::const_iterator idx = p.begin()
; idx != p.end() ; ++idx)
parms_[tmp_idx++] = *idx;
tested_scope_ = 0; tested_scope_ = 0;
repeat_count_ = 1; repeat_count_ = 1;
} }
@ -352,7 +361,7 @@ PEEvent::edge_t PEEvent::type() const
bool PEEvent::has_aa_term(Design*des, NetScope*scope) const bool PEEvent::has_aa_term(Design*des, NetScope*scope) const
{ {
assert(expr_); ivl_assert(*this, expr_);
return expr_->has_aa_term(des, scope); return expr_->has_aa_term(des, scope);
} }
@ -384,19 +393,19 @@ const verireal& PEFNumber::value() const
return *value_; return *value_;
} }
PEIdent::PEIdent(const pform_name_t&that) PEIdent::PEIdent(const pform_name_t&that, unsigned lexical_pos)
: package_(0), path_(that), no_implicit_sig_(false) : path_(that), lexical_pos_(lexical_pos), no_implicit_sig_(false)
{ {
} }
PEIdent::PEIdent(perm_string s, bool no_implicit_sig) PEIdent::PEIdent(perm_string s, unsigned lexical_pos, bool no_implicit_sig)
: package_(0), no_implicit_sig_(no_implicit_sig) : lexical_pos_(lexical_pos), no_implicit_sig_(no_implicit_sig)
{ {
path_.push_back(name_component_t(s)); path_.name.push_back(name_component_t(s));
} }
PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that) PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that, unsigned lexical_pos)
: package_(pkg), path_(that), no_implicit_sig_(true) : path_(pkg, that), lexical_pos_(lexical_pos), no_implicit_sig_(true)
{ {
} }
@ -406,14 +415,11 @@ PEIdent::~PEIdent()
static bool find_enum_constant(LexicalScope*scope, perm_string name) static bool find_enum_constant(LexicalScope*scope, perm_string name)
{ {
for (vector<enum_type_t*>::const_iterator cur = scope->enum_sets.begin() ; return std::any_of(scope->enum_sets.cbegin(), scope->enum_sets.cend(),
cur != scope->enum_sets.end() ; ++ cur) { [name](const enum_type_t *cur) {
for (list<named_pexpr_t>::const_iterator idx = (*cur)->names->begin() ; return std::any_of(cur->names->cbegin(), cur->names->cend(),
idx != (*cur)->names->end() ; ++ idx) { [name](const named_pexpr_t&idx){return idx.name == name;});
if (idx->name == name) return true; });
}
}
return false;
} }
void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
@ -425,8 +431,10 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
- this is not an implicit named port connection */ - this is not an implicit named port connection */
if (no_implicit_sig_) if (no_implicit_sig_)
return; return;
if ((path_.size() == 1) && (path_.front().index.size() == 0)) { if (path_.package)
perm_string name = path_.front().name; return;
if (path_.name.size() == 1 && path_.name.front().index.empty()) {
perm_string name = path_.name.front().name;
LexicalScope*ss = scope; LexicalScope*ss = scope;
while (ss) { while (ss) {
if (ss->wires.find(name) != ss->wires.end()) if (ss->wires.find(name) != ss->wires.end())
@ -448,7 +456,7 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
ss = ss->parent_scope(); ss = ss->parent_scope();
} }
PWire*net = new PWire(name, type, NetNet::NOT_A_PORT); PWire*net = new PWire(name, lexical_pos_, type, NetNet::NOT_A_PORT);
net->set_file(get_file()); net->set_file(get_file());
net->set_lineno(get_lineno()); net->set_lineno(get_lineno());
scope->wires[name] = net; scope->wires[name] = net;
@ -462,7 +470,7 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
bool PEIdent::has_aa_term(Design*des, NetScope*scope) const bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
{ {
symbol_search_results sr; symbol_search_results sr;
if (!symbol_search(this, des, scope, path_, &sr)) if (!symbol_search(this, des, scope, path_, lexical_pos_, &sr))
return false; return false;
// Class properties are not considered automatic since a non-blocking // Class properties are not considered automatic since a non-blocking
@ -488,14 +496,9 @@ PENewClass::PENewClass(void)
{ {
} }
PENewClass::PENewClass(const list<PExpr*>&p, data_type_t *class_type) PENewClass::PENewClass(const list<named_pexpr_t> &p, data_type_t *class_type)
: parms_(p.size()), class_type_(class_type) : parms_(p.begin(), p.end()), class_type_(class_type)
{ {
size_t tmp_idx = 0;
for (list<PExpr*>::const_iterator cur = p.begin()
; cur != p.end() ; ++ cur) {
parms_[tmp_idx++] = *cur;
}
} }
PENewClass::~PENewClass() PENewClass::~PENewClass()
@ -514,7 +517,7 @@ PENewCopy::~PENewCopy()
PENumber::PENumber(verinum*vp) PENumber::PENumber(verinum*vp)
: value_(vp) : value_(vp)
{ {
assert(vp); ivl_assert(*this, vp);
} }
PENumber::~PENumber() PENumber::~PENumber()
@ -553,7 +556,7 @@ PETernary::~PETernary()
void PETernary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) void PETernary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{ {
assert(expr_ && tru_ && fal_); ivl_assert(*this, expr_ && tru_ && fal_);
expr_->declare_implicit_nets(scope, type); expr_->declare_implicit_nets(scope, type);
tru_->declare_implicit_nets(scope, type); tru_->declare_implicit_nets(scope, type);
fal_->declare_implicit_nets(scope, type); fal_->declare_implicit_nets(scope, type);
@ -561,7 +564,7 @@ void PETernary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
bool PETernary::has_aa_term(Design*des, NetScope*scope) const bool PETernary::has_aa_term(Design*des, NetScope*scope) const
{ {
assert(expr_ && tru_ && fal_); ivl_assert(*this, expr_ && tru_ && fal_);
return expr_->has_aa_term(des, scope) return expr_->has_aa_term(des, scope)
|| tru_->has_aa_term(des, scope) || tru_->has_aa_term(des, scope)
|| fal_->has_aa_term(des, scope); || fal_->has_aa_term(des, scope);
@ -587,13 +590,13 @@ PEUnary::~PEUnary()
void PEUnary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) void PEUnary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{ {
assert(expr_); ivl_assert(*this, expr_);
expr_->declare_implicit_nets(scope, type); expr_->declare_implicit_nets(scope, type);
} }
bool PEUnary::has_aa_term(Design*des, NetScope*scope) const bool PEUnary::has_aa_term(Design*des, NetScope*scope) const
{ {
assert(expr_); ivl_assert(*this, expr_);
return expr_->has_aa_term(des, scope); return expr_->has_aa_term(des, scope);
} }

454
PExpr.h
View File

@ -1,7 +1,7 @@
#ifndef IVL_PExpr_H #ifndef IVL_PExpr_H
#define IVL_PExpr_H #define IVL_PExpr_H
/* /*
* Copyright (c) 1998-2021 Stephen Williams <steve@icarus.com> * Copyright (c) 1998-2026 Stephen Williams <steve@icarus.com>
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
@ -37,6 +37,7 @@ class NetExpr;
class NetScope; class NetScope;
class PPackage; class PPackage;
struct symbol_search_results; struct symbol_search_results;
class netclass_t;
/* /*
* The PExpr class hierarchy supports the description of * The PExpr class hierarchy supports the description of
@ -60,7 +61,7 @@ class PExpr : public LineInfo {
static const char*width_mode_name(width_mode_t mode); static const char*width_mode_name(width_mode_t mode);
PExpr(); PExpr();
virtual ~PExpr(); virtual ~PExpr() override;
virtual void dump(std::ostream&) const; virtual void dump(std::ostream&) const;
@ -156,13 +157,15 @@ class PExpr : public LineInfo {
// This method elaborates the expression as gates, but // This method elaborates the expression as gates, but
// restricted for use as l-values of continuous assignments. // restricted for use as l-values of continuous assignments.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const; virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
bool var_allowed_in_sv) const;
// This is similar to elaborate_lnet, except that the // This is similar to elaborate_lnet, except that the
// expression is evaluated to be bi-directional. This is // expression is evaluated to be bi-directional. This is
// useful for arguments to inout ports of module instances and // useful for arguments to inout ports of module instances and
// ports of tran primitives. // ports of tran primitives.
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const; virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope,
bool var_allowed_in_sv) const;
// Expressions that can be in the l-value of procedural // Expressions that can be in the l-value of procedural
// assignments can be elaborated with this method. If the // assignments can be elaborated with this method. If the
@ -172,7 +175,8 @@ class PExpr : public LineInfo {
virtual NetAssign_* elaborate_lval(Design*des, virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope, NetScope*scope,
bool is_cassign, bool is_cassign,
bool is_force) const; bool is_force,
bool is_init = false) const;
// This method returns true if the expression represents a // This method returns true if the expression represents a
// structural net that can have multiple drivers. This is // structural net that can have multiple drivers. This is
@ -201,20 +205,37 @@ class PEAssignPattern : public PExpr {
public: public:
explicit PEAssignPattern(); explicit PEAssignPattern();
explicit PEAssignPattern(const std::list<PExpr*>&p); explicit PEAssignPattern(const std::list<PExpr*>&p);
~PEAssignPattern(); ~PEAssignPattern() override;
void dump(std::ostream&) const; void dump(std::ostream&) const override;
virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); 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, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const; ivl_type_t type, unsigned flags) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const; unsigned flags) const override;
private: private:
NetExpr* elaborate_expr_darray_(Design*des, NetScope*scope, NetExpr* elaborate_expr_packed_(Design *des, NetScope *scope,
ivl_type_t type, unsigned flags) const; ivl_variable_type_t base_type,
unsigned int width,
const netranges_t &dims,
unsigned int cur_dim,
bool need_const) const;
NetExpr* elaborate_expr_struct_(Design *des, NetScope *scope,
const netstruct_t *struct_type,
bool need_const) const;
NetExpr* elaborate_expr_array_(Design *des, NetScope *scope,
const netarray_t *array_type,
bool need_const, bool up) const;
NetExpr* elaborate_expr_uarray_(Design *des, NetScope *scope,
const netuarray_t *uarray_type,
const netranges_t &dims,
unsigned int cur_dim,
bool need_const) const;
private: private:
std::vector<PExpr*>parms_; std::vector<PExpr*>parms_;
@ -224,35 +245,39 @@ class PEConcat : public PExpr {
public: public:
explicit PEConcat(const std::list<PExpr*>&p, PExpr*r =0); explicit PEConcat(const std::list<PExpr*>&p, PExpr*r =0);
~PEConcat(); ~PEConcat() override;
virtual void dump(std::ostream&) const; virtual void dump(std::ostream&) const override;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override;
virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual bool has_aa_term(Design*des, NetScope*scope) const override;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const; virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const; bool var_allowed_in_sv) const override;
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope,
bool var_allowed_in_sv) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const; ivl_type_t type, unsigned flags) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const; unsigned flags) const override;
virtual NetAssign_* elaborate_lval(Design*des, virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope, NetScope*scope,
bool is_cassign, bool is_cassign,
bool is_force) const; bool is_force,
bool is_init = false) const override;
virtual bool is_collapsible_net(Design*des, NetScope*scope, virtual bool is_collapsible_net(Design*des, NetScope*scope,
NetNet::PortType port_type) const; NetNet::PortType port_type) const override;
private: private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope, NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool bidirectional_flag) const; bool bidirectional_flag,
bool var_allowed_in_sv) const;
private: private:
std::vector<PExpr*>parms_; std::vector<PExpr*>parms_;
std::valarray<width_mode_t>width_modes_; std::valarray<width_mode_t>width_modes_;
@ -277,14 +302,14 @@ class PEEvent : public PExpr {
// Use this constructor to create events based on edges or levels. // Use this constructor to create events based on edges or levels.
PEEvent(edge_t t, PExpr*e); PEEvent(edge_t t, PExpr*e);
~PEEvent(); ~PEEvent() override;
edge_t type() const; edge_t type() const;
PExpr* expr() const; PExpr* expr() const;
virtual void dump(std::ostream&) const; virtual void dump(std::ostream&) const override;
virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual bool has_aa_term(Design*des, NetScope*scope) const override;
private: private:
edge_t type_; edge_t type_;
@ -298,19 +323,19 @@ class PEFNumber : public PExpr {
public: public:
explicit PEFNumber(verireal*vp); explicit PEFNumber(verireal*vp);
~PEFNumber(); ~PEFNumber() override;
const verireal& value() const; const verireal& value() const;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
ivl_type_t type, unsigned flags) const; ivl_type_t type, unsigned flags) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const; unsigned flags) const override;
virtual void dump(std::ostream&) const; virtual void dump(std::ostream&) const override;
private: private:
verireal*value_; verireal*value_;
@ -319,40 +344,41 @@ class PEFNumber : public PExpr {
class PEIdent : public PExpr { class PEIdent : public PExpr {
public: public:
explicit PEIdent(perm_string, bool no_implicit_sig=false); explicit PEIdent(perm_string, unsigned lexical_pos, bool no_implicit_sig=false);
explicit PEIdent(PPackage*pkg, const pform_name_t&name); explicit PEIdent(PPackage*pkg, const pform_name_t&name, unsigned lexical_pos);
explicit PEIdent(const pform_name_t&); explicit PEIdent(const pform_name_t&, unsigned lexical_pos);
~PEIdent(); ~PEIdent() override;
// Add another name to the string of hierarchy that is the // Add another name to the string of hierarchy that is the
// current identifier. // current identifier.
void append_name(perm_string); void append_name(perm_string);
virtual void dump(std::ostream&) const; virtual void dump(std::ostream&) const override;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override;
virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual bool has_aa_term(Design*des, NetScope*scope) const override;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
// Identifiers are allowed (with restrictions) is assign l-values. // Identifiers are allowed (with restrictions) is assign l-values.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const; virtual NetNet* elaborate_lnet(Design*des, NetScope*scope, bool var_allowed_in_sv) const override;
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const; virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope, bool var_allowed_in_sv) const override;
// Identifiers are also allowed as procedural assignment l-values. // Identifiers are also allowed as procedural assignment l-values.
virtual NetAssign_* elaborate_lval(Design*des, virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope, NetScope*scope,
bool is_cassign, bool is_cassign,
bool is_force) const; bool is_force,
bool is_init = false) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const; ivl_type_t type, unsigned flags) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const; unsigned flags) const override;
// Elaborate the PEIdent as a port to a module. This method // Elaborate the PEIdent as a port to a module. This method
// only applies to Ident expressions. // only applies to Ident expressions.
@ -364,15 +390,15 @@ class PEIdent : public PExpr {
NetNet* elaborate_unpacked_net(Design*des, NetScope*sc) const; NetNet* elaborate_unpacked_net(Design*des, NetScope*sc) const;
virtual bool is_collapsible_net(Design*des, NetScope*scope, virtual bool is_collapsible_net(Design*des, NetScope*scope,
NetNet::PortType port_type) const; NetNet::PortType port_type) const override;
const PPackage* package() const { return package_; } const pform_scoped_name_t& path() const { return path_; }
const pform_name_t& path() const { return path_; } unsigned lexical_pos() const { return lexical_pos_; }
private: private:
PPackage*package_; pform_scoped_name_t path_;
pform_name_t path_; unsigned lexical_pos_;
bool no_implicit_sig_; bool no_implicit_sig_;
private: private:
@ -389,7 +415,7 @@ class PEIdent : public PExpr {
// the values written to the msb/lsb arguments. If there are // the values written to the msb/lsb arguments. If there are
// invalid bits (xz) in either expression, then the defined // invalid bits (xz) in either expression, then the defined
// flag is set to *false*. // flag is set to *false*.
bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb, bool&defined) const; void calculate_parts_(Design*, NetScope*, long&msb, long&lsb, bool&defined) const;
NetExpr* calculate_up_do_base_(Design*, NetScope*, bool need_const) const; NetExpr* calculate_up_do_base_(Design*, NetScope*, bool need_const) const;
bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const; bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const;
@ -403,28 +429,37 @@ class PEIdent : public PExpr {
// [2:0][x] - BAD // [2:0][x] - BAD
// [y][x] - BAD // [y][x] - BAD
// Leave the last index for special handling. // Leave the last index for special handling.
bool calculate_packed_indices_(Design*des, NetScope*scope, NetNet*net, bool calculate_packed_indices_(Design*des, NetScope*scope, const NetNet*net,
std::list<long>&prefix_indices) const; std::list<long>&prefix_indices) const;
private: private:
NetAssign_*elaborate_lval_method_class_member_(Design*, NetScope*) const;
void report_mixed_assignment_conflict_(const char*category) const;
NetAssign_ *elaborate_lval_array_(Design *des, NetScope *scope,
bool is_force, NetNet *reg) const;
NetAssign_ *elaborate_lval_var_(Design *des, NetScope *scope,
bool is_force, bool is_cassign,
NetNet *reg, ivl_type_t data_type,
pform_name_t tail_path) const;
NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*, NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*,
bool need_const_idx) const; bool need_const_idx, bool is_force) const;
bool elaborate_lval_net_bit_(Design*, NetScope*, NetAssign_*, bool elaborate_lval_net_bit_(Design*, NetScope*, NetAssign_*,
bool need_const_idx) const; bool need_const_idx, bool is_force) const;
bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const; bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*,
bool is_force) const;
bool elaborate_lval_net_idx_(Design*, NetScope*, NetAssign_*, bool elaborate_lval_net_idx_(Design*, NetScope*, NetAssign_*,
index_component_t::ctype_t, index_component_t::ctype_t,
bool need_const_idx) const; bool need_const_idx, bool is_force) const;
NetAssign_*elaborate_lval_net_class_member_(Design*, NetScope*, NetAssign_*elaborate_lval_net_class_member_(Design*, NetScope*,
const netclass_t *class_type, const netclass_t *class_type,
NetNet*, NetNet*,
pform_name_t) const; pform_name_t) const;
bool elaborate_lval_net_packed_member_(Design*, NetScope*, bool elaborate_lval_net_packed_member_(Design*, NetScope*,
NetAssign_*, NetAssign_*,
pform_name_t member_path) const; pform_name_t member_path, bool is_force) const;
bool elaborate_lval_darray_bit_(Design*, NetScope*, bool elaborate_lval_darray_bit_(Design*, NetScope*,
NetAssign_*) const; NetAssign_*, bool is_force) const;
private: private:
NetExpr* elaborate_expr_(Design *des, NetScope *scope, NetExpr* elaborate_expr_(Design *des, NetScope *scope,
@ -456,18 +491,12 @@ class PEIdent : public PExpr {
const NetScope*found_in, const NetScope*found_in,
ivl_type_t par_type, ivl_type_t par_type,
unsigned expr_wid) const; unsigned expr_wid) const;
NetExpr*elaborate_expr_param_idx_up_(Design*des, NetExpr*elaborate_expr_param_idx_up_do_(Design*des,
NetScope*scope, NetScope*scope,
const NetExpr*par, const NetExpr*par,
const NetScope*found_in, const NetScope*found_in,
ivl_type_t par_type, ivl_type_t par_type,
bool need_const) const; bool up, 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_net(Design*des, NetExpr*elaborate_expr_net(Design*des,
NetScope*scope, NetScope*scope,
NetNet*net, NetNet*net,
@ -485,16 +514,11 @@ class PEIdent : public PExpr {
NetESignal*net, NetESignal*net,
NetScope*found, NetScope*found,
unsigned expr_wid) const; unsigned expr_wid) const;
NetExpr*elaborate_expr_net_idx_up_(Design*des, NetExpr*elaborate_expr_net_idx_up_do_(Design*des,
NetScope*scope, NetScope*scope,
NetESignal*net, NetESignal*net,
NetScope*found, NetScope*found,
bool need_const) const; bool up, 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_bit_(Design*des, NetExpr*elaborate_expr_net_bit_(Design*des,
NetScope*scope, NetScope*scope,
NetESignal*net, NetESignal*net,
@ -506,26 +530,23 @@ class PEIdent : public PExpr {
NetScope*found, NetScope*found,
bool need_const) const; bool need_const) const;
NetExpr*elaborate_expr_class_member_(Design*des,
NetScope*scope,
unsigned expr_wid,
unsigned flags) const;
NetExpr *elaborate_expr_class_field_(Design*des, NetScope*scope, NetExpr *elaborate_expr_class_field_(Design*des, NetScope*scope,
const symbol_search_results &sr, const symbol_search_results &sr,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const; unsigned flags) const;
unsigned test_width_method_(Design*des, NetScope*scope, width_mode_t&mode);
unsigned test_width_parameter_(const NetExpr *par, width_mode_t&mode); unsigned test_width_parameter_(const NetExpr *par, width_mode_t&mode);
ivl_type_t resolve_type_(Design *des, const symbol_search_results &sr,
unsigned int &index_depth) const;
private: private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope, NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool bidirectional_flag) const; bool bidirectional_flag,
bool var_allowed_in_sv) const;
bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig, bool eval_part_select_(Design*des, NetScope*scope, const NetNet*sig,
long&midx, long&lidx) const; long&midx, long&lidx) const;
}; };
@ -533,16 +554,16 @@ class PENewArray : public PExpr {
public: public:
explicit PENewArray (PExpr*s, PExpr*i); explicit PENewArray (PExpr*s, PExpr*i);
~PENewArray(); ~PENewArray() override;
virtual void dump(std::ostream&) const; virtual void dump(std::ostream&) const override;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const; ivl_type_t type, unsigned flags) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const; unsigned flags) const override;
private: private:
PExpr*size_; PExpr*size_;
@ -555,21 +576,21 @@ class PENewClass : public PExpr {
// New without (or with default) constructor // New without (or with default) constructor
explicit PENewClass (); explicit PENewClass ();
// New with constructor arguments // New with constructor arguments
explicit PENewClass (const std::list<PExpr*>&p, explicit PENewClass (const std::list<named_pexpr_t> &p,
data_type_t *class_type = nullptr); data_type_t *class_type = nullptr);
~PENewClass(); ~PENewClass() override;
virtual void dump(std::ostream&) const; virtual void dump(std::ostream&) const override;
// Class objects don't have a useful width, but the expression // Class objects don't have a useful width, but the expression
// is IVL_VT_CLASS. // is IVL_VT_CLASS.
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
// Note that class (new) expressions only appear in context // Note that class (new) expressions only appear in context
// that uses this form of the elaborate_expr method. In fact, // that uses this form of the elaborate_expr method. In fact,
// the type argument is going to be a netclass_t object. // the type argument is going to be a netclass_t object.
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const; ivl_type_t type, unsigned flags) const override;
private: private:
NetExpr* elaborate_expr_constructor_(Design*des, NetScope*scope, NetExpr* elaborate_expr_constructor_(Design*des, NetScope*scope,
@ -577,25 +598,25 @@ class PENewClass : public PExpr {
NetExpr*obj, unsigned flags) const; NetExpr*obj, unsigned flags) const;
private: private:
std::vector<PExpr*>parms_; std::vector<named_pexpr_t> parms_;
data_type_t *class_type_; data_type_t *class_type_;
}; };
class PENewCopy : public PExpr { class PENewCopy : public PExpr {
public: public:
explicit PENewCopy(PExpr*src); explicit PENewCopy(PExpr*src);
~PENewCopy(); ~PENewCopy() override;
virtual void dump(std::ostream&) const; virtual void dump(std::ostream&) const override;
// Class objects don't have a useful width, but the expression // Class objects don't have a useful width, but the expression
// is IVL_VT_CLASS. // is IVL_VT_CLASS.
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
// Note that class (new) expressions only appear in context // Note that class (new) expressions only appear in context
// that uses this form of the elaborate_expr method. In fact, // that uses this form of the elaborate_expr method. In fact,
// the type argument is going to be a netclass_t object. // the type argument is going to be a netclass_t object.
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const; ivl_type_t type, unsigned flags) const override;
private: private:
PExpr*src_; PExpr*src_;
@ -604,38 +625,39 @@ class PENewCopy : public PExpr {
class PENull : public PExpr { class PENull : public PExpr {
public: public:
explicit PENull(); explicit PENull();
~PENull(); ~PENull() override;
virtual void dump(std::ostream&) const; virtual void dump(std::ostream&) const override;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const; ivl_type_t type, unsigned flags) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const; unsigned flags) const override;
}; };
class PENumber : public PExpr { class PENumber : public PExpr {
public: public:
explicit PENumber(verinum*vp); explicit PENumber(verinum*vp);
~PENumber(); ~PENumber() override;
const verinum& value() const; const verinum& value() const;
virtual void dump(std::ostream&) const; virtual void dump(std::ostream&) const override;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
virtual NetExpr *elaborate_expr(Design*des, NetScope*scope, virtual NetExpr *elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const; ivl_type_t type, unsigned flags) const override;
virtual NetEConst*elaborate_expr(Design*des, NetScope*, virtual NetEConst*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned) const; unsigned expr_wid, unsigned) const override;
virtual NetAssign_* elaborate_lval(Design*des, virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope, NetScope*scope,
bool is_cassign, bool is_cassign,
bool is_force) const; bool is_force,
bool is_init = false) const override;
private: private:
verinum*const value_; verinum*const value_;
@ -652,20 +674,24 @@ class PEString : public PExpr {
public: public:
explicit PEString(char*s); explicit PEString(char*s);
~PEString(); ~PEString() override;
std::string value() const; std::string value() const;
virtual void dump(std::ostream&) const; virtual void dump(std::ostream&) const override;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); 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; ivl_type_t type, unsigned flags) const override;
virtual NetEConst*elaborate_expr(Design*des, NetScope*, virtual NetEConst*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned) const; 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: private:
char*text_; char*text_;
}; };
@ -673,13 +699,13 @@ class PEString : public PExpr {
class PETypename : public PExpr { class PETypename : public PExpr {
public: public:
explicit PETypename(data_type_t*data_type); explicit PETypename(data_type_t*data_type);
~PETypename(); ~PETypename() override;
virtual void dump(std::ostream&) const; virtual void dump(std::ostream&) const override;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const; ivl_type_t type, unsigned flags) const override;
inline data_type_t* get_type() const { return data_type_; } inline data_type_t* get_type() const { return data_type_; }
@ -691,20 +717,20 @@ class PEUnary : public PExpr {
public: public:
explicit PEUnary(char op, PExpr*ex); explicit PEUnary(char op, PExpr*ex);
~PEUnary(); ~PEUnary() override;
virtual void dump(std::ostream&out) const; virtual void dump(std::ostream&out) const override;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override;
virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual bool has_aa_term(Design*des, NetScope*scope) const override;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const; unsigned flags) const override;
public: public:
inline char get_op() const { return op_; } inline char get_op() const { return op_; }
@ -722,20 +748,20 @@ class PEBinary : public PExpr {
public: public:
explicit PEBinary(char op, PExpr*l, PExpr*r); explicit PEBinary(char op, PExpr*l, PExpr*r);
~PEBinary(); ~PEBinary() override;
virtual void dump(std::ostream&out) const; virtual void dump(std::ostream&out) const override;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override;
virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual bool has_aa_term(Design*des, NetScope*scope) const override;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const; unsigned flags) const override;
protected: protected:
char op_; char op_;
@ -766,13 +792,13 @@ class PEBComp : public PEBinary {
public: public:
explicit PEBComp(char op, PExpr*l, PExpr*r); explicit PEBComp(char op, PExpr*l, PExpr*r);
~PEBComp(); ~PEBComp() override;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
NetExpr* elaborate_expr(Design*des, NetScope*scope, NetExpr* elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags) const; unsigned expr_wid, unsigned flags) const override;
private: private:
unsigned l_width_; unsigned l_width_;
@ -786,13 +812,13 @@ class PEBLogic : public PEBinary {
public: public:
explicit PEBLogic(char op, PExpr*l, PExpr*r); explicit PEBLogic(char op, PExpr*l, PExpr*r);
~PEBLogic(); ~PEBLogic() override;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
NetExpr* elaborate_expr(Design*des, NetScope*scope, NetExpr* elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags) const; unsigned expr_wid, unsigned flags) const override;
}; };
/* /*
@ -804,38 +830,38 @@ class PEBLeftWidth : public PEBinary {
public: public:
explicit PEBLeftWidth(char op, PExpr*l, PExpr*r); explicit PEBLeftWidth(char op, PExpr*l, PExpr*r);
~PEBLeftWidth() =0; ~PEBLeftWidth() override =0;
virtual NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp, virtual NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
unsigned expr_wid) const =0; unsigned expr_wid) const =0;
protected: protected:
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const; unsigned flags) const override;
}; };
class PEBPower : public PEBLeftWidth { class PEBPower : public PEBLeftWidth {
public: public:
explicit PEBPower(char op, PExpr*l, PExpr*r); explicit PEBPower(char op, PExpr*l, PExpr*r);
~PEBPower(); ~PEBPower() override;
NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp, NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
unsigned expr_wid) const; unsigned expr_wid) const override;
}; };
class PEBShift : public PEBLeftWidth { class PEBShift : public PEBLeftWidth {
public: public:
explicit PEBShift(char op, PExpr*l, PExpr*r); explicit PEBShift(char op, PExpr*l, PExpr*r);
~PEBShift(); ~PEBShift() override;
NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp, NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
unsigned expr_wid) const; unsigned expr_wid) const override;
}; };
/* /*
@ -846,20 +872,20 @@ class PETernary : public PExpr {
public: public:
explicit PETernary(PExpr*e, PExpr*t, PExpr*f); explicit PETernary(PExpr*e, PExpr*t, PExpr*f);
~PETernary(); ~PETernary() override;
virtual void dump(std::ostream&out) const; virtual void dump(std::ostream&out) const override;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override;
virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual bool has_aa_term(Design*des, NetScope*scope) const override;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const; unsigned flags) const override;
private: private:
NetExpr* elab_and_eval_alternative_(Design*des, NetScope*scope, NetExpr* elab_and_eval_alternative_(Design*des, NetScope*scope,
@ -879,43 +905,53 @@ class PETernary : public PExpr {
*/ */
class PECallFunction : public PExpr { class PECallFunction : public PExpr {
public: public:
explicit PECallFunction(const pform_name_t&n, const std::vector<PExpr *> &parms); explicit PECallFunction(const pform_name_t &n, const std::vector<named_pexpr_t> &parms);
// Call function defined in package. // Call function defined in package.
explicit PECallFunction(PPackage*pkg, perm_string n, const std::vector<PExpr *> &parms); explicit PECallFunction(PPackage *pkg, const pform_name_t &n, const std::list<named_pexpr_t> &parms);
explicit PECallFunction(PPackage*pkg, perm_string n, const std::list<PExpr *> &parms);
// Used to convert a user function called as a task // Used to convert a user function called as a task
explicit PECallFunction(PPackage*pkg, const pform_name_t&n, const std::vector<PExpr *> &parms); explicit PECallFunction(PPackage *pkg, const pform_name_t &n, const std::vector<named_pexpr_t> &parms);
// Call of system function (name is not hierarchical) // Call of system function (name is not hierarchical)
explicit PECallFunction(perm_string n, const std::vector<PExpr *> &parms); explicit PECallFunction(perm_string n, const std::vector<named_pexpr_t> &parms);
explicit PECallFunction(perm_string n); explicit PECallFunction(perm_string n);
// std::list versions. Should be removed! // std::list versions. Should be removed!
explicit PECallFunction(const pform_name_t&n, const std::list<PExpr *> &parms); explicit PECallFunction(const pform_name_t &n, const std::list<named_pexpr_t> &parms);
explicit PECallFunction(perm_string n, const std::list<PExpr *> &parms); explicit PECallFunction(perm_string n, const std::list<named_pexpr_t> &parms);
~PECallFunction(); // 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);
virtual void dump(std::ostream &) const; ~PECallFunction() override;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); // 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 bool has_aa_term(Design*des, NetScope*scope) const; virtual void dump(std::ostream &) const override;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override;
virtual bool has_aa_term(Design*des, NetScope*scope) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const; ivl_type_t type, unsigned flags) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags) const; unsigned expr_wid, unsigned flags) const override;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
private: private:
PPackage*package_; pform_scoped_name_t path_;
pform_name_t path_; std::vector<named_pexpr_t> parms_;
std::vector<PExpr *> parms_; // If non-null, this call is prefix().tail_name(...) (SV method chain).
PExpr* chain_prefix_ = nullptr;
// For system functions. // For system functions.
bool is_overridden_; bool is_overridden_;
@ -928,14 +964,11 @@ class PECallFunction : public PExpr {
NetExpr* elaborate_expr_(Design *des, NetScope *scope, NetExpr* elaborate_expr_(Design *des, NetScope *scope,
unsigned flags) const; unsigned flags) const;
NetExpr*elaborate_expr_pkg_(Design*des, NetScope*scope,
unsigned flags)const;
NetExpr* elaborate_expr_method_(Design*des, NetScope*scope, NetExpr* elaborate_expr_method_(Design*des, NetScope*scope,
symbol_search_results&search_results) symbol_search_results&search_results)
const; const;
NetExpr* elaborate_expr_method_par_(Design*des, NetScope*scope, NetExpr* elaborate_expr_method_par_(Design*des, const NetScope*scope,
symbol_search_results&search_results) const symbol_search_results&search_results)
const; const;
@ -947,16 +980,35 @@ class PECallFunction : public PExpr {
unsigned test_width_sfunc_(Design*des, NetScope*scope, unsigned test_width_sfunc_(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode);
unsigned test_width_method_(Design*des, NetScope*scope, unsigned test_width_method_(Design*des, NetScope*scope,
symbol_search_results&search_results, const symbol_search_results&search_results,
width_mode_t&mode); width_mode_t&mode);
NetExpr*elaborate_base_(Design*des, NetScope*scope, NetScope*dscope, NetExpr*elaborate_base_(Design*des, NetScope*scope, NetScope*dscope,
unsigned flags) const; unsigned flags) const;
unsigned elaborate_arguments_(Design*des, NetScope*scope, unsigned elaborate_arguments_(Design*des, NetScope*scope,
NetFuncDef*def, bool need_const, const NetFuncDef*def, bool need_const,
std::vector<NetExpr*>&parms, 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);
}; };
/* /*
@ -966,18 +1018,18 @@ class PECastSize : public PExpr {
public: public:
explicit PECastSize(PExpr*size, PExpr*base); explicit PECastSize(PExpr*size, PExpr*base);
~PECastSize(); ~PECastSize() override;
void dump(std::ostream &out) const; void dump(std::ostream &out) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const; unsigned flags) const override;
virtual bool has_aa_term(Design *des, NetScope *scope) const; virtual bool has_aa_term(Design *des, NetScope *scope) const override;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
private: private:
PExpr* size_; PExpr* size_;
@ -991,20 +1043,20 @@ class PECastType : public PExpr {
public: public:
explicit PECastType(data_type_t*target, PExpr*base); explicit PECastType(data_type_t*target, PExpr*base);
~PECastType(); ~PECastType() override;
void dump(std::ostream &out) const; void dump(std::ostream &out) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const; ivl_type_t type, unsigned flags) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags) const; unsigned expr_wid, unsigned flags) const override;
virtual bool has_aa_term(Design *des, NetScope *scope) const; virtual bool has_aa_term(Design *des, NetScope *scope) const override;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode) override;
private: private:
data_type_t* target_; data_type_t* target_;
@ -1019,16 +1071,16 @@ class PECastSign : public PExpr {
public: public:
explicit PECastSign(bool signed_flag, PExpr *base); explicit PECastSign(bool signed_flag, PExpr *base);
~PECastSign() = default; ~PECastSign() override = default;
void dump(std::ostream &out) const; void dump(std::ostream &out) const override;
NetExpr* elaborate_expr(Design *des, NetScope *scope, NetExpr* elaborate_expr(Design *des, NetScope *scope,
unsigned expr_wid, unsigned flags) const; unsigned expr_wid, unsigned flags) const override;
virtual bool has_aa_term(Design *des, NetScope *scope) const; virtual bool has_aa_term(Design *des, NetScope *scope) const override;
unsigned test_width(Design *des, NetScope *scope, width_mode_t &mode); unsigned test_width(Design *des, NetScope *scope, width_mode_t &mode) override;
private: private:
std::unique_ptr<PExpr> base_; std::unique_ptr<PExpr> base_;
@ -1042,11 +1094,11 @@ class PEVoid : public PExpr {
public: public:
explicit PEVoid(); explicit PEVoid();
~PEVoid(); ~PEVoid() override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const; unsigned flags) const override;
}; };
#endif /* IVL_PExpr_H */ #endif /* IVL_PExpr_H */

View File

@ -20,7 +20,6 @@
# include "config.h" # include "config.h"
# include "PTask.h" # include "PTask.h"
# include "Statement.h" # include "Statement.h"
# include <cassert>
# include "ivl_assert.h" # include "ivl_assert.h"
using namespace std; using namespace std;
@ -38,8 +37,8 @@ PFunction::~PFunction()
void PFunction::set_statement(Statement*s) void PFunction::set_statement(Statement*s)
{ {
assert(s != 0); ivl_assert(*this, s != 0);
assert(statement_ == 0); ivl_assert(*this, statement_ == 0);
statement_ = s; statement_ = s;
} }

View File

@ -1,5 +1,5 @@
/* /*
* 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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -22,48 +22,42 @@
# include "PGate.h" # include "PGate.h"
# include "PExpr.h" # include "PExpr.h"
# include "verinum.h" # include "verinum.h"
# include <cassert> # include "ivl_assert.h"
using namespace std; using namespace std;
void PGate::set_pins_(list<PExpr*>*pins) void PGate::set_pins_(list<PExpr*>*pins)
{ {
assert(pins); ivl_assert(*this, pins);
assert(pins->size() == pins_.size()); ivl_assert(*this, pins->size() == pins_.size());
for (size_t idx = 0 ; idx < pins_.size() ; idx += 1) { for (size_t idx = 0 ; idx < pins_.size() ; idx += 1) {
pins_[idx] = pins->front(); pins_[idx] = pins->front();
pins->pop_front(); pins->pop_front();
} }
assert(pins->empty()); ivl_assert(*this, pins->empty());
delete pins; delete pins;
} }
PGate::PGate(perm_string name, list<PExpr*>*pins, const list<PExpr*>*del) 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 (pins) set_pins_(pins);
if (del) delay_.set_delays(del); if (del) delay_.set_delays(del);
str0_ = IVL_DR_STRONG;
str1_ = IVL_DR_STRONG;
} }
PGate::PGate(perm_string name, list<PExpr*>*pins, PExpr*del) 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 (pins) set_pins_(pins);
if (del) delay_.set_delay(del); if (del) delay_.set_delay(del);
str0_ = IVL_DR_STRONG;
str1_ = IVL_DR_STRONG;
} }
PGate::PGate(perm_string name, list<PExpr*>*pins) 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); if (pins) set_pins_(pins);
str0_ = IVL_DR_STRONG;
str1_ = IVL_DR_STRONG;
} }
PGate::~PGate() PGate::~PGate()
@ -72,28 +66,18 @@ PGate::~PGate()
void PGate::set_ranges(list<pform_range_t>*ranges) void PGate::set_ranges(list<pform_range_t>*ranges)
{ {
assert(ranges_ == 0); ivl_assert(*this, ranges_ == 0);
ranges_ = 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; strength_ = str;
}
ivl_drive_t PGate::strength1() const
{
return str1_;
}
void PGate::strength1(ivl_drive_t s)
{
str1_ = s;
} }
void PGate::elaborate_scope(Design*, NetScope*) const void PGate::elaborate_scope(Design*, NetScope*) const
@ -109,15 +93,10 @@ void PGate::elaborate_scope(Design*, NetScope*) const
* numbers of expressions. * numbers of expressions.
*/ */
void PGate::eval_delays(Design*des, NetScope*scope, void PGate::eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays,
NetExpr*&rise_expr,
NetExpr*&fall_expr,
NetExpr*&decay_expr,
bool as_net_flag) const bool as_net_flag) const
{ {
delay_.eval_delays(des, scope, delay_.eval_delays(des, scope, delays, as_net_flag);
rise_expr, fall_expr, decay_expr,
as_net_flag);
} }
unsigned PGate::delay_count() const unsigned PGate::delay_count() const
@ -133,13 +112,13 @@ PNamedItem::SymbolType PGate::symbol_type() const
PGAssign::PGAssign(list<PExpr*>*pins) PGAssign::PGAssign(list<PExpr*>*pins)
: PGate(perm_string(), pins) : PGate(perm_string(), pins)
{ {
assert(pin_count() == 2); ivl_assert(*this, pin_count() == 2);
} }
PGAssign::PGAssign(list<PExpr*>*pins, list<PExpr*>*dels) PGAssign::PGAssign(list<PExpr*>*pins, list<PExpr*>*dels)
: PGate(perm_string(), pins, dels) : PGate(perm_string(), pins, dels)
{ {
assert(pin_count() == 2); ivl_assert(*this, pin_count() == 2);
} }
PGAssign::~PGAssign() PGAssign::~PGAssign()
@ -148,7 +127,7 @@ PGAssign::~PGAssign()
PGBuiltin::PGBuiltin(Type t, perm_string name, PGBuiltin::PGBuiltin(Type t, perm_string name,
list<PExpr*>*pins, list<PExpr*>*pins,
list<PExpr*>*del) const list<PExpr*>*del)
: PGate(name, pins, del), type_(t) : PGate(name, pins, del), type_(t)
{ {
} }
@ -270,7 +249,7 @@ PGModule::PGModule(perm_string type, perm_string name, list<PExpr*>*pins)
} }
PGModule::PGModule(perm_string type, perm_string name, PGModule::PGModule(perm_string type, perm_string name,
named<PExpr*>*pins, unsigned npins) named_pexpr_t *pins, unsigned npins)
: PGate(name, 0), bound_type_(0), type_(type), overrides_(0), pins_(pins), : PGate(name, 0), bound_type_(0), type_(type), overrides_(0), pins_(pins),
npins_(npins), parms_(0), nparms_(0) npins_(npins), parms_(0), nparms_(0)
{ {
@ -288,14 +267,14 @@ PGModule::~PGModule()
void PGModule::set_parameters(list<PExpr*>*o) void PGModule::set_parameters(list<PExpr*>*o)
{ {
assert(overrides_ == 0); ivl_assert(*this, overrides_ == 0);
overrides_ = o; overrides_ = o;
} }
void PGModule::set_parameters(named<PExpr*>*pa, unsigned npa) void PGModule::set_parameters(named_pexpr_t *pa, unsigned npa)
{ {
assert(parms_ == 0); ivl_assert(*this, parms_ == 0);
assert(overrides_ == 0); ivl_assert(*this, overrides_ == 0);
parms_ = pa; parms_ = pa;
nparms_ = npa; nparms_ = npa;
} }

74
PGate.h
View File

@ -1,7 +1,7 @@
#ifndef IVL_PGate_H #ifndef IVL_PGate_H
#define IVL_PGate_H #define IVL_PGate_H
/* /*
* 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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -31,6 +31,8 @@
class PExpr; class PExpr;
class PUdp; class PUdp;
class Module; class Module;
struct delay_exprs_t;
struct drive_strength_t;
/* /*
* A PGate represents a Verilog gate. The gate has a name and other * A PGate represents a Verilog gate. The gate has a name and other
@ -57,7 +59,7 @@ class PGate : public PNamedItem {
explicit PGate(perm_string name, std::list<PExpr*>*pins); explicit PGate(perm_string name, std::list<PExpr*>*pins);
virtual ~PGate(); virtual ~PGate() override;
void set_ranges(std::list<pform_range_t>*ranges); void set_ranges(std::list<pform_range_t>*ranges);
bool is_array() const { return ranges_ != 0; } bool is_array() const { return ranges_ != 0; }
@ -66,10 +68,7 @@ class PGate : public PNamedItem {
// This evaluates the delays as far as possible, but returns // This evaluates the delays as far as possible, but returns
// an expression, and do not signal errors. // an expression, and do not signal errors.
void eval_delays(Design*des, NetScope*scope, void eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays,
NetExpr*&rise_time,
NetExpr*&fall_time,
NetExpr*&decay_time,
bool as_net_flag =false) const; bool as_net_flag =false) const;
unsigned delay_count() const; unsigned delay_count() const;
@ -77,11 +76,9 @@ class PGate : public PNamedItem {
unsigned pin_count() const { return pins_.size(); } unsigned pin_count() const { return pins_.size(); }
PExpr*pin(unsigned idx) const { return pins_[idx]; } PExpr*pin(unsigned idx) const { return pins_[idx]; }
ivl_drive_t strength0() const; drive_strength_t strength() const;
ivl_drive_t strength1() const;
void strength0(ivl_drive_t); void strength(const drive_strength_t &str);
void strength1(ivl_drive_t);
std::map<perm_string,PExpr*> attributes; std::map<perm_string,PExpr*> attributes;
@ -90,7 +87,7 @@ class PGate : public PNamedItem {
virtual void elaborate_scope(Design*des, NetScope*sc) const; virtual void elaborate_scope(Design*des, NetScope*sc) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const; virtual bool elaborate_sig(Design*des, NetScope*scope) const;
SymbolType symbol_type() const; SymbolType symbol_type() const override;
protected: protected:
const std::vector<PExpr*>& get_pins() const { return pins_; } const std::vector<PExpr*>& get_pins() const { return pins_; }
@ -109,7 +106,7 @@ class PGate : public PNamedItem {
std::list<pform_range_t>*ranges_; std::list<pform_range_t>*ranges_;
ivl_drive_t str0_, str1_; drive_strength_t strength_;
void set_pins_(std::list<PExpr*>*pins); void set_pins_(std::list<PExpr*>*pins);
@ -127,14 +124,15 @@ class PGAssign : public PGate {
public: public:
explicit PGAssign(std::list<PExpr*>*pins); explicit PGAssign(std::list<PExpr*>*pins);
explicit PGAssign(std::list<PExpr*>*pins, std::list<PExpr*>*dels); explicit PGAssign(std::list<PExpr*>*pins, std::list<PExpr*>*dels);
~PGAssign(); ~PGAssign() override;
void dump(std::ostream&out, unsigned ind =4) const; void dump(std::ostream&out, unsigned ind =4) const override;
virtual void elaborate(Design*des, NetScope*scope) const; virtual void elaborate(Design*des, NetScope*scope) const override;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
private: 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;
}; };
@ -159,18 +157,17 @@ class PGBuiltin : public PGate {
public: public:
explicit PGBuiltin(Type t, perm_string name, explicit PGBuiltin(Type t, perm_string name,
std::list<PExpr*>*pins, std::list<PExpr*>*pins,
std::list<PExpr*>*del); const std::list<PExpr*>*del);
explicit PGBuiltin(Type t, perm_string name, explicit PGBuiltin(Type t, perm_string name,
std::list<PExpr*>*pins, std::list<PExpr*>*pins,
PExpr*del); PExpr*del);
~PGBuiltin(); ~PGBuiltin() override;
Type type() const { return type_; } Type type() const { return type_; }
const char * gate_name() const; const char * gate_name() const;
virtual void dump(std::ostream&out, unsigned ind =4) const; virtual void dump(std::ostream&out, unsigned ind =4) const override;
virtual void elaborate(Design*, NetScope*scope) const; virtual void elaborate(Design*, NetScope*scope) const override;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
private: private:
void calculate_gate_and_lval_count_(unsigned&gate_count, void calculate_gate_and_lval_count_(unsigned&gate_count,
@ -204,25 +201,23 @@ class PGModule : public PGate {
// If the binding of ports is by name, this constructor takes // If the binding of ports is by name, this constructor takes
// the bindings and stores them for later elaboration. // the bindings and stores them for later elaboration.
explicit PGModule(perm_string type, perm_string name, explicit PGModule(perm_string type, perm_string name,
named<PExpr*>*pins, unsigned npins); named_pexpr_t *pins, unsigned npins);
// If the module type is known by design, then use this // If the module type is known by design, then use this
// constructor. // constructor.
explicit PGModule(Module*type, perm_string name); explicit PGModule(Module*type, perm_string name);
~PGModule(); ~PGModule() override;
// Parameter overrides can come as an ordered list, or a set // Parameter overrides can come as an ordered list, or a set
// of named expressions. // of named expressions.
void set_parameters(std::list<PExpr*>*o); void set_parameters(std::list<PExpr*>*o);
void set_parameters(named<PExpr*>*pa, unsigned npa); void set_parameters(named_pexpr_t *pa, unsigned npa);
std::map<perm_string,PExpr*> attributes; virtual void dump(std::ostream&out, unsigned ind =4) const override;
virtual void elaborate(Design*, NetScope*scope) const override;
virtual void dump(std::ostream&out, unsigned ind =4) const; virtual void elaborate_scope(Design*des, NetScope*sc) const override;
virtual void elaborate(Design*, NetScope*scope) const; virtual bool elaborate_sig(Design*des, NetScope*scope) const override;
virtual void elaborate_scope(Design*des, NetScope*sc) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
// This returns the module name of this module. It is a // This returns the module name of this module. It is a
// permallocated string. // permallocated string.
@ -232,19 +227,28 @@ class PGModule : public PGate {
Module*bound_type_; Module*bound_type_;
perm_string type_; perm_string type_;
std::list<PExpr*>*overrides_; std::list<PExpr*>*overrides_;
named<PExpr*>*pins_; named_pexpr_t *pins_;
unsigned npins_; unsigned npins_;
// These members support parameter override by name // These members support parameter override by name
named<PExpr*>*parms_; named_pexpr_t *parms_;
unsigned nparms_; unsigned nparms_;
friend class delayed_elaborate_scope_mod_instances; 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_udp_(Design*, PUdp *udp, NetScope*scope) const;
void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const; void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const;
void elaborate_scope_mod_instances_(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, Module*mod) 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. // Not currently used.
#if 0 #if 0
bool elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const; bool elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const;

View File

@ -1,7 +1,7 @@
#ifndef IVL_PGenerate_H #ifndef IVL_PGenerate_H
#define IVL_PGenerate_H #define IVL_PGenerate_H
/* /*
* Copyright (c) 2006-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 2006-2025 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -26,10 +26,12 @@
# include <list> # include <list>
# include <map> # include <map>
# include <valarray> # include <valarray>
# include <vector>
# include "pform_types.h" # include "pform_types.h"
class Design; class Design;
class NetScope; class NetScope;
class PClass;
class PExpr; class PExpr;
class PFunction; class PFunction;
class PProcess; class PProcess;
@ -54,7 +56,7 @@ class PGenerate : public PNamedItem, public LexicalScope {
public: public:
explicit PGenerate(LexicalScope*parent, unsigned id_number); explicit PGenerate(LexicalScope*parent, unsigned id_number);
~PGenerate(); ~PGenerate() override;
// Generate schemes have an ID number, for when the scope is // Generate schemes have an ID number, for when the scope is
// implicit. // implicit.
@ -92,9 +94,11 @@ class PGenerate : public PNamedItem, public LexicalScope {
std::list<PGate*> gates; std::list<PGate*> gates;
void add_gate(PGate*); void add_gate(PGate*);
// Tasks instantiated within this scheme. // Definitions instantiated within this scheme.
std::map<perm_string,PTask*> tasks; std::map<perm_string,PTask*> tasks;
std::map<perm_string,PFunction*>funcs; std::map<perm_string,PFunction*>funcs;
std::map<perm_string,PClass*> classes;
std::vector<PClass*> classes_lexical;
// Generate schemes can contain further generate schemes. // Generate schemes can contain further generate schemes.
std::list<PGenerate*> generate_schemes; std::list<PGenerate*> generate_schemes;
@ -112,7 +116,7 @@ class PGenerate : public PNamedItem, public LexicalScope {
void dump(std::ostream&out, unsigned indent) const; void dump(std::ostream&out, unsigned indent) const;
SymbolType symbol_type() const; SymbolType symbol_type() const override;
private: private:
void check_for_valid_genvar_value_(long value); void check_for_valid_genvar_value_(long value);

View File

@ -1,7 +1,7 @@
#ifndef IVL_PModport_H #ifndef IVL_PModport_H
#define IVL_PModport_H #define IVL_PModport_H
/* /*
* Copyright (c) 2015-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 2015-2025 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -34,14 +34,14 @@ class PModport : public PNamedItem {
// The name is a perm-allocated string. It is the simple name // The name is a perm-allocated string. It is the simple name
// of the modport, without any scope. // of the modport, without any scope.
explicit PModport(perm_string name); explicit PModport(perm_string name);
~PModport(); ~PModport() override;
perm_string name() const { return name_; } perm_string name() const { return name_; }
typedef std::pair <NetNet::PortType,PExpr*> simple_port_t; typedef std::pair <NetNet::PortType,PExpr*> simple_port_t;
std::map<perm_string,simple_port_t> simple_ports; std::map<perm_string,simple_port_t> simple_ports;
SymbolType symbol_type() const; SymbolType symbol_type() const override;
private: private:
perm_string name_; perm_string name_;

View File

@ -1,7 +1,7 @@
#ifndef IVL_PNamedItem_H #ifndef IVL_PNamedItem_H
#define IVL_PNamedItem_H #define IVL_PNamedItem_H
/* /*
* Copyright (c) 2019 Martin Whitaker (icarus@martin-whitaker.me.uk) * Copyright (c) 2019-2025 Martin Whitaker (icarus@martin-whitaker.me.uk)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -34,7 +34,7 @@ class PNamedItem : virtual public LineInfo {
INSTANCE }; INSTANCE };
explicit PNamedItem(); explicit PNamedItem();
virtual ~PNamedItem(); virtual ~PNamedItem() override;
virtual SymbolType symbol_type() const; virtual SymbolType symbol_type() const;
}; };
@ -49,9 +49,9 @@ class PGenvar : public PNamedItem {
public: public:
explicit PGenvar(); explicit PGenvar();
virtual ~PGenvar(); virtual ~PGenvar() override;
SymbolType symbol_type() const; SymbolType symbol_type() const override;
}; };
#endif /* IVL_PNamedItem_H */ #endif /* IVL_PNamedItem_H */

View File

@ -1,7 +1,7 @@
#ifndef IVL_PPackage_H #ifndef IVL_PPackage_H
#define IVL_PPackage_H #define IVL_PPackage_H
/* /*
* Copyright (c) 2012-2014 Stephen Williams (steve@icarus.com) * Copyright (c) 2012-2025 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
@ -24,6 +24,7 @@
# include "LineInfo.h" # include "LineInfo.h"
# include "StringHeap.h" # include "StringHeap.h"
# include <iostream> # include <iostream>
# include <vector>
/* /*
* SystemVerilog supports class declarations with their own lexical * SystemVerilog supports class declarations with their own lexical
@ -35,13 +36,20 @@ class PPackage : public PScopeExtra, public LineInfo {
public: public:
explicit PPackage (perm_string name, LexicalScope*parent); explicit PPackage (perm_string name, LexicalScope*parent);
~PPackage(); ~PPackage() override;
bool elaborate_scope(Design*des, NetScope*scope); bool elaborate_scope(Design*des, NetScope*scope);
bool elaborate_sig(Design*des, NetScope*scope) const; bool elaborate_sig(Design*des, NetScope*scope) const;
bool elaborate(Design*des, NetScope*scope) const; bool elaborate(Design*des, NetScope*scope) const;
void pform_dump(std::ostream&out) const; void pform_dump(std::ostream&out) const;
struct export_t {
PPackage *pkg;
perm_string name;
};
std::vector<export_t> exports;
}; };
#endif /* IVL_PPackage_H */ #endif /* IVL_PPackage_H */

View File

@ -1,7 +1,7 @@
#ifndef IVL_PScope_H #ifndef IVL_PScope_H
#define IVL_PScope_H #define IVL_PScope_H
/* /*
* Copyright (c) 2008-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 2008-2026 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -25,6 +25,7 @@
# include "ivl_target.h" # include "ivl_target.h"
# include <map> # include <map>
# include <set> # include <set>
# include <unordered_set>
# include <vector> # include <vector>
class PEvent; class PEvent;
@ -67,9 +68,14 @@ class LexicalScope {
// Symbols that are defined or declared in this scope. // Symbols that are defined or declared in this scope.
std::map<perm_string,PNamedItem*>local_symbols; std::map<perm_string,PNamedItem*>local_symbols;
// Symbols that are explicitly imported. Bind the imported name // Symbols that are explicitly imported. This contains the package where
// to the package from which the name is imported. // 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; std::map<perm_string,PPackage*>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.
std::map<perm_string,std::unordered_set<PPackage*>> explicit_imports_from;
// Packages that are wildcard imported. When identifiers from // Packages that are wildcard imported. When identifiers from
// these packages are referenced, they will be added to the // these packages are referenced, they will be added to the
@ -115,6 +121,10 @@ class LexicalScope {
bool overridable; bool overridable;
// Whether the parameter is a type parameter // Whether the parameter is a type parameter
bool type_flag = false; 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;
SymbolType symbol_type() const; SymbolType symbol_type() const;
}; };
@ -190,7 +200,7 @@ class PScope : public LexicalScope {
// modules. Scopes for tasks and functions point to their // modules. Scopes for tasks and functions point to their
// containing module. // containing module.
explicit PScope(perm_string name, LexicalScope*parent =0); explicit PScope(perm_string name, LexicalScope*parent =0);
virtual ~PScope(); virtual ~PScope() override;
perm_string pscope_name() const { return name_; } perm_string pscope_name() const { return name_; }
@ -225,7 +235,7 @@ class PScopeExtra : public PScope {
public: public:
explicit PScopeExtra(perm_string, LexicalScope*parent =0); explicit PScopeExtra(perm_string, LexicalScope*parent =0);
~PScopeExtra(); ~PScopeExtra() override;
/* Task definitions within this module */ /* Task definitions within this module */
std::map<perm_string,PTask*> tasks; std::map<perm_string,PTask*> tasks;

View File

@ -19,10 +19,11 @@
# include "PSpec.h" # include "PSpec.h"
PSpecPath::PSpecPath(unsigned src_cnt, unsigned dst_cnt, char polarity, PSpecPath::PSpecPath(const std::list<perm_string> &src_list,
bool full_flag) const std::list<perm_string> &dst_list,
char polarity, bool full_flag)
: conditional(false), condition(0), edge(0), : conditional(false), condition(0), edge(0),
src(src_cnt), dst(dst_cnt), src(src_list.begin(), src_list.end()), dst(dst_list.begin(), dst_list.end()),
data_source_expression(0) data_source_expression(0)
{ {
full_flag_ = full_flag; full_flag_ = full_flag;

10
PSpec.h
View File

@ -1,7 +1,7 @@
#ifndef IVL_PSpec_H #ifndef IVL_PSpec_H
#define IVL_PSpec_H #define IVL_PSpec_H
/* /*
* Copyright (c) 2006-2014 Stephen Williams <steve@icarus.com> * Copyright (c) 2006-2025 Stephen Williams <steve@icarus.com>
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -22,6 +22,7 @@
# include "LineInfo.h" # include "LineInfo.h"
# include "StringHeap.h" # include "StringHeap.h"
# include <vector> # include <vector>
# include <list>
class PExpr; class PExpr;
@ -56,9 +57,10 @@ class PExpr;
class PSpecPath : public LineInfo { class PSpecPath : public LineInfo {
public: public:
PSpecPath(unsigned src_cnt, unsigned dst_cnt, char polarity, PSpecPath(const std::list<perm_string> &src_list,
bool full_flag); const std::list<perm_string> &dst_list,
~PSpecPath(); char polarity, bool full_flag);
~PSpecPath() override;
void elaborate(class Design*des, class NetScope*scope) const; void elaborate(class Design*des, class NetScope*scope) const;

View File

@ -18,8 +18,8 @@
*/ */
# include "config.h" # include "config.h"
# include "PTask.h" # include "PTask.h"
# include <cassert> # include "ivl_assert.h"
using namespace std; using namespace std;
@ -39,13 +39,13 @@ bool PTaskFunc::var_init_needs_explicit_lifetime() const
void PTaskFunc::set_ports(vector<pform_tf_port_t>*p) void PTaskFunc::set_ports(vector<pform_tf_port_t>*p)
{ {
assert(ports_ == 0); ivl_assert(*this, ports_ == 0);
ports_ = p; ports_ = p;
} }
void PTaskFunc::set_this(class_type_t*type, PWire*this_wire) void PTaskFunc::set_this(class_type_t*type, PWire*this_wire)
{ {
assert(this_type_ == 0); ivl_assert(*this, this_type_ == 0);
this_type_ = type; this_type_ = type;
// Push a synthesis argument that is the "this" value. // Push a synthesis argument that is the "this" value.
@ -72,7 +72,7 @@ PTask::~PTask()
void PTask::set_statement(Statement*s) void PTask::set_statement(Statement*s)
{ {
assert(statement_ == 0); ivl_assert(*this, statement_ == 0);
statement_ = s; statement_ = s;
} }

37
PTask.h
View File

@ -1,7 +1,7 @@
#ifndef IVL_PTask_H #ifndef IVL_PTask_H
#define IVL_PTask_H #define IVL_PTask_H
/* /*
* Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2025 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -39,9 +39,9 @@ class PTaskFunc : public PScope, public PNamedItem {
public: public:
PTaskFunc(perm_string name, LexicalScope*parent); PTaskFunc(perm_string name, LexicalScope*parent);
~PTaskFunc(); ~PTaskFunc() override;
bool var_init_needs_explicit_lifetime() const; bool var_init_needs_explicit_lifetime() const override;
void set_ports(std::vector<pform_tf_port_t>*p); void set_ports(std::vector<pform_tf_port_t>*p);
@ -63,7 +63,8 @@ class PTaskFunc : public PScope, public PNamedItem {
// default value expressions, if any. // default value expressions, if any.
void elaborate_sig_ports_(Design*des, NetScope*scope, void elaborate_sig_ports_(Design*des, NetScope*scope,
std::vector<NetNet*>&ports, std::vector<NetNet*>&ports,
std::vector<NetExpr*>&pdefs) const; std::vector<NetExpr*> &pdefs,
std::vector<perm_string> &port_names) const;
void dump_ports_(std::ostream&out, unsigned ind) const; void dump_ports_(std::ostream&out, unsigned ind) const;
@ -79,7 +80,7 @@ class PTask : public PTaskFunc {
public: public:
explicit PTask(perm_string name, LexicalScope*parent, bool is_auto); explicit PTask(perm_string name, LexicalScope*parent, bool is_auto);
~PTask(); ~PTask() override;
void set_statement(Statement *s); void set_statement(Statement *s);
@ -90,16 +91,16 @@ class PTask : public PTaskFunc {
void elaborate_scope(Design*des, NetScope*scope) const; void elaborate_scope(Design*des, NetScope*scope) const;
// Bind the ports to the regs that are the ports. // Bind the ports to the regs that are the ports.
void elaborate_sig(Design*des, NetScope*scope) const; void elaborate_sig(Design*des, NetScope*scope) const override;
// Elaborate the statement to finish off the task definition. // Elaborate the statement to finish off the task definition.
void elaborate(Design*des, NetScope*scope) const; void elaborate(Design*des, NetScope*scope) const override;
bool is_auto() const { return is_auto_; }; bool is_auto() const { return is_auto_; };
void dump(std::ostream&, unsigned) const; void dump(std::ostream&, unsigned) const override;
SymbolType symbol_type() const; SymbolType symbol_type() const override;
private: private:
Statement*statement_; Statement*statement_;
@ -121,7 +122,7 @@ class PFunction : public PTaskFunc {
public: public:
explicit PFunction(perm_string name, LexicalScope*parent, bool is_auto); explicit PFunction(perm_string name, LexicalScope*parent, bool is_auto);
~PFunction(); ~PFunction() override;
void set_statement(Statement *s); void set_statement(Statement *s);
void set_return(data_type_t*t); void set_return(data_type_t*t);
@ -141,16 +142,16 @@ class PFunction : public PTaskFunc {
void elaborate_scope(Design*des, NetScope*scope) const; void elaborate_scope(Design*des, NetScope*scope) const;
/* elaborate the ports and return value. */ /* elaborate the ports and return value. */
void elaborate_sig(Design *des, NetScope*) const; void elaborate_sig(Design *des, NetScope*) const override;
/* Elaborate the behavioral statement. */ /* Elaborate the behavioral statement. */
void elaborate(Design *des, NetScope*) const; void elaborate(Design *des, NetScope*) const override;
bool is_auto() const { return is_auto_; }; bool is_auto() const { return is_auto_; };
void dump(std::ostream&, unsigned) const; void dump(std::ostream&, unsigned) const override;
SymbolType symbol_type() const; SymbolType symbol_type() const override;
private: private:
data_type_t* return_type_; data_type_t* return_type_;
@ -173,12 +174,12 @@ class PLet : public PTaskFunc {
// FIXME: Should the port list be a vector. Check once implemented completely // FIXME: Should the port list be a vector. Check once implemented completely
explicit PLet(perm_string name, LexicalScope*parent, explicit PLet(perm_string name, LexicalScope*parent,
std::list<let_port_t*>*ports, PExpr*expr); std::list<let_port_t*>*ports, PExpr*expr);
~PLet(); ~PLet() override;
void elaborate_sig(Design*des, NetScope*scope) const { (void)des; (void)scope; } void elaborate_sig(Design*des, NetScope*scope) const override { (void)des; (void)scope; }
void elaborate(Design*des, NetScope*scope) const { (void)des; (void)scope; } void elaborate(Design*des, NetScope*scope) const override { (void)des; (void)scope; }
void dump(std::ostream&, unsigned) const; void dump(std::ostream&, unsigned) const override;
private: private:
std::list<let_port_t*>*ports_; std::list<let_port_t*>*ports_;

72
PTimingCheck.cc Normal file
View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2006-2023 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.
*/
# include "PTimingCheck.h"
PRecRem::PRecRem(event_t* reference_event,
event_t* data_event,
PExpr* setup_limit,
PExpr* hold_limit,
pform_name_t* notifier,
PExpr* timestamp_cond,
PExpr* timecheck_cond,
pform_name_t* delayed_reference,
pform_name_t* delayed_data)
:
reference_event_ (reference_event),
data_event_ (data_event),
setup_limit_ (setup_limit),
hold_limit_ (hold_limit),
notifier_ (notifier),
timestamp_cond_ (timestamp_cond),
timecheck_cond_ (timecheck_cond),
delayed_reference_ (delayed_reference),
delayed_data_ (delayed_data)
{
}
PRecRem::~PRecRem()
{
}
PSetupHold::PSetupHold(event_t* reference_event,
event_t* data_event,
PExpr* setup_limit,
PExpr* hold_limit,
pform_name_t* notifier,
PExpr* timestamp_cond,
PExpr* timecheck_cond,
pform_name_t* delayed_reference,
pform_name_t* delayed_data)
:
reference_event_ (reference_event),
data_event_ (data_event),
setup_limit_ (setup_limit),
hold_limit_ (hold_limit),
notifier_ (notifier),
timestamp_cond_ (timestamp_cond),
timecheck_cond_ (timecheck_cond),
delayed_reference_ (delayed_reference),
delayed_data_ (delayed_data)
{
}
PSetupHold::~PSetupHold()
{
}

139
PTimingCheck.h Normal file
View File

@ -0,0 +1,139 @@
#ifndef IVL_PTimingCheck_H
#define IVL_PTimingCheck_H
/*
* Copyright (c) 2006-2025 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.
*/
# include "LineInfo.h"
# include "PExpr.h"
# include "pform_types.h"
# include <memory>
/*
* The PTimingCheck is the base class for all timing checks
*/
class PTimingCheck : public LineInfo {
public:
enum EdgeType {EDGE_01, EDGE_0X, EDGE_10, EDGE_1X, EDGE_X0, EDGE_X1};
struct event_t {
pform_name_t name;
bool posedge;
bool negedge;
std::vector<EdgeType> edges;
std::unique_ptr<PExpr> condition;
};
// This struct is used to parse the optional arguments
struct optional_args_t {
pform_name_t* notifier = nullptr;
PExpr* timestamp_cond = nullptr;
PExpr* timecheck_cond = nullptr;
pform_name_t* delayed_reference = nullptr;
pform_name_t* delayed_data = nullptr;
PExpr* event_based_flag = nullptr;
PExpr* remain_active_flag = nullptr;
};
PTimingCheck() { }
virtual ~PTimingCheck() override { }
virtual void elaborate(class Design*des, class NetScope*scope) const = 0;
virtual void dump(std::ostream&out, unsigned ind) const = 0;
};
/*
* The PRecRem is the parse of a $recrem timing check
*/
class PRecRem : public PTimingCheck {
public:
PRecRem(event_t* reference_event,
event_t* data_event,
PExpr* setup_limit,
PExpr* hold_limit,
pform_name_t* notifier,
PExpr* timestamp_cond,
PExpr* timecheck_cond,
pform_name_t* delayed_reference,
pform_name_t* delayed_data);
~PRecRem() override;
void elaborate(class Design*des, class NetScope*scope) const override;
void dump(std::ostream&out, unsigned ind) const override;
private:
std::unique_ptr<event_t> reference_event_;
std::unique_ptr<event_t> data_event_;
std::unique_ptr<PExpr> setup_limit_;
std::unique_ptr<PExpr> hold_limit_;
std::unique_ptr<pform_name_t> notifier_;
std::unique_ptr<PExpr> timestamp_cond_;
std::unique_ptr<PExpr> timecheck_cond_;
std::unique_ptr<pform_name_t> delayed_reference_;
std::unique_ptr<pform_name_t> delayed_data_;
};
/*
* The PSetupHold is the parse of a $setuphold timing check
*/
class PSetupHold : public PTimingCheck {
public:
PSetupHold(event_t* reference_event,
event_t* data_event,
PExpr* setup_limit,
PExpr* hold_limit,
pform_name_t* notifier,
PExpr* timestamp_cond,
PExpr* timecheck_cond,
pform_name_t* delayed_reference,
pform_name_t* delayed_data);
~PSetupHold() override;
void elaborate(class Design*des, class NetScope*scope) const override;
void dump(std::ostream&out, unsigned ind) const override;
private:
std::unique_ptr<event_t> reference_event_;
std::unique_ptr<event_t> data_event_;
std::unique_ptr<PExpr> setup_limit_;
std::unique_ptr<PExpr> hold_limit_;
std::unique_ptr<pform_name_t> notifier_;
std::unique_ptr<PExpr> timestamp_cond_;
std::unique_ptr<PExpr> timecheck_cond_;
std::unique_ptr<pform_name_t> delayed_reference_;
std::unique_ptr<pform_name_t> delayed_data_;
};
#endif /* IVL_PTimingCheck_H */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2024 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -21,15 +21,15 @@
# include "ivl_assert.h" # include "ivl_assert.h"
# include "PWire.h" # include "PWire.h"
# include "PExpr.h" # include "PExpr.h"
# include <cassert>
using namespace std; using namespace std;
PWire::PWire(perm_string n, PWire::PWire(perm_string n,
unsigned lp,
NetNet::Type t, NetNet::Type t,
NetNet::PortType pt, NetNet::PortType pt,
PWSRType rt) PWSRType rt)
: name_(n), type_(t), port_type_(pt), signed_(false), : name_(n), lexical_pos_(lp), type_(t), port_type_(pt), signed_(false),
port_set_(false), net_set_(false), is_scalar_(false), port_set_(false), net_set_(false), is_scalar_(false),
error_cnt_(0), discipline_(0) error_cnt_(0), discipline_(0)
{ {
@ -59,7 +59,7 @@ perm_string PWire::basename() const
bool PWire::set_wire_type(NetNet::Type t) bool PWire::set_wire_type(NetNet::Type t)
{ {
assert(t != NetNet::IMPLICIT); ivl_assert(*this, t != NetNet::IMPLICIT);
switch (type_) { switch (type_) {
case NetNet::IMPLICIT: case NetNet::IMPLICIT:
@ -90,8 +90,8 @@ NetNet::PortType PWire::get_port_type() const
bool PWire::set_port_type(NetNet::PortType pt) bool PWire::set_port_type(NetNet::PortType pt)
{ {
assert(pt != NetNet::NOT_A_PORT); ivl_assert(*this, pt != NetNet::NOT_A_PORT);
assert(pt != NetNet::PIMPLICIT); ivl_assert(*this, pt != NetNet::PIMPLICIT);
switch (port_type_) { switch (port_type_) {
case NetNet::PIMPLICIT: case NetNet::PIMPLICIT:
@ -181,13 +181,13 @@ void PWire::set_data_type(data_type_t*type)
if (set_data_type_.get() == type) if (set_data_type_.get() == type)
return; return;
assert(!set_data_type_.get()); ivl_assert(*this, !set_data_type_.get());
set_data_type_.reset(type); set_data_type_.reset(type);
} }
void PWire::set_discipline(ivl_discipline_t d) void PWire::set_discipline(ivl_discipline_t d)
{ {
assert(discipline_ == 0); ivl_assert(*this, discipline_ == 0);
discipline_ = d; discipline_ = d;
} }

22
PWire.h
View File

@ -1,7 +1,7 @@
#ifndef IVL_PWire_H #ifndef IVL_PWire_H
#define IVL_PWire_H #define IVL_PWire_H
/* /*
* Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2025 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -55,6 +55,7 @@ class PWire : public PNamedItem {
public: public:
PWire(perm_string name, PWire(perm_string name,
unsigned lexical_pos,
NetNet::Type t, NetNet::Type t,
NetNet::PortType pt, NetNet::PortType pt,
PWSRType rt = SR_NET); PWSRType rt = SR_NET);
@ -62,12 +63,17 @@ class PWire : public PNamedItem {
// Return a hierarchical name. // Return a hierarchical name.
perm_string basename() const; perm_string basename() const;
unsigned lexical_pos() const { return lexical_pos_; }
NetNet::Type get_wire_type() const; NetNet::Type get_wire_type() const;
bool set_wire_type(NetNet::Type); bool set_wire_type(NetNet::Type);
NetNet::PortType get_port_type() const; NetNet::PortType get_port_type() const;
bool set_port_type(NetNet::PortType); bool set_port_type(NetNet::PortType);
void set_const(bool is_const) { is_const_ = is_const; };
bool get_const() const { return is_const_; };
void set_signed(bool flag); void set_signed(bool flag);
bool get_signed() const; bool get_signed() const;
@ -85,9 +91,9 @@ class PWire : public PNamedItem {
// Write myself to the specified stream. // Write myself to the specified stream.
void dump(std::ostream&out, unsigned ind=4) const; void dump(std::ostream&out, unsigned ind=4) const;
NetNet* elaborate_sig(Design*, NetScope*scope) const; NetNet* elaborate_sig(Design*, NetScope*scope);
SymbolType symbol_type() const; SymbolType symbol_type() const override;
bool is_net() const { return net_set_; }; bool is_net() const { return net_set_; };
bool is_port() const { return port_set_; }; bool is_port() const { return port_set_; };
@ -96,10 +102,16 @@ class PWire : public PNamedItem {
private: private:
perm_string name_; perm_string name_;
unsigned lexical_pos_;
NetNet::Type type_; NetNet::Type type_;
NetNet::PortType port_type_; NetNet::PortType port_type_;
bool signed_; bool signed_;
// Whether the wire is variable declared with the const keyword.
bool is_const_ = false;
bool is_elaborating_ = false;
// These members hold expressions for the bit width of the // These members hold expressions for the bit width of the
// wire. If they do not exist, the wire is 1 bit wide. If they // wire. If they do not exist, the wire is 1 bit wide. If they
// do exist, they represent the packed dimensions of the // do exist, they represent the packed dimensions of the
@ -128,10 +140,10 @@ class PWire : public PNamedItem {
PWire& operator= (const PWire&); PWire& operator= (const PWire&);
ivl_type_t elaborate_type(Design*des, NetScope*scope, ivl_type_t elaborate_type(Design*des, NetScope*scope,
const std::vector<netrange_t>&packed_dimensions) const; const netranges_t &packed_dimensions) const;
ivl_type_t elaborate_darray_type(Design*des, NetScope*scope, ivl_type_t elaborate_darray_type(Design*des, NetScope*scope,
const char *darray_type, const char *darray_type,
const std::vector<netrange_t>&packed_dimensions) const netranges_t &packed_dimensions)
const; const;
}; };

View File

@ -1,83 +0,0 @@
* Getting Started with Icarus Verilog
Icarus Verilog is a Verilog compiler. It is suitable for use as a
simulator, and, to some degree, synthesizer. Icarus Verilog runs under
Linux and a variety of UNIX systems, as well as Windows as a command
line tool, so the instructions are generally applicable to all
environments. Note that this is only a quick start. For more detailed
documentation, see the manual page for the iverilog command.
* Hello, World!
The first thing you want to do as a user is learn how to compile and
execute even the most trivial design. For the purposes of simulation,
we use as our example *the* most trivial simulation:
module main;
initial
begin
$display("Hello, World");
$finish ;
end
endmodule
By a text editor (or copy hello.vl from the Icarus Verilog examples
directory) arrange for this program to be in a text file, "hello.vl".
Next, compile this program with a command like this:
% iverilog -o hello hello.vl
The results of this compile are placed into the file "hello", as the
"-o" flag tells the compiler where to place the compiled result. Next,
execute the compiled program like so:
% vvp hello
Hello, World
And there it is, the program has been executed. So what happened? The
first step, the "iverilog" command, read and interpreted the source
file, then generated a compiled result. The compiled form may be
selected by command line switches, but the default form is the VVP
format, which is actually run by the "vvp" command.
The "iverilog" and "vvp" commands are the only commands that users
use to invoke Icarus Verilog. What the compiler actually does is
controlled by command line switches. In our little example, we asked
the compiler to compile the source program to the default vvp form,
which is in turn executed by the vvp program.
* Windows Install
The easiest way to install under Windows is to get a precompiled
installer for the version you wish to install. Icarus Verilog is
distributed for Windows users as a self-installing .exe. Just execute
the installer and follow the instructions. During the install, take
note of the directory where the program is installed: for example,
C:\iverilog is a good place to install.
Once the binary is installed, you need to add the bin directory to
your execution path. The executables you need are in C:\iverilog\bin,
where the "C:\iverilog" part is actually the root of where you
installed the package. The programs are in the bin subdirectory. Put
this directory in your PATH environment variable, and the above
commands become accessible to you at the command line prompt, or even
in batch files.
* Linux Install
Under Linux, the install is even easier. For RedHat and Mandrake based
systems, there is the appropriate RPM file. Just install the package
with the "rpm -U <file>" command. Debian users should get Icarus
Verilog packages from the main Debian software site.
* Install From Source
In this case, see README.txt and other documentation that comes with
the source.

268
README.md
View File

@ -1,15 +1,45 @@
# The ICARUS Verilog Compilation System # The ICARUS Verilog Compilation System
Copyright 2000-2019 Stephen Williams Copyright 2000-2026 Stephen Williams
<details>
<summary><h2>Table of Contents</h2></summary>
1. [What is ICARUS Verilog?](#what-is-icarus-verilog)
2. [Building/Installing Icarus Verilog From Source](#buildinginstalling-icarus-verilog-from-source)
- [Compile Time Prerequisites](#compile-time-prerequisites)
- [Compilation](#compilation)
- [(Optional) Testing](#optional-testing)
- [Installation](#installation)
3. [How Icarus Verilog Works](#how-icarus-verilog-works)
- [Preprocessing](#preprocessing)
- [Parse](#parse)
- [Elaboration](#elaboration)
- [Optimization](#optimization)
- [Code Generation](#code-generation)
- [Attributes](#attributes)
4. [Running iverilog](#running-iverilog)
- [Examples](#examples)
5. [Unsupported Constructs](#unsupported-constructs)
6. [Nonstandard Constructs or Behaviors](#nonstandard-constructs-or-behaviors)
- [Builtin system functions](#builtin-system-functions)
- [Preprocessing Library Modules](#preprocessing-library-modules)
- [Width in %t Time Formats](#width-in-t-time-formats)
- [vpiScope iterator on vpiScope objects](#vpiscope-iterator-on-vpiscope-objects)
- [Time 0 Race Resolution](#time-0-race-resolution)
- [Nets with Types](#nets-with-types)
7. [Credits](#credits)
</details>
## What is ICARUS Verilog? ## What is ICARUS Verilog?
Icarus Verilog is intended to compile ALL of the Verilog HDL as Icarus Verilog is intended to compile ALL of the Verilog HDL, as
described in the IEEE-1364 standard. Of course, it's not quite there described in the IEEE 1364 standard. Of course, it's not quite there
yet. It does currently handle a mix of structural and behavioural yet. It also compiles a (slowly growing) subset of the SystemVerilog
constructs. For a view of the current state of Icarus Verilog, see its language, as described in the IEEE 1800 standard. For a view of the
home page at http://iverilog.icarus.com/. current state of Icarus Verilog, see its home page at
https://steveicarus.github.io/iverilog/.
Icarus Verilog is not aimed at being a simulator in the traditional Icarus Verilog is not aimed at being a simulator in the traditional
sense, but a compiler that generates code employed by back-end sense, but a compiler that generates code employed by back-end
@ -18,7 +48,7 @@ tools.
> For instructions on how to run Icarus Verilog, see the `iverilog` man page. > For instructions on how to run Icarus Verilog, see the `iverilog` man page.
## Building/Installing Icarus Verilog From Source ## Building/Installing Icarus Verilog from Source
If you are starting from the source, the build process is designed to be If you are starting from the source, the build process is designed to be
as simple as practical. Someone basically familiar with the target as simple as practical. Someone basically familiar with the target
@ -26,10 +56,13 @@ system and C/C++ compilation should be able to build the source
distribution with little effort. Some actual programming skills are distribution with little effort. Some actual programming skills are
not required, but helpful in case of problems. not required, but helpful in case of problems.
> If you are building on Windows, see the mingw.txt file.
### Compile Time Prerequisites ### Compile Time Prerequisites
You can use:
```bash
apt install -y autoconf gperf make gcc g++ bison flex
```
You need the following software to compile Icarus Verilog from source You need the following software to compile Icarus Verilog from source
on a UNIX-like system: on a UNIX-like system:
@ -49,7 +82,7 @@ on a UNIX-like system:
OSX note: bison 2.3 shipped with MacOS including Catalina generates OSX note: bison 2.3 shipped with MacOS including Catalina generates
broken code, but bison 3+ works. We recommend using the Fink broken code, but bison 3+ works. We recommend using the Fink
project version of bison and flex (finkproject.org), brew version project version of bison and flex (finkproject.org), brew version
works fine either. works fine too.
- gperf 3.0 or later - gperf 3.0 or later
The lexical analyzer doesn't recognize keywords directly, The lexical analyzer doesn't recognize keywords directly,
@ -77,21 +110,29 @@ on a UNIX-like system:
### Compilation ### Compilation
Unpack the tar-ball and cd into the `verilog-#########` directory <details>
(presumably, that is how you got to this README) and compile the source <summary><h4><a href="https://github.com/steveicarus/iverilog/releases">Compiling From Release</a></h4></summary>
with the commands:
``` Unpack the tar-ball, `cd` into the `verilog-#########` directory,
and compile the source with the commands:
```bash
./configure ./configure
make make
``` ```
</details>
<details>
<summary><h4>Compiling From GitHub</h4></summary>
If you are building from git, you have to run the command below before If you are building from git, you have to run the command below before
compiling the source. This will generate the "configure" file, which is compiling the source. This will generate the "configure" file, which is
automatically done when building from tarball. automatically done when building from tarball.
``` ```bash
sh autoconf.sh sh autoconf.sh
./configure
make
``` ```
Normally, this command automatically figures out everything it needs Normally, this command automatically figures out everything it needs
@ -126,12 +167,13 @@ configure script that modify its behaviour:
i686-w64-mingw32 for building 32-bit Windows executables i686-w64-mingw32 for building 32-bit Windows executables
Both options require installing the required mingw-w64 packages. Both options require installing the required mingw-w64 packages.
``` ```
</details>
### (Optional) Testing ### (Optional) Testing
To run a simple test before installation, execute To run a simple test before installation, execute
``` ```bash
make check make check
``` ```
@ -146,7 +188,7 @@ default install in /usr/local unless you specify a different prefix
with the `--prefix=<path>` flag to the configure command.) You may need with the `--prefix=<path>` flag to the configure command.) You may need
to do this as root to gain access to installation directories. to do this as root to gain access to installation directories.
``` ```bash
make install make install
``` ```
@ -166,11 +208,11 @@ switches.
### Preprocessing ### Preprocessing
There is a separate program, ivlpp, that does the preprocessing. This There is a separate program, `ivlpp`, that does the preprocessing. This
program implements the `` `include `` and `` `define `` directives producing program implements the `` `include `` and `` `define `` directives producing
output that is equivalent but without the directives. The output is a output that is equivalent but without the directives. The output is a
single file with line number directives, so that the actual compiler single file with line number directives, so that the actual compiler
only sees a single input file. See ivlpp/ivlpp.txt for details. only sees a single input file. See `ivlpp/ivlpp.txt` for details.
### Parse ### Parse
@ -251,7 +293,7 @@ to generate actual output.
The user selects the target code generator with the `-t` flag on the The user selects the target code generator with the `-t` flag on the
command line. command line.
### ATTRIBUTES ### Attributes
> NOTE: The $attribute syntax will soon be deprecated in favour of the Verilog-2001 attribute syntax, which is cleaner and standardized. > NOTE: The $attribute syntax will soon be deprecated in favour of the Verilog-2001 attribute syntax, which is cleaner and standardized.
@ -290,31 +332,32 @@ attributes. They have the same general meaning as with the $attribute
syntax, but they are attached to objects by position instead of by syntax, but they are attached to objects by position instead of by
name. Also, the key is a Verilog identifier instead of a string. name. Also, the key is a Verilog identifier instead of a string.
## Running iverilog ## Running `iverilog`
The preferred way to invoke the compiler is with the `iverilog`(1) The preferred way to invoke the compiler is with the `iverilog`(1)
command. This program invokes the preprocessor (ivlpp) and the command. This program invokes the preprocessor (`ivlpp`) and the
compiler (`ivl`) with the proper command line options to get the job compiler (`ivl`) with the proper command line options to get the job
done in a friendly way. See the `iverilog`(1) man page for usage details. done in a friendly way. See the `iverilog`(1) man page for usage details.
## EXAMPLES ### EXAMPLE: Hello World
Example: Compiling `"hello.vl"` Example: Compiling `"hello.vl"`
``` ```verilog
------------------------ hello.vl ---------------------------- // ------------------------ hello.vl ----------------------------
module main(); module main();
initial initial
begin begin
$display("Hi there"); $display("Hello World");
$finish ; $finish ;
end end
endmodule endmodule
-------------------------------------------------------------- // --------------------------------------------------------------
``` ```
Ensure that `iverilog` is on your search path, and the vpi library Ensure that `iverilog` is on your search path, and the vpi library
@ -322,16 +365,16 @@ is available.
To compile the program: To compile the program:
``` ```bash
iverilog hello.vl iverilog hello.vl
``` ```
(The above presumes that /usr/local/include and /usr/local/lib are (The above presumes that `/usr/local/include` and `/usr/local/lib` are
part of the compiler search path, which is usually the case for gcc.) part of the compiler search path, which is usually the case for `gcc`.)
To run the program: To run the generated program:
``` ```bash
./a.out ./a.out
``` ```
@ -348,165 +391,30 @@ Verilog web page for the current state of support for Verilog, and in
particular, browse the bug report database for reported unsupported particular, browse the bug report database for reported unsupported
constructs. constructs.
- System functions are supported, but the return value is a little - Specify blocks are parsed but ignored by default. When enabled
tricky. See SYSTEM FUNCTION TABLE FILES in the iverilog man page. by the `-gspecify` compiler option, a subset of specify block
constructs are supported.
- Specify blocks are parsed but ignored in general.
- `trireg` is not supported. `tri0` and `tri1` are supported. - `trireg` is not supported. `tri0` and `tri1` are supported.
- tran primitives, i.e. `tran`, `tranif1`, `tranif0`, `rtran`, `rtranif1`
and `rtranif0` are not supported.
- Net delays, of the form `wire #N foo;` do not work. Delays in - Net delays, of the form `wire #N foo;` do not work. Delays in
every other context do work properly, including the V2001 form every other context do work properly, including the V2001 form
`wire #5 foo = bar;` `wire #5 foo = bar;`
- Event controls inside non-blocking assignments are not supported. The list of unsupported SystemVerilog constructs is too large to
i.e.: `a <= @(posedge clk) b;` enumerate here.
- Macro arguments are not supported. `` `define `` macros are supported, ## Nonstandard Constructs and Behaviors
but they cannot take arguments.
## Nonstandard Constructs or Behaviors Icarus Verilog includes some features that are not part of the IEEE 1364
standard, but have well-defined meaning, and also sometimes gives nonstandard
(but extended) meanings to some features of the language that are defined.
See the "Icarus Verilog Extensions" and "Icarus Verilog Quirks" sections at
https://steveicarus.github.io/iverilog/ for more details.
Icarus Verilog includes some features that are not part of the ## Credits
IEEE1364 standard, but have well-defined meaning, and also sometimes
gives nonstandard (but extended) meanings to some features of the
language that are defined. See the "extensions.txt" documentation for
more details.
* `$is_signed(<expr>)` Except where otherwise noted, Icarus Verilog, ivl, and ivlpp are
This system function returns 1 if the expression contained is
signed, or 0 otherwise. This is mostly of use for compiler
regression tests.
* `$sizeof(<expr>)`, `$bits(<expr>)`
The `$bits` system function returns the size in bits of the
expression that is its argument. The result of this
function is undefined if the argument doesn't have a
self-determined size.
The `$sizeof` function is deprecated in favour of `$bits`, which is
the same thing, but included in the SystemVerilog definition.
* `$simtime`
The `$simtime` system function returns as a 64bit value the
simulation time, unscaled by the time units of local
scope. This is different from the $time and $stime functions
which return the scaled times. This function is added for
regression testing of the compiler and run time, but can be
used by applications who really want the simulation time.
Note that the simulation time can be confusing if there are
lots of different `` `timescales`` within a design. It is not in
general possible to predict what the simulation precision will
turn out to be.
* `$mti_random()`, `$mti_dist_uniform`
These functions are similar to the IEEE1364 standard $random
functions, but they use the Mersenne Twister (MT19937)
algorithm. This is considered an excellent random number
generator, but does not generate the same sequence as the
standardized $random.
### Builtin system functions
Certain of the system functions have well-defined meanings, so
can theoretically be evaluated at compile-time, instead of
using runtime VPI code. Doing so means that VPI cannot
override the definitions of functions handled in this
manner. On the other hand, this makes them synthesizable, and
also allows for more aggressive constant propagation. The
functions handled in this manner are:
* `$bits`
* `$signed`
* `$sizeof`
* `$unsigned`
Implementations of these system functions in VPI modules will be ignored.
### Preprocessing Library Modules
Icarus Verilog does preprocess modules that are loaded from
libraries via the -y mechanism. However, the only macros
defined during the compilation of that file are those that it
defines itself (or includes) or that are defined in the
command line or command file.
Specifically, macros defined in the non-library source files
are not remembered when the library module is loaded. This is
intentional. If it were otherwise, then compilation results
might vary depending on the order that libraries are loaded,
and that is too unpredictable.
It is said that some commercial compilers do allow macro
definitions to span library modules. That's just plain weird.
### Width in `%t` Time Formats
Standard Verilog does not allow width fields in the %t formats
of display strings. For example, this is illegal:
```
$display("Time is %0t", $time);
```
Standard Verilog instead relies on the $timeformat to
completely specify the format.
Icarus Verilog allows the programmer to specify the field
width. The `%t` format in Icarus Verilog works exactly as it
does in standard Verilog. However, if the programmer chooses
to specify a minimum width (i.e., `%5t`), then for that display
Icarus Verilog will override the `$timeformat` minimum width and
use the explicit minimum width.
### vpiScope iterator on vpiScope objects.
In the VPI, the normal way to iterate over vpiScope objects
contained within a vpiScope object, is the vpiInternalScope
iterator. Icarus Verilog adds support for the vpiScope
iterator of a vpiScope object, that iterates over *everything*
the is contained in the current scope. This is useful in cases
where one wants to iterate over all the objects in a scope
without iterating over all the contained types explicitly.
### time 0 race resolution.
Combinational logic is routinely modelled using always
blocks. However, this can lead to race conditions if the
inputs to the combinational block are initialized in initial
statements. Icarus Verilog slightly modifies time 0 scheduling
by arranging for always statements with ANYEDGE sensitivity
lists to be scheduled before any other threads. This causes
combinational always blocks to be triggered when the values in
the sensitivity list are initialized by initial threads.
### Nets with Types
Icarus Verilog supports an extended syntax that allows nets
and regs to be explicitly typed. The currently supported types
are logic, bool and real. This implies that `logic` and `bool`
are new keywords. Typical syntax is:
```
wire real foo = 1.0;
reg logic bar, bat;
```
... and so forth. The syntax can be turned off by using the
-g2 flag to iverilog, and turned on explicitly with the -g2x
flag to iverilog.
## CREDITS
Except where otherwise noted, Icarus Verilog, ivl and ivlpp are
Copyright Stephen Williams. The proper notices are in the head of each Copyright Stephen Williams. The proper notices are in the head of each
file. However, I have early on received aid in the form of fixes, file. However, I have early on received aid in the form of fixes,
Verilog guidance, and especially testing from many people. Testers, in Verilog guidance, and especially testing from many people. Testers, in

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2024 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -29,8 +29,9 @@ Statement::~Statement()
{ {
} }
PAssign_::PAssign_(PExpr*lval__, PExpr*ex, bool is_constant) PAssign_::PAssign_(PExpr*lval__, PExpr*ex, bool is_constant, bool is_init)
: event_(0), count_(0), lval_(lval__), rval_(ex), is_constant_(is_constant) : event_(0), count_(0), lval_(lval__), rval_(ex), is_constant_(is_constant),
is_init_(is_init)
{ {
delay_ = 0; delay_ = 0;
} }
@ -73,8 +74,8 @@ PAssign::PAssign(PExpr*lval__, PExpr*cnt, PEventStatement*d, PExpr*ex)
{ {
} }
PAssign::PAssign(PExpr*lval__, PExpr*ex, bool is_constant) PAssign::PAssign(PExpr*lval__, PExpr*ex, bool is_constant, bool is_init)
: PAssign_(lval__, ex, is_constant), op_(0) : PAssign_(lval__, ex, is_constant, is_init), op_(0)
{ {
} }
@ -139,8 +140,8 @@ PChainConstructor* PBlock::extract_chain_constructor()
void PBlock::set_join_type(PBlock::BL_TYPE type) void PBlock::set_join_type(PBlock::BL_TYPE type)
{ {
assert(bl_type_ == BL_PAR); ivl_assert(*this, bl_type_ == BL_PAR);
assert(type==BL_PAR || type==BL_JOIN_NONE || type==BL_JOIN_ANY); ivl_assert(*this, type==BL_PAR || type==BL_JOIN_NONE || type==BL_JOIN_ANY);
bl_type_ = type; bl_type_ = type;
} }
@ -165,37 +166,19 @@ PNamedItem::SymbolType PBlock::symbol_type() const
return BLOCK; return BLOCK;
} }
PCallTask::PCallTask(const pform_name_t&n, const list<PExpr*>&p) PCallTask::PCallTask(const pform_name_t &n, const list<named_pexpr_t> &p)
: package_(0), path_(n), parms_(p.size()) : package_(0), path_(n), parms_(p.begin(), p.end())
{ {
list<PExpr*>::const_iterator cur = p.begin();
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
parms_[idx] = *cur;
++cur;
}
assert(cur == p.end());
} }
PCallTask::PCallTask(PPackage*pkg, const pform_name_t&n, const list<PExpr*>&p) PCallTask::PCallTask(PPackage *pkg, const pform_name_t &n, const list<named_pexpr_t> &p)
: package_(pkg), path_(n), parms_(p.size()) : package_(pkg), path_(n), parms_(p.begin(), p.end())
{ {
list<PExpr*>::const_iterator cur = p.begin();
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
parms_[idx] = *cur;
++cur;
}
assert(cur == p.end());
} }
PCallTask::PCallTask(perm_string n, const list<PExpr*>&p) PCallTask::PCallTask(perm_string n, const list<named_pexpr_t> &p)
: package_(0), parms_(p.size()) : package_(0), parms_(p.begin(), p.end())
{ {
list<PExpr*>::const_iterator cur = p.begin();
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
parms_[idx] = *cur;
++cur;
}
assert(cur == p.end());
path_.push_back(name_component_t(n)); path_.push_back(name_component_t(n));
} }
@ -233,15 +216,14 @@ PCAssign::~PCAssign()
delete expr_; delete expr_;
} }
PChainConstructor::PChainConstructor(const list<PExpr*>&parms) PChainConstructor::PChainConstructor(const list<named_pexpr_t> &parms)
: parms_(parms.size()) : parms_(parms.begin(), parms.end())
{
}
PChainConstructor::PChainConstructor(const vector<named_pexpr_t> &parms)
: parms_(parms)
{ {
list<PExpr*>::const_iterator cur = parms.begin();
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
parms_[idx] = *cur;
++cur;
}
assert(cur == parms.end());
} }
PChainConstructor::~PChainConstructor() PChainConstructor::~PChainConstructor()
@ -303,7 +285,7 @@ PDoWhile::~PDoWhile()
PEventStatement::PEventStatement(const std::vector<PEEvent*>&ee) PEventStatement::PEventStatement(const std::vector<PEEvent*>&ee)
: expr_(ee), statement_(0), always_sens_(false) : expr_(ee), statement_(0), always_sens_(false)
{ {
assert(expr_.size() > 0); ivl_assert(*this, expr_.size() > 0);
} }
@ -349,12 +331,8 @@ PForce::~PForce()
} }
PForeach::PForeach(perm_string av, const list<perm_string>&ix, Statement*s) PForeach::PForeach(perm_string av, const list<perm_string>&ix, Statement*s)
: array_var_(av), index_vars_(ix.size()), statement_(s) : array_var_(av), index_vars_(ix.begin(), ix.end()), statement_(s)
{ {
size_t idx = 0;
for (list<perm_string>::const_iterator cur = ix.begin()
; cur != ix.end() ; ++cur)
index_vars_[idx++] = *cur;
} }
PForeach::~PForeach() PForeach::~PForeach()
@ -418,8 +396,8 @@ PReturn::~PReturn()
delete expr_; delete expr_;
} }
PTrigger::PTrigger(PPackage*pkg, const pform_name_t&ev) PTrigger::PTrigger(PPackage*pkg, const pform_name_t&ev, unsigned lexical_pos)
: package_(pkg), event_(ev) : event_(pkg, ev), lexical_pos_(lexical_pos)
{ {
} }
@ -427,8 +405,8 @@ PTrigger::~PTrigger()
{ {
} }
PNBTrigger::PNBTrigger(const pform_name_t&ev, PExpr*dly) PNBTrigger::PNBTrigger(const pform_name_t&ev, unsigned lexical_pos, PExpr*dly)
: event_(ev), dly_(dly) : event_(ev), lexical_pos_(lexical_pos), dly_(dly)
{ {
} }

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