3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-23 00:55:32 +00:00

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.
This commit is contained in:
Zachary Snow 2021-01-27 13:21:13 -05:00
parent baf1875307
commit b93b6f4285
4 changed files with 176 additions and 72 deletions

View file

@ -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

View file

@ -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