aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZachary Snow <zach@zachjs.com>2022-10-29 15:14:11 -0400
committerZachary Snow <zach@zachjs.com>2022-10-29 15:14:11 -0400
commit71e7e09092dc262b7cddbfc99e1b92e81ac58f21 (patch)
treef487fbfb87a81cd2ab8616db883078a91c50504c
parent31c15e5fa60b8cb47e7785fc420d90e860708034 (diff)
downloadyosys-71e7e09092dc262b7cddbfc99e1b92e81ac58f21.tar.gz
yosys-71e7e09092dc262b7cddbfc99e1b92e81ac58f21.tar.bz2
yosys-71e7e09092dc262b7cddbfc99e1b92e81ac58f21.zip
verilog: Support module-scoped task/function calls
This is primarily intended to enable the standard-permitted use of module-scoped identifiers to refer to tasks and non-constant functions. As a side-effect, this also adds support for the non-standard use of module-scoped identifiers referring to constant functions, a feature that is supported in some other tools, including Iverilog.
-rw-r--r--CHANGELOG3
-rw-r--r--frontends/ast/simplify.cc4
-rw-r--r--tests/simple/module_scope_func.v45
3 files changed, 52 insertions, 0 deletions
diff --git a/CHANGELOG b/CHANGELOG
index bb55c0c59..fab1519b6 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -9,6 +9,9 @@ Yosys 0.22 .. Yosys 0.22-dev
Setting it to 1 causes abort() to be called when Yosys terminates with an
error message.
+ * Verilog
+ - Support for module-scoped identifiers referring to tasks and functions.
+
Yosys 0.21 .. Yosys 0.22
--------------------------
* Verific support
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 49bf9af09..c932e2c49 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -3656,6 +3656,8 @@ skip_dynamic_range_lvalue_expansion:;
goto apply_newNode;
}
+ if (current_scope.count(str) == 0)
+ str = try_pop_module_prefix();
if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION)
log_file_error(filename, location.first_line, "Can't resolve function name `%s'.\n", str.c_str());
}
@@ -3727,6 +3729,8 @@ skip_dynamic_range_lvalue_expansion:;
goto apply_newNode;
}
+ if (current_scope.count(str) == 0)
+ str = try_pop_module_prefix();
if (current_scope.count(str) == 0 || current_scope[str]->type != AST_TASK)
log_file_error(filename, location.first_line, "Can't resolve task name `%s'.\n", str.c_str());
}
diff --git a/tests/simple/module_scope_func.v b/tests/simple/module_scope_func.v
new file mode 100644
index 000000000..928078da4
--- /dev/null
+++ b/tests/simple/module_scope_func.v
@@ -0,0 +1,45 @@
+// Some strict implementatins either forbid hierarchical identifiers within
+// constant expressions, or forbid declaring functions in generate blocks, or
+// both. Yosys and Iverilog are not strict in either of these ways.
+module module_scope_func_top(
+ input wire inp,
+ output wire [31:0] out1, out2, out4, out5, out7, out8,
+ output reg [31:0] out3, out6, out9
+);
+ function automatic integer incr;
+ input integer value;
+ incr = value + 1;
+ endfunction
+ task send;
+ output integer out;
+ out = 55;
+ endtask
+
+ assign out1 = module_scope_func_top.incr(inp);
+ localparam C = module_scope_func_top.incr(10);
+ assign out2 = C;
+ initial module_scope_func_top.send(out3);
+
+ if (1) begin : blk
+ // shadows module_scope_func_top.incr
+ function automatic integer incr;
+ input integer value;
+ incr = value * 2;
+ endfunction
+ // shadows module_scope_func_top.send
+ task send;
+ output integer out;
+ out = 66;
+ endtask
+
+ assign out4 = module_scope_func_top.incr(inp);
+ localparam D = module_scope_func_top.incr(20);
+ assign out5 = D;
+ initial module_scope_func_top.send(out6);
+
+ assign out7 = incr(inp);
+ localparam E = incr(30);
+ assign out8 = E;
+ initial send(out9);
+ end
+endmodule