sv: support tasks and functions within packages

This commit is contained in:
Zachary Snow 2021-05-27 16:47:02 -04:00 committed by Zachary Snow
parent 6d5d845788
commit 8cfed1a979
5 changed files with 56 additions and 2 deletions

View File

@ -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();
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,4 @@
read_verilog -sv package_task_func.sv
proc
opt -full
sat -verify -seq 1 -prove-asserts -show-all