Support for wide modulus operations.
[iverilog.git] / design_dump.cc
blob34551f4d2dfac8430a63a889ee831435c31929ea
1 /*
2 * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
8 * any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 #ifdef HAVE_CVS_IDENT
20 #ident "$Id: design_dump.cc,v 1.176 2007/06/02 03:42:12 steve Exp $"
21 #endif
23 # include "config.h"
26 * This file contains all the dump methods of the netlist classes.
28 # include <typeinfo>
29 # include <iostream>
30 # include <iomanip>
31 # include "netlist.h"
32 # include "compiler.h"
33 # include "ivl_assert.h"
35 static ostream& operator<< (ostream&o, NetBlock::Type t)
37 switch (t) {
38 case NetBlock::SEQU:
39 o << "begin";
40 break;
41 case NetBlock::PARA:
42 o << "fork";
43 break;
45 return o;
48 ostream& operator << (ostream&o, Link::strength_t str)
50 switch (str) {
51 case Link::HIGHZ:
52 o << "highz";
53 break;
54 case Link::WEAK:
55 o << "weak";
56 break;
57 case Link::PULL:
58 o << "pull";
59 break;
60 case Link::STRONG:
61 o << "strong";
62 break;
63 case Link::SUPPLY:
64 o << "supply";
65 break;
66 default:
67 assert(0);
69 return o;
72 ostream& operator << (ostream&o, ivl_variable_type_t val)
74 switch (val) {
75 case IVL_VT_VOID:
76 o << "void";
77 break;
78 case IVL_VT_NO_TYPE:
79 o << "<no_type>";
80 break;
81 case IVL_VT_REAL:
82 o << "real";
83 break;
84 case IVL_VT_BOOL:
85 o << "bool";
86 break;
87 case IVL_VT_LOGIC:
88 o << "logic";
89 break;
91 return o;
94 static inline void dump_scope_path(ostream&o, const NetScope*scope)
96 if (const NetScope*parent = scope->parent()) {
97 dump_scope_path(o, parent);
98 o << ".";
100 const hname_t name = scope->fullname();
101 o << name.peek_name();
102 if (name.has_number())
103 o << "[" << name.peek_number() << "]";
106 ostream& operator <<(ostream&o, struct __ScopePathManip marg)
108 if (marg.scope != 0)
109 dump_scope_path(o, marg.scope);
110 return o;
113 void NetDelaySrc::dump(ostream&o, unsigned ind) const
115 o << setw(ind) << "" << "specify delay";
116 if (posedge_) o << " posedge";
117 if (negedge_) o << " negedge";
118 o << " src "
119 << "(" << transition_delays_[IVL_PE_01]
120 << "," << transition_delays_[IVL_PE_10]
121 << "," << transition_delays_[IVL_PE_0z]
122 << "/" << transition_delays_[IVL_PE_z1]
123 << "," << transition_delays_[IVL_PE_1z]
124 << "," << transition_delays_[IVL_PE_z0]
125 << "/" << transition_delays_[IVL_PE_0x]
126 << "," << transition_delays_[IVL_PE_x1]
127 << "," << transition_delays_[IVL_PE_1x]
128 << "/" << transition_delays_[IVL_PE_x0]
129 << "," << transition_delays_[IVL_PE_xz]
130 << "," << transition_delays_[IVL_PE_zx]
131 << "): " << endl;
132 dump_node_pins(o, ind+4);
135 /* Dump a net. This can be a wire or register. */
136 void NetNet::dump_net(ostream&o, unsigned ind) const
138 o << setw(ind) << "" << type() << ": " << name()
139 << "[" << s0_ << ":" << e0_ << " count=" << pin_count() << "]";
140 if (local_flag_)
141 o << " (local)";
142 o << " " << data_type_;
143 if (signed_)
144 o << " signed";
145 switch (port_type_) {
146 case NetNet::NOT_A_PORT:
147 break;
148 case NetNet::PIMPLICIT:
149 o << " implicit-port?";
150 break;
151 case NetNet::PINPUT:
152 o << " input";
153 break;
154 case NetNet::POUTPUT:
155 o << " output";
156 break;
157 case NetNet::PINOUT:
158 o << " inout";
159 break;
161 o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")";
162 if (scope())
163 o << " scope=" << scope_path(scope());
164 o << " #(" << rise_time() << "," << fall_time() << ","
165 << decay_time() << ") vector_width=" << vector_width()
166 << " pin_count=" << pin_count()
167 << " init=";
168 for (unsigned idx = pin_count() ; idx > 0 ; idx -= 1)
169 o << pin(idx-1).get_init();
171 o << " (";
172 for (unsigned idx = pin_count() ; idx > 0 ; idx -= 1)
173 o << pin(idx-1).nexus()->get_init();
174 o << ")" << endl;
176 for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
177 if (! pin(idx).is_linked())
178 continue;
180 const Nexus*nex = pin(idx).nexus();
181 o << setw(ind+4) << "" << "[" << idx << "]: " << nex
182 << " " << nex->name() << endl;
185 for (unsigned idx = 0 ; idx < delay_paths_.size() ; idx += 1) {
186 const NetDelaySrc*cur = delay_paths_[idx];
187 cur->dump(o, ind+4);
190 dump_obj_attr(o, ind+4);
193 /* Dump a NetNode and its pins. Dump what I know about the netnode on
194 the first line, then list all the pins, with the name of the
195 connected signal. */
196 void NetNode::dump_node(ostream&o, unsigned ind) const
198 o << setw(ind) << "" << "node: ";
199 o << typeid(*this).name() << " #(" << rise_time()
200 << "," << fall_time() << "," << decay_time() << ") " << name()
201 << endl;
203 dump_node_pins(o, ind+4);
204 dump_obj_attr(o, ind+4);
207 /* This is the generic dumping of all the signals connected to each
208 pin of the object. The "this" object is not printed, only the
209 signals connected to this. */
210 void NetObj::dump_node_pins(ostream&o, unsigned ind) const
212 for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
213 o << setw(ind) << "" << idx << " " << pin(idx).get_name()
214 << "<" << pin(idx).get_inst() << ">";
216 switch (pin(idx).get_dir()) {
217 case Link::PASSIVE:
218 o << " p";
219 break;
220 case Link::INPUT:
221 o << " I";
222 break;
223 case Link::OUTPUT:
224 o << " O";
225 break;
228 o << " (" << pin(idx).drive0() << "0 "
229 << pin(idx).drive1() << "1): ";
231 if (pin(idx).is_linked()) {
232 const Nexus*nex = pin(idx).nexus();
233 o << nex << " " << nex->name();
235 o << endl;
240 void NetObj::dump_obj_attr(ostream&o, unsigned ind) const
242 unsigned idx;
243 for (idx = 0 ; idx < attr_cnt() ; idx += 1) {
244 o << setw(ind) << "" << attr_key(idx) << " = \"" <<
245 attr_value(idx) << "\"" << endl;
249 void NetAddSub::dump_node(ostream&o, unsigned ind) const
251 o << setw(ind) << "" << "Adder (NetAddSub): " << name()
252 << " width=" << width() << " pin_count=" << pin_count()
253 << endl;
254 dump_node_pins(o, ind+4);
255 dump_obj_attr(o, ind+4);
258 void NetArrayDq::dump_node(ostream&o, unsigned ind) const
260 o << setw(ind) << "" << "NetArrayDq: " << name()
261 << " array=" << mem_->name()
262 << endl;
263 dump_node_pins(o, ind+4);
264 dump_obj_attr(o, ind+4);
267 void NetCLShift::dump_node(ostream&o, unsigned ind) const
269 o << setw(ind) << "" << "Combinatorial shift (NetCLShift): " <<
270 name() << endl;
271 dump_node_pins(o, ind+4);
272 dump_obj_attr(o, ind+4);
275 void NetCompare::dump_node(ostream&o, unsigned ind) const
277 o << setw(ind) << "" << "LPM_COMPARE (NetCompare): " << name() << endl;
278 dump_node_pins(o, ind+4);
279 dump_obj_attr(o, ind+4);
282 void NetConcat::dump_node(ostream&o, unsigned ind) const
284 o << setw(ind) << "" << "NetConcat: "
285 << name()
286 << " scope=" << scope_path(scope())
287 << " width=" << width_ << endl;
288 dump_node_pins(o, ind+4);
289 dump_obj_attr(o, ind+4);
292 void NetDivide::dump_node(ostream&o, unsigned ind) const
294 o << setw(ind) << "" << "NET_DIVIDE (NetDivide): " << name() << endl;
295 dump_node_pins(o, ind+4);
296 dump_obj_attr(o, ind+4);
299 void NetMult::dump_node(ostream&o, unsigned ind) const
301 o << setw(ind) << "" << "LPM_MULT (NetMult): " << name() << endl;
302 dump_node_pins(o, ind+4);
303 dump_obj_attr(o, ind+4);
306 void NetMux::dump_node(ostream&o, unsigned ind) const
308 o << setw(ind) << "" << "Multiplexer (NetMux): " << name()
309 << " width=" << width_ << " swidth=" << swidth_ << " size=" << size_
310 << " scope=" << scope_path(scope()) << endl;
311 dump_node_pins(o, ind+4);
312 dump_obj_attr(o, ind+4);
315 void NetBUFZ::dump_node(ostream&o, unsigned ind) const
317 o << setw(ind) << "" << "NetBUFZ: " << name()
318 << " scope=" << scope_path(scope())
319 << " delay=(" << rise_time() << "," << fall_time() << "," <<
320 decay_time() << ") width=" << width() << endl;
321 dump_node_pins(o, ind+4);
324 void NetCaseCmp::dump_node(ostream&o, unsigned ind) const
326 if (eeq_)
327 o << setw(ind) << "" << "case compare === : " << name() << endl;
328 else
329 o << setw(ind) << "" << "case compare !== : " << name() << endl;
331 dump_node_pins(o, ind+4);
334 void NetConst::dump_node(ostream&o, unsigned ind) const
336 o << setw(ind) << "" << "constant " << width_ << "'b";
337 for (unsigned idx = width_ ; idx > 0 ; idx -= 1)
338 o << value_[idx-1];
339 o << ": " << name() << endl;
340 dump_node_pins(o, ind+4);
343 void NetFF::dump_node(ostream&o, unsigned ind) const
345 o << setw(ind) << "" << "LPM_FF: " << name()
346 << " scope=" << scope_path(scope())
347 << " aset_value=" << aset_value_ << endl;
349 dump_node_pins(o, ind+4);
350 dump_obj_attr(o, ind+4);
353 void NetLiteral::dump_node(ostream&o, unsigned ind) const
355 o << setw(ind) << "" << "constant real " << real_
356 << ": " << name() << endl;
357 dump_node_pins(o, ind+4);
360 void NetLogic::dump_node(ostream&o, unsigned ind) const
362 o << setw(ind) << "" << "logic: ";
363 switch (type_) {
364 case AND:
365 o << "and";
366 break;
367 case BUF:
368 o << "buf";
369 break;
370 case BUFIF0:
371 o << "bufif0";
372 break;
373 case BUFIF1:
374 o << "bufif1";
375 break;
376 case CMOS:
377 o << "cmos";
378 break;
379 case NAND:
380 o << "nand";
381 break;
382 case NMOS:
383 o << "nmos";
384 break;
385 case NOR:
386 o << "nor";
387 break;
388 case NOT:
389 o << "not";
390 break;
391 case NOTIF0:
392 o << "notif0";
393 break;
394 case NOTIF1:
395 o << "notif1";
396 break;
397 case OR:
398 o << "or";
399 break;
400 case PULLDOWN:
401 o << "pulldown";
402 break;
403 case PULLUP:
404 o << "pullup";
405 break;
406 case RCMOS:
407 o << "rcmos";
408 break;
409 case RNMOS:
410 o << "rnmos";
411 break;
412 case RPMOS:
413 o << "rpmos";
414 break;
415 case PMOS:
416 o << "pmos";
417 break;
418 case XNOR:
419 o << "xnor";
420 break;
421 case XOR:
422 o << "xor";
423 break;
425 o << " #(" << rise_time()
426 << "," << fall_time() << "," << decay_time() << ") " << name()
427 << " scope=" << scope_path(scope())
428 << endl;
430 dump_node_pins(o, ind+4);
431 dump_obj_attr(o, ind+4);
434 void NetModulo::dump_node(ostream&o, unsigned ind) const
436 o << setw(ind) << "" << "NET_MODULO (NetModulo): " << name() << endl;
437 dump_node_pins(o, ind+4);
438 dump_obj_attr(o, ind+4);
441 void NetPartSelect::dump_node(ostream&o, unsigned ind) const
443 const char*pt = "";
444 switch (dir_) {
445 case VP:
446 pt = "VP";
447 break;
448 case PV:
449 pt = "PV";
450 break;
451 case BI:
452 pt = "BI";
453 break;
455 o << setw(ind) << "" << "NetPartSelect(" << pt << "): "
456 << name() << " off=" << off_ << " wid=" << wid_ <<endl;
457 dump_node_pins(o, ind+4);
458 dump_obj_attr(o, ind+4);
461 void NetReplicate::dump_node(ostream&o, unsigned ind) const
463 o << setw(ind) << "" << "NetReplicate: "
464 << name() << " wid=" << width_ << ", repeat_=" << repeat_
465 << ", input wid=" << width_/repeat_ << endl;
466 dump_node_pins(o, ind+4);
467 dump_obj_attr(o, ind+4);
470 void NetSignExtend::dump_node(ostream&o, unsigned ind) const
472 o << setw(ind) << "" << "NetSignExtend: "
473 << name() << " output width=" << width_ << endl;
474 dump_node_pins(o, ind+4);
475 dump_obj_attr(o, ind+4);
478 void NetUReduce::dump_node(ostream&o, unsigned ind) const
480 o << setw(ind) << "" << "reduction logic: ";
481 switch (type_) {
482 case NONE:
483 o << "NONE";
484 break;
485 case AND:
486 o << "and";
487 break;
488 case OR:
489 o << "or";
490 break;
491 case XOR:
492 o << "xor";
493 break;
494 case NAND:
495 o << "nand";
496 break;
497 case NOR:
498 o << "nor";
499 break;
500 case XNOR:
501 o << "xnor";
502 break;
504 o << " #(" << rise_time()
505 << "," << fall_time() << "," << decay_time() << ") " << name()
506 << " scope=" << scope_path(scope())
507 << endl;
509 dump_node_pins(o, ind+4);
510 dump_obj_attr(o, ind+4);
513 void NetSysFunc::dump_node(ostream&o, unsigned ind) const
515 o << setw(ind) << "" << def_->name << "(...)" << endl;
516 dump_node_pins(o, ind+4);
517 dump_obj_attr(o, ind+4);
520 void NetUserFunc::dump_node(ostream&o, unsigned ind) const
522 o << setw(ind) << "" << scope_path(def_) << "(";
523 o << ")" << endl;
524 dump_node_pins(o, ind+4);
525 dump_obj_attr(o, ind+4);
528 void NetTaskDef::dump(ostream&o, unsigned ind) const
530 o << setw(ind) << "" << "task " << scope_path(scope_) << ";" << endl;
532 for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1) {
533 o << setw(ind+4) << "";
534 assert(ports_[idx]);
535 switch (ports_[idx]->port_type()) {
536 case NetNet::PINPUT:
537 o << "input ";
538 break;
539 case NetNet::POUTPUT:
540 o << "output ";
541 break;
542 case NetNet::PINOUT:
543 o << "input ";
544 break;
545 default:
546 o << "NOT_A_PORT ";
547 break;
549 o << ports_[idx]->name() << ";" << endl;
552 proc_->dump(o, ind+4);
554 o << setw(ind) << "" << "endtask" << endl;
557 void NetUDP::dump_node(ostream&o, unsigned ind) const
559 o << setw(ind) << "" << "UDP (" << udp_name() << "): ";
560 o << " #(" << rise_time() << "," << fall_time() << "," << decay_time() <<
561 ") " << name() << endl;
563 dump_node_pins(o, ind+4);
564 dump_obj_attr(o, ind+4);
567 void NetProcTop::dump(ostream&o, unsigned ind) const
569 switch (type_) {
570 case NetProcTop::KINITIAL:
571 o << "initial /* " << get_line() << " in "
572 << scope_path(scope_) << " */" << endl;
573 break;
574 case NetProcTop::KALWAYS:
575 o << "always /* " << get_line() << " in "
576 << scope_path(scope_) << " */" << endl;
577 break;
580 for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1) {
581 o << setw(ind+2) << "" << "(* " << attr_key(idx) << " = "
582 << attr_value(idx) << " *)" << endl;
585 statement_->dump(o, ind+2);
588 void NetAssign_::dump_lval(ostream&o) const
590 if (sig_) {
591 o << sig_->name();
592 if (word_) {
593 o << "[word=" << *word_ << "]";
595 if (base_) {
596 o << "[" << *base_ << " +: " << lwid_ << "]";
598 } else {
599 o << "";
603 void NetAssignBase::dump_lval(ostream&o) const
605 o << "{";
606 lval_->dump_lval(o);
608 for (NetAssign_*cur = lval_->more ; cur ; cur = cur->more) {
609 o << ", ";
610 cur->dump_lval(o);
613 o << "}";
616 /* Dump an assignment statement */
617 void NetAssign::dump(ostream&o, unsigned ind) const
619 o << setw(ind) << "";
620 dump_lval(o);
622 o << " = ";
624 if (const NetExpr*de = get_delay())
625 o << "#(" << *de << ") ";
627 o << *rval() << ";" << endl;
630 void NetAssignNB::dump(ostream&o, unsigned ind) const
632 o << setw(ind) << "";
633 dump_lval(o);
635 o << " <= ";
637 if (const NetExpr*de = get_delay())
638 o << "#(" << *de << ") ";
640 o << *rval() << ";" << endl;
644 void NetAssignBase::dump(ostream&o, unsigned ind) const
646 if (const NetAssignNB *n1 = dynamic_cast<const NetAssignNB*>(this)) {
647 n1->dump(o,ind);
648 } else if (const NetAssign *n2 = dynamic_cast<const NetAssign*>(this)) {
649 n2->dump(o,ind);
653 /* Dump a block statement */
654 void NetBlock::dump(ostream&o, unsigned ind) const
656 o << setw(ind) << "" << type_;
657 if (subscope_)
658 o << " : " << scope_path(subscope_);
659 o << endl;
661 if (last_) {
662 const NetProc*cur = last_;
663 do {
664 cur = cur->next_;
665 cur->dump(o, ind+4);
666 } while (cur != last_);
669 o << setw(ind) << "" << "end" << endl;
672 void NetCase::dump(ostream&o, unsigned ind) const
674 switch (type_) {
675 case EQ:
676 o << setw(ind) << "" << "case (" << *expr_ << ")" << endl;
677 break;
678 case EQX:
679 o << setw(ind) << "" << "casex (" << *expr_ << ")" << endl;
680 break;
681 case EQZ:
682 o << setw(ind) << "" << "casez (" << *expr_ << ")" << endl;
683 break;
686 for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) {
687 o << setw(ind+2) << "";
688 if (items_[idx].guard)
689 o << *items_[idx].guard << ":";
690 else
691 o << "default:";
693 if (items_[idx].statement) {
694 o << endl;
695 items_[idx].statement->dump(o, ind+6);
696 } else {
697 o << " ;" << endl;
701 o << setw(ind) << "" << "endcase" << endl;
704 void NetCAssign::dump(ostream&o, unsigned ind) const
706 o << setw(ind) << "" << "cassign ";
707 dump_lval(o);
708 o << " = " << *rval() << "; /* " << get_line() << " */" << endl;
711 void NetCondit::dump(ostream&o, unsigned ind) const
713 o << setw(ind) << "" << "if (";
714 expr_->dump(o);
715 o << ")" << endl;
717 if (if_) if_->dump(o, ind+4);
718 else o << setw(ind+4) << "" << "/* empty */ ;" << endl;
720 if (else_) {
721 o << setw(ind) << "" << "else" << endl;
722 else_->dump(o, ind+4);
726 void NetDeassign::dump(ostream&o, unsigned ind) const
728 o << setw(ind) << "" << "deassign ";
729 dump_lval(o);
730 o << "; /* " << get_line() << " */" << endl;
733 void NetDisable::dump(ostream&o, unsigned ind) const
735 o << setw(ind) << "" << "disable " << scope_path(target_) << "; "
736 << "/* " << get_line() << " */" << endl;
739 void NetEvProbe::dump_node(ostream&o, unsigned ind) const
741 o << setw(ind) << "";
743 switch (edge_) {
744 case ANYEDGE:
745 o << "anyedge ";
746 break;
747 case POSEDGE:
748 o << "posedge ";
749 break;
750 case NEGEDGE:
751 o << "negedge ";
752 break;
754 o << setw(ind) << "" << "-> " << event_->name() << "; " << endl;
755 dump_node_pins(o, ind+4);
756 dump_obj_attr(o, ind+4);
759 void NetEvTrig::dump(ostream&o, unsigned ind) const
761 o << setw(ind) << "" << "-> " << event_->name() << "; "
762 << "// " << get_line() << endl;
765 void NetEvWait::dump(ostream&o, unsigned ind) const
767 o << setw(ind) <<"" << "@(";
769 if (nevents() > 0)
770 o << event(0)->name();
772 for (unsigned idx = 1 ; idx < nevents() ; idx += 1)
773 o << " or " << event(idx)->name();
775 o << ") // " << get_line() << endl;
777 if (statement_)
778 statement_->dump(o, ind+2);
779 else
780 o << setw(ind+2) << "" << "/* noop */ ;" << endl;
783 void NetForce::dump(ostream&o, unsigned ind) const
785 o << setw(ind) << "" << "force ";
786 dump_lval(o);
787 o << " = " << *rval() << "; /* " << get_line() << " */" << endl;
790 void NetForever::dump(ostream&o, unsigned ind) const
792 o << setw(ind) << "" << "forever" << endl;
793 statement_->dump(o, ind+2);
796 void NetFuncDef::dump(ostream&o, unsigned ind) const
798 o << setw(ind) << "" << "function " << scope_path(scope_) << endl;
799 if (result_sig_)
800 o << setw(ind+2) << "" << "Return signal: "
801 << result_sig_->name() << endl;
802 if (statement_)
803 statement_->dump(o, ind+2);
804 else
805 o << setw(ind+2) << "" << "// NO STATEMENT" << endl;
808 void NetPDelay::dump(ostream&o, unsigned ind) const
810 if (expr_) {
811 o << setw(ind) << "" << "#" << *expr_;
813 } else {
814 o << setw(ind) << "" << "#" << delay_;
817 if (statement_) {
818 o << endl;
819 statement_->dump(o, ind+2);
820 } else {
821 o << " /* noop */;" << endl;
825 void NetRelease::dump(ostream&o, unsigned ind) const
827 o << setw(ind) << "" << "release ";
828 dump_lval(o);
829 o << "; /* " << get_line() << " */" << endl;
832 void NetRepeat::dump(ostream&o, unsigned ind) const
834 o << setw(ind) << "" << "repeat (" << *expr_ << ")" << endl;
835 statement_->dump(o, ind+2);
838 void NetScope::dump(ostream&o) const
840 /* This is a constructed hierarchical name. */
841 o << scope_path(this);
843 switch (type_) {
844 case BEGIN_END:
845 o << " sequential block";
846 break;
847 case FORK_JOIN:
848 o << " parallel block";
849 break;
850 case FUNC:
851 o << " function";
852 break;
853 case MODULE:
854 o << " module <" << (module_name_? module_name_.str() : "") << ">";
855 break;
856 case TASK:
857 o << " task";
858 break;
859 case GENBLOCK:
860 o << " generate block";
861 break;
863 o << endl;
865 for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1)
866 o << " (* " << attr_key(idx) << " = "
867 << attr_value(idx) << " *)" << endl;
869 o << " timescale = 10e" << time_unit() << " / 10e"
870 << time_precision() << endl;
872 /* Dump the parameters for this scope. */
874 map<perm_string,param_expr_t>::const_iterator pp;
875 for (pp = parameters.begin()
876 ; pp != parameters.end() ; pp ++) {
877 o << " parameter ";
879 if ((*pp).second.signed_flag)
880 o << "signed ";
882 if ((*pp).second.msb)
883 o << "[" << *(*pp).second.msb
884 << ":" << *(*pp).second.lsb << "] ";
886 o << (*pp).first << " = " <<
887 *(*pp).second.expr << ";" << endl;
890 for (pp = localparams.begin()
891 ; pp != localparams.end() ; pp ++) {
892 o << " localparam " << (*pp).first << " = " <<
893 *(*pp).second.expr << ";" << endl;
897 /* Dump the saved defparam assignments here. */
899 map<pform_name_t,NetExpr*>::const_iterator pp;
900 for (pp = defparams.begin()
901 ; pp != defparams.end() ; pp ++ ) {
902 o << " defparam " << (*pp).first << " = " <<
903 *(*pp).second << ";" << endl;
907 /* Dump the events in this scope. */
908 for (NetEvent*cur = events_ ; cur ; cur = cur->snext_) {
909 o << " event " << cur->name() << "; nprobe="
910 << cur->nprobe() << " scope=" << scope_path(cur->scope())
911 << " // " << cur->get_line() << endl;
914 // Dump the signals,
915 if (signals_) {
916 NetNet*cur = signals_->sig_next_;
917 do {
918 cur->dump_net(o, 4);
919 cur = cur->sig_next_;
920 } while (cur != signals_->sig_next_);
923 // Dump specparams
924 typedef map<perm_string,spec_val_t>::const_iterator specparam_it_t;
925 for (specparam_it_t cur = specparams.begin()
926 ; cur != specparams.end() ; cur ++ ) {
927 o << " specparam " << (*cur).first
928 << " = ";
929 spec_val_t value = (*cur).second;
930 switch (value.type) {
931 case IVL_VT_REAL:
932 o << "R:" << value.real_val;
933 break;
934 case IVL_VT_BOOL:
935 o << "I:" << value.integer;
936 break;
937 default:
938 o << "<bad type>";
939 break;
941 o << endl;
944 switch (type_) {
945 case FUNC:
946 if (func_def())
947 func_def()->dump(o, 4);
948 else
949 o << " MISSING FUNCTION DEFINITION" << endl;
950 break;
951 case TASK:
952 task_def()->dump(o, 4);
953 break;
954 default:
955 break;
958 /* Dump any sub-scopes. */
959 for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
960 cur->dump(o);
963 void NetSTask::dump(ostream&o, unsigned ind) const
965 o << setw(ind) << "" << name_;
967 if (parms_.count() > 0) {
968 o << "(";
969 if (parms_[0])
970 parms_[0]->dump(o);
972 for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
973 o << ", ";
974 if (parms_[idx])
975 parms_[idx]->dump(o);
978 o << ")";
980 o << ";" << endl;
983 void NetUTask::dump(ostream&o, unsigned ind) const
985 o << setw(ind) << "" << scope_path(task_) << ";" << endl;
988 void NetWhile::dump(ostream&o, unsigned ind) const
990 o << setw(ind) << "" << "while (" << *cond_ << ")" << endl;
991 proc_->dump(o, ind+3);
994 /* Dump a statement type that someone didn't write a dump for. */
995 void NetProc::dump(ostream&o, unsigned ind) const
997 o << setw(ind) << "" << "// " << typeid(*this).name() << endl;
1000 /* Dump an expression that no one wrote a dump method for. */
1001 void NetExpr::dump(ostream&o) const
1003 o << "(?" << typeid(*this).name() << "?)";
1006 void NetEBinary::dump(ostream&o) const
1008 o << "(";
1009 left_->dump(o);
1010 o << ")";
1011 switch (op_) {
1012 default:
1013 o << op_;
1014 break;
1015 case 'a':
1016 o << "&&";
1017 break;
1018 case 'E':
1019 o << "===";
1020 break;
1021 case 'e':
1022 o << "==";
1023 break;
1024 case 'G':
1025 o << ">=";
1026 break;
1027 case 'l':
1028 o << "<<";
1029 break;
1030 case 'L':
1031 o << "<=";
1032 break;
1033 case 'n':
1034 o << "!=";
1035 break;
1036 case 'N':
1037 o << "!==";
1038 break;
1039 case 'o':
1040 o << "||";
1041 break;
1042 case 'O':
1043 o << "~|";
1044 break;
1045 case 'p':
1046 o << "**";
1047 break;
1048 case 'r':
1049 o << ">>";
1050 break;
1051 case 'R':
1052 o << ">>>";
1053 break;
1054 case 'X':
1055 o << "~^";
1056 break;
1058 o << "(";
1059 right_->dump(o);
1060 o << ")";
1063 void NetEConcat::dump(ostream&o) const
1065 if (repeat_calculated_) {
1066 if (repeat_value_ != 1)
1067 o << repeat_value_;
1068 } else if (repeat_) {
1069 o << "<" << *repeat_ << ">";
1072 if (parms_[0])
1073 o << "{" << *parms_[0];
1074 else
1075 o << "{";
1077 for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
1078 if (parms_[idx])
1079 o << ", " << *parms_[idx];
1080 else
1081 o << ", ";
1083 o << "}";
1086 void NetEConst::dump(ostream&o) const
1088 if (value_.is_string())
1089 o << "\"" << value_.as_string() << "\"";
1090 else
1091 o << value_;
1094 void NetEConstParam::dump(ostream&o) const
1096 o << "<" << name_ << "=";
1097 NetEConst::dump(o);
1098 o << ", wid=" << expr_width() << ">";
1101 void NetECReal::dump(ostream&o) const
1103 o << value_;
1106 void NetECRealParam::dump(ostream&o) const
1108 o << "<" << name_ << "=";
1109 NetECReal::dump(o);
1110 o << ">";
1113 void NetEEvent::dump(ostream&o) const
1115 o << "<event=" << event_->name() << ">";
1118 void NetEScope::dump(ostream&o) const
1120 o << "<scope=" << scope_path(scope_) << ">";
1123 void NetESelect::dump(ostream&o) const
1125 o << "<select";
1126 if (has_sign())
1127 o << "+=";
1128 else
1129 o << "=";
1131 expr_->dump(o);
1132 o << "[";
1134 if (base_)
1135 base_->dump(o);
1136 else
1137 o << "(0)";
1139 o << "+:" << expr_width() << "]>";
1142 void NetESFunc::dump(ostream&o) const
1144 o << name_ << "(";
1145 if (nparms() > 0)
1146 o << *parm(0);
1147 for (unsigned idx = 1 ; idx < nparms() ; idx += 1)
1148 o << ", " << *parm(idx);
1149 o << ")";
1152 void NetESignal::dump(ostream&o) const
1154 if (has_sign())
1155 o << "+";
1156 o << name();
1157 if (word_) o << "[word=" << *word_ << "]";
1158 o << "[" << msi()<<":"<<lsi() << "]";
1161 void NetEParam::dump(ostream&o) const
1163 if (scope_ != 0)
1164 o << "<" << scope_path(scope_) << "." << name_ << ">";
1165 else if (name_)
1166 o << "<" << name_ << ">";
1167 else
1168 o << "<" "???" ">";
1171 void NetETernary::dump(ostream&o) const
1173 o << "(" << *cond_ << ") ? (" << *true_val_ << ") : (" <<
1174 *false_val_ << ")";
1177 void NetEUFunc::dump(ostream&o) const
1179 o << func_->basename() << "(";
1180 if (parms_.count() > 0) {
1181 parms_[0]->dump(o);
1182 for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
1183 o << ", ";
1184 parms_[idx]->dump(o);
1187 o << ")";
1190 void NetEUnary::dump(ostream&o) const
1192 switch (op_) {
1193 case 'N':
1194 o << "~|";
1195 break;
1196 default:
1197 o << op_;
1198 break;
1200 o << "(";
1201 expr_->dump(o);
1202 o << ")";
1205 void Design::dump(ostream&o) const
1207 o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl;
1208 o << "SCOPES:" << endl;
1209 for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
1210 scope != root_scopes_.end(); scope++)
1211 (*scope)->dump(o);
1213 o << "ELABORATED NODES:" << endl;
1215 // dump the nodes,
1216 if (nodes_) {
1217 NetNode*cur = nodes_->node_next_;
1218 do {
1219 cur->dump_node(o, 0);
1220 cur = cur->node_next_;
1221 } while (cur != nodes_->node_next_);
1224 o << "ELABORATED PROCESSES:" << endl;
1226 // Dump the processes.
1227 for (const NetProcTop*idx = procs_ ; idx ; idx = idx->next_)
1228 idx->dump(o, 0);