Add -D to iverilog-vpi and update documentation.
[iverilog.git] / elab_scope.cc
blob2909077e742d53b2d37ad6cb9eb0b828ed899cbb
1 /*
2 * Copyright (c) 2000-2003 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
8 * any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 #ifdef HAVE_CVS_IDENT
20 #ident "$Id: elab_scope.cc,v 1.46 2007/06/02 03:42:12 steve Exp $"
21 #endif
23 # include "config.h"
24 # include "compiler.h"
25 # include "netmisc.h"
26 # include <iostream>
27 # include <stdio.h>
30 * Elaboration happens in two passes, generally. The first scans the
31 * pform to generate the NetScope tree and attach it to the Design
32 * object. The methods in this source file implement the elaboration
33 * of the scopes.
36 # include "Module.h"
37 # include "PEvent.h"
38 # include "PExpr.h"
39 # include "PGate.h"
40 # include "PGenerate.h"
41 # include "PTask.h"
42 # include "PWire.h"
43 # include "Statement.h"
44 # include "netlist.h"
45 # include "util.h"
46 # include <typeinfo>
47 # include <assert.h>
49 bool Module::elaborate_scope(Design*des, NetScope*scope,
50 const replace_t&replacements) const
52 if (debug_scopes) {
53 cerr << get_line() << ": debug: Elaborate scope "
54 << scope_path(scope) << "." << endl;
57 // Generate all the parameters that this instance of this
58 // module introduces to the design. This loop elaborates the
59 // parameters, but doesn't evaluate references to
60 // parameters. This scan practically locates all the
61 // parameters and puts them in the parameter table in the
62 // design.
64 // No expressions are evaluated, yet. For now, leave them in
65 // the pform and just place a NetEParam placeholder in the
66 // place of the elaborated expression.
68 typedef map<perm_string,param_expr_t>::const_iterator mparm_it_t;
69 typedef map<pform_name_t,PExpr*>::const_iterator pform_parm_it_t;
72 // This loop scans the parameters in the module, and creates
73 // stub parameter entries in the scope for the parameter name.
75 for (mparm_it_t cur = parameters.begin()
76 ; cur != parameters.end() ; cur ++) {
78 NetEParam*tmp = new NetEParam;
79 tmp->set_line(*((*cur).second.expr));
80 tmp->cast_signed( (*cur).second.signed_flag );
82 scope->set_parameter((*cur).first, tmp, 0, 0, false);
85 for (mparm_it_t cur = localparams.begin()
86 ; cur != localparams.end() ; cur ++) {
88 NetEParam*tmp = new NetEParam;
89 tmp->set_line(*((*cur).second.expr));
90 if ((*cur).second.msb)
91 tmp->cast_signed( (*cur).second.signed_flag );
93 scope->set_parameter((*cur).first, tmp, 0, 0, false);
97 // Now scan the parameters again, this time elaborating them
98 // for use as parameter values. This is after the previous
99 // scan so that local parameter names can be used in the
100 // r-value expressions.
102 for (mparm_it_t cur = parameters.begin()
103 ; cur != parameters.end() ; cur ++) {
105 PExpr*ex = (*cur).second.expr;
106 assert(ex);
108 NetExpr*val = ex->elaborate_pexpr(des, scope);
109 NetExpr*msb = 0;
110 NetExpr*lsb = 0;
111 bool signed_flag = (*cur).second.signed_flag;
113 /* If the parameter declaration includes msb and lsb,
114 then use them to calculate a width for the
115 result. Then make sure the constant expression of the
116 parameter value is coerced to have the correct
117 and defined width. */
118 if ((*cur).second.msb) {
119 msb = (*cur).second.msb ->elaborate_pexpr(des, scope);
120 assert(msb);
121 lsb = (*cur).second.lsb ->elaborate_pexpr(des, scope);
124 if (signed_flag) {
125 /* If explicitly signed, then say so. */
126 val->cast_signed(true);
127 } else if ((*cur).second.msb) {
128 /* If there is a range, then the signedness comes
129 from the type and not the expression. */
130 val->cast_signed(signed_flag);
131 } else {
132 /* otherwise, let the expression describe
133 itself. */
134 signed_flag = val->has_sign();
137 val = scope->set_parameter((*cur).first, val,
138 msb, lsb, signed_flag);
139 assert(val);
140 delete val;
143 /* run parameter replacements that were collected from the
144 containing scope and meant for me. */
145 for (replace_t::const_iterator cur = replacements.begin()
146 ; cur != replacements.end() ; cur ++) {
148 NetExpr*val = (*cur).second;
149 if (val == 0) {
150 cerr << get_line() << ": internal error: "
151 << "Missing expression in parameter replacement for "
152 << (*cur).first;
154 assert(val);
155 if (debug_scopes) {
156 cerr << get_line() << ": debug: "
157 << "Replace " << (*cur).first
158 << " with expression " << *val
159 << " from " << val->get_line() << "." << endl;
161 bool flag = scope->replace_parameter((*cur).first, val);
162 if (! flag) {
163 cerr << val->get_line() << ": warning: parameter "
164 << (*cur).first << " not found in "
165 << scope_path(scope) << "." << endl;
169 for (mparm_it_t cur = localparams.begin()
170 ; cur != localparams.end() ; cur ++) {
172 PExpr*ex = (*cur).second.expr;
173 assert(ex);
175 NetExpr*val = ex->elaborate_pexpr(des, scope);
176 NetExpr*msb = 0;
177 NetExpr*lsb = 0;
178 bool signed_flag = false;
180 /* If the parameter declaration includes msb and lsb,
181 then use them to calculate a width for the
182 result. Then make sure the constant expression of the
183 parameter value is coerced to have the correct
184 and defined width. */
185 if ((*cur).second.msb) {
186 msb = (*cur).second.msb ->elaborate_pexpr(des, scope);
187 assert(msb);
188 lsb = (*cur).second.lsb ->elaborate_pexpr(des, scope);
189 signed_flag = (*cur).second.signed_flag;
192 val->cast_signed(signed_flag);
193 val = scope->set_parameter((*cur).first, val,
194 msb, lsb, signed_flag);
195 assert(val);
196 delete val;
199 // Run through the defparams for this module, elaborate the
200 // expressions in this context and save the result is a table
201 // for later final override.
203 // It is OK to elaborate the expressions of the defparam here
204 // because Verilog requires that the expressions only use
205 // local parameter names. It is *not* OK to do the override
206 // here because the parameter receiving the assignment may be
207 // in a scope not discovered by this pass.
209 for (pform_parm_it_t cur = defparms.begin()
210 ; cur != defparms.end() ; cur ++ ) {
212 PExpr*ex = (*cur).second;
213 assert(ex);
215 NetExpr*val = ex->elaborate_pexpr(des, scope);
216 if (val == 0) continue;
217 scope->defparams[(*cur).first] = val;
220 // Evaluate the attributes. Evaluate them in the scope of the
221 // module that the attribute is attached to. Is this correct?
222 unsigned nattr;
223 attrib_list_t*attr = evaluate_attributes(attributes, nattr, des, scope);
225 for (unsigned idx = 0 ; idx < nattr ; idx += 1)
226 scope->attribute(attr[idx].key, attr[idx].val);
228 delete[]attr;
230 // Generate schemes can create new scopes in the form of
231 // generated code. Scan the generate schemes, and *generate*
232 // new scopes, which is slightly different from simple
233 // elaboration.
235 typedef list<PGenerate*>::const_iterator generate_it_t;
236 for (generate_it_t cur = generate_schemes.begin()
237 ; cur != generate_schemes.end() ; cur ++ ) {
238 (*cur) -> generate_scope(des, scope);
242 // Tasks introduce new scopes, so scan the tasks in this
243 // module. Create a scope for the task and pass that to the
244 // elaborate_scope method of the PTask for detailed
245 // processing.
247 typedef map<perm_string,PTask*>::const_iterator tasks_it_t;
249 for (tasks_it_t cur = tasks_.begin()
250 ; cur != tasks_.end() ; cur ++ ) {
252 hname_t use_name( (*cur).first );
253 if (scope->child(use_name)) {
254 cerr << get_line() << ": error: task/scope name "
255 << use_name << " already used in this context."
256 << endl;
257 des->errors += 1;
258 continue;
260 NetScope*task_scope = new NetScope(scope, use_name,
261 NetScope::TASK);
262 (*cur).second->elaborate_scope(des, task_scope);
266 // Functions are very similar to tasks, at least from the
267 // perspective of scopes. So handle them exactly the same
268 // way.
270 typedef map<perm_string,PFunction*>::const_iterator funcs_it_t;
272 for (funcs_it_t cur = funcs_.begin()
273 ; cur != funcs_.end() ; cur ++ ) {
275 hname_t use_name( (*cur).first );
276 if (scope->child(use_name)) {
277 cerr << get_line() << ": error: function/scope name "
278 << use_name << " already used in this context."
279 << endl;
280 des->errors += 1;
281 continue;
283 NetScope*func_scope = new NetScope(scope, use_name,
284 NetScope::FUNC);
285 (*cur).second->elaborate_scope(des, func_scope);
289 // Gates include modules, which might introduce new scopes, so
290 // scan all of them to create those scopes.
292 typedef list<PGate*>::const_iterator gates_it_t;
293 for (gates_it_t cur = gates_.begin()
294 ; cur != gates_.end() ; cur ++ ) {
296 (*cur) -> elaborate_scope(des, scope);
300 // initial and always blocks may contain begin-end and
301 // fork-join blocks that can introduce scopes. Therefore, I
302 // get to scan processes here.
304 typedef list<PProcess*>::const_iterator proc_it_t;
306 for (proc_it_t cur = behaviors_.begin()
307 ; cur != behaviors_.end() ; cur ++ ) {
309 (*cur) -> statement() -> elaborate_scope(des, scope);
312 // Scan through all the named events in this scope. We do not
313 // need anything more than the current scope to do this
314 // elaboration, so do it now. This allows for normal
315 // elaboration to reference these events.
317 for (map<perm_string,PEvent*>::const_iterator et = events.begin()
318 ; et != events.end() ; et ++ ) {
320 (*et).second->elaborate_scope(des, scope);
323 return des->errors == 0;
326 bool PGenerate::generate_scope(Design*des, NetScope*container)
328 switch (scheme_type) {
329 case GS_LOOP:
330 return generate_scope_loop_(des, container);
332 case GS_CONDIT:
333 return generate_scope_condit_(des, container, false);
335 case GS_ELSE:
336 return generate_scope_condit_(des, container, true);
338 default:
339 cerr << get_line() << ": sorry: Generate of this sort"
340 << " is not supported yet!" << endl;
341 return false;
346 * This is the elaborate scope method for a generate loop.
348 bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
350 // We're going to need a genvar...
351 int genvar;
353 // The initial value for the genvar does not need (nor can it
354 // use) the genvar itself, so we can evaluate this expression
355 // the same way any other paramter value is evaluated.
356 NetExpr*init_ex = elab_and_eval(des, container, loop_init, -1);
357 NetEConst*init = dynamic_cast<NetEConst*> (init_ex);
358 if (init == 0) {
359 cerr << get_line() << ": error: Cannot evaluate genvar"
360 << " init expression: " << *loop_init << endl;
361 des->errors += 1;
362 return false;
365 genvar = init->value().as_long();
366 delete init_ex;
368 if (debug_elaborate)
369 cerr << get_line() << ": debug: genvar init = " << genvar << endl;
371 container->genvar_tmp = loop_index;
372 container->genvar_tmp_val = genvar;
373 NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
374 NetEConst*test = dynamic_cast<NetEConst*>(test_ex);
375 assert(test);
376 while (test->value().as_long()) {
378 // The actual name of the scope includes the genvar so
379 // that each instance has a unique name in the
380 // container. The format of using [] is part of the
381 // Verilog standard.
382 hname_t use_name (scope_name, genvar);
383 if (container->child(use_name)) {
384 cerr << get_line() << ": error: block/scope name "
385 << use_name << " already used in this context."
386 << endl;
387 des->errors += 1;
388 return false;
390 if (debug_elaborate)
391 cerr << get_line() << ": debug: "
392 << "Create generated scope " << use_name << endl;
394 NetScope*scope = new NetScope(container, use_name,
395 NetScope::GENBLOCK);
397 // Set in the scope a localparam for the value of the
398 // genvar within this instance of the generate
399 // block. Code within this scope thus has access to the
400 // genvar as a constant.
402 verinum genvar_verinum(genvar);
403 genvar_verinum.has_sign(true);
404 NetEConstParam*gp = new NetEConstParam(scope,
405 loop_index,
406 genvar_verinum);
407 scope->set_localparam(loop_index, gp);
409 if (debug_elaborate)
410 cerr << get_line() << ": debug: "
411 << "Create implicit localparam "
412 << loop_index << " = " << genvar_verinum << endl;
415 elaborate_subscope_(des, scope);
417 // Calculate the step for the loop variable.
418 NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1);
419 NetEConst*step = dynamic_cast<NetEConst*>(step_ex);
420 assert(step);
421 if (debug_elaborate)
422 cerr << get_line() << ": debug: genvar step from "
423 << genvar << " to " << step->value().as_long() << endl;
425 genvar = step->value().as_long();
426 container->genvar_tmp_val = genvar;
427 delete step;
428 delete test_ex;
429 test_ex = elab_and_eval(des, container, loop_test, -1);
430 test = dynamic_cast<NetEConst*>(test_ex);
431 assert(test);
434 // Clear the genvar_tmp field in the scope to reflect that the
435 // genvar is no longer value for evaluating expressions.
436 container->genvar_tmp = perm_string();
438 return true;
441 bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else_flag)
443 NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
444 NetEConst*test = dynamic_cast<NetEConst*> (test_ex);
445 assert(test);
447 // If the condition evaluates as false, then do not create the
448 // scope.
449 if (test->value().as_long() == 0 && !else_flag
450 || test->value().as_long() != 0 && else_flag) {
451 if (debug_elaborate)
452 cerr << get_line() << ": debug: Generate condition "
453 << (else_flag? "(else)" : "(if)")
454 << " value=" << test->value() << ": skip generation"
455 << endl;
456 delete test_ex;
457 return true;
460 hname_t use_name (scope_name);
461 if (container->child(use_name)) {
462 cerr << get_line() << ": error: block/scope name "
463 << scope_name << " already used in this context."
464 << endl;
465 des->errors += 1;
466 return false;
468 if (debug_elaborate)
469 cerr << get_line() << ": debug: Generate condition "
470 << (else_flag? "(else)" : "(if)")
471 << " value=" << test->value() << ": Generate scope="
472 << use_name << endl;
474 NetScope*scope = new NetScope(container, use_name,
475 NetScope::GENBLOCK);
477 elaborate_subscope_(des, scope);
479 return true;
482 void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
484 // Scan the generated scope for nested generate schemes,
485 // and *generate* new scopes, which is slightly different
486 // from simple elaboration.
488 typedef list<PGenerate*>::const_iterator generate_it_t;
489 for (generate_it_t cur = generates.begin()
490 ; cur != generates.end() ; cur ++ ) {
491 (*cur) -> generate_scope(des, scope);
494 // Scan the generated scope for gates that may create
495 // their own scopes.
496 typedef list<PGate*>::const_iterator pgate_list_it_t;
497 for (pgate_list_it_t cur = gates.begin()
498 ; cur != gates.end() ; cur ++) {
499 (*cur) ->elaborate_scope(des, scope);
502 // Save the scope that we created, for future use.
503 scope_list_.push_back(scope);
506 void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
508 if (get_name() == "") {
509 cerr << get_line() << ": error: Instantiation of module "
510 << mod->mod_name() << " requires an instance name." << endl;
511 des->errors += 1;
512 return;
515 // Missing module instance names have already been rejected.
516 assert(get_name() != "");
518 // Check for duplicate scopes. Simply look up the scope I'm
519 // about to create, and if I find it then somebody beat me to
520 // it.
522 if (sc->child(hname_t(get_name()))) {
523 cerr << get_line() << ": error: Instance/Scope name " <<
524 get_name() << " already used in this context." <<
525 endl;
526 des->errors += 1;
527 return;
530 // check for recursive instantiation by scanning the current
531 // scope and its parents. Look for a module instantiation of
532 // the same module, but farther up in the scope.
534 for (NetScope*scn = sc ; scn ; scn = scn->parent()) {
535 if (scn->type() != NetScope::MODULE)
536 continue;
538 if (strcmp(mod->mod_name(), scn->module_name()) != 0)
539 continue;
541 cerr << get_line() << ": error: You cannot instantiate "
542 << "module " << mod->mod_name() << " within itself." << endl;
544 cerr << get_line() << ": : The offending instance is "
545 << scope_path(sc) << "." << get_name() << " within "
546 << scope_path(scn) << "." << endl;
548 des->errors += 1;
549 return;
552 NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_, -1) : 0;
553 NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_, -1) : 0;
554 NetEConst*msb = dynamic_cast<NetEConst*> (mse);
555 NetEConst*lsb = dynamic_cast<NetEConst*> (lse);
557 assert( (msb == 0) || (lsb != 0) );
559 long instance_low = 0;
560 long instance_high = 0;
561 long instance_count = 1;
562 bool instance_array = false;
564 if (msb) {
565 instance_array = true;
566 instance_high = msb->value().as_long();
567 instance_low = lsb->value().as_long();
568 if (instance_high > instance_low)
569 instance_count = instance_high - instance_low + 1;
570 else
571 instance_count = instance_low - instance_high + 1;
573 delete mse;
574 delete lse;
577 NetScope::scope_vec_t instances (instance_count);
578 if (debug_scopes) {
579 cerr << get_line() << ": debug: Create " << instance_count
580 << " instances of " << get_name()
581 << "." << endl;
584 // Run through the module instances, and make scopes out of
585 // them. Also do parameter overrides that are done on the
586 // instantiation line.
587 for (int idx = 0 ; idx < instance_count ; idx += 1) {
589 hname_t use_name (get_name());
591 if (instance_array) {
592 int instance_idx = idx;
593 if (instance_low < instance_high)
594 instance_idx = instance_low + idx;
595 else
596 instance_idx = instance_low - idx;
598 use_name = hname_t(get_name(), instance_idx);
601 if (debug_scopes) {
602 cerr << get_line() << ": debug: Module instance " << use_name
603 << " becomes child of " << scope_path(sc)
604 << "." << endl;
607 // Create the new scope as a MODULE with my name.
608 NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE);
609 my_scope->set_module_name(mod->mod_name());
610 my_scope->default_nettype(mod->default_nettype);
612 instances[idx] = my_scope;
614 // Set time units and precision.
615 my_scope->time_unit(mod->time_unit);
616 my_scope->time_precision(mod->time_precision);
617 des->set_precision(mod->time_precision);
619 // Look for module parameter replacements. The "replace" map
620 // maps parameter name to replacement expression that is
621 // passed. It is built up by the ordered overrides or named
622 // overrides.
624 typedef map<perm_string,PExpr*>::const_iterator mparm_it_t;
625 map<perm_string,PExpr*> replace;
628 // Positional parameter overrides are matched to parameter
629 // names by using the param_names list of parameter
630 // names. This is an ordered list of names so the first name
631 // is parameter 0, the second parameter 1, and so on.
633 if (overrides_) {
634 assert(parms_ == 0);
635 list<perm_string>::const_iterator cur
636 = mod->param_names.begin();
637 unsigned idx = 0;
638 for (;;) {
639 if (idx >= overrides_->count())
640 break;
641 if (cur == mod->param_names.end())
642 break;
644 replace[*cur] = (*overrides_)[idx];
646 idx += 1;
647 cur ++;
651 // Named parameter overrides carry a name with each override
652 // so the mapping into the replace list is much easier.
653 if (parms_) {
654 assert(overrides_ == 0);
655 for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
656 replace[parms_[idx].name] = parms_[idx].parm;
661 Module::replace_t replace_net;
663 // And here we scan the replacements we collected. Elaborate
664 // the expression in my context, then replace the sub-scope
665 // parameter value with the new expression.
667 for (mparm_it_t cur = replace.begin()
668 ; cur != replace.end() ; cur ++ ) {
670 PExpr*tmp = (*cur).second;
671 // No expression means that the parameter is not
672 // replaced at all.
673 if (tmp == 0)
674 continue;
675 NetExpr*val = tmp->elaborate_pexpr(des, sc);
676 replace_net[(*cur).first] = val;
679 // This call actually arranges for the description of the
680 // module type to process this instance and handle parameters
681 // and sub-scopes that might occur. Parameters are also
682 // created in that scope, as they exist. (I'll override them
683 // later.)
684 mod->elaborate_scope(des, my_scope, replace_net);
688 /* Stash the instance array of scopes into the parent
689 scope. Later elaboration passes will use this vector to
690 further elaborate the array. */
691 sc->instance_arrays[get_name()] = instances;
695 * The isn't really able to create new scopes, but it does create the
696 * event name in the current scope, so can be done during the
697 * elaborate_scope scan. Note that the name_ of the PEvent object has
698 * no hierarchy, but neither does the NetEvent, until it is stored in
699 * the NetScope object.
701 void PEvent::elaborate_scope(Design*des, NetScope*scope) const
703 NetEvent*ev = new NetEvent(name_);
704 ev->set_line(*this);
705 scope->add_event(ev);
708 void PFunction::elaborate_scope(Design*des, NetScope*scope) const
710 assert(scope->type() == NetScope::FUNC);
712 if (statement_)
713 statement_->elaborate_scope(des, scope);
716 void PTask::elaborate_scope(Design*des, NetScope*scope) const
718 assert(scope->type() == NetScope::TASK);
720 if (statement_)
721 statement_->elaborate_scope(des, scope);
726 * The base statement does not have sub-statements and does not
727 * introduce any scope, so this is a no-op.
729 void Statement::elaborate_scope(Design*, NetScope*) const
734 * When I get a behavioral block, check to see if it has a name. If it
735 * does, then create a new scope for the statements within it,
736 * otherwise use the current scope. Use the selected scope to scan the
737 * statements that I contain.
739 void PBlock::elaborate_scope(Design*des, NetScope*scope) const
741 NetScope*my_scope = scope;
743 if (name_ != 0) {
744 hname_t use_name(name_);
745 if (scope->child(use_name)) {
746 cerr << get_line() << ": error: block/scope name "
747 << use_name << " already used in this context."
748 << endl;
749 des->errors += 1;
750 return;
752 my_scope = new NetScope(scope, use_name, bl_type_==BL_PAR
753 ? NetScope::FORK_JOIN
754 : NetScope::BEGIN_END);
757 for (unsigned idx = 0 ; idx < list_.count() ; idx += 1)
758 list_[idx] -> elaborate_scope(des, my_scope);
763 * The case statement itself does not introduce scope, but contains
764 * other statements that may be named blocks. So scan the case items
765 * with the elaborate_scope method.
767 void PCase::elaborate_scope(Design*des, NetScope*scope) const
769 assert(items_);
770 for (unsigned idx = 0 ; idx < (*items_).count() ; idx += 1) {
771 assert( (*items_)[idx] );
773 if (Statement*sp = (*items_)[idx]->stat)
774 sp -> elaborate_scope(des, scope);
779 * The conditional statement (if-else) does not introduce scope, but
780 * the statements of the clauses may, so elaborate_scope the contained
781 * statements.
783 void PCondit::elaborate_scope(Design*des, NetScope*scope) const
785 if (if_)
786 if_ -> elaborate_scope(des, scope);
788 if (else_)
789 else_ -> elaborate_scope(des, scope);
793 * Statements that contain a further statement but do not
794 * intrinsically add a scope need to elaborate_scope the contained
795 * statement.
797 void PDelayStatement::elaborate_scope(Design*des, NetScope*scope) const
799 if (statement_)
800 statement_ -> elaborate_scope(des, scope);
804 * Statements that contain a further statement but do not
805 * intrinsically add a scope need to elaborate_scope the contained
806 * statement.
808 void PEventStatement::elaborate_scope(Design*des, NetScope*scope) const
810 if (statement_)
811 statement_ -> elaborate_scope(des, scope);
815 * Statements that contain a further statement but do not
816 * intrinsically add a scope need to elaborate_scope the contained
817 * statement.
819 void PForever::elaborate_scope(Design*des, NetScope*scope) const
821 if (statement_)
822 statement_ -> elaborate_scope(des, scope);
826 * Statements that contain a further statement but do not
827 * intrinsically add a scope need to elaborate_scope the contained
828 * statement.
830 void PForStatement::elaborate_scope(Design*des, NetScope*scope) const
832 if (statement_)
833 statement_ -> elaborate_scope(des, scope);
837 * Statements that contain a further statement but do not
838 * intrinsically add a scope need to elaborate_scope the contained
839 * statement.
841 void PRepeat::elaborate_scope(Design*des, NetScope*scope) const
843 if (statement_)
844 statement_ -> elaborate_scope(des, scope);
848 * Statements that contain a further statement but do not
849 * intrinsically add a scope need to elaborate_scope the contained
850 * statement.
852 void PWhile::elaborate_scope(Design*des, NetScope*scope) const
854 if (statement_)
855 statement_ -> elaborate_scope(des, scope);