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