diff options
author | Zachary Snow <zach@zachjs.com> | 2021-05-27 16:47:02 -0400 |
---|---|---|
committer | Zachary Snow <zachary.j.snow@gmail.com> | 2021-06-01 13:17:41 -0400 |
commit | 8cfed1a97957e4c096d1e0a0304d978bcb27e116 (patch) | |
tree | ea43c00a06a8e1bf86eb11fbdcd19ecf948dc4c1 | |
parent | 6d5d8457883e5de8df58997d95373d3433b781bf (diff) | |
download | yosys-8cfed1a97957e4c096d1e0a0304d978bcb27e116.tar.gz yosys-8cfed1a97957e4c096d1e0a0304d978bcb27e116.tar.bz2 yosys-8cfed1a97957e4c096d1e0a0304d978bcb27e116.zip |
sv: support tasks and functions within packages
-rw-r--r-- | frontends/ast/ast.cc | 20 | ||||
-rw-r--r-- | frontends/ast/simplify.cc | 2 | ||||
-rw-r--r-- | frontends/verilog/verilog_parser.y | 2 | ||||
-rw-r--r-- | tests/verilog/package_task_func.sv | 30 | ||||
-rw-r--r-- | tests/verilog/package_task_func.ys | 4 |
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 |