Fix buggy memory allocation introduced in #5152:
1) clean up ast_stack to reflect AST node rearrangement when necessary,
to avoid dangling pointer;
2) call free_attr() on unused attribute list when no new syntax node is
created, to avoid leaking it.
* verilog: fix string literal regular expression.
A backslash was improperly quoted, causing string literal matching
to fail when the final token before a closing quote was an escaped
backslash.
* verilog: add regression test for string literal regex bug.
Test for bug triggered by escaped backslash immediately before
closing quote (introduced in ca7d94af and fixed by 40aa7eaf).
The implementation for the implication operator in cover mode actually
implements the followed-by operator, so we can re-use it unchanged.
It is not always the correct behavior for the implication operator in
cover mode, but a) it will only cause false positives not miss anything
so if the behavior is unexpected it will be visible in the produced
traces, b) it is unlikely to make a difference for most properties one
would practically use in cover mode, c) at least one other widely used
SVA implementations behaves the same way and d) it's not clear whether
we can fix this without rewriting most of verificsva.cc
Use a greedy regular expression to match input inside a string
literal, so that flex can accumulate a longer match instead of
invoking a rule for each individual character.
There are two elements involved:
1) Apply the relevant full_case and/or parallel_case attribute(s) to
the generated AST_CASE node(s), so that the existing AST frontend and
subsequent passes will generate RTLIL with appropriate behaviour.
(This is handled in the parser "if_attr" non-terminal.)
2) Rearrange the AST_CASE structure when necessary. For "priority if"
(i.e., full_case), this requires only ensuring that directly nested
"else if" branches also inherit the full_case attribute. For
"unique if" and "unique0 if" (i.e., parallel_case+full_case and
parallel_case alone), there are two steps:
a) Flatten the AST_CASE structure such that any direct "else if"
branches are mapped to additional AST_CONDs in the parent;
b) Reverse the "direction" of the test: the constant 1 (true)
is provided in the AST_CASE node, and the expression(s) in the
if statement(s) are given in each AST_COND. This is necessary
because the constant 1, being the common factor, must occupy the
shared AST_CASE position.
(This is handled in the parser "TOK_IF" expansion of behavioral_stmt.)
Observe that:
* The generated AST has not been changed for bare "if"s (those
without unique/priority). This should minimise the risk of
unexpected regressions.
* It is possible that the flattening described in 2) a) above might
affect the behaviour of expressions with side effects in "unique if"
statements (consider "unique if( a ) ...; else if( b++ ) ...": if
a is true, is b incremented?). While it might be possible to provide
precise semantics here, IEEE 1800-2012 12.4.2 seems to be deliberately
vague ("In unique-if and unique0-if, the conditions may be evaluated
and compared in any order[...] The presence of side effects in
conditions may cause nondeterministic results.") and so it seems
doubtful that there is benefit in Yosys providing stronger promises
on the interpretation of questionable code.
Add support to the "read_verilog -sv" parser to validate the
"unique", "unique0", and "priority" keywords in contexts where
they're legal according to 1800-2012 12.4.2.
This affects only the grammar accepted; the behaviour of conditionals
is not changed. (But accepting this syntax will provide scope for
possible optimisations as future work.)
Three test cases ("unique_if", "unique_if_else", and
"unique_if_else_begin") verify that the keywords are accepted where
legal and rejected where illegal, as described in the final paragraph
of 12.4.2.
`read_verilog_file_list` should not try to read arguments as selection args. Without this, trying to pass a file without a `-f|-F` flag is misleading, in the best case giving a warning about the selection not matching any module, or in worst case just doing nothing (if the filename is a valid selection).
This adds optional in-memory caching of parsed liberty files to speed up
flows that repeatedly parse the same liberty files. To avoid increasing
the memory overhead by default, the caching is disabled by default. The
caching can be controlled globally or on a per path basis using the new
`libcache` command, which also allows purging cached data.
Otherwise the `AST_PRIMITIVE` simplifies to the corresponding function and is no longer caught by the check for `AST_PRIMITIVE`s, raising an assertion error instead of an input error.
Add bug4785.ys to tests/verilog to demonstrate.
- Remove unused statics CONST_FALSE and CONST_TRUE (which appear to have been folded into the `Index` declaration as CFALSE and CTRUE).
- Assign default value of EMPTY_LIT to `a` and `b` for comparison ops.
- Tag debug only variables with YS_MAYBE_UNUSED, don't assign unused variables (but continue to call the function because it moves the file pointer).
`Const::size()` returns int, so change iterators that use it to `auto` instead of `size_t`.
For cases where size is being explicitly cast to `int`, use the wrapper that we already have instead: `Yosys::GetSize()`.
Before this commit, the `STRING` variant inserted a literal string;
the `CHARACTER` variant inserted a string. This commit renames them
to `LITERAL` and `STRING` respectively.
Consider this SystemVerilog file:
module top(...);
input clk;
input [7:0] data;
input ack;
always @(posedge clk)
if (ack) begin
assert(data != 8'h0a);
end
endmodule
Before this commit, the span for the assert was:
if (ack) begin>
assert(data != 8'h0a)<;
After this commit, the span for the assert is:
if (ack) begin
>assert(data != 8'h0a)<;
This helps editor integrations that only look at the beginning
of the span.
These are useful for formal verification with SBY where they can be used
to display solver chosen `rand const reg` signals and signals derived
from those.
The previous error message for non-constant initial $display statements
is downgraded to a log message. Constant initial $display statements
will be shown both during elaboration and become part of the RTLIL so
that the `sim` output is complete.
This makes tests/verilog/dynamic_range_lhs.v pass, after ensuring that
nowrshmsk is actually tested.
Stride is extracted from indexing of two-dimensional packed arrays and
variable slices on the form dst[i*stride +: width] = src, and is used
to optimize the generated CASE block.
Also uses less confusing variable names for indexing of lhs wires.
When reading the BLIF input, represent the native sequential elements
with fine-grained cells like `$_FF_` instead of the coarse-grained cells
like `$ff` which we were using up to now.
There are two reasons for this:
* The sequential elements in BLIF are always single-bit, so the gate
cells are a better fit.
* This makes it symmetrical to the BLIF backend which only understands
the fine-grained cells, and only translates those to the native BLIF
features.
The $shift and $shiftx cells perform a left logical shift if the second
operand is negative. This change passes the sign of the second operand
of AST_SHIFT and AST_SHIFTX into $shift and $shiftx cells, respectively.
Compiling on GCC hid this bug as it optimized the nullptr call away as
undefined behavior, but running the SBY tests with a clang build hits
this error.
Instead of passing around in_lvalue/in_param flags to simplify, we make
the flags into properties of the AST nodes themselves. After the tree
is first parsed, we once do
ast->fixup_hierarchy_flags(true)
to walk the full hierarchy and set the flags to their initial correct
values. Then as long as one is using ->clone(), ->cloneInto() and the
AstNode constructor (with children passed to it) to modify the tree, the
flags will be kept in sync automatically. On the other hand if we are
modifying the children list of an existing node, we may need to call
node->fixup_hierarchy_flags()
to do a localized fixup. That fixup will update the flags on the node's
children, and will propagate the change down the tree if necessary.
clone() doesn't always retain the flags of the subtree being cloned. It
will produce a tree with a consistent setting of the flags, but the
root doesn't have in_param/in_lvalue set unless it's intrinsic to the
type of node being cloned (e.g. AST_PARAMETER). cloneInto() will make
sure the cloned subtree has the flags consistent with the new placement
in a hierarchy.
Add asserts to make sure the old and new way of determining the flags
agree.
The following commit will replace the way in_lvalue/in_param is being
tracked in the simplify code. Make tweaks in advance so that it will
be easier to make the old way and the new way agree.
These changes all should be innocuous.
- Add support for assignments within expressions, e.g., `x[y++] = z;` or
`x = (y *= 2) - 1;`. The logic is handled entirely within the parser
by injecting statements into the current procedural block.
- Add support for pre-increment/decrement statements, which are
behaviorally equivalent to post-increment/decrement statements.
- Fix non-standard attribute position used for post-increment/decrement
statements.