Reword how we enforce program block constraints
Making the scope type NESTED_MODULE was just plain wrong, because it didn't really encapsulate the meaning of program blocks OR nested modules. So instead create nested_module() and program_block() flags and use those to test scope constraints.
This commit is contained in:
parent
dfe7beec31
commit
8154ce2a4a
|
|
@ -1136,6 +1136,9 @@ void NetScope::dump(ostream&o) const
|
||||||
print_type(o);
|
print_type(o);
|
||||||
if (is_auto()) o << " (automatic)";
|
if (is_auto()) o << " (automatic)";
|
||||||
if (is_cell()) o << " (cell)";
|
if (is_cell()) o << " (cell)";
|
||||||
|
if (nested_module()) o << " (nested)";
|
||||||
|
if (program_block()) o << " (program)";
|
||||||
|
|
||||||
o << endl;
|
o << endl;
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1)
|
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1)
|
||||||
|
|
|
||||||
|
|
@ -693,7 +693,7 @@ NetNet* PEIdent::elaborate_bi_net(Design*des, NetScope*scope) const
|
||||||
*/
|
*/
|
||||||
NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
|
NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
assert(scope->type_is_module());
|
ivl_assert(*this, scope->type() == NetScope::MODULE);
|
||||||
NetNet*sig = des->find_signal(scope, path_);
|
NetNet*sig = des->find_signal(scope, path_);
|
||||||
if (sig == 0) {
|
if (sig == 0) {
|
||||||
cerr << get_fileline() << ": error: no wire/reg " << path_
|
cerr << get_fileline() << ": error: no wire/reg " << path_
|
||||||
|
|
|
||||||
|
|
@ -1225,7 +1225,7 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! scn->type_is_module()) continue;
|
if (scn->type() != NetScope::MODULE) continue;
|
||||||
|
|
||||||
if (strcmp(mod->mod_name(), scn->module_name()) != 0) continue;
|
if (strcmp(mod->mod_name(), scn->module_name()) != 0) continue;
|
||||||
|
|
||||||
|
|
@ -1345,7 +1345,9 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
||||||
// Create the new scope as a MODULE with my name. Note
|
// Create the new scope as a MODULE with my name. Note
|
||||||
// that if this is a nested module, mark it thus so that
|
// that if this is a nested module, mark it thus so that
|
||||||
// scope searches will continue into the parent scope.
|
// scope searches will continue into the parent scope.
|
||||||
NetScope*my_scope = new NetScope(sc, use_name, bound_type_? NetScope::NESTED_MODULE : NetScope::MODULE);
|
NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE,
|
||||||
|
bound_type_? true : false,
|
||||||
|
mod->program_block);
|
||||||
my_scope->set_line(get_file(), mod->get_file(),
|
my_scope->set_line(get_file(), mod->get_file(),
|
||||||
get_lineno(), mod->get_lineno());
|
get_lineno(), mod->get_lineno());
|
||||||
my_scope->set_module_name(mod->mod_name());
|
my_scope->set_module_name(mod->mod_name());
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ bool PScope::elaborate_sig_wires_(Design*des, NetScope*scope) const
|
||||||
reg, then report an error. */
|
reg, then report an error. */
|
||||||
|
|
||||||
if (sig && (sig->scope() == scope)
|
if (sig && (sig->scope() == scope)
|
||||||
&& (scope->type_is_module())
|
&& (scope->type() == NetScope::MODULE)
|
||||||
&& (sig->port_type() == NetNet::PINPUT)
|
&& (sig->port_type() == NetNet::PINPUT)
|
||||||
&& (sig->type() == NetNet::REG)) {
|
&& (sig->type() == NetNet::REG)) {
|
||||||
|
|
||||||
|
|
@ -110,7 +110,7 @@ bool PScope::elaborate_sig_wires_(Design*des, NetScope*scope) const
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sig && (sig->scope() == scope)
|
if (sig && (sig->scope() == scope)
|
||||||
&& (scope->type_is_module())
|
&& (scope->type() == NetScope::MODULE)
|
||||||
&& (sig->port_type() == NetNet::PINOUT)
|
&& (sig->port_type() == NetNet::PINOUT)
|
||||||
&& (sig->type() == NetNet::REG)) {
|
&& (sig->type() == NetNet::REG)) {
|
||||||
|
|
||||||
|
|
@ -122,7 +122,7 @@ bool PScope::elaborate_sig_wires_(Design*des, NetScope*scope) const
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sig && (sig->scope() == scope)
|
if (sig && (sig->scope() == scope)
|
||||||
&& scope->type_is_module()
|
&& (scope->type() == NetScope::MODULE)
|
||||||
&& (sig->port_type() == NetNet::PINOUT)
|
&& (sig->port_type() == NetNet::PINOUT)
|
||||||
&& (sig->data_type() == IVL_VT_REAL)) {
|
&& (sig->data_type() == IVL_VT_REAL)) {
|
||||||
|
|
||||||
|
|
|
||||||
45
elaborate.cc
45
elaborate.cc
|
|
@ -2312,6 +2312,18 @@ NetProc* PAssign::elaborate_compressed_(Design*des, NetScope*scope) const
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool lval_not_program_variable(const NetAssign_*lv)
|
||||||
|
{
|
||||||
|
while (lv) {
|
||||||
|
NetScope*sig_scope = lv->sig()->scope();
|
||||||
|
if (! sig_scope->program_block())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
lv = lv->more;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
assert(scope);
|
assert(scope);
|
||||||
|
|
@ -2326,6 +2338,12 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
||||||
NetAssign_*lv = elaborate_lval(des, scope);
|
NetAssign_*lv = elaborate_lval(des, scope);
|
||||||
if (lv == 0) return 0;
|
if (lv == 0) return 0;
|
||||||
|
|
||||||
|
if (scope->program_block() && lval_not_program_variable(lv)) {
|
||||||
|
cerr << get_fileline() << ": error: Blocking assignments to "
|
||||||
|
<< "non-program variables are not allowed." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* If there is an internal delay expression, elaborate it. */
|
/* If there is an internal delay expression, elaborate it. */
|
||||||
NetExpr*delay = 0;
|
NetExpr*delay = 0;
|
||||||
if (delay_ != 0)
|
if (delay_ != 0)
|
||||||
|
|
@ -2469,6 +2487,22 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return true if any lvalue parts are in a program block scope.
|
||||||
|
*/
|
||||||
|
static bool lval_is_program_variable(const NetAssign_*lv)
|
||||||
|
{
|
||||||
|
while (lv) {
|
||||||
|
NetScope*sig_scope = lv->sig()->scope();
|
||||||
|
if (sig_scope->program_block())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
lv = lv->more;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Elaborate non-blocking assignments. The statement is of the general
|
* Elaborate non-blocking assignments. The statement is of the general
|
||||||
* form:
|
* form:
|
||||||
|
|
@ -2505,6 +2539,14 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const
|
||||||
NetAssign_*lv = elaborate_lval(des, scope);
|
NetAssign_*lv = elaborate_lval(des, scope);
|
||||||
if (lv == 0) return 0;
|
if (lv == 0) return 0;
|
||||||
|
|
||||||
|
if (scope->program_block() && lval_is_program_variable(lv)) {
|
||||||
|
cerr << get_fileline() << ": error: Non-blocking assignments to "
|
||||||
|
<< "program variables are not allowed." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
// This is an error, but we can let elaboration continue
|
||||||
|
// because it would necessarily trigger other errors.
|
||||||
|
}
|
||||||
|
|
||||||
NetExpr*rv = elaborate_rval_(des, scope, count_lval_width(lv), lv->expr_type());
|
NetExpr*rv = elaborate_rval_(des, scope, count_lval_width(lv), lv->expr_type());
|
||||||
if (rv == 0) return 0;
|
if (rv == 0) return 0;
|
||||||
|
|
||||||
|
|
@ -3256,7 +3298,6 @@ NetProc* PDisable::elaborate(Design*des, NetScope*scope) const
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case NetScope::MODULE:
|
case NetScope::MODULE:
|
||||||
case NetScope::NESTED_MODULE:
|
|
||||||
cerr << get_fileline() << ": error: Cannot disable modules." << endl;
|
cerr << get_fileline() << ": error: Cannot disable modules." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -4849,7 +4890,7 @@ Design* elaborate(list<perm_string>roots)
|
||||||
|
|
||||||
// Make the root scope. This makes a NetScope object and
|
// Make the root scope. This makes a NetScope object and
|
||||||
// pushes it into the list of root scopes in the Design.
|
// pushes it into the list of root scopes in the Design.
|
||||||
NetScope*scope = des->make_root_scope(*root);
|
NetScope*scope = des->make_root_scope(*root, rmod->program_block);
|
||||||
|
|
||||||
// Collect some basic properties of this scope from the
|
// Collect some basic properties of this scope from the
|
||||||
// Module definition.
|
// Module definition.
|
||||||
|
|
|
||||||
|
|
@ -101,10 +101,11 @@ uint64_t Design::scale_to_precision(uint64_t val,
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetScope* Design::make_root_scope(perm_string root)
|
NetScope* Design::make_root_scope(perm_string root, bool program_block)
|
||||||
{
|
{
|
||||||
NetScope *root_scope_;
|
NetScope *root_scope_;
|
||||||
root_scope_ = new NetScope(0, hname_t(root), NetScope::MODULE);
|
root_scope_ = new NetScope(0, hname_t(root), NetScope::MODULE,
|
||||||
|
false, program_block);
|
||||||
/* This relies on the fact that the basename return value is
|
/* This relies on the fact that the basename return value is
|
||||||
permallocated. */
|
permallocated. */
|
||||||
root_scope_->set_module_name(root_scope_->basename());
|
root_scope_->set_module_name(root_scope_->basename());
|
||||||
|
|
|
||||||
17
net_scope.cc
17
net_scope.cc
|
|
@ -38,8 +38,8 @@ class PExpr;
|
||||||
* in question.
|
* in question.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t)
|
NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, bool nest, bool prog)
|
||||||
: type_(t), name_(n), up_(up)
|
: type_(t), name_(n), nested_module_(nest), program_block_(prog), up_(up)
|
||||||
{
|
{
|
||||||
events_ = 0;
|
events_ = 0;
|
||||||
lcounter_ = 0;
|
lcounter_ = 0;
|
||||||
|
|
@ -302,9 +302,6 @@ void NetScope::print_type(ostream&stream) const
|
||||||
case FUNC:
|
case FUNC:
|
||||||
stream << "function";
|
stream << "function";
|
||||||
break;
|
break;
|
||||||
case NESTED_MODULE:
|
|
||||||
stream << "nested_module <" << (module_name_ ? module_name_.str() : "")
|
|
||||||
<< "> instance";
|
|
||||||
case MODULE:
|
case MODULE:
|
||||||
stream << "module <" << (module_name_ ? module_name_.str() : "")
|
stream << "module <" << (module_name_ ? module_name_.str() : "")
|
||||||
<< "> instance";
|
<< "> instance";
|
||||||
|
|
@ -363,31 +360,31 @@ const NetFuncDef* NetScope::func_def() const
|
||||||
|
|
||||||
void NetScope::set_module_name(perm_string n)
|
void NetScope::set_module_name(perm_string n)
|
||||||
{
|
{
|
||||||
assert(type_ == MODULE || type_ == NESTED_MODULE);
|
assert(type_ == MODULE);
|
||||||
module_name_ = n; /* NOTE: n must have been permallocated. */
|
module_name_ = n; /* NOTE: n must have been permallocated. */
|
||||||
}
|
}
|
||||||
|
|
||||||
perm_string NetScope::module_name() const
|
perm_string NetScope::module_name() const
|
||||||
{
|
{
|
||||||
assert(type_ == MODULE || type_ == NESTED_MODULE);
|
assert(type_ == MODULE);
|
||||||
return module_name_;
|
return module_name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetScope::add_module_port(NetNet*port)
|
void NetScope::add_module_port(NetNet*port)
|
||||||
{
|
{
|
||||||
assert(type_ == MODULE || type_ == NESTED_MODULE);
|
assert(type_ == MODULE);
|
||||||
ports_.push_back(port);
|
ports_.push_back(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned NetScope::module_ports() const
|
unsigned NetScope::module_ports() const
|
||||||
{
|
{
|
||||||
assert(type_ == MODULE || type_ == NESTED_MODULE);
|
assert(type_ == MODULE);
|
||||||
return ports_.size();
|
return ports_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
NetNet* NetScope::module_port(unsigned idx) const
|
NetNet* NetScope::module_port(unsigned idx) const
|
||||||
{
|
{
|
||||||
assert(type_ == MODULE || type_ == NESTED_MODULE);
|
assert(type_ == MODULE);
|
||||||
assert(idx < ports_.size());
|
assert(idx < ports_.size());
|
||||||
return ports_[idx];
|
return ports_[idx];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
16
netlist.h
16
netlist.h
|
|
@ -724,11 +724,11 @@ extern std::ostream&operator << (std::ostream&out, const std::list<netrange_t>&r
|
||||||
class NetScope : public Attrib {
|
class NetScope : public Attrib {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum TYPE { MODULE, NESTED_MODULE, TASK, FUNC, BEGIN_END, FORK_JOIN, GENBLOCK };
|
enum TYPE { MODULE, TASK, FUNC, BEGIN_END, FORK_JOIN, GENBLOCK };
|
||||||
|
|
||||||
/* Create a new scope, and attach it to the given parent. The
|
/* Create a new scope, and attach it to the given parent. The
|
||||||
name is expected to have been permallocated. */
|
name is expected to have been permallocated. */
|
||||||
NetScope(NetScope*up, const hname_t&name, TYPE t);
|
NetScope(NetScope*up, const hname_t&name, TYPE t, bool nest=false, bool prog=false);
|
||||||
~NetScope();
|
~NetScope();
|
||||||
|
|
||||||
/* Rename the scope using the name generated by inserting as
|
/* Rename the scope using the name generated by inserting as
|
||||||
|
|
@ -805,8 +805,11 @@ class NetScope : public Attrib {
|
||||||
const NetScope* parent() const { return up_; }
|
const NetScope* parent() const { return up_; }
|
||||||
const NetScope* child(const hname_t&name) const;
|
const NetScope* child(const hname_t&name) const;
|
||||||
|
|
||||||
|
// Nested modules have slightly different scope search rules.
|
||||||
|
inline bool nested_module() const { return nested_module_; }
|
||||||
|
// Program blocks have elaboration constraints.
|
||||||
|
inline bool program_block() const { return program_block_; }
|
||||||
TYPE type() const;
|
TYPE type() const;
|
||||||
bool type_is_module() const { return type()==MODULE || type()==NESTED_MODULE; }
|
|
||||||
void print_type(ostream&) const;
|
void print_type(ostream&) const;
|
||||||
|
|
||||||
void set_task_def(NetTaskDef*);
|
void set_task_def(NetTaskDef*);
|
||||||
|
|
@ -989,6 +992,11 @@ class NetScope : public Attrib {
|
||||||
TYPE type_;
|
TYPE type_;
|
||||||
hname_t name_;
|
hname_t name_;
|
||||||
|
|
||||||
|
// True if the scope is a nested module/program block
|
||||||
|
bool nested_module_;
|
||||||
|
// True if the scope is a program block
|
||||||
|
bool program_block_;
|
||||||
|
|
||||||
perm_string file_;
|
perm_string file_;
|
||||||
perm_string def_file_;
|
perm_string def_file_;
|
||||||
unsigned lineno_;
|
unsigned lineno_;
|
||||||
|
|
@ -4012,7 +4020,7 @@ class Design {
|
||||||
|
|
||||||
const char* get_flag(const string&key) const;
|
const char* get_flag(const string&key) const;
|
||||||
|
|
||||||
NetScope* make_root_scope(perm_string name);
|
NetScope* make_root_scope(perm_string name, bool program_block);
|
||||||
NetScope* find_root_scope();
|
NetScope* find_root_scope();
|
||||||
list<NetScope*> find_root_scopes();
|
list<NetScope*> find_root_scopes();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,6 @@ void nodangle_f::signal(Design*, NetNet*sig)
|
||||||
if ((sig->port_type() != NetNet::NOT_A_PORT) &&
|
if ((sig->port_type() != NetNet::NOT_A_PORT) &&
|
||||||
((sig->scope()->type() == NetScope::TASK) ||
|
((sig->scope()->type() == NetScope::TASK) ||
|
||||||
(sig->scope()->type() == NetScope::FUNC) ||
|
(sig->scope()->type() == NetScope::FUNC) ||
|
||||||
(sig->scope()->type() == NetScope::NESTED_MODULE) ||
|
|
||||||
(sig->scope()->type() == NetScope::MODULE)))
|
(sig->scope()->type() == NetScope::MODULE)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
||||||
10
parse.y
10
parse.y
|
|
@ -5489,15 +5489,11 @@ statement_item /* This is roughly statement_item in the LRM */
|
||||||
{ PAssignNB*tmp = new PAssignNB($1,$3);
|
{ PAssignNB*tmp = new PAssignNB($1,$3);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
if (pform_in_program_block())
|
|
||||||
yyerror(@2, "Non-blocking assignments not permitted in program blocks.");
|
|
||||||
}
|
}
|
||||||
| error K_LE expression ';'
|
| error K_LE expression ';'
|
||||||
{ yyerror(@2, "Syntax in assignment statement l-value.");
|
{ yyerror(@2, "Syntax in assignment statement l-value.");
|
||||||
yyerrok;
|
yyerrok;
|
||||||
$$ = new PNoop;
|
$$ = new PNoop;
|
||||||
if (pform_in_program_block())
|
|
||||||
yyerror(@2, "Non-blocking assignments not permitted in program blocks.");
|
|
||||||
}
|
}
|
||||||
| lpvalue '=' delay1 expression ';'
|
| lpvalue '=' delay1 expression ';'
|
||||||
{ PExpr*del = $3->front(); $3->pop_front();
|
{ PExpr*del = $3->front(); $3->pop_front();
|
||||||
|
|
@ -5512,8 +5508,6 @@ statement_item /* This is roughly statement_item in the LRM */
|
||||||
PAssignNB*tmp = new PAssignNB($1,del,$4);
|
PAssignNB*tmp = new PAssignNB($1,del,$4);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
if (pform_in_program_block())
|
|
||||||
yyerror(@2, "Non-blocking assignments not permitted in program blocks.");
|
|
||||||
}
|
}
|
||||||
| lpvalue '=' event_control expression ';'
|
| lpvalue '=' event_control expression ';'
|
||||||
{ PAssign*tmp = new PAssign($1,0,$3,$4);
|
{ PAssign*tmp = new PAssign($1,0,$3,$4);
|
||||||
|
|
@ -5530,15 +5524,11 @@ statement_item /* This is roughly statement_item in the LRM */
|
||||||
{ PAssignNB*tmp = new PAssignNB($1,0,$3,$4);
|
{ PAssignNB*tmp = new PAssignNB($1,0,$3,$4);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
if (pform_in_program_block())
|
|
||||||
yyerror(@2, "Non-blocking assignments not permitted in program blocks.");
|
|
||||||
}
|
}
|
||||||
| lpvalue K_LE K_repeat '(' expression ')' event_control expression ';'
|
| lpvalue K_LE K_repeat '(' expression ')' event_control expression ';'
|
||||||
{ PAssignNB*tmp = new PAssignNB($1,$5,$7,$8);
|
{ PAssignNB*tmp = new PAssignNB($1,$5,$7,$8);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
if (pform_in_program_block())
|
|
||||||
yyerror(@2, "Non-blocking assignments not permitted in program blocks.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The IEEE1800 standard defines dynamic_array_new assignment as a
|
/* The IEEE1800 standard defines dynamic_array_new assignment as a
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ NetScope*symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
||||||
|
|
||||||
/* We can't look up if we are at the enclosing module scope
|
/* We can't look up if we are at the enclosing module scope
|
||||||
* or if a hierarchical path was given. */
|
* or if a hierarchical path was given. */
|
||||||
if ((scope->type() == NetScope::MODULE) || hier_path)
|
if ((scope->type()==NetScope::MODULE && !scope->nested_module()) || hier_path)
|
||||||
scope = 0;
|
scope = 0;
|
||||||
else
|
else
|
||||||
scope = scope->parent();
|
scope = scope->parent();
|
||||||
|
|
|
||||||
1
t-dll.cc
1
t-dll.cc
|
|
@ -2297,7 +2297,6 @@ void dll_target::scope(const NetScope*net)
|
||||||
|
|
||||||
switch (net->type()) {
|
switch (net->type()) {
|
||||||
case NetScope::MODULE:
|
case NetScope::MODULE:
|
||||||
case NetScope::NESTED_MODULE:
|
|
||||||
scop->type_ = IVL_SCT_MODULE;
|
scop->type_ = IVL_SCT_MODULE;
|
||||||
scop->tname_ = net->module_name();
|
scop->tname_ = net->module_name();
|
||||||
scop->ports = net->module_ports();
|
scop->ports = net->module_ports();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue