Skip to content

Commit

Permalink
sv: support tasks and functions within packages
Browse files Browse the repository at this point in the history
  • Loading branch information
zachjs committed Jun 1, 2021
1 parent 6d5d845 commit 8cfed1a
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 2 deletions.
20 changes: 20 additions & 0 deletions frontends/ast/ast.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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();
}
Expand Down
2 changes: 1 addition & 1 deletion frontends/ast/simplify.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion frontends/verilog/verilog_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
30 changes: 30 additions & 0 deletions tests/verilog/package_task_func.sv
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions tests/verilog/package_task_func.ys
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
read_verilog -sv package_task_func.sv
proc
opt -full
sat -verify -seq 1 -prove-asserts -show-all

0 comments on commit 8cfed1a

Please sign in to comment.