Commit Graph

10639 Commits

Author SHA1 Message Date
mjoekhan e628e6c8c5 SV: sum() and product() reductions on queues/darrays
Add integral sum() and product() reductions, including expression
forms, for queues, dynamic arrays, and class properties.

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

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

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

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

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

    LABEL: begin
      statement;
    end

    LABEL: fork
      statement;
    join

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Use `identifier_name` for all of these positions.

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

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

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

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

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

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

Fixes: e56c93a2be ("Support shadowing type identifiers in parameter declarations")
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2026-07-09 20:49:01 -07:00