Standalone muhammadjawadkhan/iverilog-uvm project setup. Documents
that this fork is experimental and must not PR UVM work to
steveicarus/iverilog. Seeds uvm/ from IVL_UVM and adds roadmap/status
workflow docs plus a smoke example.
Combine the nearly identical dynamic-array and queue method blocks in
test_width_method_ and elaborate_expr_method_ (including class property
paths), keeping queue-only pop_front/pop_back gated on queue type.
Add ordering methods for queues and dynamic arrays. Update ivtest gold
files for always_*_warn, br1005, and br_gh710b LXT per review.
Split from steveicarus/iverilog#1330 (part 06/6).
Add integral sum() and product() reductions, including expression
forms, for queues, dynamic arrays, and class properties.
Split from steveicarus/iverilog#1330 (part 05/6).
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>
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>
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>
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).
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>
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>
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>
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>
`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>
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>
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>
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>
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>
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.
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).
Add parsing and elaboration for chained calls on expression results,
with sv_call_chain_method1 regression.
Split from steveicarus/iverilog#1330 (part 02/6).