diff options
-rw-r--r-- | CHANGELOG | 4 | ||||
-rw-r--r-- | frontends/ast/simplify.cc | 12 | ||||
-rw-r--r-- | tests/verilog/always_comb_nolatch_5.ys | 15 | ||||
-rw-r--r-- | tests/verilog/always_comb_nolatch_6.ys | 15 |
4 files changed, 45 insertions, 1 deletions
@@ -5,6 +5,10 @@ List of major changes and improvements between releases Yosys 0.16 .. Yosys 0.16-dev -------------------------- + * SystemVerilog + - Fixed automatic `nosync` inference for local variables in `always_comb` + procedures not applying to nested blocks and blocks in functions + Yosys 0.15 .. Yosys 0.16 -------------------------- * Various diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 565025d3a..bd3e09c4b 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -744,6 +744,16 @@ static void mark_auto_nosync(AstNode *block, const AstNode *wire) false); } +// block names can be prefixed with an explicit scope during elaboration +static bool is_autonamed_block(const std::string &str) { + size_t last_dot = str.rfind('.'); + // unprefixed names: autonamed if the first char is a dollar sign + if (last_dot == std::string::npos) + return str.at(0) == '$'; // e.g., `$fordecl_block$1` + // prefixed names: autonamed if the final chunk begins with a dollar sign + return str.rfind(".$") == last_dot; // e.g., `\foo.bar.$fordecl_block$1` +} + // check a procedural block for auto-nosync markings, remove them, and add // nosync to local variables as necessary static void check_auto_nosync(AstNode *node) @@ -2355,7 +2365,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // if this is an autonamed block is in an always_comb if (current_always && current_always->attributes.count(ID::always_comb) - && str.at(0) == '$') + && is_autonamed_block(str)) // track local variables in this block so we can consider adding // nosync once the block has been fully elaborated for (AstNode *child : children) diff --git a/tests/verilog/always_comb_nolatch_5.ys b/tests/verilog/always_comb_nolatch_5.ys new file mode 100644 index 000000000..132878626 --- /dev/null +++ b/tests/verilog/always_comb_nolatch_5.ys @@ -0,0 +1,15 @@ +read_verilog -sv <<EOF +module top; +logic [4:0] x; +logic z; +assign z = 1'b1; +always_comb begin : foo + x = '0; + if (z) begin : bar + for (int i = 0; i < 5; i++) + x[i] = 1'b1; + end +end +endmodule +EOF +proc diff --git a/tests/verilog/always_comb_nolatch_6.ys b/tests/verilog/always_comb_nolatch_6.ys new file mode 100644 index 000000000..90ee78a68 --- /dev/null +++ b/tests/verilog/always_comb_nolatch_6.ys @@ -0,0 +1,15 @@ +read_verilog -sv <<EOF +module top(input wire x, y, output reg z); +function automatic f; + input inp; + for (int i = 0; i < 1; i++) + f = inp + 0; +endfunction +always_comb + if (y) + z = f(x); + else + z = 0; +endmodule +EOF +proc |