2 * Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
23 * Elaboration takes as input a complete parse tree and the name of a
24 * root module, and generates as output the elaborated design. This
25 * elaborated design is presented as a Module, which does not
26 * reference any other modules. It is entirely self contained.
35 # include "PGenerate.h"
40 # include "parse_api.h"
41 # include "compiler.h"
42 # include "ivl_assert.h"
45 static Link::strength_t
drive_type(PGate::strength_t drv
)
65 void PGate::elaborate(Design
*des
, NetScope
*scope
) const
67 cerr
<< "internal error: what kind of gate? " <<
68 typeid(*this).name() << endl
;
72 * Elaborate the continuous assign. (This is *not* the procedural
73 * assign.) Elaborate the lvalue and rvalue, and do the assignment.
75 void PGAssign::elaborate(Design
*des
, NetScope
*scope
) const
79 NetExpr
* rise_time
, *fall_time
, *decay_time
;
80 eval_delays(des
, scope
, rise_time
, fall_time
, decay_time
, true);
82 Link::strength_t drive0
= drive_type(strength0());
83 Link::strength_t drive1
= drive_type(strength1());
88 /* Elaborate the l-value. */
89 NetNet
*lval
= pin(0)->elaborate_lnet(des
, scope
);
94 assert(lval
->pin_count() == 1);
96 if (debug_elaborate
) {
97 cerr
<< get_fileline() << ": debug: PGassign: elaborated l-value"
98 << " width=" << lval
->vector_width()
99 << ", type=" << lval
->data_type() << endl
;
102 /* Handle the special case that the rval is simply an
103 identifier. Get the rval as a NetNet, then use NetBUFZ
104 objects to connect it to the l-value. This is necessary to
105 direct drivers. This is how I attach strengths to the
106 assignment operation. */
107 if (const PEIdent
*id
= dynamic_cast<const PEIdent
*>(pin(1))) {
108 NetNet
*rid
= id
->elaborate_net(des
, scope
, lval
->vector_width(),
109 0, 0, 0, Link::STRONG
,
116 /* If either lval or rid are real then both must be real. */
117 if ((lval
->data_type() == IVL_VT_REAL
||
118 rid
->data_type() == IVL_VT_REAL
) &&
119 lval
->data_type() != rid
->data_type()) {
120 cerr
<< get_fileline() << ": sorry: Both the r-value and "
121 "the l-value must be real in this context." << endl
;
126 ivl_assert(*this, rid
);
127 if (rid
->pin_count() != 1) {
128 cerr
<< get_fileline() << ": internal error: "
129 << "Invalid elaborate_net results here:" << endl
;
130 rid
->dump_net(cerr
, 4);
134 ivl_assert(*this, rid
->pin_count() == 1);
136 /* If the right hand net is the same type as the left
137 side net (i.e., WIRE/WIRE) then it is enough to just
138 connect them together. Otherwise, put a bufz between
139 them to carry strengths from the rval.
141 While we are at it, handle the case where the r-value
142 is not as wide as the l-value by padding with a
145 unsigned cnt
= lval
->vector_width();
146 if (rid
->vector_width() < cnt
)
147 cnt
= rid
->vector_width();
149 bool need_driver_flag
= false;
151 /* If the device is linked to itself, a driver is
152 needed. Should I print a warning here? */
153 if (lval
->pin(0) .is_linked (rid
->pin(0)))
154 need_driver_flag
= true;
156 /* If the nets are different type (i.e., reg vs. tri) then
157 a driver is needed. */
158 if (rid
->type() != lval
->type())
159 need_driver_flag
= true;
161 /* If there is a delay, then I need a driver to carry
163 if (rise_time
|| fall_time
|| decay_time
)
164 need_driver_flag
= true;
166 /* If there is a strength to be carried, then I need a
167 driver to carry that strength. */
168 if (rid
->pin(0).drive0() != drive0
)
169 need_driver_flag
= true;
171 if (rid
->pin(0).drive1() != drive1
)
172 need_driver_flag
= true;
174 /* If the r-value is more narrow then the l-value, pad
175 it to the desired width. */
176 if (cnt
< lval
->vector_width()) {
177 if (lval
->get_signed() && rid
->get_signed()) {
179 unsigned use_width
= lval
->vector_width();
182 cerr
<< get_fileline() << ": debug: PGassign "
183 << "Generate sign-extend node." << endl
;
185 rid
= pad_to_width_signed(des
, rid
, use_width
);
190 cerr
<< get_fileline() << ": debug: PGAssign "
191 << "Unsigned pad r-value from "
192 << cnt
<< " bits to "
193 << lval
->vector_width() << " bits." << endl
;
195 NetNet
*tmp
= pad_to_width(des
, rid
,
196 lval
->vector_width());
200 } else if (cnt
< rid
->vector_width()) {
203 cerr
<< get_fileline() << ": debug: PGAssign "
204 << "Truncate r-value from "
205 << cnt
<< " bits to "
206 << lval
->vector_width() << " bits." << endl
;
208 NetNet
*tmp
= crop_to_width(des
, rid
, lval
->vector_width());
212 if (! need_driver_flag
) {
214 /* Don't need a driver, presumably because the
215 r-value already has the needed drivers. Just
216 hook things up. If the r-value is too narrow
217 for the l-value, then sign extend it or zero
218 extend it, whichever makes sense. */
220 if (debug_elaborate
) {
221 cerr
<< get_fileline() << ": debug: PGAssign: "
222 << "Connect lval directly to "
223 << id
->path() << endl
;
226 connect(lval
->pin(0), rid
->pin(0));
229 /* Do need a driver. Use BUFZ objects to carry the
230 strength and delays. */
232 if (debug_elaborate
) {
233 cerr
<< get_fileline() << ": debug: PGAssign: "
234 << "Connect lval to " << id
->path()
235 << " through bufz. delay=(";
237 cerr
<< *rise_time
<< ":";
241 cerr
<< *fall_time
<< ":";
251 NetBUFZ
*dev
= new NetBUFZ(scope
, scope
->local_symbol(),
252 rid
->vector_width());
253 connect(lval
->pin(0), dev
->pin(0));
254 connect(rid
->pin(0), dev
->pin(1));
255 dev
->rise_time(rise_time
);
256 dev
->fall_time(fall_time
);
257 dev
->decay_time(decay_time
);
258 dev
->pin(0).drive0(drive0
);
259 dev
->pin(0).drive1(drive1
);
267 /* Elaborate the r-value. Account for the initial decays,
268 which are going to be attached to the last gate before the
270 NetNet
*rval
= pin(1)->elaborate_net(des
, scope
,
271 lval
->vector_width(),
275 cerr
<< get_fileline() << ": error: Unable to elaborate r-value: "
281 if (debug_elaborate
) {
282 cerr
<< get_fileline() << ": debug: PGAssign: elaborated r-value"
283 << " width="<<rval
->vector_width()
284 << ", type="<< rval
->data_type() << endl
;
287 assert(lval
&& rval
);
288 assert(rval
->pin_count() == 1);
290 /* If either lval or rval are real then both must be real. */
291 if ((lval
->data_type() == IVL_VT_REAL
||
292 rval
->data_type() == IVL_VT_REAL
) &&
293 lval
->data_type() != rval
->data_type()) {
294 cerr
<< get_fileline() << ": sorry: Both the r-value and "
295 "the l-value must be real in this context." << endl
;
300 /* If the r-value insists on being smaller then the l-value
301 (perhaps it is explicitly sized) the pad it out to be the
302 right width so that something is connected to all the bits
304 if (lval
->vector_width() > rval
->vector_width())
305 rval
= pad_to_width(des
, rval
, lval
->vector_width());
307 /* If, on the other hand, the r-value insists on being
308 LARGER then the l-value, use a part select to chop it down
310 if (lval
->vector_width() < rval
->vector_width()) {
311 NetPartSelect
*tmp
= new NetPartSelect(rval
, 0,lval
->vector_width(),
314 tmp
->set_line(*this);
315 NetNet
*osig
= new NetNet(scope
, scope
->local_symbol(),
316 NetNet::TRI
, lval
->vector_width());
317 osig
->set_line(*this);
318 osig
->data_type(rval
->data_type());
319 connect(osig
->pin(0), tmp
->pin(0));
323 /* If there is a rise/fall/decay time, then attach that delay
324 to the drivers for this net. */
325 if (rise_time
|| fall_time
|| decay_time
) {
326 rval
->pin(0).drivers_delays(rise_time
, fall_time
, decay_time
);
329 connect(lval
->pin(0), rval
->pin(0));
331 if (lval
->local_flag())
337 * Elaborate a Builtin gate. These normally get translated into
338 * NetLogic nodes that reflect the particular logic function.
340 void PGBuiltin::elaborate(Design
*des
, NetScope
*scope
) const
343 unsigned instance_width
= 1;
344 long low
= 0, high
= 0;
345 string name
= string(get_name());
348 name
= scope
->local_symbol();
350 /* If the Verilog source has a range specification for the
351 gates, then I am expected to make more than one
352 gate. Figure out how many are desired. */
354 NetExpr
*msb_exp
= elab_and_eval(des
, scope
, msb_
, -1);
355 NetExpr
*lsb_exp
= elab_and_eval(des
, scope
, lsb_
, -1);
357 NetEConst
*msb_con
= dynamic_cast<NetEConst
*>(msb_exp
);
358 NetEConst
*lsb_con
= dynamic_cast<NetEConst
*>(lsb_exp
);
361 cerr
<< get_fileline() << ": error: Unable to evaluate "
362 "expression " << *msb_
<< endl
;
368 cerr
<< get_fileline() << ": error: Unable to evaluate "
369 "expression " << *lsb_
<< endl
;
374 verinum msb
= msb_con
->value();
375 verinum lsb
= lsb_con
->value();
380 if (msb
.as_long() > lsb
.as_long())
381 count
= msb
.as_long() - lsb
.as_long() + 1;
383 count
= lsb
.as_long() - msb
.as_long() + 1;
386 high
= msb
.as_long();
388 if (debug_elaborate
) {
389 cerr
<< get_fileline() << ": debug: PGBuiltin: Make arrray "
390 << "[" << high
<< ":" << low
<< "]"
391 << " of " << count
<< " gates for " << name
<< endl
;
395 /* Now we have a gate count. Elaborate the output expression
396 only. We do it early so that we can see if we can make a
397 wide gate instead of an array of gates. */
400 cerr
<< get_fileline() << ": error: Logic gate port "
401 "expressions are not optional." << endl
;
405 NetNet
*lval_sig
= pin(0)->elaborate_lnet(des
, scope
);
408 /* Detect the special case that the l-value width exactly
409 matches the gate count. In this case, we will make a single
410 gate that has the desired vector width. */
411 if (lval_sig
->vector_width() == count
) {
412 instance_width
= count
;
415 if (debug_elaborate
&& instance_width
!= 1)
416 cerr
<< get_fileline() << ": debug: PGBuiltin: "
417 "Collapsed gate array into single wide "
418 "(" << instance_width
<< ") instance." << endl
;
421 /* Allocate all the netlist nodes for the gates. */
422 NetNode
**cur
= new NetNode
*[count
];
425 /* Calculate the gate delays from the delay expressions
426 given in the source. For logic gates, the decay time
427 is meaningless because it can never go to high
428 impedance. However, the bufif devices can generate
429 'bz output, so we will pretend that anything can.
431 If only one delay value expression is given (i.e., #5
432 nand(foo,...)) then rise, fall and decay times are
433 all the same value. If two values are given, rise and
434 fall times are use, and the decay time is the minimum
435 of the rise and fall times. Finally, if all three
436 values are given, they are taken as specified. */
438 NetExpr
* rise_time
, *fall_time
, *decay_time
;
439 eval_delays(des
, scope
, rise_time
, fall_time
, decay_time
);
441 struct attrib_list_t
*attrib_list
= 0;
442 unsigned attrib_list_n
= 0;
443 attrib_list
= evaluate_attributes(attributes
, attrib_list_n
,
446 /* Now make as many gates as the bit count dictates. Give each
447 a unique name, and set the delay times. */
449 for (unsigned idx
= 0 ; idx
< count
; idx
+= 1) {
457 tmp
<< name
<< "<" << index
<< ">";
458 perm_string inm
= lex_strings
.make(tmp
.str());
462 if (pin_count() < 2) {
463 cerr
<< get_fileline() << ": error: the AND "
464 "primitive must have an input." << endl
;
468 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
469 NetLogic::AND
, instance_width
);
472 if (pin_count() > 2) {
473 cerr
<< get_fileline() << ": sorry: multiple output BUF "
474 "primitives are not supported." << endl
;
478 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
479 NetLogic::BUF
, instance_width
);
482 if (pin_count() != 3) {
483 cerr
<< get_fileline() << ": error: the BUFIF0 "
484 "primitive must have three arguments." << endl
;
488 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
489 NetLogic::BUFIF0
, instance_width
);
492 if (pin_count() != 3) {
493 cerr
<< get_fileline() << ": error: the BUFIF1 "
494 "primitive must have three arguments." << endl
;
498 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
499 NetLogic::BUFIF1
, instance_width
);
502 if (pin_count() != 4) {
503 cerr
<< get_fileline() << ": error: the CMOS "
504 "primitive must have four arguments." << endl
;
508 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
509 NetLogic::CMOS
, instance_width
);
512 if (pin_count() < 2) {
513 cerr
<< get_fileline() << ": error: the NAND "
514 "primitive must have an input." << endl
;
518 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
519 NetLogic::NAND
, instance_width
);
522 if (pin_count() != 3) {
523 cerr
<< get_fileline() << ": error: the NMOS "
524 "primitive must have three arguments." << endl
;
528 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
529 NetLogic::NMOS
, instance_width
);
532 if (pin_count() < 2) {
533 cerr
<< get_fileline() << ": error: the NOR "
534 "primitive must have an input." << endl
;
538 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
539 NetLogic::NOR
, instance_width
);
542 if (pin_count() > 2) {
543 cerr
<< get_fileline() << ": sorry: multiple output NOT "
544 "primitives are not supported." << endl
;
548 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
549 NetLogic::NOT
, instance_width
);
552 if (pin_count() != 3) {
553 cerr
<< get_fileline() << ": error: the NOTIF0 "
554 "primitive must have three arguments." << endl
;
558 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
559 NetLogic::NOTIF0
, instance_width
);
562 if (pin_count() != 3) {
563 cerr
<< get_fileline() << ": error: the NOTIF1 "
564 "primitive must have three arguments." << endl
;
568 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
569 NetLogic::NOTIF1
, instance_width
);
572 if (pin_count() < 2) {
573 cerr
<< get_fileline() << ": error: the OR "
574 "primitive must have an input." << endl
;
578 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
579 NetLogic::OR
, instance_width
);
582 if (pin_count() != 4) {
583 cerr
<< get_fileline() << ": error: the RCMOS "
584 "primitive must have four arguments." << endl
;
588 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
589 NetLogic::RCMOS
, instance_width
);
592 if (pin_count() != 3) {
593 cerr
<< get_fileline() << ": error: the RNMOS "
594 "primitive must have three arguments." << endl
;
598 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
599 NetLogic::RNMOS
, instance_width
);
602 if (pin_count() != 3) {
603 cerr
<< get_fileline() << ": error: the RPMOS "
604 "primitive must have three arguments." << endl
;
608 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
609 NetLogic::RPMOS
, instance_width
);
612 if (pin_count() != 3) {
613 cerr
<< get_fileline() << ": error: the PMOS "
614 "primitive must have three arguments." << endl
;
618 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
619 NetLogic::PMOS
, instance_width
);
622 if (pin_count() > 1) {
623 cerr
<< get_fileline() << ": sorry: multiple output PULLDOWN "
624 "primitives are not supported." << endl
;
628 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
633 if (pin_count() > 1) {
634 cerr
<< get_fileline() << ": sorry: multiple output PULLUP "
635 "primitives are not supported." << endl
;
639 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
640 NetLogic::PULLUP
, instance_width
);
643 if (pin_count() < 2) {
644 cerr
<< get_fileline() << ": error: the XNOR "
645 "primitive must have an input." << endl
;
649 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
650 NetLogic::XNOR
, instance_width
);
653 if (pin_count() < 2) {
654 cerr
<< get_fileline() << ": error: the XOR "
655 "primitive must have an input." << endl
;
659 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
660 NetLogic::XOR
, instance_width
);
663 if (pin_count() != 2) {
664 cerr
<< get_fileline() << ": error: Pin count for "
665 << "tran device." << endl
;
669 cur
[idx
] = new NetTran(scope
, inm
, IVL_SW_TRAN
);
673 if (pin_count() != 2) {
674 cerr
<< get_fileline() << ": error: Pin count for "
675 << "rtran device." << endl
;
679 cur
[idx
] = new NetTran(scope
, inm
, IVL_SW_RTRAN
);
684 if (pin_count() != 3) {
685 cerr
<< get_fileline() << ": error: Pin count for "
686 << "tranif0 device." << endl
;
690 cur
[idx
] = new NetTran(scope
, inm
, IVL_SW_TRANIF0
);
694 if (pin_count() != 3) {
695 cerr
<< get_fileline() << ": error: Pin count for "
696 << "rtranif0 device." << endl
;
700 cur
[idx
] = new NetTran(scope
, inm
, IVL_SW_RTRANIF0
);
704 if (pin_count() != 3) {
705 cerr
<< get_fileline() << ": error: Pin count for "
706 << "tranif1 device." << endl
;
710 cur
[idx
] = new NetTran(scope
, inm
, IVL_SW_TRANIF1
);
714 if (pin_count() != 3) {
715 cerr
<< get_fileline() << ": error: Pin count for "
716 << "rtranif1 device." << endl
;
720 cur
[idx
] = new NetTran(scope
, inm
, IVL_SW_RTRANIF1
);
724 cerr
<< get_fileline() << ": internal error: unhandled "
725 "gate type." << endl
;
730 for (unsigned adx
= 0 ; adx
< attrib_list_n
; adx
+= 1)
731 cur
[idx
]->attribute(attrib_list
[adx
].key
,
732 attrib_list
[adx
].val
);
734 /* The logic devices have some uniform processing. Then
735 all may have output delays and output drive strength. */
736 if (NetLogic
*log
= dynamic_cast<NetLogic
*> (cur
[idx
])) {
737 log
->rise_time(rise_time
);
738 log
->fall_time(fall_time
);
739 log
->decay_time(decay_time
);
741 log
->pin(0).drive0(drive_type(strength0()));
742 log
->pin(0).drive1(drive_type(strength1()));
745 cur
[idx
]->set_line(*this);
746 des
->add_node(cur
[idx
]);
752 /* The gates have all been allocated, this loop runs through
753 the parameters and attaches the ports of the objects. */
755 for (unsigned idx
= 0 ; idx
< pin_count() ; idx
+= 1) {
756 const PExpr
*ex
= pin(idx
);
758 cerr
<< get_fileline() << ": error: Logic gate port "
759 "expressions are not optional." << endl
;
763 NetNet
*sig
= (idx
== 0)
765 : ex
->elaborate_net(des
, scope
, 0, 0, 0, 0);
772 /* Handle the case where there is one gate that
773 carries the whole vector width. */
775 if (1 == sig
->vector_width() && instance_width
!= 1) {
777 assert(sig
->vector_width() == 1);
779 = new NetReplicate(scope
,
780 scope
->local_symbol(),
783 rep
->set_line(*this);
785 connect(rep
->pin(1), sig
->pin(0));
787 sig
= new NetNet(scope
, scope
->local_symbol(),
788 NetNet::WIRE
, instance_width
);
789 sig
->data_type(IVL_VT_LOGIC
);
790 sig
->local_flag(true);
791 sig
->set_line(*this);
792 connect(rep
->pin(0), sig
->pin(0));
796 if (instance_width
!= sig
->vector_width()) {
798 cerr
<< get_fileline() << ": error: "
799 << "Expression width " << sig
->vector_width()
800 << " does not match width " << instance_width
801 << " of logic gate array port " << idx
806 connect(cur
[0]->pin(idx
), sig
->pin(0));
808 } else if (sig
->vector_width() == 1) {
809 /* Handle the case where a single bit is connected
810 repetitively to all the instances. */
811 for (unsigned gdx
= 0 ; gdx
< count
; gdx
+= 1)
812 connect(cur
[gdx
]->pin(idx
), sig
->pin(0));
814 } else if (sig
->vector_width() == count
) {
816 /* Handle the general case that each bit of the
817 value is connected to a different instance. In
818 this case, the output is handled slightly
819 different from the inputs. */
821 NetConcat
*cc
= new NetConcat(scope
,
822 scope
->local_symbol(),
827 /* Connect the concat to the signal. */
828 connect(cc
->pin(0), sig
->pin(0));
830 /* Connect the outputs of the gates to the concat. */
831 for (unsigned gdx
= 0 ; gdx
< count
; gdx
+= 1) {
832 connect(cur
[gdx
]->pin(0), cc
->pin(gdx
+1));
834 NetNet
*tmp2
= new NetNet(scope
,
835 scope
->local_symbol(),
837 tmp2
->local_flag(true);
838 tmp2
->data_type(IVL_VT_LOGIC
);
839 connect(cc
->pin(gdx
+1), tmp2
->pin(0));
842 } else for (unsigned gdx
= 0 ; gdx
< count
; gdx
+= 1) {
843 /* Use part selects to get the bits
844 connected to the inputs of out gate. */
845 NetPartSelect
*tmp1
= new NetPartSelect(sig
, gdx
, 1,
847 tmp1
->set_line(*this);
849 connect(tmp1
->pin(1), sig
->pin(0));
850 NetNet
*tmp2
= new NetNet(scope
, scope
->local_symbol(),
852 tmp2
->local_flag(true);
853 tmp2
->data_type(sig
->data_type());
854 connect(tmp1
->pin(0), tmp2
->pin(0));
855 connect(cur
[gdx
]->pin(idx
), tmp1
->pin(0));
859 cerr
<< get_fileline() << ": error: Gate count of " <<
860 count
<< " does not match net width of " <<
861 sig
->vector_width() << " at pin " << idx
<< "."
869 NetNet
*PGModule::resize_net_to_port_(Design
*des
, NetScope
*scope
,
870 NetNet
*sig
, unsigned port_wid
,
871 NetNet::PortType dir
) const
873 ivl_assert(*this, dir
!= NetNet::NOT_A_PORT
);
874 ivl_assert(*this, dir
!= NetNet::PIMPLICIT
);
876 NetNet
*tmp
= new NetNet(scope
, scope
->local_symbol(),
877 NetNet::WIRE
, port_wid
);
878 tmp
->local_flag(true);
881 NetPartSelect
*node
= 0;
884 case NetNet::POUTPUT
:
885 if (tmp
->vector_width() > sig
->vector_width()) {
886 node
= new NetPartSelect(tmp
, 0, sig
->vector_width(),
888 connect(node
->pin(0), sig
->pin(0));
890 node
= new NetPartSelect(sig
, 0, tmp
->vector_width(),
892 connect(node
->pin(0), tmp
->pin(0));
897 if (tmp
->vector_width() > sig
->vector_width()) {
898 node
= new NetPartSelect(tmp
, 0, sig
->vector_width(),
900 connect(node
->pin(0), sig
->pin(0));
902 node
= new NetPartSelect(sig
, 0, tmp
->vector_width(),
904 connect(node
->pin(0), tmp
->pin(0));
909 if (sig
->vector_width() > tmp
->vector_width()) {
910 node
= new NetPartSelect(sig
, 0, tmp
->vector_width(),
912 connect(node
->pin(0), tmp
->pin(0));
914 node
= new NetPartSelect(tmp
, 0, sig
->vector_width(),
916 connect(node
->pin(0), sig
->pin(0));
921 ivl_assert(*this, 0);
930 * Instantiate a module by recursively elaborating it. Set the path of
931 * the recursive elaboration so that signal names get properly
932 * set. Connect the ports of the instantiated module to the signals of
933 * the parameters. This is done with BUFZ gates so that they look just
934 * like continuous assignment connections.
936 void PGModule::elaborate_mod_(Design
*des
, Module
*rmod
, NetScope
*scope
) const
941 if (debug_elaborate
) {
942 cerr
<< get_fileline() << ": debug: Instantiate module "
943 << rmod
->mod_name() << " with instance name "
944 << get_name() << " in scope " << scope_path(scope
) << endl
;
947 // This is the array of pin expressions, shuffled to match the
948 // order of the declaration. If the source instantiation uses
949 // bind by order, this is the same as the source list.Otherwise,
950 // the source list is rearranged by name binding into this list.
951 svector
<PExpr
*>pins (rmod
->port_count());
953 // If the instance has a pins_ member, then we know we are
954 // binding by name. Therefore, make up a pins array that
955 // reflects the positions of the named ports.
957 unsigned nexp
= rmod
->port_count();
959 // Scan the bindings, matching them with port names.
960 for (unsigned idx
= 0 ; idx
< npins_
; idx
+= 1) {
962 // Given a binding, look at the module port names
963 // for the position that matches the binding name.
964 unsigned pidx
= rmod
->find_port(pins_
[idx
].name
);
966 // If the port name doesn't exist, the find_port
967 // method will return the port count. Detect that
970 cerr
<< get_fileline() << ": error: port ``" <<
971 pins_
[idx
].name
<< "'' is not a port of "
972 << get_name() << "." << endl
;
977 // If I already bound something to this port, then
978 // the pins array will already have a pointer
979 // value where I want to place this expression.
981 cerr
<< get_fileline() << ": error: port ``" <<
982 pins_
[idx
].name
<< "'' already bound." <<
988 // OK, do the binding by placing the expression in
990 pins
[pidx
] = pins_
[idx
].parm
;
994 } else if (pin_count() == 0) {
996 /* Handle the special case that no ports are
997 connected. It is possible that this is an empty
998 connect-by-name list, so we'll allow it and assume
1001 for (unsigned idx
= 0 ; idx
< rmod
->port_count() ; idx
+= 1)
1006 /* Otherwise, this is a positional list of port
1007 connections. In this case, the port count must be
1008 right. Check that is is, the get the pin list. */
1010 if (pin_count() != rmod
->port_count()) {
1011 cerr
<< get_fileline() << ": error: Wrong number "
1012 "of ports. Expecting " << rmod
->port_count() <<
1013 ", got " << pin_count() << "."
1019 // No named bindings, just use the positional list I
1021 assert(pin_count() == rmod
->port_count());
1025 // Elaborate these instances of the module. The recursive
1026 // elaboration causes the module to generate a netlist with
1027 // the ports represented by NetNet objects. I will find them
1030 NetScope::scope_vec_t
&instance
= scope
->instance_arrays
[get_name()];
1031 for (unsigned inst
= 0 ; inst
< instance
.count() ; inst
+= 1) {
1032 rmod
->elaborate(des
, instance
[inst
]);
1037 // Now connect the ports of the newly elaborated designs to
1038 // the expressions that are the instantiation parameters. Scan
1039 // the pins, elaborate the expressions attached to them, and
1040 // bind them to the port of the elaborated module.
1042 // This can get rather complicated because the port can be
1043 // unconnected (meaning an empty parameter is passed) connected
1044 // to a concatenation, or connected to an internally
1045 // unconnected port.
1047 for (unsigned idx
= 0 ; idx
< pins
.count() ; idx
+= 1) {
1049 // Skip unconnected module ports. This happens when a
1050 // null parameter is passed in.
1052 if (pins
[idx
] == 0) {
1054 // While we're here, look to see if this
1055 // unconnected (from the outside) port is an
1056 // input. If so, consider printing a port binding
1058 if (warn_portbinding
) {
1059 svector
<PEIdent
*> mport
= rmod
->get_port(idx
);
1060 if (mport
.count() == 0)
1063 perm_string pname
= peek_tail_name(mport
[0]->path());
1065 NetNet
*tmp
= instance
[0]->find_signal(pname
);
1068 if (tmp
->port_type() == NetNet::PINPUT
) {
1069 cerr
<< get_fileline() << ": warning: "
1070 << "Instantiating module "
1072 << " with dangling input port "
1073 << rmod
->ports
[idx
]->name
1082 // Inside the module, the port is zero or more signals
1083 // that were already elaborated. List all those signals
1084 // and the NetNet equivalents, for all the instances.
1085 svector
<PEIdent
*> mport
= rmod
->get_port(idx
);
1086 svector
<NetNet
*>prts (mport
.count() * instance
.count());
1088 if (debug_elaborate
) {
1089 cerr
<< get_fileline() << ": debug: " << get_name()
1090 << ": Port " << idx
<< " has " << prts
.count()
1091 << " sub-ports." << endl
;
1094 // Count the internal vector bits of the port.
1095 unsigned prts_vector_width
= 0;
1097 for (unsigned inst
= 0 ; inst
< instance
.count() ; inst
+= 1) {
1098 // Scan the instances from MSB to LSB. The port
1099 // will be assembled in that order as well.
1100 NetScope
*inst_scope
= instance
[instance
.count()-inst
-1];
1102 // Scan the module sub-ports for this instance...
1103 for (unsigned ldx
= 0 ; ldx
< mport
.count() ; ldx
+= 1) {
1104 unsigned lbase
= inst
* mport
.count();
1105 PEIdent
*pport
= mport
[ldx
];
1108 = pport
->elaborate_port(des
, inst_scope
);
1109 if (prts
[lbase
+ ldx
] == 0)
1112 assert(prts
[lbase
+ ldx
]);
1113 prts_vector_width
+= prts
[lbase
+ ldx
]->vector_width();
1117 // If I find that the port is unconnected inside the
1118 // module, then there is nothing to connect. Skip the
1120 if (prts_vector_width
== 0) {
1124 // We know by design that each instance has the same
1125 // width port. Therefore, the prts_pin_count must be an
1126 // even multiple of the instance count.
1127 assert(prts_vector_width
% instance
.count() == 0);
1129 unsigned desired_vector_width
= prts_vector_width
;
1130 if (instance
.count() != 1)
1131 desired_vector_width
= 0;
1133 // Elaborate the expression that connects to the
1134 // module[s] port. sig is the thing outside the module
1135 // that connects to the port.
1138 if ((prts
.count() == 0)
1139 || (prts
[0]->port_type() == NetNet::PINPUT
)) {
1141 /* Input to module. elaborate the expression to
1142 the desired width. If this in an instance
1143 array, then let the net determine it's own
1144 width. We use that, then, to decide how to hook
1147 NOTE that this also handles the case that the
1148 port is actually empty on the inside. We assume
1149 in that case that the port is input. */
1151 sig
= pins
[idx
]->elaborate_net(des
, scope
,
1152 desired_vector_width
,
1155 cerr
<< pins
[idx
]->get_fileline()
1156 << ": internal error: Port expression "
1157 << "too complicated for elaboration." << endl
;
1161 } else if (prts
[0]->port_type() == NetNet::PINOUT
) {
1163 /* Inout to/from module. This is a more
1164 complicated case, where the expression must be
1165 an lnet, but also an r-value net.
1167 Normally, this winds up being the same as if we
1168 just elaborated as an lnet, as passing a simple
1169 identifier elaborates to the same NetNet in
1170 both cases so the extra elaboration has no
1171 effect. But if the expression passed to the
1172 inout port is a part select, aspecial part
1173 select must be created that can paqss data in
1176 Use the elaborate_bi_net method to handle all
1177 the possible cases. */
1179 sig
= pins
[idx
]->elaborate_bi_net(des
, scope
);
1181 cerr
<< pins
[idx
]->get_fileline() << ": error: "
1182 << "Inout port expression must support "
1183 << "continuous assignment." << endl
;
1184 cerr
<< pins
[idx
]->get_fileline() << ": : "
1185 << "Port of " << rmod
->mod_name()
1186 << " is " << rmod
->ports
[idx
]->name
<< endl
;
1194 /* Port type must be OUTPUT here. */
1196 /* Output from module. Elaborate the port
1197 expression as the l-value of a continuous
1198 assignment, as the port will continuous assign
1201 sig
= pins
[idx
]->elaborate_lnet(des
, scope
);
1203 cerr
<< pins
[idx
]->get_fileline() << ": error: "
1204 << "Output port expression must support "
1205 << "continuous assignment." << endl
;
1206 cerr
<< pins
[idx
]->get_fileline() << ": : "
1207 << "Port of " << rmod
->mod_name()
1208 << " is " << rmod
->ports
[idx
]->name
<< endl
;
1218 if ((prts
.count() >= 1)
1219 && (prts
[0]->port_type() != NetNet::PINPUT
)) {
1220 assert(sig
->type() != NetNet::REG
);
1224 /* If we are working with an instance array, then the
1225 signal width must match the port width exactly. */
1226 if ((instance
.count() != 1)
1227 && (sig
->vector_width() != prts_vector_width
)
1228 && (sig
->vector_width() != prts_vector_width
/instance
.count())) {
1229 cerr
<< pins
[idx
]->get_fileline() << ": error: "
1230 << "Port expression width " << sig
->vector_width()
1231 << " does not match expected width "<< prts_vector_width
1232 << " or " << (prts_vector_width
/instance
.count())
1238 if (debug_elaborate
) {
1239 cerr
<< get_fileline() << ": debug: " << get_name()
1240 << ": Port " << (idx
+1) << " has vector width of "
1241 << prts_vector_width
<< "." << endl
;
1244 // Check that the parts have matching pin counts. If
1245 // not, they are different widths. Note that idx is 0
1246 // based, but users count parameter positions from 1.
1247 if ((instance
.count() == 1)
1248 && (prts_vector_width
!= sig
->vector_width())) {
1249 const char *tmp3
= rmod
->ports
[idx
]->name
.str();
1250 if (tmp3
== 0) tmp3
= "???";
1251 cerr
<< get_fileline() << ": warning: Port " << (idx
+1)
1252 << " (" << tmp3
<< ") of "
1253 << type_
<< " expects " << prts_vector_width
<<
1254 " bits, got " << sig
->vector_width() << "." << endl
;
1256 if (prts_vector_width
> sig
->vector_width()) {
1257 cerr
<< get_fileline() << ": : Leaving "
1258 << (prts_vector_width
-sig
->vector_width())
1259 << " high bits of the port unconnected."
1264 cerr
<< get_fileline() << ": : Leaving "
1265 << (sig
->vector_width()-prts_vector_width
)
1266 << " high bits of the expression dangling."
1270 sig
= resize_net_to_port_(des
, scope
, sig
, prts_vector_width
,
1271 prts
[0]->port_type());
1274 // Connect the sig expression that is the context of the
1275 // module instance to the ports of the elaborated module.
1277 // The prts_pin_count variable is the total width of the
1278 // port and is the maximum number of connections to
1279 // make. sig is the elaborated expression that connects
1280 // to that port. If sig has too few pins, then reduce
1281 // the number of connections to make.
1283 // Connect this many of the port pins. If the expression
1284 // is too small, then reduce the number of connects.
1285 unsigned ccount
= prts_vector_width
;
1286 if (instance
.count() == 1 && sig
->vector_width() < ccount
)
1287 ccount
= sig
->vector_width();
1289 // The spin_modulus is the width of the signal (not the
1290 // port) if this is an instance array. This causes
1291 // signals wide enough for a single instance to be
1292 // connected to all the instances.
1293 unsigned spin_modulus
= prts_vector_width
;
1294 if (instance
.count() != 1)
1295 spin_modulus
= sig
->vector_width();
1297 // Now scan the concatenation that makes up the port,
1298 // connecting pins until we run out of port pins or sig
1299 // pins. The sig object is the NetNet that is connected
1300 // to the port from the outside, and the prts object is
1301 // an array of signals to be connected to the sig.
1306 if (prts
.count() == 1) {
1308 // The simplest case, there are no
1309 // parts/concatenations on the inside of the
1310 // module, so the port and sig need simply be
1311 // connected directly.
1312 connect(prts
[0]->pin(0), sig
->pin(0));
1314 } else if (sig
->vector_width()==prts_vector_width
/instance
.count()
1315 && prts
.count()/instance
.count() == 1) {
1317 if (debug_elaborate
){
1318 cerr
<< get_fileline() << ": debug: " << get_name()
1319 << ": Replicating " << prts_vector_width
1320 << " bits across all "
1321 << prts_vector_width
/instance
.count()
1322 << " sub-ports." << endl
;
1325 // The signal width is exactly the width of a
1326 // single instance of the port. In this case,
1327 // connect the sig to all the ports identically.
1328 for (unsigned ldx
= 0 ; ldx
< prts
.count() ; ldx
+= 1)
1329 connect(prts
[ldx
]->pin(0), sig
->pin(0));
1331 } else switch (prts
[0]->port_type()) {
1332 case NetNet::POUTPUT
:
1333 ctmp
= new NetConcat(scope
, scope
->local_symbol(),
1336 des
->add_node(ctmp
);
1337 connect(ctmp
->pin(0), sig
->pin(0));
1338 for (unsigned ldx
= 0 ; ldx
< prts
.count() ; ldx
+= 1) {
1339 connect(ctmp
->pin(ldx
+1),
1340 prts
[prts
.count()-ldx
-1]->pin(0));
1344 case NetNet::PINPUT
:
1345 if (debug_elaborate
){
1346 cerr
<< get_fileline() << ": debug: " << get_name()
1347 << ": Dividing " << prts_vector_width
1348 << " bits across all "
1349 << prts_vector_width
/instance
.count()
1350 << " input sub-ports of port "
1351 << idx
<< "." << endl
;
1354 for (unsigned ldx
= 0 ; ldx
< prts
.count() ; ldx
+= 1) {
1355 NetNet
*sp
= prts
[prts
.count()-ldx
-1];
1356 NetPartSelect
*ptmp
= new NetPartSelect(sig
, spin
,
1359 des
->add_node(ptmp
);
1360 connect(ptmp
->pin(0), sp
->pin(0));
1361 spin
+= sp
->vector_width();
1364 case NetNet::PINOUT
:
1365 cerr
<< get_fileline() << ": XXXX: "
1366 << "Forgot how to bind inout ports!" << endl
;
1369 case NetNet::PIMPLICIT
:
1370 cerr
<< get_fileline() << ": internal error: "
1371 << "Unexpected IMPLICIT port" << endl
;
1374 case NetNet::NOT_A_PORT
:
1375 cerr
<< get_fileline() << ": internal error: "
1376 << "Unexpected NOT_A_PORT port." << endl
;
1386 * From a UDP definition in the source, make a NetUDP
1387 * object. Elaborate the pin expressions as netlists, then connect
1388 * those networks to the pins.
1391 void PGModule::elaborate_udp_(Design
*des
, PUdp
*udp
, NetScope
*scope
) const
1393 NetExpr
*rise_expr
=0, *fall_expr
=0, *decay_expr
=0;
1395 perm_string my_name
= get_name();
1397 my_name
= scope
->local_symbol();
1399 /* When the parser notices delay expressions in front of a
1400 module or primitive, it interprets them as parameter
1401 overrides. Correct that misconception here. */
1404 tmp_del
.set_delays(overrides_
, false);
1405 tmp_del
.eval_delays(des
, scope
, rise_expr
, fall_expr
, decay_expr
);
1407 if (dynamic_cast<NetEConst
*> (rise_expr
)) {
1410 cerr
<< get_fileline() << ": error: Delay expressions must be "
1411 << "constant for primitives." << endl
;
1412 cerr
<< get_fileline() << ": : Cannot calculate "
1413 << *rise_expr
<< endl
;
1417 if (dynamic_cast<NetEConst
*> (fall_expr
)) {
1420 cerr
<< get_fileline() << ": error: Delay expressions must be "
1421 << "constant for primitives." << endl
;
1422 cerr
<< get_fileline() << ": : Cannot calculate "
1423 << *rise_expr
<< endl
;
1427 if (dynamic_cast<NetEConst
*> (decay_expr
)) {
1430 cerr
<< get_fileline() << ": error: Delay expressions must be "
1431 << "constant for primitives." << endl
;
1432 cerr
<< get_fileline() << ": : Cannot calculate "
1433 << *rise_expr
<< endl
;
1441 NetUDP
*net
= new NetUDP(scope
, my_name
, udp
->ports
.count(), udp
);
1442 net
->rise_time(rise_expr
);
1443 net
->fall_time(fall_expr
);
1444 net
->decay_time(decay_expr
);
1446 struct attrib_list_t
*attrib_list
= 0;
1447 unsigned attrib_list_n
= 0;
1448 attrib_list
= evaluate_attributes(attributes
, attrib_list_n
,
1451 for (unsigned adx
= 0 ; adx
< attrib_list_n
; adx
+= 1)
1452 net
->attribute(attrib_list
[adx
].key
, attrib_list
[adx
].val
);
1454 delete[]attrib_list
;
1457 // This is the array of pin expressions, shuffled to match the
1458 // order of the declaration. If the source instantiation uses
1459 // bind by order, this is the same as the source
1460 // list. Otherwise, the source list is rearranged by name
1461 // binding into this list.
1462 svector
<PExpr
*>pins
;
1464 // Detect binding by name. If I am binding by name, then make
1465 // up a pins array that reflects the positions of the named
1466 // ports. If this is simply positional binding in the first
1467 // place, then get the binding from the base class.
1469 unsigned nexp
= udp
->ports
.count();
1470 pins
= svector
<PExpr
*>(nexp
);
1472 // Scan the bindings, matching them with port names.
1473 for (unsigned idx
= 0 ; idx
< npins_
; idx
+= 1) {
1475 // Given a binding, look at the module port names
1476 // for the position that matches the binding name.
1477 unsigned pidx
= udp
->find_port(pins_
[idx
].name
);
1479 // If the port name doesn't exist, the find_port
1480 // method will return the port count. Detect that
1483 cerr
<< get_fileline() << ": error: port ``" <<
1484 pins_
[idx
].name
<< "'' is not a port of "
1485 << get_name() << "." << endl
;
1490 // If I already bound something to this port, then
1491 // the (*exp) array will already have a pointer
1492 // value where I want to place this expression.
1494 cerr
<< get_fileline() << ": error: port ``" <<
1495 pins_
[idx
].name
<< "'' already bound." <<
1501 // OK, do the binding by placing the expression in
1503 pins
[pidx
] = pins_
[idx
].parm
;
1508 /* Otherwise, this is a positional list of port
1509 connections. In this case, the port count must be
1510 right. Check that is is, the get the pin list. */
1512 if (pin_count() != udp
->ports
.count()) {
1513 cerr
<< get_fileline() << ": error: Wrong number "
1514 "of ports. Expecting " << udp
->ports
.count() <<
1515 ", got " << pin_count() << "."
1521 // No named bindings, just use the positional list I
1523 assert(pin_count() == udp
->ports
.count());
1528 /* Handle the output port of the primitive special. It is an
1529 output port (the only output port) so must be passed an
1532 cerr
<< get_fileline() << ": warning: output port unconnected."
1536 NetNet
*sig
= pins
[0]->elaborate_lnet(des
, scope
);
1538 cerr
<< get_fileline() << ": error: "
1539 << "Output port expression is not valid." << endl
;
1540 cerr
<< get_fileline() << ": : Output "
1541 << "port of " << udp
->name_
1542 << " is " << udp
->ports
[0] << "." << endl
;
1545 connect(sig
->pin(0), net
->pin(0));
1549 /* Run through the pins, making netlists for the pin
1550 expressions and connecting them to the pin in question. All
1551 of this is independent of the nature of the UDP. */
1552 for (unsigned idx
= 1 ; idx
< net
->pin_count() ; idx
+= 1) {
1556 NetNet
*sig
= pins
[idx
]->elaborate_net(des
, scope
, 1, 0, 0, 0);
1558 cerr
<< "internal error: Expression too complicated "
1559 "for elaboration:" << pins
[idx
] << endl
;
1563 connect(sig
->pin(0), net
->pin(idx
));
1566 // All done. Add the object to the design.
1571 bool PGModule::elaborate_sig(Design
*des
, NetScope
*scope
) const
1573 // Look for the module type
1574 map
<perm_string
,Module
*>::const_iterator mod
= pform_modules
.find(type_
);
1575 if (mod
!= pform_modules
.end())
1576 return elaborate_sig_mod_(des
, scope
, (*mod
).second
);
1578 map
<perm_string
,PUdp
*>::const_iterator udp
= pform_primitives
.find(type_
);
1579 if (udp
!= pform_primitives
.end())
1580 return elaborate_sig_udp_(des
, scope
, (*udp
).second
);
1586 void PGModule::elaborate(Design
*des
, NetScope
*scope
) const
1588 // Look for the module type
1589 map
<perm_string
,Module
*>::const_iterator mod
= pform_modules
.find(type_
);
1590 if (mod
!= pform_modules
.end()) {
1591 elaborate_mod_(des
, (*mod
).second
, scope
);
1595 // Try a primitive type
1596 map
<perm_string
,PUdp
*>::const_iterator udp
= pform_primitives
.find(type_
);
1597 if (udp
!= pform_primitives
.end()) {
1598 assert((*udp
).second
);
1599 elaborate_udp_(des
, (*udp
).second
, scope
);
1603 cerr
<< get_fileline() << ": internal error: Unknown module type: " <<
1607 void PGModule::elaborate_scope(Design
*des
, NetScope
*sc
) const
1609 // Look for the module type
1610 map
<perm_string
,Module
*>::const_iterator mod
= pform_modules
.find(type_
);
1611 if (mod
!= pform_modules
.end()) {
1612 elaborate_scope_mod_(des
, (*mod
).second
, sc
);
1616 // Try a primitive type
1617 map
<perm_string
,PUdp
*>::const_iterator udp
= pform_primitives
.find(type_
);
1618 if (udp
!= pform_primitives
.end())
1621 // Not a module or primitive that I know about yet, so try to
1622 // load a library module file (which parses some new Verilog
1623 // code) and try again.
1624 if (load_module(type_
)) {
1626 // Try again to find the module type
1627 mod
= pform_modules
.find(type_
);
1628 if (mod
!= pform_modules
.end()) {
1629 elaborate_scope_mod_(des
, (*mod
).second
, sc
);
1633 // Try again to find a primitive type
1634 udp
= pform_primitives
.find(type_
);
1635 if (udp
!= pform_primitives
.end())
1640 // Not a module or primitive that I know about or can find by
1641 // any means, so give up.
1642 cerr
<< get_fileline() << ": error: Unknown module type: " << type_
<< endl
;
1643 missing_modules
[type_
] += 1;
1648 NetProc
* Statement::elaborate(Design
*des
, NetScope
*) const
1650 cerr
<< get_fileline() << ": internal error: elaborate: "
1651 "What kind of statement? " << typeid(*this).name() << endl
;
1652 NetProc
*cur
= new NetProc
;
1658 NetAssign_
* PAssign_::elaborate_lval(Design
*des
, NetScope
*scope
) const
1661 return lval_
->elaborate_lval(des
, scope
, false);
1665 * This function elaborates delay expressions. This is a little
1666 * different from normal elaboration because the result may need to be
1669 static NetExpr
*elaborate_delay_expr(PExpr
*expr
, Design
*des
, NetScope
*scope
)
1671 NetExpr
*dex
= elab_and_eval(des
, scope
, expr
, -1);
1673 /* If the delay expression is a real constant or vector
1674 constant, then evaluate it, scale it to the local time
1675 units, and return an adjusted NetEConst. */
1677 if (NetECReal
*tmp
= dynamic_cast<NetECReal
*>(dex
)) {
1678 verireal fn
= tmp
->value();
1680 int shift
= scope
->time_unit() - des
->get_precision();
1681 int64_t delay
= fn
.as_long64(shift
);
1686 return new NetEConst(verinum(delay
));
1690 if (NetEConst
*tmp
= dynamic_cast<NetEConst
*>(dex
)) {
1691 verinum fn
= tmp
->value();
1694 des
->scale_to_precision(fn
.as_ulong64(), scope
);
1697 return new NetEConst(verinum(delay
));
1701 /* The expression is not constant, so generate an expanded
1702 expression that includes the necessary scale shifts, and
1703 return that expression. */
1704 int shift
= scope
->time_unit() - des
->get_precision();
1712 NetExpr
*scal_val
= new NetEConst(verinum(scale
));
1713 dex
= new NetEBMult('*', dex
, scal_val
);
1717 unsigned long scale
= 1;
1723 NetExpr
*scal_val
= new NetEConst(verinum(scale
));
1724 dex
= new NetEBDiv('/', dex
, scal_val
);
1730 NetProc
* PAssign::elaborate(Design
*des
, NetScope
*scope
) const
1734 /* elaborate the lval. This detects any part selects and mux
1735 expressions that might exist. */
1736 NetAssign_
*lv
= elaborate_lval(des
, scope
);
1737 if (lv
== 0) return 0;
1739 /* If there is an internal delay expression, elaborate it. */
1742 delay
= elaborate_delay_expr(delay_
, des
, scope
);
1747 /* Elaborate the r-value expression, then try to evaluate it. */
1749 /* Find out what the r-value width is going to be. We guess it
1750 will be the l-value width, but it may turn out to be
1751 something else based on self-determined widths inside. */
1752 unsigned use_width
= lv
->lwidth();
1753 bool unsized_flag
= false;
1754 use_width
= rval()->test_width(des
, scope
, use_width
, use_width
, unsized_flag
);
1756 /* Now elaborate to the expected width. Pass the lwidth to
1757 prune any constant result to fit with the lvalue at hand. */
1758 NetExpr
*rv
= elab_and_eval(des
, scope
, rval(), use_width
, lv
->lwidth());
1759 if (rv
== 0) return 0;
1763 /* Rewrite delayed assignments as assignments that are
1764 delayed. For example, a = #<d> b; becomes:
1771 If the delay is an event delay, then the transform is
1772 similar, with the event delay replacing the time delay. It
1773 is an event delay if the event_ member has a value.
1775 This rewriting of the expression allows me to not bother to
1776 actually and literally represent the delayed assign in the
1777 netlist. The compound statement is exactly equivalent. */
1779 if (delay
|| event_
) {
1780 unsigned wid
= count_lval_width(lv
);
1783 rv
= pad_to_width(rv
, wid
);
1785 if (wid
> rv
->expr_width()) {
1786 cerr
<< get_fileline() << ": error: Unable to match "
1787 "expression width of " << rv
->expr_width() <<
1788 " to l-value width of " << wid
<< "." << endl
;
1793 NetNet
*tmp
= new NetNet(scope
, scope
->local_symbol(),
1795 tmp
->local_flag(true);
1796 tmp
->set_line(*this);
1797 tmp
->data_type(rv
->expr_type());
1799 NetESignal
*sig
= new NetESignal(tmp
);
1801 /* Generate an assignment of the l-value to the temporary... */
1802 NetAssign_
*lvt
= new NetAssign_(tmp
);
1804 NetAssign
*a1
= new NetAssign(lvt
, rv
);
1805 a1
->set_line(*this);
1807 /* Generate an assignment of the temporary to the r-value... */
1808 NetAssign
*a2
= new NetAssign(lv
, sig
);
1809 a2
->set_line(*this);
1811 /* Generate the delay statement with the final
1812 assignment attached to it. If this is an event delay,
1813 elaborate the PEventStatement. Otherwise, create the
1814 right NetPDelay object. */
1817 st
= event_
->elaborate_st(des
, scope
, a2
);
1819 cerr
<< event_
->get_fileline() << ": error: "
1820 "unable to elaborate event expression."
1828 NetPDelay
*de
= new NetPDelay(delay
, a2
);
1829 de
->set_line(*this);
1833 /* And build up the complex statement. */
1834 NetBlock
*bl
= new NetBlock(NetBlock::SEQU
, 0);
1841 /* Based on the specific type of the l-value, do cleanup
1842 processing on the r-value. */
1843 if (rv
->expr_type() == IVL_VT_REAL
) {
1845 // The r-value is a real. Casting will happen in the
1846 // code generator, so leave it.
1849 unsigned wid
= count_lval_width(lv
);
1851 rv
= pad_to_width(rv
, wid
);
1852 assert(rv
->expr_width() >= wid
);
1855 NetAssign
*cur
= new NetAssign(lv
, rv
);
1856 cur
->set_line(*this);
1862 * Elaborate non-blocking assignments. The statement is of the general
1865 * <lval> <= #<delay> <rval> ;
1867 NetProc
* PAssignNB::elaborate(Design
*des
, NetScope
*scope
) const
1871 if (scope
->in_func()) {
1872 cerr
<< get_fileline() << ": error: functions cannot have non "
1873 "blocking assignment statements." << endl
;
1878 /* Elaborate the l-value. */
1879 NetAssign_
*lv
= elaborate_lval(des
, scope
);
1880 if (lv
== 0) return 0;
1884 /* Elaborate and precalculate the r-value. */
1885 NetExpr
*rv
= elab_and_eval(des
, scope
, rval(), count_lval_width(lv
));
1889 /* Handle the (common) case that the r-value is a vector. This
1890 includes just about everything but reals. In this case, we
1891 need to pad the r-value to match the width of the l-value.
1893 If in this case the l-val is a variable (i.e. real) then
1894 the width to pad to will be 0, so this code is harmless. */
1895 if (rv
->expr_type() == IVL_VT_REAL
) {
1898 unsigned wid
= count_lval_width(lv
);
1900 rv
= pad_to_width(rv
, wid
);
1905 delay
= elaborate_delay_expr(delay_
, des
, scope
);
1907 /* All done with this node. Mark its line number and check it in. */
1908 NetAssignNB
*cur
= new NetAssignNB(lv
, rv
);
1909 cur
->set_delay(delay
);
1910 cur
->set_line(*this);
1916 * This is the elaboration method for a begin-end block. Try to
1917 * elaborate the entire block, even if it fails somewhere. This way I
1918 * get all the error messages out of it. Then, if I detected a failure
1919 * then pass the failure up.
1921 NetProc
* PBlock::elaborate(Design
*des
, NetScope
*scope
) const
1925 NetBlock::Type type
= (bl_type_
==PBlock::BL_PAR
)
1929 NetScope
*nscope
= 0;
1930 if (pscope_name() != 0) {
1931 nscope
= scope
->child(hname_t(pscope_name()));
1933 cerr
<< get_fileline() << ": internal error: "
1934 "unable to find block scope " << scope_path(scope
)
1935 << "<" << pscope_name() << ">" << endl
;
1942 elaborate_behaviors_(des
, nscope
);
1945 NetBlock
*cur
= new NetBlock(type
, nscope
);
1950 // Handle the special case that the block contains only one
1951 // statement. There is no need to keep the block node. Also,
1952 // don't elide named blocks, because they might be referenced
1954 if ((list_
.count() == 1) && (pscope_name() == 0)) {
1956 NetProc
*tmp
= list_
[0]->elaborate(des
, nscope
);
1960 for (unsigned idx
= 0 ; idx
< list_
.count() ; idx
+= 1) {
1962 NetProc
*tmp
= list_
[idx
]->elaborate(des
, nscope
);
1963 // If the statement fails to elaborate, then simply
1964 // ignore it. Presumably, the elaborate for the
1965 // statement already generated an error message and
1966 // marked the error count in the design so no need to
1967 // do any of that here.
1972 // If the result turns out to be a noop, then skip it.
1973 if (NetBlock
*tbl
= dynamic_cast<NetBlock
*>(tmp
))
1974 if (tbl
->proc_first() == 0) {
1986 * Elaborate a case statement.
1988 NetProc
* PCase::elaborate(Design
*des
, NetScope
*scope
) const
1992 NetExpr
*expr
= elab_and_eval(des
, scope
, expr_
, -1);
1994 cerr
<< get_fileline() << ": error: Unable to elaborate this case"
1995 " expression." << endl
;
1999 /* Count the items in the case statement. Note that there may
2000 be some cases that have multiple guards. Count each as a
2002 unsigned icount
= 0;
2003 for (unsigned idx
= 0 ; idx
< items_
->count() ; idx
+= 1) {
2004 PCase::Item
*cur
= (*items_
)[idx
];
2006 if (cur
->expr
.count() == 0)
2009 icount
+= cur
->expr
.count();
2012 NetCase
*res
= new NetCase(type_
, expr
, icount
);
2013 res
->set_line(*this);
2015 /* Iterate over all the case items (guard/statement pairs)
2016 elaborating them. If the guard has no expression, then this
2017 is a "default" cause. Otherwise, the guard has one or more
2018 expressions, and each guard is a case. */
2020 for (unsigned idx
= 0 ; idx
< items_
->count() ; idx
+= 1) {
2022 assert(inum
< icount
);
2023 PCase::Item
*cur
= (*items_
)[idx
];
2025 if (cur
->expr
.count() == 0) {
2026 /* If there are no expressions, then this is the
2030 st
= cur
->stat
->elaborate(des
, scope
);
2032 res
->set_case(inum
, 0, st
);
2035 } else for (unsigned e
= 0; e
< cur
->expr
.count(); e
+= 1) {
2037 /* If there are one or more expressions, then
2038 iterate over the guard expressions, elaborating
2039 a separate case for each. (Yes, the statement
2040 will be elaborated again for each.) */
2043 assert(cur
->expr
[e
]);
2044 gu
= elab_and_eval(des
, scope
, cur
->expr
[e
], -1);
2047 st
= cur
->stat
->elaborate(des
, scope
);
2049 res
->set_case(inum
, gu
, st
);
2057 NetProc
* PCondit::elaborate(Design
*des
, NetScope
*scope
) const
2061 if (debug_elaborate
)
2062 cerr
<< get_fileline() << ": debug: Elaborate condition statement"
2063 << " with conditional: " << *expr_
<< endl
;
2065 // Elaborate and try to evaluate the conditional expression.
2066 NetExpr
*expr
= elab_and_eval(des
, scope
, expr_
, -1);
2068 cerr
<< get_fileline() << ": error: Unable to elaborate"
2069 " condition expression." << endl
;
2074 // If the condition of the conditional statement is constant,
2075 // then look at the value and elaborate either the if statement
2076 // or the else statement. I don't need both. If there is no
2077 // else_ statement, the use an empty block as a noop.
2078 if (NetEConst
*ce
= dynamic_cast<NetEConst
*>(expr
)) {
2079 verinum val
= ce
->value();
2080 if (debug_elaborate
) {
2081 cerr
<< get_fileline() << ": debug: Condition expression "
2082 << "is a constant " << val
<< "." << endl
;
2085 verinum::V reduced
= verinum::V0
;
2086 for (unsigned idx
= 0 ; idx
< val
.len() ; idx
+= 1)
2087 reduced
= reduced
| val
[idx
];
2090 if (reduced
== verinum::V1
)
2092 return if_
->elaborate(des
, scope
);
2094 NetBlock
*tmp
= new NetBlock(NetBlock::SEQU
, 0);
2095 tmp
->set_line(*this);
2099 return else_
->elaborate(des
, scope
);
2101 return new NetBlock(NetBlock::SEQU
, 0);
2104 // If the condition expression is more than 1 bits, then
2105 // generate a comparison operator to get the result down to
2106 // one bit. Turn <e> into <e> != 0;
2108 if (expr
->expr_width() < 1) {
2109 cerr
<< get_fileline() << ": internal error: "
2110 "incomprehensible expression width (0)." << endl
;
2114 // Make sure the condition expression evaluates to a condition.
2115 expr
= condition_reduce(expr
);
2117 // Well, I actually need to generate code to handle the
2118 // conditional, so elaborate.
2119 NetProc
*i
= if_
? if_
->elaborate(des
, scope
) : 0;
2120 NetProc
*e
= else_
? else_
->elaborate(des
, scope
) : 0;
2122 // Detect the special cases that the if or else statements are
2123 // empty blocks. If this is the case, remove the blocks as
2125 if (NetBlock
*tmp
= dynamic_cast<NetBlock
*>(i
)) {
2126 if (tmp
->proc_first() == 0) {
2132 if (NetBlock
*tmp
= dynamic_cast<NetBlock
*>(e
)) {
2133 if (tmp
->proc_first() == 0) {
2139 NetCondit
*res
= new NetCondit(expr
, i
, e
);
2140 res
->set_line(*this);
2144 NetProc
* PCallTask::elaborate(Design
*des
, NetScope
*scope
) const
2146 if (peek_tail_name(path_
)[0] == '$')
2147 return elaborate_sys(des
, scope
);
2149 return elaborate_usr(des
, scope
);
2153 * A call to a system task involves elaborating all the parameters,
2154 * then passing the list to the NetSTask object.
2156 * There is a single special case in the call to a system
2157 * task. Normally, an expression cannot take an unindexed
2158 * memory. However, it is possible to take a system task parameter a
2159 * memory if the expression is trivial.
2161 NetProc
* PCallTask::elaborate_sys(Design
*des
, NetScope
*scope
) const
2165 unsigned parm_count
= nparms();
2167 /* Catch the special case that the system task has no
2168 parameters. The "()" string will be parsed as a single
2169 empty parameter, when we really mean no parameters at all. */
2170 if ((nparms() == 1) && (parm(0) == 0))
2173 svector
<NetExpr
*>eparms (parm_count
);
2175 for (unsigned idx
= 0 ; idx
< parm_count
; idx
+= 1) {
2176 PExpr
*ex
= parm(idx
);
2177 eparms
[idx
] = ex
? ex
->elaborate_expr(des
, scope
, -1, true) : 0;
2179 /* Attempt to pre-evaluate the parameters. It may be
2180 possible to at least partially reduce the
2182 if (eparms
[idx
]) eval_expr(eparms
[idx
]);
2185 NetSTask
*cur
= new NetSTask(peek_tail_name(path_
), eparms
);
2186 cur
->set_line(*this);
2191 * A call to a user defined task is different from a call to a system
2192 * task because a user task in a netlist has no parameters: the
2193 * assignments are done by the calling thread. For example:
2218 NetProc
* PCallTask::elaborate_usr(Design
*des
, NetScope
*scope
) const
2222 if (scope
->in_func()) {
2223 cerr
<< get_fileline() << ": error: functions cannot enable/call "
2229 NetScope
*task
= des
->find_task(scope
, path_
);
2231 cerr
<< get_fileline() << ": error: Enable of unknown task "
2232 << "``" << path_
<< "''." << endl
;
2238 assert(task
->type() == NetScope::TASK
);
2239 NetTaskDef
*def
= task
->task_def();
2241 cerr
<< get_fileline() << ": internal error: task " << path_
2242 << " doesn't have a definition in " << scope_path(scope
)
2249 if (nparms() != def
->port_count()) {
2250 cerr
<< get_fileline() << ": error: Port count mismatch in call to ``"
2251 << path_
<< "''. Got " << nparms()
2252 << " ports, expecting " << def
->port_count() << " ports." << endl
;
2259 /* Handle tasks with no parameters specially. There is no need
2260 to make a sequential block to hold the generated code. */
2261 if (nparms() == 0) {
2262 cur
= new NetUTask(task
);
2263 cur
->set_line(*this);
2267 NetBlock
*block
= new NetBlock(NetBlock::SEQU
, 0);
2270 /* Detect the case where the definition of the task is known
2271 empty. In this case, we need not bother with calls to the
2272 task, all the assignments, etc. Just return a no-op. */
2274 if (const NetBlock
*tp
= dynamic_cast<const NetBlock
*>(def
->proc())) {
2275 if (tp
->proc_first() == 0)
2279 /* Generate assignment statement statements for the input and
2280 INOUT ports of the task. These are managed by writing
2281 assignments with the task port the l-value and the passed
2282 expression the r-value. We know by definition that the port
2283 is a reg type, so this elaboration is pretty obvious. */
2285 for (unsigned idx
= 0 ; idx
< nparms() ; idx
+= 1) {
2287 NetNet
*port
= def
->port(idx
);
2288 assert(port
->port_type() != NetNet::NOT_A_PORT
);
2289 if (port
->port_type() == NetNet::POUTPUT
)
2292 NetAssign_
*lv
= new NetAssign_(port
);
2293 unsigned wid
= count_lval_width(lv
);
2295 NetExpr
*rv
= elab_and_eval(des
, scope
, parms_
[idx
], wid
);
2297 rv
= pad_to_width(rv
, wid
);
2298 NetAssign
*pr
= new NetAssign(lv
, rv
);
2302 /* Generate the task call proper... */
2303 cur
= new NetUTask(task
);
2304 cur
->set_line(*this);
2308 /* Generate assignment statements for the output and INOUT
2309 ports of the task. The l-value in this case is the
2310 expression passed as a parameter, and the r-value is the
2311 port to be copied out.
2313 We know by definition that the r-value of this copy-out is
2314 the port, which is a reg. The l-value, however, may be any
2315 expression that can be a target to a procedural
2316 assignment, including a memory word. */
2318 for (unsigned idx
= 0 ; idx
< nparms() ; idx
+= 1) {
2320 NetNet
*port
= def
->port(idx
);
2322 /* Skip input ports. */
2323 assert(port
->port_type() != NetNet::NOT_A_PORT
);
2324 if (port
->port_type() == NetNet::PINPUT
)
2328 /* Elaborate an l-value version of the port expression
2329 for output and inout ports. If the expression does
2330 not exist then quietly skip it, but if the expression
2331 is not a valid l-value print an error message. Note
2332 that the elaborate_lval method already printed a
2333 detailed message. */
2336 lv
= parms_
[idx
]->elaborate_lval(des
, scope
, false);
2338 cerr
<< parms_
[idx
]->get_fileline() << ": error: "
2339 << "I give up on task port " << (idx
+1)
2340 << " expression: " << *parms_
[idx
] << endl
;
2349 NetESignal
*sig
= new NetESignal(port
);
2350 NetExpr
*rv
= pad_to_width(sig
, count_lval_width(lv
));
2352 /* Generate the assignment statement. */
2353 NetAssign
*ass
= new NetAssign(lv
, rv
);
2362 * Elaborate a procedural continuous assign. This really looks very
2363 * much like other procedural assignments, at this point, but there
2364 * is no delay to worry about. The code generator will take care of
2365 * the differences between continuous assign and normal assignments.
2367 NetCAssign
* PCAssign::elaborate(Design
*des
, NetScope
*scope
) const
2372 NetAssign_
*lval
= lval_
->elaborate_lval(des
, scope
, false);
2376 unsigned lwid
= count_lval_width(lval
);
2378 NetExpr
*rexp
= elab_and_eval(des
, scope
, expr_
, lwid
);
2382 rexp
->set_width(lwid
);
2383 rexp
= pad_to_width(rexp
, lwid
);
2385 dev
= new NetCAssign(lval
, rexp
);
2387 if (debug_elaborate
) {
2388 cerr
<< get_fileline() << ": debug: Elaborate cassign,"
2389 << " lval width=" << lwid
2390 << " rval width=" << rexp
->expr_width()
2391 << " rval=" << *rexp
2395 dev
->set_line(*this);
2399 NetDeassign
* PDeassign::elaborate(Design
*des
, NetScope
*scope
) const
2403 NetAssign_
*lval
= lval_
->elaborate_lval(des
, scope
, false);
2407 NetDeassign
*dev
= new NetDeassign(lval
);
2408 dev
->set_line( *this );
2413 * Elaborate the delay statement (of the form #<expr> <statement>) as a
2414 * NetPDelay object. If the expression is constant, evaluate it now
2415 * and make a constant delay. If not, then pass an elaborated
2416 * expression to the constructor of NetPDelay so that the code
2417 * generator knows to evaluate the expression at run time.
2419 NetProc
* PDelayStatement::elaborate(Design
*des
, NetScope
*scope
) const
2423 if (scope
->in_func()) {
2424 cerr
<< get_fileline() << ": error: functions cannot have "
2425 "delay statements." << endl
;
2430 /* This call evaluates the delay expression to a NetEConst, if
2431 possible. This includes transforming NetECReal values to
2432 integers, and applying the proper scaling. */
2433 NetExpr
*dex
= elaborate_delay_expr(delay_
, des
, scope
);
2435 if (NetEConst
*tmp
= dynamic_cast<NetEConst
*>(dex
)) {
2437 return new NetPDelay(tmp
->value().as_ulong64(),
2438 statement_
->elaborate(des
, scope
));
2440 return new NetPDelay(tmp
->value().as_ulong(), 0);
2446 return new NetPDelay(dex
, statement_
->elaborate(des
, scope
));
2448 return new NetPDelay(dex
, 0);
2454 * The disable statement is not yet supported.
2456 NetProc
* PDisable::elaborate(Design
*des
, NetScope
*scope
) const
2460 list
<hname_t
> spath
= eval_scope_path(des
, scope
, scope_
);
2462 NetScope
*target
= des
->find_scope(scope
, spath
);
2464 cerr
<< get_fileline() << ": error: Cannot find scope "
2465 << scope_
<< " in " << scope_path(scope
) << endl
;
2470 switch (target
->type()) {
2471 case NetScope::FUNC
:
2472 cerr
<< get_fileline() << ": error: Cannot disable functions." << endl
;
2476 case NetScope::MODULE
:
2477 cerr
<< get_fileline() << ": error: Cannot disable modules." << endl
;
2485 NetDisable
*obj
= new NetDisable(target
);
2486 obj
->set_line(*this);
2491 * An event statement is an event delay of some sort, attached to a
2492 * statement. Some Verilog examples are:
2494 * @(posedge CLK) $display("clock rise");
2495 * @event_1 $display("event triggered.");
2496 * @(data or negedge clk) $display("data or clock fall.");
2498 * The elaborated netlist uses the NetEvent, NetEvWait and NetEvProbe
2499 * classes. The NetEvWait class represents the part of the netlist
2500 * that is executed by behavioral code. The process starts waiting on
2501 * the NetEvent when it executes the NetEvWait step. Net NetEvProbe
2502 * and NetEvTrig are structural and behavioral equivalents that
2503 * trigger the event, and awakens any processes blocking in the
2506 * The basic data structure is:
2508 * NetEvWait ---/---> NetEvent <----\---- NetEvProbe
2510 * NetEvWait ---+ +---- NetEvProbe
2514 * That is, many NetEvWait statements may wait on a single NetEvent
2515 * object, and Many NetEvProbe objects may trigger the NetEvent
2516 * object. The many NetEvWait objects pointing to the NetEvent object
2517 * reflects the possibility of different places in the code blocking
2518 * on the same named event, like so:
2522 * always begin @foo <statement1>; @foo <statement2> end
2524 * This tends to not happen with signal edges. The multiple probes
2525 * pointing to the same event reflect the possibility of many
2526 * expressions in the same blocking statement, like so:
2530 * always @(reset or posedge clk) <stmt>;
2532 * Conjunctions like this cause a NetEvent object be created to
2533 * represent the overall conjunction, and NetEvProbe objects for each
2536 * If the NetEvent object represents a named event from the source,
2537 * then there are NetEvTrig objects that represent the trigger
2538 * statements instead of the NetEvProbe objects representing signals.
2542 * always @foo <stmt>;
2551 * Each trigger statement in the source generates a separate NetEvTrig
2552 * object in the netlist. Those trigger objects are elaborated
2555 * Additional complications arise when named events show up in
2556 * conjunctions. An example of such a case is:
2560 * always @(foo or posedge bar) <stmt>;
2562 * Since there is by definition a NetEvent object for the foo object,
2563 * this is handled by allowing the NetEvWait object to point to
2564 * multiple NetEvent objects. All the NetEvProbe based objects are
2565 * collected and pointed as the synthetic NetEvent object, and all the
2566 * named events are added into the list of NetEvent object that the
2567 * NetEvWait object can refer to.
2570 NetProc
* PEventStatement::elaborate_st(Design
*des
, NetScope
*scope
,
2575 if (scope
->in_func()) {
2576 cerr
<< get_fileline() << ": error: functions cannot have "
2577 "event statements." << endl
;
2582 /* Create a single NetEvent and NetEvWait. Then, create a
2583 NetEvProbe for each conjunctive event in the event
2584 list. The NetEvProbe objects all refer back to the NetEvent
2587 NetEvent
*ev
= new NetEvent(scope
->local_symbol());
2588 ev
->set_line(*this);
2589 unsigned expr_count
= 0;
2591 NetEvWait
*wa
= new NetEvWait(enet
);
2592 wa
->set_line(*this);
2594 /* If there are no expressions, this is a signal that it is an
2595 @* statement. Generate an expression to use. */
2597 if (expr_
.count() == 0) {
2599 /* For synthesis we want just the inputs, but for the rest we
2600 * want inputs and outputs that may cause a value to change. */
2601 extern bool synthesis
; /* Synthesis flag from main.cc */
2602 bool rem_out
= false;
2606 NexusSet
*nset
= enet
->nex_input(rem_out
);
2608 cerr
<< get_fileline() << ": internal error: No NexusSet"
2609 << " from statement." << endl
;
2610 enet
->dump(cerr
, 6);
2615 if (nset
->count() == 0) {
2616 cerr
<< get_fileline() << ": error: No inputs to statement."
2617 << " The @* cannot execute." << endl
;
2622 NetEvProbe
*pr
= new NetEvProbe(scope
, scope
->local_symbol(),
2623 ev
, NetEvProbe::ANYEDGE
,
2625 for (unsigned idx
= 0 ; idx
< nset
->count() ; idx
+= 1)
2626 connect(nset
[0][idx
], pr
->pin(idx
));
2633 } else for (unsigned idx
= 0 ; idx
< expr_
.count() ; idx
+= 1) {
2635 assert(expr_
[idx
]->expr());
2637 /* If the expression is an identifier that matches a
2638 named event, then handle this case all at once at
2639 skip the rest of the expression handling. */
2641 if (PEIdent
*id
= dynamic_cast<PEIdent
*>(expr_
[idx
]->expr())) {
2643 const NetExpr
*par
= 0;
2646 NetScope
*found_in
= symbol_search(des
, scope
, id
->path(),
2649 if (found_in
&& eve
) {
2656 /* So now we have a normal event expression. Elaborate
2657 the sub-expression as a net and decide how to handle
2660 bool save_flag
= error_implicit
;
2661 error_implicit
= true;
2662 NetNet
*expr
= expr_
[idx
]->expr()->elaborate_net(des
, scope
,
2664 error_implicit
= save_flag
;
2666 expr_
[idx
]->dump(cerr
);
2673 unsigned pins
= (expr_
[idx
]->type() == PEEvent::ANYEDGE
)
2674 ? expr
->pin_count() : 1;
2677 switch (expr_
[idx
]->type()) {
2678 case PEEvent::POSEDGE
:
2679 pr
= new NetEvProbe(scope
, scope
->local_symbol(), ev
,
2680 NetEvProbe::POSEDGE
, pins
);
2683 case PEEvent::NEGEDGE
:
2684 pr
= new NetEvProbe(scope
, scope
->local_symbol(), ev
,
2685 NetEvProbe::NEGEDGE
, pins
);
2688 case PEEvent::ANYEDGE
:
2689 pr
= new NetEvProbe(scope
, scope
->local_symbol(), ev
,
2690 NetEvProbe::ANYEDGE
, pins
);
2697 for (unsigned p
= 0 ; p
< pr
->pin_count() ; p
+= 1)
2698 connect(pr
->pin(p
), expr
->pin(p
));
2704 /* If there was at least one conjunction that was an
2705 expression (and not a named event) then add this
2706 event. Otherwise, we didn't use it so delete it. */
2707 if (expr_count
> 0) {
2708 scope
->add_event(ev
);
2710 /* NOTE: This event that I am adding to the wait may be
2711 a duplicate of another event somewhere else. However,
2712 I don't know that until all the modules are hooked
2713 up, so it is best to leave find_similar_event to
2714 after elaboration. */
2723 * This is the special case of the event statement, the wait
2724 * statement. This is elaborated into a slightly more complicated
2725 * statement that uses non-wait statements:
2727 * wait (<expr>) <statement>
2732 * while (1 !== <expr>)
2733 * @(<expr inputs>) <noop>;
2737 NetProc
* PEventStatement::elaborate_wait(Design
*des
, NetScope
*scope
,
2741 assert(expr_
.count() == 1);
2743 if (scope
->in_func()) {
2744 cerr
<< get_fileline() << ": error: functions cannot have "
2745 "wait statements." << endl
;
2750 const PExpr
*pe
= expr_
[0]->expr();
2752 /* Elaborate wait expression. Don't eval yet, we will do that
2753 shortly, after we apply a reduction or. */
2754 NetExpr
*expr
= pe
->elaborate_expr(des
, scope
, -1, false);
2756 cerr
<< get_fileline() << ": error: Unable to elaborate"
2757 " wait condition expression." << endl
;
2762 // If the condition expression is more than 1 bits, then
2763 // generate a reduction operator to get the result down to
2764 // one bit. In other words, Turn <e> into |<e>;
2766 if (expr
->expr_width() < 1) {
2767 cerr
<< get_fileline() << ": internal error: "
2768 "incomprehensible wait expression width (0)." << endl
;
2772 if (expr
->expr_width() > 1) {
2773 assert(expr
->expr_width() > 1);
2774 NetEUReduce
*cmp
= new NetEUReduce('|', expr
);
2778 /* precalculate as much as possible of the wait expression. */
2781 /* Detect the unusual case that the wait expression is
2782 constant. Constant true is OK (it becomes transparent) but
2783 constant false is almost certainly not what is intended. */
2784 assert(expr
->expr_width() == 1);
2785 if (NetEConst
*ce
= dynamic_cast<NetEConst
*>(expr
)) {
2786 verinum val
= ce
->value();
2787 assert(val
.len() == 1);
2789 /* Constant true -- wait(1) <s1> reduces to <s1>. */
2790 if (val
[0] == verinum::V1
) {
2796 /* Otherwise, false. wait(0) blocks permanently. */
2798 cerr
<< get_fileline() << ": warning: wait expression is "
2799 << "constant false." << endl
;
2800 cerr
<< get_fileline() << ": : The statement will "
2801 << "block permanently." << endl
;
2803 /* Create an event wait and an otherwise unreferenced
2804 event variable to force a perpetual wait. */
2805 NetEvent
*wait_event
= new NetEvent(scope
->local_symbol());
2806 scope
->add_event(wait_event
);
2808 NetEvWait
*wait
= new NetEvWait(0);
2809 wait
->add_event(wait_event
);
2810 wait
->set_line(*this);
2817 /* Invert the sense of the test with an exclusive NOR. In
2818 other words, if this adjusted expression returns TRUE, then
2820 assert(expr
->expr_width() == 1);
2821 expr
= new NetEBComp('N', expr
, new NetEConst(verinum(verinum::V1
)));
2824 NetEvent
*wait_event
= new NetEvent(scope
->local_symbol());
2825 scope
->add_event(wait_event
);
2827 NetEvWait
*wait
= new NetEvWait(0 /* noop */);
2828 wait
->add_event(wait_event
);
2829 wait
->set_line(*this);
2831 NexusSet
*wait_set
= expr
->nex_input();
2832 if (wait_set
== 0) {
2833 cerr
<< get_fileline() << ": internal error: No NexusSet"
2834 << " from wait expression." << endl
;
2839 if (wait_set
->count() == 0) {
2840 cerr
<< get_fileline() << ": internal error: Empty NexusSet"
2841 << " from wait expression." << endl
;
2846 NetEvProbe
*wait_pr
= new NetEvProbe(scope
, scope
->local_symbol(),
2847 wait_event
, NetEvProbe::ANYEDGE
,
2849 for (unsigned idx
= 0; idx
< wait_set
->count() ; idx
+= 1)
2850 connect(wait_set
[0][idx
], wait_pr
->pin(idx
));
2853 des
->add_node(wait_pr
);
2855 NetWhile
*loop
= new NetWhile(expr
, wait
);
2856 loop
->set_line(*this);
2858 /* If there is no real substatement (i.e., "wait (foo) ;") then
2863 /* Create a sequential block to combine the wait loop and the
2864 delayed statement. */
2865 NetBlock
*block
= new NetBlock(NetBlock::SEQU
, 0);
2866 block
->append(loop
);
2867 block
->append(enet
);
2868 block
->set_line(*this);
2874 NetProc
* PEventStatement::elaborate(Design
*des
, NetScope
*scope
) const
2878 enet
= statement_
->elaborate(des
, scope
);
2883 enet
= new NetBlock(NetBlock::SEQU
, 0);
2884 enet
->set_line(*this);
2887 if ((expr_
.count() == 1) && (expr_
[0]->type() == PEEvent::POSITIVE
))
2888 return elaborate_wait(des
, scope
, enet
);
2890 return elaborate_st(des
, scope
, enet
);
2894 * Forever statements are represented directly in the netlist. It is
2895 * theoretically possible to use a while structure with a constant
2896 * expression to represent the loop, but why complicate the code
2899 NetProc
* PForever::elaborate(Design
*des
, NetScope
*scope
) const
2901 NetProc
*stat
= statement_
->elaborate(des
, scope
);
2902 if (stat
== 0) return 0;
2904 NetForever
*proc
= new NetForever(stat
);
2909 * Force is like a procedural assignment, most notably procedural
2910 * continuous assignment:
2912 * force <lval> = <rval>
2914 * The <lval> can be anything that a normal behavioral assignment can
2915 * take, plus net signals. This is a little bit more lax then the
2916 * other procedural assignments.
2918 NetForce
* PForce::elaborate(Design
*des
, NetScope
*scope
) const
2923 NetAssign_
*lval
= lval_
->elaborate_lval(des
, scope
, true);
2927 unsigned lwid
= count_lval_width(lval
);
2929 NetExpr
*rexp
= elab_and_eval(des
, scope
, expr_
, lwid
);
2933 rexp
->set_width(lwid
, true);
2934 rexp
= pad_to_width(rexp
, lwid
);
2936 dev
= new NetForce(lval
, rexp
);
2938 if (debug_elaborate
) {
2939 cerr
<< get_fileline() << ": debug: ELaborate force,"
2940 << " lval width=" << lval
->lwidth()
2941 << " rval width=" << rexp
->expr_width()
2942 << " rval=" << *rexp
2946 dev
->set_line(*this);
2951 * elaborate the for loop as the equivalent while loop. This eases the
2952 * task for the target code generator. The structure is:
2956 * while (cond_) begin : body
2962 NetProc
* PForStatement::elaborate(Design
*des
, NetScope
*scope
) const
2967 const PEIdent
*id1
= dynamic_cast<const PEIdent
*>(name1_
);
2969 const PEIdent
*id2
= dynamic_cast<const PEIdent
*>(name2_
);
2972 NetBlock
*top
= new NetBlock(NetBlock::SEQU
, 0);
2973 top
->set_line(*this);
2975 /* make the expression, and later the initial assignment to
2976 the condition variable. The statement in the for loop is
2977 very specifically an assignment. */
2978 NetNet
*sig
= des
->find_signal(scope
, id1
->path());
2980 cerr
<< id1
->get_fileline() << ": register ``" << id1
->path()
2981 << "'' unknown in " << scope_path(scope
) << "." << endl
;
2986 NetAssign_
*lv
= new NetAssign_(sig
);
2988 /* Calculate the width of the initialization as if this were
2989 any other assignment statement. */
2990 unsigned use_width
= lv
->lwidth();
2991 bool unsized_flag
= false;
2992 use_width
= expr1_
->test_width(des
, scope
, use_width
, use_width
, unsized_flag
);
2994 /* Make the r-value of the initial assignment, and size it
2995 properly. Then use it to build the assignment statement. */
2996 etmp
= elab_and_eval(des
, scope
, expr1_
, use_width
);
2997 etmp
->set_width(use_width
);
2998 etmp
= pad_to_width(etmp
, use_width
);
3000 if (debug_elaborate
) {
3001 cerr
<< get_fileline() << ": debug: FOR initial assign: "
3002 << sig
->name() << " = " << *etmp
<< endl
;
3003 assert(etmp
->expr_width() >= lv
->lwidth());
3006 /* Based on the specific type of the l-value, do cleanup
3007 processing on the r-value. */
3008 if (etmp
->expr_type() != IVL_VT_REAL
) {
3009 unsigned wid
= count_lval_width(lv
);
3010 etmp
->set_width(wid
);
3011 etmp
= pad_to_width(etmp
, wid
);
3012 assert(etmp
->expr_width() >= wid
);
3015 NetAssign
*init
= new NetAssign(lv
, etmp
);
3016 init
->set_line(*this);
3020 NetBlock
*body
= new NetBlock(NetBlock::SEQU
, 0);
3021 body
->set_line(*this);
3023 /* Elaborate the statement that is contained in the for
3024 loop. If there is an error, this will return 0 and I should
3025 skip the append. No need to worry, the error has been
3026 reported so it's OK that the netlist is bogus. */
3027 NetProc
*tmp
= statement_
->elaborate(des
, scope
);
3032 /* Elaborate the increment assignment statement at the end of
3033 the for loop. This is also a very specific assignment
3034 statement. Put this into the "body" block. */
3035 sig
= des
->find_signal(scope
, id2
->path());
3037 cerr
<< get_fileline() << ": error: Unable to find variable "
3038 << id2
->path() << " in for-loop increment expressin." << endl
;
3044 lv
= new NetAssign_(sig
);
3046 /* Make the rvalue of the increment expression, and size it
3048 etmp
= elab_and_eval(des
, scope
, expr2_
, lv
->lwidth());
3049 NetAssign
*step
= new NetAssign(lv
, etmp
);
3050 step
->set_line(*this);
3055 /* Elaborate the condition expression. Try to evaluate it too,
3056 in case it is a constant. This is an interesting case
3057 worthy of a warning. */
3058 NetExpr
*ce
= elab_and_eval(des
, scope
, cond_
, -1);
3064 if (dynamic_cast<NetEConst
*>(ce
)) {
3065 cerr
<< get_fileline() << ": warning: condition expression "
3066 "of for-loop is constant." << endl
;
3070 /* All done, build up the loop. */
3072 NetWhile
*loop
= new NetWhile(ce
, body
);
3073 loop
->set_line(*this);
3079 * (See the PTask::elaborate methods for basic common stuff.)
3081 * The return value of a function is represented as a reg variable
3082 * within the scope of the function that has the name of the
3083 * function. So for example with the function:
3085 * function [7:0] incr;
3090 * The scope of the function is <parent>.incr and there is a reg
3091 * variable <parent>.incr.incr. The elaborate_1 method is called with
3092 * the scope of the function, so the return reg is easily located.
3094 * The function parameters are all inputs, except for the synthetic
3095 * output parameter that is the return value. The return value goes
3096 * into port 0, and the parameters are all the remaining ports.
3099 void PFunction::elaborate(Design
*des
, NetScope
*scope
) const
3101 NetFuncDef
*def
= scope
->func_def();
3103 cerr
<< get_fileline() << ": internal error: "
3104 << "No function definition for function "
3105 << scope_path(scope
) << endl
;
3112 NetProc
*st
= statement_
->elaborate(des
, scope
);
3114 cerr
<< statement_
->get_fileline() << ": error: Unable to elaborate "
3115 "statement in function " << scope
->basename() << "." << endl
;
3123 NetProc
* PRelease::elaborate(Design
*des
, NetScope
*scope
) const
3127 NetAssign_
*lval
= lval_
->elaborate_lval(des
, scope
, true);
3131 NetRelease
*dev
= new NetRelease(lval
);
3132 dev
->set_line( *this );
3136 NetProc
* PRepeat::elaborate(Design
*des
, NetScope
*scope
) const
3140 NetExpr
*expr
= elab_and_eval(des
, scope
, expr_
, -1);
3142 cerr
<< get_fileline() << ": Unable to elaborate"
3143 " repeat expression." << endl
;
3148 NetProc
*stat
= statement_
->elaborate(des
, scope
);
3149 if (stat
== 0) return 0;
3151 // If the expression is a constant, handle certain special
3152 // iteration counts.
3153 if (NetEConst
*ce
= dynamic_cast<NetEConst
*>(expr
)) {
3154 verinum val
= ce
->value();
3155 switch (val
.as_ulong()) {
3159 return new NetBlock(NetBlock::SEQU
, 0);
3168 NetRepeat
*proc
= new NetRepeat(expr
, stat
);
3173 * A task definition is elaborated by elaborating the statement that
3174 * it contains, and connecting its ports to NetNet objects. The
3175 * netlist doesn't really need the array of parameters once elaboration
3176 * is complete, but this is the best place to store them.
3178 * The first elaboration pass finds the reg objects that match the
3179 * port names, and creates the NetTaskDef object. The port names are
3180 * in the form task.port.
3187 * So in the foo example, the PWire objects that represent the ports
3188 * of the task will include a foo.blah for the blah port. This port is
3189 * bound to a NetNet object by looking up the name. All of this is
3190 * handled by the PTask::elaborate_sig method and the results stashed
3191 * in the created NetTaskDef attached to the scope.
3193 * Elaboration pass 2 for the task definition causes the statement of
3194 * the task to be elaborated and attached to the NetTaskDef object
3195 * created in pass 1.
3197 * NOTE: I am not sure why I bothered to prepend the task name to the
3198 * port name when making the port list. It is not really useful, but
3199 * that is what I did in pform_make_task_ports, so there it is.
3202 void PTask::elaborate(Design
*des
, NetScope
*task
) const
3204 // Elaborate any processes that are part of this scope that
3205 // aren't the definition itself. This can happen, for example,
3206 // with variable initialization statements in this scope.
3207 elaborate_behaviors_(des
, task
);
3209 NetTaskDef
*def
= task
->task_def();
3213 if (statement_
== 0) {
3214 st
= new NetBlock(NetBlock::SEQU
, 0);
3218 st
= statement_
->elaborate(des
, task
);
3220 cerr
<< statement_
->get_fileline() << ": Unable to elaborate "
3221 "statement in task " << scope_path(task
)
3222 << " at " << get_fileline() << "." << endl
;
3230 NetProc
* PTrigger::elaborate(Design
*des
, NetScope
*scope
) const
3235 const NetExpr
*par
= 0;
3238 NetScope
*found_in
= symbol_search(des
, scope
, event_
,
3241 if (found_in
== 0) {
3242 cerr
<< get_fileline() << ": error: event <" << event_
<< ">"
3243 << " not found." << endl
;
3249 cerr
<< get_fileline() << ": error: <" << event_
<< ">"
3250 << " is not a named event." << endl
;
3255 NetEvTrig
*trig
= new NetEvTrig(eve
);
3256 trig
->set_line(*this);
3261 * The while loop is fairly directly represented in the netlist.
3263 NetProc
* PWhile::elaborate(Design
*des
, NetScope
*scope
) const
3265 NetWhile
*loop
= new NetWhile(elab_and_eval(des
, scope
, cond_
, -1),
3266 statement_
->elaborate(des
, scope
));
3270 bool PProcess::elaborate(Design
*des
, NetScope
*scope
) const
3272 NetProc
*cur
= statement_
->elaborate(des
, scope
);
3279 case PProcess::PR_INITIAL
:
3280 top
= new NetProcTop(scope
, NetProcTop::KINITIAL
, cur
);
3282 case PProcess::PR_ALWAYS
:
3283 top
= new NetProcTop(scope
, NetProcTop::KALWAYS
, cur
);
3286 ivl_assert(*this, top
);
3288 // Evaluate the attributes for this process, if there
3289 // are any. These attributes are to be attached to the
3290 // NetProcTop object.
3291 struct attrib_list_t
*attrib_list
= 0;
3292 unsigned attrib_list_n
= 0;
3293 attrib_list
= evaluate_attributes(attributes
, attrib_list_n
, des
, scope
);
3295 for (unsigned adx
= 0 ; adx
< attrib_list_n
; adx
+= 1)
3296 top
->attribute(attrib_list
[adx
].key
,
3297 attrib_list
[adx
].val
);
3299 delete[]attrib_list
;
3301 top
->set_line(*this);
3302 des
->add_process(top
);
3304 /* Detect the special case that this is a combinational
3305 always block. We want to attach an _ivl_schedule_push
3306 attribute to this process so that it starts up and
3307 gets into its wait statement before non-combinational
3308 code is executed. */
3310 if (top
->type() != NetProcTop::KALWAYS
)
3313 NetEvWait
*st
= dynamic_cast<NetEvWait
*>(top
->statement());
3317 if (st
->nevents() != 1)
3320 NetEvent
*ev
= st
->event(0);
3322 if (ev
->nprobe() == 0)
3325 bool anyedge_test
= true;
3326 for (unsigned idx
= 0 ; anyedge_test
&& (idx
<ev
->nprobe())
3328 const NetEvProbe
*pr
= ev
->probe(idx
);
3329 if (pr
->edge() != NetEvProbe::ANYEDGE
)
3330 anyedge_test
= false;
3336 top
->attribute(perm_string::literal("_ivl_schedule_push"),
3340 /* If this is an always block and we have no or zero delay then
3341 * a runtime infinite loop will happen. If we possible have some
3342 * delay then print a warning that an infinite loop is possible.
3344 if (type() == PProcess::PR_ALWAYS
) {
3345 DelayType dly_type
= top
->statement()->delay_type();
3347 if (dly_type
== NO_DELAY
|| dly_type
== ZERO_DELAY
) {
3348 cerr
<< get_fileline() << ": error: always statement"
3349 << " does not have any delay." << endl
;
3350 cerr
<< get_fileline() << ": : A runtime infinite"
3351 << " loop will occur." << endl
;
3355 } else if (dly_type
== POSSIBLE_DELAY
&& warn_inf_loop
) {
3356 cerr
<< get_fileline() << ": warning: always statement"
3357 << " may not have any delay." << endl
;
3358 cerr
<< get_fileline() << ": : A runtime infinite"
3359 << " loop may be possible." << endl
;
3366 void PSpecPath::elaborate(Design
*des
, NetScope
*scope
) const
3368 uint64_t delay_value
[12];
3369 unsigned ndelays
= 0;
3371 /* Do not elaborate specify delay paths if this feature is
3373 if (!gn_specify_blocks_flag
)
3376 ivl_assert(*this, conditional
|| (condition
==0));
3378 ndelays
= delays
.size();
3382 int shift
= scope
->time_unit() - des
->get_precision();
3384 /* Elaborate the delay values themselves. Remember to scale
3385 them for the timescale/precision of the scope. */
3386 for (unsigned idx
= 0 ; idx
< ndelays
; idx
+= 1) {
3387 PExpr
*exp
= delays
[idx
];
3388 NetExpr
*cur
= elab_and_eval(des
, scope
, exp
, 0);
3390 if (NetEConst
*cur_con
= dynamic_cast<NetEConst
*> (cur
)) {
3391 delay_value
[idx
] = cur_con
->value().as_ulong();
3392 for (int tmp
= 0 ; tmp
< shift
; tmp
+= 1)
3393 delay_value
[idx
] *= 10;
3395 } else if (NetECReal
*cur_rcon
= dynamic_cast<NetECReal
*>(cur
)) {
3396 delay_value
[idx
] = cur_rcon
->value().as_long(shift
);
3399 cerr
<< get_fileline() << ": error: Path delay value "
3400 << "must be constant." << endl
;
3401 delay_value
[idx
] = 0;
3407 switch (delays
.size()) {
3415 cerr
<< get_fileline() << ": error: Incorrect delay configuration."
3416 << " Given " << delays
.size() << " delay expressions." << endl
;
3422 NetNet
*condit_sig
= 0;
3423 if (conditional
&& condition
) {
3425 NetExpr
*tmp
= elab_and_eval(des
, scope
, condition
, -1);
3426 ivl_assert(*condition
, tmp
);
3428 // FIXME: Look for constant expressions here?
3431 condit_sig
= tmp
->synthesize(des
);
3432 ivl_assert(*condition
, condit_sig
);
3435 /* Create all the various paths from the path specifier. */
3436 typedef std::vector
<perm_string
>::const_iterator str_vector_iter
;
3437 for (str_vector_iter cur
= dst
.begin()
3438 ; cur
!= dst
.end() ; cur
++) {
3440 if (debug_elaborate
) {
3441 cerr
<< get_fileline() << ": debug: Path to " << (*cur
);
3443 cerr
<< " if " << condit_sig
->name();
3444 else if (conditional
)
3449 NetNet
*dst_sig
= scope
->find_signal(*cur
);
3451 cerr
<< get_fileline() << ": error: No such wire "
3452 << *cur
<< " in this module." << endl
;
3457 if (dst_sig
->port_type() != NetNet::POUTPUT
3458 && dst_sig
->port_type() != NetNet::PINOUT
) {
3460 cerr
<< get_fileline() << ": error: Path destination "
3461 << *cur
<< " must be an output or inout port." << endl
;
3465 NetDelaySrc
*path
= new NetDelaySrc(scope
, scope
->local_symbol(),
3466 src
.size(), condit_sig
,
3468 path
->set_line(*this);
3470 // The presence of the data_source_expression indicates
3471 // that this is an edge sensitive path. If so, then set
3472 // the edges. Note that edge==0 is BOTH edges.
3473 if (data_source_expression
) {
3474 if (edge
>= 0) path
->set_posedge();
3475 if (edge
<= 0) path
->set_negedge();
3480 path
->set_delays(delay_value
[0], delay_value
[1],
3481 delay_value
[2], delay_value
[3],
3482 delay_value
[4], delay_value
[5],
3483 delay_value
[6], delay_value
[7],
3484 delay_value
[8], delay_value
[9],
3485 delay_value
[10], delay_value
[11]);
3488 path
->set_delays(delay_value
[0], delay_value
[1],
3489 delay_value
[2], delay_value
[3],
3490 delay_value
[4], delay_value
[5]);
3493 path
->set_delays(delay_value
[0], delay_value
[1],
3497 path
->set_delays(delay_value
[0], delay_value
[1]);
3500 path
->set_delays(delay_value
[0]);
3505 for (str_vector_iter cur_src
= src
.begin()
3506 ; cur_src
!= src
.end() ; cur_src
++) {
3507 NetNet
*src_sig
= scope
->find_signal(*cur_src
);
3510 if (debug_elaborate
) {
3511 if (cur_src
!= src
.begin()) cerr
<< " and ";
3512 cerr
<< src_sig
->name();
3515 if ( (src_sig
->port_type() != NetNet::PINPUT
)
3516 && (src_sig
->port_type() != NetNet::PINOUT
) ) {
3518 cerr
<< get_fileline() << ": error: Path source "
3519 << *cur_src
<< " must be an input or inout port."
3524 connect(src_sig
->pin(0), path
->pin(idx
));
3527 if (debug_elaborate
) {
3532 connect(condit_sig
->pin(0), path
->pin(idx
));
3534 dst_sig
->add_delay_path(path
);
3540 * When a module is instantiated, it creates the scope then uses this
3541 * method to elaborate the contents of the module.
3543 bool Module::elaborate(Design
*des
, NetScope
*scope
) const
3545 bool result_flag
= true;
3547 if (gn_specify_blocks_flag
) {
3548 // Elaborate specparams
3549 typedef map
<perm_string
,PExpr
*>::const_iterator specparam_it_t
;
3550 for (specparam_it_t cur
= specparams
.begin()
3551 ; cur
!= specparams
.end() ; cur
++ ) {
3553 NetExpr
*val
= elab_and_eval(des
, scope
, (*cur
).second
, -1);
3554 NetScope::spec_val_t value
;
3556 if (NetECReal
*val_c
= dynamic_cast<NetECReal
*> (val
)) {
3558 value
.type
= IVL_VT_REAL
;
3559 value
.real_val
= val_c
->value().as_double();
3561 if (debug_elaborate
)
3562 cerr
<< get_fileline() << ": debug: Elaborate "
3563 << "specparam " << (*cur
).first
3564 << " value=" << value
.real_val
<< endl
;
3566 } else if (NetEConst
*val_c
= dynamic_cast<NetEConst
*> (val
)) {
3568 value
.type
= IVL_VT_BOOL
;
3569 value
.integer
= val_c
->value().as_long();
3571 if (debug_elaborate
)
3572 cerr
<< get_fileline() << ": debug: Elaborate "
3573 << "specparam " << (*cur
).first
3574 << " value=" << value
.integer
<< endl
;
3577 value
.type
= IVL_VT_NO_TYPE
;
3578 cerr
<< (*cur
).second
->get_fileline() << ": error: "
3579 << "specparam " << (*cur
).first
<< " value"
3580 << " is not constant: " << *val
<< endl
;
3586 scope
->specparams
[(*cur
).first
] = value
;
3590 // Elaborate within the generate blocks.
3591 typedef list
<PGenerate
*>::const_iterator generate_it_t
;
3592 for (generate_it_t cur
= generate_schemes
.begin()
3593 ; cur
!= generate_schemes
.end() ; cur
++ ) {
3594 (*cur
)->elaborate(des
, scope
);
3597 // Elaborate functions.
3598 typedef map
<perm_string
,PFunction
*>::const_iterator mfunc_it_t
;
3599 for (mfunc_it_t cur
= funcs_
.begin()
3600 ; cur
!= funcs_
.end() ; cur
++) {
3602 hname_t
use_name ( (*cur
).first
);
3603 NetScope
*fscope
= scope
->child(use_name
);
3605 (*cur
).second
->elaborate(des
, fscope
);
3608 // Elaborate the task definitions. This is done before the
3609 // behaviors so that task calls may reference these, and after
3610 // the signals so that the tasks can reference them.
3611 typedef map
<perm_string
,PTask
*>::const_iterator mtask_it_t
;
3612 for (mtask_it_t cur
= tasks_
.begin()
3613 ; cur
!= tasks_
.end() ; cur
++) {
3615 hname_t
use_name ( (*cur
).first
);
3616 NetScope
*tscope
= scope
->child(use_name
);
3618 (*cur
).second
->elaborate(des
, tscope
);
3621 // Get all the gates of the module and elaborate them by
3622 // connecting them to the signals. The gate may be simple or
3624 const list
<PGate
*>&gl
= get_gates();
3626 for (list
<PGate
*>::const_iterator gt
= gl
.begin()
3630 (*gt
)->elaborate(des
, scope
);
3633 // Elaborate the behaviors, making processes out of them. This
3634 // involves scanning the PProcess* list, creating a NetProcTop
3635 // for each process.
3636 result_flag
&= elaborate_behaviors_(des
, scope
);
3638 // Elaborate the specify paths of the module.
3640 for (list
<PSpecPath
*>::const_iterator sp
= specify_paths
.begin()
3641 ; sp
!= specify_paths
.end() ; sp
++) {
3643 (*sp
)->elaborate(des
, scope
);
3649 bool PGenerate::elaborate(Design
*des
, NetScope
*container
) const
3653 // Handle the special case that this is a CASE scheme. In this
3654 // case the PGenerate itself does not have the generated
3655 // item. Look instead for the case ITEM that has a scope
3656 // generated for it.
3657 if (scheme_type
== PGenerate::GS_CASE
) {
3658 if (debug_elaborate
)
3659 cerr
<< get_fileline() << ": debug: generate case"
3660 << " elaborating in scope "
3661 << scope_path(container
) << "." << endl
;
3663 typedef list
<PGenerate
*>::const_iterator generate_it_t
;
3664 for (generate_it_t cur
= generates
.begin()
3665 ; cur
!= generates
.end() ; cur
++) {
3666 PGenerate
*item
= *cur
;
3667 if (! item
->scope_list_
.empty()) {
3668 flag
&= item
->elaborate(des
, container
);
3674 typedef list
<NetScope
*>::const_iterator scope_list_it_t
;
3675 for (scope_list_it_t cur
= scope_list_
.begin()
3676 ; cur
!= scope_list_
.end() ; cur
++ ) {
3678 NetScope
*scope
= *cur
;
3679 // Check that this scope is one that is contained in the
3680 // container that the caller passed in.
3681 if (scope
->parent() != container
)
3684 // If this was an unnamed generate block, replace its
3685 // temporary name with a name generated using the naming
3686 // scheme defined in the Verilog-2005 standard.
3687 const char*name
= scope_name
.str();
3688 if (name
[0] == '$') {
3689 if (!scope
->auto_name("genblk", '0', name
+ 4)) {
3690 cerr
<< get_fileline() << ": warning: Couldn't build"
3691 << " unique name for unnamed generate block"
3692 << " - using internal name " << name
<< endl
;
3695 if (debug_elaborate
)
3696 cerr
<< get_fileline() << ": debug: Elaborate in "
3697 << "scope " << scope_path(scope
) << endl
;
3699 flag
= elaborate_(des
, scope
) & flag
;
3705 bool PGenerate::elaborate_(Design
*des
, NetScope
*scope
) const
3707 typedef list
<PGate
*>::const_iterator gates_it_t
;
3708 for (gates_it_t cur
= gates
.begin() ; cur
!= gates
.end() ; cur
++ )
3709 (*cur
)->elaborate(des
, scope
);
3711 typedef list
<PProcess
*>::const_iterator proc_it_t
;
3712 for (proc_it_t cur
= behaviors
.begin(); cur
!= behaviors
.end(); cur
++)
3713 (*cur
)->elaborate(des
, scope
);
3715 typedef list
<PGenerate
*>::const_iterator generate_it_t
;
3716 for (generate_it_t cur
= generates
.begin()
3717 ; cur
!= generates
.end() ; cur
++ ) {
3718 (*cur
)->elaborate(des
, scope
);
3724 bool PScope::elaborate_behaviors_(Design
*des
, NetScope
*scope
) const
3726 bool result_flag
= true;
3728 // Elaborate the behaviors, making processes out of them. This
3729 // involves scanning the PProcess* list, creating a NetProcTop
3730 // for each process.
3731 for (list
<PProcess
*>::const_iterator st
= behaviors
.begin()
3732 ; st
!= behaviors
.end() ; st
++ ) {
3734 result_flag
&= (*st
)->elaborate(des
, scope
);
3745 Design
* elaborate(list
<perm_string
>roots
)
3747 svector
<root_elem
*> root_elems(roots
.size());
3751 // This is the output design. I fill it in as I scan the root
3752 // module and elaborate what I find.
3753 Design
*des
= new Design
;
3755 // Scan the root modules, and elaborate their scopes.
3756 for (list
<perm_string
>::const_iterator root
= roots
.begin()
3757 ; root
!= roots
.end()
3760 // Look for the root module in the list.
3761 map
<perm_string
,Module
*>::const_iterator mod
= pform_modules
.find(*root
);
3762 if (mod
== pform_modules
.end()) {
3763 cerr
<< "error: Unable to find the root module \""
3764 << (*root
) << "\" in the Verilog source." << endl
;
3765 cerr
<< " : Perhaps ``-s " << (*root
)
3766 << "'' is incorrect?" << endl
;
3771 // Get the module definition for this root instance.
3772 Module
*rmod
= (*mod
).second
;
3774 // Make the root scope.
3775 NetScope
*scope
= des
->make_root_scope(*root
);
3776 scope
->set_line(rmod
);
3777 scope
->time_unit(rmod
->time_unit
);
3778 scope
->time_precision(rmod
->time_precision
);
3779 scope
->default_nettype(rmod
->default_nettype
);
3780 des
->set_precision(rmod
->time_precision
);
3782 Module::replace_t stub
;
3784 // Recursively elaborate from this root scope down. This
3785 // does a lot of the grunt work of creating sub-scopes, etc.
3786 if (! rmod
->elaborate_scope(des
, scope
, stub
)) {
3791 struct root_elem
*r
= new struct root_elem
;
3794 root_elems
[i
++] = r
;
3797 // Errors already? Probably missing root modules. Just give up
3798 // now and return nothing.
3799 if (des
->errors
> 0)
3802 // This method recurses through the scopes, looking for
3803 // defparam assignments to apply to the parameters in the
3804 // various scopes. This needs to be done after all the scopes
3805 // and basic parameters are taken care of because the defparam
3806 // can assign to a parameter declared *after* it.
3807 des
->run_defparams();
3810 // At this point, all parameter overrides are done. Scan the
3811 // scopes and evaluate the parameters all the way down to
3813 des
->evaluate_parameters();
3815 // With the parameters evaluated down to constants, we have
3816 // what we need to elaborate signals and memories. This pass
3817 // creates all the NetNet and NetMemory objects for declared
3819 for (i
= 0; i
< root_elems
.count(); i
++) {
3820 Module
*rmod
= root_elems
[i
]->mod
;
3821 NetScope
*scope
= root_elems
[i
]->scope
;
3823 if (! rmod
->elaborate_sig(des
, scope
)) {
3829 // Now that the structure and parameters are taken care of,
3830 // run through the pform again and generate the full netlist.
3831 for (i
= 0; i
< root_elems
.count(); i
++) {
3832 Module
*rmod
= root_elems
[i
]->mod
;
3833 NetScope
*scope
= root_elems
[i
]->scope
;
3835 rc
&= rmod
->elaborate(des
, scope
);