Careful not to lose bits parameter add expression
[iverilog.git] / design_dump.cc
blob37a1c8156fb62aed530ea083a3b4788200e9ce05
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 NAND:
377 o << "nand";
378 break;
379 case NMOS:
380 o << "nmos";
381 break;
382 case NOR:
383 o << "nor";
384 break;
385 case NOT:
386 o << "not";
387 break;
388 case NOTIF0:
389 o << "notif0";
390 break;
391 case NOTIF1:
392 o << "notif1";
393 break;
394 case OR:
395 o << "or";
396 break;
397 case PULLDOWN:
398 o << "pulldown";
399 break;
400 case PULLUP:
401 o << "pullup";
402 break;
403 case RNMOS:
404 o << "rnmos";
405 break;
406 case RPMOS:
407 o << "rpmos";
408 break;
409 case PMOS:
410 o << "pmos";
411 break;
412 case XNOR:
413 o << "xnor";
414 break;
415 case XOR:
416 o << "xor";
417 break;
419 o << " #(" << rise_time()
420 << "," << fall_time() << "," << decay_time() << ") " << name()
421 << " scope=" << scope_path(scope())
422 << endl;
424 dump_node_pins(o, ind+4);
425 dump_obj_attr(o, ind+4);
428 void NetModulo::dump_node(ostream&o, unsigned ind) const
430 o << setw(ind) << "" << "NET_MODULO (NetModulo): " << name() << endl;
431 dump_node_pins(o, ind+4);
432 dump_obj_attr(o, ind+4);
435 void NetPartSelect::dump_node(ostream&o, unsigned ind) const
437 const char*pt = "";
438 switch (dir_) {
439 case VP:
440 pt = "VP";
441 break;
442 case PV:
443 pt = "PV";
444 break;
445 case BI:
446 pt = "BI";
447 break;
449 o << setw(ind) << "" << "NetPartSelect(" << pt << "): "
450 << name() << " off=" << off_ << " wid=" << wid_ <<endl;
451 dump_node_pins(o, ind+4);
452 dump_obj_attr(o, ind+4);
455 void NetReplicate::dump_node(ostream&o, unsigned ind) const
457 o << setw(ind) << "" << "NetReplicate: "
458 << name() << " wid=" << width_ << ", repeat_=" << repeat_
459 << ", input wid=" << width_/repeat_ << endl;
460 dump_node_pins(o, ind+4);
461 dump_obj_attr(o, ind+4);
464 void NetSignExtend::dump_node(ostream&o, unsigned ind) const
466 o << setw(ind) << "" << "NetSignExtend: "
467 << name() << " output width=" << width_ << endl;
468 dump_node_pins(o, ind+4);
469 dump_obj_attr(o, ind+4);
472 void NetUReduce::dump_node(ostream&o, unsigned ind) const
474 o << setw(ind) << "" << "reduction logic: ";
475 switch (type_) {
476 case NONE:
477 o << "NONE";
478 break;
479 case AND:
480 o << "and";
481 break;
482 case OR:
483 o << "or";
484 break;
485 case XOR:
486 o << "xor";
487 break;
488 case NAND:
489 o << "nand";
490 break;
491 case NOR:
492 o << "nor";
493 break;
494 case XNOR:
495 o << "xnor";
496 break;
498 o << " #(" << rise_time()
499 << "," << fall_time() << "," << decay_time() << ") " << name()
500 << " scope=" << scope_path(scope())
501 << endl;
503 dump_node_pins(o, ind+4);
504 dump_obj_attr(o, ind+4);
507 void NetSysFunc::dump_node(ostream&o, unsigned ind) const
509 o << setw(ind) << "" << def_->name << "(...)" << endl;
510 dump_node_pins(o, ind+4);
511 dump_obj_attr(o, ind+4);
514 void NetUserFunc::dump_node(ostream&o, unsigned ind) const
516 o << setw(ind) << "" << scope_path(def_) << "(";
517 o << ")" << endl;
518 dump_node_pins(o, ind+4);
519 dump_obj_attr(o, ind+4);
522 void NetTaskDef::dump(ostream&o, unsigned ind) const
524 o << setw(ind) << "" << "task " << scope_path(scope_) << ";" << endl;
526 for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1) {
527 o << setw(ind+4) << "";
528 assert(ports_[idx]);
529 switch (ports_[idx]->port_type()) {
530 case NetNet::PINPUT:
531 o << "input ";
532 break;
533 case NetNet::POUTPUT:
534 o << "output ";
535 break;
536 case NetNet::PINOUT:
537 o << "input ";
538 break;
539 default:
540 o << "NOT_A_PORT ";
541 break;
543 o << ports_[idx]->name() << ";" << endl;
546 proc_->dump(o, ind+4);
548 o << setw(ind) << "" << "endtask" << endl;
551 void NetUDP::dump_node(ostream&o, unsigned ind) const
553 o << setw(ind) << "" << "UDP (" << udp_name() << "): ";
554 o << " #(" << rise_time() << "," << fall_time() << "," << decay_time() <<
555 ") " << name() << endl;
557 dump_node_pins(o, ind+4);
558 dump_obj_attr(o, ind+4);
561 void NetProcTop::dump(ostream&o, unsigned ind) const
563 switch (type_) {
564 case NetProcTop::KINITIAL:
565 o << "initial /* " << get_line() << " in "
566 << scope_path(scope_) << " */" << endl;
567 break;
568 case NetProcTop::KALWAYS:
569 o << "always /* " << get_line() << " in "
570 << scope_path(scope_) << " */" << endl;
571 break;
574 for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1) {
575 o << setw(ind+2) << "" << "(* " << attr_key(idx) << " = "
576 << attr_value(idx) << " *)" << endl;
579 statement_->dump(o, ind+2);
582 void NetAssign_::dump_lval(ostream&o) const
584 if (sig_) {
585 o << sig_->name();
586 if (word_) {
587 o << "[word=" << *word_ << "]";
589 if (base_) {
590 o << "[" << *base_ << " +: " << lwid_ << "]";
592 } else {
593 o << "";
597 void NetAssignBase::dump_lval(ostream&o) const
599 o << "{";
600 lval_->dump_lval(o);
602 for (NetAssign_*cur = lval_->more ; cur ; cur = cur->more) {
603 o << ", ";
604 cur->dump_lval(o);
607 o << "}";
610 /* Dump an assignment statement */
611 void NetAssign::dump(ostream&o, unsigned ind) const
613 o << setw(ind) << "";
614 dump_lval(o);
616 o << " = ";
618 if (const NetExpr*de = get_delay())
619 o << "#(" << *de << ") ";
621 o << *rval() << ";" << endl;
624 void NetAssignNB::dump(ostream&o, unsigned ind) const
626 o << setw(ind) << "";
627 dump_lval(o);
629 o << " <= ";
631 if (const NetExpr*de = get_delay())
632 o << "#(" << *de << ") ";
634 o << *rval() << ";" << endl;
638 void NetAssignBase::dump(ostream&o, unsigned ind) const
640 if (const NetAssignNB *n1 = dynamic_cast<const NetAssignNB*>(this)) {
641 n1->dump(o,ind);
642 } else if (const NetAssign *n2 = dynamic_cast<const NetAssign*>(this)) {
643 n2->dump(o,ind);
647 /* Dump a block statement */
648 void NetBlock::dump(ostream&o, unsigned ind) const
650 o << setw(ind) << "" << type_;
651 if (subscope_)
652 o << " : " << scope_path(subscope_);
653 o << endl;
655 if (last_) {
656 const NetProc*cur = last_;
657 do {
658 cur = cur->next_;
659 cur->dump(o, ind+4);
660 } while (cur != last_);
663 o << setw(ind) << "" << "end" << endl;
666 void NetCase::dump(ostream&o, unsigned ind) const
668 switch (type_) {
669 case EQ:
670 o << setw(ind) << "" << "case (" << *expr_ << ")" << endl;
671 break;
672 case EQX:
673 o << setw(ind) << "" << "casex (" << *expr_ << ")" << endl;
674 break;
675 case EQZ:
676 o << setw(ind) << "" << "casez (" << *expr_ << ")" << endl;
677 break;
680 for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) {
681 o << setw(ind+2) << "";
682 if (items_[idx].guard)
683 o << *items_[idx].guard << ":";
684 else
685 o << "default:";
687 if (items_[idx].statement) {
688 o << endl;
689 items_[idx].statement->dump(o, ind+6);
690 } else {
691 o << " ;" << endl;
695 o << setw(ind) << "" << "endcase" << endl;
698 void NetCAssign::dump(ostream&o, unsigned ind) const
700 o << setw(ind) << "" << "cassign ";
701 dump_lval(o);
702 o << " = " << *rval() << "; /* " << get_line() << " */" << endl;
705 void NetCondit::dump(ostream&o, unsigned ind) const
707 o << setw(ind) << "" << "if (";
708 expr_->dump(o);
709 o << ")" << endl;
711 if (if_) if_->dump(o, ind+4);
712 else o << setw(ind+4) << "" << "/* empty */ ;" << endl;
714 if (else_) {
715 o << setw(ind) << "" << "else" << endl;
716 else_->dump(o, ind+4);
720 void NetDeassign::dump(ostream&o, unsigned ind) const
722 o << setw(ind) << "" << "deassign ";
723 dump_lval(o);
724 o << "; /* " << get_line() << " */" << endl;
727 void NetDisable::dump(ostream&o, unsigned ind) const
729 o << setw(ind) << "" << "disable " << scope_path(target_) << "; "
730 << "/* " << get_line() << " */" << endl;
733 void NetEvProbe::dump_node(ostream&o, unsigned ind) const
735 o << setw(ind) << "";
737 switch (edge_) {
738 case ANYEDGE:
739 o << "anyedge ";
740 break;
741 case POSEDGE:
742 o << "posedge ";
743 break;
744 case NEGEDGE:
745 o << "negedge ";
746 break;
748 o << setw(ind) << "" << "-> " << event_->name() << "; " << endl;
749 dump_node_pins(o, ind+4);
750 dump_obj_attr(o, ind+4);
753 void NetEvTrig::dump(ostream&o, unsigned ind) const
755 o << setw(ind) << "" << "-> " << event_->name() << "; "
756 << "// " << get_line() << endl;
759 void NetEvWait::dump(ostream&o, unsigned ind) const
761 o << setw(ind) <<"" << "@(";
763 if (nevents() > 0)
764 o << event(0)->name();
766 for (unsigned idx = 1 ; idx < nevents() ; idx += 1)
767 o << " or " << event(idx)->name();
769 o << ") // " << get_line() << endl;
771 if (statement_)
772 statement_->dump(o, ind+2);
773 else
774 o << setw(ind+2) << "" << "/* noop */ ;" << endl;
777 void NetForce::dump(ostream&o, unsigned ind) const
779 o << setw(ind) << "" << "force ";
780 dump_lval(o);
781 o << " = " << *rval() << "; /* " << get_line() << " */" << endl;
784 void NetForever::dump(ostream&o, unsigned ind) const
786 o << setw(ind) << "" << "forever" << endl;
787 statement_->dump(o, ind+2);
790 void NetFuncDef::dump(ostream&o, unsigned ind) const
792 o << setw(ind) << "" << "function " << scope_path(scope_) << endl;
793 if (result_sig_)
794 o << setw(ind+2) << "" << "Return signal: "
795 << result_sig_->name() << endl;
796 if (statement_)
797 statement_->dump(o, ind+2);
798 else
799 o << setw(ind+2) << "" << "// NO STATEMENT" << endl;
802 void NetPDelay::dump(ostream&o, unsigned ind) const
804 if (expr_) {
805 o << setw(ind) << "" << "#" << *expr_;
807 } else {
808 o << setw(ind) << "" << "#" << delay_;
811 if (statement_) {
812 o << endl;
813 statement_->dump(o, ind+2);
814 } else {
815 o << " /* noop */;" << endl;
819 void NetRelease::dump(ostream&o, unsigned ind) const
821 o << setw(ind) << "" << "release ";
822 dump_lval(o);
823 o << "; /* " << get_line() << " */" << endl;
826 void NetRepeat::dump(ostream&o, unsigned ind) const
828 o << setw(ind) << "" << "repeat (" << *expr_ << ")" << endl;
829 statement_->dump(o, ind+2);
832 void NetScope::dump(ostream&o) const
834 /* This is a constructed hierarchical name. */
835 o << scope_path(this);
837 switch (type_) {
838 case BEGIN_END:
839 o << " sequential block";
840 break;
841 case FORK_JOIN:
842 o << " parallel block";
843 break;
844 case FUNC:
845 o << " function";
846 break;
847 case MODULE:
848 o << " module <" << (module_name_? module_name_.str() : "") << ">";
849 break;
850 case TASK:
851 o << " task";
852 break;
853 case GENBLOCK:
854 o << " generate block";
855 break;
857 o << endl;
859 for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1)
860 o << " (* " << attr_key(idx) << " = "
861 << attr_value(idx) << " *)" << endl;
863 o << " timescale = 10e" << time_unit() << " / 10e"
864 << time_precision() << endl;
866 /* Dump the parameters for this scope. */
868 map<perm_string,param_expr_t>::const_iterator pp;
869 for (pp = parameters.begin()
870 ; pp != parameters.end() ; pp ++) {
871 o << " parameter ";
873 if ((*pp).second.signed_flag)
874 o << "signed ";
876 if ((*pp).second.msb)
877 o << "[" << *(*pp).second.msb
878 << ":" << *(*pp).second.lsb << "] ";
880 o << (*pp).first << " = " <<
881 *(*pp).second.expr << ";" << endl;
884 for (pp = localparams.begin()
885 ; pp != localparams.end() ; pp ++) {
886 o << " localparam " << (*pp).first << " = " <<
887 *(*pp).second.expr << ";" << endl;
891 /* Dump the saved defparam assignments here. */
893 map<pform_name_t,NetExpr*>::const_iterator pp;
894 for (pp = defparams.begin()
895 ; pp != defparams.end() ; pp ++ ) {
896 o << " defparam " << (*pp).first << " = " <<
897 *(*pp).second << ";" << endl;
901 /* Dump the events in this scope. */
902 for (NetEvent*cur = events_ ; cur ; cur = cur->snext_) {
903 o << " event " << cur->name() << "; nprobe="
904 << cur->nprobe() << " scope=" << scope_path(cur->scope())
905 << " // " << cur->get_line() << endl;
908 // Dump the signals,
909 if (signals_) {
910 NetNet*cur = signals_->sig_next_;
911 do {
912 cur->dump_net(o, 4);
913 cur = cur->sig_next_;
914 } while (cur != signals_->sig_next_);
917 // Dump specparams
918 typedef map<perm_string,spec_val_t>::const_iterator specparam_it_t;
919 for (specparam_it_t cur = specparams.begin()
920 ; cur != specparams.end() ; cur ++ ) {
921 o << " specparam " << (*cur).first
922 << " = ";
923 spec_val_t value = (*cur).second;
924 switch (value.type) {
925 case IVL_VT_REAL:
926 o << "R:" << value.real_val;
927 break;
928 case IVL_VT_BOOL:
929 o << "I:" << value.integer;
930 break;
931 default:
932 o << "<bad type>";
933 break;
935 o << endl;
938 switch (type_) {
939 case FUNC:
940 if (func_def())
941 func_def()->dump(o, 4);
942 else
943 o << " MISSING FUNCTION DEFINITION" << endl;
944 break;
945 case TASK:
946 task_def()->dump(o, 4);
947 break;
948 default:
949 break;
952 /* Dump any sub-scopes. */
953 for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
954 cur->dump(o);
957 void NetSTask::dump(ostream&o, unsigned ind) const
959 o << setw(ind) << "" << name_;
961 if (parms_.count() > 0) {
962 o << "(";
963 if (parms_[0])
964 parms_[0]->dump(o);
966 for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
967 o << ", ";
968 if (parms_[idx])
969 parms_[idx]->dump(o);
972 o << ")";
974 o << ";" << endl;
977 void NetUTask::dump(ostream&o, unsigned ind) const
979 o << setw(ind) << "" << scope_path(task_) << ";" << endl;
982 void NetWhile::dump(ostream&o, unsigned ind) const
984 o << setw(ind) << "" << "while (" << *cond_ << ")" << endl;
985 proc_->dump(o, ind+3);
988 /* Dump a statement type that someone didn't write a dump for. */
989 void NetProc::dump(ostream&o, unsigned ind) const
991 o << setw(ind) << "" << "// " << typeid(*this).name() << endl;
994 /* Dump an expression that no one wrote a dump method for. */
995 void NetExpr::dump(ostream&o) const
997 o << "(?" << typeid(*this).name() << "?)";
1000 void NetEBinary::dump(ostream&o) const
1002 o << "(";
1003 left_->dump(o);
1004 o << ")";
1005 switch (op_) {
1006 default:
1007 o << op_;
1008 break;
1009 case 'a':
1010 o << "&&";
1011 break;
1012 case 'E':
1013 o << "===";
1014 break;
1015 case 'e':
1016 o << "==";
1017 break;
1018 case 'G':
1019 o << ">=";
1020 break;
1021 case 'l':
1022 o << "<<";
1023 break;
1024 case 'L':
1025 o << "<=";
1026 break;
1027 case 'n':
1028 o << "!=";
1029 break;
1030 case 'N':
1031 o << "!==";
1032 break;
1033 case 'o':
1034 o << "||";
1035 break;
1036 case 'O':
1037 o << "~|";
1038 break;
1039 case 'p':
1040 o << "**";
1041 break;
1042 case 'r':
1043 o << ">>";
1044 break;
1045 case 'R':
1046 o << ">>>";
1047 break;
1048 case 'X':
1049 o << "~^";
1050 break;
1052 o << "(";
1053 right_->dump(o);
1054 o << ")";
1057 void NetEConcat::dump(ostream&o) const
1059 if (repeat_calculated_) {
1060 if (repeat_value_ != 1)
1061 o << repeat_value_;
1062 } else if (repeat_) {
1063 o << "<" << *repeat_ << ">";
1066 if (parms_[0])
1067 o << "{" << *parms_[0];
1068 else
1069 o << "{";
1071 for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
1072 if (parms_[idx])
1073 o << ", " << *parms_[idx];
1074 else
1075 o << ", ";
1077 o << "}";
1080 void NetEConst::dump(ostream&o) const
1082 if (value_.is_string())
1083 o << "\"" << value_.as_string() << "\"";
1084 else
1085 o << value_;
1088 void NetEConstParam::dump(ostream&o) const
1090 o << "<" << name_ << "=";
1091 NetEConst::dump(o);
1092 o << ", wid=" << expr_width() << ">";
1095 void NetECReal::dump(ostream&o) const
1097 o << value_;
1100 void NetECRealParam::dump(ostream&o) const
1102 o << "<" << name_ << "=";
1103 NetECReal::dump(o);
1104 o << ">";
1107 void NetEEvent::dump(ostream&o) const
1109 o << "<event=" << event_->name() << ">";
1112 void NetEScope::dump(ostream&o) const
1114 o << "<scope=" << scope_path(scope_) << ">";
1117 void NetESelect::dump(ostream&o) const
1119 o << "<select";
1120 if (has_sign())
1121 o << "+=";
1122 else
1123 o << "=";
1125 expr_->dump(o);
1126 o << "[";
1128 if (base_)
1129 base_->dump(o);
1130 else
1131 o << "(0)";
1133 o << "+:" << expr_width() << "]>";
1136 void NetESFunc::dump(ostream&o) const
1138 o << name_ << "(";
1139 if (nparms() > 0)
1140 o << *parm(0);
1141 for (unsigned idx = 1 ; idx < nparms() ; idx += 1)
1142 o << ", " << *parm(idx);
1143 o << ")";
1146 void NetESignal::dump(ostream&o) const
1148 if (has_sign())
1149 o << "+";
1150 o << name();
1151 if (word_) o << "[word=" << *word_ << "]";
1152 o << "[" << msi()<<":"<<lsi() << "]";
1155 void NetEParam::dump(ostream&o) const
1157 if (scope_ != 0)
1158 o << "<" << scope_path(scope_) << "." << name_ << ">";
1159 else if (name_)
1160 o << "<" << name_ << ">";
1161 else
1162 o << "<" "???" ">";
1165 void NetETernary::dump(ostream&o) const
1167 o << "(" << *cond_ << ") ? (" << *true_val_ << ") : (" <<
1168 *false_val_ << ")";
1171 void NetEUFunc::dump(ostream&o) const
1173 o << func_->basename() << "(";
1174 if (parms_.count() > 0) {
1175 parms_[0]->dump(o);
1176 for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
1177 o << ", ";
1178 parms_[idx]->dump(o);
1181 o << ")";
1184 void NetEUnary::dump(ostream&o) const
1186 switch (op_) {
1187 case 'N':
1188 o << "~|";
1189 break;
1190 default:
1191 o << op_;
1192 break;
1194 o << "(";
1195 expr_->dump(o);
1196 o << ")";
1199 void Design::dump(ostream&o) const
1201 o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl;
1202 o << "SCOPES:" << endl;
1203 for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
1204 scope != root_scopes_.end(); scope++)
1205 (*scope)->dump(o);
1207 o << "ELABORATED NODES:" << endl;
1209 // dump the nodes,
1210 if (nodes_) {
1211 NetNode*cur = nodes_->node_next_;
1212 do {
1213 cur->dump_node(o, 0);
1214 cur = cur->node_next_;
1215 } while (cur != nodes_->node_next_);
1218 o << "ELABORATED PROCESSES:" << endl;
1220 // Dump the processes.
1221 for (const NetProcTop*idx = procs_ ; idx ; idx = idx->next_)
1222 idx->dump(o, 0);
1227 * $Log: design_dump.cc,v $
1228 * Revision 1.176 2007/06/02 03:42:12 steve
1229 * Properly evaluate scope path expressions.
1231 * Revision 1.175 2007/05/24 04:07:11 steve
1232 * Rework the heirarchical identifier parse syntax and pform
1233 * to handle more general combinations of heirarch and bit selects.
1235 * Revision 1.174 2007/03/02 06:13:22 steve
1236 * Add support for edge sensitive spec paths.
1238 * Revision 1.173 2007/02/01 03:14:33 steve
1239 * Detect and report arrays without index in net contexts.
1241 * Revision 1.172 2007/01/16 05:44:14 steve
1242 * Major rework of array handling. Memories are replaced with the
1243 * more general concept of arrays. The NetMemory and NetEMemory
1244 * classes are removed from the ivl core program, and the IVL_LPM_RAM
1245 * lpm type is removed from the ivl_target API.
1247 * Revision 1.171 2006/10/30 05:44:49 steve
1248 * Expression widths with unsized literals are pseudo-infinite width.
1250 * Revision 1.170 2006/10/03 05:06:00 steve
1251 * Support real valued specify delays, properly scaled.
1253 * Revision 1.169 2006/09/26 19:48:40 steve
1254 * Missing PSpec.cc file.
1256 * Revision 1.168 2006/09/23 04:57:19 steve
1257 * Basic support for specify timing.
1259 * Revision 1.167 2006/07/31 03:50:17 steve
1260 * Add support for power in constant expressions.
1262 * Revision 1.166 2006/06/18 04:15:50 steve
1263 * Add support for system functions in continuous assignments.
1265 * Revision 1.165 2006/04/10 00:37:42 steve
1266 * Add support for generate loops w/ wires and gates.
1268 * Revision 1.164 2006/02/02 02:43:57 steve
1269 * Allow part selects of memory words in l-values.
1271 * Revision 1.163 2005/08/27 04:32:08 steve
1272 * Handle synthesis of fully packed case statements.
1274 * Revision 1.162 2005/07/11 16:56:50 steve
1275 * Remove NetVariable and ivl_variable_t structures.
1277 * Revision 1.161 2005/07/07 16:22:49 steve
1278 * Generalize signals to carry types.
1280 * Revision 1.160 2005/05/24 01:44:27 steve
1281 * Do sign extension of structuran nets.
1283 * Revision 1.159 2005/05/17 20:56:55 steve
1284 * Parameters cannot have their width changed.
1286 * Revision 1.158 2005/05/07 03:13:30 steve
1287 * Include delay expressions for assignments in dump.
1289 * Revision 1.157 2005/03/09 05:52:03 steve
1290 * Handle case inequality in netlists.
1292 * Revision 1.156 2005/02/08 00:12:36 steve
1293 * Add the NetRepeat node, and code generator support.
1295 * Revision 1.155 2005/02/03 04:56:20 steve
1296 * laborate reduction gates into LPM_RED_ nodes.
1298 * Revision 1.154 2005/01/24 05:28:30 steve
1299 * Remove the NetEBitSel and combine all bit/part select
1300 * behavior into the NetESelect node and IVL_EX_SELECT
1301 * ivl_target expression type.
1303 * Revision 1.153 2005/01/22 18:16:00 steve
1304 * Remove obsolete NetSubnet class.
1306 * Revision 1.152 2005/01/09 20:16:00 steve
1307 * Use PartSelect/PV and VP to handle part selects through ports.
1309 * Revision 1.151 2004/12/29 23:55:43 steve
1310 * Unify elaboration of l-values for all proceedural assignments,
1311 * including assing, cassign and force.
1313 * Generate NetConcat devices for gate outputs that feed into a
1314 * vector results. Use this to hande gate arrays. Also let gate
1315 * arrays handle vectors of gates when the outputs allow for it.
1317 * Revision 1.150 2004/12/11 02:31:25 steve
1318 * Rework of internals to carry vectors through nexus instead
1319 * of single bits. Make the ivl, tgt-vvp and vvp initial changes
1320 * down this path.
1322 * Revision 1.149 2004/10/04 01:10:52 steve
1323 * Clean up spurious trailing white space.
1325 * Revision 1.148 2004/05/31 23:34:36 steve
1326 * Rewire/generalize parsing an elaboration of
1327 * function return values to allow for better
1328 * speed and more type support.
1330 * Revision 1.147 2004/02/20 06:22:56 steve
1331 * parameter keys are per_strings.
1333 * Revision 1.146 2004/02/18 17:11:54 steve
1334 * Use perm_strings for named langiage items.
1336 * Revision 1.145 2003/12/17 16:52:39 steve
1337 * Debug dumps for synth2.
1339 * Revision 1.144 2003/07/26 03:34:42 steve
1340 * Start handling pad of expressions in code generators.
1342 * Revision 1.143 2003/07/05 20:42:08 steve
1343 * Fix some enumeration warnings.
1345 * Revision 1.142 2003/06/20 00:53:19 steve
1346 * Module attributes from the parser
1347 * through to elaborated form.
1349 * Revision 1.141 2003/06/18 03:55:18 steve
1350 * Add arithmetic shift operators.
1352 * Revision 1.140 2003/05/30 02:55:32 steve
1353 * Support parameters in real expressions and
1354 * as real expressions, and fix multiply and
1355 * divide with real results.
1357 * Revision 1.139 2003/04/22 04:48:29 steve
1358 * Support event names as expressions elements.
1360 * Revision 1.138 2003/03/10 23:40:53 steve
1361 * Keep parameter constants for the ivl_target API.
1363 * Revision 1.137 2003/01/27 05:09:17 steve
1364 * Spelling fixes.
1366 * Revision 1.136 2003/01/26 21:15:58 steve
1367 * Rework expression parsing and elaboration to
1368 * accommodate real/realtime values and expressions.
1370 * Revision 1.135 2002/10/23 01:47:17 steve
1371 * Fix synth2 handling of aset/aclr signals where
1372 * flip-flops are split by begin-end blocks.
1374 * Revision 1.134 2002/10/19 22:59:49 steve
1375 * Redo the parameter vector support to allow
1376 * parameter names in range expressions.
1378 * Revision 1.133 2002/08/19 00:06:11 steve
1379 * Allow release to handle removal of target net.
1381 * Revision 1.132 2002/08/13 05:35:00 steve
1382 * Do not elide named blocks.
1384 * Revision 1.131 2002/08/12 01:34:58 steve
1385 * conditional ident string using autoconfig.
1387 * Revision 1.130 2002/08/04 18:28:14 steve
1388 * Do not use hierarchical names of memories to
1389 * generate vvp labels. -tdll target does not
1390 * used hierarchical name string to look up the
1391 * memory objects in the design.
1393 * Revision 1.129 2002/06/19 04:20:03 steve
1394 * Remove NetTmp and add NetSubnet class.
1396 * Revision 1.128 2002/06/14 21:38:41 steve
1397 * Fix expression width for repeat concatenations.
1399 * Revision 1.127 2002/06/08 23:42:46 steve
1400 * Add NetRamDq synthsesis from memory l-values.
1402 * Revision 1.126 2002/06/05 03:44:25 steve
1403 * Add support for memory words in l-value of
1404 * non-blocking assignments, and remove the special
1405 * NetAssignMem_ and NetAssignMemNB classes.
1407 * Revision 1.125 2002/06/04 05:38:44 steve
1408 * Add support for memory words in l-value of
1409 * blocking assignments, and remove the special
1410 * NetAssignMem class.
1412 * Revision 1.124 2002/05/26 01:39:02 steve
1413 * Carry Verilog 2001 attributes with processes,
1414 * all the way through to the ivl_target API.
1416 * Divide signal reference counts between rval
1417 * and lval references.
1419 * Revision 1.123 2002/05/05 21:11:49 steve
1420 * Put off evaluation of concatenation repeat expresions
1421 * until after parameters are defined. This allows parms
1422 * to be used in repeat expresions.
1424 * Add the builtin $signed system function.
1426 * Revision 1.122 2002/03/09 02:10:22 steve
1427 * Add the NetUserFunc netlist node.
1429 * Revision 1.121 2001/12/31 00:03:05 steve
1430 * Include s indicator in dump of signed numbers.
1432 * Revision 1.120 2001/12/03 04:47:14 steve
1433 * Parser and pform use hierarchical names as hname_t
1434 * objects instead of encoded strings.
1436 * Revision 1.119 2001/11/19 01:46:38 steve
1437 * Print typename is fallback expression node dump.
1439 * Revision 1.118 2001/10/19 21:53:24 steve
1440 * Support multiple root modules (Philip Blundell)
1442 * Revision 1.117 2001/08/25 23:50:02 steve
1443 * Change the NetAssign_ class to refer to the signal
1444 * instead of link into the netlist. This is faster
1445 * and uses less space. Make the NetAssignNB carry
1446 * the delays instead of the NetAssign_ lval objects.
1448 * Change the vvp code generator to support multiple
1449 * l-values, i.e. concatenations of part selects.
1451 * Revision 1.116 2001/07/27 04:51:44 steve
1452 * Handle part select expressions as variants of
1453 * NetESignal/IVL_EX_SIGNAL objects, instead of
1454 * creating new and useless temporary signals.
1456 * Revision 1.115 2001/07/27 02:41:55 steve
1457 * Fix binding of dangling function ports. do not elide them.
1459 * Revision 1.114 2001/07/25 03:10:48 steve
1460 * Create a config.h.in file to hold all the config
1461 * junk, and support gcc 3.0. (Stephan Boettcher)
1463 * Revision 1.113 2001/04/29 20:19:10 steve
1464 * Add pullup and pulldown devices.
1466 * Revision 1.112 2001/04/22 23:09:46 steve
1467 * More UDP consolidation from Stephan Boettcher.
1469 * Revision 1.111 2001/02/17 05:13:36 steve
1470 * Check that the port really exists here.
1472 * Revision 1.110 2001/01/18 03:16:35 steve
1473 * NetMux needs a scope. (PR#115)
1475 * Revision 1.109 2001/01/13 22:20:08 steve
1476 * Parse parameters within nested scopes.
1478 * Revision 1.108 2000/12/16 01:45:47 steve
1479 * Detect recursive instantiations (PR#2)
1481 * Revision 1.107 2000/12/11 00:31:43 steve
1482 * Add support for signed reg variables,
1483 * simulate in t-vvm signed comparisons.
1485 * Revision 1.106 2000/12/10 06:41:59 steve
1486 * Support delays on continuous assignment from idents. (PR#40)
1488 * Revision 1.105 2000/12/04 17:37:03 steve
1489 * Add Attrib class for holding NetObj attributes.
1491 * Revision 1.104 2000/11/11 01:52:09 steve
1492 * change set for support of nmos, pmos, rnmos, rpmos, notif0, and notif1
1493 * change set to correct behavior of bufif0 and bufif1
1494 * (Tim Leight)
1496 * Also includes fix for PR#27
1498 * Revision 1.103 2000/11/11 00:03:36 steve
1499 * Add support for the t-dll backend grabing flip-flops.
1501 * Revision 1.102 2000/11/04 06:36:24 steve
1502 * Apply sequential UDP rework from Stephan Boettcher (PR#39)
1504 * Revision 1.101 2000/10/28 00:51:41 steve
1505 * Add scope to threads in vvm, pass that scope
1506 * to vpi sysTaskFunc objects, and add vpi calls
1507 * to access that information.
1509 * $display displays scope in %m (PR#1)
1511 * Revision 1.100 2000/10/07 19:45:42 steve
1512 * Put logic devices into scopes.
1514 * Revision 1.99 2000/10/06 23:46:50 steve
1515 * ivl_target updates, including more complete
1516 * handling of ivl_nexus_t objects. Much reduced
1517 * dependencies on pointers to netlist objects.
1519 * Revision 1.98 2000/09/26 01:35:42 steve
1520 * Remove the obsolete NetEIdent class.
1522 * Revision 1.97 2000/09/17 21:26:15 steve
1523 * Add support for modulus (Eric Aardoom)
1525 * Revision 1.96 2000/09/10 02:18:16 steve
1526 * elaborate complex l-values
1528 * Revision 1.95 2000/09/02 20:54:20 steve
1529 * Rearrange NetAssign to make NetAssign_ separate.
1531 * Revision 1.94 2000/07/30 18:25:43 steve
1532 * Rearrange task and function elaboration so that the
1533 * NetTaskDef and NetFuncDef functions are created during
1534 * signal enaboration, and carry these objects in the
1535 * NetScope class instead of the extra, useless map in
1536 * the Design class.
1538 * Revision 1.93 2000/07/29 03:55:38 steve
1539 * fix problem coalescing events w/ probes.
1541 * Revision 1.92 2000/07/27 05:13:44 steve
1542 * Support elaboration of disable statements.
1544 * Revision 1.91 2000/07/22 22:09:03 steve
1545 * Parse and elaborate timescale to scopes.
1547 * Revision 1.90 2000/07/14 06:12:57 steve
1548 * Move inital value handling from NetNet to Nexus
1549 * objects. This allows better propogation of inital
1550 * values.
1552 * Clean up constant propagation a bit to account
1553 * for regs that are not really values.
1555 * Revision 1.89 2000/07/07 04:53:53 steve
1556 * Add support for non-constant delays in delay statements,
1557 * Support evaluating ! in constant expressions, and
1558 * move some code from netlist.cc to net_proc.cc.
1560 * Revision 1.88 2000/06/25 19:59:42 steve
1561 * Redesign Links to include the Nexus class that
1562 * carries properties of the connected set of links.
1564 * Revision 1.87 2000/06/24 22:55:19 steve
1565 * Get rid of useless next_link method.
1567 * Revision 1.86 2000/06/13 03:24:48 steve
1568 * Index in memory assign should be a NetExpr.
1570 * Revision 1.85 2000/05/11 23:37:27 steve
1571 * Add support for procedural continuous assignment.
1573 * Revision 1.84 2000/05/07 18:20:07 steve
1574 * Import MCD support from Stephen Tell, and add
1575 * system function parameter support to the IVL core.
1577 * Revision 1.83 2000/05/07 04:37:56 steve
1578 * Carry strength values from Verilog source to the
1579 * pform and netlist for gates.
1581 * Change vvm constants to use the driver_t to drive
1582 * a constant value. This works better if there are
1583 * multiple drivers on a signal.
1585 * Revision 1.82 2000/05/04 03:37:58 steve
1586 * Add infrastructure for system functions, move
1587 * $time to that structure and add $random.
1589 * Revision 1.81 2000/05/02 03:13:30 steve
1590 * Move memories to the NetScope object.
1592 * Revision 1.80 2000/05/02 00:58:11 steve
1593 * Move signal tables to the NetScope class.
1595 * Revision 1.79 2000/04/28 21:00:29 steve
1596 * Over agressive signal elimination in constant probadation.
1598 * Revision 1.78 2000/04/23 03:45:24 steve
1599 * Add support for the procedural release statement.
1601 * Revision 1.77 2000/04/22 04:20:19 steve
1602 * Add support for force assignment.
1604 * Revision 1.76 2000/04/12 20:02:52 steve
1605 * Finally remove the NetNEvent and NetPEvent classes,
1606 * Get synthesis working with the NetEvWait class,
1607 * and get started supporting multiple events in a
1608 * wait in vvm.