1 /*
2  * Copyright (c) 1998-2019 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 provides the pform_dump function, that dumps the module
24  * passed as a parameter. The dump is as much as possible in Verilog
25  * syntax, so that a human can tell that it really does describe the
26  * module in question.
27  */
28 # include  "pform.h"
29 # include  "PClass.h"
30 # include  "PEvent.h"
31 # include  "PGenerate.h"
32 # include  "PPackage.h"
33 # include  "PSpec.h"
34 # include  "PTask.h"
35 # include  "discipline.h"
36 # include  "ivl_target_priv.h"
37 # include  <iostream>
38 # include  <iomanip>
39 # include  <typeinfo>
40 
operator <<(ostream & out,const PExpr & obj)41 ostream& operator << (ostream&out, const PExpr&obj)
42 {
43       obj.dump(out);
44       return out;
45 }
46 
operator <<(ostream & out,const PEventStatement & obj)47 ostream& operator << (ostream&out, const PEventStatement&obj)
48 {
49       obj.dump_inline(out);
50       return out;
51 }
52 
operator <<(ostream & o,const PDelays & d)53 ostream& operator << (ostream&o, const PDelays&d)
54 {
55       d.dump_delays(o);
56       return o;
57 }
58 
operator <<(ostream & out,const index_component_t & that)59 ostream& operator<< (ostream&out, const index_component_t&that)
60 {
61       out << "[";
62       switch (that.sel) {
63 	  case index_component_t::SEL_BIT:
64 	    out << *that.msb;
65 	    break;
66 	  case index_component_t::SEL_BIT_LAST:
67 	    out << "$";
68 	    break;
69 	  case index_component_t::SEL_PART:
70 	    out << *that.msb << ":" << *that.lsb;
71 	    break;
72 	  case index_component_t::SEL_IDX_UP:
73 	    out << *that.msb << "+:" << *that.lsb;
74 	    break;
75 	  case index_component_t::SEL_IDX_DO:
76 	    out << *that.msb << "-:" << *that.lsb;
77 	    break;
78 	  default:
79 	    out << "???";
80 	    break;
81       }
82       out << "]";
83       return out;
84 }
85 
operator <<(ostream & out,const name_component_t & that)86 ostream& operator<< (ostream&out, const name_component_t&that)
87 {
88       out << that.name.str();
89 
90       typedef std::list<index_component_t>::const_iterator index_it_t;
91       for (index_it_t idx = that.index.begin()
92 		 ; idx != that.index.end() ; ++ idx ) {
93 
94 	    out << *idx;
95       }
96       return out;
97 }
98 
operator <<(ostream & o,const pform_name_t & that)99 ostream& operator<< (ostream&o, const pform_name_t&that)
100 {
101       pform_name_t::const_iterator cur;
102       if (that.size() == 0) {
103 	    o << "<nil>";
104 	    return o;
105       }
106 
107       cur = that.begin();
108       o << *cur;
109 
110       ++ cur;
111       while (cur != that.end()) {
112 	    o << "." << *cur;
113 	    ++ cur;
114       }
115 
116       return o;
117 }
118 
operator <<(std::ostream & out,ivl_process_type_t pt)119 std::ostream& operator << (std::ostream&out, ivl_process_type_t pt)
120 {
121       switch (pt) {
122 	  case IVL_PR_INITIAL:
123 	    out << "initial";
124 	    break;
125 	  case IVL_PR_ALWAYS:
126 	    out << "always";
127 	    break;
128 	  case IVL_PR_ALWAYS_COMB:
129 	    out << "always_comb";
130 	    break;
131 	  case IVL_PR_ALWAYS_FF:
132 	    out << "always_ff";
133 	    break;
134 	  case IVL_PR_ALWAYS_LATCH:
135 	    out << "always_latch";
136 	    break;
137 	  case IVL_PR_FINAL:
138 	    out << "final";
139 	    break;
140       }
141       return out;
142 }
143 
operator <<(std::ostream & out,ivl_dis_domain_t dom)144 std::ostream& operator << (std::ostream&out, ivl_dis_domain_t dom)
145 {
146       switch (dom) {
147 	  case IVL_DIS_NONE:
148 	    out << "no-domain";
149 	    break;
150 	  case IVL_DIS_DISCRETE:
151 	    out << "discrete";
152 	    break;
153 	  case IVL_DIS_CONTINUOUS:
154 	    out << "continuous";
155 	    break;
156 	  default:
157 	    assert(0);
158 	    break;
159       }
160       return out;
161 }
162 
pform_dump(ostream & out,unsigned indent) const163 void data_type_t::pform_dump(ostream&out, unsigned indent) const
164 {
165       out << setw(indent) << "" << typeid(*this).name() << endl;
166 }
167 
pform_dump(ostream & out,unsigned indent) const168 void void_type_t::pform_dump(ostream&out, unsigned indent) const
169 {
170       out << setw(indent) << "" << "void" << endl;
171 }
172 
pform_dump(ostream & out,unsigned indent) const173 void parray_type_t::pform_dump(ostream&out, unsigned indent) const
174 {
175       out << setw(indent) << "" << "Packed array " << "[...]"
176 	  << " of:" << endl;
177       base_type->pform_dump(out, indent+4);
178 }
179 
pform_dump(ostream & out,unsigned indent) const180 void struct_type_t::pform_dump(ostream&out, unsigned indent) const
181 {
182       out << setw(indent) << "" << "Struct " << (packed_flag?"packed":"unpacked")
183 	  << " with " << (members.get()==0? 0 : members->size()) << " members" << endl;
184       if (members.get()==0)
185 	    return;
186 
187       for (list<struct_member_t*>::iterator cur = members->begin()
188 		 ; cur != members->end() ; ++ cur) {
189 	    struct_member_t*curp = *cur;
190 	    curp->pform_dump(out, indent+4);
191       }
192 }
193 
pform_dump(ostream & out,unsigned indent) const194 void uarray_type_t::pform_dump(ostream&out, unsigned indent) const
195 {
196       out << setw(indent) << "" << "Unpacked array " << "[...]"
197 	  << " of:" << endl;
198       base_type->pform_dump(out, indent+4);
199 }
200 
pform_dump(ostream & fd,unsigned indent) const201 void vector_type_t::pform_dump(ostream&fd, unsigned indent) const
202 {
203       fd << setw(indent) << "" << "vector of " << base_type;
204       if (pdims.get()) {
205 	    for (list<pform_range_t>::iterator cur = pdims->begin()
206 		       ; cur != pdims->end() ; ++cur) {
207 		  fd << "[";
208 		  if (cur->first)  fd << *(cur->first);
209 		  if (cur->second) fd << ":" << *(cur->second);
210 		  fd << "]";
211 	    }
212       }
213       fd << endl;
214 }
215 
pform_dump(ostream & out,unsigned indent) const216 void class_type_t::pform_dump(ostream&out, unsigned indent) const
217 {
218       out << setw(indent) << "" << "class " << name;
219 
220       if (base_type) out << " extends <type>";
221       if (! base_args.empty()) {
222 	    out << " (";
223 	    for (list<PExpr*>::const_iterator cur = base_args.begin()
224 		       ; cur != base_args.end() ; ++cur) {
225 		  const PExpr*curp = *cur;
226 		  if (cur != base_args.begin())
227 			out << ", ";
228 		  curp->dump(out);
229 	    }
230 	    out << ")";
231       }
232 
233       out << " {";
234       for (map<perm_string,prop_info_t>::const_iterator cur = properties.begin()
235 		 ; cur != properties.end() ; ++cur) {
236 	    out << " " << cur->first;
237       }
238 
239       out << " }" << endl;
240 
241       if (base_type) base_type->pform_dump(out, indent+4);
242 }
243 
pform_dump_init(ostream & out,unsigned indent) const244 void class_type_t::pform_dump_init(ostream&out, unsigned indent) const
245 {
246       for (vector<Statement*>::const_iterator cur = initialize.begin()
247 		 ; cur != initialize.end() ; ++cur) {
248 	    Statement*curp = *cur;
249 	    curp->dump(out,indent+4);
250       }
251 }
252 
pform_dump(ostream & out,unsigned indent) const253 void struct_member_t::pform_dump(ostream&out, unsigned indent) const
254 {
255       out << setw(indent) << "" << (type.get()? typeid(*type).name() : "<nil type>");
256       for (list<decl_assignment_t*>::iterator cur = names->begin()
257 		 ; cur != names->end() ; ++cur) {
258 	    decl_assignment_t*curp = *cur;
259 	    out << " " << curp->name;
260       }
261       out << ";" << endl;
262 }
263 
dump_attributes_map(ostream & out,const map<perm_string,PExpr * > & attributes,int ind)264 static void dump_attributes_map(ostream&out,
265 				const map<perm_string,PExpr*>&attributes,
266 				int ind)
267 {
268       for (map<perm_string,PExpr*>::const_iterator idx = attributes.begin()
269 		 ; idx != attributes.end() ; ++ idx ) {
270 
271 	    out << setw(ind) << "" << "(* " << (*idx).first;
272 	    if ((*idx).second) {
273 		  out << " = " << *(*idx).second;
274 	    }
275 	    out << " *)" << endl;
276       }
277 }
278 
dump(ostream & out) const279 void PExpr::dump(ostream&out) const
280 {
281       out << typeid(*this).name();
282 }
283 
dump(ostream & out) const284 void PEAssignPattern::dump(ostream&out) const
285 {
286       out << "'{";
287       if (parms_.size() > 0) {
288 	    parms_[0]->dump(out);
289 	    for (size_t idx = 1 ; idx < parms_.size() ; idx += 1) {
290 		  out << ", ";
291 		  parms_[idx]->dump(out);
292 	    }
293       }
294       out << "}";
295 }
296 
dump(ostream & out) const297 void PEConcat::dump(ostream&out) const
298 {
299       if (repeat_)
300 	    out << "{" << *repeat_;
301 
302       if (parms_.empty()) {
303 	    out << "{}";
304 	    return;
305       }
306 
307       out << "{";
308       if (parms_[0]) out << *parms_[0];
309       for (unsigned idx = 1 ;  idx < parms_.size() ;  idx += 1) {
310 	    out << ", ";
311 	    if (parms_[idx]) out << *parms_[idx];
312       }
313 
314       out << "}";
315 
316       if (repeat_) out << "}";
317 }
318 
dump(ostream & out) const319 void PECallFunction::dump(ostream &out) const
320 {
321       if (package_) out << package_->pscope_name() << "::";
322 
323       out << path_ << "(";
324 
325       if (! parms_.empty()) {
326 	    if (parms_[0]) parms_[0]->dump(out);
327 	    for (unsigned idx = 1; idx < parms_.size(); ++idx) {
328 		  out << ", ";
329 		  if (parms_[idx]) parms_[idx]->dump(out);
330 	    }
331       }
332       out << ")";
333 }
334 
dump(ostream & out) const335 void PECastSize::dump(ostream &out) const
336 {
337       out << *size_ << "'(";
338       base_->dump(out);
339       out << ")";
340 }
341 
dump(ostream & out) const342 void PECastType::dump(ostream &out) const
343 {
344       target_->pform_dump(out, 0);
345       out << "'(";
346       base_->dump(out);
347       out << ")";
348 }
349 
dump(ostream & out) const350 void PEEvent::dump(ostream&out) const
351 {
352       switch (type_) {
353 	  case PEEvent::ANYEDGE:
354 	    break;
355 	  case PEEvent::POSEDGE:
356 	    out << "posedge ";
357 	    break;
358 	  case PEEvent::NEGEDGE:
359 	    out << "negedge ";
360 	    break;
361 	  case PEEvent::POSITIVE:
362 	    out << "positive ";
363 	    break;
364       }
365       out << *expr_;
366 
367 }
368 
dump(ostream & out) const369 void PEFNumber::dump(ostream &out) const
370 {
371       out << value();
372 }
373 
dump(ostream & out) const374 void PENewArray::dump(ostream&out) const
375 {
376       out << "new [" << *size_ << "]";
377       if (init_)
378 	    out << "(" << *init_ << ")";
379 }
380 
dump(ostream & out) const381 void PENewClass::dump(ostream&out) const
382 {
383       out << "class_new(";
384       if (parms_.size() > 0) {
385 	    parms_[0]->dump(out);
386 	    for (size_t idx = 1 ; idx < parms_.size() ; idx += 1) {
387 		  out << ", ";
388 		  if (parms_[idx]) parms_[idx]->dump(out);
389 	    }
390       }
391       out << ")";
392 }
393 
dump(ostream & out) const394 void PENewCopy::dump(ostream&out) const
395 {
396       out << "copy_new(";
397       src_->dump(out);
398       out << ")";
399 }
400 
dump(ostream & out) const401 void PENull::dump(ostream&out) const
402 {
403       out << "null";
404 }
405 
dump(ostream & out) const406 void PENumber::dump(ostream&out) const
407 {
408       out << value();
409 }
410 
dump(ostream & out) const411 void PEIdent::dump(ostream&out) const
412 {
413       if (package_)
414 	    out << package_->pscope_name() << "::";
415       out << path_;
416 }
417 
dump(ostream & out) const418 void PEString::dump(ostream&out) const
419 {
420       out << "\"" << text_ << "\"";
421 }
422 
dump(ostream & out) const423 void PETernary::dump(ostream&out) const
424 {
425       out << "(" << *expr_ << ")?(" << *tru_ << "):(" << *fal_ << ")";
426 }
427 
dump(ostream & fd) const428 void PETypename::dump(ostream&fd) const
429 {
430       fd << "<type>";
431 }
432 
dump(ostream & out) const433 void PEUnary::dump(ostream&out) const
434 {
435       switch (op_) {
436 	  case 'm':
437 	    out << "abs";
438 	    break;
439 	  default:
440 	    out << op_;
441 	    break;
442       }
443       out << "(" << *expr_ << ")";
444 }
445 
dump(ostream & out) const446 void PEBinary::dump(ostream&out) const
447 {
448 	/* Handle some special cases, where the operators are written
449 	   in function notation. */
450       if (op_ == 'm') {
451 	    out << "min(" << *left_ << "," << *right_ << ")";
452 	    return;
453       }
454       if (op_ == 'M') {
455 	    out << "min(" << *left_ << "," << *right_ << ")";
456 	    return;
457       }
458 
459       if (left_)
460 	    out << "(" << *left_ << ")";
461       else
462 	    out << "(<nil>)";
463       switch (op_) {
464 	  case 'a':
465 	    out << "&&";
466 	    break;
467 	  case 'e':
468 	    out << "==";
469 	    break;
470 	  case 'E':
471 	    out << "===";
472 	    break;
473 	  case 'l':
474 	    out << "<<";
475 	    break;
476 	  case 'L':
477 	    out << "<=";
478 	    break;
479 	  case 'n':
480 	    out << "!=";
481 	    break;
482 	  case 'N':
483 	    out << "!==";
484 	    break;
485 	  case 'p':
486 	    out << "**";
487 	    break;
488 	  case 'R':
489 	    out << ">>>";
490 	    break;
491 	  case 'r':
492 	    out << ">>";
493 	    break;
494 	  default:
495 	    out << op_;
496 	    break;
497       }
498       if (right_)
499 	    out << "(" << *right_ << ")";
500       else
501 	    out << "(<nil>)";
502 }
503 
504 
dump(ostream & out,unsigned ind) const505 void PWire::dump(ostream&out, unsigned ind) const
506 {
507       out << setw(ind) << "" << type_;
508 
509       switch (port_type_) {
510 	  case NetNet::PIMPLICIT:
511 	    out << " implicit input";
512 	    break;
513 	  case NetNet::PINPUT:
514 	    out << " input";
515 	    break;
516 	  case NetNet::POUTPUT:
517 	    out << " output";
518 	    break;
519 	  case NetNet::PINOUT:
520 	    out << " inout";
521 	    break;
522 	  case NetNet::PREF:
523 	    out << " ref";
524 	    break;
525 	  case NetNet::NOT_A_PORT:
526 	    break;
527       }
528 
529       out << " " << data_type_;
530 
531       if (signed_) {
532 	    out << " signed";
533       }
534       if (get_isint()) {
535 	    out << " integer";
536       }
537       if (get_scalar()) {
538 	    out << " scalar";
539       }
540       if (set_data_type_) {
541 	    out << " set_data_type_=" << typeid(*set_data_type_).name();
542       }
543 
544       if (discipline_) {
545 	    out << " discipline<" << discipline_->name() << ">";
546       }
547 
548       if (port_set_) {
549 	    if (port_.empty()) {
550 		  out << " port<scalar>";
551 	    } else {
552 		  out << " port";
553 		  for (list<pform_range_t>::const_iterator cur = port_.begin()
554 			     ; cur != port_.end() ; ++cur) {
555 			out << "[";
556 			if (cur->first)  out << *cur->first;
557 			if (cur->second) out << ":" << *cur->second;
558 			out << "]";
559 		  }
560 	    }
561       }
562       if (net_set_) {
563 	    if (net_.empty()) {
564 		  out << " net<scalar>";
565 	    } else {
566 		  out << " net";
567 		  for (list<pform_range_t>::const_iterator cur = net_.begin()
568 			     ; cur != net_.end() ; ++cur) {
569 			out << "[";
570 			if (cur->first)  out << *cur->first;
571 			if (cur->second) out << ":" << *cur->second;
572 			out << "]";
573 		  }
574 	    }
575       }
576 
577       out << " " << name_;
578 
579 	// If the wire has unpacked indices, dump them.
580       for (list<pform_range_t>::const_iterator cur = unpacked_.begin()
581 		 ; cur != unpacked_.end() ; ++cur) {
582 	    out << "[";
583 	    if (cur->first) out << *cur->first;
584 	    if (cur->second) out << ":" << *cur->second;
585 	    out << "]";
586       }
587 
588       out << ";" << endl;
589       if (set_data_type_) {
590 	    set_data_type_->pform_dump(out, 8);
591       }
592 
593       dump_attributes_map(out, attributes, 8);
594 }
595 
dump_pins(ostream & out) const596 void PGate::dump_pins(ostream&out) const
597 {
598       if (pin_count()) {
599 	    if (pin(0)) out << *pin(0);
600 
601 	    for (unsigned idx = 1 ;  idx < pin_count() ;  idx += 1) {
602 		  out << ", ";
603 		  if (pin(idx)) out << *pin(idx);
604 	    }
605       }
606 }
607 
dump_delays(ostream & out) const608 void PDelays::dump_delays(ostream&out) const
609 {
610       if (delay_[0] && delay_[1] && delay_[2])
611 	    out << "#(" << *delay_[0] << "," << *delay_[1] << "," <<
612 		  *delay_[2] << ")";
613       else if (delay_[0] && delay_[1])
614 	    out << "#(" << *delay_[0] << "," << *delay_[1] << ")";
615       else if (delay_[0])
616 	    out << "#" << *delay_[0];
617       else
618 	    out << "#0";
619 
620 }
621 
dump_delays(ostream & out) const622 void PGate::dump_delays(ostream&out) const
623 {
624       delay_.dump_delays(out);
625 }
626 
dump(ostream & out,unsigned ind) const627 void PGate::dump(ostream&out, unsigned ind) const
628 {
629       out << setw(ind) << "" << typeid(*this).name() << " ";
630       delay_.dump_delays(out);
631       out << " " << get_name() << "(";
632       dump_pins(out);
633       out << ");" << endl;
634 
635 }
636 
dump(ostream & out,unsigned ind) const637 void PGAssign::dump(ostream&out, unsigned ind) const
638 {
639       out << setw(ind) << "";
640       out << "assign (" << strength0() << "0 " << strength1() << "1) ";
641       dump_delays(out);
642       out << " " << *pin(0) << " = " << *pin(1) << ";" << endl;
643 }
644 
dump(ostream & out,unsigned ind) const645 void PGBuiltin::dump(ostream&out, unsigned ind) const
646 {
647       out << setw(ind) << "";
648       switch (type()) {
649 	  case PGBuiltin::BUFIF0:
650 	    out << "bufif0 ";
651 	    break;
652 	  case PGBuiltin::BUFIF1:
653 	    out << "bufif1 ";
654 	    break;
655 	  case PGBuiltin::NOTIF0:
656 	    out << "notif0 ";
657 	    break;
658 	  case PGBuiltin::NOTIF1:
659 	    out << "notif1 ";
660 	    break;
661 	  case PGBuiltin::NAND:
662 	    out << "nand ";
663 	    break;
664 	  case PGBuiltin::NMOS:
665 	    out << "nmos ";
666 	    break;
667 	  case PGBuiltin::RNMOS:
668 	    out << "rnmos ";
669 	    break;
670 	  case PGBuiltin::RPMOS:
671 	    out << "rpmos ";
672 	    break;
673 	  case PGBuiltin::PMOS:
674 	    out << "pmos ";
675 	    break;
676 	  case PGBuiltin::RCMOS:
677 	    out << "rcmos ";
678 	    break;
679 	  case PGBuiltin::CMOS:
680 	    out << "cmos ";
681 	    break;
682 	  default:
683 	    out << "builtin gate ";
684       }
685 
686       out << "(" << strength0() << "0 " << strength1() << "1) ";
687       dump_delays(out);
688       out << " " << get_name();
689 
690       if (msb_) {
691 	    out << " [" << *msb_ << ":" << *lsb_ << "]";
692       }
693 
694       out << "(";
695       dump_pins(out);
696       out << ");" << endl;
697 }
698 
dump(ostream & out,unsigned ind) const699 void PGModule::dump(ostream&out, unsigned ind) const
700 {
701       out << setw(ind) << "" << type_ << " ";
702 
703 	// If parameters are overridden by order, dump them.
704       if (overrides_ && (! overrides_->empty())) {
705 	    assert(parms_ == 0);
706             out << "#(";
707 
708 	    list<PExpr*>::const_iterator idx = overrides_->begin();
709 
710 	    if (*idx == 0)
711 		  out << "<nil>";
712 	    else
713 		  out << *idx;
714 	    for ( ;  idx != overrides_->end() ;  ++ idx) {
715 	          out << "," << *idx;
716 	    }
717 	    out << ") ";
718       }
719 
720 	// If parameters are overridden by name, dump them.
721       if (parms_) {
722 	    assert(overrides_ == 0);
723 	    out << "#(";
724 	    for (unsigned idx = 0 ;  idx < nparms_ ;  idx += 1) {
725                   if (idx > 0) out << ", ";
726 		  out << "." << parms_[idx].name << "(";
727                   if (parms_[idx].parm) out << *parms_[idx].parm;
728                   out << ")";
729 	    }
730 	    out << ") ";
731       }
732 
733       out << get_name();
734 
735 	// If the module is arrayed, print the index expressions.
736       if (msb_ || lsb_) {
737 	    out << "[";
738 	    if (msb_) out << *msb_;
739 	    out << ":";
740 	    if (lsb_) out << *lsb_;
741 	    out << "]";
742       }
743 
744       out << "(";
745       if (pins_) {
746 	    out << "." << pins_[0].name << "(";
747 	    if (pins_[0].parm) out << *pins_[0].parm;
748 	    out << ")";
749 	    for (unsigned idx = 1 ;  idx < npins_ ;  idx += 1) {
750 		  out << ", ." << pins_[idx].name << "(";
751 		  if (pins_[idx].parm)
752 			out << *pins_[idx].parm;
753 		  out << ")";
754 	    }
755       } else {
756 	    dump_pins(out);
757       }
758       out << ");" << endl;
759       dump_attributes_map(out, attributes, 8);
760 }
761 
dump(ostream & out,unsigned ind) const762 void Statement::dump(ostream&out, unsigned ind) const
763 {
764 	/* I give up. I don't know what type this statement is,
765 	   so just print the C++ typeid and let the user figure
766 	   it out. */
767       out << setw(ind) << "";
768       out << "/* " << get_fileline() << ": " << typeid(*this).name()
769 	  << " */ ;" << endl;
770       dump_attributes_map(out, attributes, ind+2);
771 }
772 
dump(ostream & out,unsigned ind) const773 void AContrib::dump(ostream&out, unsigned ind) const
774 {
775       out << setw(ind) << "";
776       out << *lval_ << " <+ " << *rval_
777 	  << "; /* " << get_fileline() << " */"
778 	  << endl;
779 }
780 
dump(ostream & out,unsigned ind) const781 void PAssign::dump(ostream&out, unsigned ind) const
782 {
783       out << setw(ind) << "";
784       if (lval()) out << *lval();
785       else out << "<dummy>";
786       out << " = ";
787       if (delay_) out << "#" << *delay_ << " ";
788       if (count_) out << "repeat(" << *count_ << ") ";
789       if (event_) out << *event_ << " ";
790       PExpr*rexpr = rval();
791       if (rexpr) out << *rval() << ";";
792       else out << "<no rval>;";
793       out << "  /* " << get_fileline() << " */" << endl;
794 }
795 
dump(ostream & out,unsigned ind) const796 void PAssignNB::dump(ostream&out, unsigned ind) const
797 {
798       out << setw(ind) << "" << *lval() << " <= ";
799       if (delay_) out << "#" << *delay_ << " ";
800       if (count_) out << "repeat(" << *count_ << ") ";
801       if (event_) out << *event_ << " ";
802       out << *rval() << ";" << "  /* " << get_fileline() << " */" << endl;
803 }
804 
dump(ostream & out,unsigned ind) const805 void PBlock::dump(ostream&out, unsigned ind) const
806 {
807       out << setw(ind) << "" << "begin";
808       if (pscope_name() != 0)
809 	    out << " : " << pscope_name();
810       out << endl;
811 
812       if (pscope_name() != 0) {
813             dump_parameters_(out, ind+2);
814 
815             dump_localparams_(out, ind+2);
816 
817             dump_events_(out, ind+2);
818 
819 	    dump_wires_(out, ind+2);
820 
821 	    dump_var_inits_(out, ind+2);
822       }
823 
824       for (unsigned idx = 0 ;  idx < list_.size() ;  idx += 1) {
825 	    if (list_[idx])
826 		  list_[idx]->dump(out, ind+2);
827 	    else
828 		  out << setw(ind+2) << "" << "/* NOOP */ ;" << endl;
829       }
830 
831       out << setw(ind) << "" << "end" << endl;
832 }
833 
dump(ostream & out,unsigned ind) const834 void PCallTask::dump(ostream&out, unsigned ind) const
835 {
836       out << setw(ind) << "" << path_;
837 
838       if (! parms_.empty()) {
839 	    out << "(";
840 	    if (parms_[0])
841 		  out << *parms_[0];
842 
843 	    for (unsigned idx = 1 ;  idx < parms_.size() ;  idx += 1) {
844 		  out << ", ";
845 		  if (parms_[idx])
846 			out << *parms_[idx];
847 	    }
848 	    out << ")";
849       }
850 
851       out << "; /* " << get_fileline() << " */" << endl;
852 }
853 
dump(ostream & out,unsigned ind) const854 void PCase::dump(ostream&out, unsigned ind) const
855 {
856       out << setw(ind) << "";
857       switch (quality_) {
858 	  case IVL_CASE_QUALITY_BASIC:
859 	    break;
860 	  case IVL_CASE_QUALITY_UNIQUE:
861 	    out << "unique ";
862 	    break;
863 	  case IVL_CASE_QUALITY_UNIQUE0:
864 	    out << "unique0 ";
865 	    break;
866 	  case IVL_CASE_QUALITY_PRIORITY:
867 	    out << "priority ";
868 	    break;
869       }
870       switch (type_) {
871 	  case NetCase::EQ:
872 	    out << "case";
873 	    break;
874 	  case NetCase::EQX:
875 	    out << "casex";
876 	    break;
877 	  case NetCase::EQZ:
878 	    out << "casez";
879 	    break;
880       }
881       out << " (" << *expr_ << ") /* " << get_fileline() << " */" << endl;
882       dump_attributes_map(out, attributes, ind+2);
883 
884       for (unsigned idx = 0 ;  idx < items_->count() ;  idx += 1) {
885 	    PCase::Item*cur = (*items_)[idx];
886 
887 	    if (! cur->expr.empty()) {
888 		  out << setw(ind+2) << "" << "default:";
889 
890 	    } else {
891 		  list<PExpr*>::iterator idx_exp = cur->expr.begin();
892 		  out << setw(ind+2) << "" << *idx_exp;
893 
894 		  for( ; idx_exp != cur->expr.end() ; ++idx_exp)
895 			out << ", " << *idx_exp;
896 
897 		  out << ":";
898 	    }
899 
900 	    if (cur->stat) {
901 		  out << endl;
902 		  cur->stat->dump(out, ind+6);
903 	    } else {
904 		  out << " ;" << endl;
905 	    }
906       }
907 
908       out << setw(ind) << "" << "endcase" << endl;
909 }
910 
dump(ostream & out,unsigned ind) const911 void PChainConstructor::dump(ostream&out, unsigned ind) const
912 {
913       out << setw(ind) << "" << "super.new(";
914       if (parms_.size() > 0) {
915 	    if (parms_[0]) out << *parms_[0];
916       }
917       for (size_t idx = 1 ; idx < parms_.size() ; idx += 1) {
918 	    out << ", ";
919 	    if (parms_[idx]) out << *parms_[idx];
920       }
921       out << ");" << endl;
922 }
923 
dump(ostream & out,unsigned ind) const924 void PCondit::dump(ostream&out, unsigned ind) const
925 {
926       out << setw(ind) << "" << "if (" << *expr_ << ")" << endl;
927       if (if_)
928 	    if_->dump(out, ind+3);
929       else
930 	    out << setw(ind) << ";" << endl;
931       if (else_) {
932 	    out << setw(ind) << "" << "else" << endl;
933 	    else_->dump(out, ind+3);
934       }
935 }
936 
dump(ostream & out,unsigned ind) const937 void PCAssign::dump(ostream&out, unsigned ind) const
938 {
939       out << setw(ind) << "" << "assign " << *lval_ << " = " << *expr_
940 	  << "; /* " << get_fileline() << " */" << endl;
941 }
942 
dump(ostream & out,unsigned ind) const943 void PDeassign::dump(ostream&out, unsigned ind) const
944 {
945       out << setw(ind) << "" << "deassign " << *lval_ << "; /* "
946 	  << get_fileline() << " */" << endl;
947 }
948 
dump(ostream & out,unsigned ind) const949 void PDelayStatement::dump(ostream&out, unsigned ind) const
950 {
951       out << setw(ind) << "" << "#" << *delay_ << " /* " <<
952 	    get_fileline() << " */";
953       if (statement_) {
954 	    out << endl;
955 	    statement_->dump(out, ind+2);
956       } else {
957 	    out << " /* noop */;" << endl;
958       }
959 }
960 
dump(ostream & out,unsigned ind) const961 void PDisable::dump(ostream&out, unsigned ind) const
962 {
963       out << setw(ind) << "" << "disable ";
964       if (scope_.empty()) out << scope_;
965       else out << "fork";
966       out << "; /* " << get_fileline() << " */" << endl;
967 }
968 
dump(ostream & out,unsigned ind) const969 void PDoWhile::dump(ostream&out, unsigned ind) const
970 {
971       out << setw(ind) << "" << "do" << endl;
972       if (statement_)
973 	    statement_->dump(out, ind+3);
974       else
975 	    out << setw(ind+3) << "" << "/* NOOP */" << endl;
976       out << setw(ind) << "" << "while (" << *cond_ << ");" << endl;
977 }
978 
dump(ostream & out,unsigned ind) const979 void PEventStatement::dump(ostream&out, unsigned ind) const
980 {
981       if (expr_.count() == 0) {
982 	    out << setw(ind) << "" << "@* ";
983 
984       } else if ((expr_.count() == 1) && (expr_[0] == 0)) {
985 	    out << setw(ind) << "" << "wait fork ";
986 
987       } else {
988 	    out << setw(ind) << "" << "@(" << *(expr_[0]);
989 	    if (expr_.count() > 1)
990 		  for (unsigned idx = 1 ;  idx < expr_.count() ;  idx += 1)
991 			out << " or " << *(expr_[idx]);
992 
993 	    out << ")";
994       }
995 
996       if (statement_) {
997 	    out << endl;
998 	    statement_->dump(out, ind+2);
999       } else {
1000 	    out << " ;" << endl;
1001       }
1002 }
1003 
dump_inline(ostream & out) const1004 void PEventStatement::dump_inline(ostream&out) const
1005 {
1006       assert(statement_ == 0);
1007 
1008       if (expr_.count() == 0) {
1009 	    out << "@* ";
1010 
1011       } else {
1012 	    out << "@(" << *(expr_[0]);
1013 	    if (expr_.count() > 1)
1014 		  for (unsigned idx = 1 ;  idx < expr_.count() ;  idx += 1)
1015 			out << " or " << *(expr_[idx]);
1016 
1017 	    out << ")";
1018       }
1019 }
1020 
dump(ostream & out,unsigned ind) const1021 void PForce::dump(ostream&out, unsigned ind) const
1022 {
1023       out << setw(ind) << "" << "force " << *lval_ << " = " << *expr_
1024 	  << "; /* " << get_fileline() << " */" << endl;
1025 }
1026 
dump(ostream & fd,unsigned ind) const1027 void PForeach::dump(ostream&fd, unsigned ind) const
1028 {
1029       fd << setw(ind) << "" << "foreach "
1030 	 << "variable=" << array_var_
1031 	 << ", indices=[";
1032       for (size_t idx = 0 ; idx < index_vars_.size() ; idx += 1) {
1033 	    if (idx > 0) fd << ",";
1034 	    fd << index_vars_[idx];
1035       }
1036 
1037       fd << "] /* " << get_fileline() << " */" << endl;
1038       if (statement_)
1039 	    statement_->dump(fd, ind+3);
1040       else
1041 	    fd << setw(ind+3) << "" << "/* NOOP */" << endl;
1042 }
1043 
dump(ostream & out,unsigned ind) const1044 void PForever::dump(ostream&out, unsigned ind) const
1045 {
1046       out << setw(ind) << "" << "forever /* " << get_fileline() << " */" << endl;
1047       if (statement_)
1048 	    statement_->dump(out, ind+3);
1049       else
1050 	    out << setw(ind+3) << "" << "/* NOOP */" << endl;
1051 }
1052 
dump(ostream & out,unsigned ind) const1053 void PForStatement::dump(ostream&out, unsigned ind) const
1054 {
1055       out << setw(ind) << "" << "for (" << *name1_ << " = " << *expr1_
1056 	  << "; " << *cond_ << "; <for_step>)" << endl;
1057       step_->dump(out, ind+6);
1058       if (statement_)
1059 	    statement_->dump(out, ind+3);
1060       else
1061 	    out << setw(ind+3) << "" << "/* NOOP */" << endl;
1062 }
1063 
dump(ostream & out,unsigned ind) const1064 void PFunction::dump(ostream&out, unsigned ind) const
1065 {
1066       out << setw(ind) << "" << "function ";
1067       if (is_auto_) out << "automatic ";
1068 
1069       out << pscope_name() << ";" << endl;
1070       if (method_of())
1071 	    out << setw(ind) << "" << "method of " << method_of()->name << ";" << endl;
1072 
1073       if (return_type_)
1074 	    return_type_->pform_dump(out, ind+8);
1075       else
1076 	    out << setw(ind+8) << "" << "<implicit type>" << endl;
1077 
1078       dump_ports_(out, ind+2);
1079 
1080       dump_parameters_(out, ind+2);
1081 
1082       dump_localparams_(out, ind+2);
1083 
1084       dump_events_(out, ind+2);
1085 
1086       dump_wires_(out, ind+2);
1087 
1088       dump_var_inits_(out, ind+2);
1089 
1090       if (statement_)
1091 	    statement_->dump(out, ind+2);
1092       else
1093 	    out << setw(ind+2) << "" << "/* NOOP */" << endl;
1094 }
1095 
dump(ostream & out,unsigned ind) const1096 void PRelease::dump(ostream&out, unsigned ind) const
1097 {
1098       out << setw(ind) << "" << "release " << *lval_ << "; /* "
1099 	  << get_fileline() << " */" << endl;
1100 }
1101 
dump(ostream & out,unsigned ind) const1102 void PRepeat::dump(ostream&out, unsigned ind) const
1103 {
1104       out << setw(ind) << "" << "repeat (" << *expr_ << ")" << endl;
1105       if (statement_)
1106 	    statement_->dump(out, ind+3);
1107       else
1108 	    out << setw(ind+3) << "" << "/* NOOP */" << endl;
1109 }
1110 
dump(ostream & fd,unsigned ind) const1111 void PReturn::dump(ostream&fd, unsigned ind) const
1112 {
1113       fd << setw(ind) << "" << "return (";
1114       if (expr_) fd << *expr_;
1115       fd << ")" << endl;
1116 }
1117 
dump(ostream & out,unsigned ind) const1118 void PTask::dump(ostream&out, unsigned ind) const
1119 {
1120       out << setw(ind) << "" << "task ";
1121       if (is_auto_) out << "automatic ";
1122       out << pscope_name() << ";" << endl;
1123       if (method_of())
1124 	    out << setw(ind) << "" << "method of " << method_of()->name << ";" << endl;
1125       dump_ports_(out, ind+2);
1126 
1127       dump_parameters_(out, ind+2);
1128 
1129       dump_localparams_(out, ind+2);
1130 
1131       dump_events_(out, ind+2);
1132 
1133       dump_wires_(out, ind+2);
1134 
1135       dump_var_inits_(out, ind+2);
1136 
1137       if (statement_)
1138 	    statement_->dump(out, ind+2);
1139       else
1140 	    out << setw(ind+2) << "" << "/* NOOP */" << endl;
1141 }
1142 
dump_ports_(std::ostream & out,unsigned ind) const1143 void PTaskFunc::dump_ports_(std::ostream&out, unsigned ind) const
1144 {
1145       if (ports_ == 0)
1146 	    return;
1147 
1148       for (unsigned idx = 0 ; idx < ports_->size() ; idx += 1) {
1149 	    if (ports_->at(idx).port == 0) {
1150 		  out << setw(ind) << "" << "ERROR PORT" << endl;
1151 		  continue;
1152 	    }
1153 
1154 	    out << setw(ind) << "";
1155 	    switch (ports_->at(idx).port->get_port_type()) {
1156 		case NetNet::PINPUT:
1157 		  out << "input ";
1158 		  break;
1159 		case NetNet::POUTPUT:
1160 		  out << "output ";
1161 		  break;
1162 		case NetNet::PINOUT:
1163 		  out << "inout ";
1164 		  break;
1165 		case NetNet::PIMPLICIT:
1166 		  out << "PIMPLICIT";
1167 		  break;
1168 		case NetNet::NOT_A_PORT:
1169 		  out << "NOT_A_PORT";
1170 		  break;
1171 		default:
1172 		  assert(0);
1173 		  break;
1174 	    }
1175 	    out << ports_->at(idx).port->basename();
1176 	    if (ports_->at(idx).defe) {
1177 		  out << " = " << *ports_->at(idx).defe;
1178 	    }
1179 	    out << ";" << endl;
1180       }
1181 }
1182 
dump(ostream & out,unsigned ind) const1183 void PTrigger::dump(ostream&out, unsigned ind) const
1184 {
1185       out << setw(ind) << "" << "-> " << event_ << ";" << endl;
1186 }
1187 
dump(ostream & out,unsigned ind) const1188 void PWhile::dump(ostream&out, unsigned ind) const
1189 {
1190       out << setw(ind) << "" << "while (" << *cond_ << ")" << endl;
1191       if (statement_)
1192 	    statement_->dump(out, ind+3);
1193       else
1194 	    out << setw(ind+3) << "" << "/* NOOP */" << endl;
1195 }
1196 
dump(ostream & out,unsigned ind) const1197 void PProcess::dump(ostream&out, unsigned ind) const
1198 {
1199       out << setw(ind) << "" << type_
1200 	  << " /* " << get_fileline() << " */" << endl;
1201 
1202       dump_attributes_map(out, attributes, ind+2);
1203 
1204       if (statement_)
1205 	    statement_->dump(out, ind+2);
1206       else
1207 	    out << setw(ind+2) << "" << "/* NOOP */" << endl;
1208 }
1209 
dump(ostream & out,unsigned ind) const1210 void AProcess::dump(ostream&out, unsigned ind) const
1211 {
1212       switch (type_) {
1213 	  case IVL_PR_INITIAL:
1214 	    out << setw(ind) << "" << "analog initial";
1215 	    break;
1216 	  case IVL_PR_ALWAYS:
1217 	    out << setw(ind) << "" << "analog";
1218 	    break;
1219 	  case IVL_PR_ALWAYS_COMB:
1220 	  case IVL_PR_ALWAYS_FF:
1221 	  case IVL_PR_ALWAYS_LATCH:
1222 	    assert(0);
1223 	    break;
1224 	  case IVL_PR_FINAL:
1225 	    out << setw(ind) << "" << "analog final";
1226 	    break;
1227       }
1228 
1229       out << " /* " << get_fileline() << " */" << endl;
1230 
1231       dump_attributes_map(out, attributes, ind+2);
1232 
1233       if (statement_)
1234 	    statement_->dump(out, ind+2);
1235       else
1236 	    out << setw(ind+2) << "" << "/* NOOP */" << endl;
1237 }
1238 
dump(std::ostream & out,unsigned ind) const1239 void PSpecPath::dump(std::ostream&out, unsigned ind) const
1240 {
1241       out << setw(ind) << "" << "specify path ";
1242 
1243       if (condition)
1244 	    out << "if (" << *condition << ") ";
1245 
1246       out << "(";
1247       if (edge) {
1248 	    if (edge > 0)
1249 		  out << "posedge ";
1250 	    else
1251 		  out << "negedge ";
1252       }
1253 
1254       for (unsigned idx = 0 ;  idx < src.size() ;  idx += 1) {
1255 	    if (idx > 0) out << ", ";
1256 	    assert(src[idx]);
1257 	    out << src[idx];
1258       }
1259 
1260       out << " ";
1261       if (polarity_) out << polarity_;
1262       if (full_flag_) out << "*> ";
1263       else out << "=> ";
1264 
1265       if (data_source_expression)
1266 	    out << "(";
1267 
1268       for (unsigned idx = 0 ; idx < dst.size() ;  idx += 1) {
1269 	    if (idx > 0) out << ", ";
1270 	    assert(dst[idx]);
1271 	    out << dst[idx];
1272       }
1273 
1274       if (data_source_expression)
1275 	    out << " : " << *data_source_expression << ")";
1276 
1277       out << ") = (";
1278       for (unsigned idx = 0 ;  idx < delays.size() ;  idx += 1) {
1279 	    if (idx > 0) out << ", ";
1280 	    assert(delays[idx]);
1281 	    out << *delays[idx];
1282       }
1283       out << ");" << endl;
1284 }
1285 
dump(ostream & out,unsigned indent) const1286 void PGenerate::dump(ostream&out, unsigned indent) const
1287 {
1288       out << setw(indent) << "" << "generate(" << id_number << ")";
1289 
1290       PGenerate*parent = dynamic_cast<PGenerate*>(parent_scope());
1291       switch (scheme_type) {
1292 	  case GS_NONE:
1293 	    break;
1294 	  case GS_LOOP:
1295 	    out << " for ("
1296 		<< loop_index
1297 		<< "=" << *loop_init
1298 		<< "; " << *loop_test
1299 		<< "; " << loop_index
1300 		<< "=" << *loop_step << ")";
1301 	    break;
1302 	  case GS_CONDIT:
1303 	    out << " if (" << *loop_test << ")";
1304 	    break;
1305 	  case GS_ELSE:
1306 	    out << " else !(" << *loop_test << ")";
1307 	    break;
1308 	  case GS_CASE:
1309 	    out << " case (" << *loop_test << ")";
1310 	    break;
1311 	  case GS_CASE_ITEM:
1312             assert(parent);
1313 	    if (loop_test)
1314 		  out << " (" << *loop_test << ") == (" << *parent->loop_test << ")";
1315 	    else
1316 		  out << " default:";
1317 	    break;
1318 	  case GS_NBLOCK:
1319 	    out << " begin";
1320       }
1321 
1322       if (scope_name)
1323 	    out << " : " << scope_name;
1324 
1325       out << endl;
1326 
1327       dump_localparams_(out, indent+2);
1328 
1329       typedef list<PGenerate::named_expr_t>::const_iterator parm_hiter_t;
1330       for (parm_hiter_t cur = defparms.begin()
1331 		 ; cur != defparms.end() ;  ++ cur ) {
1332 	    out << setw(indent+2) << "" << "defparam " << (*cur).first << " = ";
1333 	    if ((*cur).second)
1334 		  out << *(*cur).second << ";" << endl;
1335 	    else
1336 		  out << "/* ERROR */;" << endl;
1337       }
1338 
1339       dump_events_(out, indent+2);
1340 
1341       dump_wires_(out, indent+2);
1342 
1343       for (list<PGate*>::const_iterator idx = gates.begin()
1344 		 ; idx != gates.end() ; ++ idx ) {
1345 	    (*idx)->dump(out, indent+2);
1346       }
1347 
1348       dump_var_inits_(out, indent+2);
1349 
1350       for (list<PProcess*>::const_iterator idx = behaviors.begin()
1351 		 ; idx != behaviors.end() ; ++ idx ) {
1352 	    (*idx)->dump(out, indent+2);
1353       }
1354 
1355       for (list<AProcess*>::const_iterator idx = analog_behaviors.begin()
1356 		 ; idx != analog_behaviors.end() ; ++ idx ) {
1357 	    (*idx)->dump(out, indent+2);
1358       }
1359 
1360       typedef map<perm_string,LineInfo*>::const_iterator genvar_iter_t;
1361       for (genvar_iter_t cur = genvars.begin()
1362 		 ; cur != genvars.end() ; ++ cur ) {
1363 	    out << setw(indent+2) << "" << "genvar " << ((*cur).first) << ";" << endl;
1364       }
1365 
1366       for (list<PGenerate*>::const_iterator idx = generate_schemes.begin()
1367 		 ; idx != generate_schemes.end() ; ++ idx ) {
1368 	    (*idx)->dump(out, indent+2);
1369       }
1370 
1371       if (scheme_type == GS_NBLOCK) {
1372 	    out << setw(indent) << "" << "end endgenerate" << endl;
1373       } else {
1374 	    out << setw(indent) << "" << "endgenerate" << endl;
1375       }
1376 }
1377 
dump_typedefs_(ostream & out,unsigned indent) const1378 void LexicalScope::dump_typedefs_(ostream&out, unsigned indent) const
1379 {
1380       typedef map<perm_string,data_type_t*>::const_iterator iter_t;
1381       for (iter_t cur = typedefs.begin() ; cur != typedefs.end() ; ++ cur) {
1382 	    out << setw(indent) << "" << "typedef of " << cur->first << ":" << endl;
1383 	    cur->second->pform_dump(out, indent+4);
1384       }
1385 }
1386 
dump_parameters_(ostream & out,unsigned indent) const1387 void LexicalScope::dump_parameters_(ostream&out, unsigned indent) const
1388 {
1389       typedef map<perm_string,param_expr_t*>::const_iterator parm_iter_t;
1390       for (parm_iter_t cur = parameters.begin()
1391 		 ; cur != parameters.end() ; ++ cur ) {
1392 	    out << setw(indent) << "" << "parameter "
1393                 << (*cur).second->type << " ";
1394 	    if ((*cur).second->signed_flag)
1395 		  out << "signed ";
1396 	    if ((*cur).second->msb)
1397 		  out << "[" << *(*cur).second->msb << ":"
1398 		      << *(*cur).second->lsb << "] ";
1399 	    out << (*cur).first << " = ";
1400 	    if ((*cur).second->expr)
1401 		  out << *(*cur).second->expr;
1402 	    else
1403 		  out << "/* ERROR */";
1404 	    for (LexicalScope::range_t*tmp = (*cur).second->range
1405 		       ; tmp ; tmp = tmp->next) {
1406 		  if (tmp->exclude_flag)
1407 			out << " exclude ";
1408 		  else
1409 			out << " from ";
1410 		  if (tmp->low_open_flag)
1411 			out << "(";
1412 		  else
1413 			out << "[";
1414 		  if (tmp->low_expr)
1415 			out << *(tmp->low_expr);
1416 		  else if (tmp->low_open_flag==false)
1417 			out << "-inf";
1418 		  else
1419 			out << "<nil>";
1420 		  out << ":";
1421 		  if (tmp->high_expr)
1422 			out << *(tmp->high_expr);
1423 		  else if (tmp->high_open_flag==false)
1424 			out << "inf";
1425 		  else
1426 			out << "<nil>";
1427 		  if (tmp->high_open_flag)
1428 			out << ")";
1429 		  else
1430 			out << "]";
1431 	    }
1432 	    out << ";" << endl;
1433       }
1434 }
1435 
dump_localparams_(ostream & out,unsigned indent) const1436 void LexicalScope::dump_localparams_(ostream&out, unsigned indent) const
1437 {
1438       typedef map<perm_string,param_expr_t*>::const_iterator parm_iter_t;
1439       for (parm_iter_t cur = localparams.begin()
1440 		 ; cur != localparams.end() ; ++ cur ) {
1441 	    out << setw(indent) << "" << "localparam ";
1442 	    if ((*cur).second->msb)
1443 		  out << "[" << *(*cur).second->msb << ":"
1444 		      << *(*cur).second->lsb << "] ";
1445 	    out << (*cur).first << " = ";
1446 	    if ((*cur).second->expr)
1447 		  out << *(*cur).second->expr << ";" << endl;
1448 	    else
1449 		  out << "/* ERROR */;" << endl;
1450       }
1451 }
1452 
dump_enumerations_(ostream & out,unsigned indent) const1453 void LexicalScope::dump_enumerations_(ostream&out, unsigned indent) const
1454 {
1455       for (set<enum_type_t*>::const_iterator cur = enum_sets.begin()
1456 		 ; cur != enum_sets.end() ; ++ cur) {
1457 	    out << setw(indent) << "" << "enum {" << endl;
1458 
1459 	    for (list<named_pexpr_t>::const_iterator idx = (*cur)->names->begin()
1460 		       ; idx != (*cur)->names->end() ; ++ idx) {
1461 		  out << setw(indent+4) << "" << idx->name
1462 		      << " = " << idx->parm << endl;
1463 	    }
1464 
1465 	    out << setw(indent) << "" << "}" << endl;
1466       }
1467 }
1468 
dump_events_(ostream & out,unsigned indent) const1469 void LexicalScope::dump_events_(ostream&out, unsigned indent) const
1470 {
1471       for (map<perm_string,PEvent*>::const_iterator cur = events.begin()
1472 		 ; cur != events.end() ; ++ cur ) {
1473 	    PEvent*ev = (*cur).second;
1474 	    out << setw(indent) << "" << "event " << ev->name() << "; // "
1475 		<< ev->get_fileline() << endl;
1476       }
1477 }
1478 
dump_wires_(ostream & out,unsigned indent) const1479 void LexicalScope::dump_wires_(ostream&out, unsigned indent) const
1480 {
1481 	// Iterate through and display all the wires.
1482       for (map<perm_string,PWire*>::const_iterator wire = wires.begin()
1483 		 ; wire != wires.end() ; ++ wire ) {
1484 
1485 	    (*wire).second->dump(out, indent);
1486       }
1487 }
1488 
dump_var_inits_(ostream & out,unsigned indent) const1489 void LexicalScope::dump_var_inits_(ostream&out, unsigned indent) const
1490 {
1491 	// Iterate through and display all the register initializations.
1492       for (unsigned idx = 0; idx < var_inits.size(); idx += 1) {
1493 	    var_inits[idx]->dump(out, indent);
1494       }
1495 }
1496 
dump_classes_(ostream & out,unsigned indent) const1497 void PScopeExtra::dump_classes_(ostream&out, unsigned indent) const
1498 {
1499 	// Dump the task definitions.
1500       typedef map<perm_string,PClass*>::const_iterator class_iter_t;
1501       for (class_iter_t cur = classes.begin()
1502 		 ; cur != classes.end() ; ++ cur ) {
1503 	    cur->second->dump(out, indent);
1504       }
1505 }
1506 
dump_tasks_(ostream & out,unsigned indent) const1507 void PScopeExtra::dump_tasks_(ostream&out, unsigned indent) const
1508 {
1509 	// Dump the task definitions.
1510       typedef map<perm_string,PTask*>::const_iterator task_iter_t;
1511       for (task_iter_t cur = tasks.begin()
1512 		 ; cur != tasks.end() ; ++ cur ) {
1513 	    out << setw(indent) << "" << "task " << (*cur).first << ";" << endl;
1514 	    (*cur).second->dump(out, indent+2);
1515 	    out << setw(indent) << "" << "endtask;" << endl;
1516       }
1517 }
1518 
dump_funcs_(ostream & out,unsigned indent) const1519 void PScopeExtra::dump_funcs_(ostream&out, unsigned indent) const
1520 {
1521 	// Dump the task definitions.
1522       typedef map<perm_string,PFunction*>::const_iterator task_iter_t;
1523       for (task_iter_t cur = funcs.begin()
1524 		 ; cur != funcs.end() ; ++ cur ) {
1525 	    out << setw(indent) << "" << "function " << (*cur).first << ";" << endl;
1526 	    (*cur).second->dump(out, indent+2);
1527 	    out << setw(indent) << "" << "endfunction;" << endl;
1528       }
1529 }
1530 
dump(ostream & out,unsigned indent) const1531 void PClass::dump(ostream&out, unsigned indent) const
1532 {
1533       out << setw(indent) << "" << "class " << type->name << ";" << endl;
1534       type->pform_dump(out, indent+2);
1535       type->pform_dump_init(out, indent+2);
1536       dump_tasks_(out, indent+2);
1537       dump_funcs_(out, indent+2);
1538       out << setw(indent) << "" << "endclass" << endl;
1539 }
1540 
dump_specparams_(ostream & out,unsigned indent) const1541 void Module::dump_specparams_(ostream&out, unsigned indent) const
1542 {
1543       typedef map<perm_string,param_expr_t*>::const_iterator parm_iter_t;
1544       for (parm_iter_t cur = specparams.begin()
1545 		 ; cur != specparams.end() ; ++ cur ) {
1546 	    out << setw(indent) << "" << "specparam ";
1547 	    if ((*cur).second->msb)
1548 		  out << "[" << *(*cur).second->msb << ":"
1549 		      << *(*cur).second->lsb << "] ";
1550 	    out << (*cur).first << " = ";
1551 	    if ((*cur).second->expr)
1552 		  out << *(*cur).second->expr << ";" << endl;
1553 	    else
1554 		  out << "/* ERROR */;" << endl;
1555       }
1556 }
1557 
dump(ostream & out) const1558 void Module::dump(ostream&out) const
1559 {
1560       if (attributes.begin() != attributes.end()) {
1561 	    out << "(* ";
1562 	    for (map<perm_string,PExpr*>::const_iterator idx = attributes.begin()
1563 		 ; idx != attributes.end() ; ++ idx ) {
1564 		    if (idx != attributes.begin()) {
1565 			out << " , ";
1566 		    }
1567 		    out << (*idx).first;
1568 		    if ((*idx).second) {
1569 			out << " = " << *(*idx).second;
1570 		    }
1571 	    }
1572 	    out << " *)  ";
1573       }
1574 
1575       out << "module " << mod_name() << ";";
1576       if (is_cell) out << "  // Is in `celldefine.";
1577       out << endl;
1578 
1579       for (unsigned idx = 0 ;  idx < ports.size() ;  idx += 1) {
1580 	    port_t*cur = ports[idx];
1581 
1582 	    if (cur == 0) {
1583 		  out << "    unconnected" << endl;
1584 		  continue;
1585 	    }
1586 
1587 	    out << "    ." << cur->name << "(" << *cur->expr[0];
1588 	    for (unsigned wdx = 1 ;  wdx < cur->expr.size() ;  wdx += 1) {
1589 		  out << ", " << *cur->expr[wdx];
1590 	    }
1591 
1592 	    out << ")" << endl;
1593       }
1594 
1595       for (map<perm_string,Module*>::const_iterator cur = nested_modules.begin()
1596 		 ; cur != nested_modules.end() ; ++cur) {
1597 	    out << setw(4) << "" << "Nested module " << cur->first << ";" << endl;
1598       }
1599 
1600       dump_typedefs_(out, 4);
1601 
1602       dump_parameters_(out, 4);
1603 
1604       dump_localparams_(out, 4);
1605 
1606       dump_specparams_(out, 4);
1607 
1608       dump_enumerations_(out, 4);
1609 
1610       dump_classes_(out, 4);
1611 
1612       typedef map<perm_string,LineInfo*>::const_iterator genvar_iter_t;
1613       for (genvar_iter_t cur = genvars.begin()
1614 		 ; cur != genvars.end() ; ++ cur ) {
1615 	    out << "    genvar " << ((*cur).first) << ";" << endl;
1616       }
1617 
1618       typedef list<PGenerate*>::const_iterator genscheme_iter_t;
1619       for (genscheme_iter_t cur = generate_schemes.begin()
1620 		 ; cur != generate_schemes.end() ; ++ cur ) {
1621 	    (*cur)->dump(out, 4);
1622       }
1623 
1624       typedef list<Module::named_expr_t>::const_iterator parm_hiter_t;
1625       for (parm_hiter_t cur = defparms.begin()
1626 		 ; cur != defparms.end() ;  ++ cur ) {
1627 	    out << "    defparam " << (*cur).first << " = ";
1628 	    if ((*cur).second)
1629 		  out << *(*cur).second << ";" << endl;
1630 	    else
1631 		  out << "/* ERROR */;" << endl;
1632       }
1633 
1634       dump_events_(out, 4);
1635 
1636 	// Iterate through and display all the wires.
1637       dump_wires_(out, 4);
1638 
1639 	// Dump the task definitions.
1640       dump_tasks_(out, 4);
1641 
1642 	// Dump the function definitions.
1643       dump_funcs_(out, 4);
1644 
1645 
1646 	// Iterate through and display all the gates
1647       for (list<PGate*>::const_iterator gate = gates_.begin()
1648 		 ; gate != gates_.end() ; ++ gate ) {
1649 
1650 	    (*gate)->dump(out);
1651       }
1652 
1653       dump_var_inits_(out, 4);
1654 
1655       for (list<PProcess*>::const_iterator behav = behaviors.begin()
1656 		 ; behav != behaviors.end() ; ++ behav ) {
1657 
1658 	    (*behav)->dump(out, 4);
1659       }
1660 
1661       for (list<AProcess*>::const_iterator idx = analog_behaviors.begin()
1662 		 ; idx != analog_behaviors.end() ; ++ idx) {
1663 	    (*idx)->dump(out, 4);
1664       }
1665 
1666       for (list<PSpecPath*>::const_iterator spec = specify_paths.begin()
1667 		 ; spec != specify_paths.end() ; ++ spec ) {
1668 
1669 	    (*spec)->dump(out, 4);
1670       }
1671 
1672       out << "endmodule" << endl;
1673 }
1674 
pform_dump(ostream & out,Module * mod)1675 void pform_dump(ostream&out, Module*mod)
1676 {
1677       mod->dump(out);
1678 }
1679 
dump(ostream & out) const1680 void PUdp::dump(ostream&out) const
1681 {
1682       out << "primitive " << name_ << "(" << ports[0];
1683       for (unsigned idx = 1 ;  idx < ports.count() ;  idx += 1)
1684 	    out << ", " << ports[idx];
1685       out << ");" << endl;
1686 
1687       if (sequential)
1688 	    out << "    reg " << ports[0] << ";" << endl;
1689 
1690       out << "    table" << endl;
1691       for (unsigned idx = 0 ;  idx < tinput.count() ;  idx += 1) {
1692 	    out << "     ";
1693 	    for (unsigned chr = 0 ;  chr < tinput[idx].length() ;  chr += 1)
1694 		  out << " " << tinput[idx][chr];
1695 
1696 	    if (sequential)
1697 		  out << " : " << tcurrent[idx];
1698 
1699 	    out << " : " << toutput[idx] << " ;" << endl;
1700       }
1701       out << "    endtable" << endl;
1702 
1703       if (sequential)
1704 	    out << "    initial " << ports[0] << " = 1'b" << initial
1705 		<< ";" << endl;
1706 
1707 	// Dump the attributes for the primitive as attribute
1708 	// statements.
1709       for (map<string,PExpr*>::const_iterator idx = attributes.begin()
1710 		 ; idx != attributes.end() ; ++ idx ) {
1711 	    out << "    attribute " << (*idx).first;
1712 	    if ((*idx).second)
1713 		  out << " = " << *(*idx).second;
1714 	    out << endl;
1715       }
1716 
1717       out << "endprimitive" << endl;
1718 }
1719 
pform_dump(std::ostream & out,const ivl_nature_s * nat)1720 void pform_dump(std::ostream&out, const ivl_nature_s*nat)
1721 {
1722       out << "nature " << nat->name() << endl;
1723       out << "    access " << nat->access() << ";" << endl;
1724       out << "endnature" << endl;
1725 }
1726 
pform_dump(std::ostream & out,const ivl_discipline_s * dis)1727 void pform_dump(std::ostream&out, const ivl_discipline_s*dis)
1728 {
1729       out << "discipline " << dis->name() << endl;
1730       out << "    domain " << dis->domain() << ";" << endl;
1731       if (const ivl_nature_s*tmp = dis->potential())
1732 	    out << "    potential " << tmp->name() << ";" << endl;
1733       if (const ivl_nature_s*tmp = dis->flow())
1734 	    out << "    flow " << tmp->name() << ";" << endl;
1735       out << "enddiscipline" << endl;
1736 }
1737 
pform_dump(std::ostream & fd,const PClass * cl)1738 void pform_dump(std::ostream&fd, const PClass*cl)
1739 {
1740       cl->dump(fd, 0);
1741 }
1742 
pform_dump(std::ostream & out,const PPackage * pac)1743 void pform_dump(std::ostream&out, const PPackage*pac)
1744 {
1745       pac->pform_dump(out);
1746 }
1747 
pform_dump(std::ostream & out) const1748 void PPackage::pform_dump(std::ostream&out) const
1749 {
1750       out << "package " << pscope_name() << endl;
1751       dump_localparams_(out, 4);
1752       dump_parameters_(out, 4);
1753       dump_typedefs_(out, 4);
1754       dump_enumerations_(out, 4);
1755       dump_wires_(out, 4);
1756       dump_tasks_(out, 4);
1757       dump_funcs_(out, 4);
1758       dump_var_inits_(out, 4);
1759       out << "endpackage" << endl;
1760 }
1761 
pform_dump(std::ostream & fd,const PTaskFunc * obj)1762 void pform_dump(std::ostream&fd, const PTaskFunc*obj)
1763 {
1764       obj->dump(fd, 0);
1765 }
1766