1 /*
2  * Copyright (c) 1998-2020 Stephen Williams (steve@icarus.com)
3  *
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.
9  *
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.
14  *
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19 
20 # include "config.h"
21 
22 /*
23  * This file contains all the dump methods of the netlist classes.
24  */
25 # include  <typeinfo>
26 # include  <iostream>
27 # include  <iomanip>
28 # include  "netlist.h"
29 # include  "compiler.h"
30 # include  "discipline.h"
31 # include  "netclass.h"
32 # include  "netdarray.h"
33 # include  "netqueue.h"
34 # include  "netvector.h"
35 # include  "ivl_assert.h"
36 # include  "PExpr.h"
37 
operator <<(ostream & o,NetBlock::Type t)38 static ostream& operator<< (ostream&o, NetBlock::Type t)
39 {
40       switch (t) {
41 	  case NetBlock::SEQU:
42 	    o << "begin";
43 	    break;
44 	  case NetBlock::PARA:
45 	    o << "fork";
46 	    break;
47 	  case NetBlock::PARA_JOIN_NONE:
48 	    o << "fork-join_none";
49 	    break;
50 	  case NetBlock::PARA_JOIN_ANY:
51 	    o << "fork-join_any";
52 	    break;
53       }
54       return o;
55 }
56 
operator <<(ostream & o,ivl_drive_t str)57 ostream& operator << (ostream&o, ivl_drive_t str)
58 {
59       switch (str) {
60 	  case IVL_DR_HiZ:
61 	    o << "highz";
62 	    break;
63 	  case IVL_DR_SMALL:
64 	    o << "small";
65 	    break;
66 	  case IVL_DR_MEDIUM:
67 	    o << "medium";
68 	    break;
69 	  case IVL_DR_WEAK:
70 	    o << "weak";
71 	    break;
72 	  case IVL_DR_LARGE:
73 	    o << "large";
74 	    break;
75 	  case IVL_DR_PULL:
76 	    o << "pull";
77 	    break;
78 	  case IVL_DR_STRONG:
79 	    o << "strong";
80 	    break;
81 	  case IVL_DR_SUPPLY:
82 	    o << "supply";
83 	    break;
84 	  default:
85 	    assert(0);
86       }
87       return o;
88 }
89 
operator <<(ostream & o,ivl_variable_type_t val)90 ostream& operator << (ostream&o, ivl_variable_type_t val)
91 {
92       switch (val) {
93 	  case IVL_VT_VOID:
94 	    o << "void";
95 	    break;
96 	  case IVL_VT_NO_TYPE:
97 	    o << "<no_type>";
98 	    break;
99 	  case IVL_VT_REAL:
100 	    o << "real";
101 	    break;
102 	  case IVL_VT_BOOL:
103 	    o << "bool";
104 	    break;
105 	  case IVL_VT_LOGIC:
106 	    o << "logic";
107 	    break;
108 	  case IVL_VT_STRING:
109 	    o << "string";
110 	    break;
111 	  case IVL_VT_DARRAY:
112 	    o << "darray";
113 	    break;
114 	  case IVL_VT_CLASS:
115 	    o << "class";
116 	    break;
117 	  case IVL_VT_QUEUE:
118 	    o << "queue";
119 	    break;
120       }
121       return o;
122 }
123 
operator <<(ostream & o,ivl_switch_type_t val)124 ostream& operator << (ostream&o, ivl_switch_type_t val)
125 {
126       switch (val) {
127 	  case IVL_SW_TRAN:
128 	    o << "tran";
129 	    break;
130 	  case IVL_SW_TRANIF0:
131 	    o << "tranif0";
132 	    break;
133 	  case IVL_SW_TRANIF1:
134 	    o << "tranif1";
135 	    break;
136 	  case IVL_SW_RTRAN:
137 	    o << "rtran";
138 	    break;
139 	  case IVL_SW_RTRANIF0:
140 	    o << "rtranif0";
141 	    break;
142 	  case IVL_SW_RTRANIF1:
143 	    o << "rtranif1";
144 	    break;
145 	  case IVL_SW_TRAN_VP:
146 	    o << "tran(VP)";
147 	    break;
148       }
149       return o;
150 }
151 
operator <<(ostream & fd,PortType::Enum val)152 ostream& operator << (ostream&fd, PortType::Enum val)
153 {
154       switch (val) {
155 	  case PortType::NOT_A_PORT:
156 	    fd << "NOT_A_PORT";
157 	    break;
158 	  case PortType::PIMPLICIT:
159 	    fd << "PIMPLICIT";
160 	    break;
161 	  case PortType::PINPUT:
162 	    fd << "PINPUT";
163 	    break;
164 	  case PortType::POUTPUT:
165 	    fd << "POUTPUT";
166 	    break;
167 	  case PortType::PINOUT:
168 	    fd << "PINOUT";
169 	    break;
170 	  case PortType::PREF:
171 	    fd << "PREF";
172 	    break;
173 	  default:
174 	    fd << "PortType::Enum::?";
175 	    break;
176       }
177 
178       return fd;
179 }
180 
operator <<(ostream & fd,NetCaseCmp::kind_t that)181 ostream& operator << (ostream&fd, NetCaseCmp::kind_t that)
182 {
183       switch (that) {
184 	  case NetCaseCmp::EEQ:
185 	    fd << "===";
186 	    break;
187 	  case NetCaseCmp::NEQ:
188 	    fd << "!==";
189 	    break;
190 	  case NetCaseCmp::WEQ:
191 	    fd << "==?";
192 	    break;
193 	  case NetCaseCmp::WNE:
194 	    fd << "!=?";
195 	    break;
196 	  case NetCaseCmp::XEQ:
197 	    fd << "==x?";
198 	    break;
199 	  case NetCaseCmp::ZEQ:
200 	    fd << "==z?";
201 	    break;
202       }
203       return fd;
204 }
205 
debug_dump(ostream & o) const206 ostream& ivl_type_s::debug_dump(ostream&o) const
207 {
208       o << typeid(*this).name();
209       return o;
210 }
211 
debug_dump(ostream & fd) const212 ostream& netclass_t::debug_dump(ostream&fd) const
213 {
214       fd << "class " << name_ << "{";
215       for (size_t idx = 0 ; idx < property_table_.size() ; idx += 1) {
216 	    if (idx != 0) fd << "; ";
217 	    if (property_table_[idx].type)
218 		  property_table_[idx].type->debug_dump(fd);
219 	    else
220 		  fd << "NO_TYPE";
221 	    fd << " " << property_table_[idx].name;
222       }
223       fd << "}";
224       return fd;
225 }
226 
debug_dump(ostream & o) const227 ostream& netdarray_t::debug_dump(ostream&o) const
228 {
229       o << "dynamic array of " << *element_type();
230       return o;
231 }
232 
debug_dump(ostream & fd) const233 ostream& netqueue_t::debug_dump(ostream&fd) const
234 {
235       fd << "queue of ";
236       if (max_idx_ >= 0) fd << "(maximum of " << max_idx_+1 << " elements) ";
237       fd << *element_type();
238       return fd;
239 }
240 
debug_dump(ostream & o) const241 ostream& netvector_t::debug_dump(ostream&o) const
242 {
243       o << "netvector_t:" << type_ << (signed_? " signed" : " unsigned") << packed_dims_;
244       return o;
245 }
246 
dump_scope_path(ostream & o,const NetScope * scope)247 static inline void dump_scope_path(ostream&o, const NetScope*scope)
248 {
249       const NetScope*parent = scope->parent();
250       if (parent) {
251 	    dump_scope_path(o, parent);
252 	    o << ".";
253       }
254       o << scope->fullname();
255 }
256 
operator <<(ostream & o,struct __ScopePathManip marg)257 ostream& operator <<(ostream&o, struct __ScopePathManip marg)
258 {
259       if (marg.scope != 0)
260 	    dump_scope_path(o, marg.scope);
261       return o;
262 }
263 
operator <<(ostream & o,struct __ObjectPathManip marg)264 ostream& operator <<(ostream&o, struct __ObjectPathManip marg)
265 {
266       if (marg.obj != 0) {
267 	    dump_scope_path(o, marg.obj->scope());
268 	    o << "." << marg.obj->name();
269       }
270       return o;
271 }
272 
operator <<(ostream & fd,Link::DIR dir)273 ostream& operator <<(ostream&fd, Link::DIR dir)
274 {
275       switch (dir) {
276 	  case Link::PASSIVE:
277 	    fd << "PASSIVE";
278 	    break;
279 	  case Link::INPUT:
280 	    fd << "INPUT";
281 	    break;
282 	  case Link::OUTPUT:
283 	    fd << "OUTPUT";
284 	    break;
285 	  default:
286 	    fd << "<" << (int)dir << ">";
287 	    break;
288       }
289       return fd;
290 }
291 
show_type(ostream & fd) const292 void NetPins::show_type(ostream&fd) const
293 {
294       fd << typeid(*this).name();
295 }
296 
show_type(ostream & fd) const297 void NetObj::show_type(ostream&fd) const
298 {
299       fd << typeid(*this).name() << "[" << scope_path(scope_) << "." << name_ << "]";
300 }
301 
302 struct __ShowTypeManip { const NetPins*pins; };
show_type(const NetPins * pins)303 inline __ShowTypeManip show_type(const NetPins*pins)
304 { __ShowTypeManip tmp; tmp.pins = pins; return tmp; }
305 
operator <<(ostream & fd,__ShowTypeManip man)306 inline ostream& operator << (ostream&fd, __ShowTypeManip man)
307 {
308       if (man.pins == 0)
309 	    fd << "NexusSet";
310       else
311 	    man.pins->show_type(fd);
312       return fd;
313 }
314 
315 
dump_link(ostream & fd,unsigned ind) const316 void Link::dump_link(ostream&fd, unsigned ind) const
317 {
318       const Link*cur;
319       const Nexus*nex = nexus();
320 
321       if (nex == 0) {
322 	    fd << setw(ind) << "" << "<unlinked>" << endl;
323 	    return;
324       }
325 
326       for (cur = nex->first_nlink() ; cur; cur = cur->next_nlink()) {
327 	    const NetPins*obj = cur->get_obj();
328 	    unsigned pin = cur->get_pin();
329 	    fd << setw(ind) << "" << "Pin " << pin
330 	       << " of " << show_type(obj)
331 	       << ", dir=" << cur->dir_ << endl;
332       }
333 }
334 
dump(ostream & o,unsigned ind) const335 void NetBranch::dump(ostream&o, unsigned ind) const
336 {
337       static const char*pin_names[2] = {
338 	    "terminal0",
339 	    "terminal1" };
340 
341       o << setw(ind) << "" << "branch island=" << get_island();
342       o << " // " << get_fileline() << endl;
343       dump_node_pins(o, ind+4, pin_names);
344 }
345 
dump(ostream & o,unsigned ind) const346 void NetDelaySrc::dump(ostream&o, unsigned ind) const
347 {
348       o << setw(ind) << "" << "specify delay";
349       if (posedge_) o << " posedge";
350       if (negedge_) o << " negedge";
351       if (is_condit()) {
352 	    if (has_condit()) o << " if";
353 	    else o << " ifnone";
354       }
355       if (parallel_)
356 	    o << " parallel";
357       else
358 	    o << " full";
359       o << " src "
360 	<< "(" << transition_delays_[IVL_PE_01]
361 	<< "," << transition_delays_[IVL_PE_10]
362 	<< "," << transition_delays_[IVL_PE_0z]
363 	<< "/" << transition_delays_[IVL_PE_z1]
364 	<< "," << transition_delays_[IVL_PE_1z]
365 	<< "," << transition_delays_[IVL_PE_z0]
366 	<< "/" << transition_delays_[IVL_PE_0x]
367 	<< "," << transition_delays_[IVL_PE_x1]
368 	<< "," << transition_delays_[IVL_PE_1x]
369 	<< "/" << transition_delays_[IVL_PE_x0]
370 	<< "," << transition_delays_[IVL_PE_xz]
371 	<< "," << transition_delays_[IVL_PE_zx]
372 	<< ") scope=" << scope_path(scope()) << endl;
373       dump_node_pins(o, ind+4);
374 }
375 
operator <<(ostream & out,const netrange_t & that)376 static inline ostream&operator<<(ostream&out, const netrange_t&that)
377 {
378       if (that.defined())
379 	    out << "[" << that.get_msb() << ":" << that.get_lsb() << "]";
380       else
381 	    out << "[]";
382 
383       return out;
384 }
385 
operator <<(ostream & out,const list<netrange_t> & rlist)386 ostream&operator<<(ostream&out, const list<netrange_t>&rlist)
387 {
388       for (list<netrange_t>::const_iterator cur = rlist.begin()
389 		 ; cur != rlist.end() ; ++cur) {
390 	    out << *cur;
391       }
392       return out;
393 }
394 
operator <<(ostream & out,const vector<netrange_t> & rlist)395 ostream&operator<<(ostream&out, const vector<netrange_t>&rlist)
396 {
397       for (vector<netrange_t>::const_iterator cur = rlist.begin()
398 		 ; cur != rlist.end() ; ++cur) {
399 	    out << *cur;
400       }
401       return out;
402 }
403 
404 /* Dump a net. This can be a wire or register. */
dump_net(ostream & o,unsigned ind) const405 void NetNet::dump_net(ostream&o, unsigned ind) const
406 {
407       o << setw(ind) << "" << type() << ": " << name()
408 	<< unpacked_dims_ << " unpacked dims=" << unpacked_dimensions();
409       o << " pin_count=" << pin_count();
410       if (local_flag_)
411 	    o << " (local)";
412       switch (port_type_) {
413 	  case NetNet::NOT_A_PORT:
414 	    break;
415 	  case NetNet::PIMPLICIT:
416 	    o << " implicit-port?";
417 	    break;
418 	  case NetNet::PINPUT:
419 	    o << " input";
420 	    break;
421 	  case NetNet::POUTPUT:
422 	    o << " output";
423 	    break;
424 	  case NetNet::PINOUT:
425 	    o << " inout";
426 	    break;
427 	  case NetNet::PREF:
428 	    o <<" ref";
429 	    break;
430       }
431 
432       if (ivl_discipline_t dis = get_discipline())
433 	    o << " discipline=" << dis->name();
434 
435       if (net_type_)  o << " " << *net_type_;
436 
437       o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")";
438       if (scope())
439 	    o << " scope=" << scope_path(scope());
440       o << " #(" << rise_time() << "," << fall_time() << ","
441 	<<  decay_time() << ") vector_width=" << vector_width()
442 	<< " pin_count=" << pin_count();
443       if (pins_are_virtual()) {
444 	    o << " pins_are_virtual" << endl;
445 	    return;
446       }
447       o << endl;
448 
449       for (unsigned idx = 0 ;  idx < pin_count() ;  idx += 1) {
450 	    if (! pin(idx).is_linked())
451 		  continue;
452 
453 	    const Nexus*nex = pin(idx).nexus();
454 	    o << setw(ind+4) << "" << "[" << idx << "]: " << nex
455 	      << " " << nex->name() << endl;
456       }
457 
458       for (unsigned idx = 0 ;  idx < delay_paths_.size() ;  idx += 1) {
459 	    const NetDelaySrc*cur = delay_paths_[idx];
460 	    cur->dump(o, ind+4);
461       }
462 
463       dump_obj_attr(o, ind+4);
464 }
465 
466 /* Dump a NetNode and its pins. Dump what I know about the netnode on
467    the first line, then list all the pins, with the name of the
468    connected signal. */
dump_node(ostream & o,unsigned ind) const469 void NetNode::dump_node(ostream&o, unsigned ind) const
470 {
471       o << setw(ind) << "" << "node: ";
472       o << typeid(*this).name() << " #(" << rise_time()
473 	<< "," << fall_time() << "," << decay_time() << ") " << name()
474 	<< endl;
475 
476       dump_node_pins(o, ind+4);
477       dump_obj_attr(o, ind+4);
478 }
479 
480 /* This is the generic dumping of all the signals connected to each
481    pin of the object. The "this" object is not printed, only the
482    signals connected to this. */
dump_node_pins(ostream & o,unsigned ind,const char ** pin_names) const483 void NetPins::dump_node_pins(ostream&o, unsigned ind, const char**pin_names) const
484 {
485       for (unsigned idx = 0 ;  idx < pin_count() ;  idx += 1) {
486 	    o << setw(ind) << "" << idx;
487 	    if (pin_names && pin_names[idx])
488 		  o << " " << pin_names[idx];
489 	    else
490 		  o << " pin" << idx;
491 
492 	    switch (pin(idx).get_dir()) {
493 		case Link::PASSIVE:
494 		  o << " p";
495 		  break;
496 		case Link::INPUT:
497 		  o << " I";
498 		  break;
499 		case Link::OUTPUT:
500 		  o << " O";
501 		  break;
502 	    }
503 
504 	    o << " (" << pin(idx).drive0() << "0 "
505 	      << pin(idx).drive1() << "1): ";
506 
507 	    if (pin(idx).is_linked()) {
508 		  const Nexus*nex = pin(idx).nexus();
509 		  o << nex << " " << nex->name();
510 	    }
511 	    o << endl;
512 
513       }
514 }
515 
dump_obj_attr(ostream & o,unsigned ind) const516 void NetObj::dump_obj_attr(ostream&o, unsigned ind) const
517 {
518       unsigned idx;
519       for (idx = 0 ;  idx < attr_cnt() ;  idx += 1) {
520 	    o << setw(ind) << "" << attr_key(idx) << " = \"" <<
521 		  attr_value(idx) << "\"" << endl;
522       }
523 }
524 
dump_node(ostream & o,unsigned ind) const525 void NetAbs::dump_node(ostream&o, unsigned ind) const
526 {
527       o << setw(ind) << "" << "Absolute value (NetAbs): " << name()
528 	<< " width=" << width() << " pin_count=" << pin_count()
529 	<< endl;
530       dump_node_pins(o, ind+4);
531       dump_obj_attr(o, ind+4);
532 }
533 
dump_node(ostream & o,unsigned ind) const534 void NetAddSub::dump_node(ostream&o, unsigned ind) const
535 {
536       o << setw(ind) << "" << "Adder (NetAddSub): " << name()
537 	<< " width=" << width() << " pin_count=" << pin_count()
538 	<< endl;
539       static const char* pin_names[] = {
540 	    "Cout  ",
541 	    "DataA ",
542 	    "DataB ",
543 	    "Result"
544       };
545 
546       dump_node_pins(o, ind+4, pin_names);
547       dump_obj_attr(o, ind+4);
548 }
549 
dump_node(ostream & o,unsigned ind) const550 void NetArrayDq::dump_node(ostream&o, unsigned ind) const
551 {
552       o << setw(ind) << "" << "NetArrayDq: " << name()
553 	<< " array=" << mem_->name()
554 	<< endl;
555       dump_node_pins(o, ind+4);
556       dump_obj_attr(o, ind+4);
557 }
558 
dump_node(ostream & o,unsigned ind) const559 void NetCastInt2::dump_node(ostream&o, unsigned ind) const
560 {
561       o << setw(ind) << "" << "Cast to int2. (NetCastInt2): " <<
562 	    name() << " width=" << width() << endl;
563       dump_node_pins(o, ind+4);
564       dump_obj_attr(o, ind+4);
565 }
566 
dump_node(ostream & o,unsigned ind) const567 void NetCastInt4::dump_node(ostream&o, unsigned ind) const
568 {
569       o << setw(ind) << "" << "Cast to int4. (NetCastInt4): " <<
570 	    name() << " width=" << width() << endl;
571       dump_node_pins(o, ind+4);
572       dump_obj_attr(o, ind+4);
573 }
574 
dump_node(ostream & o,unsigned ind) const575 void NetCastReal::dump_node(ostream&o, unsigned ind) const
576 {
577       o << setw(ind) << "" << "Cast to real (NetCastReal): " <<
578 	    name() << endl;
579       dump_node_pins(o, ind+4);
580       dump_obj_attr(o, ind+4);
581 }
582 
dump_node(ostream & o,unsigned ind) const583 void NetCLShift::dump_node(ostream&o, unsigned ind) const
584 {
585       o << setw(ind) << "" << "Combinatorial shift (NetCLShift): " <<
586 	    name() << endl;
587       dump_node_pins(o, ind+4);
588       dump_obj_attr(o, ind+4);
589 }
590 
dump_node(ostream & o,unsigned ind) const591 void NetCompare::dump_node(ostream&o, unsigned ind) const
592 {
593       o << setw(ind) << "" << "LPM_COMPARE (NetCompare "
594 	<< (get_signed()? "signed" : "unsigned") << "): "
595 	<< name() << endl;
596       dump_node_pins(o, ind+4);
597       dump_obj_attr(o, ind+4);
598 }
599 
dump_node(ostream & o,unsigned ind) const600 void NetConcat::dump_node(ostream&o, unsigned ind) const
601 {
602       if (transparent_)
603 	    o << setw(ind) << "" << "NetConcat8: ";
604       else
605 	    o << setw(ind) << "" << "NetConcat: ";
606       o << name();
607 
608       if (rise_time())
609 	    o << " #(" << *rise_time()
610 	      << "," << *fall_time() << "," << *decay_time() << ")";
611       else
612 	    o << " #(0,0,0)";
613       o << " scope=" << scope_path(scope())
614 	<< " width=" << width_ << endl;
615       dump_node_pins(o, ind+4);
616       dump_obj_attr(o, ind+4);
617 }
618 
dump_node(ostream & o,unsigned ind) const619 void NetDivide::dump_node(ostream&o, unsigned ind) const
620 {
621       o << setw(ind) << "" << "NET_DIVIDE (NetDivide): " << name() << endl;
622       dump_node_pins(o, ind+4);
623       dump_obj_attr(o, ind+4);
624 }
625 
dump_node(ostream & o,unsigned ind) const626 void NetMult::dump_node(ostream&o, unsigned ind) const
627 {
628       o << setw(ind) << "" << "LPM_MULT (NetMult): " << name() << endl;
629       dump_node_pins(o, ind+4);
630       dump_obj_attr(o, ind+4);
631 }
632 
dump_node(ostream & o,unsigned ind) const633 void NetPow::dump_node(ostream&o, unsigned ind) const
634 {
635       o << setw(ind) << "" << "LPM_POW (NetPow): " << name()
636 	<< " scope=" << scope_path(scope())
637 	<< " delay=(";
638       if (rise_time())
639 	    o << *rise_time() << "," << *fall_time() << ","
640 	      <<  *decay_time();
641       else
642 	    o << "0,0,0";
643 
644       o << ")"  << endl;
645       dump_node_pins(o, ind+4);
646       dump_obj_attr(o, ind+4);
647 }
648 
dump_node(ostream & o,unsigned ind) const649 void NetMux::dump_node(ostream&o, unsigned ind) const
650 {
651       o << setw(ind) << "" << "Multiplexer (NetMux): " << name()
652 	<< " width=" << width_ << " swidth=" << swidth_ << " size=" << size_
653 	<< " scope=" << scope_path(scope()) << endl;
654       dump_node_pins(o, ind+4);
655       dump_obj_attr(o, ind+4);
656 }
657 
dump_node(ostream & o,unsigned ind) const658 void NetBUFZ::dump_node(ostream&o, unsigned ind) const
659 {
660       o << setw(ind) << "" << "NetBUFZ: " << name()
661 	<< " scope=" << scope_path(scope())
662 	<< " delay=(" << rise_time() << "," << fall_time() << "," <<
663 	    decay_time() << ") width=" << width()
664 	<< (transparent()? " " : " non-") << "transparent" << endl;
665       dump_node_pins(o, ind+4);
666 }
667 
dump_node(ostream & o,unsigned ind) const668 void NetCaseCmp::dump_node(ostream&o, unsigned ind) const
669 {
670       o << setw(ind) << "" << "case compare " << kind_ << ": " << name() << endl;
671 
672       dump_node_pins(o, ind+4);
673 }
674 
dump_node(ostream & o,unsigned ind) const675 void NetConst::dump_node(ostream&o, unsigned ind) const
676 {
677       o << setw(ind) << "" << "constant " << value_;
678       o << ": " << name();
679       if (rise_time())
680 	    o << " #(" << *rise_time()
681 	      << "," << *fall_time()
682 	      << "," << *decay_time() << ")";
683       else
684 	    o << " #(.,.,.)";
685       o << endl;
686       dump_node_pins(o, ind+4);
687 }
688 
dump_node(ostream & o,unsigned ind) const689 void NetFF::dump_node(ostream&o, unsigned ind) const
690 {
691       o << setw(ind) << "" << "LPM_FF: " << name()
692 	<< " scope=" << scope_path(scope());
693       if (negedge_)
694 	    o << " negedge";
695       else
696 	    o << " posedge";
697       o << " aset_value=" << aset_value_ << endl;
698 
699       dump_node_pins(o, ind+4);
700       dump_obj_attr(o, ind+4);
701 }
702 
dump_node(ostream & o,unsigned ind) const703 void NetLatch::dump_node(ostream&o, unsigned ind) const
704 {
705       o << setw(ind) << "" << "LPM_LATCH: " << name()
706 	<< " scope=" << scope_path(scope()) << endl;
707       dump_node_pins(o, ind+4);
708       dump_obj_attr(o, ind+4);
709 }
710 
dump_node(ostream & o,unsigned ind) const711 void NetLiteral::dump_node(ostream&o, unsigned ind) const
712 {
713       o << setw(ind) << "" << "constant real " << real_
714 	<< ": " << name();
715       if (rise_time())
716 	    o << " #(" << *rise_time()
717 	      << "," << *fall_time()
718 	      << "," << *decay_time() << ")";
719       else
720 	    o << " #(.,.,.)";
721       o << endl;
722       dump_node_pins(o, ind+4);
723 }
724 
dump_node(ostream & o,unsigned ind) const725 void NetLogic::dump_node(ostream&o, unsigned ind) const
726 {
727       o << setw(ind) << "" << "logic: ";
728       switch (type_) {
729 	  case AND:
730 	    o << "and";
731 	    break;
732 	  case BUF:
733 	    o << "buf";
734 	    break;
735 	  case BUFIF0:
736 	    o << "bufif0";
737 	    break;
738 	  case BUFIF1:
739 	    o << "bufif1";
740 	    break;
741 	  case CMOS:
742 	    o << "cmos";
743 	    break;
744 	  case EQUIV:
745 	    o << "<->";
746 	    break;
747 	  case IMPL:
748 	    o << "->";
749 	    break;
750 	  case NAND:
751 	    o << "nand";
752 	    break;
753 	  case NMOS:
754 	    o << "nmos";
755 	    break;
756 	  case NOR:
757 	    o << "nor";
758 	    break;
759 	  case NOT:
760 	    o << "not";
761 	    break;
762 	  case NOTIF0:
763 	    o << "notif0";
764 	    break;
765 	  case NOTIF1:
766 	    o << "notif1";
767 	    break;
768 	  case OR:
769 	    o << "or";
770 	    break;
771 	  case PULLDOWN:
772 	    o << "pulldown";
773 	    break;
774 	  case PULLUP:
775 	    o << "pullup";
776 	    break;
777 	  case RCMOS:
778 	    o << "rcmos";
779 	    break;
780 	  case RNMOS:
781 	    o << "rnmos";
782 	    break;
783 	  case RPMOS:
784 	    o << "rpmos";
785 	    break;
786 	  case PMOS:
787 	    o << "pmos";
788 	    break;
789 	  case XNOR:
790 	    o << "xnor";
791 	    break;
792 	  case XOR:
793 	    o << "xor";
794 	    break;
795       }
796       o << " #(" << rise_time()
797 	<< "," << fall_time() << "," << decay_time() << ") " << name()
798 	<< " scope=" << scope_path(scope())
799 	<< endl;
800 
801       dump_node_pins(o, ind+4);
802       dump_obj_attr(o, ind+4);
803 }
804 
dump_node(ostream & o,unsigned ind) const805 void NetModulo::dump_node(ostream&o, unsigned ind) const
806 {
807       o << setw(ind) << "" << "NET_MODULO (NetModulo): " << name() << endl;
808       dump_node_pins(o, ind+4);
809       dump_obj_attr(o, ind+4);
810 }
811 
dump_node(ostream & o,unsigned ind) const812 void NetPartSelect::dump_node(ostream&o, unsigned ind) const
813 {
814       const char*pt = "";
815       switch (dir_) {
816 	  case VP:
817 	    pt = "VP";
818 	    break;
819 	  case PV:
820 	    pt = "PV";
821 	    break;
822       }
823       o << setw(ind) << "" << "NetPartSelect(" << pt << "): "
824 	<< name();
825       if (rise_time())
826 	    o << " #(" << *rise_time()
827 	      << "," << *fall_time()
828 	      << "," << *decay_time() << ")";
829       else
830 	    o << " #(.,.,.)";
831       o << " off=" << off_ << " wid=" << wid_ <<endl;
832       dump_node_pins(o, ind+4);
833       dump_obj_attr(o, ind+4);
834 }
835 
dump_node(ostream & fd,unsigned ind) const836 void NetSubstitute::dump_node(ostream&fd, unsigned ind) const
837 {
838       fd << setw(ind) << "" << "NetSubstitute: "
839 	 << name();
840       if (rise_time())
841 	    fd << " #(" << *rise_time()
842 	       << "," << *fall_time()
843 	       << "," << *decay_time() << ")";
844       else
845 	    fd << " #(.,.,.)";
846       fd << " width=" << wid_ << " base=" << off_ <<endl;
847       dump_node_pins(fd, ind+4);
848       dump_obj_attr(fd, ind+4);
849 }
850 
dump_node(ostream & o,unsigned ind) const851 void NetReplicate::dump_node(ostream&o, unsigned ind) const
852 {
853       o << setw(ind) << "" << "NetReplicate: "
854 	<< name() << " wid=" << width_ << ", repeat_=" << repeat_
855 	<< ", input wid=" << width_/repeat_ << endl;
856       dump_node_pins(o, ind+4);
857       dump_obj_attr(o, ind+4);
858 }
859 
dump_node(ostream & o,unsigned ind) const860 void NetSignExtend::dump_node(ostream&o, unsigned ind) const
861 {
862       o << setw(ind) << "" << "NetSignExtend: " << name();
863       if (rise_time())
864 	    o << " #(" << *rise_time()
865 	      << "," << *fall_time()
866 	      << "," << *decay_time() << ")";
867       else
868 	    o << " #(.,.,.)";
869       o << " output width=" << width_ << endl;
870       dump_node_pins(o, ind+4);
871       dump_obj_attr(o, ind+4);
872 }
873 
dump_node(ostream & o,unsigned ind) const874 void NetUReduce::dump_node(ostream&o, unsigned ind) const
875 {
876       o << setw(ind) << "" << "reduction logic: ";
877       switch (type_) {
878 	  case NONE:
879 	    o << "NONE";
880 	    break;
881 	  case AND:
882 	    o << "and";
883 	    break;
884 	  case OR:
885 	    o << "or";
886 	    break;
887 	  case XOR:
888 	    o << "xor";
889 	    break;
890 	  case NAND:
891 	    o << "nand";
892 	    break;
893 	  case NOR:
894 	    o << "nor";
895 	    break;
896 	  case XNOR:
897 	    o << "xnor";
898 	    break;
899       }
900       o << " #(" << rise_time()
901 	<< "," << fall_time() << "," << decay_time() << ") " << name()
902 	<< " scope=" << scope_path(scope())
903 	<< endl;
904 
905       dump_node_pins(o, ind+4);
906       dump_obj_attr(o, ind+4);
907 }
908 
dump_node(ostream & o,unsigned ind) const909 void NetSysFunc::dump_node(ostream&o, unsigned ind) const
910 {
911       o << setw(ind) << "" << def_->name << "(...) -->"
912 	<< data_type() << " width=" << vector_width() << endl;
913       dump_node_pins(o, ind+4);
914       dump_obj_attr(o, ind+4);
915 }
916 
dump_node(ostream & o,unsigned ind) const917 void NetUserFunc::dump_node(ostream&o, unsigned ind) const
918 {
919       o << setw(ind) << "" << "USER FUNC: "
920 	<< scope_path(def_);
921       if (rise_time())
922 	    o << " #(" <<*rise_time()
923 	      <<","<<*fall_time()
924 	      << "," <<*decay_time() << ")";
925       o << endl;
926       dump_node_pins(o, ind+4);
927       dump_obj_attr(o, ind+4);
928 }
929 
dump(ostream & o,unsigned ind) const930 void NetTaskDef::dump(ostream&o, unsigned ind) const
931 {
932       o << setw(ind) << "" << "task " << scope_path(scope()) << ";" << endl;
933 
934       for (unsigned idx = 0 ;  idx < port_count() ;  idx += 1) {
935 	    const NetNet*pnet = port(idx);
936 	    o << setw(ind+4) << "";
937 	    assert(pnet);
938 	    switch (pnet->port_type()) {
939 		case NetNet::PINPUT:
940 		  o << "input ";
941 		  break;
942 		case NetNet::POUTPUT:
943 		  o << "output ";
944 		  break;
945 		case NetNet::PINOUT:
946 		  o << "input ";
947 		  break;
948 		default:
949 		  o << "NOT_A_PORT ";
950 		  break;
951 	    }
952 	    o << pnet->name() << ";" << endl;
953       }
954 
955       if (proc_)
956 	    proc_->dump(o, ind+4);
957       else
958 	    o << setw(ind+4) << "" << "MISSING PROCEDURAL CODE" << endl;
959 
960       o << setw(ind) << "" << "endtask" << endl;
961 }
962 
dump_node(ostream & o,unsigned ind) const963 void NetTran::dump_node(ostream&o, unsigned ind) const
964 {
965       o << setw(ind) << "" << type_ << " " << name()
966 	<< " island " << get_island();
967       if (type_ == IVL_SW_TRAN_VP) {
968 	    o << " width=" << vector_width()
969 	      << " part=" << part_width()
970 	      << " offset=" << part_offset();
971       }
972       o << " delay=(";
973       if (rise_time())
974 	    o << *rise_time() << "," << *fall_time() << ","
975 	      << *decay_time();
976       else
977 	    o << "0,0,0";
978 
979       o << ")" << endl;
980       dump_node_pins(o, ind+4);
981       dump_obj_attr(o, ind+4);
982 }
983 
dump_node(ostream & o,unsigned ind) const984 void NetUDP::dump_node(ostream&o, unsigned ind) const
985 {
986       o << setw(ind) << "" << "UDP (" << udp_name() << "): ";
987       o << " #(" << rise_time() << "," << fall_time() << "," << decay_time() <<
988 	    ") " << name() << endl;
989 
990       dump_node_pins(o, ind+4);
991       dump_obj_attr(o, ind+4);
992 }
993 
dump(ostream & o,unsigned ind) const994 void NetProcTop::dump(ostream&o, unsigned ind) const
995 {
996       switch (type_) {
997 	  case IVL_PR_INITIAL:
998 	    o << "initial  /* " << get_fileline() << " in "
999 	      << scope_path(scope_) << " */" << endl;
1000 	    break;
1001 	  case IVL_PR_ALWAYS:
1002 	    o << "always  /* " << get_fileline() << " in "
1003 	      << scope_path(scope_) << " */" << endl;
1004 	    break;
1005 	  case IVL_PR_ALWAYS_COMB:
1006 	    o << "always_comb  /* " << get_fileline() << " in "
1007 	      << scope_path(scope_) << " */" << endl;
1008 	    break;
1009 	  case IVL_PR_ALWAYS_FF:
1010 	    o << "always_ff  /* " << get_fileline() << " in "
1011 	      << scope_path(scope_) << " */" << endl;
1012 	    break;
1013 	  case IVL_PR_ALWAYS_LATCH:
1014 	    o << "always_latch  /* " << get_fileline() << " in "
1015 	      << scope_path(scope_) << " */" << endl;
1016 	    break;
1017 	  case IVL_PR_FINAL:
1018 	    o << "final  /* " << get_fileline() << " in "
1019 	      << scope_path(scope_) << " */" << endl;
1020 	    break;
1021       }
1022 
1023       for (unsigned idx = 0 ;  idx < attr_cnt() ;  idx += 1) {
1024 	    o << setw(ind+2) << "" << "(* " << attr_key(idx) << " = "
1025 	      << attr_value(idx) << " *)" << endl;
1026       }
1027 
1028       statement_->dump(o, ind+2);
1029 }
1030 
dump(ostream & o,unsigned ind) const1031 void NetAnalogTop::dump(ostream&o, unsigned ind) const
1032 {
1033       switch (type_) {
1034 	  case IVL_PR_INITIAL:
1035 	    o << "analog initial /* " << get_fileline() << " in "
1036 	      << scope_path(scope_) << " */" << endl;
1037 	    break;
1038 
1039 	  case IVL_PR_ALWAYS:
1040 	    o << "analog /* " << get_fileline() << " in "
1041 	      << scope_path(scope_) << " */" << endl;
1042 	    break;
1043 
1044 	    // These are not used in an analog context.
1045 	  case IVL_PR_ALWAYS_COMB:
1046 	  case IVL_PR_ALWAYS_FF:
1047 	  case IVL_PR_ALWAYS_LATCH:
1048 	    assert(0);
1049 	    break;
1050 
1051 	  case IVL_PR_FINAL:
1052 	    o << "analog final /* " << get_fileline() << " in "
1053 	      << scope_path(scope_) << " */" << endl;
1054 	    break;
1055       }
1056 
1057       statement_->dump(o, ind+2);
1058 }
1059 
dump(ostream & o,unsigned ind) const1060 void NetAlloc::dump(ostream&o, unsigned ind) const
1061 {
1062       o << setw(ind) << "// allocate storage : " << scope_path(scope_) << endl;
1063 }
1064 
dump_lval(ostream & o) const1065 void NetAssign_::dump_lval(ostream&o) const
1066 {
1067       if (sig_) o << sig_->name();
1068       else if (nest_) {
1069 	    o << "(";
1070 	    nest_->dump_lval(o);
1071 	    o << ")";
1072       }
1073       else o << "<?>";
1074 
1075       if (! member_.nil()) {
1076 	    o << "." << member_;
1077       }
1078       if (word_) {
1079 	    o << "[word=" << *word_ << "]";
1080       }
1081       if (base_) {
1082 	    o << "[" << *base_ << " +: " << lwid_ << "]";
1083       }
1084 }
1085 
dump_lval(ostream & o) const1086 void NetAssignBase::dump_lval(ostream&o) const
1087 {
1088       o << "{";
1089       lval_->dump_lval(o);
1090 
1091       for (NetAssign_*cur = lval_->more ;  cur ;  cur = cur->more) {
1092 	    o << ", ";
1093 	    cur->dump_lval(o);
1094       }
1095 
1096       o << "}";
1097 }
1098 
1099 /* Dump an assignment statement */
dump(ostream & o,unsigned ind) const1100 void NetAssign::dump(ostream&o, unsigned ind) const
1101 {
1102       o << setw(ind) << "";
1103       dump_lval(o);
1104 
1105       if (op_)
1106 	    o << " " << op_ << "= ";
1107       else
1108 	    o << " = ";
1109 
1110       if (const NetExpr*de = get_delay())
1111 	    o << "#(" << *de << ") ";
1112 
1113       o << *rval() << ";" << endl;
1114 }
1115 
dump(ostream & o,unsigned ind) const1116 void NetAssignNB::dump(ostream&o, unsigned ind) const
1117 {
1118       o << setw(ind) << "";
1119       dump_lval(o);
1120 
1121       o << " <= ";
1122 
1123       if (const NetExpr*de = get_delay())
1124 	    o << "#(" << *de << ") ";
1125       if (count_)
1126 	    o << "repeat(" << *count_ << ") ";
1127       if (event_) {
1128 	    o << *event_;
1129       }
1130 
1131       o << *rval() << ";" << endl;
1132 
1133 }
1134 
dump(ostream & o,unsigned ind) const1135 void NetAssignBase::dump(ostream&o, unsigned ind) const
1136 {
1137       if (const NetAssignNB *n1 = dynamic_cast<const NetAssignNB*>(this)) {
1138 	    n1->dump(o,ind);
1139       } else if (const NetAssign *n2 = dynamic_cast<const NetAssign*>(this)) {
1140 	    n2->dump(o,ind);
1141       }
1142 }
1143 
1144 /* Dump a block statement */
dump(ostream & o,unsigned ind) const1145 void NetBlock::dump(ostream&o, unsigned ind) const
1146 {
1147       o << setw(ind) << "" << type_;
1148       if (subscope_)
1149 	    o << " : " << scope_path(subscope_);
1150       o << endl;
1151 
1152       if (last_) {
1153 	    const NetProc*cur = last_;
1154 	    do {
1155 		  cur = cur->next_;
1156 		  cur->dump(o, ind+4);
1157 	    } while (cur != last_);
1158       }
1159 
1160       o << setw(ind) << "" << "end" << endl;
1161 }
1162 
dump(ostream & o,unsigned ind) const1163 void NetCase::dump(ostream&o, unsigned ind) const
1164 {
1165       o << setw(ind) << "";
1166       switch (quality_) {
1167 	  case IVL_CASE_QUALITY_BASIC:
1168 	    break;
1169 	  case IVL_CASE_QUALITY_UNIQUE:
1170 	    o << "unique ";
1171 	    break;
1172 	  case IVL_CASE_QUALITY_UNIQUE0:
1173 	    o << "unique0 ";
1174 	    break;
1175 	  case IVL_CASE_QUALITY_PRIORITY:
1176 	    o << "priority ";
1177 	    break;
1178       }
1179       switch (type_) {
1180 	  case EQ:
1181 	    o << "case (" << *expr_ << ")" << endl;
1182 	    break;
1183 	  case EQX:
1184 	    o << "casex (" << *expr_ << ")" << endl;
1185 	    break;
1186 	  case EQZ:
1187 	    o << "casez (" << *expr_ << ")" << endl;
1188 	    break;
1189       }
1190 
1191       for (unsigned idx = 0 ;  idx < items_.size() ;  idx += 1) {
1192 	    o << setw(ind+2) << "";
1193 	    if (items_[idx].guard)
1194 		  o << *items_[idx].guard << ":";
1195 	    else
1196 		  o << "default:";
1197 
1198 	    if (items_[idx].statement) {
1199 		  o << endl;
1200 		  items_[idx].statement->dump(o, ind+6);
1201 	    } else {
1202 		  o << " ;" << endl;
1203 	    }
1204       }
1205 
1206       o << setw(ind) << "" << "endcase" << endl;
1207 }
1208 
dump(ostream & o,unsigned ind) const1209 void NetCAssign::dump(ostream&o, unsigned ind) const
1210 {
1211       o << setw(ind) << "" << "cassign ";
1212       dump_lval(o);
1213       o << " = " << *rval() << "; /* " << get_fileline() << " */" << endl;
1214 }
1215 
dump(ostream & o,unsigned ind) const1216 void NetCondit::dump(ostream&o, unsigned ind) const
1217 {
1218       o << setw(ind) << "" << "if (";
1219       expr_->dump(o);
1220       o << ")" << endl;
1221 
1222       if (if_) if_->dump(o, ind+4);
1223       else o << setw(ind+4) << "" << "/* empty */ ;" << endl;
1224 
1225       if (else_) {
1226 	    o << setw(ind) << "" << "else" << endl;
1227 	    else_->dump(o, ind+4);
1228       }
1229 }
1230 
dump(ostream & o,unsigned ind) const1231 void NetContribution::dump(ostream&o, unsigned ind) const
1232 {
1233       o << setw(ind) << "";
1234       lval_->dump(o);
1235       o << " <+ ";
1236       rval_->dump(o);
1237       o << ";" << endl;
1238 }
1239 
dump(ostream & o,unsigned ind) const1240 void NetDeassign::dump(ostream&o, unsigned ind) const
1241 {
1242       o << setw(ind) << "" << "deassign ";
1243       dump_lval(o);
1244       o << "; /* " << get_fileline() << " */" << endl;
1245 }
1246 
dump(ostream & o,unsigned ind) const1247 void NetDisable::dump(ostream&o, unsigned ind) const
1248 {
1249       o << setw(ind) << "" << "disable ";
1250       if (target_) o << scope_path(target_);
1251       else o << "fork";
1252       o << "; " << "/* " << get_fileline() << " */" << endl;
1253 }
1254 
dump(ostream & o,unsigned ind) const1255 void NetDoWhile::dump(ostream&o, unsigned ind) const
1256 {
1257       o << setw(ind) << "" << "do" << endl;
1258       proc_->dump(o, ind+3);
1259       o << setw(ind) << "" << "while (" << *cond_ << ");" << endl;
1260 }
1261 
dump_node(ostream & o,unsigned ind) const1262 void NetEvProbe::dump_node(ostream&o, unsigned ind) const
1263 {
1264       o << setw(ind) << "";
1265 
1266       switch (edge_) {
1267 	  case ANYEDGE:
1268 	    o << "anyedge ";
1269 	    break;
1270 	  case POSEDGE:
1271 	    o << "posedge ";
1272 	    break;
1273 	  case NEGEDGE:
1274 	    o << "negedge ";
1275 	    break;
1276       }
1277       o << setw(ind) << "" << "-> " << event_->name() << "; " << endl;
1278       dump_node_pins(o, ind+4);
1279       dump_obj_attr(o, ind+4);
1280 }
1281 
dump(ostream & o,unsigned ind) const1282 void NetEvTrig::dump(ostream&o, unsigned ind) const
1283 {
1284       o << setw(ind) << "" << "-> " << event_->name() << "; "
1285 	<< "// " << get_fileline() << endl;
1286 }
1287 
dump(ostream & o,unsigned ind) const1288 void NetEvWait::dump(ostream&o, unsigned ind) const
1289 {
1290       o << setw(ind) << "";
1291 
1292 	/* Check for a wait fork. */
1293       if ((nevents() == 1) && (event(0) == 0)) {
1294 	    o << "wait fork;";
1295 	    return;
1296       }
1297 
1298       o << "@(";
1299 
1300       if (nevents() > 0)
1301 	    o << event(0)->name();
1302 
1303       for (unsigned idx = 1 ;  idx < nevents() ;  idx += 1)
1304 	    o << " or " << event(idx)->name();
1305 
1306       o << ")  // " << get_fileline() << endl;
1307 
1308       if (statement_)
1309 	    statement_->dump(o, ind+2);
1310       else
1311 	    o << setw(ind+2) << "" << "/* noop */ ;" << endl;
1312 }
1313 
operator <<(ostream & out,const NetEvWait & obj)1314 ostream& operator << (ostream&out, const NetEvWait&obj)
1315 {
1316       obj.dump_inline(out);
1317       return out;
1318 }
1319 
dump_inline(ostream & o) const1320 void NetEvWait::dump_inline(ostream&o) const
1321 {
1322 	/* Check for a wait fork. */
1323       if ((nevents() == 1) && (event(0) == 0)) {
1324 	    o << "wait fork;";
1325 	    return;
1326       }
1327 
1328       o << "@(";
1329 
1330       if (nevents() > 0)
1331 	    o << event(0)->name();
1332 
1333       for (unsigned idx = 1 ;  idx < nevents() ;  idx += 1)
1334 	    o << " or " << event(idx)->name();
1335 
1336       o << ") ";
1337 }
1338 
dump(ostream & o,unsigned ind) const1339 void NetForce::dump(ostream&o, unsigned ind) const
1340 {
1341       o << setw(ind) << "" << "force ";
1342       dump_lval(o);
1343       o << " = " << *rval() << "; /* " << get_fileline() << " */" << endl;
1344 }
1345 
dump(ostream & o,unsigned ind) const1346 void NetForever::dump(ostream&o, unsigned ind) const
1347 {
1348       o << setw(ind) << "" << "forever" << endl;
1349       statement_->dump(o, ind+2);
1350 }
1351 
dump(ostream & fd,unsigned ind) const1352 void NetForLoop::dump(ostream&fd, unsigned ind) const
1353 {
1354       fd << setw(ind) << "" << "FOR LOOP index=" << index_->name() << endl;
1355       statement_->dump(fd, ind+4);
1356       step_statement_->dump(fd, ind+4);
1357 }
1358 
dump(ostream & o,unsigned ind) const1359 void NetFree::dump(ostream&o, unsigned ind) const
1360 {
1361       o << setw(ind) << "// free storage : " << scope_path(scope_) << endl;
1362 }
1363 
dump(ostream & o,unsigned ind) const1364 void NetFuncDef::dump(ostream&o, unsigned ind) const
1365 {
1366       o << setw(ind) << "" << "function definition for " << scope_path(scope()) << endl;
1367       if (result_sig_) {
1368 	    o << setw(ind+2) << "" << "Return signal: ";
1369 	    if (result_sig_->get_signed()) o << "+";
1370 	    o << result_sig_->name() << endl;
1371       }
1372       o << setw(ind+2) << "" << "Arguments: ";
1373       if (port_count() == 0) o << "<none>";
1374       o << endl;
1375       for (unsigned idx = 0; idx < port_count(); idx += 1) {
1376 	    o << setw(ind+4) << "" << "Arg[" << idx+1 << "] = ";
1377 	    switch (port(idx)->port_type()) {
1378 		default:
1379 		  o << "implicit-port? ";
1380 		  break;
1381 		case NetNet::PINPUT:
1382 		  o << "input ";
1383 		  break;
1384 		case NetNet::POUTPUT:
1385 		  o << "output ";
1386 		  break;
1387 		case NetNet::PINOUT:
1388 		  o << "inout ";
1389 		  break;
1390 	    }
1391 	    if (port(idx)->get_signed()) o << "+";
1392 	    o << port(idx)->name() << endl;
1393       }
1394       if (proc_)
1395 	    proc_->dump(o, ind+2);
1396       else
1397 	    o << setw(ind+2) << "" << "MISSING PROCEDURAL CODE" << endl;
1398 }
1399 
dump(ostream & o,unsigned ind) const1400 void NetPDelay::dump(ostream&o, unsigned ind) const
1401 {
1402       if (expr_) {
1403 	    o << setw(ind) << "" << "#" << *expr_;
1404 
1405       } else {
1406 	    o << setw(ind) << "" << "#" << delay_;
1407       }
1408 
1409       if (statement_) {
1410 	    o << endl;
1411 	    statement_->dump(o, ind+2);
1412       } else {
1413 	    o << " /* noop */;" << endl;
1414       }
1415 }
1416 
dump(ostream & o,unsigned ind) const1417 void NetRelease::dump(ostream&o, unsigned ind) const
1418 {
1419       o << setw(ind) << "" << "release ";
1420       dump_lval(o);
1421       o << "; /* " << get_fileline() << " */" << endl;
1422 }
1423 
dump(ostream & o,unsigned ind) const1424 void NetRepeat::dump(ostream&o, unsigned ind) const
1425 {
1426       o << setw(ind) << "" << "repeat (" << *expr_ << ")" << endl;
1427       statement_->dump(o, ind+2);
1428 }
1429 
dump_scope(ostream & fd) const1430 void netclass_t::dump_scope(ostream&fd) const
1431 {
1432       class_scope_->dump(fd);
1433 }
1434 
dump(ostream & o) const1435 void NetScope::dump(ostream&o) const
1436 {
1437 	/* This is a constructed hierarchical name. */
1438       o << scope_path(this) << " ";
1439 
1440       print_type(o);
1441       if (is_auto()) o << " (automatic)";
1442       if (is_cell()) o << " (cell)";
1443       if (nested_module()) o << " (nested)";
1444       if (program_block()) o << " (program)";
1445       if (is_interface()) o << " (interface)";
1446       o << " " << children_.size() << " children, "
1447 	<< classes_.size() << " classes" << endl;
1448       if (unit() && !is_unit())
1449 	    o << "    in compilation unit " << unit()->basename() << endl;
1450 
1451       for (unsigned idx = 0 ;  idx < attr_cnt() ;  idx += 1)
1452 	    o << "    (* " << attr_key(idx) << " = "
1453 	      << attr_value(idx) << " *)" << endl;
1454 
1455       o << "    timescale = 10e" << time_unit() << " / 10e"
1456 	<< time_precision() << endl;
1457 
1458 	/* Dump the parameters for this scope. */
1459       {
1460 	    map<perm_string,param_expr_t>::const_iterator pp;
1461 	    for (pp = parameters.begin()
1462 		       ; pp != parameters.end() ;  ++ pp ) {
1463 		  if ((*pp).second.is_annotatable)
1464 			o << "    specparam ";
1465 		  else
1466 			o << "    parameter ";
1467 
1468 		  o << pp->second.type << " ";
1469 
1470 		  if ((*pp).second.signed_flag)
1471 			o << "signed ";
1472 
1473 		  if ((*pp).second.msb)
1474 			o << "[" << *(*pp).second.msb
1475 			  << ":" << *(*pp).second.lsb << "] ";
1476 
1477 		  o << (*pp).first << " = ";
1478 		  if (pp->second.val)
1479 			o << *(*pp).second.val;
1480 		  else
1481 			o << "<nil>";
1482 
1483 		  for (range_t*ran = (*pp).second.range ; ran ; ran = ran->next) {
1484 			if (ran->exclude_flag)
1485 			      o << " exclude ";
1486 			else
1487 			      o << " from ";
1488 
1489 			if (ran->low_open_flag)
1490 			      o << "(";
1491 			else
1492 			      o << "[";
1493 			if (ran->low_expr)
1494 			      o << *ran->low_expr;
1495 			else if (ran->low_open_flag==false)
1496 			      o << "-inf";
1497 			else
1498 			      o << "<?>";
1499 			if (ran->high_expr)
1500 			      o << ":" << *ran->high_expr;
1501 			else if (ran->high_open_flag==false)
1502 			      o << ":inf";
1503 			else
1504 			      o << ":<?>";
1505 			if (ran->high_open_flag)
1506 			      o << ")";
1507 			else
1508 			      o << "]";
1509 		  }
1510 
1511 		  o << ";" << endl;
1512 	    }
1513       }
1514 
1515 	/* Dump the saved defparam assignments here. */
1516       {
1517 	    list<pair<pform_name_t,PExpr*> >::const_iterator pp;
1518 	    for (pp = defparams.begin()
1519 		       ; pp != defparams.end() ;  ++ pp ) {
1520 		  o << "    defparam " << (*pp).first << " = " <<
1521 			*(*pp).second << ";" << endl;
1522 	    }
1523       }
1524 
1525       {
1526 	    list<pair<list<hname_t>,PExpr*> >::const_iterator pp;
1527 	    for (pp = defparams_later.begin()
1528 		       ; pp != defparams_later.end() ;  ++ pp ) {
1529 		  o << "    defparam(later) " << pp->first << " = " <<
1530 			*(pp->second) << ";" << endl;
1531 	    }
1532       }
1533 
1534       o << "    enum sets {" << endl;
1535 
1536 	/* Dump the enumerations and enum names in this scope. */
1537       for (map<const enum_type_t*,netenum_t*>::const_iterator cur = enum_sets_.begin()
1538 		 ; cur != enum_sets_.end() ; ++ cur) {
1539 	    o << "      " << cur->second << endl;
1540       }
1541       o << "    }" << endl;
1542 
1543       o << "    enum names {" << endl;
1544       for (map<perm_string,NetEConstEnum*>::const_iterator cur = enum_names_.begin()
1545 		 ; cur != enum_names_.end() ; ++ cur) {
1546 	    o << "      " << cur->first << " = " << cur->second->value()
1547 	      << " from " << cur->second->enumeration() << endl;
1548       }
1549       o << "    }" << endl;
1550 
1551 	/* Dump the events in this scope. */
1552       for (NetEvent*cur = events_ ;  cur ;  cur = cur->snext_) {
1553 	    o << "    event " << cur->name() << "; nprobe="
1554 	      << cur->nprobe() << " scope=" << scope_path(cur->scope())
1555 	      << " // " << cur->get_fileline() << endl;
1556       }
1557 
1558 	// Dump the signals,
1559       for (signals_map_iter_t cur = signals_map_.begin()
1560 		 ; cur != signals_map_.end() ; ++ cur) {
1561 	    cur->second->dump_net(o, 4);
1562       }
1563 
1564       switch (type_) {
1565 	  case FUNC:
1566 	    if (func_def())
1567 		  func_def()->dump(o, 4);
1568 	    else
1569 		  o << "    MISSING FUNCTION DEFINITION" << endl;
1570 	    break;
1571 	  case TASK:
1572 	    if (task_def())
1573 		  task_def()->dump(o, 4);
1574 	    else
1575 		  o << "    MISSING TASK DEFINITION" << endl;
1576 	    break;
1577 	  default:
1578 	    break;
1579       }
1580 
1581 	/* Dump any sub-scopes. */
1582       for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
1583 		 ; cur != children_.end() ; ++ cur )
1584 	    cur->second->dump(o);
1585 
1586       for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
1587 		 ; cur != classes_.end() ; ++ cur ) {
1588 	    cur->second->dump_scope(o);
1589       }
1590 }
1591 
dump(ostream & o,unsigned ind) const1592 void NetSTask::dump(ostream&o, unsigned ind) const
1593 {
1594       o << setw(ind) << "" << name_;
1595 
1596       if (! parms_.empty()) {
1597 	    o << "(";
1598 	    if (parms_[0])
1599 		  parms_[0]->dump(o);
1600 
1601 	    for (unsigned idx = 1 ;  idx < parms_.size() ;  idx += 1) {
1602 		  o << ", ";
1603 		  if (parms_[idx])
1604 			parms_[idx]->dump(o);
1605 	    }
1606 
1607 	    o << ")";
1608       }
1609       o << ";" << endl;
1610 }
1611 
dump(ostream & o,unsigned ind) const1612 void NetUTask::dump(ostream&o, unsigned ind) const
1613 {
1614       o << setw(ind) << "" << scope_path(task_) << ";" << endl;
1615 }
1616 
dump(ostream & o,unsigned ind) const1617 void NetWhile::dump(ostream&o, unsigned ind) const
1618 {
1619       o << setw(ind) << "" << "while (" << *cond_ << ")" << endl;
1620       proc_->dump(o, ind+3);
1621 }
1622 
1623 /* Dump a statement type that someone didn't write a dump for. */
dump(ostream & o,unsigned ind) const1624 void NetProc::dump(ostream&o, unsigned ind) const
1625 {
1626       o << setw(ind) << "" << "// " << typeid(*this).name() << endl;
1627 }
1628 
1629 /* Dump an expression that no one wrote a dump method for. */
dump(ostream & o) const1630 void NetExpr::dump(ostream&o) const
1631 {
1632       o << "(?" << typeid(*this).name() << "?)";
1633 }
1634 
dump(ostream & o) const1635 void NetEAccess::dump(ostream&o) const
1636 {
1637       o << nature_->name() << "." << nature_->access() << "(";
1638       assert(branch_);
1639       if (branch_->pin(0).is_linked())
1640 	    o << branch_->pin(0).nexus()->name();
1641       o << ", ";
1642       if (branch_->pin(1).is_linked())
1643 	    o << branch_->pin(1).nexus()->name();
1644       o << ")";
1645 }
1646 
dump(ostream & fd) const1647 void NetEArrayPattern::dump(ostream&fd) const
1648 {
1649       fd << "'{";
1650       if (items_.size() >= 1) {
1651 	    if (items_[0]) fd << *items_[0];
1652       }
1653       for (size_t idx = 1 ; idx < items_.size() ; idx += 1) {
1654 	    fd << ", ";
1655 	    if (items_[idx]) fd << *items_[idx];
1656       }
1657       fd << "}";
1658 }
1659 
dump(ostream & o) const1660 void NetEBinary::dump(ostream&o) const
1661 {
1662       if (op_ == 'm' || op_ == 'M') {
1663 	    if (op_ == 'm')
1664 		  o << "min";
1665 	    else
1666 		  o << "max";
1667 
1668 	    o << "(";
1669 	    left_->dump(o);
1670 	    o << ", ";
1671 	    right_->dump(o);
1672 	    o << ")";
1673 	    return;
1674       }
1675 
1676       o << "(";
1677       left_->dump(o);
1678       o << ")";
1679       switch (op_) {
1680 	  default:
1681 	    o << op_;
1682 	    break;
1683 	  case 'a':
1684 	    o << "&&";
1685 	    break;
1686 	  case 'A':
1687 	    o << "~&";
1688 	    break;
1689 	  case 'e':
1690 	    o << "==";
1691 	    break;
1692 	  case 'E':
1693 	    o << "===";
1694 	    break;
1695 	  case 'w':
1696 	    o << "==?";
1697 	    break;
1698 	  case 'G':
1699 	    o << ">=";
1700 	    break;
1701 	  case 'l':
1702 	    o << "<<";
1703 	    break;
1704 	  case 'L':
1705 	    o << "<=";
1706 	    break;
1707 	  case 'n':
1708 	    o << "!=";
1709 	    break;
1710 	  case 'N':
1711 	    o << "!==";
1712 	    break;
1713 	  case 'W':
1714 	    o << "!=?";
1715 	    break;
1716 	  case 'o':
1717 	    o << "||";
1718 	    break;
1719 	  case 'O':
1720 	    o << "~|";
1721 	    break;
1722 	  case 'p':
1723 	    o << "**";
1724 	    break;
1725 	  case 'q':
1726 	    o << "->";
1727 	    break;
1728 	  case 'Q':
1729 	    o << "<->";
1730 	    break;
1731 	  case 'r':
1732 	    o << ">>";
1733 	    break;
1734 	  case 'R':
1735 	    o << ">>>";
1736 	    break;
1737 	  case 'X':
1738 	    o << "~^";
1739 	    break;
1740       }
1741       o << "(";
1742       right_->dump(o);
1743       o << ")";
1744 }
1745 
dump(ostream & fd) const1746 void NetECast::dump(ostream&fd) const
1747 {
1748       if (op_=='2')
1749 	    fd << "bool<" << expr_width() << ">(" << *expr_ << ")";
1750       else if (op_=='v')
1751 	    fd << "logic<" << expr_width() << ">(" << *expr_ << ")";
1752       else
1753 	    NetEUnary::dump(fd);
1754 }
1755 
dump(ostream & o) const1756 void NetEConcat::dump(ostream&o) const
1757 {
1758       if (repeat_ != 1)
1759             o << repeat_;
1760 
1761       if (parms_[0])
1762 	    o << "{" << *parms_[0];
1763       else
1764 	    o << "{";
1765 
1766       for (unsigned idx = 1 ;  idx < parms_.size() ;  idx += 1) {
1767 	    if (parms_[idx])
1768 		  o << ", " << *parms_[idx];
1769 	    else
1770 		  o << ", ";
1771       }
1772       o << "}";
1773 }
1774 
dump(ostream & o) const1775 void NetEConst::dump(ostream&o) const
1776 {
1777       if (value_.is_string())
1778 	    o << "\"" << value_.as_string() << "\"";
1779       else
1780 	    o << value_;
1781 }
1782 
dump(ostream & o) const1783 void NetEConstEnum::dump(ostream&o) const
1784 {
1785       o << "<" << name_ << "=";
1786       NetEConst::dump(o);
1787       o << ", wid=" << expr_width() << ">";
1788 }
1789 
dump(ostream & o) const1790 void NetEConstParam::dump(ostream&o) const
1791 {
1792       o << "<" << name_ << "=";
1793       NetEConst::dump(o);
1794       o << ", wid=" << expr_width() << ">";
1795 }
1796 
dump(ostream & o) const1797 void NetECReal::dump(ostream&o) const
1798 {
1799       o << value_;
1800 }
1801 
dump(ostream & o) const1802 void NetECRealParam::dump(ostream&o) const
1803 {
1804       o << "<" << name_ << "=";
1805       NetECReal::dump(o);
1806       o << ">";
1807 }
1808 
dump(ostream & o) const1809 void NetEEvent::dump(ostream&o) const
1810 {
1811       o << "<event=" << event_->name() << ">";
1812 }
1813 
dump(ostream & fd) const1814 void NetELast::dump(ostream&fd) const
1815 {
1816       fd << "<last of " << sig_->name() << ">";
1817 }
1818 
dump(ostream & o) const1819 void NetENetenum::dump(ostream&o) const
1820 {
1821       o << "<netenum=" << netenum_ << ">";
1822 }
1823 
dump(ostream & o) const1824 void NetENew::dump(ostream&o) const
1825 {
1826       o << "new <type> [";
1827       if (size_) size_->dump(o);
1828       o << "]";
1829       if (init_val_) {
1830 	    o << "(";
1831 	    init_val_->dump(o);
1832 	    o << ")";
1833       }
1834 }
1835 
dump(ostream & o) const1836 void NetENull::dump(ostream&o) const
1837 {
1838       o << "<null>";
1839 }
1840 
dump(ostream & o) const1841 void NetEProperty::dump(ostream&o) const
1842 {
1843       o << net_->name() << ".<" << pidx_ << ">";
1844       if (index_)
1845 	    o << "[" << *index_ << "]";
1846 }
1847 
dump(ostream & o) const1848 void NetEScope::dump(ostream&o) const
1849 {
1850       o << "<scope=" << scope_path(scope_) << ">";
1851 }
1852 
dump(ostream & o) const1853 void NetESelect::dump(ostream&o) const
1854 {
1855       o << "<select";
1856       if (has_sign())
1857 	    o << "+=";
1858       else
1859 	    o << "=";
1860 
1861       expr_->dump(o);
1862       o << "[";
1863 
1864       if (base_)
1865 	    base_->dump(o);
1866       else
1867 	    o << "(0)";
1868 
1869       o << "+:" << expr_width() << "]";
1870       if (ivl_type_t nt = net_type()) {
1871 	    o << " net_type=(" << *nt << ")";
1872       } else {
1873 	    o << " expr_type=" << expr_type();
1874       }
1875 
1876       o << ">";
1877 }
1878 
dump(ostream & o) const1879 void NetESFunc::dump(ostream&o) const
1880 {
1881       o << name_ << "(";
1882       if (nparms() > 0)
1883 	    o << *parm(0);
1884       for (unsigned idx = 1 ;  idx < nparms() ;  idx += 1)
1885 	    o << ", " << *parm(idx);
1886       o << ")";
1887 }
1888 
dump(ostream & o) const1889 void NetEShallowCopy::dump(ostream&o) const
1890 {
1891       o << "<ShallowCopy, " << *arg1_ << " <-- " << *arg2_ << ">";
1892 }
1893 
dump(ostream & o) const1894 void NetESignal::dump(ostream&o) const
1895 {
1896       if (has_sign())
1897 	    o << "+";
1898       o << name();
1899       if (word_) o << "[word=" << *word_ << "]";
1900       vector<netrange_t>tmp = net_->net_type()->slice_dimensions();
1901       o << tmp;
1902 }
1903 
dump(ostream & o) const1904 void NetETernary::dump(ostream&o) const
1905 {
1906       o << "(" << *cond_ << ") ? (" << *true_val_ << ") : (" <<
1907 	    *false_val_ << ")";
1908 }
1909 
dump(ostream & o) const1910 void NetEUFunc::dump(ostream&o) const
1911 {
1912       o << scope_path(func_) << "(";
1913       if (! parms_.empty()) {
1914 	    parms_[0]->dump(o);
1915 	    for (unsigned idx = 1 ;  idx < parms_.size() ;  idx += 1) {
1916 		  o << ", ";
1917 		  parms_[idx]->dump(o);
1918 	    }
1919       }
1920       o << ")";
1921 }
1922 
dump(ostream & o) const1923 void NetEUnary::dump(ostream&o) const
1924 {
1925       switch (op_) {
1926 	  case 'A':
1927 	    o << "~&";
1928 	    break;
1929 	  case 'm':
1930 	    o << "abs";
1931 	    break;
1932 	  case 'N':
1933 	    o << "~|";
1934 	    break;
1935 	  case 'X':
1936 	    o << "~^";
1937 	    break;
1938           case 'I':
1939 	    o << "++";
1940 	    break;
1941           case 'D':
1942 	    o << "--";
1943 	    break;
1944           case 'i':
1945           case 'd':
1946 	    break;
1947 	  default:
1948 	    o << op_;
1949 	    break;
1950       }
1951       o << "(";
1952       expr_->dump(o);
1953       o << ")";
1954       switch (op_) {
1955           case 'i':
1956 	    o << "++";
1957 	    break;
1958           case 'd':
1959 	    o << "--";
1960 	    break;
1961       }
1962 }
1963 
dump(ostream & o) const1964 void Design::dump(ostream&o) const
1965 {
1966       o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl;
1967 
1968       o << "PACKAGES:" << endl;
1969       for (map<perm_string,NetScope*>::const_iterator cur = packages_.begin()
1970 		 ; cur != packages_.end() ; ++cur) {
1971 	    cur->second->dump(o);
1972       }
1973 
1974       o << "SCOPES:" << endl;
1975       for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
1976 	   scope != root_scopes_.end(); ++ scope ) {
1977 	    (*scope)->dump(o);
1978       }
1979 
1980       o << "ELABORATED NODES:" << endl;
1981 
1982 	// dump the nodes,
1983       if (nodes_) {
1984 	    NetNode*cur = nodes_->node_next_;
1985 	    do {
1986 		  assert(cur);
1987 		  cur->dump_node(o, 0);
1988 		  cur = cur->node_next_;
1989 	    } while (cur != nodes_->node_next_);
1990       }
1991 
1992       o << "ELABORATED BRANCHES:" << endl;
1993 
1994       if (branches_) {
1995 	    for (NetBranch*cur = branches_ ; cur ; cur = cur->next_)
1996 		  cur->dump(o, 0);
1997       }
1998 
1999       o << "ELABORATED PROCESSES:" << endl;
2000 
2001 	// Dump the processes.
2002       for (const NetProcTop*idx = procs_ ;  idx ;  idx = idx->next_)
2003 	    idx->dump(o, 0);
2004 
2005       for (const NetAnalogTop*idx = aprocs_ ; idx ; idx = idx->next_)
2006 	    idx->dump(o, 0);
2007 }
2008