1 /*
2  * Copyright (c) 1998-2020 Stephen Williams (steve@icarus.com)
3  * Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
4  *
5  *    This source code is free software; you can redistribute it
6  *    and/or modify it in source code form under the terms of the GNU
7  *    General Public License as published by the Free Software
8  *    Foundation; either version 2 of the License, or (at your option)
9  *    any later version.
10  *
11  *    This program is distributed in the hope that it will be useful,
12  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *    GNU General Public License for more details.
15  *
16  *    You should have received a copy of the GNU General Public License
17  *    along with this program; if not, write to the Free Software
18  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
21 # include "config.h"
22 
23 /*
24  * Elaboration takes as input a complete parse tree and the name of a
25  * root module, and generates as output the elaborated design. This
26  * elaborated design is presented as a Module, which does not
27  * reference any other modules. It is entirely self contained.
28  */
29 
30 # include  <typeinfo>
31 # include  <cstdlib>
32 # include  <iostream>
33 # include  <sstream>
34 # include  <list>
35 # include  "pform.h"
36 # include  "PClass.h"
37 # include  "PEvent.h"
38 # include  "PGenerate.h"
39 # include  "PPackage.h"
40 # include  "PScope.h"
41 # include  "PSpec.h"
42 # include  "netlist.h"
43 # include  "netenum.h"
44 # include  "netvector.h"
45 # include  "netdarray.h"
46 # include  "netparray.h"
47 # include  "netclass.h"
48 # include  "netmisc.h"
49 # include  "util.h"
50 # include  "parse_api.h"
51 # include  "compiler.h"
52 # include  "ivl_assert.h"
53 
54 
55 // Implemented in elab_scope.cc
56 extern void set_scope_timescale(Design*des, NetScope*scope, PScope*pscope);
57 
elaborate(Design *,NetScope *) const58 void PGate::elaborate(Design*, NetScope*) const
59 {
60       cerr << "internal error: what kind of gate? " <<
61 	    typeid(*this).name() << endl;
62 }
63 
64 /*
65  * Elaborate the continuous assign. (This is *not* the procedural
66  * assign.) Elaborate the lvalue and rvalue, and do the assignment.
67  */
elaborate(Design * des,NetScope * scope) const68 void PGAssign::elaborate(Design*des, NetScope*scope) const
69 {
70       assert(scope);
71 
72       NetExpr* rise_time, *fall_time, *decay_time;
73       eval_delays(des, scope, rise_time, fall_time, decay_time, true);
74 
75       ivl_drive_t drive0 = strength0();
76       ivl_drive_t drive1 = strength1();
77 
78       assert(pin(0));
79       assert(pin(1));
80 
81 	/* Elaborate the l-value. */
82       NetNet*lval = pin(0)->elaborate_lnet(des, scope);
83       if (lval == 0) {
84 	    return;
85       }
86 
87 	// If this turns out to be an assignment to an unpacked array,
88 	// then handle that special case elsewhere.
89       if (lval->pin_count() > 1) {
90 	    elaborate_unpacked_array_(des, scope, lval);
91 	    return;
92       }
93 
94       ivl_assert(*this, lval->pin_count() == 1);
95 
96       if (debug_elaborate) {
97 	    cerr << get_fileline() << ": PGAssign::elaborate: elaborated l-value"
98 		 << " width=" << lval->vector_width()
99 		 << ", pin_count=" << lval->pin_count() << endl;
100       }
101 
102       NetExpr*rval_expr = elaborate_rval_expr(des, scope, lval->net_type(),
103 					      lval->data_type(),
104 					      lval->vector_width(), pin(1));
105 
106       if (rval_expr == 0) {
107 	    cerr << get_fileline() << ": error: Unable to elaborate r-value: "
108 		 << *pin(1) << endl;
109 	    des->errors += 1;
110 	    return;
111       }
112 
113       NetNet*rval = rval_expr->synthesize(des, scope, rval_expr);
114 
115       if (rval == 0) {
116 	    cerr << get_fileline() << ": internal error: "
117 		 << "Failed to synthesize expression: " << *rval_expr << endl;
118 	    des->errors += 1;
119 	    return;
120       }
121 
122       if (debug_elaborate) {
123 	    cerr << get_fileline() << ": debug: PGAssign: elaborated r-value"
124 		 << " width="<< rval->vector_width()
125 		 << ", type="<< rval->data_type()
126 		 << ", expr=" << *rval_expr << endl;
127       }
128 
129       ivl_assert(*this, lval && rval);
130       ivl_assert(*this, rval->pin_count() == 1);
131 
132 	// Detect the case that the rvalue-expression is a simple
133 	// expression. In this case, we will need to create a driver
134 	// (later) to carry strengths.
135       bool need_driver_flag = false;
136       if (dynamic_cast<NetESignal*>(rval_expr))
137 	    need_driver_flag = true;
138 
139 	// expression elaboration should have caused the rval width to
140 	// match the l-value by now.
141       if (rval->vector_width() < lval->vector_width()) {
142 	    cerr << get_fileline() << ": internal error: "
143 		 << "lval-rval width mismatch: "
144 		 << "rval->vector_width()==" << rval->vector_width()
145 		 << ", lval->vector_width()==" << lval->vector_width() << endl;
146       }
147       ivl_assert(*this, rval->vector_width() >= lval->vector_width());
148 
149 	/* If the r-value insists on being larger than the l-value,
150 	   use a part select to chop it down down to size. */
151       if (lval->vector_width() < rval->vector_width()) {
152 	    NetPartSelect*tmp = new NetPartSelect(rval, 0,lval->vector_width(),
153 						  NetPartSelect::VP);
154 	    des->add_node(tmp);
155 	    tmp->set_line(*this);
156 	    netvector_t*osig_vec = new netvector_t(rval->data_type(),
157 						   lval->vector_width()-1,0);
158 	    NetNet*osig = new NetNet(scope, scope->local_symbol(),
159 				     NetNet::TRI, osig_vec);
160 	    osig->set_line(*this);
161 	    osig->local_flag(true);
162 	    connect(osig->pin(0), tmp->pin(0));
163 	    rval = osig;
164 	    need_driver_flag = false;
165       }
166 
167 	/* When we are given a non-default strength value and if the drive
168 	 * source is a bit, part, indexed select or a concatenation we need
169 	 * to add a driver (BUFZ) to convey the strength information. */
170       if ((drive0 != IVL_DR_STRONG || drive1 != IVL_DR_STRONG) &&
171           ((dynamic_cast<NetESelect*>(rval_expr)) ||
172 	   (dynamic_cast<NetEConcat*>(rval_expr)))) {
173 	    need_driver_flag = true;
174       }
175 
176       if (need_driver_flag) {
177 	    NetBUFZ*driver = new NetBUFZ(scope, scope->local_symbol(),
178 					 rval->vector_width(), false);
179 	    driver->set_line(*this);
180 	    des->add_node(driver);
181 
182 	    connect(rval->pin(0), driver->pin(1));
183 
184 	    netvector_t*tmp_vec = new netvector_t(rval->data_type(),
185 						  rval->vector_width()-1,0);
186 	    NetNet*tmp = new NetNet(scope, scope->local_symbol(),
187 				    NetNet::WIRE, tmp_vec);
188 	    tmp->set_line(*this);
189 	    tmp->local_flag(true);
190 
191 	    connect(driver->pin(0), tmp->pin(0));
192 
193 	    rval = tmp;
194       }
195 
196 	/* Set the drive and delays for the r-val. */
197 
198       if (drive0 != IVL_DR_STRONG || drive1 != IVL_DR_STRONG)
199 	    rval->pin(0).drivers_drive(drive0, drive1);
200 
201       if (rise_time || fall_time || decay_time)
202 	    rval->pin(0).drivers_delays(rise_time, fall_time, decay_time);
203 
204       connect(lval->pin(0), rval->pin(0));
205 
206       if (lval->local_flag())
207 	    delete lval;
208 
209 }
210 
elaborate_unpacked_array_(Design * des,NetScope * scope,NetNet * lval) const211 void PGAssign::elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval) const
212 {
213       PEIdent*rval_pident = dynamic_cast<PEIdent*> (pin(1));
214       ivl_assert(*this, rval_pident);
215 
216       NetNet*rval_net = rval_pident->elaborate_unpacked_net(des, scope);
217 
218       ivl_assert(*this, rval_net->pin_count() == lval->pin_count());
219 
220       assign_unpacked_with_bufz(des, scope, this, lval, rval_net);
221 }
222 
calculate_array_count_(Design * des,NetScope * scope,long & high,long & low) const223 unsigned PGBuiltin::calculate_array_count_(Design*des, NetScope*scope,
224 					   long&high, long&low) const
225 {
226       unsigned count = 1;
227       high = 0;
228       low = 0;
229 
230 	/* If the Verilog source has a range specification for the
231 	   gates, then I am expected to make more than one
232 	   gate. Figure out how many are desired. */
233       if (msb_) {
234 	    NetExpr*msb_exp = elab_and_eval(des, scope, msb_, -1, true);
235 	    NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_, -1, true);
236 
237 	    NetEConst*msb_con = dynamic_cast<NetEConst*>(msb_exp);
238 	    NetEConst*lsb_con = dynamic_cast<NetEConst*>(lsb_exp);
239 
240 	    if (msb_con == 0) {
241 		  cerr << get_fileline() << ": error: Unable to evaluate "
242 			"expression " << *msb_ << endl;
243 		  des->errors += 1;
244 		  return 0;
245 	    }
246 
247 	    if (lsb_con == 0) {
248 		  cerr << get_fileline() << ": error: Unable to evaluate "
249 			"expression " << *lsb_ << endl;
250 		  des->errors += 1;
251 		  return 0;
252 	    }
253 
254 	    verinum msb = msb_con->value();
255 	    verinum lsb = lsb_con->value();
256 
257 	    delete msb_exp;
258 	    delete lsb_exp;
259 
260 	    if (msb.as_long() > lsb.as_long())
261 		  count = msb.as_long() - lsb.as_long() + 1;
262 	    else
263 		  count = lsb.as_long() - msb.as_long() + 1;
264 
265 	    low = lsb.as_long();
266 	    high = msb.as_long();
267 
268 	    if (debug_elaborate) {
269 		  cerr << get_fileline() << ": debug: PGBuiltin: Make array "
270 		       << "[" << high << ":" << low << "]" << " of "
271 		       << count << " gates for " << get_name() << endl;
272 	    }
273       }
274 
275       return count;
276 }
277 
calculate_gate_and_lval_count_(unsigned & gate_count,unsigned & lval_count) const278 void PGBuiltin::calculate_gate_and_lval_count_(unsigned&gate_count,
279                                                unsigned&lval_count) const
280 {
281       switch (type()) {
282 	  case BUF:
283 	  case NOT:
284 	    if (pin_count() > 2) gate_count = pin_count() - 1;
285 	    else gate_count = 1;
286             lval_count = gate_count;
287 	    break;
288 	  case PULLDOWN:
289 	  case PULLUP:
290 	    gate_count = pin_count();
291             lval_count = gate_count;
292 	    break;
293 	  case TRAN:
294 	  case RTRAN:
295 	  case TRANIF0:
296 	  case TRANIF1:
297 	  case RTRANIF0:
298 	  case RTRANIF1:
299 	    gate_count = 1;
300             lval_count = 2;
301 	    break;
302 	  default:
303 	    gate_count = 1;
304             lval_count = 1;
305 	    break;
306       }
307 }
308 
create_gate_for_output_(Design * des,NetScope * scope,perm_string inst_name,unsigned instance_width) const309 NetNode* PGBuiltin::create_gate_for_output_(Design*des, NetScope*scope,
310 					    perm_string inst_name,
311 					    unsigned instance_width) const
312 {
313       NetNode*gate = 0;
314 
315       switch (type()) {
316 
317 	  case AND:
318 	    if (pin_count() < 2) {
319 		  cerr << get_fileline() << ": error: the AND "
320 			"primitive must have an input." << endl;
321 		  des->errors += 1;
322 	    } else {
323 		  gate = new NetLogic(scope, inst_name, pin_count(),
324 				      NetLogic::AND, instance_width);
325 	    }
326 	    break;
327 
328 	  case BUF:
329 	    if (pin_count() < 2) {
330 		  cerr << get_fileline() << ": error: the BUF "
331 			"primitive must have an input." << endl;
332 		  des->errors += 1;
333 	    } else {
334 		  gate = new NetLogic(scope, inst_name, 2,
335 		                      NetLogic::BUF, instance_width);
336 	    }
337 	    break;
338 
339 	  case BUFIF0:
340 	    if (pin_count() != 3) {
341 		  cerr << get_fileline() << ": error: the BUFIF0 "
342 			"primitive must have three arguments." << endl;
343 		  des->errors += 1;
344 	    } else {
345 		  gate = new NetLogic(scope, inst_name, pin_count(),
346 					  NetLogic::BUFIF0, instance_width);
347 	    }
348 	    break;
349 
350 	  case BUFIF1:
351 	    if (pin_count() != 3) {
352 		  cerr << get_fileline() << ": error: the BUFIF1 "
353 			"primitive must have three arguments." << endl;
354 		  des->errors += 1;
355 	    } else {
356 		  gate = new NetLogic(scope, inst_name, pin_count(),
357 					  NetLogic::BUFIF1, instance_width);
358 	    }
359 	    break;
360 
361 	  case CMOS:
362 	    if (pin_count() != 4) {
363 		  cerr << get_fileline() << ": error: the CMOS "
364 			"primitive must have four arguments." << endl;
365 		  des->errors += 1;
366 	    } else {
367 		  gate = new NetLogic(scope, inst_name, pin_count(),
368 				      NetLogic::CMOS, instance_width);
369 	    }
370 	    break;
371 
372 	  case NAND:
373 	    if (pin_count() < 2) {
374 		  cerr << get_fileline() << ": error: the NAND "
375 			"primitive must have an input." << endl;
376 		  des->errors += 1;
377 	    } else {
378 		  gate = new NetLogic(scope, inst_name, pin_count(),
379 				      NetLogic::NAND, instance_width);
380 	    }
381 	    break;
382 
383 	  case NMOS:
384 	    if (pin_count() != 3) {
385 		  cerr << get_fileline() << ": error: the NMOS "
386 			"primitive must have three arguments." << endl;
387 		  des->errors += 1;
388 	    } else {
389 		  gate = new NetLogic(scope, inst_name, pin_count(),
390 				      NetLogic::NMOS, instance_width);
391 	    }
392 	    break;
393 
394 	  case NOR:
395 	    if (pin_count() < 2) {
396 		  cerr << get_fileline() << ": error: the NOR "
397 			"primitive must have an input." << endl;
398 		  des->errors += 1;
399 	    } else {
400 		  gate = new NetLogic(scope, inst_name, pin_count(),
401 				      NetLogic::NOR, instance_width);
402 	    }
403 	    break;
404 
405 	  case NOT:
406 	    if (pin_count() < 2) {
407 		  cerr << get_fileline() << ": error: the NOT "
408 			"primitive must have an input." << endl;
409 		  des->errors += 1;
410 	    } else {
411 		  gate = new NetLogic(scope, inst_name, 2,
412 		                      NetLogic::NOT, instance_width);
413 	    }
414 	    break;
415 
416 	  case NOTIF0:
417 	    if (pin_count() != 3) {
418 		  cerr << get_fileline() << ": error: the NOTIF0 "
419 			"primitive must have three arguments." << endl;
420 		  des->errors += 1;
421 	    } else {
422 		  gate = new NetLogic(scope, inst_name, pin_count(),
423 				      NetLogic::NOTIF0, instance_width);
424 	    }
425 	    break;
426 
427 	  case NOTIF1:
428 	    if (pin_count() != 3) {
429 		  cerr << get_fileline() << ": error: the NOTIF1 "
430 			"primitive must have three arguments." << endl;
431 		  des->errors += 1;
432 	    } else {
433 		  gate = new NetLogic(scope, inst_name, pin_count(),
434 				      NetLogic::NOTIF1, instance_width);
435 	    }
436 	    break;
437 
438 	  case OR:
439 	    if (pin_count() < 2) {
440 		  cerr << get_fileline() << ": error: the OR "
441 			"primitive must have an input." << endl;
442 		  des->errors += 1;
443 	    } else {
444 		  gate = new NetLogic(scope, inst_name, pin_count(),
445 				      NetLogic::OR, instance_width);
446 	    }
447 	    break;
448 
449 	  case RCMOS:
450 	    if (pin_count() != 4) {
451 		  cerr << get_fileline() << ": error: the RCMOS "
452 			"primitive must have four arguments." << endl;
453 		  des->errors += 1;
454 	    } else {
455 		  gate = new NetLogic(scope, inst_name, pin_count(),
456 				      NetLogic::RCMOS, instance_width);
457 	    }
458 	    break;
459 
460 	  case RNMOS:
461 	    if (pin_count() != 3) {
462 		  cerr << get_fileline() << ": error: the RNMOS "
463 			"primitive must have three arguments." << endl;
464 		  des->errors += 1;
465 	    } else {
466 		  gate = new NetLogic(scope, inst_name, pin_count(),
467 				      NetLogic::RNMOS, instance_width);
468 	    }
469 	    break;
470 
471 	  case RPMOS:
472 	    if (pin_count() != 3) {
473 		  cerr << get_fileline() << ": error: the RPMOS "
474 			"primitive must have three arguments." << endl;
475 		  des->errors += 1;
476 	    } else {
477 		  gate = new NetLogic(scope, inst_name, pin_count(),
478 				      NetLogic::RPMOS, instance_width);
479 	    }
480 	    break;
481 
482 	  case PMOS:
483 	    if (pin_count() != 3) {
484 		  cerr << get_fileline() << ": error: the PMOS "
485 			"primitive must have three arguments." << endl;
486 		  des->errors += 1;
487 	    } else {
488 		  gate = new NetLogic(scope, inst_name, pin_count(),
489 				      NetLogic::PMOS, instance_width);
490 	    }
491 	    break;
492 
493 	  case PULLDOWN:
494 	    gate = new NetLogic(scope, inst_name, 1,
495 				NetLogic::PULLDOWN, instance_width);
496 	    break;
497 
498 	  case PULLUP:
499 	    gate = new NetLogic(scope, inst_name, 1,
500 				NetLogic::PULLUP, instance_width);
501 	    break;
502 
503 	  case XNOR:
504 	    if (pin_count() < 2) {
505 		  cerr << get_fileline() << ": error: the XNOR "
506 			"primitive must have an input." << endl;
507 		  des->errors += 1;
508 	    } else {
509 		  gate = new NetLogic(scope, inst_name, pin_count(),
510 				      NetLogic::XNOR, instance_width);
511 	    }
512 	    break;
513 
514 	  case XOR:
515 	    if (pin_count() < 2) {
516 		  cerr << get_fileline() << ": error: the XOR "
517 			"primitive must have an input." << endl;
518 		  des->errors += 1;
519 	    } else {
520 		  gate = new NetLogic(scope, inst_name, pin_count(),
521 				      NetLogic::XOR, instance_width);
522 	    }
523 	    break;
524 
525 	  case TRAN:
526 	    if (pin_count() != 2) {
527 		  cerr << get_fileline() << ": error: Pin count for "
528 		       << "tran device." << endl;
529 		  des->errors += 1;
530 	    } else {
531 		  gate = new NetTran(scope, inst_name, IVL_SW_TRAN,
532 		                     instance_width);
533 	    }
534 	    break;
535 
536 	  case RTRAN:
537 	    if (pin_count() != 2) {
538 		  cerr << get_fileline() << ": error: Pin count for "
539 		       << "rtran device." << endl;
540 		  des->errors += 1;
541 	    } else {
542 		  gate = new NetTran(scope, inst_name, IVL_SW_RTRAN,
543 		                     instance_width);
544 	    }
545 	    break;
546 
547 	  case TRANIF0:
548 	    if (pin_count() != 3) {
549 		  cerr << get_fileline() << ": error: Pin count for "
550 		       << "tranif0 device." << endl;
551 		  des->errors += 1;
552 	    } else {
553 		  gate = new NetTran(scope, inst_name, IVL_SW_TRANIF0,
554 		                     instance_width);
555 	    }
556 	    break;
557 
558 	  case RTRANIF0:
559 	    if (pin_count() != 3) {
560 		  cerr << get_fileline() << ": error: Pin count for "
561 		       << "rtranif0 device." << endl;
562 		  des->errors += 1;
563 	    } else {
564 		  gate = new NetTran(scope, inst_name, IVL_SW_RTRANIF0,
565 		                     instance_width);
566 	    }
567 	    break;
568 
569 	  case TRANIF1:
570 	    if (pin_count() != 3) {
571 		  cerr << get_fileline() << ": error: Pin count for "
572 		       << "tranif1 device." << endl;
573 		  des->errors += 1;
574 	    } else {
575 		  gate = new NetTran(scope, inst_name, IVL_SW_TRANIF1,
576 		                     instance_width);
577 	    }
578 	    break;
579 
580 	  case RTRANIF1:
581 	    if (pin_count() != 3) {
582 		  cerr << get_fileline() << ": error: Pin count for "
583 		       << "rtranif1 device." << endl;
584 		  des->errors += 1;
585 	    } else {
586 		  gate = new NetTran(scope, inst_name, IVL_SW_RTRANIF1,
587 		                     instance_width);
588 	    }
589 	    break;
590 
591 	  default:
592 	    cerr << get_fileline() << ": internal error: unhandled "
593 		  "gate type." << endl;
594 	    des->errors += 1;
595 	    break;
596       }
597 
598       return gate;
599 }
600 
check_delay_count(Design * des) const601 bool PGBuiltin::check_delay_count(Design*des) const
602 {
603       switch (type()) {
604 	  case AND:
605 	  case NAND:
606 	  case OR:
607 	  case NOR:
608 	  case XOR:
609 	  case XNOR:
610 	  case BUF:
611 	  case NOT:
612 	    if (delay_count() > 2) {
613 		  cerr << get_fileline() << ": error: More than two delays "
614 		       << "given to a " << gate_name() << " gate." << endl;
615 		  des->errors += 1;
616 		  return true;
617 	    }
618 	    break;
619 
620 	  case BUFIF0:
621 	  case NOTIF0:
622 	  case BUFIF1:
623 	  case NOTIF1:
624 	    if (delay_count() > 3) {
625 		  cerr << get_fileline() << ": error: More than three delays "
626 		       << "given to a " << gate_name() << " gate." << endl;
627 		  des->errors += 1;
628 		  return true;
629 	    }
630 	    break;
631 
632 	  case NMOS:
633 	  case RNMOS:
634 	  case PMOS:
635 	  case RPMOS:
636 	  case CMOS:
637 	  case RCMOS:
638 	    if (delay_count() > 3) {
639 		  cerr << get_fileline() << ": error: More than three delays "
640 		       << "given to a " << gate_name() << " switch." << endl;
641 		  des->errors += 1;
642 		  return true;
643 	    }
644 	    break;
645 
646 	  case TRAN:
647 	  case RTRAN:
648 	    if (delay_count() != 0) {
649 		  cerr << get_fileline() << ": error: A " << gate_name()
650 		       << " switch does not take any delays." << endl;
651 		  des->errors += 1;
652 		  return true;
653 	    }
654 	    break;
655 
656 	  case TRANIF0:
657 	  case TRANIF1:
658 	    if (delay_count() > 2) {
659 		  cerr << get_fileline() << ": error: More than two delays "
660 		       << "given to a " << gate_name() << " switch." << endl;
661 		  des->errors += 1;
662 		  return true;
663 	    }
664 	    break;
665 
666 	  case RTRANIF0:
667 	  case RTRANIF1:
668 	    if (delay_count() > 2) {
669 		  cerr << get_fileline() << ": error: More than two delays "
670 		       << "given to an " << gate_name() << " switch." << endl;
671 		  des->errors += 1;
672 		  return true;
673 	    }
674 	    break;
675 
676 	  case PULLUP:
677 	  case PULLDOWN:
678 	    if (delay_count() != 0) {
679 		  cerr << get_fileline() << ": error: A " << gate_name()
680 		       << " source does not take any delays." << endl;
681 		  des->errors += 1;
682 		  return true;
683 	    }
684 	    break;
685 
686 	  default:
687 	    cerr << get_fileline() << ": internal error: unhandled "
688 		  "gate type." << endl;
689 	    des->errors += 1;
690 	    return true;
691 	    break;
692       }
693 
694       return false;
695 }
696 
697 /*
698  * Elaborate a Builtin gate. These normally get translated into
699  * NetLogic nodes that reflect the particular logic function.
700  */
elaborate(Design * des,NetScope * scope) const701 void PGBuiltin::elaborate(Design*des, NetScope*scope) const
702 {
703       unsigned instance_width = 1;
704       perm_string name = get_name();
705 
706       if (name == "") name = scope->local_symbol();
707 
708 	/* Calculate the array bounds and instance count for the gate,
709 	   as described in the Verilog source. If there is none, then
710 	   the count is 1, and high==low==0. */
711 
712       long low=0, high=0;
713       unsigned array_count = calculate_array_count_(des, scope, high, low);
714       if (array_count == 0) return;
715 
716       unsigned gate_count = 0, lval_count = 0;
717       calculate_gate_and_lval_count_(gate_count, lval_count);
718 
719 	/* Now we have a gate count. Elaborate the lval (output or
720            bi-directional) expressions only. We do it early so that
721            we can see if we can make wide gates instead of an array
722            of gates. */
723 
724       vector<NetNet*>lval_sigs (lval_count);
725 
726       for (unsigned idx = 0 ; idx < lval_count ; idx += 1) {
727 	    if (pin(idx) == 0) {
728 		  cerr << get_fileline() << ": error: Logic gate port "
729 			"expressions are not optional." << endl;
730 		  des->errors += 1;
731 		  return;
732 	    }
733             if (lval_count > gate_count)
734 	          lval_sigs[idx] = pin(idx)->elaborate_bi_net(des, scope);
735             else
736 	          lval_sigs[idx] = pin(idx)->elaborate_lnet(des, scope);
737 
738 	      // The only way this should return zero is if an error
739 	      // happened, so for that case just return.
740 	    if (lval_sigs[idx] == 0) return;
741 
742 	      // For now, assume all the outputs are the same width.
743 	    ivl_assert(*this, idx == 0 || lval_sigs[idx]->vector_width() == lval_sigs[0]->vector_width());
744       }
745 
746 	/* Detect the special case that the l-value width exactly
747 	   matches the gate count. In this case, we will make a single
748 	   gate that has the desired vector width.
749 
750 	   NOTE: This assumes that all the outputs have the same
751 	   width. For gates with 1 output, this is trivially true. */
752       if (lval_sigs[0]->vector_width() == array_count) {
753 	    instance_width = array_count;
754 	    array_count = 1;
755 
756 	    if (debug_elaborate && instance_width != 1)
757 		  cerr << get_fileline() << ": debug: PGBuiltin: "
758 			"Collapsed gate array into single wide "
759 			"(" << instance_width << ") instance." << endl;
760       }
761 
762 	/* Calculate the gate delays from the delay expressions
763 	   given in the source. For logic gates, the decay time
764 	   is meaningless because it can never go to high
765 	   impedance. However, the bufif devices can generate
766 	   'bz output, so we will pretend that anything can.
767 
768 	   If only one delay value expression is given (i.e., #5
769 	   nand(foo,...)) then rise, fall and decay times are
770 	   all the same value. If two values are given, rise and
771 	   fall times are use, and the decay time is the minimum
772 	   of the rise and fall times. Finally, if all three
773 	   values are given, they are taken as specified. */
774 
775       if (check_delay_count(des)) return;
776       NetExpr* rise_time, *fall_time, *decay_time;
777       eval_delays(des, scope, rise_time, fall_time, decay_time, true);
778 
779       struct attrib_list_t*attrib_list;
780       unsigned attrib_list_n = 0;
781       attrib_list = evaluate_attributes(attributes, attrib_list_n,
782 					des, scope);
783 
784 	/* Allocate all the netlist nodes for the gates. */
785       vector<NetNode*>cur (array_count*gate_count);
786 
787 	/* Now make as many gates as the bit count dictates. Give each
788 	   a unique name, and set the delay times. */
789 
790       for (unsigned idx = 0 ;  idx < array_count*gate_count ;  idx += 1) {
791 	    unsigned array_idx = idx/gate_count;
792 	    unsigned gate_idx = idx%gate_count;
793 
794 	    ostringstream tmp;
795 	    unsigned index = (low < high)? (low+array_idx) : (low-array_idx);
796 
797 	    tmp << name << "<" << index << "." << gate_idx << ">";
798 	    perm_string inm = lex_strings.make(tmp.str());
799 
800 	    cur[idx] = create_gate_for_output_(des, scope, inm, instance_width);
801 	    if (cur[idx] == 0)
802 		  return;
803 
804 	    for (unsigned adx = 0 ;  adx < attrib_list_n ;  adx += 1)
805 		  cur[idx]->attribute(attrib_list[adx].key,
806 				      attrib_list[adx].val);
807 
808 	      /* Set the delays and drive strength for all built in gates. */
809 	    cur[idx]->rise_time(rise_time);
810 	    cur[idx]->fall_time(fall_time);
811 	    cur[idx]->decay_time(decay_time);
812 
813 	    cur[idx]->pin(0).drive0(strength0());
814 	    cur[idx]->pin(0).drive1(strength1());
815 
816 	    cur[idx]->set_line(*this);
817 	    des->add_node(cur[idx]);
818       }
819 
820 
821       delete[]attrib_list;
822 
823 	/* The gates have all been allocated, this loop runs through
824 	   the parameters and attaches the ports of the objects. */
825 
826       for (unsigned idx = 0 ;  idx < pin_count() ;  idx += 1) {
827 
828 	    PExpr*ex = pin(idx);
829 	    if (ex == 0) {
830 		  cerr << get_fileline() << ": error: Logic gate port "
831 		          "expressions are not optional." << endl;
832 		  des->errors += 1;
833 		  return;
834 	    }
835 	    NetNet*sig = 0;
836 	    if (idx < lval_count) {
837 		  sig = lval_sigs[idx];
838 
839 	    } else {
840                     // If this is an array, the port expression is required
841                     // to be the exact width required (this will be checked
842                     // later). But if this is a single instance, consensus
843                     // is that we just take the LSB of the port expression.
844 		  NetExpr*tmp = elab_and_eval(des, scope, ex, msb_ ? -1 : 1);
845                   if (tmp == 0)
846                         continue;
847                   if (msb_ == 0 && tmp->expr_width() != 1)
848                         tmp = new NetESelect(tmp, make_const_0(1), 1,
849                                              IVL_SEL_IDX_UP);
850 		  sig = tmp->synthesize(des, scope, tmp);
851 		  delete tmp;
852 	    }
853 
854 	    if (sig == 0)
855 		  continue;
856 
857 	    ivl_assert(*this, sig);
858 
859 	    if (array_count == 1) {
860 		    /* Handle the case where there is one gate that
861 		       carries the whole vector width. */
862 
863 		  if (1 == sig->vector_width() && instance_width != 1) {
864 
865 			assert(sig->vector_width() == 1);
866 			NetReplicate*rep
867 			      = new NetReplicate(scope,
868 						 scope->local_symbol(),
869 						 instance_width,
870 						 instance_width);
871 			rep->set_line(*this);
872 			des->add_node(rep);
873 			connect(rep->pin(1), sig->pin(0));
874 
875 			netvector_t*osig_vec = new netvector_t(IVL_VT_LOGIC,
876 							       instance_width-1,0);
877 			sig = new NetNet(scope, scope->local_symbol(),
878 					 NetNet::WIRE, osig_vec);
879 			sig->set_line(*this);
880 			sig->local_flag(true);
881 			connect(rep->pin(0), sig->pin(0));
882 
883 		  }
884 
885 		  if (instance_width != sig->vector_width()) {
886 
887 			cerr << get_fileline() << ": error: "
888 			     << "Expression width " << sig->vector_width()
889 			     << " does not match width " << instance_width
890 			     << " of logic gate array port " << idx+1
891 			     << "." << endl;
892 			des->errors += 1;
893 		  }
894 
895 		    // There is only 1 instance, but there may be
896 		    // multiple outputs to that gate. That would
897 		    // potentially mean multiple actual gates.
898 		    // Although in Verilog proper a multiple
899 		    // output gate has only 1 input, this conditional
900 		    // handles gates with N outputs and M inputs.
901 		  if (idx < gate_count) {
902 			connect(cur[idx]->pin(0), sig->pin(0));
903 		  } else {
904 			for (unsigned dev = 0 ; dev < gate_count; dev += 1)
905 			      connect(cur[dev]->pin(idx-gate_count+1), sig->pin(0));
906 		  }
907 
908 	    } else if (sig->vector_width() == 1) {
909 
910 		    /* Handle the case where a single bit is connected
911 		       repetitively to all the instances. If idx is an
912 		       output port, connect it to all array_count
913 		       devices that have outputs at this
914 		       position. Otherwise, idx is an input to all
915 		       array_count*gate_count devices. */
916 
917 		  if (idx < gate_count) {
918 			for (unsigned gdx = 0 ; gdx < array_count ; gdx += 1) {
919 			      unsigned dev = gdx*gate_count;
920 			      connect(cur[dev+idx]->pin(0), sig->pin(0));
921 			}
922 		  } else {
923 			unsigned use_idx = idx - gate_count + 1;
924 			for (unsigned gdx = 0 ;  gdx < cur.size() ;  gdx += 1)
925 			      connect(cur[gdx]->pin(use_idx), sig->pin(0));
926 		  }
927 
928 	    } else if (sig->vector_width() == array_count) {
929 
930                     /* Bi-directional switches should get collapsed into
931                        a single wide instance, so should never reach this
932                        point. Check this is so, as the following code
933                        doesn't handle bi-directional connections. */
934                   ivl_assert(*this, lval_count == gate_count);
935 
936 		    /* Handle the general case that each bit of the
937 		       value is connected to a different instance. In
938 		       this case, the output is handled slightly
939 		       different from the inputs. */
940 		  if (idx < gate_count) {
941 			NetConcat*cc = new NetConcat(scope,
942 						     scope->local_symbol(),
943 						     sig->vector_width(),
944 						     array_count);
945 			cc->set_line(*this);
946 			des->add_node(cc);
947 
948 			  /* Connect the concat to the signal. */
949 			connect(cc->pin(0), sig->pin(0));
950 
951 			  /* Connect the outputs of the gates to the concat. */
952 			for (unsigned gdx = 0 ;  gdx < array_count;  gdx += 1) {
953 			      unsigned dev = gdx*gate_count;
954 			      connect(cur[dev+idx]->pin(0), cc->pin(gdx+1));
955 
956 			      netvector_t*tmp2_vec = new netvector_t(IVL_VT_LOGIC);
957 			      NetNet*tmp2 = new NetNet(scope,
958 						       scope->local_symbol(),
959 						       NetNet::WIRE, tmp2_vec);
960 			      tmp2->set_line(*this);
961 			      tmp2->local_flag(true);
962 			      connect(cc->pin(gdx+1), tmp2->pin(0));
963 			}
964 
965 		  } else for (unsigned gdx = 0 ;  gdx < array_count ;  gdx += 1) {
966 			  /* Use part selects to get the bits
967 			     connected to the inputs of out gate. */
968 			NetPartSelect*tmp1 = new NetPartSelect(sig, gdx, 1,
969 							   NetPartSelect::VP);
970 			tmp1->set_line(*this);
971 			des->add_node(tmp1);
972 			connect(tmp1->pin(1), sig->pin(0));
973 			netvector_t*tmp2_vec = new netvector_t(sig->data_type());
974 			NetNet*tmp2 = new NetNet(scope, scope->local_symbol(),
975 						 NetNet::WIRE, tmp2_vec);
976 			tmp2->set_line(*this);
977 			tmp2->local_flag(true);
978 			connect(tmp1->pin(0), tmp2->pin(0));
979 			unsigned use_idx = idx - gate_count + 1;
980 			unsigned dev = gdx*gate_count;
981 			for (unsigned gdx2 = 0 ; gdx2 < gate_count ; gdx2 += 1)
982 			      connect(cur[dev+gdx2]->pin(use_idx), tmp1->pin(0));
983 		  }
984 
985 	    } else {
986 		  cerr << get_fileline() << ": error: Gate count of " <<
987 			array_count << " does not match net width of " <<
988 			sig->vector_width() << " at pin " << idx << "."
989 		       << endl;
990 		  des->errors += 1;
991 	    }
992 
993       }
994 
995 }
996 
resize_net_to_port_(Design * des,NetScope * scope,NetNet * sig,unsigned port_wid,NetNet::PortType dir,bool as_signed) const997 NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
998 				     NetNet*sig, unsigned port_wid,
999 				     NetNet::PortType dir, bool as_signed) const
1000 {
1001       ivl_assert(*this, dir != NetNet::NOT_A_PORT);
1002       ivl_assert(*this, dir != NetNet::PIMPLICIT);
1003 
1004       netvector_t*tmp_type = new netvector_t(IVL_VT_LOGIC, port_wid-1, 0);
1005       NetNet*tmp = new NetNet(scope, scope->local_symbol(),
1006 			      NetNet::WIRE, tmp_type);
1007       tmp->local_flag(true);
1008       tmp->set_line(*this);
1009 
1010 	// Handle the special case of a bi-directional part
1011 	// select. Create a NetTran(VP) instead of a uni-directional
1012 	// NetPartSelect node.
1013       if (dir == NetNet::PINOUT) {
1014 	    unsigned wida = sig->vector_width();
1015 	    unsigned widb = tmp->vector_width();
1016 	    bool part_b = widb < wida;
1017 	      // This needs to pad the value!
1018 	      // Also delete the inout specific warning when this is fixed.
1019 	      // It is located just before this routine is called.
1020 	    NetTran*node = new NetTran(scope, scope->local_symbol(),
1021 				       part_b? wida : widb,
1022 				       part_b? widb : wida,
1023 				       0);
1024 	    if (part_b) {
1025 		  connect(node->pin(0), sig->pin(0));
1026 		  connect(node->pin(1), tmp->pin(0));
1027 	    } else {
1028 		  connect(node->pin(0), tmp->pin(0));
1029 		  connect(node->pin(1), sig->pin(0));
1030 	    }
1031 
1032 	    node->set_line(*this);
1033 	    des->add_node(node);
1034 
1035 	    return tmp;
1036       }
1037 
1038       unsigned pwidth = tmp->vector_width();
1039       unsigned swidth = sig->vector_width();
1040       switch (dir) {
1041 	  case NetNet::POUTPUT:
1042 	    if (pwidth > swidth) {
1043 		  NetPartSelect*node = new NetPartSelect(tmp, 0, swidth,
1044 					   NetPartSelect::VP);
1045 		  connect(node->pin(0), sig->pin(0));
1046 		  des->add_node(node);
1047 	    } else {
1048 		  NetNet*osig;
1049 		  if (as_signed) {
1050 			osig = pad_to_width_signed(des, tmp, swidth, *this);
1051 		  } else {
1052 			osig = pad_to_width(des, tmp, swidth, *this);
1053 		  }
1054 		  connect(osig->pin(0), sig->pin(0));
1055 	    }
1056 	    break;
1057 
1058 	  case NetNet::PINPUT:
1059 	    if (pwidth > swidth) {
1060 		  delete tmp;
1061 		  if (as_signed) {
1062 			tmp = pad_to_width_signed(des, sig, pwidth, *this);
1063 		  } else {
1064 			tmp = pad_to_width(des, sig, pwidth, *this);
1065 		  }
1066 	    } else {
1067 		  NetPartSelect*node = new NetPartSelect(sig, 0, pwidth,
1068 					   NetPartSelect::VP);
1069 		  connect(node->pin(0), tmp->pin(0));
1070 		  des->add_node(node);
1071 	    }
1072 	    break;
1073 
1074 	  case NetNet::PINOUT:
1075 	    ivl_assert(*this, 0);
1076 	    break;
1077 
1078 	  case NetNet::PREF:
1079 	    ivl_assert(*this, 0);
1080 	    break;
1081 
1082 	  default:
1083 	    ivl_assert(*this, 0);
1084       }
1085 
1086       return tmp;
1087 }
1088 
need_bufz_for_input_port(const vector<NetNet * > & prts)1089 static bool need_bufz_for_input_port(const vector<NetNet*>&prts)
1090 {
1091       if (prts[0]->port_type() != NetNet::PINPUT)
1092 	    return false;
1093 
1094       if (prts[0]->pin(0).nexus()->drivers_present())
1095 	    return true;
1096 
1097       return false;
1098 }
1099 
1100 /*
1101  * Convert a wire or tri to a tri0 or tri1 as needed to make
1102  * an unconnected drive pull for floating inputs.
1103  */
convert_net(Design * des,const LineInfo * line,NetNet * net,NetNet::Type type)1104 static void convert_net(Design*des, const LineInfo *line,
1105                         NetNet *net, NetNet::Type type)
1106 {
1107 	// If the types already match just return.
1108       if (net->type() == type) return;
1109 
1110 	// We can only covert a wire or tri to have a default pull.
1111       if (net->type() == NetNet::WIRE || net->type() == NetNet::TRI) {
1112 	    net->type(type);
1113 	    return;
1114       }
1115 
1116 	// We may have to support this at some point in time!
1117       cerr << line->get_fileline() << ": sorry: Can not pull floating "
1118               "input type '" << net->type() << "'." << endl;
1119       des->errors += 1;
1120 }
1121 
isolate_and_connect(Design * des,NetScope * scope,const PGModule * mod,NetNet * port,NetNet * sig,NetNet::PortType ptype)1122 static void isolate_and_connect(Design*des, NetScope*scope, const PGModule*mod,
1123 				NetNet*port, NetNet*sig, NetNet::PortType ptype)
1124 {
1125       switch (ptype) {
1126 	  case NetNet::POUTPUT:
1127 	    {
1128 		  NetBUFZ*tmp = new NetBUFZ(scope, scope->local_symbol(),
1129 					    sig->vector_width(), true);
1130 		  tmp->set_line(*mod);
1131 		  des->add_node(tmp);
1132 		  connect(tmp->pin(1), port->pin(0));
1133 		  connect(tmp->pin(0), sig->pin(0));
1134 	    }
1135 	    break;
1136 	  case NetNet::PINOUT:
1137 	    {
1138 		  NetTran*tmp = new NetTran(scope, scope->local_symbol(),
1139 					    sig->vector_width(),
1140 					    sig->vector_width(), 0);
1141 		  tmp->set_line(*mod);
1142 		  des->add_node(tmp);
1143 		  connect(tmp->pin(1), port->pin(0));
1144 		  connect(tmp->pin(0), sig->pin(0));
1145 	    }
1146 	    break;
1147 	  default:
1148 	    ivl_assert(*mod, 0);
1149 	    break;
1150       }
1151 }
1152 
1153 /*
1154  * Instantiate a module by recursively elaborating it. Set the path of
1155  * the recursive elaboration so that signal names get properly
1156  * set. Connect the ports of the instantiated module to the signals of
1157  * the parameters. This is done with BUFZ gates so that they look just
1158  * like continuous assignment connections.
1159  */
elaborate_mod_(Design * des,Module * rmod,NetScope * scope) const1160 void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
1161 {
1162 
1163       assert(scope);
1164 
1165       if (debug_elaborate) {
1166 	    cerr << get_fileline() << ": debug: Instantiate module "
1167 		 << rmod->mod_name() << " with instance name "
1168 		 << get_name() << " in scope " << scope_path(scope) << endl;
1169       }
1170 
1171 	// This is the array of pin expressions, shuffled to match the
1172 	// order of the declaration. If the source instantiation uses
1173 	// bind by order, this is the same as the source list. Otherwise,
1174 	// the source list is rearranged by name binding into this list.
1175       vector<PExpr*>pins (rmod->port_count());
1176       vector<bool>pins_fromwc (rmod->port_count(), false);
1177       vector<bool>pins_is_explicitly_not_connected (rmod->port_count(), false);
1178 
1179 	// If the instance has a pins_ member, then we know we are
1180 	// binding by name. Therefore, make up a pins array that
1181 	// reflects the positions of the named ports.
1182       if (pins_) {
1183 	    unsigned nexp = rmod->port_count();
1184 
1185 	      // Scan the bindings, matching them with port names.
1186 	    for (unsigned idx = 0 ;  idx < npins_ ;  idx += 1) {
1187 
1188 		    // Handle wildcard named port
1189 		  if (pins_[idx].name[0] == '*') {
1190 			for (unsigned j = 0 ; j < nexp ; j += 1) {
1191 			      if ((!pins[j]) && (!pins_is_explicitly_not_connected[j])) {
1192 				    pins_fromwc[j] = true;
1193 				    NetNet*       net = 0;
1194 				    const NetExpr*par = 0;
1195 				    NetEvent*     eve = 0;
1196 				    pform_name_t path_;
1197 				    path_.push_back(name_component_t(rmod->ports[j]->name));
1198 				    symbol_search(this, des, scope,
1199 						  path_, net, par, eve);
1200 				    if (net != 0) {
1201 					  pins[j] = new PEIdent(rmod->ports[j]->name, true);
1202 					  pins[j]->set_lineno(get_lineno());
1203 					  pins[j]->set_file(get_file());
1204 				    }
1205 			      }
1206 			}
1207 			continue;
1208 		  }
1209 
1210 		    // Given a binding, look at the module port names
1211 		    // for the position that matches the binding name.
1212 		  unsigned pidx = rmod->find_port(pins_[idx].name);
1213 
1214 		    // If the port name doesn't exist, the find_port
1215 		    // method will return the port count. Detect that
1216 		    // as an error.
1217 		  if (pidx == nexp) {
1218 			cerr << get_fileline() << ": error: port ``" <<
1219 			      pins_[idx].name << "'' is not a port of "
1220 			     << get_name() << "." << endl;
1221 			des->errors += 1;
1222 			continue;
1223 		  }
1224 
1225 		    // If I am overriding a wildcard port, delete and
1226 		    // override it
1227 		  if (pins_fromwc[pidx]) {
1228 			delete pins[pidx];
1229 			pins_fromwc[pidx] = false;
1230 
1231 		    // If I already explicitly bound something to
1232 		    // this port, then the pins array will already
1233 		    // have a pointer value where I want to place this
1234 		    // expression.
1235 		  } else if (pins[pidx]) {
1236 			cerr << get_fileline() << ": error: port ``" <<
1237 			      pins_[idx].name << "'' already bound." <<
1238 			      endl;
1239 			des->errors += 1;
1240 			continue;
1241 		  }
1242 
1243 		    // OK, do the binding by placing the expression in
1244 		    // the right place.
1245 		  pins[pidx] = pins_[idx].parm;
1246 		  if (!pins[pidx])
1247 			pins_is_explicitly_not_connected[pidx] = true;
1248 	    }
1249 
1250 
1251       } else if (pin_count() == 0) {
1252 
1253 	      /* Handle the special case that no ports are
1254 		 connected. It is possible that this is an empty
1255 		 connect-by-name list, so we'll allow it and assume
1256 		 that is the case. */
1257 
1258 	    for (unsigned idx = 0 ;  idx < rmod->port_count() ;  idx += 1)
1259 		  pins[idx] = 0;
1260 
1261       } else {
1262 
1263 	      /* Otherwise, this is a positional list of port
1264 		 connections. In this case, the port count must be
1265 		 right. Check that is is, the get the pin list. */
1266 
1267 	    if (pin_count() != rmod->port_count()) {
1268 		  cerr << get_fileline() << ": error: Wrong number "
1269 			"of ports. Expecting " << rmod->port_count() <<
1270 			", got " << pin_count() << "."
1271 		       << endl;
1272 		  des->errors += 1;
1273 		  return;
1274 	    }
1275 
1276 	      // No named bindings, just use the positional list I
1277 	      // already have.
1278 	    assert(pin_count() == rmod->port_count());
1279 	    pins = get_pins();
1280       }
1281 
1282 	// Elaborate these instances of the module. The recursive
1283 	// elaboration causes the module to generate a netlist with
1284 	// the ports represented by NetNet objects. I will find them
1285 	// later.
1286 
1287       NetScope::scope_vec_t&instance = scope->instance_arrays[get_name()];
1288       if (debug_elaborate) cerr << get_fileline() << ": debug: start "
1289 	    "recursive elaboration of " << instance.size() << " instance(s) of " <<
1290 	    get_name() << "..." << endl;
1291       for (unsigned inst = 0 ;  inst < instance.size() ;  inst += 1) {
1292 	    rmod->elaborate(des, instance[inst]);
1293 	    instance[inst]->set_num_ports( rmod->port_count() );
1294       }
1295       if (debug_elaborate) cerr << get_fileline() << ": debug: ...done." << endl;
1296 
1297 
1298 	// Now connect the ports of the newly elaborated designs to
1299 	// the expressions that are the instantiation parameters. Scan
1300 	// the pins, elaborate the expressions attached to them, and
1301 	// bind them to the port of the elaborated module.
1302 
1303 	// This can get rather complicated because the port can be
1304 	// unconnected (meaning an empty parameter is passed) connected
1305 	// to a concatenation, or connected to an internally
1306 	// unconnected port.
1307 
1308       for (unsigned idx = 0 ;  idx < pins.size() ;  idx += 1) {
1309 	    bool unconnected_port = false;
1310 
1311 	    perm_string port_name = rmod->get_port_name(idx);
1312 
1313 	      // Skip unconnected module ports. This happens when a
1314 	      // null parameter is passed in.
1315 
1316 	    if (pins[idx] == 0) {
1317 
1318 		  if (pins_fromwc[idx]) {
1319 			cerr << get_fileline() << ": error: Wildcard named "
1320 			        "port connection (.*) did not find a matching "
1321 			        "identifier for port " << (idx+1) << " ("
1322 			     << port_name << ")." << endl;
1323 			des->errors += 1;
1324 			return;
1325 		  }
1326 
1327 		    // We need this information to support the
1328 		    // unconnected_drive directive and for a
1329 		    // unconnected input warning when asked for.
1330 		  vector<PEIdent*> mport = rmod->get_port(idx);
1331 		  if (mport.empty()) continue;
1332 
1333 		  perm_string pname = peek_tail_name(mport[0]->path());
1334 
1335 		  NetNet*tmp = instance[0]->find_signal(pname);
1336 
1337 		    // Handle the error case where there is no internal
1338 		    // signal connected to the port.
1339 		  if (!tmp) continue;
1340 		  assert(tmp);
1341 
1342 		  if (tmp->port_type() == NetNet::PINPUT) {
1343 			  // If we have an unconnected input convert it
1344 			  // as needed if an unconnected_drive directive
1345 			  // was given. This only works for tri or wire!
1346 			switch (rmod->uc_drive) {
1347 			    case Module::UCD_PULL0:
1348 			      convert_net(des, this, tmp, NetNet::TRI0);
1349 			      break;
1350 			    case Module::UCD_PULL1:
1351 			      convert_net(des, this, tmp, NetNet::TRI1);
1352 			      break;
1353 			    case Module::UCD_NONE:
1354 			      break;
1355 			}
1356 
1357 			  // Print a warning for an unconnected input.
1358 			if (warn_portbinding) {
1359 			      cerr << get_fileline() << ": warning: "
1360 				   << "Instantiating module "
1361 				   << rmod->mod_name()
1362 				   << " with dangling input port "
1363 				   << (idx+1) << " (" << port_name;
1364 			      switch (rmod->uc_drive) {
1365 				  case Module::UCD_PULL0:
1366 				    cerr << ") pulled low." << endl;
1367 				    break;
1368 				  case Module::UCD_PULL1:
1369 				    cerr << ") pulled high." << endl;
1370 				    break;
1371 				  case Module::UCD_NONE:
1372 				    cerr << ") floating." << endl;
1373 				    break;
1374 			      }
1375 			}
1376 		  }
1377 		  unconnected_port = true;
1378 	    }
1379 
1380 	      // Inside the module, the port connects zero or more signals
1381 	      // that were already elaborated. List all those signals
1382 	      // and the NetNet equivalents, for all the instances.
1383 	    vector<PEIdent*> mport = rmod->get_port(idx);
1384 	    vector<NetNet*>  prts (mport.size() * instance.size());
1385 
1386 	    if (debug_elaborate) {
1387 		  cerr << get_fileline() << ": debug: " << get_name()
1388 		       << ": Port " << (idx+1) << " (" << port_name
1389 		       << ") has " << prts.size() << " sub-ports." << endl;
1390 	    }
1391 
1392 	      // Count the internal vector bits of the port.
1393 	    unsigned prts_vector_width = 0;
1394 
1395 	    for (unsigned inst = 0 ;  inst < instance.size() ;  inst += 1) {
1396 		    // Scan the instances from MSB to LSB. The port
1397 		    // will be assembled in that order as well.
1398 		  NetScope*inst_scope = instance[instance.size()-inst-1];
1399 
1400 		  unsigned int prt_vector_width = 0;
1401 		  PortType::Enum ptype = PortType::PIMPLICIT;
1402 		    // Scan the module sub-ports for this instance...
1403 		    // (Sub-ports are concatenated ports that form the
1404 		    // single port for the instance. This is not a
1405 		    // commonly used feature.)
1406 		  for (unsigned ldx = 0 ;  ldx < mport.size() ;  ldx += 1) {
1407 			unsigned lbase = inst * mport.size();
1408 			PEIdent*pport = mport[ldx];
1409 			ivl_assert(*this, pport);
1410 			NetNet *netnet = pport->elaborate_subport(des, inst_scope);
1411 			prts[lbase + ldx] = netnet;
1412 			if (netnet == 0)
1413 			      continue;
1414 
1415 			ivl_assert(*this, netnet);
1416 			unsigned port_width = netnet->vector_width() * netnet->pin_count();
1417 			prts_vector_width += port_width;
1418 			prt_vector_width += port_width;
1419 			ptype = PortType::merged(netnet->port_type(), ptype);
1420 		  }
1421 		  inst_scope->add_module_port_info(idx, port_name, ptype, prt_vector_width );
1422 	    }
1423 
1424 	      // If I find that the port is unconnected inside the
1425 	      // module, then there is nothing to connect. Skip the
1426 	      // argument.
1427 	    if ((prts_vector_width == 0) || unconnected_port) {
1428 		  continue;
1429 	    }
1430 
1431 	      // We know by design that each instance has the same
1432 	      // width port. Therefore, the prts_pin_count must be an
1433 	      // even multiple of the instance count.
1434 	    assert(prts_vector_width % instance.size() == 0);
1435 
1436 	    if (!prts.empty() && (prts[0]->port_type() == NetNet::PINPUT)
1437                 && prts[0]->pin(0).nexus()->drivers_present()
1438                 && pins[idx]->is_collapsible_net(des, scope)) {
1439                   prts[0]->port_type(NetNet::PINOUT);
1440 
1441 		  cerr << pins[idx]->get_fileline() << ": warning: input port "
1442 		       << prts[0]->name() << " is coerced to inout." << endl;
1443 	    }
1444 
1445 	    if (!prts.empty() && (prts[0]->port_type() == NetNet::POUTPUT)
1446                 && (prts[0]->type() != NetNet::REG)
1447                 && prts[0]->pin(0).nexus()->has_floating_input()
1448                 && pins[idx]->is_collapsible_net(des, scope)) {
1449                   prts[0]->port_type(NetNet::PINOUT);
1450 
1451 		  cerr << pins[idx]->get_fileline() << ": warning: output port "
1452 		       << prts[0]->name() << " is coerced to inout." << endl;
1453 	    }
1454 
1455 	      // Elaborate the expression that connects to the
1456 	      // module[s] port. sig is the thing outside the module
1457 	      // that connects to the port.
1458 
1459 	    NetNet*sig = 0;
1460 	    NetNet::PortType ptype = prts[0]->port_type();
1461 	    if (prts.empty() || (ptype == NetNet::PINPUT)) {
1462 
1463 		    // Special case: If the input port is an unpacked
1464 		    // array, then there should be no sub-ports and
1465 		    // the r-value expression is processed
1466 		    // differently.
1467 		  if (prts.size() >= 1 && prts[0]->pin_count()>1) {
1468 			ivl_assert(*this, prts.size()==1);
1469 
1470 			PEIdent*rval_pident = dynamic_cast<PEIdent*> (pins[idx]);
1471 			ivl_assert(*this, rval_pident);
1472 
1473 			NetNet*rval_net = rval_pident->elaborate_unpacked_net(des, scope);
1474 			ivl_assert(*this, rval_net->pin_count() == prts[0]->pin_count());
1475 			assign_unpacked_with_bufz(des, scope, this, prts[0], rval_net);
1476 			continue;
1477 		  }
1478 
1479 		    /* Input to module. elaborate the expression to
1480 		       the desired width. If this in an instance
1481 		       array, then let the net determine its own
1482 		       width. We use that, then, to decide how to hook
1483 		       it up.
1484 
1485 		       NOTE that this also handles the case that the
1486 		       port is actually empty on the inside. We assume
1487 		       in that case that the port is input. */
1488 
1489 		  NetExpr*tmp_expr = elab_and_eval(des, scope, pins[idx], -1);
1490 		  if (tmp_expr == 0) {
1491 			cerr << pins[idx]->get_fileline()
1492 			     << ": error: Failed to elaborate port expression."
1493 			     << endl;
1494 			des->errors += 1;
1495 			continue;
1496 		  }
1497 
1498 		  if (debug_elaborate) {
1499 			cerr << get_fileline() << ": debug: "
1500 			     << "Elaborating INPUT port expression: " << *tmp_expr << endl;
1501 		  }
1502 
1503 		  sig = tmp_expr->synthesize(des, scope, tmp_expr);
1504 		  if (sig == 0) {
1505 			cerr << pins[idx]->get_fileline()
1506 			     << ": internal error: Port expression "
1507 			     << "too complicated for elaboration." << endl;
1508 			continue;
1509 		  }
1510 
1511 		  delete tmp_expr;
1512 		  if (!sig->get_lineno()) sig->set_line(*this);
1513 
1514 		  if (need_bufz_for_input_port(prts)) {
1515 			NetBUFZ*tmp = new NetBUFZ(scope, scope->local_symbol(),
1516 						  sig->vector_width(), true);
1517 			tmp->set_line(*this);
1518 			des->add_node(tmp);
1519 			connect(tmp->pin(1), sig->pin(0));
1520 
1521 			netvector_t*tmp2_vec = new netvector_t(sig->data_type(),
1522 							       sig->vector_width()-1,0);
1523 			NetNet*tmp2 = new NetNet(scope, scope->local_symbol(),
1524 						 NetNet::WIRE, tmp2_vec);
1525 			tmp2->local_flag(true);
1526 			tmp2->set_line(*this);
1527 			connect(tmp->pin(0), tmp2->pin(0));
1528 			sig = tmp2;
1529 		  }
1530 
1531 		    // If we have a real signal driving a bit/vector port
1532 		    // then we convert the real value using the appropriate
1533 		    // width cast. Since a real is only one bit the whole
1534 		    // thing needs to go to each instance when arrayed.
1535 		  if ((sig->data_type() == IVL_VT_REAL ) &&
1536 		      !prts.empty() && (prts[0]->data_type() != IVL_VT_REAL )) {
1537 			sig = cast_to_int4(des, scope, sig,
1538 			                  prts_vector_width/instance.size());
1539 		  }
1540 		    // If we have a bit/vector signal driving a real port
1541 		    // then we convert the value to a real.
1542 		  if ((sig->data_type() != IVL_VT_REAL ) &&
1543 		      !prts.empty() && (prts[0]->data_type() == IVL_VT_REAL )) {
1544 			sig = cast_to_real(des, scope, sig);
1545 		  }
1546 		    // If we have a 4-state bit/vector signal driving a
1547 		    // 2-state port then we convert the value to 2-state.
1548 		  if ((sig->data_type() == IVL_VT_LOGIC ) &&
1549 		      !prts.empty() && (prts[0]->data_type() == IVL_VT_BOOL )) {
1550 			sig = cast_to_int2(des, scope, sig,
1551 					   sig->vector_width());
1552 		  }
1553 
1554 	    } else if (ptype == NetNet::PINOUT) {
1555 
1556 		    // For now, do not support unpacked array outputs.
1557 		  ivl_assert(*this, prts[0]->unpacked_dimensions()==0);
1558 
1559 		    /* Inout to/from module. This is a more
1560 		       complicated case, where the expression must be
1561 		       an lnet, but also an r-value net.
1562 
1563 		       Normally, this winds up being the same as if we
1564 		       just elaborated as an lnet, as passing a simple
1565 		       identifier elaborates to the same NetNet in
1566 		       both cases so the extra elaboration has no
1567 		       effect. But if the expression passed to the
1568 		       inout port is a part select, a special part
1569 		       select must be created that can pass data in
1570 		       both directions.
1571 
1572 		       Use the elaborate_bi_net method to handle all
1573 		       the possible cases. */
1574 
1575 		  sig = pins[idx]->elaborate_bi_net(des, scope);
1576 		  if (sig == 0) {
1577 			cerr << pins[idx]->get_fileline() << ": error: "
1578 			     << "Inout port expression must support "
1579 			     << "continuous assignment." << endl;
1580 			cerr << pins[idx]->get_fileline() << ":      : Port "
1581 			     << (idx+1) << " (" << port_name << ") of "
1582 			     << rmod->mod_name() << " is connected to "
1583 			     << *pins[idx] << endl;
1584 			des->errors += 1;
1585 			continue;
1586 		  }
1587 
1588 		    // We do not support automatic bits to real conversion
1589 		    // for inout ports.
1590 		  if ((sig->data_type() == IVL_VT_REAL ) &&
1591 		      !prts.empty() && (prts[0]->data_type() != IVL_VT_REAL )) {
1592 			cerr << pins[idx]->get_fileline() << ": error: "
1593 			     << "Cannot automatically connect bit based "
1594 			        "inout port " << (idx+1) << " (" << port_name
1595 			     << ") of module " << rmod->mod_name()
1596 			     << " to real signal " << sig->name() << "." << endl;
1597 			des->errors += 1;
1598 			continue;
1599 		  }
1600 
1601 		    // We do not support real inout ports at all.
1602 		  if (!prts.empty() && (prts[0]->data_type() == IVL_VT_REAL )) {
1603 			cerr << pins[idx]->get_fileline() << ": error: "
1604 			     << "No support for connecting real inout ports ("
1605 			        "port " << (idx+1) << " (" << port_name
1606 			     << ") of module " << rmod->mod_name() << ")." << endl;
1607 			des->errors += 1;
1608 			continue;
1609 		  }
1610 
1611 
1612 	    } else {
1613 
1614 		    /* Port type must be OUTPUT here. */
1615 		  ivl_assert(*this, ptype == NetNet::POUTPUT);
1616 
1617 		    // Special case: If the output port is an unpacked
1618 		    // array, then there should be no sub-ports and
1619 		    // the passed port expression is processed
1620 		    // differently. Note that we are calling it the
1621 		    // "r-value" expression, but since this is an
1622 		    // output port, we assign to it from the internal object.
1623 		  if (prts[0]->pin_count() > 1) {
1624 			ivl_assert(*this, prts.size()==1);
1625 
1626 			PEIdent*rval_pident = dynamic_cast<PEIdent*>(pins[idx]);
1627 			ivl_assert(*this, rval_pident);
1628 
1629 			NetNet*rval_net = rval_pident->elaborate_unpacked_net(des, scope);
1630 			ivl_assert(*this, rval_net->pin_count() == prts[0]->pin_count());
1631 
1632 			assign_unpacked_with_bufz(des, scope, this, rval_net, prts[0]);
1633 			continue;
1634 		  }
1635 
1636 		    // At this point, arrays are handled.
1637 		  ivl_assert(*this, prts[0]->unpacked_dimensions()==0);
1638 
1639 		    /* Output from module. Elaborate the port
1640 		       expression as the l-value of a continuous
1641 		       assignment, as the port will continuous assign
1642 		       into the port. */
1643 
1644 		  sig = pins[idx]->elaborate_lnet(des, scope);
1645 		  if (sig == 0) {
1646 			cerr << pins[idx]->get_fileline() << ": error: "
1647 			     << "Output port expression must support "
1648 			     << "continuous assignment." << endl;
1649 			cerr << pins[idx]->get_fileline() << ":      : Port "
1650 			     << (idx+1) << " (" << port_name << ") of "
1651 			     << rmod->mod_name() << " is connected to "
1652 			     << *pins[idx] << endl;
1653 			des->errors += 1;
1654 			continue;
1655 		  }
1656 
1657 		    // If we have a real port driving a bit/vector signal
1658 		    // then we convert the real value using the appropriate
1659 		    // width cast. Since a real is only one bit the whole
1660 		    // thing needs to go to each instance when arrayed.
1661 		  if ((sig->data_type() != IVL_VT_REAL ) &&
1662 		      !prts.empty() && (prts[0]->data_type() == IVL_VT_REAL )) {
1663 			if (sig->vector_width() % instance.size() != 0) {
1664 			      cerr << pins[idx]->get_fileline() << ": error: "
1665 			              "When automatically converting a real "
1666 			              "port of an arrayed instance to a bit "
1667 			              "signal" << endl;
1668 			      cerr << pins[idx]->get_fileline() << ":      : "
1669 			              "the signal width ("
1670 			           << sig->vector_width() << ") must be an "
1671 			              "integer multiple of the instance count ("
1672 			           << instance.size() << ")." << endl;
1673 			      des->errors += 1;
1674 			      continue;
1675 			}
1676 			prts_vector_width = sig->vector_width();
1677 			for (unsigned pidx = 0; pidx < prts.size(); pidx += 1) {
1678 			      prts[pidx] = cast_to_int4(des, scope, prts[pidx],
1679 			                               prts_vector_width /
1680 			                               instance.size());
1681 			}
1682 		  }
1683 
1684 		    // If we have a bit/vector port driving a single real
1685 		    // signal then we convert the value to a real.
1686 		  if ((sig->data_type() == IVL_VT_REAL ) &&
1687 		      !prts.empty() && (prts[0]->data_type() != IVL_VT_REAL )) {
1688 			prts_vector_width -= prts[0]->vector_width() - 1;
1689 			prts[0] = cast_to_real(des, scope, prts[0]);
1690 			  // No support for multiple real drivers.
1691 			if (instance.size() != 1) {
1692 			      cerr << pins[idx]->get_fileline() << ": error: "
1693 			           << "Cannot connect an arrayed instance of "
1694 			              "module " << rmod->mod_name() << " to "
1695 			              "real signal " << sig->name() << "."
1696 			           << endl;
1697 			      des->errors += 1;
1698 			      continue;
1699 			}
1700 		  }
1701 
1702 		    // If we have a 4-state bit/vector port driving a
1703 		    // 2-state signal then we convert the value to 2-state.
1704 		  if ((sig->data_type() == IVL_VT_BOOL ) &&
1705 		      !prts.empty() && (prts[0]->data_type() == IVL_VT_LOGIC )) {
1706 			for (unsigned pidx = 0; pidx < prts.size(); pidx += 1) {
1707 			      prts[pidx] = cast_to_int2(des, scope, prts[pidx],
1708 			                                prts[pidx]->vector_width());
1709 			}
1710 		  }
1711 
1712 		    // A real to real connection is not allowed for arrayed
1713 		    // instances. You cannot have multiple real drivers.
1714 		  if ((sig->data_type() == IVL_VT_REAL ) &&
1715 		      !prts.empty() && (prts[0]->data_type() == IVL_VT_REAL ) &&
1716 		      instance.size() != 1) {
1717 			cerr << pins[idx]->get_fileline() << ": error: "
1718 			     << "An arrayed instance of " << rmod->mod_name()
1719 			     << " cannot have a real port (port " << (idx+1)
1720 			     << " : " << port_name << ") connected to a "
1721 			        "real signal (" << sig->name() << ")." << endl;
1722 			des->errors += 1;
1723 			continue;
1724 		  }
1725 
1726 	    }
1727 
1728 	    assert(sig);
1729 
1730 #ifndef NDEBUG
1731 	    if ((! prts.empty())
1732 		&& (ptype != NetNet::PINPUT)) {
1733 		  assert(sig->type() != NetNet::REG);
1734 	    }
1735 #endif
1736 
1737 	      /* If we are working with an instance array, then the
1738 		 signal width must match the port width exactly. */
1739 	    if ((instance.size() != 1)
1740 		&& (sig->vector_width() != prts_vector_width)
1741 		&& (sig->vector_width() != prts_vector_width/instance.size())) {
1742 		  cerr << pins[idx]->get_fileline() << ": error: "
1743 		       << "Port expression width " << sig->vector_width()
1744 		       << " does not match expected width "<< prts_vector_width
1745 		       << " or " << (prts_vector_width/instance.size())
1746 		       << "." << endl;
1747 		  des->errors += 1;
1748 		  continue;
1749 	    }
1750 
1751 	    if (debug_elaborate) {
1752 		  cerr << get_fileline() << ": debug: " << get_name()
1753 		       << ": Port " << (idx+1) << " (" << port_name
1754 		       << ") has vector width of " << prts_vector_width
1755 		       << "." << endl;
1756 	    }
1757 
1758 	      // Check that the parts have matching pin counts. If
1759 	      // not, they are different widths. Note that idx is 0
1760 	      // based, but users count parameter positions from 1.
1761 	    if ((instance.size() == 1)
1762 		&& (prts_vector_width != sig->vector_width())) {
1763 		  bool as_signed = false;
1764 
1765 		  switch (ptype) {
1766 		    case NetNet::POUTPUT:
1767 			as_signed = prts[0]->get_signed();
1768 			break;
1769 		    case NetNet::PINPUT:
1770 			as_signed = sig->get_signed();
1771 			break;
1772 		    case NetNet::PINOUT:
1773 			  /* This may not be correct! */
1774 			as_signed = prts[0]->get_signed() && sig->get_signed();
1775 			break;
1776 		      case NetNet::PREF:
1777 			ivl_assert(*this, 0);
1778 			break;
1779 		    default:
1780 			ivl_assert(*this, 0);
1781 		  }
1782 
1783 		  cerr << get_fileline() << ": warning: Port " << (idx+1)
1784 		       << " (" << port_name << ") of "
1785 		       << type_ << " expects " << prts_vector_width <<
1786 			" bits, got " << sig->vector_width() << "." << endl;
1787 
1788 		    // Delete this when inout ports pad correctly.
1789 		  if (ptype == NetNet::PINOUT) {
1790 		     if (prts_vector_width > sig->vector_width()) {
1791 			cerr << get_fileline() << ":        : Leaving "
1792 			     << (prts_vector_width-sig->vector_width())
1793 			     << " high bits of the port unconnected."
1794 			     << endl;
1795 		     } else {
1796 			cerr << get_fileline() << ":        : Leaving "
1797 			     << (sig->vector_width()-prts_vector_width)
1798 			     << " high bits of the expression dangling."
1799 			     << endl;
1800 		     }
1801 		    // Keep the if, but delete the "} else" when fixed.
1802 		  } else if (prts_vector_width > sig->vector_width()) {
1803 			cerr << get_fileline() << ":        : Padding ";
1804 			if (as_signed) cerr << "(signed) ";
1805 			cerr << (prts_vector_width-sig->vector_width())
1806 			     << " high bits of the port."
1807 			     << endl;
1808 		  } else {
1809 			if (ptype == NetNet::PINPUT) {
1810 			      cerr << get_fileline() << ":        : Pruning ";
1811 			} else {
1812 			      cerr << get_fileline() << ":        : Padding ";
1813 			}
1814 			if (as_signed) cerr << "(signed) ";
1815 			cerr << (sig->vector_width()-prts_vector_width)
1816 			     << " high bits of the expression."
1817 			     << endl;
1818 		  }
1819 
1820 		  sig = resize_net_to_port_(des, scope, sig, prts_vector_width,
1821 					    ptype, as_signed);
1822 	    }
1823 
1824 	      // Connect the sig expression that is the context of the
1825 	      // module instance to the ports of the elaborated module.
1826 
1827 	      // The prts_pin_count variable is the total width of the
1828 	      // port and is the maximum number of connections to
1829 	      // make. sig is the elaborated expression that connects
1830 	      // to that port. If sig has too few pins, then reduce
1831 	      // the number of connections to make.
1832 
1833 	      // Connect this many of the port pins. If the expression
1834 	      // is too small, then reduce the number of connects.
1835 	    unsigned ccount = prts_vector_width;
1836 	    if (instance.size() == 1 && sig->vector_width() < ccount)
1837 		  ccount = sig->vector_width();
1838 
1839 	      // Now scan the concatenation that makes up the port,
1840 	      // connecting pins until we run out of port pins or sig
1841 	      // pins. The sig object is the NetNet that is connected
1842 	      // to the port from the outside, and the prts object is
1843 	      // an array of signals to be connected to the sig.
1844 
1845 	    NetConcat*ctmp;
1846 
1847 	    if (prts.size() == 1) {
1848 
1849 		    // The simplest case, there are no
1850 		    // parts/concatenations on the inside of the
1851 		    // module, so the port and sig need simply be
1852 		    // connected directly. But don't collapse ports
1853 		    // that are a delay path destination, to avoid
1854 		    // the delay being applied to other drivers of
1855 		    // the external signal.
1856 		  if (prts[0]->delay_paths() > 0) {
1857 			isolate_and_connect(des, scope, this, prts[0], sig, ptype);
1858 		  } else {
1859 			connect(prts[0]->pin(0), sig->pin(0));
1860 		  }
1861 
1862 	    } else if (sig->vector_width()==prts_vector_width/instance.size()
1863 		       && prts.size()/instance.size() == 1) {
1864 
1865 		  if (debug_elaborate){
1866 			cerr << get_fileline() << ": debug: " << get_name()
1867 			     << ": Replicating " << prts_vector_width
1868 			     << " bits across all "
1869 			     << prts_vector_width/instance.size()
1870 			     << " sub-ports." << endl;
1871 		  }
1872 
1873 		    // The signal width is exactly the width of a
1874 		    // single instance of the port. In this case,
1875 		    // connect the sig to all the ports identically.
1876 		  for (unsigned ldx = 0 ;  ldx < prts.size() ;	ldx += 1) {
1877 			if (prts[ldx]->delay_paths() > 0) {
1878 			      isolate_and_connect(des, scope, this, prts[ldx], sig, ptype);
1879 			} else {
1880 			      connect(prts[ldx]->pin(0), sig->pin(0));
1881 			}
1882 		  }
1883 
1884 	    } else switch (ptype) {
1885 		case NetNet::POUTPUT:
1886 		  ctmp = new NetConcat(scope, scope->local_symbol(),
1887 				       prts_vector_width, prts.size());
1888 		  ctmp->set_line(*this);
1889 		  des->add_node(ctmp);
1890 		  connect(ctmp->pin(0), sig->pin(0));
1891 		  for (unsigned ldx = 0 ;  ldx < prts.size() ;  ldx += 1) {
1892 			connect(ctmp->pin(ldx+1),
1893 				prts[prts.size()-ldx-1]->pin(0));
1894 		  }
1895 		  break;
1896 
1897 		case NetNet::PINPUT:
1898 		  if (debug_elaborate){
1899 			cerr << get_fileline() << ": debug: " << get_name()
1900 			     << ": Dividing " << prts_vector_width
1901 			     << " bits across all "
1902 			     << prts_vector_width/instance.size()
1903 			     << " input sub-ports of port "
1904 			     << (idx+1) << "." << endl;
1905 		  }
1906 
1907 		  for (unsigned ldx = 0, spin = 0 ;
1908 		       ldx < prts.size() ;  ldx += 1) {
1909 			NetNet*sp = prts[prts.size()-ldx-1];
1910 			NetPartSelect*ptmp = new NetPartSelect(sig, spin,
1911 							   sp->vector_width(),
1912 							   NetPartSelect::VP);
1913 			ptmp->set_line(*this);
1914 			des->add_node(ptmp);
1915 			connect(ptmp->pin(0), sp->pin(0));
1916 			spin += sp->vector_width();
1917 		  }
1918 		  break;
1919 
1920 		case NetNet::PINOUT:
1921 		  for (unsigned ldx = 0, spin = 0 ;
1922 		       ldx < prts.size() ;  ldx += 1) {
1923 			NetNet*sp = prts[prts.size()-ldx-1];
1924 			NetTran*ttmp = new NetTran(scope,
1925 			                           scope->local_symbol(),
1926 			                           sig->vector_width(),
1927 			                           sp->vector_width(),
1928 			                           spin);
1929 			ttmp->set_line(*this);
1930 			des->add_node(ttmp);
1931 			connect(ttmp->pin(0), sig->pin(0));
1932 			connect(ttmp->pin(1), sp->pin(0));
1933 			spin += sp->vector_width();
1934 		  }
1935 		  break;
1936 
1937 		case NetNet::PREF:
1938 		  cerr << get_fileline() << ": sorry: "
1939 		       << "Reference ports not supported yet." << endl;
1940 		  des->errors += 1;
1941 		  break;
1942 
1943 		case NetNet::PIMPLICIT:
1944 		  cerr << get_fileline() << ": internal error: "
1945 		       << "Unexpected IMPLICIT port" << endl;
1946 		  des->errors += 1;
1947 		  break;
1948 		case NetNet::NOT_A_PORT:
1949 		  cerr << get_fileline() << ": internal error: "
1950 		       << "Unexpected NOT_A_PORT port." << endl;
1951 		  des->errors += 1;
1952 		  break;
1953 	    }
1954 
1955       }
1956 
1957 }
1958 
calculate_instance_count_(Design * des,NetScope * scope,long & high,long & low,perm_string name) const1959 unsigned PGModule::calculate_instance_count_(Design*des, NetScope*scope,
1960                                              long&high, long&low,
1961                                              perm_string name) const
1962 {
1963       unsigned count = 1;
1964       high = 0;
1965       low = 0;
1966 
1967 	/* If the Verilog source has a range specification for the UDP, then
1968 	 * I am expected to make more than one gate. Figure out how many are
1969 	 * desired. */
1970       if (msb_) {
1971 	    NetExpr*msb_exp = elab_and_eval(des, scope, msb_, -1, true);
1972 	    NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_, -1, true);
1973 
1974 	    NetEConst*msb_con = dynamic_cast<NetEConst*>(msb_exp);
1975 	    NetEConst*lsb_con = dynamic_cast<NetEConst*>(lsb_exp);
1976 
1977 	    if (msb_con == 0) {
1978 		  cerr << get_fileline() << ": error: Unable to evaluate "
1979 			"expression " << *msb_ << endl;
1980 		  des->errors += 1;
1981 		  return 0;
1982 	    }
1983 
1984 	    if (lsb_con == 0) {
1985 		  cerr << get_fileline() << ": error: Unable to evaluate "
1986 			"expression " << *lsb_ << endl;
1987 		  des->errors += 1;
1988 		  return 0;
1989 	    }
1990 
1991 	    verinum msb = msb_con->value();
1992 	    verinum lsb = lsb_con->value();
1993 
1994 	    delete msb_exp;
1995 	    delete lsb_exp;
1996 
1997 	    if (msb.as_long() > lsb.as_long())
1998 		  count = msb.as_long() - lsb.as_long() + 1;
1999 	    else
2000 		  count = lsb.as_long() - msb.as_long() + 1;
2001 
2002 	    low = lsb.as_long();
2003 	    high = msb.as_long();
2004 
2005 	    if (debug_elaborate) {
2006 		  cerr << get_fileline() << ": debug: PGModule: Make range "
2007 		       << "[" << high << ":" << low << "]" << " of "
2008 		       << count << " UDPs for " << name << endl;
2009 	    }
2010       }
2011 
2012       return count;
2013 }
2014 
2015 /*
2016  * From a UDP definition in the source, make a NetUDP
2017  * object. Elaborate the pin expressions as netlists, then connect
2018  * those networks to the pins.
2019  */
2020 
elaborate_udp_(Design * des,PUdp * udp,NetScope * scope) const2021 void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
2022 {
2023       NetExpr*rise_expr =0, *fall_expr =0, *decay_expr =0;
2024 
2025       perm_string my_name = get_name();
2026       if (my_name == 0)
2027 	    my_name = scope->local_symbol();
2028 
2029 	/* When the parser notices delay expressions in front of a
2030 	   module or primitive, it interprets them as parameter
2031 	   overrides. Correct that misconception here. */
2032       if (overrides_) {
2033 	    if (overrides_->size() > 2) {
2034 		  cerr << get_fileline() << ": error: UDPs take at most two "
2035 		          "delay arguments." << endl;
2036 		  des->errors += 1;
2037 	    } else {
2038 		  PDelays tmp_del;
2039 		  tmp_del.set_delays(overrides_, false);
2040 		  tmp_del.eval_delays(des, scope, rise_expr, fall_expr,
2041 		                      decay_expr, true);
2042 	    }
2043       }
2044 
2045       long low = 0, high = 0;
2046       unsigned inst_count = calculate_instance_count_(des, scope, high, low,
2047                                                       my_name);
2048       if (inst_count == 0) return;
2049 
2050       if (inst_count != 1) {
2051 	    cerr << get_fileline() << ": sorry: UDPs with a range ("
2052 	         << my_name << " [" << high << ":" << low << "]) are "
2053 	         << "not supported." << endl;
2054 	    des->errors += 1;
2055 	    return;
2056       }
2057 
2058       assert(udp);
2059       NetUDP*net = new NetUDP(scope, my_name, udp->ports.count(), udp);
2060       net->set_line(*this);
2061       net->rise_time(rise_expr);
2062       net->fall_time(fall_expr);
2063       net->decay_time(decay_expr);
2064 
2065       struct attrib_list_t*attrib_list;
2066       unsigned attrib_list_n = 0;
2067       attrib_list = evaluate_attributes(attributes, attrib_list_n,
2068 					des, scope);
2069 
2070       for (unsigned adx = 0 ;  adx < attrib_list_n ;  adx += 1)
2071 	    net->attribute(attrib_list[adx].key, attrib_list[adx].val);
2072 
2073       delete[]attrib_list;
2074 
2075 
2076 	// This is the array of pin expressions, shuffled to match the
2077 	// order of the declaration. If the source instantiation uses
2078 	// bind by order, this is the same as the source
2079 	// list. Otherwise, the source list is rearranged by name
2080 	// binding into this list.
2081       vector<PExpr*>pins;
2082 
2083 	// Detect binding by name. If I am binding by name, then make
2084 	// up a pins array that reflects the positions of the named
2085 	// ports. If this is simply positional binding in the first
2086 	// place, then get the binding from the base class.
2087       if (pins_) {
2088 	    unsigned nexp = udp->ports.count();
2089 	    pins = vector<PExpr*>(nexp);
2090 
2091 	      // Scan the bindings, matching them with port names.
2092 	    for (unsigned idx = 0 ;  idx < npins_ ;  idx += 1) {
2093 
2094 		    // Given a binding, look at the module port names
2095 		    // for the position that matches the binding name.
2096 		  unsigned pidx = udp->find_port(pins_[idx].name);
2097 
2098 		    // If the port name doesn't exist, the find_port
2099 		    // method will return the port count. Detect that
2100 		    // as an error.
2101 		  if (pidx == nexp) {
2102 			cerr << get_fileline() << ": error: port ``" <<
2103 			      pins_[idx].name << "'' is not a port of "
2104 			     << get_name() << "." << endl;
2105 			des->errors += 1;
2106 			continue;
2107 		  }
2108 
2109 		    // If I already bound something to this port, then
2110 		    // the (*exp) array will already have a pointer
2111 		    // value where I want to place this expression.
2112 		  if (pins[pidx]) {
2113 			cerr << get_fileline() << ": error: port ``" <<
2114 			      pins_[idx].name << "'' already bound." <<
2115 			      endl;
2116 			des->errors += 1;
2117 			continue;
2118 		  }
2119 
2120 		    // OK, do the binding by placing the expression in
2121 		    // the right place.
2122 		  pins[pidx] = pins_[idx].parm;
2123 	    }
2124 
2125       } else {
2126 
2127 	      /* Otherwise, this is a positional list of port
2128 		 connections. In this case, the port count must be
2129 		 right. Check that is is, the get the pin list. */
2130 
2131 	    if (pin_count() != udp->ports.count()) {
2132 		  cerr << get_fileline() << ": error: Wrong number "
2133 			"of ports. Expecting " << udp->ports.count() <<
2134 			", got " << pin_count() << "."
2135 		       << endl;
2136 		  des->errors += 1;
2137 		  return;
2138 	    }
2139 
2140 	      // No named bindings, just use the positional list I
2141 	      // already have.
2142 	    assert(pin_count() == udp->ports.count());
2143 	    pins = get_pins();
2144       }
2145 
2146 
2147 	/* Handle the output port of the primitive special. It is an
2148 	   output port (the only output port) so must be passed an
2149 	   l-value net. */
2150       if (pins[0] == 0) {
2151 	    cerr << get_fileline() << ": warning: output port unconnected."
2152 		 << endl;
2153 
2154       } else {
2155 	    NetNet*sig = pins[0]->elaborate_lnet(des, scope);
2156 	    if (sig == 0) {
2157 		  cerr << get_fileline() << ": error: "
2158 		       << "Output port expression is not valid." << endl;
2159 		  cerr << get_fileline() << ":      : Output "
2160 		       << "port of " << udp->name_
2161 		       << " is " << udp->ports[0] << "." << endl;
2162 		  des->errors += 1;
2163 	    } else {
2164 		  connect(sig->pin(0), net->pin(0));
2165 	    }
2166 	    if (sig->vector_width() != 1) {
2167 		  cerr << get_fileline() << ": error: "
2168 		       << "Output port expression " << *pins[0]
2169 		       << " is too wide (" << sig->vector_width()
2170 		       << ") expected 1." << endl;
2171 		  des->errors += 1;
2172 	    }
2173       }
2174 
2175 	/* Run through the pins, making netlists for the pin
2176 	   expressions and connecting them to the pin in question. All
2177 	   of this is independent of the nature of the UDP. */
2178       for (unsigned idx = 1 ;  idx < net->pin_count() ;  idx += 1) {
2179 	    if (pins[idx] == 0)
2180 		  continue;
2181 
2182 	    NetExpr*expr_tmp = elab_and_eval(des, scope, pins[idx], 1);
2183 	    if (expr_tmp == 0) {
2184 		  cerr << "internal error: Expression too complicated "
2185 			"for elaboration:" << *pins[idx] << endl;
2186 		  continue;
2187 	    }
2188 	    NetNet*sig = expr_tmp->synthesize(des, scope, expr_tmp);
2189 	    ivl_assert(*this, sig);
2190 	    sig->set_line(*this);
2191 
2192 	    delete expr_tmp;
2193 
2194 	    connect(sig->pin(0), net->pin(idx));
2195 	    if (sig->vector_width() != 1) {
2196 		  cerr << get_fileline() << ": error: "
2197 		       << "Input port expression " << *pins[idx]
2198 		       << " is too wide (" << sig->vector_width()
2199 		       << ") expected 1." << endl;
2200 		  des->errors += 1;
2201 	    }
2202       }
2203 
2204 	// All done. Add the object to the design.
2205       des->add_node(net);
2206 }
2207 
2208 
elaborate_sig(Design * des,NetScope * scope) const2209 bool PGModule::elaborate_sig(Design*des, NetScope*scope) const
2210 {
2211       if (bound_type_) {
2212 	    return elaborate_sig_mod_(des, scope, bound_type_);
2213       }
2214 
2215 	// Look for the module type
2216       map<perm_string,Module*>::const_iterator mod = pform_modules.find(type_);
2217       if (mod != pform_modules.end())
2218 	    return elaborate_sig_mod_(des, scope, (*mod).second);
2219 
2220 	// elaborate_sig_udp_ currently always returns true so skip all this
2221 	// for now.
2222 #if 0
2223       map<perm_string,PUdp*>::const_iterator udp = pform_primitives.find(type_);
2224       if (udp != pform_primitives.end())
2225 	    return elaborate_sig_udp_(des, scope, (*udp).second);
2226 #endif
2227 
2228       return true;
2229 }
2230 
2231 
elaborate(Design * des,NetScope * scope) const2232 void PGModule::elaborate(Design*des, NetScope*scope) const
2233 {
2234       if (bound_type_) {
2235 	    elaborate_mod_(des, bound_type_, scope);
2236 	    return;
2237       }
2238 
2239 	// Look for the module type
2240       map<perm_string,Module*>::const_iterator mod = pform_modules.find(type_);
2241       if (mod != pform_modules.end()) {
2242 	    elaborate_mod_(des, (*mod).second, scope);
2243 	    return;
2244       }
2245 
2246 	// Try a primitive type
2247       map<perm_string,PUdp*>::const_iterator udp = pform_primitives.find(type_);
2248       if (udp != pform_primitives.end()) {
2249 	    assert((*udp).second);
2250 	    elaborate_udp_(des, (*udp).second, scope);
2251 	    return;
2252       }
2253 
2254       if (!ignore_missing_modules) {
2255         cerr << get_fileline() << ": internal error: Unknown module type: " <<
2256 	      type_ << endl;
2257       }
2258 }
2259 
elaborate_scope(Design * des,NetScope * sc) const2260 void PGModule::elaborate_scope(Design*des, NetScope*sc) const
2261 {
2262 	// If the module type is known by design, then go right to it.
2263       if (bound_type_) {
2264 	    elaborate_scope_mod_(des, bound_type_, sc);
2265 	    return;
2266       }
2267 
2268 	// Look for the module type
2269       map<perm_string,Module*>::const_iterator mod = pform_modules.find(type_);
2270       if (mod != pform_modules.end()) {
2271 	    elaborate_scope_mod_(des, mod->second, sc);
2272 	    return;
2273       }
2274 
2275 	// Try a primitive type
2276       map<perm_string,PUdp*>::const_iterator udp = pform_primitives.find(type_);
2277       if (udp != pform_primitives.end())
2278 	    return;
2279 
2280 	// Not a module or primitive that I know about yet, so try to
2281 	// load a library module file (which parses some new Verilog
2282 	// code) and try again.
2283       int parser_errors = 0;
2284       if (load_module(type_, parser_errors)) {
2285 
2286 	      // Try again to find the module type
2287 	    mod = pform_modules.find(type_);
2288 	    if (mod != pform_modules.end()) {
2289 		  elaborate_scope_mod_(des, mod->second, sc);
2290 		  return;
2291 	    }
2292 
2293 	      // Try again to find a primitive type
2294 	    udp = pform_primitives.find(type_);
2295 	    if (udp != pform_primitives.end())
2296 		  return;
2297       }
2298 
2299       if (parser_errors) {
2300             cerr << get_fileline() << ": error: Failed to parse library file." << endl;
2301             des->errors += parser_errors + 1;
2302       }
2303 
2304 	// Not a module or primitive that I know about or can find by
2305 	// any means, so give up.
2306       if (!ignore_missing_modules) {
2307         cerr << get_fileline() << ": error: Unknown module type: " << type_ << endl;
2308         missing_modules[type_] += 1;
2309         des->errors += 1;
2310       }
2311 }
2312 
2313 
elaborate(Design * des,NetScope *) const2314 NetProc* Statement::elaborate(Design*des, NetScope*) const
2315 {
2316       cerr << get_fileline() << ": internal error: elaborate: "
2317 	    "What kind of statement? " << typeid(*this).name() << endl;
2318       NetProc*cur = new NetProc;
2319       des->errors += 1;
2320       return cur;
2321 }
2322 
2323 
elaborate_lval(Design * des,NetScope * scope) const2324 NetAssign_* PAssign_::elaborate_lval(Design*des, NetScope*scope) const
2325 {
2326 	// A function called as a task does not have an L-value.
2327       if (! lval_) {
2328 	      // The R-value must be a simple function call.
2329 	    assert (dynamic_cast<PECallFunction*>(rval_));
2330 	    PExpr::width_mode_t mode = PExpr::SIZED;
2331 	    rval_->test_width(des, scope, mode);
2332 	      // Create a L-value that matches the function return type.
2333 	    NetNet*tmp;
2334 	    netvector_t*tmp_vec = new netvector_t(rval_->expr_type(),
2335 	                                          rval_->expr_width()-1, 0,
2336 	                                          rval_->has_sign());
2337 
2338 	    if(rval_->expr_type() == IVL_VT_DARRAY) {
2339 		netdarray_t*darray = new netdarray_t(tmp_vec);
2340 		tmp = new NetNet(scope, scope->local_symbol(), NetNet::REG, darray);
2341 	    } else {
2342 		tmp = new NetNet(scope, scope->local_symbol(), NetNet::REG, tmp_vec);
2343 	    }
2344 
2345 	    tmp->set_file(rval_->get_file());
2346 	    tmp->set_lineno(rval_->get_lineno());
2347 	    NetAssign_*lv = new NetAssign_(tmp);
2348 	    return lv;
2349       }
2350 
2351       if (debug_elaborate) {
2352 	    cerr << get_fileline() << ": PAssign_::elaborate_lval: "
2353 		 << "lval_ = " << *lval_ << endl;
2354 	    cerr << get_fileline() << ": PAssign_::elaborate_lval: "
2355 		 << "lval_ expr type = " << typeid(*lval_).name() << endl;
2356       }
2357 
2358       return lval_->elaborate_lval(des, scope, false, false);
2359 }
2360 
elaborate_rval_(Design * des,NetScope * scope,ivl_type_t net_type) const2361 NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
2362 				   ivl_type_t net_type) const
2363 {
2364       ivl_assert(*this, rval_);
2365 
2366       NetExpr*rv = elab_and_eval(des, scope, rval_, net_type, is_constant_);
2367 
2368       if (!is_constant_ || !rv) return rv;
2369 
2370       cerr << get_fileline() << ": error: "
2371             "The RHS expression must be constant." << endl;
2372       cerr << get_fileline() << "       : "
2373             "This expression violates the rule: " << *rv << endl;
2374       des->errors += 1;
2375       delete rv;
2376       return 0;
2377 }
2378 
elaborate_rval_(Design * des,NetScope * scope,ivl_type_t lv_net_type,ivl_variable_type_t lv_type,unsigned lv_width,bool force_unsigned) const2379 NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
2380 				   ivl_type_t lv_net_type,
2381 				   ivl_variable_type_t lv_type,
2382 				   unsigned lv_width,
2383 				   bool force_unsigned) const
2384 {
2385       ivl_assert(*this, rval_);
2386 
2387 	// Don't have a good value for the lv_net_type argument to
2388 	// elaborate_rval_expr, so punt and pass nil. In the future we
2389 	// should look into fixing calls to this method to pass a
2390 	// net_type instead of the separate lv_width/lv_type values.
2391       NetExpr*rv = elaborate_rval_expr(des, scope, lv_net_type, lv_type, lv_width,
2392 				       rval(), is_constant_, force_unsigned);
2393 
2394       if (!is_constant_ || !rv) return rv;
2395 
2396       if (dynamic_cast<NetEConst*>(rv)) return rv;
2397       if (dynamic_cast<NetECReal*>(rv)) return rv;
2398 
2399       cerr << get_fileline() << ": error: "
2400             "The RHS expression must be constant." << endl;
2401       cerr << get_fileline() << "       : "
2402             "This expression violates the rule: " << *rv << endl;
2403       des->errors += 1;
2404       delete rv;
2405       return 0;
2406 }
2407 
2408 /*
2409  * This function elaborates delay expressions. This is a little
2410  * different from normal elaboration because the result may need to be
2411  * scaled.
2412  */
elaborate_delay_expr(PExpr * expr,Design * des,NetScope * scope)2413 static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
2414 {
2415       NetExpr*dex = elab_and_eval(des, scope, expr, -1);
2416 
2417 	// If the elab_and_eval returns nil, then the function
2418 	// failed. It should already have printed an error message,
2419 	// but we can add some detail. Lets add the error count, just
2420 	// in case.
2421       if (dex == 0) {
2422 	    cerr << expr->get_fileline() << ": error: "
2423 		 << "Unable to elaborate (or evaluate) delay expression."
2424 		 << endl;
2425 	    des->errors += 1;
2426 	    return 0;
2427       }
2428 
2429       check_for_inconsistent_delays(scope);
2430 
2431 	/* If the delay expression is a real constant or vector
2432 	   constant, then evaluate it, scale it to the local time
2433 	   units, and return an adjusted NetEConst. */
2434 
2435       if (NetECReal*tmp = dynamic_cast<NetECReal*>(dex)) {
2436 	    uint64_t delay = get_scaled_time_from_real(des, scope, tmp);
2437 
2438 	    delete tmp;
2439 	    NetEConst*tmp2 = new NetEConst(verinum(delay, 64));
2440 	    tmp2->set_line(*expr);
2441 	    return tmp2;
2442       }
2443 
2444 
2445       if (NetEConst*tmp = dynamic_cast<NetEConst*>(dex)) {
2446 	    verinum fn = tmp->value();
2447 	    uint64_t delay = des->scale_to_precision(fn.as_ulong64(), scope);
2448 
2449 	    delete tmp;
2450 	    NetEConst*tmp2 = new NetEConst(verinum(delay, 64));
2451 	    tmp2->set_line(*expr);
2452 	    return tmp2;
2453       }
2454 
2455 
2456 	/* The expression is not constant, so generate an expanded
2457 	   expression that includes the necessary scale shifts, and
2458 	   return that expression. */
2459       ivl_assert(*expr, dex);
2460       if (dex->expr_type() == IVL_VT_REAL) {
2461 	      // Scale the real value.
2462 	    int shift = scope->time_unit() - scope->time_precision();
2463 	    assert(shift >= 0);
2464 	    double round = 1;
2465 	    for (int lp = 0; lp < shift; lp += 1) round *= 10.0;
2466 
2467 	    NetExpr*scal_val = new NetECReal(verireal(round));
2468 	    scal_val->set_line(*expr);
2469 	    dex = new NetEBMult('*', dex, scal_val, 1, true);
2470 	    dex->set_line(*expr);
2471 
2472 	      // Cast this part of the expression to an integer.
2473 	    dex = new NetECast('v', dex, 64, false);
2474 	    dex->set_line(*expr);
2475 
2476 	      // Now scale the integer value.
2477 	    shift = scope->time_precision() - des->get_precision();
2478 	    assert(shift >= 0);
2479 	    uint64_t scale = 1;
2480 	    for (int lp = 0; lp < shift; lp += 1) scale *= 10;
2481 
2482 	    scal_val = new NetEConst(verinum(scale, 64));
2483 	    scal_val->set_line(*expr);
2484 	    dex = new NetEBMult('*', dex, scal_val, 64, false);
2485 	    dex->set_line(*expr);
2486       } else {
2487 	    int shift = scope->time_unit() - des->get_precision();
2488 	    assert(shift >= 0);
2489 	    uint64_t scale = 1;
2490 	    for (int lp = 0; lp < shift; lp += 1) scale *= 10;
2491 
2492 	    NetExpr*scal_val = new NetEConst(verinum(scale, 64));
2493 	    scal_val->set_line(*expr);
2494 	    dex = new NetEBMult('*', dex, scal_val, 64, false);
2495 	    dex->set_line(*expr);
2496       }
2497 
2498       return dex;
2499 }
2500 
elaborate_compressed_(Design * des,NetScope * scope) const2501 NetProc* PAssign::elaborate_compressed_(Design*des, NetScope*scope) const
2502 {
2503       ivl_assert(*this, ! delay_);
2504       ivl_assert(*this, ! count_);
2505       ivl_assert(*this, ! event_);
2506 
2507       NetAssign_*lv = elaborate_lval(des, scope);
2508       if (lv == 0) return 0;
2509 
2510 	// Compressed assignments should behave identically to the
2511 	// equivalent uncompressed assignments. This means we need
2512 	// to take the type of the LHS into account when determining
2513 	// the type of the RHS expression.
2514       bool force_unsigned;
2515       switch (op_) {
2516 	  case 'l':
2517 	  case 'r':
2518 	  case 'R':
2519 	      // The right-hand operand of shift operations is
2520 	      // self-determined.
2521 	    force_unsigned = false;
2522 	    break;
2523 	  default:
2524 	    force_unsigned = !lv->get_signed();
2525 	    break;
2526       }
2527       NetExpr*rv = elaborate_rval_(des, scope, 0, lv->expr_type(),
2528 				   count_lval_width(lv), force_unsigned);
2529       if (rv == 0) return 0;
2530 
2531 	// The ivl_target API doesn't support signalling the type
2532 	// of a lval, so convert arithmetic shifts into logical
2533 	// shifts now if the lval is unsigned.
2534       char op = op_;
2535       if ((op == 'R') && !lv->get_signed())
2536 	    op = 'r';
2537 
2538       NetAssign*cur = new NetAssign(lv, op, rv);
2539       cur->set_line(*this);
2540 
2541       return cur;
2542 }
2543 
2544 /*
2545  * Assignments within program blocks can only write to certain types
2546  * of variables. We can only write to:
2547  *    - variables in a program block
2548  *    - static properties of a class
2549  */
lval_not_program_variable(const NetAssign_ * lv)2550 static bool lval_not_program_variable(const NetAssign_*lv)
2551 {
2552       while (lv) {
2553 	    NetScope*sig_scope = lv->scope();
2554 	    if (! sig_scope->program_block() && sig_scope->type()!=NetScope::CLASS)
2555 		  return true;
2556 
2557 	    lv = lv->more;
2558       }
2559       return false;
2560 }
2561 
elaborate(Design * des,NetScope * scope) const2562 NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
2563 {
2564       assert(scope);
2565 
2566 	/* If this is a compressed assignment, then handle the
2567 	   elaboration in a specialized function. */
2568       if (op_ != 0)
2569 	    return elaborate_compressed_(des, scope);
2570 
2571 	/* elaborate the lval. This detects any part selects and mux
2572 	   expressions that might exist. */
2573       NetAssign_*lv = elaborate_lval(des, scope);
2574       if (lv == 0) return 0;
2575 
2576       if (scope->program_block() && lval_not_program_variable(lv)) {
2577 	    cerr << get_fileline() << ": error: Blocking assignments to "
2578 		 << "non-program variables are not allowed." << endl;
2579 	    des->errors += 1;
2580       }
2581 
2582 	/* If there is an internal delay expression, elaborate it. */
2583       NetExpr*delay = 0;
2584       if (delay_ != 0)
2585 	    delay = elaborate_delay_expr(delay_, des, scope);
2586 
2587       NetExpr*rv;
2588       const ivl_type_s*lv_net_type = lv->net_type();
2589 
2590       if (debug_elaborate) {
2591 	    cerr << get_fileline() << ": PAssign::elaborate: ";
2592 	    if (lv_net_type)
2593 		  cerr << "lv_net_type=" << *lv_net_type << endl;
2594 	    else
2595 		  cerr << "lv_net_type=<nil>" << endl;
2596       }
2597 
2598 	/* If the l-value is a compound type of some sort, then use
2599 	   the newer net_type form of the elaborate_rval_ method to
2600 	   handle the new types. */
2601       if (dynamic_cast<const netclass_t*> (lv_net_type)) {
2602 	    ivl_assert(*this, lv->more==0);
2603 	    rv = elaborate_rval_(des, scope, lv_net_type);
2604 
2605       } else if (const netdarray_t*dtype = dynamic_cast<const netdarray_t*> (lv_net_type)) {
2606 	    ivl_assert(*this, lv->more==0);
2607 	    if (debug_elaborate) {
2608 		  if (lv->word())
2609 			cerr << get_fileline() << ": PAssign::elaborate: "
2610 			     << "lv->word() = " << *lv->word() << endl;
2611 		  else
2612 			cerr << get_fileline() << ": PAssign::elaborate: "
2613 			     << "lv->word() = <nil>" << endl;
2614 	    }
2615 	    ivl_type_t use_lv_type = lv_net_type;
2616 	    if (lv->word())
2617 		  use_lv_type = dtype->element_type();
2618 
2619 	    rv = elaborate_rval_(des, scope, use_lv_type);
2620 
2621       } else if (const netuarray_t*utype = dynamic_cast<const netuarray_t*>(lv_net_type)) {
2622 	    ivl_assert(*this, lv->more==0);
2623 	    if (debug_elaborate) {
2624 		  if (lv->word())
2625 			cerr << get_fileline() << ": PAssign::elaborate: "
2626 			     << "lv->word() = " << *lv->word() << endl;
2627 		  else
2628 			cerr << get_fileline() << ": PAssign::elaborate: "
2629 			     << "lv->word() = <nil>" << endl;
2630 	    }
2631 	    ivl_type_t use_lv_type = lv_net_type;
2632 	    ivl_assert(*this, lv->word());
2633 	    use_lv_type = utype->element_type();
2634 
2635 	    ivl_assert(*this, use_lv_type);
2636 	    rv = elaborate_rval_(des, scope, use_lv_type);
2637 
2638       } else {
2639 	      /* Elaborate the r-value expression, then try to evaluate it. */
2640 	    rv = elaborate_rval_(des, scope, lv_net_type, lv->expr_type(), count_lval_width(lv));
2641       }
2642 
2643       if (rv == 0) return 0;
2644       assert(rv);
2645 
2646       if (count_) assert(event_);
2647 
2648 	/* Rewrite delayed assignments as assignments that are
2649 	   delayed. For example, a = #<d> b; becomes:
2650 
2651 	     begin
2652 	        tmp = b;
2653 		#<d> a = tmp;
2654 	     end
2655 
2656 	   If the delay is an event delay, then the transform is
2657 	   similar, with the event delay replacing the time delay. It
2658 	   is an event delay if the event_ member has a value.
2659 
2660 	   This rewriting of the expression allows me to not bother to
2661 	   actually and literally represent the delayed assign in the
2662 	   netlist. The compound statement is exactly equivalent. */
2663 
2664       if (delay || event_) {
2665 	    unsigned wid = count_lval_width(lv);
2666 
2667 	    netvector_t*tmp2_vec = new netvector_t(rv->expr_type(),wid-1,0);
2668 	    NetNet*tmp = new NetNet(scope, scope->local_symbol(),
2669 				    NetNet::REG, tmp2_vec);
2670 	    tmp->local_flag(true);
2671 	    tmp->set_line(*this);
2672 
2673 	    NetESignal*sig = new NetESignal(tmp);
2674 
2675 	      /* Generate an assignment of the l-value to the temporary... */
2676 	    NetAssign_*lvt = new NetAssign_(tmp);
2677 
2678 	    NetAssign*a1 = new NetAssign(lvt, rv);
2679 	    a1->set_line(*this);
2680 
2681 	      /* Generate an assignment of the temporary to the r-value... */
2682 	    NetAssign*a2 = new NetAssign(lv, sig);
2683 	    a2->set_line(*this);
2684 
2685 	      /* Generate the delay statement with the final
2686 		 assignment attached to it. If this is an event delay,
2687 		 elaborate the PEventStatement. Otherwise, create the
2688 		 right NetPDelay object. For a repeat event control
2689 		 repeat the event and then do the final assignment.  */
2690 	    NetProc*st;
2691 	    if (event_) {
2692 		  if (count_) {
2693 			NetExpr*count = elab_and_eval(des, scope, count_, -1);
2694 			if (count == 0) {
2695 			      cerr << get_fileline() << ": Unable to "
2696 			              "elaborate repeat expression." << endl;
2697 			      des->errors += 1;
2698 			      return 0;
2699 			}
2700 			st = event_->elaborate(des, scope);
2701 			if (st == 0) {
2702 			      cerr << event_->get_fileline() << ": error: "
2703 			              "unable to elaborate event expression."
2704 			      << endl;
2705 			      des->errors += 1;
2706 			      return 0;
2707 			}
2708 			st->set_line(*this);
2709 
2710 			  // If the expression is a constant, handle
2711 			  // certain special iteration counts.
2712 			if (NetEConst*ce = dynamic_cast<NetEConst*>(count)) {
2713 			      long val = ce->value().as_long();
2714 				// We only need the real statement.
2715 			      if (val <= 0) {
2716 				    delete count;
2717 				    delete st;
2718 				    st = 0;
2719 
2720 				// We don't need the repeat statement.
2721 			      } else if (val == 1) {
2722 				    delete count;
2723 
2724 				// We need a repeat statement.
2725 			      } else {
2726 				    st = new NetRepeat(count, st);
2727 				    st->set_line(*this);
2728 			      }
2729 			} else {
2730 			      st = new NetRepeat(count, st);
2731 			      st->set_line(*this);
2732 			}
2733 		  } else {
2734 			st = event_->elaborate_st(des, scope, a2);
2735 			if (st == 0) {
2736 			      cerr << event_->get_fileline() << ": error: "
2737 			              "unable to elaborate event expression."
2738 			      << endl;
2739 			      des->errors += 1;
2740 			      return 0;
2741 			}
2742 			st->set_line(*this);
2743 		  }
2744 	    } else {
2745 		  NetPDelay*de = new NetPDelay(delay, a2);
2746 		  de->set_line(*this);
2747 		  st = de;
2748 	    }
2749 
2750 	      /* And build up the complex statement. */
2751 	    NetBlock*bl = new NetBlock(NetBlock::SEQU, 0);
2752 	    bl->append(a1);
2753 	    if (st) bl->append(st);
2754 	    if (count_) bl->append(a2);
2755 	    bl->set_line(*this);
2756 
2757 	    return bl;
2758       }
2759 
2760       if (lv->enumeration()) {
2761 	    if (! rv->enumeration()) {
2762 		  cerr << get_fileline() << ": error: "
2763 		          "This assignment requires an explicit cast." << endl;
2764 		  des->errors += 1;
2765 	    } else if (! lv->enumeration()->matches(rv->enumeration())) {
2766 		  cerr << get_fileline() << ": error: "
2767 		          "Enumeration type mismatch in assignment." << endl;
2768 		  des->errors += 1;
2769 	    }
2770       }
2771 
2772       NetAssign*cur = new NetAssign(lv, rv);
2773       cur->set_line(*this);
2774 
2775       return cur;
2776 }
2777 
2778 /*
2779  * Return true if any lvalue parts are in a program block scope.
2780  */
lval_is_program_variable(const NetAssign_ * lv)2781 static bool lval_is_program_variable(const NetAssign_*lv)
2782 {
2783       while (lv) {
2784 	    NetScope*sig_scope = lv->sig()->scope();
2785 	    if (sig_scope->program_block())
2786 		  return true;
2787 
2788 	    lv = lv->more;
2789       }
2790 
2791       return false;
2792 }
2793 
2794 /*
2795  * Elaborate non-blocking assignments. The statement is of the general
2796  * form:
2797  *
2798  *    <lval> <= #<delay> <rval> ;
2799  */
elaborate(Design * des,NetScope * scope) const2800 NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const
2801 {
2802       assert(scope);
2803 
2804       if (scope->in_func()) {
2805 	    cerr << get_fileline() << ": error: functions cannot have non "
2806 	            "blocking assignment statements." << endl;
2807 	    des->errors += 1;
2808 	    return 0;
2809       }
2810 
2811       if (scope->in_final()) {
2812 	    cerr << get_fileline() << ": error: final procedures cannot have "
2813 		    "non blocking assignment statements." << endl;
2814 	    des->errors += 1;
2815 	    return 0;
2816       }
2817 
2818       if (scope->is_auto() && lval()->has_aa_term(des, scope)) {
2819 	    cerr << get_fileline() << ": error: automatically allocated "
2820                     "variables may not be assigned values using non-blocking "
2821 	            "assignments." << endl;
2822 	    des->errors += 1;
2823 	    return 0;
2824       }
2825 
2826 	/* Elaborate the l-value. */
2827       NetAssign_*lv = elaborate_lval(des, scope);
2828       if (lv == 0) return 0;
2829 
2830       if (scope->program_block() && lval_is_program_variable(lv)) {
2831 	    cerr << get_fileline() << ": error: Non-blocking assignments to "
2832 		 << "program variables are not allowed." << endl;
2833 	    des->errors += 1;
2834 	      // This is an error, but we can let elaboration continue
2835 	      // because it would necessarily trigger other errors.
2836       }
2837 
2838       NetExpr*rv = elaborate_rval_(des, scope, 0, lv->expr_type(), count_lval_width(lv));
2839       if (rv == 0) return 0;
2840 
2841       NetExpr*delay = 0;
2842       if (delay_ != 0) {
2843 	    assert(count_ == 0 && event_ == 0);
2844 	    delay = elaborate_delay_expr(delay_, des, scope);
2845       }
2846 
2847       NetExpr*count = 0;
2848       NetEvWait*event = 0;
2849       if (count_ != 0 || event_ != 0) {
2850 	    if (count_ != 0) {
2851                   if (scope->is_auto() && count_->has_aa_term(des, scope)) {
2852                         cerr << get_fileline() << ": error: automatically "
2853                                 "allocated variables may not be referenced "
2854                                 "in intra-assignment event controls of "
2855                                 "non-blocking assignments." << endl;
2856                         des->errors += 1;
2857                         return 0;
2858                   }
2859 
2860 		  assert(event_ != 0);
2861 		  count = elab_and_eval(des, scope, count_, -1);
2862 		  if (count == 0) {
2863 			cerr << get_fileline() << ": Unable to elaborate "
2864 			        "repeat expression." << endl;
2865 			des->errors += 1;
2866 			return 0;
2867 		  }
2868 	    }
2869 
2870             if (scope->is_auto() && event_->has_aa_term(des, scope)) {
2871                   cerr << get_fileline() << ": error: automatically "
2872                           "allocated variables may not be referenced "
2873                           "in intra-assignment event controls of "
2874                           "non-blocking assignments." << endl;
2875                   des->errors += 1;
2876                   return 0;
2877             }
2878 
2879 	    NetProc*st = event_->elaborate(des, scope);
2880 	    if (st == 0) {
2881 		  cerr << get_fileline() << ": unable to elaborate "
2882 		          "event expression." << endl;
2883 		  des->errors += 1;
2884 		  return 0;
2885 	    }
2886 	    event = dynamic_cast<NetEvWait*>(st) ;
2887 	    assert(event);
2888 
2889 	      // Some constant values are special.
2890 	    if (NetEConst*ce = dynamic_cast<NetEConst*>(count)) {
2891 		  long val = ce->value().as_long();
2892 		    // We only need the assignment statement.
2893 		  if (val <= 0) {
2894 			delete count;
2895 			delete event;
2896 			count = 0;
2897 			event = 0;
2898 		    // We only need the event.
2899 		  } else if (val == 1) {
2900 			delete count;
2901 			count = 0;
2902 		  }
2903 	    }
2904       }
2905 
2906 	/* All done with this node. Mark its line number and check it in. */
2907       NetAssignNB*cur = new NetAssignNB(lv, rv, event, count);
2908       cur->set_delay(delay);
2909       cur->set_line(*this);
2910       return cur;
2911 }
2912 
2913 
2914 /*
2915  * This is the elaboration method for a begin-end block. Try to
2916  * elaborate the entire block, even if it fails somewhere. This way I
2917  * get all the error messages out of it. Then, if I detected a failure
2918  * then pass the failure up.
2919  */
elaborate(Design * des,NetScope * scope) const2920 NetProc* PBlock::elaborate(Design*des, NetScope*scope) const
2921 {
2922       assert(scope);
2923 
2924       NetBlock::Type type;
2925       switch (bl_type_) {
2926 	  case PBlock::BL_SEQ:
2927 	    type = NetBlock::SEQU;
2928 	    break;
2929 	  case PBlock::BL_PAR:
2930 	    type = NetBlock::PARA;
2931 	    break;
2932 	  case PBlock::BL_JOIN_NONE:
2933 	    type = NetBlock::PARA_JOIN_NONE;
2934 	    break;
2935 	  case PBlock::BL_JOIN_ANY:
2936 	    type = NetBlock::PARA_JOIN_ANY;
2937 	    break;
2938 	    // Added to remove a "type" uninitialized compiler warning.
2939 	    // This should never be reached since all the PBlock enumeration
2940 	    // cases are handled above.
2941 	  default:
2942 	    type = NetBlock::SEQU;
2943 	    assert(0);
2944       }
2945 
2946       NetScope*nscope = 0;
2947       if (pscope_name() != 0) {
2948 	    nscope = scope->child(hname_t(pscope_name()));
2949 	    if (nscope == 0) {
2950 		  cerr << get_fileline() << ": internal error: "
2951 			"unable to find block scope " << scope_path(scope)
2952 		       << "." << pscope_name() << endl;
2953 		  des->errors += 1;
2954 		  return 0;
2955 	    }
2956 	    assert(nscope);
2957       }
2958 
2959       NetBlock*cur = new NetBlock(type, nscope);
2960 
2961       if (nscope) {
2962 	      // Handle any variable initialization statements in this scope.
2963 	      // For automatic scopes these statements need to be executed
2964 	      // each time the block is entered, so add them to the main
2965 	      // block. For static scopes, put them in a separate process
2966 	      // that will be executed at the start of simulation.
2967 	    if (nscope->is_auto()) {
2968 		  for (unsigned idx = 0; idx < var_inits.size(); idx += 1) {
2969 			NetProc*tmp = var_inits[idx]->elaborate(des, nscope);
2970 			if (tmp) cur->append(tmp);
2971 		  }
2972 	    } else {
2973 		  elaborate_var_inits_(des, nscope);
2974 	    }
2975       }
2976 
2977       if (nscope == 0)
2978 	    nscope = scope;
2979 
2980 	// Handle the special case that the sequential block contains
2981 	// only one statement. There is no need to keep the block node.
2982 	// Also, don't elide named blocks, because they might be
2983 	// referenced elsewhere.
2984       if ((type == NetBlock::SEQU) && (list_.size() == 1) &&
2985           (pscope_name() == 0)) {
2986 	    assert(list_[0]);
2987 	    NetProc*tmp = list_[0]->elaborate(des, nscope);
2988 	    return tmp;
2989       }
2990 
2991       for (unsigned idx = 0 ;  idx < list_.size() ;  idx += 1) {
2992 	    assert(list_[idx]);
2993 	    NetProc*tmp = list_[idx]->elaborate(des, nscope);
2994 	      // If the statement fails to elaborate, then simply
2995 	      // ignore it. Presumably, the elaborate for the
2996 	      // statement already generated an error message and
2997 	      // marked the error count in the design so no need to
2998 	      // do any of that here.
2999 	    if (tmp == 0) {
3000 		  continue;
3001 	    }
3002 
3003 	      // If the result turns out to be a noop, then skip it.
3004 	    if (NetBlock*tbl = dynamic_cast<NetBlock*>(tmp))
3005 		  if (tbl->proc_first() == 0) {
3006 			delete tbl;
3007 			continue;
3008 		  }
3009 
3010 	    cur->append(tmp);
3011       }
3012 
3013 	// Update flags in parent scope.
3014       if (!nscope->is_const_func())
3015 	    scope->is_const_func(false);
3016       if (nscope->calls_sys_task())
3017 	    scope->calls_sys_task(true);
3018 
3019       cur->set_line(*this);
3020       return cur;
3021 }
3022 
test_case_width(Design * des,NetScope * scope,PExpr * pe,PExpr::width_mode_t & mode)3023 static int test_case_width(Design*des, NetScope*scope, PExpr*pe,
3024 			   PExpr::width_mode_t&mode)
3025 {
3026       unsigned expr_width = pe->test_width(des, scope, mode);
3027       if (debug_elaborate) {
3028 	    cerr << pe->get_fileline() << ": debug: test_width "
3029 		 << "of case expression " << *pe
3030 		 << endl;
3031 	    cerr << pe->get_fileline() << ":        "
3032 		 << "returns type=" << pe->expr_type()
3033 		 << ", width="      << expr_width
3034 		 << ", signed="     << pe->has_sign()
3035 		 << ", mode="       << PExpr::width_mode_name(mode)
3036 		 << endl;
3037       }
3038       return expr_width;
3039 }
3040 
elab_and_eval_case(Design * des,NetScope * scope,PExpr * pe,bool context_is_real,bool context_unsigned,unsigned context_width)3041 static NetExpr*elab_and_eval_case(Design*des, NetScope*scope, PExpr*pe,
3042 				  bool context_is_real, bool context_unsigned,
3043 				  unsigned context_width)
3044 {
3045       if (context_unsigned)
3046 	    pe->cast_signed(false);
3047 
3048       unsigned width = context_is_real ? pe->expr_width() : context_width;
3049       NetExpr*expr = pe->elaborate_expr(des, scope, width, PExpr::NO_FLAGS);
3050       if (expr == 0) return 0;
3051 
3052       if (context_is_real)
3053 	    expr = cast_to_real(expr);
3054 
3055       eval_expr(expr, context_width);
3056 
3057       return expr;
3058 }
3059 
3060 /*
3061  * Elaborate a case statement.
3062  */
elaborate(Design * des,NetScope * scope) const3063 NetProc* PCase::elaborate(Design*des, NetScope*scope) const
3064 {
3065       ivl_assert(*this, scope);
3066 
3067 	/* The type of the case expression and case item expressions is
3068 	   determined according to the following rules:
3069 
3070 	    - if any of the expressions is real, all the expressions are
3071 	      evaluated as real (non-real expressions will be treated as
3072 	      self-determined, then converted to real)
3073 
3074 	    - otherwise if any of the expressions is unsigned, all the
3075 	      expressions are evaluated as unsigned
3076 
3077 	    - otherwise all the expressions are evaluated as signed
3078 
3079 	   If the type is not real, the bit width is determined by the
3080 	   largest self-determined width of any of the expressions. */
3081 
3082       PExpr::width_mode_t context_mode = PExpr::SIZED;
3083       unsigned context_width = test_case_width(des, scope, expr_, context_mode);
3084       bool context_is_real = (expr_->expr_type() == IVL_VT_REAL);
3085       bool context_unsigned = !expr_->has_sign();
3086 
3087       for (unsigned idx = 0; idx < items_->count(); idx += 1) {
3088 
3089 	    PCase::Item*cur = (*items_)[idx];
3090 
3091 	    for (list<PExpr*>::iterator idx_expr = cur->expr.begin()
3092 		 ; idx_expr != cur->expr.end() ; ++idx_expr) {
3093 
3094 		  PExpr*cur_expr = *idx_expr;
3095 		  ivl_assert(*this, cur_expr);
3096 
3097 		  PExpr::width_mode_t cur_mode = PExpr::SIZED;
3098 		  unsigned cur_width = test_case_width(des, scope, cur_expr,
3099 						       cur_mode);
3100 		  if (cur_mode > context_mode)
3101 			context_mode = cur_mode;
3102 		  if (cur_width > context_width)
3103 			context_width = cur_width;
3104 		  if (cur_expr->expr_type() == IVL_VT_REAL)
3105 			context_is_real = true;
3106 		  if (!cur_expr->has_sign())
3107 			context_unsigned = true;
3108 	    }
3109       }
3110 
3111       if (context_is_real) {
3112 	    context_width = 1;
3113 	    context_unsigned = false;
3114 
3115       } else if (context_mode >= PExpr::LOSSLESS) {
3116 
3117 	      /* Expressions may choose a different size if they are
3118 		 in a lossless context, so we need to run through the
3119 		 process again to get the final expression width. */
3120 
3121 	    context_width = test_case_width(des, scope, expr_, context_mode);
3122 
3123 	    for (unsigned idx = 0; idx < items_->count(); idx += 1) {
3124 
3125 		  PCase::Item*cur = (*items_)[idx];
3126 
3127 		  for (list<PExpr*>::iterator idx_expr = cur->expr.begin()
3128 		       ; idx_expr != cur->expr.end() ; ++idx_expr) {
3129 
3130 			PExpr*cur_expr = *idx_expr;
3131 			ivl_assert(*this, cur_expr);
3132 
3133 			unsigned cur_width = test_case_width(des, scope, cur_expr,
3134 							     context_mode);
3135 			if (cur_width > context_width)
3136 			      context_width = cur_width;
3137 		  }
3138 	    }
3139 
3140 	    if (context_width < integer_width)
3141 		  context_width += 1;
3142       }
3143 
3144       if (debug_elaborate) {
3145 	    cerr << get_fileline() << ": debug: case context is ";
3146 	    if (context_is_real) {
3147 		  cerr << "real" << endl;
3148 	    } else {
3149 		  cerr << (context_unsigned ? "unsigned" : "signed")
3150 		       << " vector, width=" << context_width << endl;
3151 	    }
3152       }
3153       NetExpr*expr = elab_and_eval_case(des, scope, expr_,
3154 					context_is_real,
3155 					context_unsigned,
3156 					context_width);
3157       if (expr == 0) {
3158 	    cerr << get_fileline() << ": error: Unable to elaborate this case"
3159 		  " expression." << endl;
3160 	    return 0;
3161       }
3162 
3163 	/* Count the items in the case statement. Note that there may
3164 	   be some cases that have multiple guards. Count each as a
3165 	   separate item. */
3166       unsigned icount = 0;
3167       for (unsigned idx = 0 ;  idx < items_->count() ;  idx += 1) {
3168 	    PCase::Item*cur = (*items_)[idx];
3169 
3170 	    if (cur->expr.empty())
3171 		  icount += 1;
3172 	    else
3173 		  icount += cur->expr.size();
3174       }
3175 
3176       NetCase*res = new NetCase(quality_, type_, expr, icount);
3177       res->set_line(*this);
3178 
3179 	/* Iterate over all the case items (guard/statement pairs)
3180 	   elaborating them. If the guard has no expression, then this
3181 	   is a "default" case. Otherwise, the guard has one or more
3182 	   expressions, and each guard is a case. */
3183       unsigned inum = 0;
3184       for (unsigned idx = 0 ;  idx < items_->count() ;  idx += 1) {
3185 
3186 	    ivl_assert(*this, inum < icount);
3187 	    PCase::Item*cur = (*items_)[idx];
3188 
3189 	    if (cur->expr.empty()) {
3190 		    /* If there are no expressions, then this is the
3191 		       default case. */
3192 		  NetProc*st = 0;
3193 		  if (cur->stat)
3194 			st = cur->stat->elaborate(des, scope);
3195 
3196 		  res->set_case(inum, 0, st);
3197 		  inum += 1;
3198 
3199 	    } else for (list<PExpr*>::iterator idx_expr = cur->expr.begin()
3200 			      ; idx_expr != cur->expr.end() ; ++idx_expr) {
3201 
3202 		    /* If there are one or more expressions, then
3203 		       iterate over the guard expressions, elaborating
3204 		       a separate case for each. (Yes, the statement
3205 		       will be elaborated again for each.) */
3206 		  PExpr*cur_expr = *idx_expr;
3207 		  ivl_assert(*this, cur_expr);
3208 		  NetExpr*gu = elab_and_eval_case(des, scope, cur_expr,
3209 						  context_is_real,
3210 						  context_unsigned,
3211 						  context_width);
3212 
3213 		  NetProc*st = 0;
3214 		  if (cur->stat)
3215 			st = cur->stat->elaborate(des, scope);
3216 
3217 		  res->set_case(inum, gu, st);
3218 		  inum += 1;
3219 	    }
3220       }
3221 
3222       res->prune();
3223 
3224       return res;
3225 }
3226 
elaborate(Design * des,NetScope * scope) const3227 NetProc* PChainConstructor::elaborate(Design*des, NetScope*scope) const
3228 {
3229       assert(scope);
3230 
3231       if (debug_elaborate) {
3232 	    cerr << get_fileline() << ": PChainConstructor::elaborate: "
3233 		 << "Elaborate constructor chain in scope=" << scope_path(scope) << endl;
3234       }
3235 
3236 	// The scope is the <class>.new function, so scope->parent()
3237 	// is the class. Use that to get the class type that we are
3238 	// constructing.
3239       NetScope*scope_class = scope->parent();
3240       const netclass_t*class_this = scope_class->class_def();
3241       ivl_assert(*this, class_this);
3242 
3243 	// We also need the super-class.
3244       const netclass_t*class_super = class_this->get_super();
3245       if (class_super == 0) {
3246 	    cerr << get_fileline() << ": error: "
3247 		 << "Class " << class_this->get_name()
3248 		 << " has no parent class for super.new constructor chaining." << endl;
3249 	    des->errors += 1;
3250 	    NetBlock*tmp = new NetBlock(NetBlock::SEQU, 0);
3251 	    tmp->set_line(*this);
3252 	    return tmp;
3253       }
3254 
3255 	// Need the "this" variable for the current constructor. We're
3256 	// going to pass this to the chained constructor.
3257       NetNet*var_this = scope->find_signal(perm_string::literal("@"));
3258 
3259 	// If super.new is an implicit constructor, then there are no
3260 	// arguments (other than "this" to worry about, so make a
3261 	// NetEUFunc and there we go.
3262       if (NetScope*new_scope = class_super->method_from_name(perm_string::literal("new@"))) {
3263 	    NetESignal*eres = new NetESignal(var_this);
3264 	    vector<NetExpr*> parms(1);
3265 	    parms[0] = eres;
3266 	    NetEUFunc*tmp = new NetEUFunc(scope, new_scope, eres, parms, true);
3267 	    tmp->set_line(*this);
3268 
3269 	    NetAssign_*lval_this = new NetAssign_(var_this);
3270 	    NetAssign*stmt = new NetAssign(lval_this, tmp);
3271 	    stmt->set_line(*this);
3272 	    return stmt;
3273       }
3274 
3275 	// If super.new(...) is a user defined constructor, then call
3276 	// it. This is a bit more complicated because there may be arguments.
3277       if (NetScope*new_scope = class_super->method_from_name(perm_string::literal("new"))) {
3278 
3279 	    int missing_parms = 0;
3280 	    NetFuncDef*def = new_scope->func_def();
3281 	    ivl_assert(*this, def);
3282 
3283 	    NetESignal*eres = new NetESignal(var_this);
3284 	    vector<NetExpr*> parms (def->port_count());
3285 	    parms[0] = eres;
3286 
3287 	    for (size_t idx = 1 ; idx < parms.size() ; idx += 1) {
3288 		  if (idx <= parms_.size() && parms_[idx-1]) {
3289 			PExpr*tmp = parms_[idx-1];
3290 			parms[idx] = elaborate_rval_expr(des, scope,
3291 							 def->port(idx)->net_type(),
3292 							 def->port(idx)->data_type(),
3293 							 def->port(idx)->vector_width(),
3294 							 tmp, false);
3295 			continue;
3296 		  }
3297 
3298 		  if (NetExpr*tmp = def->port_defe(idx)) {
3299 			parms[idx] = tmp;
3300 			continue;
3301 		  }
3302 
3303 		  missing_parms += 1;
3304 		  parms[idx] = 0;
3305 	    }
3306 
3307 	    if (missing_parms) {
3308 		  cerr << get_fileline() << ": error: "
3309 		       << "Missing " << missing_parms
3310 		       << " arguments to constructor " << scope_path(new_scope) << "." << endl;
3311 		  des->errors += 1;
3312 	    }
3313 
3314 	    NetEUFunc*tmp = new NetEUFunc(scope, new_scope, eres, parms, true);
3315 	    tmp->set_line(*this);
3316 
3317 	    NetAssign_*lval_this = new NetAssign_(var_this);
3318 	    NetAssign*stmt = new NetAssign(lval_this, tmp);
3319 	    stmt->set_line(*this);
3320 	    return stmt;
3321       }
3322 
3323 	// There is no constructor at all in the parent, so skip it.
3324       NetBlock*tmp = new NetBlock(NetBlock::SEQU, 0);
3325       tmp->set_line(*this);
3326       return tmp;
3327 }
3328 
elaborate(Design * des,NetScope * scope) const3329 NetProc* PCondit::elaborate(Design*des, NetScope*scope) const
3330 {
3331       assert(scope);
3332 
3333       if (debug_elaborate)
3334 	    cerr << get_fileline() << ": debug: Elaborate condition statement"
3335 		 << " with conditional: " << *expr_ << endl;
3336 
3337 	// Elaborate and try to evaluate the conditional expression.
3338       NetExpr*expr = elab_and_eval(des, scope, expr_, -1);
3339       if (expr == 0) {
3340 	    cerr << get_fileline() << ": error: Unable to elaborate"
3341 		  " condition expression." << endl;
3342 	    des->errors += 1;
3343 	    return 0;
3344       }
3345 
3346 	// If the condition of the conditional statement is constant,
3347 	// then look at the value and elaborate either the if statement
3348 	// or the else statement. I don't need both. If there is no
3349 	// else_ statement, then use an empty block as a noop.
3350       if (NetEConst*ce = dynamic_cast<NetEConst*>(expr)) {
3351 	    verinum val = ce->value();
3352 	    if (debug_elaborate) {
3353 		  cerr << get_fileline() << ": debug: Condition expression "
3354 		       << "is a constant " << val << "." << endl;
3355 	    }
3356 
3357 	    verinum::V reduced = verinum::V0;
3358 	    for (unsigned idx = 0 ;  idx < val.len() ;  idx += 1)
3359 		  reduced = reduced | val[idx];
3360 
3361 	    delete expr;
3362 	    if (reduced == verinum::V1)
3363 		  if (if_) {
3364 			return if_->elaborate(des, scope);
3365 		  } else {
3366 			NetBlock*tmp = new NetBlock(NetBlock::SEQU, 0);
3367 			tmp->set_line(*this);
3368 			return tmp;
3369 		  }
3370 	    else if (else_)
3371 		  return else_->elaborate(des, scope);
3372 	    else
3373 		  return new NetBlock(NetBlock::SEQU, 0);
3374       }
3375 
3376 	// If the condition expression is more than 1 bits, then
3377 	// generate a comparison operator to get the result down to
3378 	// one bit. Turn <e> into <e> != 0;
3379 
3380       if (expr->expr_width() < 1) {
3381 	    cerr << get_fileline() << ": internal error: "
3382 		  "incomprehensible expression width (0)." << endl;
3383 	    return 0;
3384       }
3385 
3386 	// Make sure the condition expression evaluates to a condition.
3387       expr = condition_reduce(expr);
3388 
3389 	// Well, I actually need to generate code to handle the
3390 	// conditional, so elaborate.
3391       NetProc*i = if_? if_->elaborate(des, scope) : 0;
3392       NetProc*e = else_? else_->elaborate(des, scope) : 0;
3393 
3394 	// Detect the special cases that the if or else statements are
3395 	// empty blocks. If this is the case, remove the blocks as
3396 	// null statements.
3397       if (NetBlock*tmp = dynamic_cast<NetBlock*>(i)) {
3398 	    if (tmp->proc_first() == 0) {
3399 		  delete i;
3400 		  i = 0;
3401 	    }
3402       }
3403 
3404       if (NetBlock*tmp = dynamic_cast<NetBlock*>(e)) {
3405 	    if (tmp->proc_first() == 0) {
3406 		  delete e;
3407 		  e = 0;
3408 	    }
3409       }
3410 
3411       NetCondit*res = new NetCondit(expr, i, e);
3412       res->set_line(*this);
3413       return res;
3414 }
3415 
elaborate(Design * des,NetScope * scope) const3416 NetProc* PCallTask::elaborate(Design*des, NetScope*scope) const
3417 {
3418       if (peek_tail_name(path_)[0] == '$')
3419 	    return elaborate_sys(des, scope);
3420       else
3421 	    return elaborate_usr(des, scope);
3422 }
3423 
3424 /*
3425  * A call to a system task involves elaborating all the parameters,
3426  * then passing the list to the NetSTask object.
3427  *XXXX
3428  * There is a single special case in the call to a system
3429  * task. Normally, an expression cannot take an unindexed
3430  * memory. However, it is possible to take a system task parameter a
3431  * memory if the expression is trivial.
3432  */
elaborate_sys(Design * des,NetScope * scope) const3433 NetProc* PCallTask::elaborate_sys(Design*des, NetScope*scope) const
3434 {
3435       assert(scope);
3436 
3437       if (path_.size() > 1) {
3438 	    cerr << get_fileline() << ": error: Hierarchical system task names"
3439 		 << " make no sense: " << path_ << endl;
3440 	    des->errors += 1;
3441       }
3442 
3443       unsigned parm_count = parms_.size();
3444 
3445 	/* Catch the special case that the system task has no
3446 	   parameters. The "()" string will be parsed as a single
3447 	   empty parameter, when we really mean no parameters at all. */
3448       if ((parm_count== 1) && (parms_[0] == 0))
3449 	    parm_count = 0;
3450 
3451       vector<NetExpr*>eparms (parm_count);
3452 
3453       perm_string name = peek_tail_name(path_);
3454 
3455       for (unsigned idx = 0 ;  idx < parm_count ;  idx += 1) {
3456 	    PExpr*ex = parms_[idx];
3457 	    if (ex != 0) {
3458 		  eparms[idx] = elab_sys_task_arg(des, scope, name, idx, ex);
3459 	    } else {
3460 		  eparms[idx] = 0;
3461 	    }
3462       }
3463 
3464 	// Special case: Specify blocks are turned off, and this is an
3465 	// $sdf_annotate system task. There will be nothing for $sdf
3466 	// to annotate, and the user is intending to turn the behavior
3467 	// off anyhow, so replace the system task invocation with a no-op.
3468       if (gn_specify_blocks_flag == false && name == "$sdf_annotate") {
3469 
3470 	    cerr << get_fileline() << ": warning: Omitting $sdf_annotate() "
3471 	         << "since specify blocks are being omitted." << endl;
3472 	    NetBlock*noop = new NetBlock(NetBlock::SEQU, scope);
3473 	    noop->set_line(*this);
3474 	    return noop;
3475       }
3476 
3477       scope->calls_sys_task(true);
3478 
3479       NetSTask*cur = new NetSTask(name, def_sfunc_as_task, eparms);
3480       cur->set_line(*this);
3481       return cur;
3482 }
3483 
3484 /*
3485  * A call to a user defined task is different from a call to a system
3486  * task because a user task in a netlist has no parameters: the
3487  * assignments are done by the calling thread. For example:
3488  *
3489  *  task foo;
3490  *    input a;
3491  *    output b;
3492  *    [...]
3493  *  endtask;
3494  *
3495  *  [...] foo(x, y);
3496  *
3497  * is really:
3498  *
3499  *  task foo;
3500  *    reg a;
3501  *    reg b;
3502  *    [...]
3503  *  endtask;
3504  *
3505  *  [...]
3506  *  begin
3507  *    a = x;
3508  *    foo;
3509  *    y = b;
3510  *  end
3511  */
elaborate_usr(Design * des,NetScope * scope) const3512 NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
3513 {
3514       assert(scope);
3515 
3516       NetScope*pscope = scope;
3517       if (package_) {
3518 	    pscope = des->find_package(package_->pscope_name());
3519 	    ivl_assert(*this, pscope);
3520       }
3521 
3522       NetScope*task = des->find_task(pscope, path_);
3523       if (task == 0) {
3524 	      // For SystemVerilog this may be a few other things.
3525 	    if (gn_system_verilog()) {
3526 		  NetProc *tmp;
3527 		    // This could be a method attached to a signal?
3528 		  tmp = elaborate_method_(des, scope);
3529 		  if (tmp) return tmp;
3530 		    // Or it could be a function call ignoring the return?
3531 		  tmp = elaborate_function_(des, scope);
3532 		  if (tmp) return tmp;
3533 	    }
3534 
3535 	    cerr << get_fileline() << ": error: Enable of unknown task "
3536 		 << "``" << path_ << "''." << endl;
3537 	    des->errors += 1;
3538 	    return 0;
3539       }
3540 
3541       assert(task);
3542       assert(task->type() == NetScope::TASK);
3543       NetTaskDef*def = task->task_def();
3544       if (def == 0) {
3545 	    cerr << get_fileline() << ": internal error: task " << path_
3546 		 << " doesn't have a definition in " << scope_path(scope)
3547 		 << "." << endl;
3548 	    des->errors += 1;
3549 	    return 0;
3550       }
3551       assert(def);
3552 
3553 	/* In SystemVerilog a method calling another method in the
3554 	 * current class needs to be elaborated as a method with an
3555 	 * implicit this added.  */
3556       if (gn_system_verilog() && (path_.size() == 1)) {
3557 	    const NetScope *c_scope = scope->get_class_scope();
3558 	    if (c_scope && (c_scope == task->get_class_scope())) {
3559 		  NetProc *tmp = elaborate_method_(des, scope, true);
3560 		  assert(tmp);
3561 		  return tmp;
3562 	    }
3563       }
3564 
3565       unsigned parm_count = def->port_count();
3566 
3567 	/* Handle non-automatic tasks with no parameters specially. There is
3568            no need to make a sequential block to hold the generated code. */
3569       if ((parm_count == 0) && !task->is_auto()) {
3570 	    NetUTask*cur = new NetUTask(task);
3571 	    cur->set_line(*this);
3572 	    return cur;
3573       }
3574 
3575       return elaborate_build_call_(des, scope, task, 0);
3576 }
3577 
3578 /*
3579  * This private method is called to elaborate built-in methods. The
3580  * method_name is the detected name of the built-in method, and the
3581  * sys_task_name is the internal system-task name to use.
3582  */
elaborate_sys_task_method_(Design * des,NetScope * scope,NetNet * net,perm_string method_name,const char * sys_task_name) const3583 NetProc* PCallTask::elaborate_sys_task_method_(Design*des, NetScope*scope,
3584 					       NetNet*net,
3585 					       perm_string method_name,
3586 					       const char*sys_task_name) const
3587 {
3588       NetESignal*sig = new NetESignal(net);
3589       sig->set_line(*this);
3590 
3591 	/* If there is a single NULL argument then ignore it since it is
3592 	 * left over from the parser and is not needed by the method. */
3593       unsigned nparms = parms_.size();
3594       if ((nparms == 1) && (parms_[0] == 0)) nparms = 0;
3595 
3596       vector<NetExpr*>argv (1 + nparms);
3597       argv[0] = sig;
3598 
3599       if (method_name == "delete") {
3600 	      // The queue delete method takes an optional element.
3601 	    if (net->queue_type()) {
3602 		  if (nparms > 1)  {
3603 			cerr << get_fileline() << ": error: queue delete() "
3604 			     << "method takes zero or one argument." << endl;
3605 			des->errors += 1;
3606 		  }
3607 	    } else if (nparms > 0) {
3608 		  cerr << get_fileline() << ": error: darray delete() "
3609 		       << "method takes no arguments." << endl;
3610 		  des->errors += 1;
3611 	    }
3612       }
3613 
3614       for (unsigned idx = 0 ; idx < nparms ; idx += 1) {
3615 	    PExpr*ex = parms_[idx];
3616 	    if (ex != 0) {
3617 		  argv[idx+1] = elab_sys_task_arg(des, scope,
3618 						  method_name,
3619 						  idx, ex);
3620 	    } else {
3621 		  argv[idx+1] = 0;
3622 	    }
3623       }
3624 
3625       NetSTask*sys = new NetSTask(sys_task_name, IVL_SFUNC_AS_TASK_IGNORE, argv);
3626       sys->set_line(*this);
3627       return sys;
3628 }
3629 
3630 /*
3631  * This private method is called to elaborate queue push methods. The
3632  * sys_task_name is the internal system-task name to use.
3633  */
elaborate_queue_method_(Design * des,NetScope * scope,NetNet * net,perm_string method_name,const char * sys_task_name) const3634 NetProc* PCallTask::elaborate_queue_method_(Design*des, NetScope*scope,
3635 					    NetNet*net,
3636 					    perm_string method_name,
3637 					    const char*sys_task_name) const
3638 {
3639       NetESignal*sig = new NetESignal(net);
3640       sig->set_line(*this);
3641 
3642       unsigned nparms = parms_.size();
3643 	// insert() requires two arguments.
3644       if ((method_name == "insert") && (nparms != 2)) {
3645 	    cerr << get_fileline() << ": error: " << method_name
3646 		 << "() method requires two arguments." << endl;
3647 	    des->errors += 1;
3648       }
3649 	// push_front() and push_back() require one argument.
3650       if ((method_name != "insert") && (nparms != 1)) {
3651 	    cerr << get_fileline() << ": error: " << method_name
3652 		 << "() method requires a single argument." << endl;
3653 	    des->errors += 1;
3654       }
3655 
3656 	// Get the context width if this is a logic type.
3657       ivl_variable_type_t base_type = net->darray_type()->element_base_type();
3658       int context_width = -1;
3659       switch (base_type) {
3660 	  case IVL_VT_BOOL:
3661 	  case IVL_VT_LOGIC:
3662 	    context_width = net->darray_type()->element_width();
3663 	    break;
3664 	  default:
3665 	    break;
3666       }
3667 
3668       vector<NetExpr*>argv (nparms+1);
3669       argv[0] = sig;
3670       if (method_name != "insert") {
3671 	    if ((nparms == 0) || (parms_[0] == 0)) {
3672 		  argv[1] = 0;
3673 		  cerr << get_fileline() << ": error: " << method_name
3674 		       << "() methods first argument is missing." << endl;
3675 		  des->errors += 1;
3676 	    } else
3677 		  argv[1] = elab_and_eval(des, scope, parms_[0], context_width,
3678 		                          false, false, base_type);
3679       } else {
3680 	    if ((nparms == 0) || (parms_[0] == 0)) {
3681 		  argv[1] = 0;
3682 		  cerr << get_fileline() << ": error: " << method_name
3683 		       << "() methods first argument is missing." << endl;
3684 		  des->errors += 1;
3685 	    } else
3686 		  argv[1] = elab_and_eval(des, scope, parms_[0], 32,
3687 		                          false, false, IVL_VT_LOGIC);
3688 
3689 	    if ((nparms < 2) || (parms_[1] == 0)) {
3690 		  argv[2] = 0;
3691 		  cerr << get_fileline() << ": error: " << method_name
3692 		       << "() methods second argument is missing." << endl;
3693 		  des->errors += 1;
3694 	    } else
3695 		  argv[2] = elab_and_eval(des, scope, parms_[1], context_width,
3696 		                          false, false, base_type);
3697       }
3698 
3699       NetSTask*sys = new NetSTask(sys_task_name, IVL_SFUNC_AS_TASK_IGNORE, argv);
3700       sys->set_line(*this);
3701       return sys;
3702 }
3703 
elaborate_method_(Design * des,NetScope * scope,bool add_this_flag) const3704 NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
3705                                       bool add_this_flag) const
3706 {
3707       pform_name_t use_path = path_;
3708       perm_string method_name = peek_tail_name(use_path);
3709       use_path.pop_back();
3710 
3711       NetNet *net;
3712       const NetExpr *par;
3713       NetEvent *eve;
3714       const NetExpr *ex1, *ex2;
3715 
3716 	/* Add the implicit this reference when requested. */
3717       if (add_this_flag) {
3718 	    assert(use_path.empty());
3719 	    use_path.push_front(name_component_t(perm_string::literal("@")));
3720       }
3721 
3722 	// There is no signal to search for so this cannot be a method.
3723       if (use_path.empty()) return 0;
3724 
3725 	// Search for an object using the use_path. This should
3726 	// resolve to a class object. Note that the "this" symbol
3727 	// (internally represented as "@") is handled by there being a
3728 	// "this" object in the instance scope.
3729       symbol_search(this, des, scope, use_path,
3730 		    net, par, eve, ex1, ex2);
3731 
3732       if (net == 0)
3733 	    return 0;
3734 
3735 	// Is this a delete method for dynamic arrays?
3736       if (net->darray_type() && method_name=="delete") {
3737 	    return elaborate_sys_task_method_(des, scope, net, method_name,
3738 					      "$ivl_darray_method$delete");
3739       }
3740 
3741       if (net->queue_type()) {
3742 	    if (method_name == "push_back")
3743 		  return elaborate_queue_method_(des, scope, net, method_name,
3744 						 "$ivl_queue_method$push_back");
3745 	    else if (method_name == "push_front")
3746 		  return elaborate_queue_method_(des, scope, net, method_name,
3747 						 "$ivl_queue_method$push_front");
3748 	    else if (method_name == "insert")
3749 		  return elaborate_queue_method_(des, scope, net, method_name,
3750 						 "$ivl_queue_method$insert");
3751       }
3752 
3753       if (const netclass_t*class_type = net->class_type()) {
3754 	    NetScope*task = class_type->method_from_name(method_name);
3755 	    if (task == 0) {
3756 		  cerr << get_fileline() << ": internal error: "
3757 		       << "Can't find task " << method_name
3758 		       << " in class " << class_type->get_name() << endl;
3759 		  des->errors += 1;
3760 		  return 0;
3761 	    }
3762 
3763 	    if (debug_elaborate) {
3764 		  cerr << get_fileline() << ": PCallTask::elaborate_method_: "
3765 		       << "Elaborate " << class_type->get_name()
3766 		       << " method " << task->basename() << endl;
3767 	    }
3768 
3769 	    NetESignal*use_this = new NetESignal(net);
3770 	    use_this->set_line(*this);
3771 
3772 	    return elaborate_build_call_(des, scope, task, use_this);
3773       }
3774 
3775       return 0;
3776 }
3777 
3778 /*
3779  * If during elaboration we determine (for sure) that we are calling a
3780  * task (and not just a void function) then this method tests if that
3781  * task call is allowed in the current context. If so, return true. If
3782  * not, print and error message and return false;
3783  */
test_task_calls_ok_(Design * des,NetScope * scope) const3784 bool PCallTask::test_task_calls_ok_(Design*des, NetScope*scope) const
3785 {
3786       if (scope->in_func()) {
3787 	    cerr << get_fileline() << ": error: Functions cannot enable/call "
3788 	            "tasks." << endl;
3789 	    des->errors += 1;
3790 	    return false;
3791       }
3792 
3793       if (scope->in_final()) {
3794 	    cerr << get_fileline() << ": error: final procedures cannot "
3795 	            "enable/call tasks." << endl;
3796 	    des->errors += 1;
3797 	    return false;
3798       }
3799 
3800       return true;
3801 }
3802 
elaborate_function_(Design * des,NetScope * scope) const3803 NetProc* PCallTask::elaborate_function_(Design*des, NetScope*scope) const
3804 {
3805       NetFuncDef*func = des->find_function(scope, path_);
3806 	// This is not a function, so this task call cannot be a function
3807 	// call with a missing return assignment.
3808       if (! func) return 0;
3809 
3810       if (gn_system_verilog() && func->is_void())
3811 	    return elaborate_void_function_(des, scope, func);
3812 
3813 	// Generate a function call version of this task call.
3814       PExpr*rval = new PECallFunction(package_, path_, parms_);
3815       rval->set_file(get_file());
3816       rval->set_lineno(get_lineno());
3817 	// Generate an assign to nothing.
3818       PAssign*tmp = new PAssign(0, rval);
3819       tmp->set_file(get_file());
3820       tmp->set_lineno(get_lineno());
3821       cerr << get_fileline() << ": warning: User function '"
3822            << peek_tail_name(path_) << "' is being called as a task." << endl;
3823 	// Elaborate the assignment to a dummy variable.
3824       return tmp->elaborate(des, scope);
3825 }
3826 
elaborate_void_function_(Design * des,NetScope * scope,NetFuncDef * def) const3827 NetProc* PCallTask::elaborate_void_function_(Design*des, NetScope*scope,
3828 					     NetFuncDef*def) const
3829 {
3830       NetScope*dscope = def->scope();
3831 
3832       if (debug_elaborate) {
3833 	    cerr << get_fileline() << ": PCallTask::elaborate_void_function_: "
3834 		 << "function void " << scope_path(dscope)
3835 		 << endl;
3836       }
3837 
3838       ivl_assert(*this, dscope->elab_stage() >= 3);
3839       return elaborate_build_call_(des, scope, dscope, 0);
3840 }
3841 
elaborate_build_call_(Design * des,NetScope * scope,NetScope * task,NetExpr * use_this) const3842 NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope,
3843 					  NetScope*task, NetExpr*use_this) const
3844 {
3845       NetBaseDef*def = 0;
3846       if (task->type() == NetScope::TASK) {
3847 	    def = task->task_def();
3848 
3849 	      // OK, this is certainly a TASK that I'm calling. Make
3850 	      // sure that is OK where I am. Even if this test fails,
3851 	      // continue with the elaboration as if it were OK so
3852 	      // that we can catch more errors.
3853 	    test_task_calls_ok_(des, scope);
3854 
3855       } else if (task->type() == NetScope::FUNC) {
3856 	    NetFuncDef*tmp = task->func_def();
3857 	    if (!tmp->is_void()) {
3858 		  cerr << get_fileline() << ": error: "
3859 		       << "Calling a non-void function as a task." << endl;
3860 		  des->errors += 1;
3861 	    }
3862 	    def = tmp;
3863       }
3864 
3865 	/* The caller has checked the parms_ size to make sure it
3866 	   matches the task definition, so we can just use the task
3867 	   definition to get the parm_count. */
3868 
3869       unsigned parm_count = def->port_count();
3870 
3871       if (parms_.size() > parm_count) {
3872 	    cerr << get_fileline() << ": error: "
3873 		 << "Too many arguments (" << parms_.size()
3874 		 << ", expecting " << parm_count << ")"
3875 		 << " in call to task." << endl;
3876 	    des->errors += 1;
3877       }
3878 
3879       NetBlock*block = new NetBlock(NetBlock::SEQU, 0);
3880       block->set_line(*this);
3881 
3882 	/* Detect the case where the definition of the task is known
3883 	   empty. In this case, we need not bother with calls to the
3884 	   task, all the assignments, etc. Just return a no-op. */
3885 
3886       if (const NetBlock*tp = dynamic_cast<const NetBlock*>(def->proc())) {
3887 	    if (tp->proc_first() == 0)
3888 		  return block;
3889       }
3890 
3891         /* If this is an automatic task, generate a statement to
3892            allocate the local storage. */
3893 
3894       if (task->is_auto()) {
3895 	    NetAlloc*ap = new NetAlloc(task);
3896 	    ap->set_line(*this);
3897 	    block->append(ap);
3898       }
3899 
3900 	/* If this is a method call, then the use_this pointer will
3901 	   have an expression for the "this" argument. The "this"
3902 	   argument is the first argument of any method, so emit it
3903 	   here. */
3904 
3905       if (use_this) {
3906 	    ivl_assert(*this, def->port_count() >= 1);
3907 	    NetNet*port = def->port(0);
3908 	    ivl_assert(*this, port->port_type()==NetNet::PINPUT);
3909 
3910 	    NetAssign_*lv = new NetAssign_(port);
3911 	    NetAssign*pr = new NetAssign(lv, use_this);
3912 	    pr->set_line(*this);
3913 	    block->append(pr);
3914       }
3915 
3916 	/* Generate assignment statement statements for the input and
3917 	   INOUT ports of the task. These are managed by writing
3918 	   assignments with the task port the l-value and the passed
3919 	   expression the r-value. We know by definition that the port
3920 	   is a reg type, so this elaboration is pretty obvious. */
3921 
3922       for (unsigned idx = use_this?1:0 ;  idx < parm_count ;  idx += 1) {
3923 
3924 	    size_t parms_idx = use_this? idx-1 : idx;
3925 
3926 	    NetNet*port = def->port(idx);
3927 	    assert(port->port_type() != NetNet::NOT_A_PORT);
3928 	    if (port->port_type() == NetNet::POUTPUT)
3929 		  continue;
3930 
3931 	    NetAssign_*lv = new NetAssign_(port);
3932 	    unsigned wid = count_lval_width(lv);
3933 	    ivl_variable_type_t lv_type = lv->expr_type();
3934 
3935 	    NetExpr*rv = 0;
3936 
3937 	    if (parms_idx < parms_.size() && parms_[parms_idx]) {
3938 		  rv = elaborate_rval_expr(des, scope, port->net_type(),
3939 					   lv_type, wid, parms_ [parms_idx]);
3940 		  if (NetEEvent*evt = dynamic_cast<NetEEvent*> (rv)) {
3941 			cerr << evt->get_fileline() << ": error: An event '"
3942 			     << evt->event()->name() << "' can not be a user "
3943 			      "task argument." << endl;
3944 			des->errors += 1;
3945 			continue;
3946 		  }
3947 
3948 	    } else if (def->port_defe(idx)) {
3949 		  if (! gn_system_verilog()) {
3950 			cerr << get_fileline() << ": internal error: "
3951 			     << "Found (and using) default task expression "
3952 			        "requires SystemVerilog." << endl;
3953 			des->errors += 1;
3954 		  }
3955 		  rv = def->port_defe(idx);
3956 		  if (lv_type==IVL_VT_BOOL||lv_type==IVL_VT_LOGIC)
3957 			rv = pad_to_width(rv->dup_expr(), wid, *this);
3958 
3959 	    } else {
3960 		  cerr << get_fileline() << ": error: "
3961 		       << "Missing argument " << (idx+1)
3962 		       << " of call to task." << endl;
3963 		  des->errors += 1;
3964 		  continue;
3965 	    }
3966 
3967 	    NetAssign*pr = new NetAssign(lv, rv);
3968 	    pr->set_line(*this);
3969 	    block->append(pr);
3970       }
3971 
3972 	/* Generate the task call proper... */
3973       NetUTask*cur = new NetUTask(task);
3974       cur->set_line(*this);
3975       block->append(cur);
3976 
3977 	/* Generate assignment statements for the output and INOUT
3978 	   ports of the task. The l-value in this case is the
3979 	   expression passed as a parameter, and the r-value is the
3980 	   port to be copied out.
3981 
3982 	   We know by definition that the r-value of this copy-out is
3983 	   the port, which is a reg. The l-value, however, may be any
3984 	   expression that can be a target to a procedural
3985 	   assignment, including a memory word. */
3986 
3987       for (unsigned idx = use_this?1:0 ;  idx < parm_count ;  idx += 1) {
3988 
3989 	    size_t parms_idx = use_this? idx-1 : idx;
3990 
3991 	    NetNet*port = def->port(idx);
3992 
3993 	      /* Skip input ports. */
3994 	    assert(port->port_type() != NetNet::NOT_A_PORT);
3995 	    if (port->port_type() == NetNet::PINPUT)
3996 		  continue;
3997 
3998 
3999 	      /* Elaborate an l-value version of the port expression
4000 		 for output and inout ports. If the expression does
4001 		 not exist or is not a valid l-value print an error
4002 		 message. Note that the elaborate_lval method already
4003 		 printed a detailed message for the latter case. */
4004 	    NetAssign_*lv = 0;
4005 	    if (parms_idx < parms_.size() && parms_[parms_idx]) {
4006 		  lv = parms_[parms_idx]->elaborate_lval(des, scope, false, false);
4007 		  if (lv == 0) {
4008 			cerr << parms_[parms_idx]->get_fileline() << ": error: "
4009 			     << "I give up on task port " << (idx+1)
4010 			     << " expression: " << *parms_[parms_idx] << endl;
4011 		  }
4012 	    } else if (port->port_type() == NetNet::POUTPUT) {
4013 		    // Output ports were skipped earlier, so
4014 		    // report the error now.
4015 		  cerr << get_fileline() << ": error: "
4016 		       << "Missing argument " << (idx+1)
4017 		       << " of call to task." << endl;
4018 		  des->errors += 1;
4019 	    }
4020 
4021 	    if (lv == 0)
4022 		  continue;
4023 
4024 	    NetExpr*rv = new NetESignal(port);
4025 
4026 	      /* Handle any implicit cast. */
4027 	    unsigned lv_width = count_lval_width(lv);
4028 	    if (lv->expr_type() != rv->expr_type()) {
4029 		  switch (lv->expr_type()) {
4030 		      case IVL_VT_REAL:
4031 			rv = cast_to_real(rv);
4032 			break;
4033 		      case IVL_VT_BOOL:
4034 			rv = cast_to_int2(rv, lv_width);
4035 			break;
4036 		      case IVL_VT_LOGIC:
4037 			rv = cast_to_int4(rv, lv_width);
4038 			break;
4039 		      default:
4040 			  /* Don't yet know how to handle this. */
4041 			ivl_assert(*this, 0);
4042 			break;
4043 		  }
4044 	    }
4045 	    rv = pad_to_width(rv, lv_width, *this);
4046 
4047 	      /* Generate the assignment statement. */
4048 	    NetAssign*ass = new NetAssign(lv, rv);
4049 	    ass->set_line(*this);
4050 
4051 	    block->append(ass);
4052       }
4053 
4054         /* If this is an automatic task, generate a statement to free
4055            the local storage. */
4056       if (task->is_auto()) {
4057 	    NetFree*fp = new NetFree(task);
4058 	    fp->set_line(*this);
4059 	    block->append(fp);
4060       }
4061 
4062       return block;
4063 }
4064 
4065 /*
4066  * Elaborate a procedural continuous assign. This really looks very
4067  * much like other procedural assignments, at this point, but there
4068  * is no delay to worry about. The code generator will take care of
4069  * the differences between continuous assign and normal assignments.
4070  */
elaborate(Design * des,NetScope * scope) const4071 NetCAssign* PCAssign::elaborate(Design*des, NetScope*scope) const
4072 {
4073       NetCAssign*dev = 0;
4074       assert(scope);
4075 
4076       if (scope->is_auto() && lval_->has_aa_term(des, scope)) {
4077 	    cerr << get_fileline() << ": error: automatically allocated "
4078                     "variables may not be assigned values using procedural "
4079 	            "continuous assignments." << endl;
4080 	    des->errors += 1;
4081 	    return 0;
4082       }
4083 
4084       if (scope->is_auto() && expr_->has_aa_term(des, scope)) {
4085 	    cerr << get_fileline() << ": error: automatically allocated "
4086                     "variables may not be referenced in procedural "
4087 	            "continuous assignments." << endl;
4088 	    des->errors += 1;
4089 	    return 0;
4090       }
4091 
4092       NetAssign_*lval = lval_->elaborate_lval(des, scope, true, false);
4093       if (lval == 0)
4094 	    return 0;
4095 
4096       unsigned lwid = count_lval_width(lval);
4097       ivl_variable_type_t ltype = lval->expr_type();
4098 
4099 	// Need to figure out a better thing to do about the
4100 	// lv_net_type argument to elaborate_rval_expr here. This
4101 	// would entail getting the NetAssign_ to give us an
4102 	// ivl_type_t as needed.
4103       NetExpr*rexp = elaborate_rval_expr(des, scope, 0, ltype, lwid, expr_);
4104       if (rexp == 0)
4105 	    return 0;
4106 
4107       dev = new NetCAssign(lval, rexp);
4108 
4109       if (debug_elaborate) {
4110 	    cerr << get_fileline() << ": debug: Elaborate cassign,"
4111 		 << " lval width=" << lwid
4112 		 << " rval width=" << rexp->expr_width()
4113 		 << " rval=" << *rexp
4114 		 << endl;
4115       }
4116 
4117       dev->set_line(*this);
4118       return dev;
4119 }
4120 
elaborate(Design * des,NetScope * scope) const4121 NetDeassign* PDeassign::elaborate(Design*des, NetScope*scope) const
4122 {
4123       assert(scope);
4124 
4125       if (scope->is_auto() && lval_->has_aa_term(des, scope)) {
4126 	    cerr << get_fileline() << ": error: automatically allocated "
4127                     "variables may not be assigned values using procedural "
4128 	            "continuous assignments." << endl;
4129 	    des->errors += 1;
4130 	    return 0;
4131       }
4132 
4133       NetAssign_*lval = lval_->elaborate_lval(des, scope, true, false);
4134       if (lval == 0)
4135 	    return 0;
4136 
4137       NetDeassign*dev = new NetDeassign(lval);
4138       dev->set_line( *this );
4139       return dev;
4140 }
4141 
4142 /*
4143  * Elaborate the delay statement (of the form #<expr> <statement>) as a
4144  * NetPDelay object. If the expression is constant, evaluate it now
4145  * and make a constant delay. If not, then pass an elaborated
4146  * expression to the constructor of NetPDelay so that the code
4147  * generator knows to evaluate the expression at run time.
4148  */
elaborate(Design * des,NetScope * scope) const4149 NetProc* PDelayStatement::elaborate(Design*des, NetScope*scope) const
4150 {
4151       assert(scope);
4152 
4153       if (scope->in_func()) {
4154 	    cerr << get_fileline() << ": error: functions cannot have "
4155 	            "delay statements." << endl;
4156 	    des->errors += 1;
4157 	    return 0;
4158       }
4159 
4160       if (scope->in_final()) {
4161 	    cerr << get_fileline() << ": error: final procedures cannot "
4162 	            "have delay statements." << endl;
4163 	    des->errors += 1;
4164 	    return 0;
4165       }
4166 
4167 	/* This call evaluates the delay expression to a NetEConst, if
4168 	   possible. This includes transforming NetECReal values to
4169 	   integers, and applying the proper scaling. */
4170       NetExpr*dex = elaborate_delay_expr(delay_, des, scope);
4171 
4172       NetPDelay *obj;
4173       if (NetEConst*tmp = dynamic_cast<NetEConst*>(dex)) {
4174 	    if (statement_)
4175 		  obj = new NetPDelay(tmp->value().as_ulong64(),
4176 		                      statement_->elaborate(des, scope));
4177 	    else
4178 		  obj = new NetPDelay(tmp->value().as_ulong64(), 0);
4179 
4180 	    delete dex;
4181 
4182       } else {
4183 	    if (statement_)
4184 		  obj = new NetPDelay(dex, statement_->elaborate(des, scope));
4185 	    else
4186 		  obj = new NetPDelay(dex, 0);
4187       }
4188       obj->set_line(*this);
4189       return obj;
4190 }
4191 
4192 /*
4193  * The disable statement is not yet supported.
4194  */
elaborate(Design * des,NetScope * scope) const4195 NetProc* PDisable::elaborate(Design*des, NetScope*scope) const
4196 {
4197       assert(scope);
4198 
4199 	/* If the disable scope_ is empty then this is a SystemVerilog
4200 	 * disable fork statement. */
4201       if (scope_.empty()) {
4202 	    if (gn_system_verilog()) {
4203 		  NetDisable*obj = new NetDisable(0);
4204 		  obj->set_line(*this);
4205 		  return obj;
4206 	    } else {
4207 		  cerr << get_fileline()
4208 		       << ": error: 'disable fork' requires SystemVerilog."
4209 		       << endl;
4210 		  des->errors += 1;
4211 		  return 0;
4212 	    }
4213       }
4214 
4215       list<hname_t> spath = eval_scope_path(des, scope, scope_);
4216 
4217       NetScope*target = des->find_scope(scope, spath);
4218       if (target == 0) {
4219 	    cerr << get_fileline() << ": error: Cannot find scope "
4220 		 << scope_ << " in " << scope_path(scope) << endl;
4221 	    des->errors += 1;
4222 	    return 0;
4223       }
4224 
4225       switch (target->type()) {
4226 	  case NetScope::FUNC:
4227 	    cerr << get_fileline() << ": error: Cannot disable functions." << endl;
4228 	    des->errors += 1;
4229 	    return 0;
4230 
4231 	  case NetScope::MODULE:
4232 	    cerr << get_fileline() << ": error: Cannot disable modules." << endl;
4233 	    des->errors += 1;
4234 	    return 0;
4235 
4236 	  default:
4237 	    break;
4238       }
4239 
4240       NetDisable*obj = new NetDisable(target);
4241       obj->set_line(*this);
4242       return obj;
4243 }
4244 
4245 /*
4246  * The do/while loop is fairly directly represented in the netlist.
4247  */
elaborate(Design * des,NetScope * scope) const4248 NetProc* PDoWhile::elaborate(Design*des, NetScope*scope) const
4249 {
4250       NetExpr*ce = elab_and_eval(des, scope, cond_, -1);
4251       NetProc*sub;
4252       if (statement_)
4253 	    sub = statement_->elaborate(des, scope);
4254       else
4255 	    sub = new NetBlock(NetBlock::SEQU, 0);
4256       if (ce == 0 || sub == 0) {
4257 	    delete ce;
4258 	    delete sub;
4259 	    return 0;
4260       }
4261       NetDoWhile*loop = new NetDoWhile(ce, sub);
4262       loop->set_line(*this);
4263       return loop;
4264 }
4265 
4266 /*
4267  * An event statement is an event delay of some sort, attached to a
4268  * statement. Some Verilog examples are:
4269  *
4270  *      @(posedge CLK) $display("clock rise");
4271  *      @event_1 $display("event triggered.");
4272  *      @(data or negedge clk) $display("data or clock fall.");
4273  *
4274  * The elaborated netlist uses the NetEvent, NetEvWait and NetEvProbe
4275  * classes. The NetEvWait class represents the part of the netlist
4276  * that is executed by behavioral code. The process starts waiting on
4277  * the NetEvent when it executes the NetEvWait step. Net NetEvProbe
4278  * and NetEvTrig are structural and behavioral equivalents that
4279  * trigger the event, and awakens any processes blocking in the
4280  * associated wait.
4281  *
4282  * The basic data structure is:
4283  *
4284  *       NetEvWait ---/--->  NetEvent  <----\---- NetEvProbe
4285  *        ...         |                     |         ...
4286  *       NetEvWait ---+                     +---- NetEvProbe
4287  *                                          |         ...
4288  *                                          +---- NetEvTrig
4289  *
4290  * That is, many NetEvWait statements may wait on a single NetEvent
4291  * object, and Many NetEvProbe objects may trigger the NetEvent
4292  * object. The many NetEvWait objects pointing to the NetEvent object
4293  * reflects the possibility of different places in the code blocking
4294  * on the same named event, like so:
4295  *
4296  *         event foo;
4297  *           [...]
4298  *         always begin @foo <statement1>; @foo <statement2> end
4299  *
4300  * This tends to not happen with signal edges. The multiple probes
4301  * pointing to the same event reflect the possibility of many
4302  * expressions in the same blocking statement, like so:
4303  *
4304  *         wire reset, clk;
4305  *           [...]
4306  *         always @(reset or posedge clk) <stmt>;
4307  *
4308  * Conjunctions like this cause a NetEvent object be created to
4309  * represent the overall conjunction, and NetEvProbe objects for each
4310  * event expression.
4311  *
4312  * If the NetEvent object represents a named event from the source,
4313  * then there are NetEvTrig objects that represent the trigger
4314  * statements instead of the NetEvProbe objects representing signals.
4315  * For example:
4316  *
4317  *         event foo;
4318  *         always @foo <stmt>;
4319  *         initial begin
4320  *                [...]
4321  *            -> foo;
4322  *                [...]
4323  *            -> foo;
4324  *                [...]
4325  *         end
4326  *
4327  * Each trigger statement in the source generates a separate NetEvTrig
4328  * object in the netlist. Those trigger objects are elaborated
4329  * elsewhere.
4330  *
4331  * Additional complications arise when named events show up in
4332  * conjunctions. An example of such a case is:
4333  *
4334  *         event foo;
4335  *         wire bar;
4336  *         always @(foo or posedge bar) <stmt>;
4337  *
4338  * Since there is by definition a NetEvent object for the foo object,
4339  * this is handled by allowing the NetEvWait object to point to
4340  * multiple NetEvent objects. All the NetEvProbe based objects are
4341  * collected and pointed as the synthetic NetEvent object, and all the
4342  * named events are added into the list of NetEvent object that the
4343  * NetEvWait object can refer to.
4344  */
4345 
elaborate_st(Design * des,NetScope * scope,NetProc * enet) const4346 NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
4347 				       NetProc*enet) const
4348 {
4349       assert(scope);
4350 
4351       if (scope->in_func()) {
4352 	    cerr << get_fileline() << ": error: functions cannot have "
4353 	            "event statements." << endl;
4354 	    des->errors += 1;
4355 	    return 0;
4356       }
4357 
4358       if (scope->in_final()) {
4359 	    cerr << get_fileline() << ": error: final procedures cannot "
4360 	            "have event statements." << endl;
4361 	    des->errors += 1;
4362 	    return 0;
4363       }
4364 
4365 	/* Create a single NetEvent and NetEvWait. Then, create a
4366 	   NetEvProbe for each conjunctive event in the event
4367 	   list. The NetEvProbe objects all refer back to the NetEvent
4368 	   object. */
4369 
4370       NetEvent*ev = new NetEvent(scope->local_symbol());
4371       ev->set_line(*this);
4372       ev->local_flag(true);
4373       unsigned expr_count = 0;
4374 
4375       NetEvWait*wa = new NetEvWait(enet);
4376       wa->set_line(*this);
4377 
4378 	/* If there are no expressions, this is a signal that it is an
4379 	   @* statement. Generate an expression to use. */
4380 
4381       if (expr_.count() == 0) {
4382 	    assert(enet);
4383 	     /* For synthesis or always_comb/latch we want just the inputs,
4384 	      * but for the rest we want inputs and outputs that may cause
4385 	      * a value to change. */
4386 	    extern bool synthesis; /* Synthesis flag from main.cc */
4387 	    bool rem_out = false;
4388 	    if (synthesis || always_sens_) {
4389 		  rem_out = true;
4390 	    }
4391 	      // If this is an always_comb/latch then we need an implicit T0
4392 	      // trigger of the event expression.
4393 	    if (always_sens_) wa->set_t0_trigger();
4394 	    NexusSet*nset = enet->nex_input(rem_out, always_sens_);
4395 	    if (nset == 0) {
4396 		  cerr << get_fileline() << ": error: Unable to elaborate:"
4397 		       << endl;
4398 		  enet->dump(cerr, 6);
4399 		  des->errors += 1;
4400 		  return enet;
4401 	    }
4402 
4403 	    if (nset->size() == 0) {
4404                   if (always_sens_) return wa;
4405 
4406 		  cerr << get_fileline() << ": warning: @* found no "
4407 		          "sensitivities so it will never trigger."
4408 		       << endl;
4409 		    /* Add the currently unreferenced event to the scope. */
4410 		  scope->add_event(ev);
4411 		    /* Delete the current wait, create a new one with no
4412 		     * statement and add the event to it. This creates a
4413 		     * perpetual wait since nothing will ever trigger the
4414 		     * unreferenced event. */
4415 		  delete wa;
4416 		  wa = new NetEvWait(0);
4417 		  wa->set_line(*this);
4418 		  wa->add_event(ev);
4419 		  return wa;
4420 	    }
4421 
4422 	    NetEvProbe*pr = new NetEvProbe(scope, scope->local_symbol(),
4423 					   ev, NetEvProbe::ANYEDGE,
4424 					   nset->size());
4425 	    for (unsigned idx = 0 ;  idx < nset->size() ;  idx += 1) {
4426 		  unsigned wid = nset->at(idx).wid;
4427 		  unsigned vwid = nset->at(idx).lnk.nexus()->vector_width();
4428 		    // Is this a part select?
4429 		  if (always_sens_ && (wid != vwid)) {
4430 			cerr << get_fileline() << ": sorry: constant "
4431 			        "selects in always_* processes are not "
4432 			        "currently supported (all bits will be "
4433 			        "included)." << endl;
4434 # if 0
4435 			unsigned base = nset->at(idx).base;
4436 cerr << get_fileline() << ": base = " << base << endl;
4437 // FIXME: make this work with selects that go before the base.
4438 			assert(base < vwid);
4439 			if (base + wid > vwid) wid = vwid - base;
4440 cerr << get_fileline() << ": base = " << base << ", width = " << wid
4441      << ", expr width = " << vwid << endl;
4442 nset->at(idx).lnk.dump_link(cerr, 4);
4443 cerr << endl;
4444 // FIXME: Convert the link to the appropriate NetNet
4445 			netvector_t*tmp_vec = new netvector_t(IVL_VT_BOOL, vwid, 0);
4446 			NetNet*sig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, tmp_vec);
4447 			NetPartSelect*tmp = new NetPartSelect(sig, base, wid, NetPartSelect::VP);
4448 			des->add_node(tmp);
4449 			tmp->set_line(*this);
4450 // FIXME: create a part select to get the correct bits to connect.
4451 			connect(tmp->pin(1), nset->at(idx).lnk);
4452 			connect(tmp->pin(0), pr->pin(idx));
4453 # endif
4454 			connect(nset->at(idx).lnk, pr->pin(idx));
4455 		  } else {
4456 			connect(nset->at(idx).lnk, pr->pin(idx));
4457 		  }
4458 	    }
4459 
4460 	    delete nset;
4461 	    des->add_node(pr);
4462 
4463 	    expr_count = 1;
4464 
4465       } else for (unsigned idx = 0 ;  idx < expr_.count() ;  idx += 1) {
4466 
4467 	    assert(expr_[idx]->expr());
4468 
4469 	      /* If the expression is an identifier that matches a
4470 		 named event, then handle this case all at once and
4471 		 skip the rest of the expression handling. */
4472 
4473 	    if (PEIdent*id = dynamic_cast<PEIdent*>(expr_[idx]->expr())) {
4474 		  NetNet*       sig = 0;
4475 		  const NetExpr*par = 0;
4476 		  NetEvent*     eve = 0;
4477 
4478 		  NetScope*use_scope = scope;
4479 		  if (id->package()) {
4480 			use_scope = des->find_package(id->package()->pscope_name());
4481 			ivl_assert(*this, use_scope);
4482 		  }
4483 
4484 		  NetScope*found_in = symbol_search(this, des, use_scope,
4485                                                     id->path(),
4486 						    sig, par, eve);
4487 
4488 		  if (found_in && eve) {
4489 			wa->add_event(eve);
4490 			  /* You can not look for the posedge or negedge of
4491 			   * an event. */
4492 			if (expr_[idx]->type() != PEEvent::ANYEDGE) {
4493                               cerr << get_fileline() << ": error: ";
4494                               switch (expr_[idx]->type()) {
4495 				  case PEEvent::POSEDGE:
4496 				    cerr << "posedge";
4497 				    break;
4498 				  case PEEvent::NEGEDGE:
4499 				    cerr << "negedge";
4500 				    break;
4501 				  default:
4502 				    cerr << "unknown edge type!";
4503 				    assert(0);
4504 			      }
4505 			      cerr << " can not be used with a named event ("
4506 			           << eve->name() << ")." << endl;
4507                               des->errors += 1;
4508 			}
4509 			continue;
4510 		  }
4511 	    }
4512 
4513 
4514 	      /* So now we have a normal event expression. Elaborate
4515 		 the sub-expression as a net and decide how to handle
4516 		 the edge. */
4517 
4518             if (scope->is_auto()) {
4519                   if (! dynamic_cast<PEIdent*>(expr_[idx]->expr())) {
4520                         cerr << get_fileline() << ": sorry, complex event "
4521                                 "expressions are not yet supported in "
4522                                 "automatic tasks." << endl;
4523                         des->errors += 1;
4524                         return 0;
4525                   }
4526             }
4527 
4528 	    NetExpr*tmp = elab_and_eval(des, scope, expr_[idx]->expr(), -1);
4529 	    if (tmp == 0) {
4530 		  cerr << get_fileline() << ": error: "
4531 			  "Failed to evaluate event expression '"
4532 		       << *expr_[idx] << "'." << endl;
4533 		  des->errors += 1;
4534 		  continue;
4535 	    }
4536 
4537 	    NetNet*expr = tmp->synthesize(des, scope, tmp);
4538 	    if (expr == 0) {
4539 		  expr_[idx]->dump(cerr);
4540 		  cerr << endl;
4541 		  des->errors += 1;
4542 		  continue;
4543 	    }
4544 	    assert(expr);
4545 
4546 	    delete tmp;
4547 
4548 	    unsigned pins = (expr_[idx]->type() == PEEvent::ANYEDGE)
4549 		  ? expr->pin_count() : 1;
4550 
4551 	    NetEvProbe*pr;
4552 	    switch (expr_[idx]->type()) {
4553 		case PEEvent::POSEDGE:
4554 		  pr = new NetEvProbe(scope, scope->local_symbol(), ev,
4555 				      NetEvProbe::POSEDGE, pins);
4556 		  break;
4557 
4558 		case PEEvent::NEGEDGE:
4559 		  pr = new NetEvProbe(scope, scope->local_symbol(), ev,
4560 				      NetEvProbe::NEGEDGE, pins);
4561 		  break;
4562 
4563 		case PEEvent::ANYEDGE:
4564 		  pr = new NetEvProbe(scope, scope->local_symbol(), ev,
4565 				      NetEvProbe::ANYEDGE, pins);
4566 		  break;
4567 
4568 		default:
4569 		  pr = NULL;
4570 		  assert(0);
4571 	    }
4572 
4573 	    for (unsigned p = 0 ;  p < pr->pin_count() ; p += 1)
4574 		  connect(pr->pin(p), expr->pin(p));
4575 
4576 	    des->add_node(pr);
4577 	    expr_count += 1;
4578       }
4579 
4580 	/* If there was at least one conjunction that was an
4581 	   expression (and not a named event) then add this
4582 	   event. Otherwise, we didn't use it so delete it. */
4583       if (expr_count > 0) {
4584 	    scope->add_event(ev);
4585 	    wa->add_event(ev);
4586 	      /* NOTE: This event that I am adding to the wait may be
4587 		 a duplicate of another event somewhere else. However,
4588 		 I don't know that until all the modules are hooked
4589 		 up, so it is best to leave find_similar_event to
4590 		 after elaboration. */
4591       } else {
4592 	    delete ev;
4593       }
4594 
4595       return wa;
4596 }
4597 
4598 /*
4599  * This is the special case of the event statement, the wait
4600  * statement. This is elaborated into a slightly more complicated
4601  * statement that uses non-wait statements:
4602  *
4603  *     wait (<expr>)  <statement>
4604  *
4605  * becomes
4606  *
4607  *     begin
4608  *         while (1 !== <expr>)
4609  *           @(<expr inputs>) <noop>;
4610  *         <statement>;
4611  *     end
4612  */
elaborate_wait(Design * des,NetScope * scope,NetProc * enet) const4613 NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope,
4614 					 NetProc*enet) const
4615 {
4616       assert(scope);
4617       assert(expr_.count() == 1);
4618 
4619       if (scope->in_func()) {
4620 	    cerr << get_fileline() << ": error: functions cannot have "
4621 	            "wait statements." << endl;
4622 	    des->errors += 1;
4623 	    return 0;
4624       }
4625 
4626       if (scope->in_final()) {
4627 	    cerr << get_fileline() << ": error: final procedures cannot "
4628 	            "have wait statements." << endl;
4629 	    des->errors += 1;
4630 	    return 0;
4631       }
4632 
4633       PExpr *pe = expr_[0]->expr();
4634 
4635 	/* Elaborate wait expression. Don't eval yet, we will do that
4636 	   shortly, after we apply a reduction or. */
4637 
4638       PExpr::width_mode_t mode = PExpr::SIZED;
4639       pe->test_width(des, scope, mode);
4640       NetExpr*expr = pe->elaborate_expr(des, scope, pe->expr_width(),
4641                                         PExpr::NO_FLAGS);
4642       if (expr == 0) {
4643 	    cerr << get_fileline() << ": error: Unable to elaborate"
4644 		  " wait condition expression." << endl;
4645 	    des->errors += 1;
4646 	    return 0;
4647       }
4648 
4649 	// If the condition expression is more than 1 bits, then
4650 	// generate a reduction operator to get the result down to
4651 	// one bit. In other words, Turn <e> into |<e>;
4652 
4653       if (expr->expr_width() < 1) {
4654 	    cerr << get_fileline() << ": internal error: "
4655 		  "incomprehensible wait expression width (0)." << endl;
4656 	    return 0;
4657       }
4658 
4659       if (expr->expr_width() > 1) {
4660 	    assert(expr->expr_width() > 1);
4661 	    NetEUReduce*cmp = new NetEUReduce('|', expr);
4662 	    cmp->set_line(*pe);
4663 	    expr = cmp;
4664       }
4665 
4666 	/* precalculate as much as possible of the wait expression. */
4667       eval_expr(expr);
4668 
4669 	/* Detect the unusual case that the wait expression is
4670 	   constant. Constant true is OK (it becomes transparent) but
4671 	   constant false is almost certainly not what is intended. */
4672       assert(expr->expr_width() == 1);
4673       if (NetEConst*ce = dynamic_cast<NetEConst*>(expr)) {
4674 	    verinum val = ce->value();
4675 	    assert(val.len() == 1);
4676 
4677 	      /* Constant true -- wait(1) <s1> reduces to <s1>. */
4678 	    if (val[0] == verinum::V1) {
4679 		  delete expr;
4680 		  assert(enet);
4681 		  return enet;
4682 	    }
4683 
4684 	      /* Otherwise, false. wait(0) blocks permanently. */
4685 
4686 	    cerr << get_fileline() << ": warning: wait expression is "
4687 		 << "constant false." << endl;
4688 	    cerr << get_fileline() << ":        : The statement will "
4689 		 << "block permanently." << endl;
4690 
4691 	      /* Create an event wait and an otherwise unreferenced
4692 		 event variable to force a perpetual wait. */
4693 	    NetEvent*wait_event = new NetEvent(scope->local_symbol());
4694 	    wait_event->set_line(*this);
4695 	    wait_event->local_flag(true);
4696 	    scope->add_event(wait_event);
4697 
4698 	    NetEvWait*wait = new NetEvWait(0);
4699 	    wait->add_event(wait_event);
4700 	    wait->set_line(*this);
4701 
4702 	    delete expr;
4703 	    delete enet;
4704 	    return wait;
4705       }
4706 
4707 	/* Invert the sense of the test with an exclusive NOR. In
4708 	   other words, if this adjusted expression returns TRUE, then
4709 	   wait. */
4710       assert(expr->expr_width() == 1);
4711       expr = new NetEBComp('N', expr, new NetEConst(verinum(verinum::V1)));
4712       expr->set_line(*pe);
4713       eval_expr(expr);
4714 
4715       NetEvent*wait_event = new NetEvent(scope->local_symbol());
4716       wait_event->set_line(*this);
4717       wait_event->local_flag(true);
4718       scope->add_event(wait_event);
4719 
4720       NetEvWait*wait = new NetEvWait(0 /* noop */);
4721       wait->add_event(wait_event);
4722       wait->set_line(*this);
4723 
4724       NexusSet*wait_set = expr->nex_input();
4725       if (wait_set == 0) {
4726 	    cerr << get_fileline() << ": internal error: No NexusSet"
4727 		 << " from wait expression." << endl;
4728 	    des->errors += 1;
4729 	    return 0;
4730       }
4731 
4732       if (wait_set->size() == 0) {
4733 	    cerr << get_fileline() << ": internal error: Empty NexusSet"
4734 		 << " from wait expression." << endl;
4735 	    des->errors += 1;
4736 	    return 0;
4737       }
4738 
4739       NetEvProbe*wait_pr = new NetEvProbe(scope, scope->local_symbol(),
4740 					  wait_event, NetEvProbe::ANYEDGE,
4741 					  wait_set->size());
4742       for (unsigned idx = 0; idx < wait_set->size() ;  idx += 1)
4743 	    connect(wait_set->at(idx).lnk, wait_pr->pin(idx));
4744 
4745       delete wait_set;
4746       des->add_node(wait_pr);
4747 
4748       NetWhile*loop = new NetWhile(expr, wait);
4749       loop->set_line(*this);
4750 
4751 	/* If there is no real substatement (i.e., "wait (foo) ;") then
4752 	   we are done. */
4753       if (enet == 0)
4754 	    return loop;
4755 
4756 	/* Create a sequential block to combine the wait loop and the
4757 	   delayed statement. */
4758       NetBlock*block = new NetBlock(NetBlock::SEQU, 0);
4759       block->append(loop);
4760       block->append(enet);
4761       block->set_line(*this);
4762 
4763       return block;
4764 }
4765 
4766 /*
4767  * This is a special case of the event statement, the wait fork
4768  * statement. This is elaborated into a simplified statement.
4769  *
4770  *     wait fork;
4771  *
4772  * becomes
4773  *
4774  *     @(0) <noop>;
4775  */
elaborate_wait_fork(Design * des,NetScope * scope) const4776 NetProc* PEventStatement::elaborate_wait_fork(Design*des, NetScope*scope) const
4777 {
4778       assert(scope);
4779       assert(expr_.count() == 1);
4780       assert(expr_[0] == 0);
4781       assert(! statement_);
4782 
4783       if (scope->in_func()) {
4784 	    cerr << get_fileline() << ": error: functions cannot have "
4785 	            "wait fork statements." << endl;
4786 	    des->errors += 1;
4787 	    return 0;
4788       }
4789 
4790       if (scope->in_final()) {
4791 	    cerr << get_fileline() << ": error: final procedures cannot "
4792 	            "have wait fork statements." << endl;
4793 	    des->errors += 1;
4794 	    return 0;
4795       }
4796 
4797       if (gn_system_verilog()) {
4798 	    NetEvWait*wait = new NetEvWait(0 /* noop */);
4799 	    wait->add_event(0);
4800 	    wait->set_line(*this);
4801 	    return wait;
4802       } else {
4803 	    cerr << get_fileline()
4804 	         << ": error: 'wait fork' requires SystemVerilog." << endl;
4805 	    des->errors += 1;
4806 	    return 0;
4807       }
4808 
4809 }
4810 
elaborate(Design * des,NetScope * scope) const4811 NetProc* PEventStatement::elaborate(Design*des, NetScope*scope) const
4812 {
4813 	/* Check to see if this is a wait fork statement. */
4814       if ((expr_.count() == 1) && (expr_[0] == 0))
4815 		  return elaborate_wait_fork(des, scope);
4816 
4817       NetProc*enet = 0;
4818       if (statement_) {
4819 	    enet = statement_->elaborate(des, scope);
4820 	    if (enet == 0)
4821 		  return 0;
4822 
4823       } else {
4824 	    enet = new NetBlock(NetBlock::SEQU, 0);
4825 	    enet->set_line(*this);
4826       }
4827 
4828       if ((expr_.count() == 1) && (expr_[0]->type() == PEEvent::POSITIVE))
4829 	    return elaborate_wait(des, scope, enet);
4830 
4831       return elaborate_st(des, scope, enet);
4832 }
4833 
4834 /*
4835  * Forever statements are represented directly in the netlist. It is
4836  * theoretically possible to use a while structure with a constant
4837  * expression to represent the loop, but why complicate the code
4838  * generators so?
4839  */
elaborate(Design * des,NetScope * scope) const4840 NetProc* PForever::elaborate(Design*des, NetScope*scope) const
4841 {
4842       NetProc*stat;
4843       if (statement_)
4844 	    stat = statement_->elaborate(des, scope);
4845       else
4846 	    stat = new NetBlock(NetBlock::SEQU, 0);
4847       if (stat == 0) return 0;
4848 
4849       NetForever*proc = new NetForever(stat);
4850       proc->set_line(*this);
4851       return proc;
4852 }
4853 
4854 /*
4855  * Force is like a procedural assignment, most notably procedural
4856  * continuous assignment:
4857  *
4858  *    force <lval> = <rval>
4859  *
4860  * The <lval> can be anything that a normal behavioral assignment can
4861  * take, plus net signals. This is a little bit more lax than the
4862  * other procedural assignments.
4863  */
elaborate(Design * des,NetScope * scope) const4864 NetForce* PForce::elaborate(Design*des, NetScope*scope) const
4865 {
4866       NetForce*dev = 0;
4867       assert(scope);
4868 
4869       if (scope->is_auto() && lval_->has_aa_term(des, scope)) {
4870 	    cerr << get_fileline() << ": error: automatically allocated "
4871                     "variables may not be assigned values using procedural "
4872 	            "force statements." << endl;
4873 	    des->errors += 1;
4874 	    return 0;
4875       }
4876 
4877       if (scope->is_auto() && expr_->has_aa_term(des, scope)) {
4878 	    cerr << get_fileline() << ": error: automatically allocated "
4879                     "variables may not be referenced in procedural force "
4880 	            "statements." << endl;
4881 	    des->errors += 1;
4882 	    return 0;
4883       }
4884 
4885       NetAssign_*lval = lval_->elaborate_lval(des, scope, false, true);
4886       if (lval == 0)
4887 	    return 0;
4888 
4889       unsigned lwid = count_lval_width(lval);
4890       ivl_variable_type_t ltype = lval->expr_type();
4891 
4892 	// Like a variety of other assigns, we need to figure out a
4893 	// better way to get a reasonable lv_net_type value, and that
4894 	// probably will involve NetAssign_ having a method for
4895 	// synthesizing one as needed.
4896       NetExpr*rexp = elaborate_rval_expr(des, scope, 0, ltype, lwid, expr_);
4897       if (rexp == 0)
4898 	    return 0;
4899 
4900       dev = new NetForce(lval, rexp);
4901 
4902       if (debug_elaborate) {
4903 	    cerr << get_fileline() << ": debug: Elaborate force,"
4904 		 << " lval width=" << lval->lwidth()
4905 		 << " rval width=" << rexp->expr_width()
4906 		 << " rval=" << *rexp
4907 		 << endl;
4908       }
4909 
4910       dev->set_line(*this);
4911       return dev;
4912 }
4913 
find_property_in_class(const LineInfo & loc,const NetScope * scope,perm_string name,const netclass_t * & found_in,int & property)4914 static void find_property_in_class(const LineInfo&loc, const NetScope*scope, perm_string name, const netclass_t*&found_in, int&property)
4915 {
4916       found_in = find_class_containing_scope(loc, scope);
4917       property = -1;
4918 
4919       if (found_in==0) return;
4920 
4921       property = found_in->property_idx_from_name(name);
4922       if (property < 0) {
4923 	    found_in = 0;
4924 	    return;
4925       }
4926 }
4927 
4928 /*
4929  * The foreach statement can be written as a for statement like so:
4930  *
4931  *     for (<idx> = $low(<array>) ; <idx> <= $high(<array>) ; <idx> += 1)
4932  *          <statement_>
4933  *
4934  * The <idx> variable is already known to be in the containing named
4935  * block scope, which was created by the parser.
4936  */
elaborate(Design * des,NetScope * scope) const4937 NetProc* PForeach::elaborate(Design*des, NetScope*scope) const
4938 {
4939 	// Locate the signal for the array variable
4940       pform_name_t array_name;
4941       array_name.push_back(name_component_t(array_var_));
4942       NetNet*array_sig = des->find_signal(scope, array_name);
4943 
4944 	// And if necessary, look for the class property that is
4945 	// referenced.
4946       const netclass_t*class_scope = 0;
4947       int class_property = -1;
4948       if (array_sig == 0)
4949 	    find_property_in_class(*this, scope, array_var_, class_scope, class_property);
4950 
4951       if (debug_elaborate && array_sig) {
4952 	    cerr << get_fileline() << ": PForeach::elaborate: "
4953 		 << "Found array_sig in " << scope_path(array_sig->scope()) << "." << endl;
4954       }
4955 
4956       if (debug_elaborate && class_scope) {
4957 	    cerr << get_fileline() << ": PForeach::elaborate: "
4958 		 << "Found array_sig property (" << class_property
4959 		 << ") in class " << class_scope->get_name()
4960 		 << " as " << *class_scope->get_prop_type(class_property) << "." << endl;
4961       }
4962 
4963       if (class_scope!=0 && class_property >= 0) {
4964 	    ivl_type_t ptype = class_scope->get_prop_type(class_property);
4965 	    const netsarray_t*atype = dynamic_cast<const netsarray_t*> (ptype);
4966 	    if (atype == 0) {
4967 		  cerr << get_fileline() << ": error: "
4968 		       << "I can't handle the type of " << array_var_
4969 		       << " as a foreach loop." << endl;
4970 		  des->errors += 1;
4971 		  return 0;
4972 	    }
4973 
4974 	    const std::vector<netrange_t>&dims = atype->static_dimensions();
4975 	    if (dims.size() < index_vars_.size()) {
4976 		  cerr << get_fileline() << ": error: "
4977 		       << "class " << class_scope->get_name()
4978 		       << " property " << array_var_
4979 		       << " has too few dimensions for foreach dimension list." << endl;
4980 		  des->errors += 1;
4981 		  return 0;
4982 	    }
4983 
4984 	    return elaborate_static_array_(des, scope, dims);
4985       }
4986 
4987       if (array_sig == 0) {
4988 	    cerr << get_fileline() << ": error:"
4989 		 << " Unable to find foreach array " << array_name
4990 		 << " in scope " << scope_path(scope)
4991 		 << "." << endl;
4992 	    des->errors += 1;
4993 	    return 0;
4994       }
4995 
4996       ivl_assert(*this, array_sig);
4997 
4998       if (debug_elaborate) {
4999 	    cerr << get_fileline() << ": PForeach::elaborate: "
5000 		 << "Scan array " << array_sig->name()
5001 		 << " of " << array_sig->data_type()
5002 		 << " with " << array_sig->unpacked_dimensions() << " unpacked"
5003 		 << " and " << array_sig->packed_dimensions()
5004 		 << " packed dimensions." << endl;
5005       }
5006 
5007       std::vector<netrange_t>dims = array_sig->unpacked_dims();
5008       if (array_sig->packed_dimensions() > 0) {
5009             dims.insert(dims.end(), array_sig->packed_dims().begin(), array_sig->packed_dims().end());
5010       }
5011 
5012 	// Classic arrays are processed this way.
5013       if (array_sig->data_type()==IVL_VT_BOOL)
5014 	    return elaborate_static_array_(des, scope, dims);
5015       if (array_sig->data_type()==IVL_VT_LOGIC)
5016 	    return elaborate_static_array_(des, scope, dims);
5017       if (array_sig->unpacked_dimensions() >= index_vars_.size())
5018 	    return elaborate_static_array_(des, scope, dims);
5019 
5020 	// At this point, we know that the array is dynamic so we
5021 	// handle that slightly differently, using run-time tests.
5022 
5023       if (index_vars_.size() != 1) {
5024 	    cerr << get_fileline() << ": sorry: "
5025 		 << "Multi-index foreach loops not supported." << endl;
5026 	    des->errors += 1;
5027       }
5028 
5029 	// Get the signal for the index variable.
5030       pform_name_t index_name;
5031       index_name.push_back(name_component_t(index_vars_[0]));
5032       NetNet*idx_sig = des->find_signal(scope, index_name);
5033       ivl_assert(*this, idx_sig);
5034 
5035       NetESignal*array_exp = new NetESignal(array_sig);
5036       array_exp->set_line(*this);
5037 
5038       NetESignal*idx_exp = new NetESignal(idx_sig);
5039       idx_exp->set_line(*this);
5040 
5041 	// Make an initialization expression for the index.
5042       NetESFunc*init_expr = new NetESFunc("$low", IVL_VT_BOOL, 32, 1);
5043       init_expr->set_line(*this);
5044       init_expr->parm(0, array_exp);
5045 
5046 	// Make a condition expression: idx <= $high(array)
5047       NetESFunc*high_exp = new NetESFunc("$high", IVL_VT_BOOL, 32, 1);
5048       high_exp->set_line(*this);
5049       high_exp->parm(0, array_exp);
5050 
5051       NetEBComp*cond_expr = new NetEBComp('L', idx_exp, high_exp);
5052       cond_expr->set_line(*this);
5053 
5054 	/* Elaborate the statement that is contained in the foreach
5055 	   loop. */
5056       NetProc*sub;
5057       if (statement_)
5058 	    sub = statement_->elaborate(des, scope);
5059       else
5060 	    sub = new NetBlock(NetBlock::SEQU, 0);
5061 
5062 	/* Make a step statement: idx += 1 */
5063       NetAssign_*idx_lv = new NetAssign_(idx_sig);
5064       NetEConst*step_val = make_const_val(1);
5065       NetAssign*step = new NetAssign(idx_lv, '+', step_val);
5066       step->set_line(*this);
5067 
5068       NetForLoop*stmt = new NetForLoop(idx_sig, init_expr, cond_expr, sub, step);
5069       stmt->set_line(*this);
5070       stmt->wrap_up();
5071 
5072       return stmt;
5073 }
5074 
5075 /*
5076  * This is a variant of the PForeach::elaborate() method that handles
5077  * the case that the array has static dimensions. We can use constants
5078  * and possibly do some optimizations.
5079  */
elaborate_static_array_(Design * des,NetScope * scope,const vector<netrange_t> & dims) const5080 NetProc* PForeach::elaborate_static_array_(Design*des, NetScope*scope,
5081 					   const vector<netrange_t>&dims) const
5082 {
5083       if (debug_elaborate) {
5084 	    cerr << get_fileline() << ": PForeach::elaborate_static_array_: "
5085 		 << "Handle as array with static dimensions." << endl;
5086       }
5087 
5088       ivl_assert(*this, index_vars_.size() > 0);
5089       ivl_assert(*this, dims.size() >= index_vars_.size());
5090 
5091       NetProc*sub;
5092       if (statement_)
5093 	    sub = statement_->elaborate(des, scope);
5094       else
5095 	    sub = new NetBlock(NetBlock::SEQU, 0);
5096       NetForLoop*stmt = 0;
5097 
5098       for (int idx_idx = index_vars_.size()-1 ; idx_idx >= 0 ; idx_idx -= 1) {
5099 	    const netrange_t&idx_range = dims[idx_idx];
5100 
5101 	      // Get the $high and $low constant values for this slice
5102 	      // of the array.
5103 	    NetEConst*hig_expr = make_const_val_s(idx_range.get_msb());
5104 	    NetEConst*low_expr = make_const_val_s(idx_range.get_lsb());
5105 	    if (idx_range.get_msb() < idx_range.get_lsb()) {
5106 		  NetEConst*tmp = hig_expr;
5107 		  hig_expr = low_expr;
5108 		  low_expr = tmp;
5109 	    }
5110 
5111 	    hig_expr->set_line(*this);
5112 	    low_expr->set_line(*this);
5113 
5114 	    pform_name_t idx_name;
5115 	    idx_name.push_back(name_component_t(index_vars_[idx_idx]));
5116 	    NetNet*idx_sig = des->find_signal(scope, idx_name);
5117 	    ivl_assert(*this, idx_sig);
5118 
5119 	      // Make the condition expression <idx> <= $high(slice)
5120 	    NetESignal*idx_expr = new NetESignal(idx_sig);
5121 	    idx_expr->set_line(*this);
5122 
5123 	    NetEBComp*cond_expr = new NetEBComp('L', idx_expr, hig_expr);
5124 	    cond_expr->set_line(*this);
5125 
5126 	      // Make the step statement: <idx> += 1
5127 	    NetAssign_*idx_lv = new NetAssign_(idx_sig);
5128 	    NetEConst*step_val = make_const_val_s(1);
5129 	    NetAssign*step = new NetAssign(idx_lv, '+', step_val);
5130 	    step->set_line(*this);
5131 
5132 	    stmt = new NetForLoop(idx_sig, low_expr, cond_expr, sub, step);
5133 	    stmt->set_line(*this);
5134 	    stmt->wrap_up();
5135 
5136 	    sub = stmt;
5137       }
5138 
5139       return stmt? stmt : sub;
5140 }
5141 
5142 /*
5143  * elaborate the for loop as the equivalent while loop. This eases the
5144  * task for the target code generator. The structure is:
5145  *
5146  *     begin : top
5147  *       name1_ = expr1_;
5148  *       while (cond_) begin : body
5149  *          statement_;
5150  *          name2_ = expr2_;
5151  *       end
5152  *     end
5153  */
elaborate(Design * des,NetScope * scope) const5154 NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
5155 {
5156       NetExpr*initial_expr;
5157       assert(scope);
5158 
5159       const PEIdent*id1 = dynamic_cast<const PEIdent*>(name1_);
5160       assert(id1);
5161 
5162 	/* make the expression, and later the initial assignment to
5163 	   the condition variable. The statement in the for loop is
5164 	   very specifically an assignment. */
5165       NetNet*sig = des->find_signal(scope, id1->path());
5166       if (sig == 0) {
5167 	    cerr << id1->get_fileline() << ": register ``" << id1->path()
5168 		 << "'' unknown in " << scope_path(scope) << "." << endl;
5169 	    des->errors += 1;
5170 	    return 0;
5171       }
5172       assert(sig);
5173 
5174 	/* Make the r-value of the initial assignment, and size it
5175 	   properly. Then use it to build the assignment statement. */
5176       initial_expr = elaborate_rval_expr(des, scope, sig->net_type(),
5177 					 sig->data_type(), sig->vector_width(),
5178 					 expr1_);
5179 
5180       if (debug_elaborate && initial_expr) {
5181 	    cerr << get_fileline() << ": debug: FOR initial assign: "
5182 		 << sig->name() << " = " << *initial_expr << endl;
5183       }
5184 
5185 	/* Elaborate the statement that is contained in the for
5186 	   loop. If there is an error, this will return 0 and I should
5187 	   skip the append. No need to worry, the error has been
5188 	   reported so it's OK that the netlist is bogus. */
5189       NetProc*sub;
5190       if (statement_)
5191 	    sub = statement_->elaborate(des, scope);
5192       else
5193 	    sub = new NetBlock(NetBlock::SEQU, 0);
5194 
5195 	/* Now elaborate the for_step statement. I really should do
5196 	   some error checking here to make sure the step statement
5197 	   really does step the variable. */
5198       NetProc*step = step_->elaborate(des, scope);
5199 
5200 	/* Elaborate the condition expression. Try to evaluate it too,
5201 	   in case it is a constant. This is an interesting case
5202 	   worthy of a warning. */
5203       NetExpr*ce = elab_and_eval(des, scope, cond_, -1);
5204       if (dynamic_cast<NetEConst*>(ce)) {
5205 	    cerr << get_fileline() << ": warning: condition expression "
5206 		  "of for-loop is constant." << endl;
5207       }
5208 
5209 	/* Error recovery - if we failed to elaborate any of the loop
5210 	   expressions, give up now. */
5211       if (initial_expr == 0 || ce == 0 || step == 0 || sub == 0) {
5212 	    delete initial_expr;
5213 	    delete ce;
5214 	    delete step;
5215 	    delete sub;
5216 	    return 0;
5217       }
5218 	/* All done, build up the loop. */
5219 
5220       NetForLoop*loop = new NetForLoop(sig, initial_expr, ce, sub, step);
5221       loop->set_line(*this);
5222       loop->wrap_up();
5223       return loop;
5224 }
5225 
5226 /*
5227  * (See the PTask::elaborate methods for basic common stuff.)
5228  *
5229  * The return value of a function is represented as a reg variable
5230  * within the scope of the function that has the name of the
5231  * function. So for example with the function:
5232  *
5233  *    function [7:0] incr;
5234  *      input [7:0] in1;
5235  *      incr = in1 + 1;
5236  *    endfunction
5237  *
5238  * The scope of the function is <parent>.incr and there is a reg
5239  * variable <parent>.incr.incr. The elaborate_1 method is called with
5240  * the scope of the function, so the return reg is easily located.
5241  *
5242  * The function parameters are all inputs, except for the synthetic
5243  * output parameter that is the return value. The return value goes
5244  * into port 0, and the parameters are all the remaining ports.
5245  */
5246 
elaborate(Design * des,NetScope * scope) const5247 void PFunction::elaborate(Design*des, NetScope*scope) const
5248 {
5249       if (scope->elab_stage() > 2)
5250             return;
5251 
5252       scope->set_elab_stage(3);
5253 
5254       NetFuncDef*def = scope->func_def();
5255       if (def == 0) {
5256 	    cerr << get_fileline() << ": internal error: "
5257 		 << "No function definition for function "
5258 		 << scope_path(scope) << endl;
5259 	    des->errors += 1;
5260 	    return;
5261       }
5262       assert(def);
5263 
5264       ivl_assert(*this, statement_);
5265       NetProc*st = statement_->elaborate(des, scope);
5266       if (st == 0) {
5267 	    cerr << statement_->get_fileline() << ": error: Unable to elaborate "
5268 		  "statement in function " << scope->basename() << "." << endl;
5269             scope->is_const_func(true); // error recovery
5270 	    des->errors += 1;
5271 	    return;
5272       }
5273 
5274 	// Handle any variable initialization statements in this scope.
5275 	// For automatic functions, these statements need to be executed
5276 	// each time the function is called, so insert them at the start
5277 	// of the elaborated definition. For static functions, put them
5278 	// in a separate process that will be executed before the start
5279 	// of simulation.
5280       if (is_auto_) {
5281 	      // Get the NetBlock of the statement. If it is not a
5282 	      // NetBlock then create one to wrap the initialization
5283 	      // statements and the original statement.
5284 	    NetBlock*blk = dynamic_cast<NetBlock*> (st);
5285 	    if ((blk == 0) && (var_inits.size() > 0)) {
5286 		  blk = new NetBlock(NetBlock::SEQU, scope);
5287 		  blk->set_line(*this);
5288 		  blk->append(st);
5289 		  st = blk;
5290 	    }
5291 	    for (unsigned idx = var_inits.size(); idx > 0; idx -= 1) {
5292 		  NetProc*tmp = var_inits[idx-1]->elaborate(des, scope);
5293 		  if (tmp) blk->prepend(tmp);
5294 	    }
5295       } else {
5296 	    elaborate_var_inits_(des, scope);
5297       }
5298 
5299       def->set_proc(st);
5300 }
5301 
elaborate(Design * des,NetScope * scope) const5302 NetProc* PRelease::elaborate(Design*des, NetScope*scope) const
5303 {
5304       assert(scope);
5305 
5306       if (scope->is_auto() && lval_->has_aa_term(des, scope)) {
5307 	    cerr << get_fileline() << ": error: automatically allocated "
5308                     "variables may not be assigned values using procedural "
5309 	            "force statements." << endl;
5310 	    des->errors += 1;
5311 	    return 0;
5312       }
5313 
5314       NetAssign_*lval = lval_->elaborate_lval(des, scope, false, true);
5315       if (lval == 0)
5316 	    return 0;
5317 
5318       NetRelease*dev = new NetRelease(lval);
5319       dev->set_line( *this );
5320       return dev;
5321 }
5322 
elaborate(Design * des,NetScope * scope) const5323 NetProc* PRepeat::elaborate(Design*des, NetScope*scope) const
5324 {
5325       assert(scope);
5326 
5327       NetExpr*expr = elab_and_eval(des, scope, expr_, -1);
5328       if (expr == 0) {
5329 	    cerr << get_fileline() << ": Unable to elaborate"
5330 		  " repeat expression." << endl;
5331 	    des->errors += 1;
5332 	    return 0;
5333       }
5334 	// If the expression is real, convert to an integer. 64 bits
5335 	// should be more enough for any real use case.
5336       if (expr->expr_type() == IVL_VT_REAL)
5337 	    expr = cast_to_int4(expr, 64);
5338 
5339       NetProc*stat;
5340       if (statement_)
5341 	    stat = statement_->elaborate(des, scope);
5342       else
5343 	    stat = new NetBlock(NetBlock::SEQU, 0);
5344       if (stat == 0) return 0;
5345 
5346 	// If the expression is a constant, handle certain special
5347 	// iteration counts.
5348       if (NetEConst*ce = dynamic_cast<NetEConst*>(expr)) {
5349 	    long val = ce->value().as_long();
5350 	    if (val <= 0) {
5351 		  delete expr;
5352 		  delete stat;
5353 		  return new NetBlock(NetBlock::SEQU, 0);
5354 	    } else if (val == 1) {
5355 		  delete expr;
5356 		  return stat;
5357 	    }
5358       }
5359 
5360       NetRepeat*proc = new NetRepeat(expr, stat);
5361       proc->set_line( *this );
5362       return proc;
5363 }
5364 
elaborate(Design * des,NetScope * scope) const5365 NetProc* PReturn::elaborate(Design*des, NetScope*scope) const
5366 {
5367       NetScope*target = scope;
5368       for (;;) {
5369 	    if (target == 0) {
5370 		  cerr << get_fileline() << ": error: "
5371 		       << "Return statement is not in a function." << endl;
5372 		  des->errors += 1;
5373 		  return 0;
5374 	    }
5375 
5376 	    if (target->type() == NetScope::FUNC)
5377 		  break;
5378 
5379 	    if (target->type() == NetScope::TASK) {
5380 		  cerr << get_fileline() << ": error: "
5381 		       << "Cannot \"return\" from tasks." << endl;
5382 		  des->errors += 1;
5383 		  return 0;
5384 	    }
5385 
5386 	    if (target->type()==NetScope::BEGIN_END) {
5387 		  target = target->parent();
5388 		  continue;
5389 	    }
5390 
5391 	    cerr << get_fileline() << ": error: "
5392 		 << "Cannot \"return\" from this scope: " << scope_path(target) << endl;
5393 	    des->errors += 1;
5394 	    return 0;
5395       }
5396       ivl_assert(*this, target->type() == NetScope::FUNC);
5397 
5398       if (target->func_def()->is_void()) {
5399 	    if (expr_) {
5400 		  cerr << get_fileline() << ": error: "
5401 		       << "A value can't be returned from a void function." << endl;
5402 		  des->errors += 1;
5403 		  return 0;
5404 	    }
5405 	    NetDisable*disa = new NetDisable(target);
5406 	    disa->set_line( *this );
5407 	    return disa;
5408       }
5409 
5410       if (expr_ == 0) {
5411 	    cerr << get_fileline() << ": error: "
5412 		 << "Return from " << scope_path(target)
5413 		 << " requires a return value expression." << endl;
5414 	    des->errors += 1;
5415 	    return 0;
5416       }
5417 
5418       NetNet*res = target->find_signal(target->basename());
5419       ivl_assert(*this, res);
5420       ivl_variable_type_t lv_type = res->data_type();
5421       unsigned long wid = res->vector_width();
5422       NetAssign_*lv = new NetAssign_(res);
5423 
5424       NetExpr*val = elaborate_rval_expr(des, scope, res->net_type(),
5425 					lv_type, wid, expr_);
5426 
5427       NetBlock*proc = new NetBlock(NetBlock::SEQU, 0);
5428       proc->set_line( *this );
5429 
5430       NetAssign*assn = new NetAssign(lv, val);
5431       assn->set_line( *this );
5432       proc->append(assn);
5433 
5434       NetDisable*disa = new NetDisable(target);
5435       disa->set_line( *this );
5436       proc->append( disa );
5437 
5438       return proc;
5439 }
5440 
5441 /*
5442  * A task definition is elaborated by elaborating the statement that
5443  * it contains, and connecting its ports to NetNet objects. The
5444  * netlist doesn't really need the array of parameters once elaboration
5445  * is complete, but this is the best place to store them.
5446  *
5447  * The first elaboration pass finds the reg objects that match the
5448  * port names, and creates the NetTaskDef object. The port names are
5449  * in the form task.port.
5450  *
5451  *      task foo;
5452  *        output blah;
5453  *        begin <body> end
5454  *      endtask
5455  *
5456  * So in the foo example, the PWire objects that represent the ports
5457  * of the task will include a foo.blah for the blah port. This port is
5458  * bound to a NetNet object by looking up the name. All of this is
5459  * handled by the PTask::elaborate_sig method and the results stashed
5460  * in the created NetTaskDef attached to the scope.
5461  *
5462  * Elaboration pass 2 for the task definition causes the statement of
5463  * the task to be elaborated and attached to the NetTaskDef object
5464  * created in pass 1.
5465  *
5466  * NOTE: I am not sure why I bothered to prepend the task name to the
5467  * port name when making the port list. It is not really useful, but
5468  * that is what I did in pform_make_task_ports, so there it is.
5469  */
5470 
elaborate(Design * des,NetScope * task) const5471 void PTask::elaborate(Design*des, NetScope*task) const
5472 {
5473       NetTaskDef*def = task->task_def();
5474       assert(def);
5475 
5476       NetProc*st;
5477       if (statement_ == 0) {
5478 	    st = new NetBlock(NetBlock::SEQU, 0);
5479 
5480       } else {
5481 
5482 	    st = statement_->elaborate(des, task);
5483 	    if (st == 0) {
5484 		  cerr << statement_->get_fileline() << ": Unable to elaborate "
5485 			"statement in task " << scope_path(task)
5486 		       << " at " << get_fileline() << "." << endl;
5487 		  return;
5488 	    }
5489       }
5490 
5491 	// Handle any variable initialization statements in this scope.
5492 	// For automatic tasks , these statements need to be executed
5493 	// each time the task is called, so insert them at the start
5494 	// of the elaborated definition. For static tasks, put them
5495 	// in a separate process that will be executed before the start
5496 	// of simulation.
5497       if (is_auto_) {
5498 	      // Get the NetBlock of the statement. If it is not a
5499 	      // NetBlock then create one to wrap the initialization
5500 	      // statements and the original statement.
5501 	    NetBlock*blk = dynamic_cast<NetBlock*> (st);
5502 	    if ((blk == 0) && (var_inits.size() > 0)) {
5503 		  blk = new NetBlock(NetBlock::SEQU, task);
5504 		  blk->set_line(*this);
5505 		  blk->append(st);
5506 		  st = blk;
5507 	    }
5508 	    for (unsigned idx = var_inits.size(); idx > 0; idx -= 1) {
5509 		  NetProc*tmp = var_inits[idx-1]->elaborate(des, task);
5510 		  if (tmp) blk->prepend(tmp);
5511 	    }
5512       } else {
5513 	    elaborate_var_inits_(des, task);
5514       }
5515 
5516       def->set_proc(st);
5517 }
5518 
elaborate(Design * des,NetScope * scope) const5519 NetProc* PTrigger::elaborate(Design*des, NetScope*scope) const
5520 {
5521       assert(scope);
5522 
5523       NetScope*use_scope = scope;
5524       if (package_) {
5525 	    use_scope = des->find_package(package_->pscope_name());
5526 	    ivl_assert(*this, use_scope);
5527       }
5528 
5529       NetNet*       sig = 0;
5530       const NetExpr*par = 0;
5531       NetEvent*     eve = 0;
5532 
5533       NetScope*found_in = symbol_search(this, des, use_scope, event_,
5534 					sig, par, eve);
5535 
5536       if (found_in == 0) {
5537 	    cerr << get_fileline() << ": error: event <" << event_ << ">"
5538 		 << " not found." << endl;
5539 	    des->errors += 1;
5540 	    return 0;
5541       }
5542 
5543       if (eve == 0) {
5544 	    cerr << get_fileline() << ": error:  <" << event_ << ">"
5545 		 << " is not a named event." << endl;
5546 	    des->errors += 1;
5547 	    return 0;
5548       }
5549 
5550       NetEvTrig*trig = new NetEvTrig(eve);
5551       trig->set_line(*this);
5552       return trig;
5553 }
5554 
5555 /*
5556  * The while loop is fairly directly represented in the netlist.
5557  */
elaborate(Design * des,NetScope * scope) const5558 NetProc* PWhile::elaborate(Design*des, NetScope*scope) const
5559 {
5560       NetExpr*ce = elab_and_eval(des, scope, cond_, -1);
5561       NetProc*sub;
5562       if (statement_)
5563 	    sub = statement_->elaborate(des, scope);
5564       else
5565 	    sub = new NetBlock(NetBlock::SEQU, 0);
5566       if (ce == 0 || sub == 0) {
5567 	    delete ce;
5568 	    delete sub;
5569 	    return 0;
5570       }
5571       NetWhile*loop = new NetWhile(ce, sub);
5572       loop->set_line(*this);
5573       return loop;
5574 }
5575 
elaborate(Design * des,NetScope * scope) const5576 bool PProcess::elaborate(Design*des, NetScope*scope) const
5577 {
5578       scope->in_final(type() == IVL_PR_FINAL);
5579       NetProc*cur = statement_->elaborate(des, scope);
5580       scope->in_final(false);
5581       if (cur == 0) {
5582 	    return false;
5583       }
5584 
5585       NetProcTop*top=new NetProcTop(scope, type(), cur);
5586       ivl_assert(*this, top);
5587 
5588 	// Evaluate the attributes for this process, if there
5589 	// are any. These attributes are to be attached to the
5590 	// NetProcTop object.
5591       struct attrib_list_t*attrib_list;
5592       unsigned attrib_list_n = 0;
5593       attrib_list = evaluate_attributes(attributes, attrib_list_n, des, scope);
5594 
5595       for (unsigned adx = 0 ;  adx < attrib_list_n ;  adx += 1)
5596 	    top->attribute(attrib_list[adx].key,
5597 			   attrib_list[adx].val);
5598 
5599       delete[]attrib_list;
5600 
5601       top->set_line(*this);
5602       des->add_process(top);
5603 
5604 	/* Detect the special case that this is a combinational
5605 	always block. We want to attach an _ivl_schedule_push
5606 	attribute to this process so that it starts up and
5607 	gets into its wait statement before non-combinational
5608 	code is executed. */
5609       do {
5610 	    if ((top->type() != IVL_PR_ALWAYS) &&
5611 	        (top->type() != IVL_PR_ALWAYS_COMB) &&
5612 	        (top->type() != IVL_PR_ALWAYS_FF) &&
5613 	        (top->type() != IVL_PR_ALWAYS_LATCH))
5614 		  break;
5615 
5616 	    NetEvWait*st = dynamic_cast<NetEvWait*>(top->statement());
5617 	    if (st == 0)
5618 		  break;
5619 
5620 	    if (st->nevents() != 1)
5621 		  break;
5622 
5623 	    NetEvent*ev = st->event(0);
5624 
5625 	    if (ev->nprobe() == 0)
5626 		  break;
5627 
5628 	    bool anyedge_test = true;
5629 	    for (unsigned idx = 0 ;  anyedge_test && (idx<ev->nprobe())
5630 		       ; idx += 1) {
5631 		  const NetEvProbe*pr = ev->probe(idx);
5632 		  if (pr->edge() != NetEvProbe::ANYEDGE)
5633 			anyedge_test = false;
5634 	    }
5635 
5636 	    if (! anyedge_test)
5637 		  break;
5638 
5639 	    top->attribute(perm_string::literal("_ivl_schedule_push"),
5640 			   verinum(1));
5641       } while (0);
5642 
5643       return true;
5644 }
5645 
elaborate(Design * des,NetScope * scope) const5646 void PSpecPath::elaborate(Design*des, NetScope*scope) const
5647 {
5648       uint64_t delay_value[12];
5649       unsigned ndelays = 0;
5650 
5651 	/* Do not elaborate specify delay paths if this feature is
5652 	   turned off. */
5653       if (!gn_specify_blocks_flag) return;
5654 
5655       ivl_assert(*this, conditional || (condition==0));
5656 
5657       ndelays = delays.size();
5658       if (ndelays > 12) ndelays = 12;
5659 
5660       check_for_inconsistent_delays(scope);
5661 
5662 	/* Elaborate the delay values themselves. Remember to scale
5663 	   them for the timescale/precision of the scope. */
5664       for (unsigned idx = 0 ;  idx < ndelays ;  idx += 1) {
5665 	    PExpr*exp = delays[idx];
5666 	    NetExpr*cur = elab_and_eval(des, scope, exp, -1);
5667 
5668 	    if (NetEConst*con = dynamic_cast<NetEConst*> (cur)) {
5669 		  verinum fn = con->value();
5670 		  delay_value[idx] = des->scale_to_precision(fn.as_ulong64(),
5671 		                                             scope);
5672 
5673 	    } else if (NetECReal*rcon = dynamic_cast<NetECReal*>(cur)) {
5674 		  delay_value[idx] = get_scaled_time_from_real(des, scope,
5675 		                                               rcon);
5676 
5677 	    } else {
5678 		  cerr << get_fileline() << ": error: Path delay value "
5679 		       << "must be constant (" << *cur << ")." << endl;
5680 		  delay_value[idx] = 0;
5681 		  des->errors += 1;
5682 	    }
5683 	    delete cur;
5684       }
5685 
5686       switch (delays.size()) {
5687 	  case 1:
5688 	  case 2:
5689 	  case 3:
5690 	  case 6:
5691 	  case 12:
5692 	    break;
5693 	  default:
5694 	    cerr << get_fileline() << ": error: Incorrect delay configuration."
5695 		 << " Given " << delays.size() << " delay expressions." << endl;
5696 	    ndelays = 1;
5697 	    des->errors += 1;
5698 	    break;
5699       }
5700 
5701       NetNet*condit_sig = 0;
5702       if (conditional && condition) {
5703 
5704 	    NetExpr*tmp = elab_and_eval(des, scope, condition, -1);
5705 	    ivl_assert(*condition, tmp);
5706 
5707 	      // FIXME: Look for constant expressions here?
5708 
5709 	      // Get a net form.
5710 	    condit_sig = tmp->synthesize(des, scope, tmp);
5711 	    ivl_assert(*condition, condit_sig);
5712       }
5713 
5714 	/* A parallel connection does not support more than a one to one
5715 	   connection (source/destination). */
5716       if (! full_flag_ && ((src.size() != 1) || (dst.size() != 1))) {
5717 	    /* To be compatible with NC-Verilog we allow a parallel connection
5718 	     * with multiple sources/destinations if all the paths are only a
5719 	     * single bit wide (a scalar or a one bit vector). */
5720 	    bool all_single = true;
5721 	    typedef std::vector<perm_string>::const_iterator str_vec_iter;
5722 	    for (str_vec_iter cur = src.begin();
5723 		 ( cur != src.end() && all_single); ++ cur) {
5724 		  NetNet *psig = scope->find_signal(*cur);
5725 		    /* We will report a missing signal as invalid later. For
5726 		     * now assume it's a single bit. */
5727 		  if (psig == 0) continue;
5728 		  if (psig->vector_width() != 1) all_single = false;
5729 	    }
5730 	    for (str_vec_iter cur = dst.begin();
5731 		 ( cur != dst.end() && all_single); ++ cur) {
5732 		  NetNet *psig = scope->find_signal(*cur);
5733 		    /* The same as above for source paths. */
5734 		  if (psig == 0) continue;
5735 		  if (psig->vector_width() != 1) all_single = false;
5736 	    }
5737 
5738 	    if (! all_single) {
5739 		  cerr << get_fileline() << ": error: Parallel connections "
5740 		          "only support one source/destination path found ("
5741 		       << src.size() << "/" << dst.size() << ")." << endl;
5742 		  des->errors += 1;
5743 	    }
5744       }
5745 
5746 	/* Create all the various paths from the path specifier. */
5747       typedef std::vector<perm_string>::const_iterator str_vector_iter;
5748       for (str_vector_iter cur = dst.begin()
5749 		 ; cur != dst.end() ; ++ cur ) {
5750 
5751 	    if (debug_elaborate) {
5752 		  cerr << get_fileline() << ": debug: Path to " << (*cur);
5753 		  if (condit_sig)
5754 			cerr << " if " << condit_sig->name();
5755 		  else if (conditional)
5756 			cerr << " ifnone";
5757 		  cerr << " from ";
5758 	    }
5759 
5760 	    NetNet*dst_sig = scope->find_signal(*cur);
5761 	    if (dst_sig == 0) {
5762 		  cerr << get_fileline() << ": error: No wire '"
5763 		       << *cur << "' in this module." << endl;
5764 		  des->errors += 1;
5765 		  continue;
5766 	    }
5767 
5768 	    unsigned long dst_wid = dst_sig->vector_width();
5769 
5770 	    if (dst_sig->port_type() != NetNet::POUTPUT
5771 		&& dst_sig->port_type() != NetNet::PINOUT) {
5772 
5773 		  cerr << get_fileline() << ": error: Path destination "
5774 		       << *cur << " must be an output or inout port." << endl;
5775 		  des->errors += 1;
5776 	    }
5777 
5778 	    NetDelaySrc*path = new NetDelaySrc(scope, scope->local_symbol(),
5779 					       src.size(), condit_sig,
5780 					       conditional, !full_flag_);
5781 	    path->set_line(*this);
5782 
5783 	      // The presence of the data_source_expression indicates
5784 	      // that this is an edge sensitive path. If so, then set
5785 	      // the edges. Note that edge==0 is BOTH edges.
5786 	    if (data_source_expression) {
5787 		  if (edge >= 0) path->set_posedge();
5788 		  if (edge <= 0) path->set_negedge();
5789 	    }
5790 
5791 	    switch (ndelays) {
5792 		case 12:
5793 		  path->set_delays(delay_value[0],  delay_value[1],
5794 				   delay_value[2],  delay_value[3],
5795 				   delay_value[4],  delay_value[5],
5796 				   delay_value[6],  delay_value[7],
5797 				   delay_value[8],  delay_value[9],
5798 				   delay_value[10], delay_value[11]);
5799 		  break;
5800 		case 6:
5801 		  path->set_delays(delay_value[0], delay_value[1],
5802 				   delay_value[2], delay_value[3],
5803 				   delay_value[4], delay_value[5]);
5804 		  break;
5805 		case 3:
5806 		  path->set_delays(delay_value[0], delay_value[1],
5807 				   delay_value[2]);
5808 		  break;
5809 		case 2:
5810 		  path->set_delays(delay_value[0], delay_value[1]);
5811 		  break;
5812 		case 1:
5813 		  path->set_delays(delay_value[0]);
5814 		  break;
5815 	    }
5816 
5817 	    unsigned idx = 0;
5818 	    for (str_vector_iter cur_src = src.begin()
5819 		       ; cur_src != src.end() ; ++ cur_src ) {
5820 		  NetNet*src_sig = scope->find_signal(*cur_src);
5821 		  if (src_sig == 0) {
5822 			cerr << get_fileline() << ": error: No wire '"
5823 			     << *cur_src << "' in this module." << endl;
5824 			des->errors += 1;
5825 			continue;
5826 		  }
5827 
5828 		  if (debug_elaborate) {
5829 			if (cur_src != src.begin()) cerr << " and ";
5830 			cerr << src_sig->name();
5831 		  }
5832 
5833 		  if ( (src_sig->port_type() != NetNet::PINPUT)
5834 		    && (src_sig->port_type() != NetNet::PINOUT) ) {
5835 
5836 			cerr << get_fileline() << ": error: Path source "
5837 			     << *cur_src << " must be an input or inout port."
5838 			     << endl;
5839 			des->errors += 1;
5840 		  }
5841 
5842 		    // For a parallel connection the source and destination
5843 		    // must be the same width.
5844 		  if (! full_flag_) {
5845 			unsigned long src_wid = src_sig->vector_width();
5846 			if (src_wid != dst_wid) {
5847 			      cerr << get_fileline() << ": error: For a "
5848 			              "parallel connection the "
5849 			              "source/destination width must match "
5850 			              "found (" << src_wid << "/" << dst_wid
5851 			           << ")." << endl;
5852 			      des->errors += 1;
5853 			}
5854 		  }
5855 
5856 		  connect(src_sig->pin(0), path->pin(idx));
5857 		  idx += 1;
5858 	    }
5859 	    if (debug_elaborate) {
5860 		  cerr << endl;
5861 	    }
5862 
5863 	    if (condit_sig)
5864 		  connect(condit_sig->pin(0), path->pin(idx));
5865 
5866 	    dst_sig->add_delay_path(path);
5867       }
5868 }
5869 
elaborate_functions(Design * des,NetScope * scope,const map<perm_string,PFunction * > & funcs)5870 static void elaborate_functions(Design*des, NetScope*scope,
5871 				const map<perm_string,PFunction*>&funcs)
5872 {
5873       typedef map<perm_string,PFunction*>::const_iterator mfunc_it_t;
5874       for (mfunc_it_t cur = funcs.begin()
5875 		 ; cur != funcs.end() ; ++ cur ) {
5876 
5877 	    hname_t use_name ( (*cur).first );
5878 	    NetScope*fscope = scope->child(use_name);
5879 	    assert(fscope);
5880 	    (*cur).second->elaborate(des, fscope);
5881       }
5882 }
5883 
elaborate_tasks(Design * des,NetScope * scope,const map<perm_string,PTask * > & tasks)5884 static void elaborate_tasks(Design*des, NetScope*scope,
5885 			    const map<perm_string,PTask*>&tasks)
5886 {
5887       typedef map<perm_string,PTask*>::const_iterator mtask_it_t;
5888       for (mtask_it_t cur = tasks.begin()
5889 		 ; cur != tasks.end() ; ++ cur ) {
5890 
5891 	    hname_t use_name ( (*cur).first );
5892 	    NetScope*tscope = scope->child(use_name);
5893 	    assert(tscope);
5894 	    (*cur).second->elaborate(des, tscope);
5895       }
5896 }
5897 
elaborate_classes(Design * des,NetScope * scope,const map<perm_string,PClass * > & classes)5898 static void elaborate_classes(Design*des, NetScope*scope,
5899 			      const map<perm_string,PClass*>&classes)
5900 {
5901       for (map<perm_string,PClass*>::const_iterator cur = classes.begin()
5902 		 ; cur != classes.end() ; ++ cur) {
5903 	    netclass_t*use_class = scope->find_class(cur->second->pscope_name());
5904 	    use_class->elaborate(des, cur->second);
5905 
5906 	    if (use_class->test_for_missing_initializers()) {
5907 		  cerr << cur->second->get_fileline() << ": error: "
5908 		       << "Const properties of class " << use_class->get_name()
5909 		       << " are missing initialization." << endl;
5910 		  des->errors += 1;
5911 	    }
5912       }
5913 }
5914 
elaborate(Design * des,NetScope * scope) const5915 bool PPackage::elaborate(Design*des, NetScope*scope) const
5916 {
5917       bool result_flag = true;
5918 
5919 	// Elaborate function methods, and...
5920       elaborate_functions(des, scope, funcs);
5921 
5922 	// Elaborate task methods.
5923       elaborate_tasks(des, scope, tasks);
5924 
5925 	// Elaborate class definitions.
5926       elaborate_classes(des, scope, classes);
5927 
5928 	// Elaborate the variable initialization statements, making a
5929 	// single initial process out of them.
5930       result_flag &= elaborate_var_inits_(des, scope);
5931 
5932       return result_flag;
5933 }
5934 
5935 /*
5936  * When a module is instantiated, it creates the scope then uses this
5937  * method to elaborate the contents of the module.
5938  */
5939 
elaborate(Design * des,NetScope * scope) const5940 bool Module::elaborate(Design*des, NetScope*scope) const
5941 {
5942       bool result_flag = true;
5943 
5944 	// Elaborate within the generate blocks.
5945       typedef list<PGenerate*>::const_iterator generate_it_t;
5946       for (generate_it_t cur = generate_schemes.begin()
5947 		 ; cur != generate_schemes.end() ; ++ cur ) {
5948 	    (*cur)->elaborate(des, scope);
5949       }
5950 
5951 	// Elaborate functions.
5952       elaborate_functions(des, scope, funcs);
5953 
5954 	// Elaborate the task definitions. This is done before the
5955 	// behaviors so that task calls may reference these, and after
5956 	// the signals so that the tasks can reference them.
5957       elaborate_tasks(des, scope, tasks);
5958 
5959 	// Elaborate class definitions.
5960       elaborate_classes(des, scope, classes);
5961 
5962 	// Get all the gates of the module and elaborate them by
5963 	// connecting them to the signals. The gate may be simple or
5964 	// complex.
5965       const list<PGate*>&gl = get_gates();
5966 
5967       for (list<PGate*>::const_iterator gt = gl.begin()
5968 		 ; gt != gl.end() ; ++ gt ) {
5969 
5970 	    (*gt)->elaborate(des, scope);
5971       }
5972 
5973 	// Elaborate the variable initialization statements, making a
5974 	// single initial process out of them.
5975       result_flag &= elaborate_var_inits_(des, scope);
5976 
5977 	// Elaborate the behaviors, making processes out of them. This
5978 	// involves scanning the PProcess* list, creating a NetProcTop
5979 	// for each process.
5980       result_flag &= elaborate_behaviors_(des, scope);
5981 
5982 	// Elaborate the specify paths of the module.
5983 
5984       for (list<PSpecPath*>::const_iterator sp = specify_paths.begin()
5985 		 ; sp != specify_paths.end() ; ++ sp ) {
5986 
5987 	    (*sp)->elaborate(des, scope);
5988       }
5989 
5990       return result_flag;
5991 }
5992 
5993 /*
5994  * Elaborating a netclass_t means elaborating the PFunction and PTask
5995  * objects that it contains. The scopes and signals have already been
5996  * elaborated in the class of the netclass_t scope, so we can get the
5997  * child scope for each definition and use that for the context of the
5998  * function.
5999  */
elaborate(Design * des,PClass * pclass)6000 void netclass_t::elaborate(Design*des, PClass*pclass)
6001 {
6002       if (! pclass->type->initialize_static.empty()) {
6003 	    std::vector<Statement*>&stmt_list = pclass->type->initialize_static;
6004 	    NetBlock*stmt = new NetBlock(NetBlock::SEQU, 0);
6005 	    for (size_t idx = 0 ; idx < stmt_list.size() ; idx += 1) {
6006 		  NetProc*tmp = stmt_list[idx]->elaborate(des, class_scope_);
6007 		  if (tmp == 0) continue;
6008 		  stmt->append(tmp);
6009 	    }
6010 	    NetProcTop*top = new NetProcTop(class_scope_, IVL_PR_INITIAL, stmt);
6011 	    top->set_line(*pclass);
6012 	    des->add_process(top);
6013       }
6014 
6015       for (map<perm_string,PFunction*>::iterator cur = pclass->funcs.begin()
6016 		 ; cur != pclass->funcs.end() ; ++ cur) {
6017 	    if (debug_elaborate) {
6018 		  cerr << cur->second->get_fileline() << ": netclass_t::elaborate: "
6019 		       << "Elaborate class " << scope_path(class_scope_)
6020 		       << " function method " << cur->first << endl;
6021 	    }
6022 
6023 	    NetScope*scope = class_scope_->child( hname_t(cur->first) );
6024 	    ivl_assert(*cur->second, scope);
6025 	    cur->second->elaborate(des, scope);
6026       }
6027 
6028       for (map<perm_string,PTask*>::iterator cur = pclass->tasks.begin()
6029 		 ; cur != pclass->tasks.end() ; ++ cur) {
6030 	    if (debug_elaborate) {
6031 		  cerr << cur->second->get_fileline() << ": netclass_t::elaborate: "
6032 		       << "Elaborate class " << scope_path(class_scope_)
6033 		       << " task method " << cur->first << endl;
6034 	    }
6035 
6036 	    NetScope*scope = class_scope_->child( hname_t(cur->first) );
6037 	    ivl_assert(*cur->second, scope);
6038 	    cur->second->elaborate(des, scope);
6039       }
6040 }
6041 
elaborate(Design * des,NetScope * container) const6042 bool PGenerate::elaborate(Design*des, NetScope*container) const
6043 {
6044       if (direct_nested_)
6045 	    return elaborate_direct_(des, container);
6046 
6047       bool flag = true;
6048 
6049       if (debug_elaborate) {
6050 	    cerr << get_fileline() << ": PGenerate::elaborate: "
6051 		  "generate " << scheme_type
6052 		 << " elaborating in scope " << scope_path(container)
6053 		 << "." << endl;
6054 	    cerr << get_fileline() << ": PGenerate::elaborate: "
6055 		  "generate scope_name=" << scope_name
6056 		 << ", id_number=" << id_number << endl;
6057       }
6058 
6059 	// Handle the special case that this is a CASE scheme. In this
6060 	// case the PGenerate itself does not have the generated
6061 	// item. Look instead for the case ITEM that has a scope
6062 	// generated for it.
6063       if (scheme_type == PGenerate::GS_CASE) {
6064 
6065 	    typedef list<PGenerate*>::const_iterator generate_it_t;
6066 	    for (generate_it_t cur = generate_schemes.begin()
6067 		       ; cur != generate_schemes.end() ; ++ cur ) {
6068 		  PGenerate*item = *cur;
6069 		  if (item->direct_nested_ || !item->scope_list_.empty()) {
6070 			flag &= item->elaborate(des, container);
6071 		  }
6072 	    }
6073 	    return flag;
6074       }
6075 
6076       typedef list<NetScope*>::const_iterator scope_list_it_t;
6077       for (scope_list_it_t cur = scope_list_.begin()
6078 		 ; cur != scope_list_.end() ; ++ cur ) {
6079 
6080 	    NetScope*scope = *cur;
6081 	      // Check that this scope is one that is contained in the
6082 	      // container that the caller passed in.
6083 	    if (scope->parent() != container)
6084 		  continue;
6085 
6086 	      // If this was an unnamed generate block, replace its
6087 	      // temporary name with a name generated using the naming
6088 	      // scheme defined in the Verilog-2005 standard.
6089 	    const char*name = scope_name.str();
6090 	    if (name[0] == '$') {
6091 
6092 		  if (!scope->auto_name("genblk", '0', name + 4)) {
6093 			cerr << get_fileline() << ": warning: Couldn't build"
6094 			     << " unique name for unnamed generate block"
6095 			     << " - using internal name " << name << endl;
6096 		  }
6097 	    }
6098 	    if (debug_elaborate)
6099 		  cerr << get_fileline() << ": debug: Elaborate in "
6100 		       << "scope " << scope_path(scope) << endl;
6101 
6102 	    flag = elaborate_(des, scope) & flag;
6103       }
6104 
6105       return flag;
6106 }
6107 
elaborate_direct_(Design * des,NetScope * container) const6108 bool PGenerate::elaborate_direct_(Design*des, NetScope*container) const
6109 {
6110       bool flag = true;
6111 
6112       if (debug_elaborate) {
6113 	    cerr << get_fileline() << ": debug: "
6114 		 << "Direct nesting elaborate in scope "
6115 		 << scope_path(container)
6116 		 << ", scheme_type=" << scheme_type << endl;
6117       }
6118 
6119 	// Elaborate for a direct nested generated scheme knows
6120 	// that there are only sub_schemes to be elaborated.  There
6121 	// should be exactly 1 active generate scheme, search for it
6122 	// using this loop.
6123       typedef list<PGenerate*>::const_iterator generate_it_t;
6124       for (generate_it_t cur = generate_schemes.begin()
6125 		 ; cur != generate_schemes.end() ; ++ cur ) {
6126 	    PGenerate*item = *cur;
6127 	    if (debug_elaborate) {
6128 		  cerr << get_fileline() << ": PGenerate::elaborate_direct_: "
6129 		       << "item->scope_name=" << item->scope_name
6130 		       << ", item->scheme_type=" << item->scheme_type
6131 		       << ", item->direct_nested_=" << item->direct_nested_
6132 		       << ", item->scope_list_.size()=" << item->scope_list_.size()
6133 		       << "." << endl;
6134 	    }
6135 
6136 	      // Special case: If this is a case generate scheme, then
6137 	      // the PGenerate object (item) does not actually
6138 	      // contain anything. Instead scan the case items, which
6139 	      // are listed as sub-schemes of the item.
6140 	    if (item->scheme_type == PGenerate::GS_CASE) {
6141 		  for (generate_it_t icur = item->generate_schemes.begin()
6142 			     ; icur != item->generate_schemes.end() ; ++ icur ) {
6143 			PGenerate*case_item = *icur;
6144 			if (case_item->direct_nested_ || !case_item->scope_list_.empty()) {
6145 			      flag &= case_item->elaborate(des, container);
6146 			}
6147 		  }
6148 	    } else {
6149 		  if (item->direct_nested_ || !item->scope_list_.empty()) {
6150 			  // Found the item, and it is direct nested.
6151 			flag &= item->elaborate(des, container);
6152 		  }
6153 	    }
6154       }
6155       return flag;
6156 }
6157 
elaborate_(Design * des,NetScope * scope) const6158 bool PGenerate::elaborate_(Design*des, NetScope*scope) const
6159 {
6160       elaborate_functions(des, scope, funcs);
6161       elaborate_tasks(des, scope, tasks);
6162 
6163       typedef list<PGate*>::const_iterator gates_it_t;
6164       for (gates_it_t cur = gates.begin() ; cur != gates.end() ; ++ cur )
6165 	    (*cur)->elaborate(des, scope);
6166 
6167       elaborate_var_inits_(des, scope);
6168 
6169       typedef list<PProcess*>::const_iterator proc_it_t;
6170       for (proc_it_t cur = behaviors.begin(); cur != behaviors.end(); ++ cur )
6171 	    (*cur)->elaborate(des, scope);
6172 
6173       typedef list<PGenerate*>::const_iterator generate_it_t;
6174       for (generate_it_t cur = generate_schemes.begin()
6175 		 ; cur != generate_schemes.end() ; ++ cur ) {
6176 	    (*cur)->elaborate(des, scope);
6177       }
6178 
6179       return true;
6180 }
6181 
elaborate_behaviors_(Design * des,NetScope * scope) const6182 bool PScope::elaborate_behaviors_(Design*des, NetScope*scope) const
6183 {
6184       bool result_flag = true;
6185 
6186 	// Elaborate the behaviors, making processes out of them. This
6187 	// involves scanning the PProcess* list, creating a NetProcTop
6188 	// for each process.
6189       for (list<PProcess*>::const_iterator st = behaviors.begin()
6190 		 ; st != behaviors.end() ; ++ st ) {
6191 
6192 	    result_flag &= (*st)->elaborate(des, scope);
6193       }
6194 
6195       for (list<AProcess*>::const_iterator st = analog_behaviors.begin()
6196 		 ; st != analog_behaviors.end() ; ++ st ) {
6197 
6198 	    result_flag &= (*st)->elaborate(des, scope);
6199       }
6200 
6201       return result_flag;
6202 }
6203 
elaborate_var_inits_(Design * des,NetScope * scope) const6204 bool LexicalScope::elaborate_var_inits_(Design*des, NetScope*scope) const
6205 {
6206       if (var_inits.size() == 0)
6207 	    return true;
6208 
6209       NetProc*proc = 0;
6210       if (var_inits.size() == 1) {
6211 	    proc = var_inits[0]->elaborate(des, scope);
6212       } else {
6213 	    NetBlock*blk = new NetBlock(NetBlock::SEQU, 0);
6214 	    bool flag = true;
6215 	    for (unsigned idx = 0; idx < var_inits.size(); idx += 1) {
6216 		  NetProc*tmp = var_inits[idx]->elaborate(des, scope);
6217 		  if (tmp)
6218 			blk->append(tmp);
6219 		  else
6220 			flag = false;
6221 	    }
6222 	    if (flag) proc = blk;
6223       }
6224       if (proc == 0)
6225 	    return false;
6226 
6227       NetProcTop*top = new NetProcTop(scope, IVL_PR_INITIAL, proc);
6228       if (const LineInfo*li = dynamic_cast<const LineInfo*>(this)) {
6229 	    top->set_line(*li);
6230       }
6231       if (gn_system_verilog()) {
6232 	    top->attribute(perm_string::literal("_ivl_schedule_init"),
6233 			   verinum(1));
6234       }
6235       des->add_process(top);
6236 
6237       scope->set_var_init(proc);
6238 
6239       return true;
6240 }
6241 
6242 class elaborate_package_t : public elaborator_work_item_t {
6243     public:
elaborate_package_t(Design * d,NetScope * scope,PPackage * p)6244       elaborate_package_t(Design*d, NetScope*scope, PPackage*p)
6245       : elaborator_work_item_t(d), scope_(scope), package_(p)
6246       { }
6247 
~elaborate_package_t()6248       ~elaborate_package_t() { }
6249 
elaborate_runrun()6250       virtual void elaborate_runrun()
6251       {
6252 	    if (! package_->elaborate_scope(des, scope_))
6253 		  des->errors += 1;
6254       }
6255 
6256     private:
6257       NetScope*scope_;
6258       PPackage*package_;
6259 };
6260 
6261 class elaborate_root_scope_t : public elaborator_work_item_t {
6262     public:
elaborate_root_scope_t(Design * des__,NetScope * scope,Module * rmod)6263       elaborate_root_scope_t(Design*des__, NetScope*scope, Module*rmod)
6264       : elaborator_work_item_t(des__), scope_(scope), rmod_(rmod)
6265       { }
6266 
~elaborate_root_scope_t()6267       ~elaborate_root_scope_t() { }
6268 
elaborate_runrun()6269       virtual void elaborate_runrun()
6270       {
6271 	    Module::replace_t root_repl;
6272 	    for (list<Module::named_expr_t>::iterator cur = Module::user_defparms.begin()
6273 		       ; cur != Module::user_defparms.end() ; ++ cur ) {
6274 
6275 		  pform_name_t tmp_name = cur->first;
6276 		  if (peek_head_name(tmp_name) != scope_->basename())
6277 			continue;
6278 
6279 		  tmp_name.pop_front();
6280 		  if (tmp_name.size() != 1)
6281 			continue;
6282 
6283 		  root_repl[peek_head_name(tmp_name)] = cur->second;
6284 	    }
6285 
6286 	    if (! rmod_->elaborate_scope(des, scope_, root_repl))
6287 		  des->errors += 1;
6288       }
6289 
6290     private:
6291       NetScope*scope_;
6292       Module*rmod_;
6293 };
6294 
6295 class top_defparams : public elaborator_work_item_t {
6296     public:
top_defparams(Design * des__)6297       explicit top_defparams(Design*des__)
6298       : elaborator_work_item_t(des__)
6299       { }
6300 
~top_defparams()6301       ~top_defparams() { }
6302 
elaborate_runrun()6303       virtual void elaborate_runrun()
6304       {
6305 	    if (debug_scopes) {
6306 		  cerr << "debug: top_defparams::elaborate_runrun()" << endl;
6307 	    }
6308 	      // This method recurses through the scopes, looking for
6309 	      // defparam assignments to apply to the parameters in the
6310 	      // various scopes. This needs to be done after all the scopes
6311 	      // and basic parameters are taken care of because the defparam
6312 	      // can assign to a parameter declared *after* it.
6313 	    des->run_defparams();
6314 
6315 	      // At this point, all parameter overrides are done. Scan the
6316 	      // scopes and evaluate the parameters all the way down to
6317 	      // constants.
6318 	    des->evaluate_parameters();
6319 
6320 	    if (debug_scopes) {
6321 		  cerr << "debug: top_defparams::elaborate_runrun() done" << endl;
6322 	    }
6323       }
6324 };
6325 
6326 class later_defparams : public elaborator_work_item_t {
6327     public:
later_defparams(Design * des__)6328       explicit later_defparams(Design*des__)
6329       : elaborator_work_item_t(des__)
6330       { }
6331 
~later_defparams()6332       ~later_defparams() { }
6333 
elaborate_runrun()6334       virtual void elaborate_runrun()
6335       {
6336 	    if (debug_scopes) {
6337 		  cerr << "debug: later_defparams::elaborate_runrun()" << endl;
6338 	    }
6339 
6340 	    list<NetScope*>tmp_list;
6341 	    for (set<NetScope*>::iterator cur = des->defparams_later.begin()
6342 		       ; cur != des->defparams_later.end() ; ++ cur )
6343 		  tmp_list.push_back(*cur);
6344 
6345 	    des->defparams_later.clear();
6346 
6347 	    while (! tmp_list.empty()) {
6348 		  NetScope*cur = tmp_list.front();
6349 		  tmp_list.pop_front();
6350 		  cur->run_defparams_later(des);
6351 	    }
6352 
6353 	      // The overridden parameters will be evaluated later in
6354 	      // a top_defparams work item.
6355 
6356 	    if (debug_scopes) {
6357 		  cerr << "debuf: later_defparams::elaborate_runrun() done" << endl;
6358 	    }
6359       }
6360 };
6361 
operator <<(ostream & o,ivl_process_type_t t)6362 static ostream& operator<< (ostream&o, ivl_process_type_t t)
6363 {
6364       switch (t) {
6365 	case IVL_PR_ALWAYS:
6366 	    o << "always";
6367 	    break;
6368 	case IVL_PR_ALWAYS_COMB:
6369 	    o << "always_comb";
6370 	    break;
6371 	case IVL_PR_ALWAYS_FF:
6372 	    o << "always_ff";
6373 	    break;
6374 	case IVL_PR_ALWAYS_LATCH:
6375 	    o << "always_latch";
6376 	    break;
6377 	case IVL_PR_INITIAL:
6378 	    o << "initial";
6379 	    break;
6380 	case IVL_PR_FINAL:
6381 	    o << "final";
6382 	    break;
6383       }
6384       return o;
6385 }
6386 
check_proc_delay() const6387 bool Design::check_proc_delay() const
6388 {
6389       bool result = false;
6390 
6391       for (const NetProcTop*pr = procs_ ;  pr ;  pr = pr->next_) {
6392 	      /* If this is an always process and we have no or zero delay then
6393 	       * a runtime infinite loop will happen. If we possibly have some
6394 	       * delay then print a warning that an infinite loop is possible.
6395 	       */
6396 	    if (pr->type() == IVL_PR_ALWAYS) {
6397 		  DelayType dly_type = pr->statement()->delay_type();
6398 
6399 		  if (dly_type == NO_DELAY || dly_type == ZERO_DELAY) {
6400 			cerr << pr->get_fileline() << ": error: always "
6401 			        "process does not have any delay." << endl;
6402 			cerr << pr->get_fileline() << ":      : A runtime "
6403 			        "infinite loop will occur." << endl;
6404 			result = true;
6405 
6406 		  } else if (dly_type == POSSIBLE_DELAY && warn_inf_loop) {
6407 			cerr << pr->get_fileline() << ": warning: always "
6408 			        "process may not have any delay." << endl;
6409 			cerr << pr->get_fileline() << ":        : A runtime "
6410 			     << "infinite loop may be possible." << endl;
6411 		  }
6412 	    }
6413 
6414 	      // The always_comb/ff/latch processes have special delay rules
6415 	      // that need to be checked.
6416 	    if ((pr->type() == IVL_PR_ALWAYS_COMB) ||
6417 	        (pr->type() == IVL_PR_ALWAYS_FF) ||
6418 	        (pr->type() == IVL_PR_ALWAYS_LATCH)) {
6419 		  const NetEvWait *wait = dynamic_cast<const NetEvWait*> (pr->statement());
6420 		  if (! wait) {
6421 			  // The always_comb/latch processes have an event
6422 			  // control added automatically by the compiler.
6423 			assert(pr->type() == IVL_PR_ALWAYS_FF);
6424 			cerr << pr->get_fileline() << ": error: the first "
6425 			        "statement of an always_ff process must be "
6426 			        "an event control statement." << endl;
6427 			result = true;
6428 		  } else if (wait->statement()->delay_type(true) != NO_DELAY) {
6429 			cerr << pr->get_fileline() << ": error: there must ";
6430 
6431 			if (pr->type() == IVL_PR_ALWAYS_FF) {
6432 			      cerr << "only be a single event control and "
6433 			              "no blocking delays in an always_ff "
6434 			              "process.";
6435 			} else {
6436 			      cerr << "be no event controls or blocking "
6437 			              "delays in an " << pr->type()
6438 			           << " process.";
6439 			}
6440 			cerr << endl;
6441 			result = true;
6442 		  }
6443 
6444 		  if ((pr->type() != IVL_PR_ALWAYS_FF) &&
6445 		      (wait->nevents() == 0)) {
6446 			if (pr->type() == IVL_PR_ALWAYS_LATCH) {
6447 			      cerr << pr->get_fileline() << ": error: "
6448 			              "always_latch process has no event "
6449 			              "control." << endl;
6450 			      result = true;
6451 			} else {
6452 			      assert(pr->type() == IVL_PR_ALWAYS_COMB);
6453 			      cerr << pr->get_fileline() << ": warning: "
6454 			              "always_comb process has no "
6455 			              "sensitivities." << endl;
6456 			}
6457 		  }
6458 	    }
6459 
6460 	        /* If this is a final block it must not have a delay,
6461 		   but this should have been caught by the statement
6462 		   elaboration, so maybe this should be an internal
6463 		   error? */
6464 	    if (pr->type() == IVL_PR_FINAL) {
6465 		  DelayType dly_type = pr->statement()->delay_type();
6466 
6467 		  if (dly_type != NO_DELAY) {
6468 			cerr << pr->get_fileline() << ": error: final"
6469 			     << " statement contains a delay." << endl;
6470 			result = true;
6471 		  }
6472 	    }
6473       }
6474 
6475       return result;
6476 }
6477 
print_nexus_name(const Nexus * nex)6478 static void print_nexus_name(const Nexus*nex)
6479 {
6480       for (const Link*cur = nex->first_nlink(); cur; cur = cur->next_nlink()) {
6481 	    if (cur->get_dir() != Link::OUTPUT) continue;
6482 	    const NetPins*obj = cur->get_obj();
6483 	      // For a NetNet (signal) just use the name.
6484 	    if (const NetNet*net = dynamic_cast<const NetNet*>(obj)) {
6485 		  cerr << net->name();
6486 		  return;
6487 	      // For a NetPartSelect calculate the name.
6488 	    } else if (const NetPartSelect*ps = dynamic_cast<const NetPartSelect*>(obj)) {
6489 		  assert(ps->pin_count() >= 2);
6490 		  assert(ps->pin(1).get_dir() == Link::INPUT);
6491 		  assert(ps->pin(1).is_linked());
6492 		  print_nexus_name(ps->pin(1).nexus());
6493 		  cerr << "[]";
6494 		  return;
6495 	      // For a NetUReduce calculate the name.
6496 	    } else if (const NetUReduce*reduce = dynamic_cast<const NetUReduce*>(obj)) {
6497 		  assert(reduce->pin_count() == 2);
6498 		  assert(reduce->pin(1).get_dir() == Link::INPUT);
6499 		  assert(reduce->pin(1).is_linked());
6500 		  switch (reduce->type()) {
6501 		    case NetUReduce::AND:
6502 			cerr << "&";
6503 			break;
6504 		    case NetUReduce::OR:
6505 			cerr << "|";
6506 			break;
6507 		    case NetUReduce::XOR:
6508 			cerr << "^";
6509 			break;
6510 		    case NetUReduce::NAND:
6511 			cerr << "~&";
6512 			break;
6513 		    case NetUReduce::NOR:
6514 			cerr << "~|";
6515 			break;
6516 		    case NetUReduce::XNOR:
6517 			cerr << "~^";
6518 			break;
6519 		    case NetUReduce::NONE:
6520 			assert(0);
6521 		  }
6522 		  print_nexus_name(reduce->pin(1).nexus());
6523 		  return;
6524 	    } else if (const NetLogic*logic = dynamic_cast<const NetLogic*>(obj)) {
6525 		  assert(logic->pin_count() >= 2);
6526 		  assert(logic->pin(1).get_dir() == Link::INPUT);
6527 		  assert(logic->pin(1).is_linked());
6528 		  switch (logic->type()) {
6529 		    case NetLogic::NOT:
6530 			cerr << "~";
6531 			break;
6532 		    default:
6533 			  // The other operators should never be used here,
6534 			  // so just return the nexus name.
6535 			cerr << nex->name();
6536 			return;
6537 		  }
6538 		  print_nexus_name(logic->pin(1).nexus());
6539 		  return;
6540 	    }
6541 	// Use the following to find the type of anything that may be missing:
6542 	//    cerr << "(" << typeid(*obj).name() << ") ";
6543       }
6544 	// Otherwise just use the nexus name so somthing is printed.
6545       cerr << nex->name();
6546 }
6547 
print_event_probe_name(const NetEvProbe * prb)6548 static void print_event_probe_name(const NetEvProbe *prb)
6549 {
6550       assert(prb->pin_count() == 1);
6551       assert(prb->pin(0).get_dir() == Link::INPUT);
6552       assert(prb->pin(0).is_linked());
6553       print_nexus_name(prb->pin(0).nexus());
6554 }
6555 
check_event_probe_width(const LineInfo * info,const NetEvProbe * prb)6556 static void check_event_probe_width(const LineInfo *info, const NetEvProbe *prb)
6557 {
6558       assert(prb->pin_count() == 1);
6559       assert(prb->pin(0).get_dir() == Link::INPUT);
6560       assert(prb->pin(0).is_linked());
6561       if (prb->edge() == NetEvProbe::ANYEDGE) return;
6562       if (prb->pin(0).nexus()->vector_width() > 1) {
6563 	    cerr << info->get_fileline() << " Warning: Synthesis wants "
6564                     "the sensitivity list expressions for '";
6565 	    switch (prb->edge()) {
6566 	      case NetEvProbe::POSEDGE:
6567 		  cerr << "posedge ";
6568 		  break;
6569 	      case NetEvProbe::NEGEDGE:
6570 		  cerr << "negedge ";
6571 		  break;
6572 	      default:
6573 		  break;
6574 	    }
6575 	    print_nexus_name(prb->pin(0).nexus());
6576 	    cerr << "' to be a single bit." << endl;
6577       }
6578 }
6579 
check_ff_sensitivity(const NetProc * statement)6580 static void check_ff_sensitivity(const NetProc* statement)
6581 {
6582       const NetEvWait *evwt = dynamic_cast<const NetEvWait*> (statement);
6583 	// We have already checked for and reported if the first statmemnt is
6584 	// not a wait.
6585       if (! evwt) return;
6586 
6587       for (unsigned cevt = 0; cevt < evwt->nevents(); cevt += 1) {
6588 	    const NetEvent *evt = evwt->event(cevt);
6589 	    for (unsigned cprb = 0; cprb < evt->nprobe(); cprb += 1) {
6590 		  const NetEvProbe *prb = evt->probe(cprb);
6591 		  check_event_probe_width(evwt, prb);
6592 		  if (prb->edge() == NetEvProbe::ANYEDGE) {
6593 			cerr << evwt->get_fileline() << " Warning: Synthesis "
6594 			        "requires the sensitivity list of an "
6595 			        "always_ff process to only be edge "
6596 			        "sensitive. ";
6597 			print_event_probe_name(prb);
6598 			cerr  << " is missing a pos/negedge." << endl;
6599 		  }
6600 	    }
6601       }
6602 }
6603 
6604 /*
6605  * Check to see if the always_* processes only contain synthesizable
6606  * constructs.
6607  */
check_proc_synth() const6608 bool Design::check_proc_synth() const
6609 {
6610       bool result = false;
6611       for (const NetProcTop*pr = procs_ ;  pr ;  pr = pr->next_) {
6612 	    if ((pr->type() == IVL_PR_ALWAYS_COMB) ||
6613 	        (pr->type() == IVL_PR_ALWAYS_FF) ||
6614 	        (pr->type() == IVL_PR_ALWAYS_LATCH)) {
6615 		  result |= pr->statement()->check_synth(pr->type(),
6616 		                                         pr->scope());
6617 		  if (pr->type() == IVL_PR_ALWAYS_FF) {
6618 			check_ff_sensitivity(pr->statement());
6619 		  }
6620 	    }
6621       }
6622       return result;
6623 }
6624 
6625 /*
6626  * Check whether all design elements have an explicit timescale or all
6627  * design elements use the default timescale. If a mixture of explicit
6628  * and default timescales is found, a warning message is output. Note
6629  * that we only need to check the top level design elements - nested
6630  * design elements will always inherit the timescale from their parent
6631  * if they don't have any local timescale declarations.
6632  *
6633  * NOTE: Strictly speaking, this should be an error for SystemVerilog
6634  * (1800-2012 section 3.14.2).
6635  */
check_timescales(bool & some_explicit,bool & some_implicit,const PScope * scope)6636 static void check_timescales(bool&some_explicit, bool&some_implicit,
6637 			     const PScope*scope)
6638 {
6639       if (scope->time_unit_is_default)
6640 	    some_implicit = true;
6641       else
6642 	    some_explicit = true;
6643       if (scope->time_prec_is_default)
6644 	    some_implicit = true;
6645       else
6646 	    some_explicit = true;
6647 }
6648 
check_timescales()6649 static void check_timescales()
6650 {
6651       bool some_explicit = false;
6652       bool some_implicit = false;
6653       map<perm_string,Module*>::iterator mod;
6654       for (mod = pform_modules.begin(); mod != pform_modules.end(); ++mod) {
6655 	    const Module*mp = (*mod).second;
6656 	    check_timescales(some_explicit, some_implicit, mp);
6657 	    if (some_explicit && some_implicit)
6658 		  break;
6659       }
6660       map<perm_string,PPackage*>::iterator pkg;
6661       if (gn_system_verilog() && !(some_explicit && some_implicit)) {
6662 	    for (pkg = pform_packages.begin(); pkg != pform_packages.end(); ++pkg) {
6663 		  const PPackage*pp = (*pkg).second;
6664 		  check_timescales(some_explicit, some_implicit, pp);
6665 		  if (some_explicit && some_implicit)
6666 			break;
6667 	    }
6668       }
6669       if (gn_system_verilog() && !(some_explicit && some_implicit)) {
6670 	    for (unsigned idx = 0; idx < pform_units.size(); idx += 1) {
6671 		  const PPackage*pp = pform_units[idx];
6672 		    // We don't need a timescale if the compilation unit
6673 		    // contains no items outside a design element.
6674 		  if (pp->parameters.empty() &&
6675 		      pp->localparams.empty() &&
6676 		      pp->wires.empty() &&
6677 		      pp->tasks.empty() &&
6678 		      pp->funcs.empty() &&
6679 		      pp->classes.empty())
6680 			continue;
6681 
6682 		  check_timescales(some_explicit, some_implicit, pp);
6683 		  if (some_explicit && some_implicit)
6684 			break;
6685 	    }
6686       }
6687 
6688       if (!(some_explicit && some_implicit))
6689 	    return;
6690 
6691       if (gn_system_verilog()) {
6692 	    cerr << "warning: "
6693 		 << "Some design elements have no explicit time unit and/or"
6694 		 << endl;
6695 	    cerr << "       : "
6696 		 << "time precision. This may cause confusing timing results."
6697 		 << endl;
6698 	    cerr << "       : "
6699 		 << "Affected design elements are:"
6700 		 << endl;
6701       } else {
6702 	    cerr << "warning: "
6703 		 << "Some modules have no timescale. This may cause"
6704 		 << endl;
6705 	    cerr << "       : "
6706 		 << "confusing timing results.	Affected modules are:"
6707 		 << endl;
6708       }
6709 
6710       for (mod = pform_modules.begin(); mod != pform_modules.end(); ++mod) {
6711 	    Module*mp = (*mod).second;
6712 	    if (mp->has_explicit_timescale())
6713 		  continue;
6714 	    cerr << "       :   -- module " << (*mod).first
6715 		 << " declared here: " << mp->get_fileline() << endl;
6716       }
6717 
6718       if (!gn_system_verilog())
6719 	    return;
6720 
6721       for (pkg = pform_packages.begin(); pkg != pform_packages.end(); ++pkg) {
6722 	    PPackage*pp = (*pkg).second;
6723 	    if (pp->has_explicit_timescale())
6724 		  continue;
6725 	    cerr << "       :   -- package " << (*pkg).first
6726 		 << " declared here: " << pp->get_fileline() << endl;
6727       }
6728 
6729       for (unsigned idx = 0; idx < pform_units.size(); idx += 1) {
6730 	    PPackage*pp = pform_units[idx];
6731 	    if (pp->has_explicit_timescale())
6732 		  continue;
6733 
6734 	    if (pp->parameters.empty() &&
6735 		pp->localparams.empty() &&
6736 		pp->wires.empty() &&
6737 		pp->tasks.empty() &&
6738 		pp->funcs.empty() &&
6739 		pp->classes.empty())
6740 		  continue;
6741 
6742 	    cerr << "       :   -- compilation unit";
6743 	    if (pform_units.size() > 1) {
6744 		  cerr << " from: " << pp->get_file();
6745 	    }
6746 	    cerr << endl;
6747       }
6748 }
6749 
6750 /*
6751  * This function is the root of all elaboration. The input is the list
6752  * of root module names. The function locates the Module definitions
6753  * for each root, does the whole elaboration sequence, and fills in
6754  * the resulting Design.
6755  */
6756 
6757 struct pack_elem {
6758       PPackage*pack;
6759       NetScope*scope;
6760 };
6761 
6762 struct root_elem {
6763       Module *mod;
6764       NetScope *scope;
6765 };
6766 
elaborate(list<perm_string> roots)6767 Design* elaborate(list<perm_string>roots)
6768 {
6769       unsigned npackages = pform_packages.size();
6770       if (gn_system_verilog())
6771 	    npackages += pform_units.size();
6772 
6773       vector<struct root_elem> root_elems(roots.size());
6774       vector<struct pack_elem> pack_elems(npackages);
6775       map<LexicalScope*,NetScope*> unit_scopes;
6776       bool rc = true;
6777       unsigned i = 0;
6778 
6779 	// This is the output design. I fill it in as I scan the root
6780 	// module and elaborate what I find.
6781       Design*des = new Design;
6782 
6783 	// Elaborate the compilation unit scopes. From here on, these are
6784 	// treated as an additional set of packages.
6785       if (gn_system_verilog()) {
6786 	    for (i = 0; i < pform_units.size(); i += 1) {
6787 		  PPackage*unit = pform_units[i];
6788 		  NetScope*scope = des->make_package_scope(unit->pscope_name(), 0, true);
6789 		  scope->set_line(unit);
6790 		  scope->add_imports(&unit->explicit_imports);
6791 		  set_scope_timescale(des, scope, unit);
6792 
6793 		  elaborator_work_item_t*es = new elaborate_package_t(des, scope, unit);
6794 		  des->elaboration_work_list.push_back(es);
6795 
6796 		  pack_elems[i].pack = unit;
6797 		  pack_elems[i].scope = scope;
6798 
6799 		  unit_scopes[unit] = scope;
6800 	    }
6801       }
6802 
6803 	// Elaborate the packages. Package elaboration is simpler
6804 	// because there are fewer sub-scopes involved. Note that
6805 	// in SystemVerilog, packages are not allowed to refer to
6806 	// the compilation unit scope, but the VHDL preprocessor
6807 	// assumes they can.
6808       for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
6809 		 ; pac != pform_packages.end() ; ++ pac) {
6810 
6811 	    ivl_assert(*pac->second, pac->first == pac->second->pscope_name());
6812 	    NetScope*unit_scope = unit_scopes[pac->second->parent_scope()];
6813 	    NetScope*scope = des->make_package_scope(pac->first, unit_scope, false);
6814 	    scope->set_line(pac->second);
6815 	    scope->add_imports(&pac->second->explicit_imports);
6816 	    set_scope_timescale(des, scope, pac->second);
6817 
6818 	    elaborator_work_item_t*es = new elaborate_package_t(des, scope, pac->second);
6819 	    des->elaboration_work_list.push_back(es);
6820 
6821 	    pack_elems[i].pack = pac->second;
6822 	    pack_elems[i].scope = scope;
6823 	    i += 1;
6824       }
6825 
6826 	// Scan the root modules by name, and elaborate their scopes.
6827       i = 0;
6828       for (list<perm_string>::const_iterator root = roots.begin()
6829 		 ; root != roots.end() ; ++ root ) {
6830 
6831 	      // Look for the root module in the list.
6832 	    map<perm_string,Module*>::const_iterator mod = pform_modules.find(*root);
6833 	    if (mod == pform_modules.end()) {
6834 		  cerr << "error: Unable to find the root module \""
6835 		       << (*root) << "\" in the Verilog source." << endl;
6836 		  cerr << "     : Perhaps ``-s " << (*root)
6837 		       << "'' is incorrect?" << endl;
6838 		  des->errors++;
6839 		  continue;
6840 	    }
6841 
6842 	      // Get the module definition for this root instance.
6843 	    Module *rmod = (*mod).second;
6844 
6845 	      // Get the compilation unit scope for this module.
6846 	    NetScope*unit_scope = unit_scopes[rmod->parent_scope()];
6847 
6848 	      // Make the root scope. This makes a NetScope object and
6849 	      // pushes it into the list of root scopes in the Design.
6850 	    NetScope*scope = des->make_root_scope(*root, unit_scope,
6851 						  rmod->program_block,
6852 						  rmod->is_interface);
6853 
6854 	      // Collect some basic properties of this scope from the
6855 	      // Module definition.
6856 	    scope->set_line(rmod);
6857 	    scope->add_imports(&rmod->explicit_imports);
6858 	    set_scope_timescale(des, scope, rmod);
6859 
6860 	      // Save this scope, along with its definition, in the
6861 	      // "root_elems" list for later passes.
6862 	    root_elems[i].mod = rmod;
6863 	    root_elems[i].scope = scope;
6864 	    i += 1;
6865 
6866 	      // Arrange for these scopes to be elaborated as root
6867 	      // scopes. Create an "elaborate_root_scope" object to
6868 	      // contain the work item, and append it to the scope
6869 	      // elaborations work list.
6870 	    elaborator_work_item_t*es = new elaborate_root_scope_t(des, scope, rmod);
6871 	    des->elaboration_work_list.push_back(es);
6872       }
6873 
6874 	// Run the work list of scope elaborations until the list is
6875 	// empty. This list is initially populated above where the
6876 	// initial root scopes are primed.
6877       while (! des->elaboration_work_list.empty()) {
6878 	      // Push a work item to process the defparams of any scopes
6879 	      // that are elaborated during this pass. For the first pass
6880 	      // this will be all the root scopes. For subsequent passes
6881 	      // it will be any scopes created during the previous pass
6882 	      // by a generate construct or instance array.
6883 	    des->elaboration_work_list.push_back(new top_defparams(des));
6884 
6885 	      // Transfer the queue to a temporary queue.
6886 	    list<elaborator_work_item_t*> cur_queue;
6887 	    while (! des->elaboration_work_list.empty()) {
6888 		  cur_queue.push_back(des->elaboration_work_list.front());
6889 		  des->elaboration_work_list.pop_front();
6890 	    }
6891 
6892 	      // Run from the temporary queue. If the temporary queue
6893 	      // items create new work queue items, they will show up
6894 	      // in the elaboration_work_list and then we get to run
6895 	      // through them in the next pass.
6896 	    while (! cur_queue.empty()) {
6897 		  elaborator_work_item_t*tmp = cur_queue.front();
6898 		  cur_queue.pop_front();
6899 		  tmp->elaborate_runrun();
6900 		  delete tmp;
6901 	    }
6902 
6903 	    if (! des->elaboration_work_list.empty()) {
6904 		  des->elaboration_work_list.push_back(new later_defparams(des));
6905 	    }
6906       }
6907 
6908       if (debug_elaborate) {
6909 	    cerr << "<toplevel>: elaborate: "
6910 		 << "elaboration work list done. Start processing residual defparams." << endl;
6911       }
6912 
6913 	// Look for residual defparams (that point to a non-existent
6914 	// scope) and clean them out.
6915       des->residual_defparams();
6916 
6917 	// Errors already? Probably missing root modules. Just give up
6918 	// now and return nothing.
6919       if (des->errors > 0)
6920 	    return des;
6921 
6922 	// Now we have the full design, check for timescale inconsistencies.
6923       if (warn_timescale)
6924 	    check_timescales();
6925 
6926       if (debug_elaborate) {
6927 	    cerr << "<toplevel>: elaborate: "
6928 		 << "Start calling Package elaborate_sig methods." << endl;
6929       }
6930 
6931 	// With the parameters evaluated down to constants, we have
6932 	// what we need to elaborate signals and memories. This pass
6933 	// creates all the NetNet and NetMemory objects for declared
6934 	// objects.
6935       for (i = 0; i < pack_elems.size(); i += 1) {
6936 	    PPackage*pack = pack_elems[i].pack;
6937 	    NetScope*scope= pack_elems[i].scope;
6938 
6939 	    if (! pack->elaborate_sig(des, scope)) {
6940 		  if (debug_elaborate) {
6941 			cerr << "<toplevel>" << ": debug: " << pack->pscope_name()
6942 			     << ": elaborate_sig failed!!!" << endl;
6943 		  }
6944 		  delete des;
6945 		  return 0;
6946 	    }
6947       }
6948 
6949       if (debug_elaborate) {
6950 	    cerr << "<toplevel>: elaborate: "
6951 		 << "Start calling $root elaborate_sig methods." << endl;
6952       }
6953 
6954       if (debug_elaborate) {
6955 	    cerr << "<toplevel>: elaborate: "
6956 		 << "Start calling root module elaborate_sig methods." << endl;
6957       }
6958 
6959       for (i = 0; i < root_elems.size(); i++) {
6960 	    Module *rmod = root_elems[i].mod;
6961 	    NetScope *scope = root_elems[i].scope;
6962 	    scope->set_num_ports( rmod->port_count() );
6963 
6964 	    if (debug_elaborate) {
6965 		  cerr << "<toplevel>" << ": debug: " << rmod->mod_name()
6966 		       << ": port elaboration root "
6967 		       << rmod->port_count() << " ports" << endl;
6968 	    }
6969 
6970 	    if (! rmod->elaborate_sig(des, scope)) {
6971 		  if (debug_elaborate) {
6972 			cerr << "<toplevel>" << ": debug: " << rmod->mod_name()
6973 			     << ": elaborate_sig failed!!!" << endl;
6974 		  }
6975 		  delete des;
6976 		  return 0;
6977 	    }
6978 
6979 	      // Some of the generators need to have the ports correctly
6980 	      // defined for the root modules. This code does that.
6981 	    for (unsigned idx = 0; idx < rmod->port_count(); idx += 1) {
6982 		  vector<PEIdent*> mport = rmod->get_port(idx);
6983                   unsigned int prt_vector_width = 0;
6984                   PortType::Enum ptype = PortType::PIMPLICIT;
6985 		  for (unsigned pin = 0; pin < mport.size(); pin += 1) {
6986 			  // This really does more than we need and adds extra
6987 			  // stuff to the design that should be cleaned later.
6988 			NetNet *netnet = mport[pin]->elaborate_subport(des, scope);
6989 			if (netnet != 0) {
6990 			  // Elaboration may actually fail with
6991 			  // erroneous input source
6992                           prt_vector_width += netnet->vector_width() * netnet->pin_count();
6993                           ptype = PortType::merged(netnet->port_type(), ptype);
6994 			}
6995 		  }
6996                   if (debug_elaborate) {
6997                            cerr << "<toplevel>" << ": debug: " << rmod->mod_name()
6998                                 << ": adding module port "
6999                                 << rmod->get_port_name(idx) << endl;
7000                      }
7001 		  scope->add_module_port_info(idx, rmod->get_port_name(idx), ptype, prt_vector_width );
7002 	    }
7003       }
7004 
7005 	// Now that the structure and parameters are taken care of,
7006 	// run through the pform again and generate the full netlist.
7007 
7008       for (i = 0; i < pack_elems.size(); i += 1) {
7009 	    PPackage*pkg = pack_elems[i].pack;
7010 	    NetScope*scope = pack_elems[i].scope;
7011 	    rc &= pkg->elaborate(des, scope);
7012       }
7013 
7014       for (i = 0; i < root_elems.size(); i++) {
7015 	    Module *rmod = root_elems[i].mod;
7016 	    NetScope *scope = root_elems[i].scope;
7017 	    rc &= rmod->elaborate(des, scope);
7018       }
7019 
7020       if (rc == false) {
7021 	    delete des;
7022 	    return 0;
7023       }
7024 
7025 	// Now that everything is fully elaborated verify that we do
7026 	// not have an always block with no delay (an infinite loop),
7027         // or a final block with a delay.
7028       bool has_failure = des->check_proc_delay();
7029 
7030 	// Check to see if the always_comb/ff/latch processes only have
7031 	// synthesizable constructs
7032       has_failure |= des->check_proc_synth();
7033 
7034       if (debug_elaborate) {
7035                cerr << "<toplevel>" << ": debug: "
7036                     << " finishing with "
7037                     <<  des->find_root_scopes().size() << " root scopes " << endl;
7038          }
7039 
7040       if (has_failure) {
7041 	    delete des;
7042 	    des = 0;
7043       }
7044 
7045       return des;
7046 }
7047