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