$finish() now stops at the end of the time step not immediately.
[iverilog.git] / net_scope.cc
blob18c5dab90efa4bc4f5d9cd4ea409bd8227a544af
1 /*
2 * Copyright (c) 2000 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: net_scope.cc,v 1.38 2007/06/02 03:42:13 steve Exp $"
21 #endif
23 # include "config.h"
24 # include "compiler.h"
26 # include "netlist.h"
27 # include <sstream>
30 * The NetScope class keeps a scope tree organized. Each node of the
31 * scope tree points to its parent, its right sibling and its leftmost
32 * child. The root node has no parent or siblings. The node stores the
33 * name of the scope. The complete hierarchical name of the scope is
34 * formed by appending the path of scopes from the root to the scope
35 * in question.
38 NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t)
39 : type_(t), up_(up), sib_(0), sub_(0)
41 signals_ = 0;
42 events_ = 0;
43 lcounter_ = 0;
45 if (up) {
46 time_unit_ = up->time_unit();
47 time_prec_ = up->time_precision();
48 sib_ = up_->sub_;
49 up_->sub_ = this;
50 } else {
51 time_unit_ = 0;
52 time_prec_ = 0;
53 assert(t == MODULE);
56 switch (t) {
57 case NetScope::TASK:
58 task_ = 0;
59 break;
60 case NetScope::FUNC:
61 func_ = 0;
62 break;
63 case NetScope::MODULE:
64 module_name_ = perm_string();
65 break;
66 default: /* BEGIN_END and FORK_JOIN, do nothing */
67 break;
69 name_ = n;
72 NetScope::~NetScope()
74 assert(sib_ == 0);
75 assert(sub_ == 0);
76 lcounter_ = 0;
78 /* name_ and module_name_ are perm-allocated. */
81 NetExpr* NetScope::set_parameter(perm_string key, NetExpr*expr,
82 NetExpr*msb, NetExpr*lsb, bool signed_flag)
84 param_expr_t&ref = parameters[key];
85 NetExpr* res = ref.expr;
86 ref.expr = expr;
87 ref.msb = msb;
88 ref.lsb = lsb;
89 ref.signed_flag = signed_flag;
90 return res;
94 * Return false if this creates a new parameter.
96 bool NetScope::replace_parameter(perm_string key, NetExpr*expr)
98 bool flag = true;
99 param_expr_t&ref = parameters[key];
101 NetExpr* res = ref.expr;
103 if (res) {
104 delete res;
105 } else {
106 flag = false;
107 ref.msb = 0;
108 ref.lsb = 0;
109 ref.signed_flag = false;
112 ref.expr = expr;
113 return flag;
116 NetExpr* NetScope::set_localparam(perm_string key, NetExpr*expr)
118 param_expr_t&ref = localparams[key];
119 NetExpr* res = ref.expr;
120 ref.expr = expr;
121 ref.msb = 0;
122 ref.lsb = 0;
123 ref.signed_flag = false;
124 return res;
128 * NOTE: This method takes a const char* as a key to lookup a
129 * parameter, because we don't save that pointer. However, due to the
130 * way the map<> template works, we need to *cheat* and use the
131 * perm_string::literal method to fake the compiler into doing the
132 * compare without actually creating a perm_string.
134 const NetExpr* NetScope::get_parameter(const char* key,
135 const NetExpr*&msb,
136 const NetExpr*&lsb) const
138 map<perm_string,param_expr_t>::const_iterator idx;
140 idx = parameters.find(perm_string::literal(key));
141 if (idx != parameters.end()) {
142 msb = (*idx).second.msb;
143 lsb = (*idx).second.lsb;
144 return (*idx).second.expr;
147 idx = localparams.find(perm_string::literal(key));
148 if (idx != localparams.end()) {
149 msb = (*idx).second.msb;
150 lsb = (*idx).second.lsb;
151 return (*idx).second.expr;
154 return 0;
157 NetScope::TYPE NetScope::type() const
159 return type_;
162 void NetScope::set_task_def(NetTaskDef*def)
164 assert( type_ == TASK );
165 assert( task_ == 0 );
166 task_ = def;
169 NetTaskDef* NetScope::task_def()
171 assert( type_ == TASK );
172 return task_;
175 const NetTaskDef* NetScope::task_def() const
177 assert( type_ == TASK );
178 return task_;
181 void NetScope::set_func_def(NetFuncDef*def)
183 assert( type_ == FUNC );
184 assert( func_ == 0 );
185 func_ = def;
188 NetFuncDef* NetScope::func_def()
190 assert( type_ == FUNC );
191 return func_;
194 const NetFuncDef* NetScope::func_def() const
196 assert( type_ == FUNC );
197 return func_;
200 void NetScope::set_module_name(perm_string n)
202 assert(type_ == MODULE);
203 module_name_ = n; /* NOTE: n mus have been permallocated. */
206 perm_string NetScope::module_name() const
208 assert(type_ == MODULE);
209 return module_name_;
212 void NetScope::time_unit(int val)
214 time_unit_ = val;
217 void NetScope::time_precision(int val)
219 time_prec_ = val;
222 int NetScope::time_unit() const
224 return time_unit_;
227 int NetScope::time_precision() const
229 return time_prec_;
232 void NetScope::default_nettype(NetNet::Type nt)
234 default_nettype_ = nt;
237 NetNet::Type NetScope::default_nettype() const
239 return default_nettype_;
242 perm_string NetScope::basename() const
244 return name_.peek_name();
247 void NetScope::add_event(NetEvent*ev)
249 assert(ev->scope_ == 0);
250 ev->scope_ = this;
251 ev->snext_ = events_;
252 events_ = ev;
255 void NetScope::rem_event(NetEvent*ev)
257 assert(ev->scope_ == this);
258 ev->scope_ = 0;
259 if (events_ == ev) {
260 events_ = ev->snext_;
262 } else {
263 NetEvent*cur = events_;
264 while (cur->snext_ != ev) {
265 assert(cur->snext_);
266 cur = cur->snext_;
268 cur->snext_ = ev->snext_;
271 ev->snext_ = 0;
275 NetEvent* NetScope::find_event(const char*name)
277 for (NetEvent*cur = events_; cur ; cur = cur->snext_)
278 if (strcmp(cur->name(), name) == 0)
279 return cur;
281 return 0;
284 void NetScope::add_signal(NetNet*net)
286 if (signals_ == 0) {
287 net->sig_next_ = net;
288 net->sig_prev_ = net;
289 } else {
290 net->sig_next_ = signals_->sig_next_;
291 net->sig_prev_ = signals_;
292 net->sig_next_->sig_prev_ = net;
293 net->sig_prev_->sig_next_ = net;
295 signals_ = net;
298 void NetScope::rem_signal(NetNet*net)
300 assert(net->scope() == this);
301 if (signals_ == net)
302 signals_ = net->sig_prev_;
304 if (signals_ == net) {
305 signals_ = 0;
306 } else {
307 net->sig_prev_->sig_next_ = net->sig_next_;
308 net->sig_next_->sig_prev_ = net->sig_prev_;
313 * This method looks for a signal within the current scope. The name
314 * is assumed to be the base name of the signal, so no sub-scopes are
315 * searched.
317 NetNet* NetScope::find_signal(const char*key)
319 if (signals_ == 0)
320 return 0;
322 NetNet*cur = signals_;
323 do {
324 if (cur->name() == key)
325 return cur;
326 cur = cur->sig_prev_;
327 } while (cur != signals_);
328 return 0;
332 * This method locates a child scope by name. The name is the simple
333 * name of the child, no hierarchy is searched.
335 NetScope* NetScope::child(const hname_t&name)
337 if (sub_ == 0) return 0;
339 NetScope*cur = sub_;
340 while (cur->name_ != name) {
341 if (cur->sib_ == 0) return 0;
342 cur = cur->sib_;
345 return cur;
348 const NetScope* NetScope::child(const hname_t&name) const
350 if (sub_ == 0) return 0;
352 NetScope*cur = sub_;
353 while (cur->name_ != name) {
354 if (cur->sib_ == 0) return 0;
355 cur = cur->sib_;
358 return cur;
361 NetScope* NetScope::parent()
363 return up_;
366 const NetScope* NetScope::parent() const
368 return up_;
371 perm_string NetScope::local_symbol()
373 ostringstream res;
374 res << "_s" << (lcounter_++);
375 return lex_strings.make(res.str());
377 #if 0
378 string NetScope::local_hsymbol()
380 return string(name()) + "." + string(local_symbol());
382 #endif
385 * $Log: net_scope.cc,v $
386 * Revision 1.38 2007/06/02 03:42:13 steve
387 * Properly evaluate scope path expressions.
389 * Revision 1.37 2007/04/26 03:06:22 steve
390 * Rework hname_t to use perm_strings.
392 * Revision 1.36 2007/01/16 05:44:15 steve
393 * Major rework of array handling. Memories are replaced with the
394 * more general concept of arrays. The NetMemory and NetEMemory
395 * classes are removed from the ivl core program, and the IVL_LPM_RAM
396 * lpm type is removed from the ivl_target API.
398 * Revision 1.35 2005/11/27 05:56:20 steve
399 * Handle bit select of parameter with ranges.
401 * Revision 1.34 2005/07/11 16:56:50 steve
402 * Remove NetVariable and ivl_variable_t structures.
404 * Revision 1.33 2004/10/04 01:10:54 steve
405 * Clean up spurious trailing white space.
407 * Revision 1.32 2004/06/13 04:56:54 steve
408 * Add support for the default_nettype directive.
410 * Revision 1.31 2004/02/20 06:22:56 steve
411 * parameter keys are per_strings.
413 * Revision 1.30 2004/02/18 17:11:56 steve
414 * Use perm_strings for named langiage items.
416 * Revision 1.29 2003/09/13 01:30:07 steve
417 * Missing case warnings.
419 * Revision 1.28 2003/03/10 23:40:53 steve
420 * Keep parameter constants for the ivl_target API.
422 * Revision 1.27 2003/03/06 04:37:12 steve
423 * lex_strings.add module names earlier.
425 * Revision 1.26 2003/03/06 00:28:41 steve
426 * All NetObj objects have lex_string base names.
428 * Revision 1.25 2003/03/01 06:25:30 steve
429 * Add the lex_strings string handler, and put
430 * scope names and system task/function names
431 * into this table. Also, permallocate event
432 * names from the beginning.
434 * Revision 1.24 2003/01/27 05:09:17 steve
435 * Spelling fixes.
437 * Revision 1.23 2003/01/26 21:15:58 steve
438 * Rework expression parsing and elaboration to
439 * accommodate real/realtime values and expressions.
441 * Revision 1.22 2003/01/14 21:16:18 steve
442 * Move strstream to ostringstream for compatibility.
444 * Revision 1.21 2002/12/07 02:49:24 steve
445 * Named event triggers can take hierarchical names.
447 * Revision 1.20 2002/10/19 22:59:49 steve
448 * Redo the parameter vector support to allow
449 * parameter names in range expressions.
451 * Revision 1.19 2002/08/12 01:34:59 steve
452 * conditional ident string using autoconfig.
454 * Revision 1.18 2002/08/05 04:18:45 steve
455 * Store only the base name of memories.
457 * Revision 1.17 2002/07/22 21:07:08 steve
458 * Initialize the lcounter_ to 0.
460 * Revision 1.16 2001/12/03 04:47:15 steve
461 * Parser and pform use hierarchical names as hname_t
462 * objects instead of encoded strings.
464 * Revision 1.15 2001/11/08 05:15:50 steve
465 * Remove string paths from PExpr elaboration.
467 * Revision 1.14 2001/10/20 05:21:51 steve
468 * Scope/module names are char* instead of string.
470 * Revision 1.13 2001/07/25 03:10:49 steve
471 * Create a config.h.in file to hold all the config
472 * junk, and support gcc 3.0. (Stephan Boettcher)
474 * Revision 1.12 2001/07/04 04:34:06 steve
475 * Scope-locals use _s instead of _l.
477 * Revision 1.11 2000/12/16 01:45:48 steve
478 * Detect recursive instantiations (PR#2)
480 * Revision 1.10 2000/10/06 23:46:50 steve
481 * ivl_target updates, including more complete
482 * handling of ivl_nexus_t objects. Much reduced
483 * dependencies on pointers to netlist objects.
485 * Revision 1.9 2000/08/27 15:51:50 steve
486 * t-dll iterates signals, and passes them to the
487 * target module.
489 * Some of NetObj should return char*, not string.
491 * Revision 1.8 2000/07/30 18:25:44 steve
492 * Rearrange task and function elaboration so that the
493 * NetTaskDef and NetFuncDef functions are created during
494 * signal enaboration, and carry these objects in the
495 * NetScope class instead of the extra, useless map in
496 * the Design class.