mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-07 01:54:10 +00:00
sv: fix always_comb auto nosync for nested and function blocks
This commit is contained in:
parent
957fdb328a
commit
bf15dbd0f7
|
@ -5,6 +5,10 @@ List of major changes and improvements between releases
|
||||||
Yosys 0.16 .. Yosys 0.16-dev
|
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
|
Yosys 0.15 .. Yosys 0.16
|
||||||
--------------------------
|
--------------------------
|
||||||
* Various
|
* Various
|
||||||
|
|
|
@ -744,6 +744,16 @@ static void mark_auto_nosync(AstNode *block, const AstNode *wire)
|
||||||
false);
|
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
|
// check a procedural block for auto-nosync markings, remove them, and add
|
||||||
// nosync to local variables as necessary
|
// nosync to local variables as necessary
|
||||||
static void check_auto_nosync(AstNode *node)
|
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 this is an autonamed block is in an always_comb
|
||||||
if (current_always && current_always->attributes.count(ID::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
|
// track local variables in this block so we can consider adding
|
||||||
// nosync once the block has been fully elaborated
|
// nosync once the block has been fully elaborated
|
||||||
for (AstNode *child : children)
|
for (AstNode *child : children)
|
||||||
|
|
15
tests/verilog/always_comb_nolatch_5.ys
Normal file
15
tests/verilog/always_comb_nolatch_5.ys
Normal file
|
@ -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
|
15
tests/verilog/always_comb_nolatch_6.ys
Normal file
15
tests/verilog/always_comb_nolatch_6.ys
Normal file
|
@ -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
|
Loading…
Reference in a new issue