aboutsummaryrefslogtreecommitdiffstats
path: root/tests/simple
diff options
context:
space:
mode:
authorZachary Snow <zach@zachjs.com>2021-01-27 13:21:13 -0500
committerZachary Snow <zach@zachjs.com>2021-02-04 10:18:27 -0500
commitb93b6f4285243ebbb43ad95769dc2890b6e1e7ab (patch)
treef5d807a7d07dfa1d046daa340a1544c1ce39ce7a /tests/simple
parentbaf1875307f1608762169d3037ba005da88b201e (diff)
downloadyosys-b93b6f4285243ebbb43ad95769dc2890b6e1e7ab.tar.gz
yosys-b93b6f4285243ebbb43ad95769dc2890b6e1e7ab.tar.bz2
yosys-b93b6f4285243ebbb43ad95769dc2890b6e1e7ab.zip
verilog: refactored constant function evaluation
Elaboration now attempts constant evaluation of any function call with only constant arguments, regardless of the context or contents of the function. This removes the concept of "recommended constant evaluation" which previously applied to functions with `for` loops or which were (sometimes erroneously) identified as recursive. Any function call in a constant context (e.g., `localparam`) or which contains a constant-only procedural construct (`while` or `repeat`) in its body will fail as before if constant evaluation does not succeed.
Diffstat (limited to 'tests/simple')
-rw-r--r--tests/simple/const_fold_func.v61
-rw-r--r--tests/simple/const_func_shadow.v33
2 files changed, 94 insertions, 0 deletions
diff --git a/tests/simple/const_fold_func.v b/tests/simple/const_fold_func.v
new file mode 100644
index 000000000..ee2f12e06
--- /dev/null
+++ b/tests/simple/const_fold_func.v
@@ -0,0 +1,61 @@
+module top(
+ input wire [3:0] inp,
+ output wire [3:0] out1, out2, out3, out4, out5,
+ output reg [3:0] out6
+);
+ function automatic [3:0] flip;
+ input [3:0] inp;
+ flip = ~inp;
+ endfunction
+
+ function automatic [3:0] help;
+ input [3:0] inp;
+ help = flip(inp);
+ endfunction
+
+ // while loops are const-eval-only
+ function automatic [3:0] loop;
+ input [3:0] inp;
+ reg [3:0] val;
+ begin
+ val = inp;
+ loop = 1;
+ while (val != inp) begin
+ loop = loop * 2;
+ val = val + 1;
+ end
+ end
+ endfunction
+
+ // not const-eval-only, despite calling a const-eval-only function
+ function automatic [3:0] help_mul;
+ input [3:0] inp;
+ help_mul = inp * loop(2);
+ endfunction
+
+ // can be elaborated so long as exp is a constant
+ function automatic [3:0] pow_flip_a;
+ input [3:0] base, exp;
+ begin
+ pow_flip_a = 1;
+ if (exp > 0)
+ pow_flip_a = base * pow_flip_a(flip(base), exp - 1);
+ end
+ endfunction
+
+ function automatic [3:0] pow_flip_b;
+ input [3:0] base, exp;
+ begin
+ out6[exp] = base & 1;
+ pow_flip_b = 1;
+ if (exp > 0)
+ pow_flip_b = base * pow_flip_b(flip(base), exp - 1);
+ end
+ endfunction
+
+ assign out1 = flip(flip(inp));
+ assign out2 = help(flip(inp));
+ assign out3 = help_mul(inp);
+ assign out4 = pow_flip_a(flip(inp), 3);
+ assign out5 = pow_flip_b(2, 2);
+endmodule
diff --git a/tests/simple/const_func_shadow.v b/tests/simple/const_func_shadow.v
new file mode 100644
index 000000000..ca63606d9
--- /dev/null
+++ b/tests/simple/const_func_shadow.v
@@ -0,0 +1,33 @@
+module top(w, x, y, z);
+ function [11:0] func;
+ input reg [2:0] x;
+ input reg [2:0] y;
+ begin
+ x = x * (y + 1);
+ begin : foo
+ reg [2:0] y;
+ y = x + 1;
+ begin : bar
+ reg [2:0] x;
+ x = y + 1;
+ begin : blah
+ reg [2:0] y;
+ y = x + 1;
+ func[2:0] = y;
+ end
+ func[5:3] = x;
+ end
+ func[8:6] = y;
+ end
+ func[11:9] = x;
+ end
+ endfunction
+ output wire [func(2, 3) - 1:0] w;
+ output wire [func(1, 3) - 1:0] x;
+ output wire [func(3, 1) - 1:0] y;
+ output wire [func(5, 2) - 1:0] z;
+ assign w = 1'sb1;
+ assign x = 1'sb1;
+ assign y = 1'sb1;
+ assign z = 1'sb1;
+endmodule