aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZachary Snow <zach@zachjs.com>2021-05-27 16:47:02 -0400
committerZachary Snow <zachary.j.snow@gmail.com>2021-06-01 13:17:41 -0400
commit8cfed1a97957e4c096d1e0a0304d978bcb27e116 (patch)
treeea43c00a06a8e1bf86eb11fbdcd19ecf948dc4c1
parent6d5d8457883e5de8df58997d95373d3433b781bf (diff)
downloadyosys-8cfed1a97957e4c096d1e0a0304d978bcb27e116.tar.gz
yosys-8cfed1a97957e4c096d1e0a0304d978bcb27e116.tar.bz2
yosys-8cfed1a97957e4c096d1e0a0304d978bcb27e116.zip
sv: support tasks and functions within packages
-rw-r--r--frontends/ast/ast.cc20
-rw-r--r--frontends/ast/simplify.cc2
-rw-r--r--frontends/verilog/verilog_parser.y2
-rw-r--r--tests/verilog/package_task_func.sv30
-rw-r--r--tests/verilog/package_task_func.ys4
5 files changed, 56 insertions, 2 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index 7e5cc9411..7e53713e3 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -1196,6 +1196,25 @@ static void process_module(RTLIL::Design *design, AstNode *ast, bool defer, AstN
design->add(current_module);
}
+// renames identifiers in tasks and functions within a package
+static void rename_in_package_stmts(AstNode *pkg)
+{
+ std::unordered_set<std::string> idents;
+ for (AstNode *item : pkg->children)
+ idents.insert(item->str);
+ std::function<void(AstNode*)> rename =
+ [&rename, &idents, pkg](AstNode *node) {
+ for (AstNode *child : node->children) {
+ if (idents.count(child->str))
+ child->str = pkg->str + "::" + child->str.substr(1);
+ rename(child);
+ }
+ };
+ for (AstNode *item : pkg->children)
+ if (item->type == AST_FUNCTION || item->type == AST_TASK)
+ rename(item);
+}
+
// create AstModule instances for all modules in the AST tree and add them to 'design'
void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool no_dump_ptr, bool dump_vlog1, bool dump_vlog2, bool dump_rtlil,
bool nolatches, bool nomeminit, bool nomem2reg, bool mem2reg, bool noblackbox, bool lib, bool nowb, bool noopt, bool icells, bool pwires, bool nooverwrite, bool overwrite, bool defer, bool autowire)
@@ -1284,6 +1303,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump
else if (child->type == AST_PACKAGE) {
// process enum/other declarations
child->simplify(true, false, false, 1, -1, false, false);
+ rename_in_package_stmts(child);
design->verilog_packages.push_back(child->clone());
current_scope.clear();
}
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 305f67da8..517647afb 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -875,7 +875,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
for (size_t i = 0; i < children.size(); i++) {
AstNode *node = children[i];
// these nodes appear at the top level in a package and can define names
- if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_TYPEDEF) {
+ if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_TYPEDEF || node->type == AST_FUNCTION || node->type == AST_TASK) {
current_scope[node->str] = node;
}
if (node->type == AST_ENUM) {
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index c2b43f45b..93ddbec91 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -593,7 +593,7 @@ package_body:
package_body package_body_stmt | %empty;
package_body_stmt:
- typedef_decl | localparam_decl | param_decl;
+ typedef_decl | localparam_decl | param_decl | task_func_decl;
interface:
TOK_INTERFACE {
diff --git a/tests/verilog/package_task_func.sv b/tests/verilog/package_task_func.sv
new file mode 100644
index 000000000..2df7a5205
--- /dev/null
+++ b/tests/verilog/package_task_func.sv
@@ -0,0 +1,30 @@
+package P;
+ localparam Y = 2;
+ localparam X = Y + 1;
+ task t;
+ output integer x;
+ x = Y;
+ endtask
+ function automatic integer f;
+ input integer i;
+ f = i * X;
+ endfunction
+ function automatic integer g;
+ input integer i;
+ g = i == 0 ? 1 : Y * g(i - 1);
+ endfunction
+ localparam Z = g(4);
+endpackage
+
+module top;
+ integer a;
+ initial P::t(a);
+ integer b = P::f(3);
+ integer c = P::g(3);
+ integer d = P::Z;
+
+ assert property (a == 2);
+ assert property (b == 9);
+ assert property (c == 8);
+ assert property (d == 16);
+endmodule
diff --git a/tests/verilog/package_task_func.ys b/tests/verilog/package_task_func.ys
new file mode 100644
index 000000000..c94cc2acb
--- /dev/null
+++ b/tests/verilog/package_task_func.ys
@@ -0,0 +1,4 @@
+read_verilog -sv package_task_func.sv
+proc
+opt -full
+sat -verify -seq 1 -prove-asserts -show-all