Merge branch 'work13b'

This commit is contained in:
Stephen Williams 2013-04-16 16:47:37 -07:00
commit 256c0986bb
22 changed files with 596 additions and 136 deletions

View File

@ -174,7 +174,7 @@ PEBShift::~PEBShift()
}
PECallFunction::PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms)
: path_(n), parms_(parms)
: package_(0), path_(n), parms_(parms)
{
}
@ -186,19 +186,29 @@ static pform_name_t pn_from_ps(perm_string n)
return tmp;
}
PECallFunction::PECallFunction(PPackage*pkg, perm_string n, const list<PExpr *> &parms)
: package_(pkg), path_(pn_from_ps(n)), parms_(parms.size())
{
int tmp_idx = 0;
assert(parms_.size() == parms.size());
for (list<PExpr*>::const_iterator idx = parms.begin()
; idx != parms.end() ; ++idx)
parms_[tmp_idx++] = *idx;
}
PECallFunction::PECallFunction(perm_string n, const vector<PExpr*>&parms)
: path_(pn_from_ps(n)), parms_(parms)
: package_(0), path_(pn_from_ps(n)), parms_(parms)
{
}
PECallFunction::PECallFunction(perm_string n)
: path_(pn_from_ps(n))
: package_(0), path_(pn_from_ps(n))
{
}
// NOTE: Anachronism. Try to work all use of svector out.
PECallFunction::PECallFunction(const pform_name_t&n, const list<PExpr *> &parms)
: path_(n), parms_(parms.size())
: package_(0), path_(n), parms_(parms.size())
{
int tmp_idx = 0;
assert(parms_.size() == parms.size());
@ -208,7 +218,7 @@ PECallFunction::PECallFunction(const pform_name_t&n, const list<PExpr *> &parms)
}
PECallFunction::PECallFunction(perm_string n, const list<PExpr*>&parms)
: path_(pn_from_ps(n)), parms_(parms.size())
: package_(0), path_(pn_from_ps(n)), parms_(parms.size())
{
int tmp_idx = 0;
assert(parms_.size() == parms.size());
@ -333,10 +343,9 @@ PEIdent::PEIdent(perm_string s, bool no_implicit_sig)
path_.push_back(name_component_t(s));
}
PEIdent::PEIdent(PPackage*pkg, perm_string s)
: package_(pkg), no_implicit_sig_(true)
PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that)
: package_(pkg), path_(that), no_implicit_sig_(true)
{
path_.push_back(name_component_t(s));
}
PEIdent::~PEIdent()

16
PExpr.h
View File

@ -291,7 +291,7 @@ class PEIdent : public PExpr {
public:
explicit PEIdent(perm_string, bool no_implicit_sig=false);
explicit PEIdent(PPackage*pkg, perm_string name);
explicit PEIdent(PPackage*pkg, const pform_name_t&name);
explicit PEIdent(const pform_name_t&);
~PEIdent();
@ -770,11 +770,15 @@ class PETernary : public PExpr {
class PECallFunction : public PExpr {
public:
explicit PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms);
// Call function defined in package.
explicit PECallFunction(PPackage*pkg, perm_string n, const std::vector<PExpr *> &parms);
explicit PECallFunction(PPackage*pkg, perm_string n, const std::list<PExpr *> &parms);
// Call of system function (name is not hierarchical)
explicit PECallFunction(perm_string n, const vector<PExpr *> &parms);
explicit PECallFunction(perm_string n);
// svector versions. Should be removed!
// std::list versions. Should be removed!
explicit PECallFunction(const pform_name_t&n, const list<PExpr *> &parms);
explicit PECallFunction(perm_string n, const list<PExpr *> &parms);
@ -794,14 +798,17 @@ class PECallFunction : public PExpr {
width_mode_t&mode);
private:
PPackage*package_;
pform_name_t path_;
vector<PExpr *> parms_;
std::vector<PExpr *> parms_;
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
NetExpr* cast_to_width_(NetExpr*expr, unsigned wid) const;
NetExpr*elaborate_expr_pkg_(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags)const;
NetExpr*elaborate_expr_method_(Design*des, NetScope*scope,
unsigned expr_wid) const;
#if 0
@ -820,6 +827,9 @@ class PECallFunction : public PExpr {
unsigned test_width_method_(Design*des, NetScope*scope,
width_mode_t&mode);
NetExpr*elaborate_base_(Design*des, NetScope*scope, NetScope*dscope,
unsigned expr_wid, unsigned flags) const;
unsigned elaborate_arguments_(Design*des, NetScope*scope,
NetFuncDef*def, bool need_const,
std::vector<NetExpr*>&parms,

View File

@ -38,6 +38,8 @@ class PPackage : public PScopeExtra, public LineInfo {
~PPackage();
bool elaborate_scope(Design*des, NetScope*scope);
bool elaborate_sig(Design*des, NetScope*scope) const;
bool elaborate(Design*des, NetScope*scope) const;
void pform_dump(std::ostream&out) const;
};

View File

@ -127,7 +127,18 @@ void PBlock::set_statement(const vector<Statement*>&st)
}
PCallTask::PCallTask(const pform_name_t&n, const list<PExpr*>&p)
: path_(n), parms_(p.size())
: package_(0), path_(n), parms_(p.size())
{
list<PExpr*>::const_iterator cur = p.begin();
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
parms_[idx] = *cur;
++cur;
}
assert(cur == p.end());
}
PCallTask::PCallTask(PPackage*pkg, const pform_name_t&n, const list<PExpr*>&p)
: package_(pkg), path_(n), parms_(p.size())
{
list<PExpr*>::const_iterator cur = p.begin();
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
@ -138,7 +149,7 @@ PCallTask::PCallTask(const pform_name_t&n, const list<PExpr*>&p)
}
PCallTask::PCallTask(perm_string n, const list<PExpr*>&p)
: parms_(p.size())
: package_(0), parms_(p.size())
{
list<PExpr*>::const_iterator cur = p.begin();
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {

View File

@ -31,6 +31,7 @@
# include "HName.h"
# include "LineInfo.h"
class PExpr;
class PPackage;
class Statement;
class PEventStatement;
class Design;
@ -198,6 +199,7 @@ class PBlock : public PScope, public Statement {
class PCallTask : public Statement {
public:
explicit PCallTask(PPackage*pkg, const pform_name_t&n, const list<PExpr*>&parms);
explicit PCallTask(const pform_name_t&n, const list<PExpr*>&parms);
explicit PCallTask(perm_string n, const list<PExpr*>&parms);
~PCallTask();
@ -217,6 +219,7 @@ class PCallTask : public Statement {
NetProc*elaborate_build_call_(Design*des, NetScope*scope,
NetScope*task, NetExpr*use_this) const;
PPackage*package_;
pform_name_t path_;
vector<PExpr*> parms_;
};

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 1999-2013 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -1775,10 +1776,41 @@ static NetExpr* check_for_class_property(const LineInfo*li,
return tmp;
}
NetExpr* PECallFunction::elaborate_expr_pkg_(Design*des, NetScope*scope,
unsigned expr_wid,
unsigned flags) const
{
if (debug_elaborate) {
cerr << get_fileline() << ": PECallFunction::elaborate_expr_pkg_: "
<< "Elaborate " << path_
<< " as function in package " << package_->pscope_name()
<< "." << endl;
}
// Find the package that contains this definition, and use the
// package scope as the search starting point for the function
// definition.
NetScope*pscope = des->find_package(package_->pscope_name());
ivl_assert(*this, pscope);
NetFuncDef*def = des->find_function(pscope, path_);
ivl_assert(*this, def);
NetScope*dscope = def->scope();
ivl_assert(*this, dscope);
if (! check_call_matches_definition_(des, dscope))
return 0;
return elaborate_base_(des, scope, dscope, expr_wid, flags);
}
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags) const
{
if (package_)
return elaborate_expr_pkg_(des, scope, expr_wid, flags);
flags &= ~SYS_TASK_ARG; // don't propagate the SYS_TASK_ARG flag
if (peek_tail_name(path_)[0] == '$')
@ -1835,9 +1867,20 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
scope->is_const_func(false);
}
return elaborate_base_(des, scope, dscope, expr_wid, flags);
}
NetExpr* PECallFunction::elaborate_base_(Design*des, NetScope*scope, NetScope*dscope,
unsigned expr_wid, unsigned flags) const
{
if (! check_call_matches_definition_(des, dscope))
return 0;
NetFuncDef*def = dscope->func_def();
bool need_const = NEED_CONST & flags;
unsigned parms_count = parms_.size();
if ((parms_count == 1) && (parms_[0] == 0))
parms_count = 0;
@ -2719,13 +2762,13 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
use_path.pop_back();
ivl_assert(*this, net == 0);
symbol_search(this, des, scope, use_path, net, par, eve, ex1, ex2);
symbol_search(this, des, use_scope, use_path, net, par, eve, ex1, ex2);
if (net == 0) {
// Nope, no struct/class with member.
} else if (net->struct_type() != 0) {
return check_for_struct_members(this, des, scope,
return check_for_struct_members(this, des, use_scope,
net, use_path.back().index,
member_comp);
@ -2986,7 +3029,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
<< " for member " << member_comp << "." << endl;
ivl_assert(*this, net == 0);
symbol_search(this, des, scope, use_path, net, par, eve, ex1, ex2);
symbol_search(this, des, use_scope, use_path, net, par, eve, ex1, ex2);
// Check to see if we have a net and if so is it an
// enumeration? If so then check to see if this is an
@ -3002,7 +3045,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
// This expression cannot be a select!
assert(use_path.back().index.empty());
return check_for_enum_methods(this, des, scope,
return check_for_enum_methods(this, des, use_scope,
netenum,
use_path, member_comp.name,
expr, expr_wid, NULL, 0);
@ -3021,7 +3064,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
<< "got " << use_path.back().index.size() << "." << endl;
}
return check_for_struct_members(this, des, scope,
return check_for_struct_members(this, des, use_scope,
net, use_path.back().index,
member_comp);
}
@ -3033,7 +3076,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
<< " look for property " << member_comp << endl;
}
return check_for_class_property(this, des, scope,
return check_for_class_property(this, des, use_scope,
net, member_comp);
}
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2000-2013 Stephen Williams (steve@icarus.com)
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
* Copyright CERN 2012-2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -21,6 +21,7 @@
# include "config.h"
# include "PExpr.h"
# include "PPackage.h"
# include "netlist.h"
# include "netmisc.h"
# include "netstruct.h"
@ -163,7 +164,16 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
if (NetAssign_*tmp = elaborate_lval_method_class_member_(des, scope))
return tmp;
symbol_search(this, des, scope, path_, reg, par, eve);
/* Normally find the name in the passed scope. But if this is
imported from a package, then located the variable from the
package scope. */
NetScope*use_scope = scope;
if (package_) {
use_scope = des->find_package(package_->pscope_name());
ivl_assert(*this, use_scope);
}
symbol_search(this, des, use_scope, path_, reg, par, eve);
/* If the signal is not found, check to see if this is a
member of a struct. Take the name of the form "a.b.member",
@ -173,7 +183,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
pform_name_t use_path = path_;
perm_string tmp_name = peek_tail_name(use_path);
use_path.pop_back();
symbol_search(this, des, scope, use_path, reg, par, eve);
symbol_search(this, des, use_scope, use_path, reg, par, eve);
if (reg && reg->struct_type()) {
method_name = tmp_name;
@ -188,7 +198,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
if (reg == 0) {
cerr << get_fileline() << ": error: Could not find variable ``"
<< path_ << "'' in ``" << scope_path(scope) <<
<< path_ << "'' in ``" << scope_path(use_scope) <<
"''" << endl;
des->errors += 1;
@ -228,7 +238,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
unless this is the l-value of a force. */
if ((reg->type() != NetNet::REG) && !is_force) {
cerr << get_fileline() << ": error: " << path_ <<
" is not a valid l-value in " << scope_path(scope) <<
" is not a valid l-value in " << scope_path(use_scope) <<
"." << endl;
cerr << reg->get_fileline() << ": : " << path_ <<
" is declared here as " << reg->type() << "." << endl;
@ -238,13 +248,13 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
if (reg->struct_type() && !method_name.nil()) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_packed_member_(des, scope, lv, method_name);
elaborate_lval_net_packed_member_(des, use_scope, lv, method_name);
return lv;
}
if (reg->class_type() && !method_name.nil() && gn_system_verilog()) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_class_member_(des, scope, lv, method_name);
elaborate_lval_net_class_member_(des, use_scope, lv, method_name);
return lv;
}
@ -768,7 +778,7 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
return true;
}
bool PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*scope,
bool PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*,
NetAssign_*lv,
const perm_string&method_name) const
{

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -552,7 +553,9 @@ bool PPackage::elaborate_scope(Design*des, NetScope*scope)
}
collect_scope_parameters_(des, scope, parameters);
collect_scope_localparams_(des, scope, localparams);
elaborate_scope_funcs(des, scope, funcs);
elaborate_scope_tasks(des, scope, tasks);
return true;
}

View File

@ -29,6 +29,7 @@
# include "PExpr.h"
# include "PGate.h"
# include "PGenerate.h"
# include "PPackage.h"
# include "PTask.h"
# include "PWire.h"
# include "Statement.h"
@ -166,7 +167,13 @@ static void elaborate_sig_funcs(Design*des, NetScope*scope,
continue;
}
(*cur).second->elaborate_sig(des, fscope);
if (debug_elaborate) {
cerr << cur->second->get_fileline() << ": elaborate_sig_funcs: "
<< "Elaborate function " << use_name
<< " in " << scope_path(fscope) << endl;
}
cur->second->elaborate_sig(des, fscope);
}
}
@ -193,6 +200,22 @@ static void elaborate_sig_classes(Design*des, NetScope*scope,
}
}
bool PPackage::elaborate_sig(Design*des, NetScope*scope) const
{
bool flag = true;
flag = elaborate_sig_wires_(des, scope) && flag;
// After all the wires are elaborated, we are free to
// elaborate the ports of the tasks defined within this
// module. Run through them now.
elaborate_sig_funcs(des, scope, funcs);
elaborate_sig_tasks(des, scope, tasks);
return flag;
}
bool Module::elaborate_sig(Design*des, NetScope*scope) const
{
bool flag = true;

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 1998-2013 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -3206,7 +3207,13 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
return 0;
}
NetScope*task = des->find_task(scope, path_);
NetScope*pscope = scope;
if (package_) {
pscope = des->find_package(package_->pscope_name());
ivl_assert(*this, pscope);
}
NetScope*task = des->find_task(pscope, path_);
if (task == 0) {
// For SystemVerilog this may be a few other things.
if (gn_system_verilog()) {
@ -4876,6 +4883,19 @@ static void elaborate_classes(Design*des, NetScope*scope,
}
}
bool PPackage::elaborate(Design*des, NetScope*scope) const
{
bool result_flag = true;
// Elaborate function methods, and...
elaborate_functions(des, scope, funcs);
// Elaborate task methods.
elaborate_tasks(des, scope, tasks);
return result_flag;
}
/*
* When a module is instantiated, it creates the scope then uses this
* method to elaborate the contents of the module.
@ -5122,11 +5142,6 @@ bool PScope::elaborate_behaviors_(Design*des, NetScope*scope) const
return result_flag;
}
struct root_elem {
Module *mod;
NetScope *scope;
};
class elaborate_package_t : public elaborator_work_item_t {
public:
elaborate_package_t(Design*d, NetScope*scope, PPackage*p)
@ -5298,9 +5313,21 @@ bool Design::check_proc_delay() const
* for each root, does the whole elaboration sequence, and fills in
* the resulting Design.
*/
struct pack_elem {
PPackage*pack;
NetScope*scope;
};
struct root_elem {
Module *mod;
NetScope *scope;
};
Design* elaborate(list<perm_string>roots)
{
svector<root_elem*> root_elems(roots.size());
vector<struct root_elem> root_elems(roots.size());
vector<struct pack_elem> pack_elems(pform_packages.size());
bool rc = true;
unsigned i = 0;
@ -5310,6 +5337,7 @@ Design* elaborate(list<perm_string>roots)
// Elaborate the packages. Package elaboration is simpler
// because there are fewer sub-scopes involved.
i = 0;
for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
; pac != pform_packages.end() ; ++ pac) {
@ -5318,9 +5346,14 @@ Design* elaborate(list<perm_string>roots)
elaborator_work_item_t*es = new elaborate_package_t(des, scope, pac->second);
des->elaboration_work_list.push_back(es);
pack_elems[i].pack = pac->second;
pack_elems[i].scope = scope;
i += 1;
}
// Scan the root modules by name, and elaborate their scopes.
i = 0;
for (list<perm_string>::const_iterator root = roots.begin()
; root != roots.end() ; ++ root ) {
@ -5353,10 +5386,9 @@ Design* elaborate(list<perm_string>roots)
// Save this scope, along with its definition, in the
// "root_elems" list for later passes.
struct root_elem *r = new struct root_elem;
r->mod = rmod;
r->scope = scope;
root_elems[i++] = r;
root_elems[i].mod = rmod;
root_elems[i].scope = scope;
i += 1;
// Arrange for these scopes to be elaborated as root
// scopes. Create an "elaborate_root_scope" object to
@ -5413,23 +5445,36 @@ Design* elaborate(list<perm_string>roots)
// what we need to elaborate signals and memories. This pass
// creates all the NetNet and NetMemory objects for declared
// objects.
for (i = 0; i < root_elems.count(); i++) {
for (i = 0; i < pack_elems.size(); i += 1) {
PPackage*pack = pack_elems[i].pack;
NetScope*scope= pack_elems[i].scope;
Module *rmod = root_elems[i]->mod;
NetScope *scope = root_elems[i]->scope;
if (! pack->elaborate_sig(des, scope)) {
if (debug_elaborate) {
cerr << "<toplevel>" << ": debug: " << pack->pscope_name()
<< ": elaborate_sig failed!!!" << endl;
}
delete des;
return 0;
}
}
for (i = 0; i < root_elems.size(); i++) {
Module *rmod = root_elems[i].mod;
NetScope *scope = root_elems[i].scope;
scope->set_num_ports( rmod->port_count() );
if (debug_elaborate) {
cerr << "<toplevel>" << ": debug: " << rmod->mod_name()
<< ": port elaboration root "
<< rmod->port_count() << " ports" << endl;
}
if (debug_elaborate) {
cerr << "<toplevel>" << ": debug: " << rmod->mod_name()
<< ": port elaboration root "
<< rmod->port_count() << " ports" << endl;
}
if (! rmod->elaborate_sig(des, scope)) {
if (debug_elaborate) {
cerr << "<toplevel>" << ": debug: " << rmod->mod_name()
<< ": elaborate_sig failed!!!" << endl;
}
if (debug_elaborate) {
cerr << "<toplevel>" << ": debug: " << rmod->mod_name()
<< ": elaborate_sig failed!!!" << endl;
}
delete des;
return 0;
}
@ -5461,12 +5506,17 @@ Design* elaborate(list<perm_string>roots)
// Now that the structure and parameters are taken care of,
// run through the pform again and generate the full netlist.
for (i = 0; i < root_elems.count(); i++) {
Module *rmod = root_elems[i]->mod;
NetScope *scope = root_elems[i]->scope;
for (i = 0; i < pack_elems.size(); i += 1) {
PPackage*pkg = pack_elems[i].pack;
NetScope*scope = pack_elems[i].scope;
rc &= pkg->elaborate(des, scope);
}
for (i = 0; i < root_elems.size(); i++) {
Module *rmod = root_elems[i].mod;
NetScope *scope = root_elems[i].scope;
rc &= rmod->elaborate(des, scope);
delete root_elems[i];
}
if (rc == false) {

18
emit.cc
View File

@ -436,6 +436,7 @@ bool NetScope::emit_defs(struct target_t*tgt) const
bool flag = true;
switch (type_) {
case PACKAGE:
case MODULE:
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
; cur != children_.end() ; ++ cur )
@ -470,11 +471,17 @@ int Design::emit(struct target_t*tgt) const
if (tgt->start_design(this) == false)
return -2;
// enumerate the scopes
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); ++ scope )
(*scope)->emit_scope(tgt);
// enumerate package scopes
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
; scope != packages_.end() ; ++ scope) {
scope->second->emit_scope(tgt);
}
// enumerate root scopes
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
; scope != root_scopes_.end(); ++ scope ) {
(*scope)->emit_scope(tgt);
}
// emit nodes
bool nodes_rc = true;
@ -494,6 +501,9 @@ int Design::emit(struct target_t*tgt) const
// emit task and function definitions
bool tasks_rc = true;
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
; scope != packages_.end() ; ++ scope )
tasks_rc &= scope->second->emit_defs(tgt);
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
; scope != root_scopes_.end(); ++ scope )
tasks_rc &= (*scope)->emit_defs(tgt);

View File

@ -91,6 +91,19 @@ static bool in_module = false;
static bool in_UDP = false;
bool in_celldefine = false;
UCDriveType uc_drive = UCD_NONE;
/*
* The parser sometimes needs to indicate to the lexor that the next
* identifier needs to be understood in the context of a package. The
* parser feeds back that left context with calls to the
* lex_in_package_scope.
*/
static PPackage* in_package_scope = 0;
void lex_in_package_scope(PPackage*pkg)
{
in_package_scope = pkg;
}
%}
%x CCOMMENT
@ -297,6 +310,24 @@ TU [munpf]
break;
}
/* Special case: If this is part of a scoped name, then check
the package for identifier details. For example, if the
source file is foo::bar, the parse.y will note the
PACKAGE_IDENTIFIER and "::" token and mark the
"in_package_scope" variable. Then this lexor will see the
identifier here and interpret it in the package scope. */
if (in_package_scope) {
if (rc == IDENTIFIER) {
if (data_type_t*type = pform_test_type_identifier(in_package_scope, yylval.text)) {
delete[]yylval.text;
yylval.data_type = type;
rc = TYPE_IDENTIFIER;
}
}
in_package_scope = 0;
return rc;
}
/* If this identifier names a discipline, then return this as
a DISCIPLINE_IDENTIFIER and return the discipline as the
value instead. */
@ -310,6 +341,16 @@ TU [munpf]
}
}
/* If this identifer names a previously declared package, then
return this as a PACKAGE_IDENTIFIER instead. */
if (rc == IDENTIFIER && gn_system_verilog()) {
if (PPackage*pkg = pform_test_package_identifier(yylval.text)) {
delete[]yylval.text;
yylval.package = pkg;
rc = PACKAGE_IDENTIFIER;
}
}
/* If this identifier names a previously declared type, then
return this as a TYPE_IDENTIFIER instead. */
if (rc == IDENTIFIER && gn_system_verilog()) {

View File

@ -400,9 +400,15 @@ void NetScope::run_defparams_later(Design*des)
void Design::evaluate_parameters()
{
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); ++ scope )
for (map<perm_string,NetScope*>::const_iterator cur = packages_.begin()
; cur != packages_.end() ; ++ cur) {
cur->second->evaluate_parameters(this);
}
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
; scope != root_scopes_.end() ; ++ scope ) {
(*scope)->evaluate_parameters(this);
}
}
void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)

61
parse.y
View File

@ -401,6 +401,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
class_type_t*class_type;
real_type_t::type_t real_type;
property_qualifier_t property_qualifier;
PPackage*package;
verinum* number;
@ -410,8 +411,9 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
list<index_component_t> *dimensions;
};
%token <text> IDENTIFIER SYSTEM_IDENTIFIER STRING TIME_LITERAL
%token <text> IDENTIFIER SYSTEM_IDENTIFIER STRING TIME_LITERAL
%token <data_type> TYPE_IDENTIFIER
%token <package> PACKAGE_IDENTIFIER
%token <discipline> DISCIPLINE_IDENTIFIER
%token <text> PATHPULSE_IDENTIFIER
%token <number> BASED_NUMBER DEC_NUMBER UNBASED_NUMBER
@ -894,6 +896,17 @@ constraint_set /* IEEE1800-2005 A.1.9 */
| '{' constraint_expression_list '}'
;
data_declaration /* IEEE1800-2005: A.2.1.3 */
: attribute_list_opt data_type_or_implicit list_of_variable_decl_assignments ';'
{ data_type_t*data_type = $2;
if (data_type == 0) {
data_type = new vector_type_t(IVL_VT_LOGIC, false, 0);
FILE_NAME(data_type, @2);
}
pform_makewire(@2, 0, str_strength, $3, NetNet::IMPLICIT_REG, data_type);
}
;
data_type /* IEEE1800-2005: A.2.2.1 */
: integer_vector_type unsigned_signed_opt range_opt
{ ivl_variable_type_t use_vtype = $1;
@ -925,6 +938,12 @@ data_type /* IEEE1800-2005: A.2.2.1 */
{ if ($2) $$ = new parray_type_t($1, $2);
else $$ = $1;
}
| PACKAGE_IDENTIFIER K_SCOPE_RES
{ lex_in_package_scope($1); }
TYPE_IDENTIFIER
{ lex_in_package_scope(0);
$$ = $4;
}
| K_string
{ string_type_t*tmp = new string_type_t;
FILE_NAME(tmp, @1);
@ -1373,14 +1392,12 @@ package_import_declaration /* IEEE1800-2005 A.2.1.3 */
;
package_import_item
: IDENTIFIER K_SCOPE_RES IDENTIFIER
: PACKAGE_IDENTIFIER K_SCOPE_RES IDENTIFIER
{ pform_package_import(@2, $1, $3);
delete[]$1;
delete[]$3;
}
| IDENTIFIER K_SCOPE_RES '*'
| PACKAGE_IDENTIFIER K_SCOPE_RES '*'
{ pform_package_import(@2, $1, 0);
delete[]$1;
}
;
@ -1395,6 +1412,8 @@ package_item /* IEEE1800-2005 A.1.10 */
| K_localparam param_type localparam_assign_list ';'
| type_declaration
| function_declaration
| task_declaration
| data_declaration
;
package_item_list
@ -2985,16 +3004,17 @@ expr_primary
delete $1;
}
| IDENTIFIER K_SCOPE_RES IDENTIFIER
{ $$ = pform_package_ident(@2, $1, $3); }
| PACKAGE_IDENTIFIER K_SCOPE_RES hierarchy_identifier
{ $$ = pform_package_ident(@2, $1, $3);
delete $3;
}
/* An identifier followed by an expression list in parentheses is a
function call. If a system identifier, then a system function
call. */
| hierarchy_identifier '(' expression_list_proper ')'
{ PECallFunction*tmp = new PECallFunction(*$1, *$3);
FILE_NAME(tmp, @1);
{ PECallFunction*tmp = pform_make_call_function(@1, *$1, *$3);
delete $1;
$$ = tmp;
}
@ -3006,15 +3026,21 @@ expr_primary
$$ = tmp;
}
| hierarchy_identifier '(' ')'
{ const vector<PExpr*> empty;
PECallFunction*tmp = new PECallFunction(*$1, empty);
FILE_NAME(tmp, @1);
{ const list<PExpr*> empty;
PECallFunction*tmp = pform_make_call_function(@1, *$1, empty);
delete $1;
$$ = tmp;
if (!gn_system_verilog()) {
yyerror(@1, "error: Empty function argument list requires SystemVerilog.");
}
}
| PACKAGE_IDENTIFIER K_SCOPE_RES IDENTIFIER '(' expression_list_proper ')'
{ perm_string use_name = lex_strings.make($3);
PECallFunction*tmp = new PECallFunction($1, use_name, *$5);
FILE_NAME(tmp, @3);
delete[]$3;
$$ = tmp;
}
| SYSTEM_IDENTIFIER '(' ')'
{ perm_string tn = lex_strings.make($1);
const vector<PExpr*>empty;
@ -3837,7 +3863,7 @@ atom2_type
rule to reflect the rules for assignment l-values. */
lpvalue
: hierarchy_identifier
{ PEIdent*tmp = new PEIdent(*$1);
{ PEIdent*tmp = pform_new_ident(*$1);
FILE_NAME(tmp, @1);
$$ = tmp;
delete $1;
@ -5700,8 +5726,7 @@ statement_item /* This is roughly statement_item in the LRM */
}
| hierarchy_identifier '(' expression_list_with_nuls ')' ';'
{ PCallTask*tmp = new PCallTask(*$1, *$3);
FILE_NAME(tmp, @1);
{ PCallTask*tmp = pform_make_call_task(@1, *$1, *$3);
delete $1;
delete $3;
$$ = tmp;
@ -5735,8 +5760,7 @@ statement_item /* This is roughly statement_item in the LRM */
| hierarchy_identifier ';'
{ list<PExpr*>pt;
PCallTask*tmp = new PCallTask(*$1, pt);
FILE_NAME(tmp, @1);
PCallTask*tmp = pform_make_call_task(@1, *$1, pt);
delete $1;
$$ = tmp;
}
@ -5744,8 +5768,7 @@ statement_item /* This is roughly statement_item in the LRM */
| hierarchy_identifier '(' error ')' ';'
{ yyerror(@3, "error: Syntax error in task arguments.");
list<PExpr*>pt;
PCallTask*tmp = new PCallTask(*$1, pt);
FILE_NAME(tmp, @1);
PCallTask*tmp = pform_make_call_task(@1, *$1, pt);
delete $1;
$$ = tmp;
}

View File

@ -78,6 +78,15 @@ extern UCDriveType uc_drive;
extern bool have_timeunit_decl;
extern bool have_timeprec_decl;
/*
* The parser signals back to the lexor that the next identifier
* should be in the package scope. For example, if the source is
* <package> :: <foo>
* Then the parser calls this function to set the package context so
* that the lexor can interpret <foo> in the package context.
*/
extern void lex_in_package_scope(PPackage*pkg);
/*
* Test if this identifier is a type identifier in the current
* context. The pform code needs to help the lexor here because the
@ -85,6 +94,13 @@ extern bool have_timeprec_decl;
* type names.
*/
extern data_type_t* pform_test_type_identifier(const char*txt);
extern data_type_t* pform_test_type_identifier(PPackage*pkg, const char*txt);
/*
* Test if this identigier is a package name. The pform needs to help
* the lexor here because the parser detects packages and saves them.
*/
extern PPackage* pform_test_package_identifier(const char*txt);
/*
* Export these functions because we have to generate PENumber class

120
pform.cc
View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 1998-2013 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -424,18 +425,15 @@ PBlock* pform_push_block_scope(char*name, PBlock::BL_TYPE bt)
*/
PEIdent* pform_new_ident(const pform_name_t&name)
{
if (name.size() != 1)
return new PEIdent(name);
LexicalScope*scope = pform_peek_scope();
map<perm_string,PPackage*>::const_iterator pkg = scope->imports.find(name.back().name);
map<perm_string,PPackage*>::const_iterator pkg = scope->imports.find(name.front().name);
if (pkg == scope->imports.end())
return new PEIdent(name);
// XXXX For now, do not support indexed imported names.
assert(name.back().index.size() == 0);
return new PEIdent(pkg->second, name.back().name);
return new PEIdent(pkg->second, name);
}
PGenerate* pform_parent_generate(void)
@ -519,18 +517,98 @@ data_type_t* pform_test_type_identifier(const char*txt)
return 0;
perm_string name = lex_strings.make(txt);
map<perm_string,data_type_t*>::iterator cur;
LexicalScope*cur_scope = lexical_scope;
do {
map<perm_string,data_type_t*>::iterator cur;
// First look to see if this identifier is imported from
// a package. If it is, see if it is a type in that
// package. If it is, then great. If imported as
// something other then a type, then give up now becase
// the name has at least shadowed any other possible
// meaning for this name.
map<perm_string,PPackage*>::iterator cur_pkg;
cur_pkg = cur_scope->imports.find(name);
if (cur_pkg != cur_scope->imports.end()) {
PPackage*pkg = cur_pkg->second;
cur = pkg->typedefs.find(name);
if (cur != pkg->typedefs.end())
return cur->second;
// Not a type. Give up.
return 0;
}
cur = cur_scope->typedefs.find(name);
if (cur != cur_scope->typedefs.end())
return cur->second;
cur_scope = cur_scope->parent_scope();
} while (cur_scope);
return 0;
}
PECallFunction* pform_make_call_function(const struct vlltype&loc,
const pform_name_t&name,
const list<PExpr*>&parms)
{
PECallFunction*tmp = 0;
// First try to get the function name from a package. Check
// the imports, and if the name is there, make the function as
// a package member.
do {
if (name.size() != 1)
break;
perm_string use_name = peek_tail_name(name);
map<perm_string,PPackage*>::iterator cur_pkg;
cur_pkg = lexical_scope->imports.find(use_name);
if (cur_pkg == lexical_scope->imports.end())
break;
tmp = new PECallFunction(cur_pkg->second, use_name, parms);
} while(0);
if (tmp == 0) {
tmp = new PECallFunction(name, parms);
}
FILE_NAME(tmp, loc);
return tmp;
}
PCallTask* pform_make_call_task(const struct vlltype&loc,
const pform_name_t&name,
const list<PExpr*>&parms)
{
PCallTask*tmp = 0;
do {
if (name.size() != 1)
break;
perm_string use_name = peek_tail_name(name);
map<perm_string,PPackage*>::iterator cur_pkg;
cur_pkg = lexical_scope->imports.find(use_name);
if (cur_pkg == lexical_scope->imports.end())
break;
tmp = new PCallTask(cur_pkg->second, name, parms);
} while (0);
if (tmp == 0) {
tmp = new PCallTask(name, parms);
}
FILE_NAME(tmp, loc);
return tmp;
}
static void pform_put_behavior_in_scope(PProcess*pp)
{
lexical_scope->behaviors.push_back(pp);
@ -2243,6 +2321,7 @@ void pform_makewire(const vlltype&li,
first = first->next;
} while (first != decls->next);
// The pform_set_data_type function will delete the names list.
pform_set_data_type(li, data_type, names, type, 0);
// This time, go through the list, deleting cells as I'm done.
@ -2264,6 +2343,35 @@ void pform_makewire(const vlltype&li,
}
}
/*
* This should eventually repliace the form above that takes a
* net_decl_assign_t argument.
*/
void pform_makewire(const struct vlltype&li,
std::list<PExpr*>*, str_pair_t ,
std::list<decl_assignment_t*>*assign_list,
NetNet::Type type,
data_type_t*data_type)
{
list<perm_string>*names = new list<perm_string>;
for (list<decl_assignment_t*>::iterator cur = assign_list->begin()
; cur != assign_list->end() ; ++ cur) {
decl_assignment_t* curp = *cur;
names->push_back(curp->name);
}
pform_set_data_type(li, data_type, names, type, 0);
while (! assign_list->empty()) {
decl_assignment_t*first = assign_list->front();
assign_list->pop_front();
// For now, do not handle assignment expressions.
assert(! first->expr.get());
delete first;
}
}
/*
* This function is called by the parser to create task ports. The
* resulting wire (which should be a register) is put into a list to

24
pform.h
View File

@ -57,6 +57,7 @@
*/
class PGate;
class PExpr;
class PPackage;
class PSpecPath;
class PClass;
class PPackage;
@ -207,10 +208,10 @@ extern void pform_start_package_declaration(const struct vlltype&loc,
const char*type);
extern void pform_end_package_declaration(const struct vlltype&loc);
extern void pform_package_import(const struct vlltype&loc,
const char*pkg_name, const char*ident);
PPackage*pkg, const char*ident);
extern PExpr* pform_package_ident(const struct vlltype&loc,
const char*pkg_name, const char*ident);
PPackage*pkg, pform_name_t*ident);
/*
* This creates an identifier aware of names that may have been
@ -272,6 +273,18 @@ extern PGenerate* pform_parent_generate(void);
extern void pform_set_typedef(perm_string name, data_type_t*data_type);
/*
* This function makes a PECallFunction of the named function. Decide
* if this function is in the scope or is imported from a package.
*/
extern PECallFunction* pform_make_call_function(const struct vlltype&loc,
const pform_name_t&name,
const std::list<PExpr*>&parms);
extern PCallTask* pform_make_call_task(const struct vlltype&loc,
const pform_name_t&name,
const std::list<PExpr*>&parms);
/*
* The makewire functions announce to the pform code new wires. These
* go into a module that is currently opened.
@ -301,6 +314,13 @@ extern void pform_makewire(const struct vlltype&li,
NetNet::Type type,
data_type_t*data_type);
extern void pform_makewire(const struct vlltype&li,
std::list<PExpr*>*delay,
str_pair_t str,
std::list<decl_assignment_t*>*assign_list,
NetNet::Type type,
data_type_t*data_type);
/* This form handles nets declared as structures. (See pform_struct_type.cc) */
extern void pform_makewire(const struct vlltype&li,
struct_type_t*struct_type,

View File

@ -239,6 +239,8 @@ void PEConcat::dump(ostream&out) const
void PECallFunction::dump(ostream &out) const
{
if (package_) out << package_->pscope_name() << "::";
out << path_ << "(";
if (! parms_.empty()) {
@ -1537,5 +1539,7 @@ void PPackage::pform_dump(std::ostream&out) const
out << "package " << pscope_name() << endl;
dump_localparams_(out, 4);
dump_parameters_(out, 4);
dump_tasks_(out, 4);
dump_funcs_(out, 4);
out << "endpackage" << endl;
}

View File

@ -71,18 +71,8 @@ void pform_end_package_declaration(const struct vlltype&loc)
* package is declared in pform ahead of time (it is) and that we can
* simply transfer definitions to the current scope (we can).
*/
void pform_package_import(const struct vlltype&, const char*pkg_name, const char*ident)
void pform_package_import(const struct vlltype&, PPackage*pkg, const char*ident)
{
perm_string use_name = lex_strings.make(pkg_name);
map<perm_string,PPackage*>::const_iterator pcur = pform_packages.find(use_name);
if (pcur == pform_packages.end()) {
ostringstream msg;
msg << "Package " << pkg_name << " not found." << ends;
VLerror(msg.str().c_str());
return;
}
PPackage*pkg = pcur->second;
LexicalScope*scope = pform_peek_scope();
if (ident) {
@ -90,15 +80,50 @@ void pform_package_import(const struct vlltype&, const char*pkg_name, const char
map<perm_string,LexicalScope::param_expr_t>::const_iterator cur
= pkg->parameters.find(use_ident);
if (cur == pkg->parameters.end()) {
ostringstream msg;
msg << "Symbol " << use_ident
<< " not found in package " << pcur->first << "." << ends;
VLerror(msg.str().c_str());
if (cur != pkg->parameters.end()) {
scope->imports[cur->first] = pkg;
return;
}
scope->imports[cur->first] = pkg;
cur = pkg->localparams.find(use_ident);
if (cur != pkg->localparams.end()) {
scope->imports[cur->first] = pkg;
return;
}
map<perm_string,data_type_t*>::const_iterator tcur;
tcur = pkg->typedefs.find(use_ident);
if (tcur != pkg->typedefs.end()) {
scope->imports[tcur->first] = pkg;
return;
}
map<perm_string,PFunction*>::const_iterator fcur;
fcur = pkg->funcs.find(use_ident);
if (fcur != pkg->funcs.end()) {
scope->imports[fcur->first] = pkg;
return;
}
map<perm_string,PTask*>::const_iterator ttcur;
ttcur = pkg->tasks.find(use_ident);
if (ttcur != pkg->tasks.end()) {
scope->imports[ttcur->first] = pkg;
return;
}
map<perm_string,PWire*>::const_iterator wcur;
wcur = pkg->wires.find(use_ident);
if (wcur != pkg->wires.end()) {
scope->imports[wcur->first] = pkg;
return;
}
ostringstream msg;
msg << "Symbol " << use_ident
<< " not found in package " << pkg->pscope_name() << "." << ends;
VLerror(msg.str().c_str());
return;
} else {
@ -109,24 +134,56 @@ void pform_package_import(const struct vlltype&, const char*pkg_name, const char
scope->imports[cur->first] = pkg;
}
for (map<perm_string,LexicalScope::param_expr_t>::const_iterator cur = pkg->localparams.begin()
; cur != pkg->localparams.end() ; ++cur) {
scope->imports[cur->first] = pkg;
}
for (map<perm_string,data_type_t*>::const_iterator cur = pkg->typedefs.begin()
; cur != pkg->typedefs.end() ; ++cur) {
scope->imports[cur->first] = pkg;
}
for (map<perm_string,PFunction*>::const_iterator cur = pkg->funcs.begin()
; cur != pkg->funcs.end() ; ++cur) {
scope->imports[cur->first] = pkg;
}
}
}
PExpr* pform_package_ident(const struct vlltype&loc,
const char*pkg_name, const char*ident_name)
PPackage*pkg, pform_name_t*ident_name)
{
perm_string use_name = lex_strings.make(pkg_name);
map<perm_string,PPackage*>::const_iterator pcur = pform_packages.find(use_name);
if (pcur == pform_packages.end()) {
ostringstream msg;
msg << "Package " << pkg_name << " not found." << ends;
VLerror(msg.str().c_str());
return 0;
}
assert(pcur->second);
perm_string use_ident = lex_strings.make(ident_name);
PEIdent*tmp = new PEIdent(pcur->second, use_ident);
assert(ident_name);
PEIdent*tmp = new PEIdent(pkg, *ident_name);
FILE_NAME(tmp, loc);
return tmp;
}
data_type_t* pform_test_type_identifier(PPackage*pkg, const char*txt)
{
perm_string use_name = lex_strings.make(txt);
map<perm_string,data_type_t*>::const_iterator cur = pkg->typedefs.find(use_name);
if (cur != pkg->typedefs.end())
return cur->second;
return 0;
}
/*
* The lexor uses this function to know if the
*/
PPackage* pform_test_package_identifier(const char*pkg_name)
{
perm_string use_name = lex_strings.make(pkg_name);
map<perm_string,PPackage*>::const_iterator pcur = pform_packages.find(use_name);
if (pcur == pform_packages.end())
return 0;
assert(pcur->second);
return pcur->second;
}

View File

@ -2035,14 +2035,14 @@ extern "C" const char* ivl_scope_name(ivl_scope_t net)
extern "C" unsigned ivl_scope_params(ivl_scope_t net)
{
assert(net);
return net->nparam_;
return net->param.size();
}
extern "C" ivl_parameter_t ivl_scope_param(ivl_scope_t net, unsigned idx)
{
assert(net);
assert(idx < net->nparam_);
return net->param_ + idx;
assert(idx < net->param.size());
return & (net->param[idx]);
}
extern "C" ivl_scope_t ivl_scope_parent(ivl_scope_t net)

View File

@ -259,6 +259,13 @@ ivl_scope_t dll_target::find_scope(ivl_design_s &des, const NetScope*cur)
return scope;
}
for (size_t idx = 0; idx < des.packages.size(); idx += 1) {
assert(des.packages[idx]);
ivl_scope_t scope = find_scope_from_root(des.packages[idx], cur);
if (scope)
return scope;
}
for (map<const NetScope*,ivl_scope_t>::iterator idx = des.classes.begin()
; idx != des.classes.end() ; ++ idx) {
ivl_scope_t scope = find_scope_from_root(idx->second, cur);
@ -467,9 +474,9 @@ ivl_parameter_t dll_target::scope_find_param(ivl_scope_t scope,
const char*name)
{
unsigned idx = 0;
while (idx < scope->nparam_) {
if (strcmp(name, scope->param_[idx].basename) == 0)
return scope->param_ + idx;
while (idx < scope->param.size()) {
if (strcmp(name, scope->param[idx].basename) == 0)
return &scope->param[idx];
idx += 1;
}
@ -484,13 +491,12 @@ ivl_parameter_t dll_target::scope_find_param(ivl_scope_t scope,
*/
void dll_target::make_scope_parameters(ivl_scope_t scop, const NetScope*net)
{
scop->nparam_ = net->parameters.size();
if (scop->nparam_ == 0) {
scop->param_ = 0;
if (net->parameters.size() == 0) {
scop->param.clear();
return;
}
scop->param_ = new struct ivl_parameter_s [scop->nparam_];
scop->param.resize(net->parameters.size());
unsigned idx = 0;
typedef map<perm_string,NetScope::param_expr_t>::const_iterator pit_t;
@ -498,14 +504,20 @@ void dll_target::make_scope_parameters(ivl_scope_t scop, const NetScope*net)
for (pit_t cur_pit = net->parameters.begin()
; cur_pit != net->parameters.end() ; ++ cur_pit ) {
assert(idx < scop->nparam_);
ivl_parameter_t cur_par = scop->param_ + idx;
cur_par->basename = (*cur_pit).first;
assert(idx < scop->param.size());
ivl_parameter_t cur_par = &scop->param[idx];
cur_par->basename = cur_pit->first;
cur_par->local = cur_pit->second.local_flag;
cur_par->scope = scop;
FILE_NAME(cur_par, &((*cur_pit).second));
FILE_NAME(cur_par, &(cur_pit->second));
NetExpr*etmp = (*cur_pit).second.val;
NetExpr*etmp = cur_pit->second.val;
if (etmp == 0) {
cerr << "?:?: internal error: "
<< "What is the parameter expression for " << cur_pit->first
<< " in " << net->fullname() << "?" << endl;
}
assert(etmp);
make_scope_param_expr(cur_par, etmp);
idx += 1;
}

View File

@ -653,8 +653,7 @@ struct ivl_scope_s {
unsigned nlpm_;
ivl_lpm_t* lpm_;
unsigned nparam_;
ivl_parameter_t param_;
std::vector<struct ivl_parameter_s> param;
/* Scopes that are tasks/functions have a definition. */
ivl_statement_t def;