2 * Copyright (c) 1998-2006 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
20 #ident "$Id: elaborate.cc,v 1.374 2007/06/05 21:35:51 steve Exp $"
26 * Elaboration takes as input a complete parse tree and the name of a
27 * root module, and generates as output the elaborated design. This
28 * elaborated design is presented as a Module, which does not
29 * reference any other modules. It is entirely self contained.
37 # include "PGenerate.h"
42 # include "parse_api.h"
43 # include "compiler.h"
44 # include "ivl_assert.h"
47 static Link::strength_t
drive_type(PGate::strength_t drv
)
67 void PGate::elaborate(Design
*des
, NetScope
*scope
) const
69 cerr
<< "internal error: what kind of gate? " <<
70 typeid(*this).name() << endl
;
74 * Elaborate the continuous assign. (This is *not* the procedural
75 * assign.) Elaborate the lvalue and rvalue, and do the assignment.
77 void PGAssign::elaborate(Design
*des
, NetScope
*scope
) const
81 NetExpr
* rise_time
, *fall_time
, *decay_time
;
82 eval_delays(des
, scope
, rise_time
, fall_time
, decay_time
, true);
84 Link::strength_t drive0
= drive_type(strength0());
85 Link::strength_t drive1
= drive_type(strength1());
90 /* Normally, l-values to continuous assignments are NOT allowed
91 to implicitly declare nets. However, so many tools do allow
92 it that Icarus Verilog will allow it, at least if extensions
94 bool implicit_lval_ok
= false;
95 if (generation_flag
== GN_VER2001X
)
96 implicit_lval_ok
= true;
98 /* Elaborate the l-value. */
99 NetNet
*lval
= pin(0)->elaborate_lnet(des
, scope
, implicit_lval_ok
);
104 assert(lval
->pin_count() == 1);
106 if (debug_elaborate
) {
107 cerr
<< get_line() << ": debug: PGassign: elaborated l-value"
108 << " width=" << lval
->vector_width()
109 << ", type=" << lval
->data_type() << endl
;
112 /* Handle the special case that the rval is simply an
113 identifier. Get the rval as a NetNet, then use NetBUFZ
114 objects to connect it to the l-value. This is necessary to
115 direct drivers. This is how I attach strengths to the
116 assignment operation. */
117 if (const PEIdent
*id
= dynamic_cast<const PEIdent
*>(pin(1))) {
118 NetNet
*rid
= id
->elaborate_net(des
, scope
, lval
->vector_width(),
119 0, 0, 0, Link::STRONG
,
126 ivl_assert(*this, rid
);
127 if (rid
->pin_count() != 1) {
128 cerr
<< get_line() << ": internal error: "
129 << "Invalid elaborate_net results here:" << endl
;
130 rid
->dump_net(cerr
, 4);
133 ivl_assert(*this, rid
->pin_count() == 1);
135 /* If the right hand net is the same type as the left
136 side net (i.e., WIRE/WIRE) then it is enough to just
137 connect them together. Otherwise, put a bufz between
138 them to carry strengths from the rval.
140 While we are at it, handle the case where the r-value
141 is not as wide as the l-value by padding with a
144 unsigned cnt
= lval
->vector_width();
145 if (rid
->vector_width() < cnt
)
146 cnt
= rid
->vector_width();
148 bool need_driver_flag
= false;
150 /* If the device is linked to itself, a driver is
151 needed. Should I print a warning here? */
152 if (lval
->pin(0) .is_linked (rid
->pin(0)))
153 need_driver_flag
= true;
155 /* If the nets are different type (i.e., reg vs. tri) then
156 a driver is needed. */
157 if (rid
->type() != lval
->type())
158 need_driver_flag
= true;
160 /* If there is a delay, then I need a driver to carry
162 if (rise_time
|| fall_time
|| decay_time
)
163 need_driver_flag
= true;
165 /* If there is a strength to be carried, then I need a
166 driver to carry that strength. */
167 if (rid
->pin(0).drive0() != drive0
)
168 need_driver_flag
= true;
170 if (rid
->pin(0).drive1() != drive1
)
171 need_driver_flag
= true;
173 /* If the r-value is more narrow then the l-value, pad
174 it to the desired width. */
175 if (cnt
< lval
->vector_width()) {
176 if (lval
->get_signed() && rid
->get_signed()) {
178 unsigned use_width
= lval
->vector_width();
181 cerr
<< get_line() << ": debug: PGassign "
182 << "Generate sign-extend node." << endl
;
184 rid
= pad_to_width_signed(des
, rid
, use_width
);
189 cerr
<< get_line() << ": debug: PGAssign "
190 << "Unsigned pad r-value from "
191 << cnt
<< " bits to "
192 << lval
->vector_width() << " bits." << endl
;
194 NetNet
*tmp
= pad_to_width(des
, rid
,
195 lval
->vector_width());
199 } else if (cnt
< rid
->vector_width()) {
202 cerr
<< get_line() << ": debug: PGAssign "
203 << "Truncate r-value from "
204 << cnt
<< " bits to "
205 << lval
->vector_width() << " bits." << endl
;
207 NetNet
*tmp
= crop_to_width(des
, rid
, lval
->vector_width());
211 if (! need_driver_flag
) {
213 /* Don't need a driver, presumably because the
214 r-value already has the needed drivers. Just
215 hook things up. If the r-value is too narrow
216 for the l-value, then sign extend it or zero
217 extend it, whichever makes sense. */
219 if (debug_elaborate
) {
220 cerr
<< get_line() << ": debug: PGAssign: "
221 << "Connect lval directly to "
222 << id
->path() << endl
;
225 connect(lval
->pin(0), rid
->pin(0));
228 /* Do need a driver. Use BUFZ objects to carry the
229 strength and delays. */
231 if (debug_elaborate
) {
232 cerr
<< get_line() << ": debug: PGAssign: "
233 << "Connect lval to " << id
->path()
234 << " through bufz. delay=(";
236 cerr
<< *rise_time
<< ":";
240 cerr
<< *fall_time
<< ":";
250 NetBUFZ
*dev
= new NetBUFZ(scope
, scope
->local_symbol(),
251 rid
->vector_width());
252 connect(lval
->pin(0), dev
->pin(0));
253 connect(rid
->pin(0), dev
->pin(1));
254 dev
->rise_time(rise_time
);
255 dev
->fall_time(fall_time
);
256 dev
->decay_time(decay_time
);
257 dev
->pin(0).drive0(drive0
);
258 dev
->pin(0).drive1(drive1
);
266 /* Elaborate the r-value. Account for the initial decays,
267 which are going to be attached to the last gate before the
269 NetNet
*rval
= pin(1)->elaborate_net(des
, scope
,
270 lval
->vector_width(),
271 rise_time
, fall_time
, decay_time
,
274 cerr
<< get_line() << ": error: Unable to elaborate r-value: "
280 if (debug_elaborate
) {
281 cerr
<< get_line() << ": debug: PGAssign: elaborated r-value"
282 << " width="<<rval
->vector_width()
283 << ", type="<< rval
->data_type() << endl
;
286 assert(lval
&& rval
);
287 assert(rval
->pin_count() == 1);
289 /* If the r-value insists on being smaller then the l-value
290 (perhaps it is explicitly sized) the pad it out to be the
291 right width so that something is connected to all the bits
293 if (lval
->vector_width() > rval
->vector_width())
294 rval
= pad_to_width(des
, rval
, lval
->vector_width());
296 /* If, on the other hand, the r-value insists on being
297 LARGER then the l-value, use a part select to chop it down
299 if (lval
->vector_width() < rval
->vector_width()) {
300 NetPartSelect
*tmp
= new NetPartSelect(rval
, 0,lval
->vector_width(),
303 tmp
->set_line(*this);
304 NetNet
*osig
= new NetNet(scope
, scope
->local_symbol(),
305 NetNet::TRI
, lval
->vector_width());
306 osig
->set_line(*this);
307 osig
->data_type(rval
->data_type());
308 connect(osig
->pin(0), tmp
->pin(0));
312 connect(lval
->pin(0), rval
->pin(0));
314 if (lval
->local_flag())
320 * Elaborate a Builtin gate. These normally get translated into
321 * NetLogic nodes that reflect the particular logic function.
323 void PGBuiltin::elaborate(Design
*des
, NetScope
*scope
) const
326 unsigned instance_width
= 1;
327 long low
= 0, high
= 0;
328 string name
= string(get_name());
331 name
= scope
->local_symbol();
333 /* If the Verilog source has a range specification for the
334 gates, then I am expected to make more than one
335 gate. Figure out how many are desired. */
337 NetExpr
*msb_exp
= elab_and_eval(des
, scope
, msb_
, -1);
338 NetExpr
*lsb_exp
= elab_and_eval(des
, scope
, lsb_
, -1);
340 NetEConst
*msb_con
= dynamic_cast<NetEConst
*>(msb_exp
);
341 NetEConst
*lsb_con
= dynamic_cast<NetEConst
*>(lsb_exp
);
344 cerr
<< get_line() << ": error: Unable to evaluate "
345 "expression " << *msb_
<< endl
;
351 cerr
<< get_line() << ": error: Unable to evaluate "
352 "expression " << *lsb_
<< endl
;
357 verinum msb
= msb_con
->value();
358 verinum lsb
= lsb_con
->value();
363 if (msb
.as_long() > lsb
.as_long())
364 count
= msb
.as_long() - lsb
.as_long() + 1;
366 count
= lsb
.as_long() - msb
.as_long() + 1;
369 high
= msb
.as_long();
371 if (debug_elaborate
) {
372 cerr
<< get_line() << ": debug: PGBuiltin: Make arrray "
373 << "[" << high
<< ":" << low
<< "]"
374 << " of " << count
<< " gates for " << name
<< endl
;
378 /* Now we have a gate count. Elaborate the output expression
379 only. We do it early so that we can see if we can make a
380 wide gate instead of an array of gates. */
383 cerr
<< get_line() << ": error: Logic gate port "
384 "expressions are not optional." << endl
;
388 NetNet
*lval_sig
= pin(0)->elaborate_lnet(des
, scope
, true);
391 /* Detect the special case that the l-value width exactly
392 matches the gate count. In this case, we will make a single
393 gate that has the desired vector width. */
394 if (lval_sig
->vector_width() == count
) {
395 instance_width
= count
;
398 if (debug_elaborate
&& instance_width
!= 1)
399 cerr
<< get_line() << ": debug: PGBuiltin: "
400 "Collapsed gate array into single wide "
401 "(" << instance_width
<< ") instance." << endl
;
404 /* Allocate all the netlist nodes for the gates. */
405 NetLogic
**cur
= new NetLogic
*[count
];
408 /* Calculate the gate delays from the delay expressions
409 given in the source. For logic gates, the decay time
410 is meaningless because it can never go to high
411 impedance. However, the bufif devices can generate
412 'bz output, so we will pretend that anything can.
414 If only one delay value expression is given (i.e., #5
415 nand(foo,...)) then rise, fall and decay times are
416 all the same value. If two values are given, rise and
417 fall times are use, and the decay time is the minimum
418 of the rise and fall times. Finally, if all three
419 values are given, they are taken as specified. */
421 NetExpr
* rise_time
, *fall_time
, *decay_time
;
422 eval_delays(des
, scope
, rise_time
, fall_time
, decay_time
);
424 struct attrib_list_t
*attrib_list
= 0;
425 unsigned attrib_list_n
= 0;
426 attrib_list
= evaluate_attributes(attributes
, attrib_list_n
,
429 /* Now make as many gates as the bit count dictates. Give each
430 a unique name, and set the delay times. */
432 for (unsigned idx
= 0 ; idx
< count
; idx
+= 1) {
440 tmp
<< name
<< "<" << index
<< ">";
441 perm_string inm
= lex_strings
.make(tmp
.str());
445 if (pin_count() < 2) {
446 cerr
<< get_line() << ": error: the AND "
447 "primitive must have an input." << endl
;
451 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
452 NetLogic::AND
, instance_width
);
455 if (pin_count() > 2) {
456 cerr
<< get_line() << ": sorry: multiple output BUF "
457 "primitives are not supported." << endl
;
461 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
462 NetLogic::BUF
, instance_width
);
465 if (pin_count() != 3) {
466 cerr
<< get_line() << ": error: the BUFIF0 "
467 "primitive must have three arguments." << endl
;
471 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
472 NetLogic::BUFIF0
, instance_width
);
475 if (pin_count() != 3) {
476 cerr
<< get_line() << ": error: the BUFIF1 "
477 "primitive must have three arguments." << endl
;
481 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
482 NetLogic::BUFIF1
, instance_width
);
485 if (pin_count() != 4) {
486 cerr
<< get_line() << ": error: the CMOS "
487 "primitive must have four arguments." << endl
;
491 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
492 NetLogic::CMOS
, instance_width
);
495 if (pin_count() < 2) {
496 cerr
<< get_line() << ": error: the NAND "
497 "primitive must have an input." << endl
;
501 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
502 NetLogic::NAND
, instance_width
);
505 if (pin_count() != 3) {
506 cerr
<< get_line() << ": error: the NMOS "
507 "primitive must have three arguments." << endl
;
511 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
512 NetLogic::NMOS
, instance_width
);
515 if (pin_count() < 2) {
516 cerr
<< get_line() << ": error: the NOR "
517 "primitive must have an input." << endl
;
521 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
522 NetLogic::NOR
, instance_width
);
525 if (pin_count() > 2) {
526 cerr
<< get_line() << ": sorry: multiple output NOT "
527 "primitives are not supported." << endl
;
531 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
532 NetLogic::NOT
, instance_width
);
535 if (pin_count() != 3) {
536 cerr
<< get_line() << ": error: the NOTIF0 "
537 "primitive must have three arguments." << endl
;
541 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
542 NetLogic::NOTIF0
, instance_width
);
545 if (pin_count() != 3) {
546 cerr
<< get_line() << ": error: the NOTIF1 "
547 "primitive must have three arguments." << endl
;
551 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
552 NetLogic::NOTIF1
, instance_width
);
555 if (pin_count() < 2) {
556 cerr
<< get_line() << ": error: the OR "
557 "primitive must have an input." << endl
;
561 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
562 NetLogic::OR
, instance_width
);
565 if (pin_count() != 4) {
566 cerr
<< get_line() << ": error: the RCMOS "
567 "primitive must have four arguments." << endl
;
571 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
572 NetLogic::RCMOS
, instance_width
);
575 if (pin_count() != 3) {
576 cerr
<< get_line() << ": error: the RNMOS "
577 "primitive must have three arguments." << endl
;
581 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
582 NetLogic::RNMOS
, instance_width
);
585 if (pin_count() != 3) {
586 cerr
<< get_line() << ": error: the RPMOS "
587 "primitive must have three arguments." << endl
;
591 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
592 NetLogic::RPMOS
, instance_width
);
595 if (pin_count() != 3) {
596 cerr
<< get_line() << ": error: the PMOS "
597 "primitive must have three arguments." << endl
;
601 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
602 NetLogic::PMOS
, instance_width
);
605 if (pin_count() > 1) {
606 cerr
<< get_line() << ": sorry: multiple output PULLDOWN "
607 "primitives are not supported." << endl
;
611 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
616 if (pin_count() > 1) {
617 cerr
<< get_line() << ": sorry: multiple output PULLUP "
618 "primitives are not supported." << endl
;
622 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
623 NetLogic::PULLUP
, instance_width
);
626 if (pin_count() < 2) {
627 cerr
<< get_line() << ": error: the XNOR "
628 "primitive must have an input." << endl
;
632 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
633 NetLogic::XNOR
, instance_width
);
636 if (pin_count() < 2) {
637 cerr
<< get_line() << ": error: the XOR "
638 "primitive must have an input." << endl
;
642 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
643 NetLogic::XOR
, instance_width
);
646 cerr
<< get_line() << ": internal error: unhandled "
647 "gate type." << endl
;
652 for (unsigned adx
= 0 ; adx
< attrib_list_n
; adx
+= 1)
653 cur
[idx
]->attribute(attrib_list
[adx
].key
,
654 attrib_list
[adx
].val
);
656 cur
[idx
]->rise_time(rise_time
);
657 cur
[idx
]->fall_time(fall_time
);
658 cur
[idx
]->decay_time(decay_time
);
660 cur
[idx
]->pin(0).drive0(drive_type(strength0()));
661 cur
[idx
]->pin(0).drive1(drive_type(strength1()));
663 des
->add_node(cur
[idx
]);
669 /* The gates have all been allocated, this loop runs through
670 the parameters and attaches the ports of the objects. */
672 for (unsigned idx
= 0 ; idx
< pin_count() ; idx
+= 1) {
673 const PExpr
*ex
= pin(idx
);
675 cerr
<< get_line() << ": error: Logic gate port "
676 "expressions are not optional." << endl
;
680 NetNet
*sig
= (idx
== 0)
682 : ex
->elaborate_net(des
, scope
, 0, 0, 0, 0);
689 /* Handle the case where there is one gate that
690 carries the whole vector width. */
692 if (1 == sig
->vector_width() && instance_width
!= 1) {
694 assert(sig
->vector_width() == 1);
696 = new NetReplicate(scope
,
697 scope
->local_symbol(),
700 rep
->set_line(*this);
702 connect(rep
->pin(1), sig
->pin(0));
704 sig
= new NetNet(scope
, scope
->local_symbol(),
705 NetNet::WIRE
, instance_width
);
706 sig
->data_type(IVL_VT_LOGIC
);
707 sig
->local_flag(true);
708 sig
->set_line(*this);
709 connect(rep
->pin(0), sig
->pin(0));
713 if (instance_width
!= sig
->vector_width()) {
715 cerr
<< get_line() << ": error: "
716 << "Expression width " << sig
->vector_width()
717 << " does not match width " << instance_width
718 << " of logic gate array port " << idx
723 connect(cur
[0]->pin(idx
), sig
->pin(0));
725 } else if (sig
->vector_width() == 1) {
726 /* Handle the case where a single bit is connected
727 repetitively to all the instances. */
728 for (unsigned gdx
= 0 ; gdx
< count
; gdx
+= 1)
729 connect(cur
[gdx
]->pin(idx
), sig
->pin(0));
731 } else if (sig
->vector_width() == count
) {
733 /* Handle the general case that each bit of the
734 value is connected to a different instance. In
735 this case, the output is handled slightly
736 different from the inputs. */
738 NetConcat
*cc
= new NetConcat(scope
,
739 scope
->local_symbol(),
744 /* Connect the concat to the signal. */
745 connect(cc
->pin(0), sig
->pin(0));
747 /* Connect the outputs of the gates to the concat. */
748 for (unsigned gdx
= 0 ; gdx
< count
; gdx
+= 1) {
749 connect(cur
[gdx
]->pin(0), cc
->pin(gdx
+1));
751 NetNet
*tmp2
= new NetNet(scope
,
752 scope
->local_symbol(),
754 tmp2
->local_flag(true);
755 tmp2
->data_type(IVL_VT_LOGIC
);
756 connect(cc
->pin(gdx
+1), tmp2
->pin(0));
759 } else for (unsigned gdx
= 0 ; gdx
< count
; gdx
+= 1) {
760 /* Use part selects to get the bits
761 connected to the inputs of out gate. */
762 NetPartSelect
*tmp1
= new NetPartSelect(sig
, gdx
, 1,
764 tmp1
->set_line(*this);
766 connect(tmp1
->pin(1), sig
->pin(0));
767 NetNet
*tmp2
= new NetNet(scope
, scope
->local_symbol(),
769 tmp2
->local_flag(true);
770 tmp2
->data_type(sig
->data_type());
771 connect(tmp1
->pin(0), tmp2
->pin(0));
772 connect(cur
[gdx
]->pin(idx
), tmp1
->pin(0));
776 cerr
<< get_line() << ": error: Gate count of " <<
777 count
<< " does not match net width of " <<
778 sig
->vector_width() << " at pin " << idx
<< "."
786 NetNet
*PGModule::resize_net_to_port_(Design
*des
, NetScope
*scope
,
787 NetNet
*sig
, unsigned port_wid
,
788 NetNet::PortType dir
) const
790 ivl_assert(*this, dir
!= NetNet::NOT_A_PORT
);
791 ivl_assert(*this, dir
!= NetNet::PIMPLICIT
);
793 NetNet
*tmp
= new NetNet(scope
, scope
->local_symbol(),
794 NetNet::WIRE
, port_wid
);
795 tmp
->local_flag(true);
798 NetPartSelect
*node
= 0;
801 case NetNet::POUTPUT
:
802 if (tmp
->vector_width() > sig
->vector_width()) {
803 node
= new NetPartSelect(tmp
, 0, sig
->vector_width(),
806 node
= new NetPartSelect(tmp
, 0, sig
->vector_width(),
809 connect(node
->pin(0), sig
->pin(0));
813 if (tmp
->vector_width() > sig
->vector_width()) {
814 node
= new NetPartSelect(sig
, 0, tmp
->vector_width(),
817 node
= new NetPartSelect(sig
, 0, tmp
->vector_width(),
820 connect(node
->pin(0), tmp
->pin(0));
824 if (sig
->vector_width() > tmp
->vector_width()) {
825 node
= new NetPartSelect(sig
, 0, tmp
->vector_width(),
827 connect(node
->pin(0), tmp
->pin(0));
829 node
= new NetPartSelect(tmp
, 0, sig
->vector_width(),
831 connect(node
->pin(0), sig
->pin(0));
836 ivl_assert(*this, 0);
845 * Instantiate a module by recursively elaborating it. Set the path of
846 * the recursive elaboration so that signal names get properly
847 * set. Connect the ports of the instantiated module to the signals of
848 * the parameters. This is done with BUFZ gates so that they look just
849 * like continuous assignment connections.
851 void PGModule::elaborate_mod_(Design
*des
, Module
*rmod
, NetScope
*scope
) const
856 if (debug_elaborate
) {
857 cerr
<< get_line() << ": debug: Instantiate module "
858 << rmod
->mod_name() << " with instance name "
859 << get_name() << " in scope " << scope_path(scope
) << endl
;
862 // This is the array of pin expressions, shuffled to match the
863 // order of the declaration. If the source instantiation uses
864 // bind by order, this is the same as the source list.Otherwise,
865 // the source list is rearranged by name binding into this list.
866 svector
<PExpr
*>pins (rmod
->port_count());
868 // If the instance has a pins_ member, then we know we are
869 // binding by name. Therefore, make up a pins array that
870 // reflects the positions of the named ports.
872 unsigned nexp
= rmod
->port_count();
874 // Scan the bindings, matching them with port names.
875 for (unsigned idx
= 0 ; idx
< npins_
; idx
+= 1) {
877 // Given a binding, look at the module port names
878 // for the position that matches the binding name.
879 unsigned pidx
= rmod
->find_port(pins_
[idx
].name
);
881 // If the port name doesn't exist, the find_port
882 // method will return the port count. Detect that
885 cerr
<< get_line() << ": error: port ``" <<
886 pins_
[idx
].name
<< "'' is not a port of "
887 << get_name() << "." << endl
;
892 // If I already bound something to this port, then
893 // the pins array will already have a pointer
894 // value where I want to place this expression.
896 cerr
<< get_line() << ": error: port ``" <<
897 pins_
[idx
].name
<< "'' already bound." <<
903 // OK, do the binding by placing the expression in
905 pins
[pidx
] = pins_
[idx
].parm
;
909 } else if (pin_count() == 0) {
911 /* Handle the special case that no ports are
912 connected. It is possible that this is an empty
913 connect-by-name list, so we'll allow it and assume
916 for (unsigned idx
= 0 ; idx
< rmod
->port_count() ; idx
+= 1)
921 /* Otherwise, this is a positional list of port
922 connections. In this case, the port count must be
923 right. Check that is is, the get the pin list. */
925 if (pin_count() != rmod
->port_count()) {
926 cerr
<< get_line() << ": error: Wrong number "
927 "of ports. Expecting " << rmod
->port_count() <<
928 ", got " << pin_count() << "."
934 // No named bindings, just use the positional list I
936 assert(pin_count() == rmod
->port_count());
940 // Elaborate these instances of the module. The recursive
941 // elaboration causes the module to generate a netlist with
942 // the ports represented by NetNet objects. I will find them
945 NetScope::scope_vec_t
&instance
= scope
->instance_arrays
[get_name()];
946 for (unsigned inst
= 0 ; inst
< instance
.count() ; inst
+= 1) {
947 rmod
->elaborate(des
, instance
[inst
]);
952 // Now connect the ports of the newly elaborated designs to
953 // the expressions that are the instantiation parameters. Scan
954 // the pins, elaborate the expressions attached to them, and
955 // bind them to the port of the elaborated module.
957 // This can get rather complicated because the port can be
958 // unconnected (meaning an empty parameter is passed) connected
959 // to a concatenation, or connected to an internally
962 for (unsigned idx
= 0 ; idx
< pins
.count() ; idx
+= 1) {
964 // Skip unconnected module ports. This happens when a
965 // null parameter is passed in.
967 if (pins
[idx
] == 0) {
969 // While we're here, look to see if this
970 // unconnected (from the outside) port is an
971 // input. If so, consider printing a port binding
973 if (warn_portbinding
) {
974 svector
<PEIdent
*> mport
= rmod
->get_port(idx
);
975 if (mport
.count() == 0)
978 perm_string pname
= peek_tail_name(mport
[0]->path());
980 NetNet
*tmp
= instance
[0]->find_signal(pname
);
983 if (tmp
->port_type() == NetNet::PINPUT
) {
984 cerr
<< get_line() << ": warning: "
985 << "Instantiating module "
987 << " with dangling input port "
988 << rmod
->ports
[idx
]->name
997 // Inside the module, the port is zero or more signals
998 // that were already elaborated. List all those signals
999 // and the NetNet equivalents, for all the instances.
1000 svector
<PEIdent
*> mport
= rmod
->get_port(idx
);
1001 svector
<NetNet
*>prts (mport
.count() * instance
.count());
1003 if (debug_elaborate
) {
1004 cerr
<< get_line() << ": debug: " << get_name()
1005 << ": Port " << idx
<< " has " << prts
.count()
1006 << " sub-ports." << endl
;
1009 // Count the internal vector bits of the port.
1010 unsigned prts_vector_width
= 0;
1012 for (unsigned inst
= 0 ; inst
< instance
.count() ; inst
+= 1) {
1013 NetScope
*inst_scope
= instance
[inst
];
1015 // Scan the module sub-ports for this instance...
1016 for (unsigned ldx
= 0 ; ldx
< mport
.count() ; ldx
+= 1) {
1017 unsigned lbase
= inst
* mport
.count();
1018 PEIdent
*pport
= mport
[ldx
];
1021 = pport
->elaborate_port(des
, inst_scope
);
1022 if (prts
[lbase
+ ldx
] == 0)
1025 assert(prts
[lbase
+ ldx
]);
1026 prts_vector_width
+= prts
[lbase
+ ldx
]->vector_width();
1030 // If I find that the port is unconnected inside the
1031 // module, then there is nothing to connect. Skip the
1033 if (prts_vector_width
== 0) {
1037 // We know by design that each instance has the same
1038 // width port. Therefore, the prts_pin_count must be an
1039 // even multiple of the instance count.
1040 assert(prts_vector_width
% instance
.count() == 0);
1042 unsigned desired_vector_width
= prts_vector_width
;
1043 if (instance
.count() != 1)
1044 desired_vector_width
= 0;
1046 // Elaborate the expression that connects to the
1047 // module[s] port. sig is the thing outside the module
1048 // that connects to the port.
1051 if ((prts
.count() == 0)
1052 || (prts
[0]->port_type() == NetNet::PINPUT
)) {
1054 /* Input to module. elaborate the expression to
1055 the desired width. If this in an instance
1056 array, then let the net determine it's own
1057 width. We use that, then, to decide how to hook
1060 NOTE that this also handles the case that the
1061 port is actually empty on the inside. We assume
1062 in that case that the port is input. */
1064 sig
= pins
[idx
]->elaborate_net(des
, scope
,
1065 desired_vector_width
,
1068 cerr
<< pins
[idx
]->get_line()
1069 << ": internal error: Port expression "
1070 << "too complicated for elaboration." << endl
;
1074 } else if (prts
[0]->port_type() == NetNet::PINOUT
) {
1076 /* Inout to/from module. This is a more
1077 complicated case, where the expression must be
1078 an lnet, but also an r-value net.
1080 Normally, this winds up being the same as if we
1081 just elaborated as an lnet, as passing a simple
1082 identifier elaborates to the same NetNet in
1083 both cases so the extra elaboration has no
1084 effect. But if the expression passed to the
1085 inout port is a part select, aspecial part
1086 select must be created that can paqss data in
1089 Use the elaborate_bi_net method to handle all
1090 the possible cases. */
1092 sig
= pins
[idx
]->elaborate_bi_net(des
, scope
);
1094 cerr
<< pins
[idx
]->get_line() << ": error: "
1095 << "Inout port expression must support "
1096 << "continuous assignment." << endl
;
1097 cerr
<< pins
[idx
]->get_line() << ": : "
1098 << "Port of " << rmod
->mod_name()
1099 << " is " << rmod
->ports
[idx
]->name
<< endl
;
1107 /* Port type must be OUTPUT here. */
1109 /* Output from module. Elaborate the port
1110 expression as the l-value of a continuous
1111 assignment, as the port will continuous assign
1114 sig
= pins
[idx
]->elaborate_lnet(des
, scope
, true);
1116 cerr
<< pins
[idx
]->get_line() << ": error: "
1117 << "Output port expression must support "
1118 << "continuous assignment." << endl
;
1119 cerr
<< pins
[idx
]->get_line() << ": : "
1120 << "Port of " << rmod
->mod_name()
1121 << " is " << rmod
->ports
[idx
]->name
<< endl
;
1131 if ((prts
.count() >= 1)
1132 && (prts
[0]->port_type() != NetNet::PINPUT
)) {
1133 assert(sig
->type() != NetNet::REG
);
1137 /* If we are working with an instance array, then the
1138 signal width must match the port width exactly. */
1139 if ((instance
.count() != 1)
1140 && (sig
->vector_width() != prts_vector_width
)
1141 && (sig
->vector_width() != prts_vector_width
/instance
.count())) {
1142 cerr
<< pins
[idx
]->get_line() << ": error: "
1143 << "Port expression width " << sig
->vector_width()
1144 << " does not match expected width "<< prts_vector_width
1145 << " or " << (prts_vector_width
/instance
.count())
1151 if (debug_elaborate
) {
1152 cerr
<< get_line() << ": debug: " << get_name()
1153 << ": Port " << (idx
+1) << " has vector width of "
1154 << prts_vector_width
<< "." << endl
;
1157 // Check that the parts have matching pin counts. If
1158 // not, they are different widths. Note that idx is 0
1159 // based, but users count parameter positions from 1.
1160 if ((instance
.count() == 1)
1161 && (prts_vector_width
!= sig
->vector_width())) {
1162 const char *tmp3
= rmod
->ports
[idx
]->name
.str();
1163 if (tmp3
== 0) tmp3
= "???";
1164 cerr
<< get_line() << ": warning: Port " << (idx
+1)
1165 << " (" << tmp3
<< ") of "
1166 << type_
<< " expects " << prts_vector_width
<<
1167 " bits, got " << sig
->vector_width() << "." << endl
;
1169 if (prts_vector_width
> sig
->vector_width()) {
1170 cerr
<< get_line() << ": : Leaving "
1171 << (prts_vector_width
-sig
->vector_width())
1172 << " high bits of the port unconnected."
1177 cerr
<< get_line() << ": : Leaving "
1178 << (sig
->vector_width()-prts_vector_width
)
1179 << " high bits of the expression dangling."
1183 sig
= resize_net_to_port_(des
, scope
, sig
, prts_vector_width
,
1184 prts
[0]->port_type());
1187 // Connect the sig expression that is the context of the
1188 // module instance to the ports of the elaborated module.
1190 // The prts_pin_count variable is the total width of the
1191 // port and is the maximum number of connections to
1192 // make. sig is the elaborated expression that connects
1193 // to that port. If sig has too few pins, then reduce
1194 // the number of connections to make.
1196 // Connect this many of the port pins. If the expression
1197 // is too small, then reduce the number of connects.
1198 unsigned ccount
= prts_vector_width
;
1199 if (instance
.count() == 1 && sig
->vector_width() < ccount
)
1200 ccount
= sig
->vector_width();
1202 // The spin_modulus is the width of the signal (not the
1203 // port) if this is an instance array. This causes
1204 // signals wide enough for a single instance to be
1205 // connected to all the instances.
1206 unsigned spin_modulus
= prts_vector_width
;
1207 if (instance
.count() != 1)
1208 spin_modulus
= sig
->vector_width();
1210 // Now scan the concatenation that makes up the port,
1211 // connecting pins until we run out of port pins or sig
1212 // pins. The sig object is the NetNet that is connected
1213 // to the port from the outside, and the prts object is
1214 // an array of signals to be connected to the sig.
1219 if (prts
.count() == 1) {
1221 // The simplest case, there are no
1222 // parts/concatenations on the inside of the
1223 // module, so the port and sig need simply be
1224 // connected directly.
1225 connect(prts
[0]->pin(0), sig
->pin(0));
1227 } else if (sig
->vector_width()==prts_vector_width
/instance
.count()
1228 && prts
.count()/instance
.count() == 1) {
1230 if (debug_elaborate
){
1231 cerr
<< get_line() << ": debug: " << get_name()
1232 << ": Replicating " << prts_vector_width
1233 << " bits across all "
1234 << prts_vector_width
/instance
.count()
1235 << " sub-ports." << endl
;
1238 // The signal width is exactly the width of a
1239 // single instance of the port. In this case,
1240 // connect the sig to all the ports identically.
1241 for (unsigned ldx
= 0 ; ldx
< prts
.count() ; ldx
+= 1)
1242 connect(prts
[ldx
]->pin(0), sig
->pin(0));
1244 } else switch (prts
[0]->port_type()) {
1245 case NetNet::POUTPUT
:
1246 ctmp
= new NetConcat(scope
, scope
->local_symbol(),
1249 des
->add_node(ctmp
);
1250 connect(ctmp
->pin(0), sig
->pin(0));
1251 for (unsigned ldx
= 0 ; ldx
< prts
.count() ; ldx
+= 1) {
1252 connect(ctmp
->pin(ldx
+1),
1253 prts
[prts
.count()-ldx
-1]->pin(0));
1257 case NetNet::PINPUT
:
1258 if (debug_elaborate
){
1259 cerr
<< get_line() << ": debug: " << get_name()
1260 << ": Dividing " << prts_vector_width
1261 << " bits across all "
1262 << prts_vector_width
/instance
.count()
1263 << " input sub-ports of port "
1264 << idx
<< "." << endl
;
1267 for (unsigned ldx
= 0 ; ldx
< prts
.count() ; ldx
+= 1) {
1268 NetNet
*sp
= prts
[prts
.count()-ldx
-1];
1269 NetPartSelect
*ptmp
= new NetPartSelect(sig
, spin
,
1272 des
->add_node(ptmp
);
1273 connect(ptmp
->pin(0), sp
->pin(0));
1274 spin
+= sp
->vector_width();
1277 case NetNet::PINOUT
:
1278 cerr
<< get_line() << ": XXXX: "
1279 << "Forgot how to bind inout ports!" << endl
;
1282 case NetNet::PIMPLICIT
:
1283 cerr
<< get_line() << ": internal error: "
1284 << "Unexpected IMPLICIT port" << endl
;
1287 case NetNet::NOT_A_PORT
:
1288 cerr
<< get_line() << ": internal error: "
1289 << "Unexpected NOT_A_PORT port." << endl
;
1299 * From a UDP definition in the source, make a NetUDP
1300 * object. Elaborate the pin expressions as netlists, then connect
1301 * those networks to the pins.
1304 void PGModule::elaborate_udp_(Design
*des
, PUdp
*udp
, NetScope
*scope
) const
1306 NetExpr
*rise_expr
=0, *fall_expr
=0, *decay_expr
=0;
1308 perm_string my_name
= get_name();
1310 my_name
= scope
->local_symbol();
1312 /* When the parser notices delay expressions in front of a
1313 module or primitive, it interprets them as parameter
1314 overrides. Correct that misconception here. */
1317 tmp_del
.set_delays(overrides_
, false);
1318 tmp_del
.eval_delays(des
, scope
, rise_expr
, fall_expr
, decay_expr
);
1320 if (dynamic_cast<NetEConst
*> (rise_expr
)) {
1323 cerr
<< get_line() << ": error: Delay expressions must be "
1324 << "constant for primitives." << endl
;
1325 cerr
<< get_line() << ": : Cannot calculate "
1326 << *rise_expr
<< endl
;
1330 if (dynamic_cast<NetEConst
*> (fall_expr
)) {
1333 cerr
<< get_line() << ": error: Delay expressions must be "
1334 << "constant for primitives." << endl
;
1335 cerr
<< get_line() << ": : Cannot calculate "
1336 << *rise_expr
<< endl
;
1340 if (dynamic_cast<NetEConst
*> (decay_expr
)) {
1343 cerr
<< get_line() << ": error: Delay expressions must be "
1344 << "constant for primitives." << endl
;
1345 cerr
<< get_line() << ": : Cannot calculate "
1346 << *rise_expr
<< endl
;
1354 NetUDP
*net
= new NetUDP(scope
, my_name
, udp
->ports
.count(), udp
);
1355 net
->rise_time(rise_expr
);
1356 net
->fall_time(fall_expr
);
1357 net
->decay_time(decay_expr
);
1359 struct attrib_list_t
*attrib_list
= 0;
1360 unsigned attrib_list_n
= 0;
1361 attrib_list
= evaluate_attributes(attributes
, attrib_list_n
,
1364 for (unsigned adx
= 0 ; adx
< attrib_list_n
; adx
+= 1)
1365 net
->attribute(attrib_list
[adx
].key
, attrib_list
[adx
].val
);
1367 delete[]attrib_list
;
1370 // This is the array of pin expressions, shuffled to match the
1371 // order of the declaration. If the source instantiation uses
1372 // bind by order, this is the same as the source
1373 // list. Otherwise, the source list is rearranged by name
1374 // binding into this list.
1375 svector
<PExpr
*>pins
;
1377 // Detect binding by name. If I am binding by name, then make
1378 // up a pins array that reflects the positions of the named
1379 // ports. If this is simply positional binding in the first
1380 // place, then get the binding from the base class.
1382 unsigned nexp
= udp
->ports
.count();
1383 pins
= svector
<PExpr
*>(nexp
);
1385 // Scan the bindings, matching them with port names.
1386 for (unsigned idx
= 0 ; idx
< npins_
; idx
+= 1) {
1388 // Given a binding, look at the module port names
1389 // for the position that matches the binding name.
1390 unsigned pidx
= udp
->find_port(pins_
[idx
].name
);
1392 // If the port name doesn't exist, the find_port
1393 // method will return the port count. Detect that
1396 cerr
<< get_line() << ": error: port ``" <<
1397 pins_
[idx
].name
<< "'' is not a port of "
1398 << get_name() << "." << endl
;
1403 // If I already bound something to this port, then
1404 // the (*exp) array will already have a pointer
1405 // value where I want to place this expression.
1407 cerr
<< get_line() << ": error: port ``" <<
1408 pins_
[idx
].name
<< "'' already bound." <<
1414 // OK, do the binding by placing the expression in
1416 pins
[pidx
] = pins_
[idx
].parm
;
1421 /* Otherwise, this is a positional list of port
1422 connections. In this case, the port count must be
1423 right. Check that is is, the get the pin list. */
1425 if (pin_count() != udp
->ports
.count()) {
1426 cerr
<< get_line() << ": error: Wrong number "
1427 "of ports. Expecting " << udp
->ports
.count() <<
1428 ", got " << pin_count() << "."
1434 // No named bindings, just use the positional list I
1436 assert(pin_count() == udp
->ports
.count());
1441 /* Handle the output port of the primitive special. It is an
1442 output port (the only output port) so must be passed an
1445 cerr
<< get_line() << ": warning: output port unconnected."
1449 NetNet
*sig
= pins
[0]->elaborate_lnet(des
, scope
, true);
1451 cerr
<< get_line() << ": error: "
1452 << "Output port expression is not valid." << endl
;
1453 cerr
<< get_line() << ": : Output "
1454 << "port of " << udp
->name_
1455 << " is " << udp
->ports
[0] << "." << endl
;
1458 connect(sig
->pin(0), net
->pin(0));
1462 /* Run through the pins, making netlists for the pin
1463 expressions and connecting them to the pin in question. All
1464 of this is independent of the nature of the UDP. */
1465 for (unsigned idx
= 1 ; idx
< net
->pin_count() ; idx
+= 1) {
1469 NetNet
*sig
= pins
[idx
]->elaborate_net(des
, scope
, 1, 0, 0, 0);
1471 cerr
<< "internal error: Expression too complicated "
1472 "for elaboration:" << pins
[idx
] << endl
;
1476 connect(sig
->pin(0), net
->pin(idx
));
1479 // All done. Add the object to the design.
1484 bool PGModule::elaborate_sig(Design
*des
, NetScope
*scope
) const
1486 // Look for the module type
1487 map
<perm_string
,Module
*>::const_iterator mod
= pform_modules
.find(type_
);
1488 if (mod
!= pform_modules
.end())
1489 return elaborate_sig_mod_(des
, scope
, (*mod
).second
);
1495 void PGModule::elaborate(Design
*des
, NetScope
*scope
) const
1497 // Look for the module type
1498 map
<perm_string
,Module
*>::const_iterator mod
= pform_modules
.find(type_
);
1499 if (mod
!= pform_modules
.end()) {
1500 elaborate_mod_(des
, (*mod
).second
, scope
);
1504 // Try a primitive type
1505 map
<perm_string
,PUdp
*>::const_iterator udp
= pform_primitives
.find(type_
);
1506 if (udp
!= pform_primitives
.end()) {
1507 assert((*udp
).second
);
1508 elaborate_udp_(des
, (*udp
).second
, scope
);
1512 cerr
<< get_line() << ": internal error: Unknown module type: " <<
1516 void PGModule::elaborate_scope(Design
*des
, NetScope
*sc
) const
1518 // Look for the module type
1519 map
<perm_string
,Module
*>::const_iterator mod
= pform_modules
.find(type_
);
1520 if (mod
!= pform_modules
.end()) {
1521 elaborate_scope_mod_(des
, (*mod
).second
, sc
);
1525 // Try a primitive type
1526 map
<perm_string
,PUdp
*>::const_iterator udp
= pform_primitives
.find(type_
);
1527 if (udp
!= pform_primitives
.end())
1530 // Not a module or primitive that I know about yet, so try to
1531 // load a library module file (which parses some new Verilog
1532 // code) and try again.
1533 if (load_module(type_
)) {
1535 // Try again to find the module type
1536 mod
= pform_modules
.find(type_
);
1537 if (mod
!= pform_modules
.end()) {
1538 elaborate_scope_mod_(des
, (*mod
).second
, sc
);
1542 // Try again to find a primitive type
1543 udp
= pform_primitives
.find(type_
);
1544 if (udp
!= pform_primitives
.end())
1549 // Not a module or primitive that I know about or can find by
1550 // any means, so give up.
1551 cerr
<< get_line() << ": error: Unknown module type: " << type_
<< endl
;
1552 missing_modules
[type_
] += 1;
1557 NetProc
* Statement::elaborate(Design
*des
, NetScope
*) const
1559 cerr
<< get_line() << ": internal error: elaborate: "
1560 "What kind of statement? " << typeid(*this).name() << endl
;
1561 NetProc
*cur
= new NetProc
;
1567 NetAssign_
* PAssign_::elaborate_lval(Design
*des
, NetScope
*scope
) const
1570 return lval_
->elaborate_lval(des
, scope
, false);
1574 * This function elaborates delay expressions. This is a little
1575 * different from normal elaboration because the result may need to be
1578 static NetExpr
*elaborate_delay_expr(PExpr
*expr
, Design
*des
, NetScope
*scope
)
1580 NetExpr
*dex
= elab_and_eval(des
, scope
, expr
, -1);
1582 /* If the delay expression is a real constant or vector
1583 constant, then evaluate it, scale it to the local time
1584 units, and return an adjusted NetEConst. */
1586 if (NetECReal
*tmp
= dynamic_cast<NetECReal
*>(dex
)) {
1587 verireal fn
= tmp
->value();
1589 int shift
= scope
->time_unit() - des
->get_precision();
1590 int64_t delay
= fn
.as_long64(shift
);
1595 return new NetEConst(verinum(delay
));
1599 if (NetEConst
*tmp
= dynamic_cast<NetEConst
*>(dex
)) {
1600 verinum fn
= tmp
->value();
1603 des
->scale_to_precision(fn
.as_ulong64(), scope
);
1606 return new NetEConst(verinum(delay
));
1610 /* The expression is not constant, so generate an expanded
1611 expression that includes the necessary scale shifts, and
1612 return that expression. */
1613 int shift
= scope
->time_unit() - des
->get_precision();
1621 NetExpr
*scal_val
= new NetEConst(verinum(scale
));
1622 dex
= new NetEBMult('*', dex
, scal_val
);
1626 unsigned long scale
= 1;
1632 NetExpr
*scal_val
= new NetEConst(verinum(scale
));
1633 dex
= new NetEBDiv('/', dex
, scal_val
);
1639 NetProc
* PAssign::elaborate(Design
*des
, NetScope
*scope
) const
1643 /* elaborate the lval. This detects any part selects and mux
1644 expressions that might exist. */
1645 NetAssign_
*lv
= elaborate_lval(des
, scope
);
1646 if (lv
== 0) return 0;
1648 /* If there is an internal delay expression, elaborate it. */
1651 delay
= elaborate_delay_expr(delay_
, des
, scope
);
1656 /* Elaborate the r-value expression, then try to evaluate it. */
1658 /* Find out what the r-value width is going to be. We guess it
1659 will be the l-value width, but it may turn out to be
1660 something else based on self-determined widths inside. */
1661 unsigned use_width
= lv
->lwidth();
1662 bool unsized_flag
= false;
1663 use_width
= rval()->test_width(des
, scope
, use_width
, use_width
, unsized_flag
);
1665 /* Now elaborate to the expected width. Pass the lwidth to
1666 prune any constant result to fit with the lvalue at hand. */
1667 NetExpr
*rv
= elab_and_eval(des
, scope
, rval(), use_width
, lv
->lwidth());
1668 if (rv
== 0) return 0;
1672 /* Rewrite delayed assignments as assignments that are
1673 delayed. For example, a = #<d> b; becomes:
1680 If the delay is an event delay, then the transform is
1681 similar, with the event delay replacing the time delay. It
1682 is an event delay if the event_ member has a value.
1684 This rewriting of the expression allows me to not bother to
1685 actually and literally represent the delayed assign in the
1686 netlist. The compound statement is exactly equivalent. */
1688 if (delay
|| event_
) {
1689 unsigned wid
= lv
->lwidth();
1692 rv
= pad_to_width(rv
, wid
);
1694 if (wid
> rv
->expr_width()) {
1695 cerr
<< get_line() << ": error: Unable to match "
1696 "expression width of " << rv
->expr_width() <<
1697 " to l-value width of " << wid
<< "." << endl
;
1702 NetNet
*tmp
= new NetNet(scope
, scope
->local_symbol(),
1704 tmp
->set_line(*this);
1705 tmp
->data_type(rv
->expr_type());
1707 NetESignal
*sig
= new NetESignal(tmp
);
1709 /* Generate an assignment of the l-value to the temporary... */
1710 NetAssign_
*lvt
= new NetAssign_(tmp
);
1712 NetAssign
*a1
= new NetAssign(lvt
, rv
);
1713 a1
->set_line(*this);
1715 /* Generate an assignment of the temporary to the r-value... */
1716 NetAssign
*a2
= new NetAssign(lv
, sig
);
1717 a2
->set_line(*this);
1719 /* Generate the delay statement with the final
1720 assignment attached to it. If this is an event delay,
1721 elaborate the PEventStatement. Otherwise, create the
1722 right NetPDelay object. */
1725 st
= event_
->elaborate_st(des
, scope
, a2
);
1727 cerr
<< event_
->get_line() << ": error: "
1728 "unable to elaborate event expression."
1736 NetPDelay
*de
= new NetPDelay(delay
, a2
);
1737 de
->set_line(*this);
1741 /* And build up the complex statement. */
1742 NetBlock
*bl
= new NetBlock(NetBlock::SEQU
, 0);
1749 /* Based on the specific type of the l-value, do cleanup
1750 processing on the r-value. */
1751 if (rv
->expr_type() == IVL_VT_REAL
) {
1753 // The r-value is a real. Casting will happen in the
1754 // code generator, so leave it.
1757 unsigned wid
= count_lval_width(lv
);
1759 rv
= pad_to_width(rv
, wid
);
1760 assert(rv
->expr_width() >= wid
);
1763 NetAssign
*cur
= new NetAssign(lv
, rv
);
1764 cur
->set_line(*this);
1770 * Elaborate non-blocking assignments. The statement is of the general
1773 * <lval> <= #<delay> <rval> ;
1775 NetProc
* PAssignNB::elaborate(Design
*des
, NetScope
*scope
) const
1779 if (scope
->in_func()) {
1780 cerr
<< get_line() << ": error: functions cannot have non "
1781 "blocking assignment statements." << endl
;
1786 /* Elaborate the l-value. */
1787 NetAssign_
*lv
= elaborate_lval(des
, scope
);
1788 if (lv
== 0) return 0;
1792 /* Elaborate and precalculate the r-value. */
1793 NetExpr
*rv
= elab_and_eval(des
, scope
, rval(), count_lval_width(lv
));
1797 /* Handle the (common) case that the r-value is a vector. This
1798 includes just about everything but reals. In this case, we
1799 need to pad the r-value to match the width of the l-value.
1801 If in this case the l-val is a variable (i.e. real) then
1802 the width to pad to will be 0, so this code is harmless. */
1803 if (rv
->expr_type() == IVL_VT_REAL
) {
1806 unsigned wid
= count_lval_width(lv
);
1808 rv
= pad_to_width(rv
, wid
);
1813 delay
= elaborate_delay_expr(delay_
, des
, scope
);
1815 /* All done with this node. Mark its line number and check it in. */
1816 NetAssignNB
*cur
= new NetAssignNB(lv
, rv
);
1817 cur
->set_delay(delay
);
1818 cur
->set_line(*this);
1824 * This is the elaboration method for a begin-end block. Try to
1825 * elaborate the entire block, even if it fails somewhere. This way I
1826 * get all the error messages out of it. Then, if I detected a failure
1827 * then pass the failure up.
1829 NetProc
* PBlock::elaborate(Design
*des
, NetScope
*scope
) const
1833 NetBlock::Type type
= (bl_type_
==PBlock::BL_PAR
)
1837 NetScope
*nscope
= 0;
1838 if (name_
.str() != 0) {
1839 nscope
= scope
->child(hname_t(name_
));
1841 cerr
<< get_line() << ": internal error: "
1842 "unable to find block scope " << scope_path(scope
)
1843 << "<" << name_
<< ">" << endl
;
1852 NetBlock
*cur
= new NetBlock(type
, nscope
);
1857 // Handle the special case that the block contains only one
1858 // statement. There is no need to keep the block node. Also,
1859 // don't elide named blocks, because they might be referenced
1861 if ((list_
.count() == 1) && (name_
.str() == 0)) {
1863 NetProc
*tmp
= list_
[0]->elaborate(des
, nscope
);
1867 for (unsigned idx
= 0 ; idx
< list_
.count() ; idx
+= 1) {
1869 NetProc
*tmp
= list_
[idx
]->elaborate(des
, nscope
);
1870 // If the statement fails to elaborate, then simply
1871 // ignore it. Presumably, the elaborate for the
1872 // statement already generated an error message and
1873 // marked the error count in the design so no need to
1874 // do any of that here.
1879 // If the result turns out to be a noop, then skip it.
1880 if (NetBlock
*tbl
= dynamic_cast<NetBlock
*>(tmp
))
1881 if (tbl
->proc_first() == 0) {
1893 * Elaborate a case statement.
1895 NetProc
* PCase::elaborate(Design
*des
, NetScope
*scope
) const
1899 NetExpr
*expr
= elab_and_eval(des
, scope
, expr_
, -1);
1901 cerr
<< get_line() << ": error: Unable to elaborate this case"
1902 " expression." << endl
;
1906 /* Count the items in the case statement. Note that there may
1907 be some cases that have multiple guards. Count each as a
1909 unsigned icount
= 0;
1910 for (unsigned idx
= 0 ; idx
< items_
->count() ; idx
+= 1) {
1911 PCase::Item
*cur
= (*items_
)[idx
];
1913 if (cur
->expr
.count() == 0)
1916 icount
+= cur
->expr
.count();
1919 NetCase
*res
= new NetCase(type_
, expr
, icount
);
1920 res
->set_line(*this);
1922 /* Iterate over all the case items (guard/statement pairs)
1923 elaborating them. If the guard has no expression, then this
1924 is a "default" cause. Otherwise, the guard has one or more
1925 expressions, and each guard is a case. */
1927 for (unsigned idx
= 0 ; idx
< items_
->count() ; idx
+= 1) {
1929 assert(inum
< icount
);
1930 PCase::Item
*cur
= (*items_
)[idx
];
1932 if (cur
->expr
.count() == 0) {
1933 /* If there are no expressions, then this is the
1937 st
= cur
->stat
->elaborate(des
, scope
);
1939 res
->set_case(inum
, 0, st
);
1942 } else for (unsigned e
= 0; e
< cur
->expr
.count(); e
+= 1) {
1944 /* If there are one or more expressions, then
1945 iterate over the guard expressions, elaborating
1946 a separate case for each. (Yes, the statement
1947 will be elaborated again for each.) */
1950 assert(cur
->expr
[e
]);
1951 gu
= elab_and_eval(des
, scope
, cur
->expr
[e
], -1);
1954 st
= cur
->stat
->elaborate(des
, scope
);
1956 res
->set_case(inum
, gu
, st
);
1964 NetProc
* PCondit::elaborate(Design
*des
, NetScope
*scope
) const
1968 if (debug_elaborate
)
1969 cerr
<< get_line() << ": debug: Elaborate condition statement"
1970 << " with conditional: " << *expr_
<< endl
;
1972 // Elaborate and try to evaluate the conditional expression.
1973 NetExpr
*expr
= elab_and_eval(des
, scope
, expr_
, -1);
1975 cerr
<< get_line() << ": error: Unable to elaborate"
1976 " condition expression." << endl
;
1981 // If the condition of the conditional statement is constant,
1982 // then look at the value and elaborate either the if statement
1983 // or the else statement. I don't need both. If there is no
1984 // else_ statement, the use an empty block as a noop.
1985 if (NetEConst
*ce
= dynamic_cast<NetEConst
*>(expr
)) {
1986 verinum val
= ce
->value();
1987 if (debug_elaborate
) {
1988 cerr
<< get_line() << ": debug: Condition expression "
1989 << "is a constant " << val
<< "." << endl
;
1992 verinum::V reduced
= verinum::V0
;
1993 for (unsigned idx
= 0 ; idx
< val
.len() ; idx
+= 1)
1994 reduced
= reduced
| val
[idx
];
1997 if (reduced
== verinum::V1
)
1999 return if_
->elaborate(des
, scope
);
2001 NetBlock
*tmp
= new NetBlock(NetBlock::SEQU
, 0);
2002 tmp
->set_line(*this);
2006 return else_
->elaborate(des
, scope
);
2008 return new NetBlock(NetBlock::SEQU
, 0);
2011 // If the condition expression is more than 1 bits, then
2012 // generate a comparison operator to get the result down to
2013 // one bit. Turn <e> into <e> != 0;
2015 if (expr
->expr_width() < 1) {
2016 cerr
<< get_line() << ": internal error: "
2017 "incomprehensible expression width (0)." << endl
;
2021 if (expr
->expr_width() > 1) {
2022 assert(expr
->expr_width() > 1);
2023 verinum
zero (verinum::V0
, expr
->expr_width());
2024 NetEConst
*ezero
= new NetEConst(zero
);
2025 ezero
->set_width(expr
->expr_width());
2026 NetEBComp
*cmp
= new NetEBComp('n', expr
, ezero
);
2030 // Well, I actually need to generate code to handle the
2031 // conditional, so elaborate.
2032 NetProc
*i
= if_
? if_
->elaborate(des
, scope
) : 0;
2033 NetProc
*e
= else_
? else_
->elaborate(des
, scope
) : 0;
2035 // Detect the special cases that the if or else statements are
2036 // empty blocks. If this is the case, remove the blocks as
2038 if (NetBlock
*tmp
= dynamic_cast<NetBlock
*>(i
)) {
2039 if (tmp
->proc_first() == 0) {
2045 if (NetBlock
*tmp
= dynamic_cast<NetBlock
*>(e
)) {
2046 if (tmp
->proc_first() == 0) {
2052 NetCondit
*res
= new NetCondit(expr
, i
, e
);
2053 res
->set_line(*this);
2057 NetProc
* PCallTask::elaborate(Design
*des
, NetScope
*scope
) const
2059 if (peek_tail_name(path_
)[0] == '$')
2060 return elaborate_sys(des
, scope
);
2062 return elaborate_usr(des
, scope
);
2066 * A call to a system task involves elaborating all the parameters,
2067 * then passing the list to the NetSTask object.
2069 * There is a single special case in the call to a system
2070 * task. Normally, an expression cannot take an unindexed
2071 * memory. However, it is possible to take a system task parameter a
2072 * memory if the expression is trivial.
2074 NetProc
* PCallTask::elaborate_sys(Design
*des
, NetScope
*scope
) const
2078 unsigned parm_count
= nparms();
2080 /* Catch the special case that the system task has no
2081 parameters. The "()" string will be parsed as a single
2082 empty parameter, when we really mean no parameters at all. */
2083 if ((nparms() == 1) && (parm(0) == 0))
2086 svector
<NetExpr
*>eparms (parm_count
);
2088 for (unsigned idx
= 0 ; idx
< parm_count
; idx
+= 1) {
2089 PExpr
*ex
= parm(idx
);
2090 eparms
[idx
] = ex
? ex
->elaborate_expr(des
, scope
, -1, true) : 0;
2092 /* Attempt to pre-evaluate the parameters. It may be
2093 possible to at least partially reduce the
2096 if (NetExpr
*tmp
= eparms
[idx
]->eval_tree()) {
2103 NetSTask
*cur
= new NetSTask(peek_tail_name(path_
), eparms
);
2108 * A call to a user defined task is different from a call to a system
2109 * task because a user task in a netlist has no parameters: the
2110 * assignments are done by the calling thread. For example:
2135 NetProc
* PCallTask::elaborate_usr(Design
*des
, NetScope
*scope
) const
2139 if (scope
->in_func()) {
2140 cerr
<< get_line() << ": error: functions cannot enable/call "
2146 NetScope
*task
= des
->find_task(scope
, path_
);
2148 cerr
<< get_line() << ": error: Enable of unknown task "
2149 << "``" << path_
<< "''." << endl
;
2155 assert(task
->type() == NetScope::TASK
);
2156 NetTaskDef
*def
= task
->task_def();
2158 cerr
<< get_line() << ": internal error: task " << path_
2159 << " doesn't have a definition in " << scope_path(scope
)
2166 if (nparms() != def
->port_count()) {
2167 cerr
<< get_line() << ": error: Port count mismatch in call to ``"
2168 << path_
<< "''. Got " << nparms()
2169 << " ports, expecting " << def
->port_count() << " ports." << endl
;
2176 /* Handle tasks with no parameters specially. There is no need
2177 to make a sequential block to hold the generated code. */
2178 if (nparms() == 0) {
2179 cur
= new NetUTask(task
);
2180 cur
->set_line(*this);
2184 NetBlock
*block
= new NetBlock(NetBlock::SEQU
, 0);
2187 /* Detect the case where the definition of the task is known
2188 empty. In this case, we need not bother with calls to the
2189 task, all the assignments, etc. Just return a no-op. */
2191 if (const NetBlock
*tp
= dynamic_cast<const NetBlock
*>(def
->proc())) {
2192 if (tp
->proc_first() == 0)
2196 /* Generate assignment statement statements for the input and
2197 INOUT ports of the task. These are managed by writing
2198 assignments with the task port the l-value and the passed
2199 expression the r-value. We know by definition that the port
2200 is a reg type, so this elaboration is pretty obvious. */
2202 for (unsigned idx
= 0 ; idx
< nparms() ; idx
+= 1) {
2204 NetNet
*port
= def
->port(idx
);
2205 assert(port
->port_type() != NetNet::NOT_A_PORT
);
2206 if (port
->port_type() == NetNet::POUTPUT
)
2209 NetAssign_
*lv
= new NetAssign_(port
);
2210 unsigned wid
= count_lval_width(lv
);
2212 NetExpr
*rv
= elab_and_eval(des
, scope
, parms_
[idx
], wid
);
2214 rv
= pad_to_width(rv
, wid
);
2215 NetAssign
*pr
= new NetAssign(lv
, rv
);
2219 /* Generate the task call proper... */
2220 cur
= new NetUTask(task
);
2221 cur
->set_line(*this);
2225 /* Generate assignment statements for the output and INOUT
2226 ports of the task. The l-value in this case is the
2227 expression passed as a parameter, and the r-value is the
2228 port to be copied out.
2230 We know by definition that the r-value of this copy-out is
2231 the port, which is a reg. The l-value, however, may be any
2232 expression that can be a target to a procedural
2233 assignment, including a memory word. */
2235 for (unsigned idx
= 0 ; idx
< nparms() ; idx
+= 1) {
2237 NetNet
*port
= def
->port(idx
);
2239 /* Skip input ports. */
2240 assert(port
->port_type() != NetNet::NOT_A_PORT
);
2241 if (port
->port_type() == NetNet::PINPUT
)
2245 /* Elaborate an l-value version of the port expression
2246 for output and inout ports. If the expression does
2247 not exist then quietly skip it, but if the expression
2248 is not a valid l-value print an error message. Note
2249 that the elaborate_lval method already printed a
2250 detailed message. */
2253 lv
= parms_
[idx
]->elaborate_lval(des
, scope
, false);
2255 cerr
<< parms_
[idx
]->get_line() << ": error: "
2256 << "I give up on task port " << (idx
+1)
2257 << " expression: " << *parms_
[idx
] << endl
;
2266 NetESignal
*sig
= new NetESignal(port
);
2267 NetExpr
*rv
= pad_to_width(sig
, count_lval_width(lv
));
2269 /* Generate the assignment statement. */
2270 NetAssign
*ass
= new NetAssign(lv
, rv
);
2279 * Elaborate a procedural continuous assign. This really looks very
2280 * much like other procedural assignments, at this point, but there
2281 * is no delay to worry about. The code generator will take care of
2282 * the differences between continuous assign and normal assignments.
2284 NetCAssign
* PCAssign::elaborate(Design
*des
, NetScope
*scope
) const
2289 NetAssign_
*lval
= lval_
->elaborate_lval(des
, scope
, false);
2293 unsigned lwid
= count_lval_width(lval
);
2295 NetExpr
*rexp
= elab_and_eval(des
, scope
, expr_
, lwid
);
2299 rexp
->set_width(lwid
);
2300 rexp
= pad_to_width(rexp
, lwid
);
2302 dev
= new NetCAssign(lval
, rexp
);
2304 if (debug_elaborate
) {
2305 cerr
<< get_line() << ": debug: Elaborate cassign,"
2306 << " lval width=" << lwid
2307 << " rval width=" << rexp
->expr_width()
2308 << " rval=" << *rexp
2312 dev
->set_line(*this);
2316 NetDeassign
* PDeassign::elaborate(Design
*des
, NetScope
*scope
) const
2320 NetAssign_
*lval
= lval_
->elaborate_lval(des
, scope
, false);
2324 NetDeassign
*dev
= new NetDeassign(lval
);
2325 dev
->set_line( *this );
2330 * Elaborate the delay statement (of the form #<expr> <statement>) as a
2331 * NetPDelay object. If the expression is constant, evaluate it now
2332 * and make a constant delay. If not, then pass an elaborated
2333 * expression to the constructor of NetPDelay so that the code
2334 * generator knows to evaluate the expression at run time.
2336 NetProc
* PDelayStatement::elaborate(Design
*des
, NetScope
*scope
) const
2340 if (scope
->in_func()) {
2341 cerr
<< get_line() << ": error: functions cannot have "
2342 "delay statements." << endl
;
2347 /* This call evaluates the delay expression to a NetEConst, if
2348 possible. This includes transforming NetECReal values to
2349 integers, and applying the proper scaling. */
2350 NetExpr
*dex
= elaborate_delay_expr(delay_
, des
, scope
);
2352 if (NetEConst
*tmp
= dynamic_cast<NetEConst
*>(dex
)) {
2354 return new NetPDelay(tmp
->value().as_ulong64(),
2355 statement_
->elaborate(des
, scope
));
2357 return new NetPDelay(tmp
->value().as_ulong(), 0);
2363 return new NetPDelay(dex
, statement_
->elaborate(des
, scope
));
2365 return new NetPDelay(dex
, 0);
2371 * The disable statement is not yet supported.
2373 NetProc
* PDisable::elaborate(Design
*des
, NetScope
*scope
) const
2377 list
<hname_t
> spath
= eval_scope_path(des
, scope
, scope_
);
2379 NetScope
*target
= des
->find_scope(scope
, spath
);
2381 cerr
<< get_line() << ": error: Cannot find scope "
2382 << scope_
<< " in " << scope_path(scope
) << endl
;
2387 switch (target
->type()) {
2388 case NetScope::FUNC
:
2389 cerr
<< get_line() << ": error: Cannot disable functions." << endl
;
2393 case NetScope::MODULE
:
2394 cerr
<< get_line() << ": error: Cannot disable modules." << endl
;
2402 NetDisable
*obj
= new NetDisable(target
);
2403 obj
->set_line(*this);
2408 * An event statement is an event delay of some sort, attached to a
2409 * statement. Some Verilog examples are:
2411 * @(posedge CLK) $display("clock rise");
2412 * @event_1 $display("event triggered.");
2413 * @(data or negedge clk) $display("data or clock fall.");
2415 * The elaborated netlist uses the NetEvent, NetEvWait and NetEvProbe
2416 * classes. The NetEvWait class represents the part of the netlist
2417 * that is executed by behavioral code. The process starts waiting on
2418 * the NetEvent when it executes the NetEvWait step. Net NetEvProbe
2419 * and NetEvTrig are structural and behavioral equivalents that
2420 * trigger the event, and awakens any processes blocking in the
2423 * The basic data structure is:
2425 * NetEvWait ---/---> NetEvent <----\---- NetEvProbe
2427 * NetEvWait ---+ +---- NetEvProbe
2431 * That is, many NetEvWait statements may wait on a single NetEvent
2432 * object, and Many NetEvProbe objects may trigger the NetEvent
2433 * object. The many NetEvWait objects pointing to the NetEvent object
2434 * reflects the possibility of different places in the code blocking
2435 * on the same named event, like so:
2439 * always begin @foo <statement1>; @foo <statement2> end
2441 * This tends to not happen with signal edges. The multiple probes
2442 * pointing to the same event reflect the possibility of many
2443 * expressions in the same blocking statement, like so:
2447 * always @(reset or posedge clk) <stmt>;
2449 * Conjunctions like this cause a NetEvent object be created to
2450 * represent the overall conjunction, and NetEvProbe objects for each
2453 * If the NetEvent object represents a named event from the source,
2454 * then there are NetEvTrig objects that represent the trigger
2455 * statements instead of the NetEvProbe objects representing signals.
2459 * always @foo <stmt>;
2468 * Each trigger statement in the source generates a separate NetEvTrig
2469 * object in the netlist. Those trigger objects are elaborated
2472 * Additional complications arise when named events show up in
2473 * conjunctions. An example of such a case is:
2477 * always @(foo or posedge bar) <stmt>;
2479 * Since there is by definition a NetEvent object for the foo object,
2480 * this is handled by allowing the NetEvWait object to point to
2481 * multiple NetEvent objects. All the NetEvProbe based objects are
2482 * collected and pointed as the synthetic NetEvent object, and all the
2483 * named events are added into the list of NetEvent object that the
2484 * NetEvWait object can refer to.
2487 NetProc
* PEventStatement::elaborate_st(Design
*des
, NetScope
*scope
,
2492 if (scope
->in_func()) {
2493 cerr
<< get_line() << ": error: functions cannot have "
2494 "event statements." << endl
;
2499 /* Create a single NetEvent and NetEvWait. Then, create a
2500 NetEvProbe for each conjunctive event in the event
2501 list. The NetEvProbe objects all refer back to the NetEvent
2504 NetEvent
*ev
= new NetEvent(scope
->local_symbol());
2505 ev
->set_line(*this);
2506 unsigned expr_count
= 0;
2508 NetEvWait
*wa
= new NetEvWait(enet
);
2509 wa
->set_line(*this);
2511 /* If there are no expressions, this is a signal that it is an
2512 @* statement. Generate an expression to use. */
2514 if (expr_
.count() == 0) {
2516 NexusSet
*nset
= enet
->nex_input();
2518 cerr
<< get_line() << ": internal error: No NexusSet"
2519 << " from statement." << endl
;
2520 enet
->dump(cerr
, 6);
2525 if (nset
->count() == 0) {
2526 cerr
<< get_line() << ": error: No inputs to statement."
2527 << " The @* cannot execute." << endl
;
2532 NetEvProbe
*pr
= new NetEvProbe(scope
, scope
->local_symbol(),
2533 ev
, NetEvProbe::ANYEDGE
,
2535 for (unsigned idx
= 0 ; idx
< nset
->count() ; idx
+= 1)
2536 connect(nset
[0][idx
], pr
->pin(idx
));
2543 } else for (unsigned idx
= 0 ; idx
< expr_
.count() ; idx
+= 1) {
2545 assert(expr_
[idx
]->expr());
2547 /* If the expression is an identifier that matches a
2548 named event, then handle this case all at once at
2549 skip the rest of the expression handling. */
2551 if (PEIdent
*id
= dynamic_cast<PEIdent
*>(expr_
[idx
]->expr())) {
2553 const NetExpr
*par
= 0;
2556 NetScope
*found_in
= symbol_search(des
, scope
, id
->path(),
2559 if (found_in
&& eve
) {
2566 /* So now we have a normal event expression. Elaborate
2567 the sub-expression as a net and decide how to handle
2570 bool save_flag
= error_implicit
;
2571 error_implicit
= true;
2572 NetNet
*expr
= expr_
[idx
]->expr()->elaborate_net(des
, scope
,
2574 error_implicit
= save_flag
;
2576 expr_
[idx
]->dump(cerr
);
2583 unsigned pins
= (expr_
[idx
]->type() == PEEvent::ANYEDGE
)
2584 ? expr
->pin_count() : 1;
2587 switch (expr_
[idx
]->type()) {
2588 case PEEvent::POSEDGE
:
2589 pr
= new NetEvProbe(scope
, scope
->local_symbol(), ev
,
2590 NetEvProbe::POSEDGE
, pins
);
2593 case PEEvent::NEGEDGE
:
2594 pr
= new NetEvProbe(scope
, scope
->local_symbol(), ev
,
2595 NetEvProbe::NEGEDGE
, pins
);
2598 case PEEvent::ANYEDGE
:
2599 pr
= new NetEvProbe(scope
, scope
->local_symbol(), ev
,
2600 NetEvProbe::ANYEDGE
, pins
);
2607 for (unsigned p
= 0 ; p
< pr
->pin_count() ; p
+= 1)
2608 connect(pr
->pin(p
), expr
->pin(p
));
2614 /* If there was at least one conjunction that was an
2615 expression (and not a named event) then add this
2616 event. Otherwise, we didn't use it so delete it. */
2617 if (expr_count
> 0) {
2618 scope
->add_event(ev
);
2620 /* NOTE: This event that I am adding to the wait may be
2621 a duplicate of another event somewhere else. However,
2622 I don't know that until all the modules are hooked
2623 up, so it is best to leave find_similar_event to
2624 after elaboration. */
2633 * This is the special case of the event statement, the wait
2634 * statement. This is elaborated into a slightly more complicated
2635 * statement that uses non-wait statements:
2637 * wait (<expr>) <statement>
2642 * while (1 !== <expr>)
2643 * @(<expr inputs>) <noop>;
2647 NetProc
* PEventStatement::elaborate_wait(Design
*des
, NetScope
*scope
,
2651 assert(expr_
.count() == 1);
2653 if (scope
->in_func()) {
2654 cerr
<< get_line() << ": error: functions cannot have "
2655 "wait statements." << endl
;
2660 const PExpr
*pe
= expr_
[0]->expr();
2662 /* Elaborate wait expression. Don't eval yet, we will do that
2663 shortly, after we apply a reduction or. */
2664 NetExpr
*expr
= pe
->elaborate_expr(des
, scope
, -1, false);
2666 cerr
<< get_line() << ": error: Unable to elaborate"
2667 " wait condition expression." << endl
;
2672 // If the condition expression is more than 1 bits, then
2673 // generate a reduction operator to get the result down to
2674 // one bit. In other words, Turn <e> into |<e>;
2676 if (expr
->expr_width() < 1) {
2677 cerr
<< get_line() << ": internal error: "
2678 "incomprehensible wait expression width (0)." << endl
;
2682 if (expr
->expr_width() > 1) {
2683 assert(expr
->expr_width() > 1);
2684 NetEUReduce
*cmp
= new NetEUReduce('|', expr
);
2688 /* precalculate as much as possible of the wait expression. */
2689 if (NetExpr
*tmp
= expr
->eval_tree()) {
2694 /* Detect the unusual case that the wait expression is
2695 constant. Constant true is OK (it becomes transparent) but
2696 constant false is almost certainly not what is intended. */
2697 assert(expr
->expr_width() == 1);
2698 if (NetEConst
*ce
= dynamic_cast<NetEConst
*>(expr
)) {
2699 verinum val
= ce
->value();
2700 assert(val
.len() == 1);
2702 /* Constant true -- wait(1) <s1> reduces to <s1>. */
2703 if (val
[0] == verinum::V1
) {
2709 /* Otherwise, false. wait(0) blocks permanently. */
2711 cerr
<< get_line() << ": warning: wait expression is "
2712 << "constant false." << endl
;
2713 cerr
<< get_line() << ": : The statement will "
2714 << "block permanently." << endl
;
2716 /* Create an event wait and an otherwise unreferenced
2717 event variable to force a perpetual wait. */
2718 NetEvent
*wait_event
= new NetEvent(scope
->local_symbol());
2719 scope
->add_event(wait_event
);
2721 NetEvWait
*wait
= new NetEvWait(0);
2722 wait
->add_event(wait_event
);
2723 wait
->set_line(*this);
2730 /* Invert the sense of the test with an exclusive NOR. In
2731 other words, if this adjusted expression returns TRUE, then
2733 assert(expr
->expr_width() == 1);
2734 expr
= new NetEBComp('N', expr
, new NetEConst(verinum(verinum::V1
)));
2735 NetExpr
*tmp
= expr
->eval_tree();
2741 NetEvent
*wait_event
= new NetEvent(scope
->local_symbol());
2742 scope
->add_event(wait_event
);
2744 NetEvWait
*wait
= new NetEvWait(0 /* noop */);
2745 wait
->add_event(wait_event
);
2746 wait
->set_line(*this);
2748 NexusSet
*wait_set
= expr
->nex_input();
2749 if (wait_set
== 0) {
2750 cerr
<< get_line() << ": internal error: No NexusSet"
2751 << " from wait expression." << endl
;
2756 if (wait_set
->count() == 0) {
2757 cerr
<< get_line() << ": internal error: Empty NexusSet"
2758 << " from wait expression." << endl
;
2763 NetEvProbe
*wait_pr
= new NetEvProbe(scope
, scope
->local_symbol(),
2764 wait_event
, NetEvProbe::ANYEDGE
,
2766 for (unsigned idx
= 0; idx
< wait_set
->count() ; idx
+= 1)
2767 connect(wait_set
[0][idx
], wait_pr
->pin(idx
));
2770 des
->add_node(wait_pr
);
2772 NetWhile
*loop
= new NetWhile(expr
, wait
);
2773 loop
->set_line(*this);
2775 /* If there is no real substatement (i.e., "wait (foo) ;") then
2780 /* Create a sequential block to combine the wait loop and the
2781 delayed statement. */
2782 NetBlock
*block
= new NetBlock(NetBlock::SEQU
, 0);
2783 block
->append(loop
);
2784 block
->append(enet
);
2785 block
->set_line(*this);
2791 NetProc
* PEventStatement::elaborate(Design
*des
, NetScope
*scope
) const
2795 enet
= statement_
->elaborate(des
, scope
);
2800 enet
= new NetBlock(NetBlock::SEQU
, 0);
2801 enet
->set_line(*this);
2804 if ((expr_
.count() == 1) && (expr_
[0]->type() == PEEvent::POSITIVE
))
2805 return elaborate_wait(des
, scope
, enet
);
2807 return elaborate_st(des
, scope
, enet
);
2811 * Forever statements are represented directly in the netlist. It is
2812 * theoretically possible to use a while structure with a constant
2813 * expression to represent the loop, but why complicate the code
2816 NetProc
* PForever::elaborate(Design
*des
, NetScope
*scope
) const
2818 NetProc
*stat
= statement_
->elaborate(des
, scope
);
2819 if (stat
== 0) return 0;
2821 NetForever
*proc
= new NetForever(stat
);
2826 * Force is like a procedural assignment, most notably prodedural
2827 * continuous assignment:
2829 * force <lval> = <rval>
2831 * The <lval> can be anything that a normal behavioral assignment can
2832 * take, plus net signals. This is a little bit more lax then the
2833 * other proceedural assignments.
2835 NetForce
* PForce::elaborate(Design
*des
, NetScope
*scope
) const
2840 NetAssign_
*lval
= lval_
->elaborate_lval(des
, scope
, true);
2844 unsigned lwid
= count_lval_width(lval
);
2846 NetExpr
*rexp
= elab_and_eval(des
, scope
, expr_
, lwid
);
2850 rexp
->set_width(lwid
, true);
2851 rexp
= pad_to_width(rexp
, lwid
);
2853 dev
= new NetForce(lval
, rexp
);
2855 if (debug_elaborate
) {
2856 cerr
<< get_line() << ": debug: ELaborate force,"
2857 << " lval width=" << lval
->lwidth()
2858 << " rval width=" << rexp
->expr_width()
2859 << " rval=" << *rexp
2863 dev
->set_line(*this);
2868 * elaborate the for loop as the equivalent while loop. This eases the
2869 * task for the target code generator. The structure is:
2873 * while (cond_) begin : body
2879 NetProc
* PForStatement::elaborate(Design
*des
, NetScope
*scope
) const
2884 const PEIdent
*id1
= dynamic_cast<const PEIdent
*>(name1_
);
2886 const PEIdent
*id2
= dynamic_cast<const PEIdent
*>(name2_
);
2889 NetBlock
*top
= new NetBlock(NetBlock::SEQU
, 0);
2890 top
->set_line(*this);
2892 /* make the expression, and later the initial assignment to
2893 the condition variable. The statement in the for loop is
2894 very specifically an assignment. */
2895 NetNet
*sig
= des
->find_signal(scope
, id1
->path());
2897 cerr
<< id1
->get_line() << ": register ``" << id1
->path()
2898 << "'' unknown in this context." << endl
;
2903 NetAssign_
*lv
= new NetAssign_(sig
);
2905 /* Calculate the width of the initialization as if this were
2906 any other assignment statement. */
2907 unsigned use_width
= lv
->lwidth();
2908 bool unsized_flag
= false;
2909 use_width
= expr1_
->test_width(des
, scope
, use_width
, use_width
, unsized_flag
);
2911 /* Make the r-value of the initial assignment, and size it
2912 properly. Then use it to build the assignment statement. */
2913 etmp
= elab_and_eval(des
, scope
, expr1_
, use_width
);
2914 etmp
->set_width(use_width
);
2915 etmp
= pad_to_width(etmp
, use_width
);
2917 if (debug_elaborate
) {
2918 cerr
<< get_line() << ": debug: FOR initial assign: "
2919 << sig
->name() << " = " << *etmp
<< endl
;
2920 assert(etmp
->expr_width() >= lv
->lwidth());
2923 NetAssign
*init
= new NetAssign(lv
, etmp
);
2924 init
->set_line(*this);
2928 NetBlock
*body
= new NetBlock(NetBlock::SEQU
, 0);
2929 body
->set_line(*this);
2931 /* Elaborate the statement that is contained in the for
2932 loop. If there is an error, this will return 0 and I should
2933 skip the append. No need to worry, the error has been
2934 reported so it's OK that the netlist is bogus. */
2935 NetProc
*tmp
= statement_
->elaborate(des
, scope
);
2940 /* Elaborate the increment assignment statement at the end of
2941 the for loop. This is also a very specific assignment
2942 statement. Put this into the "body" block. */
2943 sig
= des
->find_signal(scope
, id2
->path());
2945 cerr
<< get_line() << ": error: Unable to find variable "
2946 << id2
->path() << " in for-loop increment expressin." << endl
;
2952 lv
= new NetAssign_(sig
);
2954 /* Make the rvalue of the increment expression, and size it
2956 etmp
= elab_and_eval(des
, scope
, expr2_
, lv
->lwidth());
2957 NetAssign
*step
= new NetAssign(lv
, etmp
);
2958 step
->set_line(*this);
2963 /* Elaborate the condition expression. Try to evaluate it too,
2964 in case it is a constant. This is an interesting case
2965 worthy of a warning. */
2966 NetExpr
*ce
= elab_and_eval(des
, scope
, cond_
, -1);
2972 if (dynamic_cast<NetEConst
*>(ce
)) {
2973 cerr
<< get_line() << ": warning: condition expression "
2974 "of for-loop is constant." << endl
;
2978 /* All done, build up the loop. */
2980 NetWhile
*loop
= new NetWhile(ce
, body
);
2981 loop
->set_line(*this);
2987 * (See the PTask::elaborate methods for basic common stuff.)
2989 * The return value of a function is represented as a reg variable
2990 * within the scope of the function that has the name of the
2991 * function. So for example with the function:
2993 * function [7:0] incr;
2998 * The scope of the function is <parent>.incr and there is a reg
2999 * variable <parent>.incr.incr. The elaborate_1 method is called with
3000 * the scope of the function, so the return reg is easily located.
3002 * The function parameters are all inputs, except for the synthetic
3003 * output parameter that is the return value. The return value goes
3004 * into port 0, and the parameters are all the remaining ports.
3007 void PFunction::elaborate(Design
*des
, NetScope
*scope
) const
3009 NetFuncDef
*def
= scope
->func_def();
3011 cerr
<< get_line() << ": internal error: "
3012 << "No function definition for function "
3013 << scope_path(scope
) << endl
;
3019 NetProc
*st
= statement_
->elaborate(des
, scope
);
3021 cerr
<< statement_
->get_line() << ": error: Unable to elaborate "
3022 "statement in function " << scope
->basename() << "." << endl
;
3030 NetProc
* PRelease::elaborate(Design
*des
, NetScope
*scope
) const
3034 NetAssign_
*lval
= lval_
->elaborate_lval(des
, scope
, true);
3038 NetRelease
*dev
= new NetRelease(lval
);
3039 dev
->set_line( *this );
3043 NetProc
* PRepeat::elaborate(Design
*des
, NetScope
*scope
) const
3047 NetExpr
*expr
= elab_and_eval(des
, scope
, expr_
, -1);
3049 cerr
<< get_line() << ": Unable to elaborate"
3050 " repeat expression." << endl
;
3055 NetProc
*stat
= statement_
->elaborate(des
, scope
);
3056 if (stat
== 0) return 0;
3058 // If the expression is a constant, handle certain special
3059 // iteration counts.
3060 if (NetEConst
*ce
= dynamic_cast<NetEConst
*>(expr
)) {
3061 verinum val
= ce
->value();
3062 switch (val
.as_ulong()) {
3066 return new NetBlock(NetBlock::SEQU
, 0);
3075 NetRepeat
*proc
= new NetRepeat(expr
, stat
);
3080 * A task definition is elaborated by elaborating the statement that
3081 * it contains, and connecting its ports to NetNet objects. The
3082 * netlist doesn't really need the array of parameters once elaboration
3083 * is complete, but this is the best place to store them.
3085 * The first elaboration pass finds the reg objects that match the
3086 * port names, and creates the NetTaskDef object. The port names are
3087 * in the form task.port.
3094 * So in the foo example, the PWire objects that represent the ports
3095 * of the task will include a foo.blah for the blah port. This port is
3096 * bound to a NetNet object by looking up the name. All of this is
3097 * handled by the PTask::elaborate_sig method and the results stashed
3098 * in the created NetTaskDef attached to the scope.
3100 * Elaboration pass 2 for the task definition causes the statement of
3101 * the task to be elaborated and attached to the NetTaskDef object
3102 * created in pass 1.
3104 * NOTE: I am not sure why I bothered to prepend the task name to the
3105 * port name when making the port list. It is not really useful, but
3106 * that is what I did in pform_make_task_ports, so there it is.
3109 void PTask::elaborate(Design
*des
, NetScope
*task
) const
3111 NetTaskDef
*def
= task
->task_def();
3115 if (statement_
== 0) {
3116 st
= new NetBlock(NetBlock::SEQU
, 0);
3120 st
= statement_
->elaborate(des
, task
);
3122 cerr
<< statement_
->get_line() << ": Unable to elaborate "
3123 "statement in task " << scope_path(task
)
3124 << " at " << get_line() << "." << endl
;
3132 NetProc
* PTrigger::elaborate(Design
*des
, NetScope
*scope
) const
3137 const NetExpr
*par
= 0;
3140 NetScope
*found_in
= symbol_search(des
, scope
, event_
,
3143 if (found_in
== 0) {
3144 cerr
<< get_line() << ": error: event <" << event_
<< ">"
3145 << " not found." << endl
;
3151 cerr
<< get_line() << ": error: <" << event_
<< ">"
3152 << " is not a named event." << endl
;
3157 NetEvTrig
*trig
= new NetEvTrig(eve
);
3158 trig
->set_line(*this);
3163 * The while loop is fairly directly represented in the netlist.
3165 NetProc
* PWhile::elaborate(Design
*des
, NetScope
*scope
) const
3167 NetWhile
*loop
= new NetWhile(elab_and_eval(des
, scope
, cond_
, -1),
3168 statement_
->elaborate(des
, scope
));
3172 bool PProcess::elaborate(Design
*des
, NetScope
*scope
) const
3174 NetProc
*cur
= statement_
->elaborate(des
, scope
);
3181 case PProcess::PR_INITIAL
:
3182 top
= new NetProcTop(scope
, NetProcTop::KINITIAL
, cur
);
3184 case PProcess::PR_ALWAYS
:
3185 top
= new NetProcTop(scope
, NetProcTop::KALWAYS
, cur
);
3188 ivl_assert(*this, top
);
3190 // Evaluate the attributes for this process, if there
3191 // are any. These attributes are to be attached to the
3192 // NetProcTop object.
3193 struct attrib_list_t
*attrib_list
= 0;
3194 unsigned attrib_list_n
= 0;
3195 attrib_list
= evaluate_attributes(attributes
, attrib_list_n
, des
, scope
);
3197 for (unsigned adx
= 0 ; adx
< attrib_list_n
; adx
+= 1)
3198 top
->attribute(attrib_list
[adx
].key
,
3199 attrib_list
[adx
].val
);
3201 delete[]attrib_list
;
3203 top
->set_line(*this);
3204 des
->add_process(top
);
3206 /* Detect the special case that this is a combinational
3207 always block. We want to attach an _ivl_schedule_push
3208 attribute to this process so that it starts up and
3209 gets into its wait statement before non-combinational
3210 code is executed. */
3212 if (top
->type() != NetProcTop::KALWAYS
)
3215 NetEvWait
*st
= dynamic_cast<NetEvWait
*>(top
->statement());
3219 if (st
->nevents() != 1)
3222 NetEvent
*ev
= st
->event(0);
3224 if (ev
->nprobe() == 0)
3227 bool anyedge_test
= true;
3228 for (unsigned idx
= 0 ; anyedge_test
&& (idx
<ev
->nprobe())
3230 const NetEvProbe
*pr
= ev
->probe(idx
);
3231 if (pr
->edge() != NetEvProbe::ANYEDGE
)
3232 anyedge_test
= false;
3238 top
->attribute(perm_string::literal("_ivl_schedule_push"),
3245 void PSpecPath::elaborate(Design
*des
, NetScope
*scope
) const
3247 uint64_t delay_value
[12];
3248 unsigned ndelays
= 0;
3250 /* Do not elaborate specify delay paths if this feature is
3252 if (!gn_specify_blocks_flag
)
3255 /* Check for various path types that are not supported. */
3256 if (conditional
&& !condition
) {
3257 cerr
<< get_line() << ": sorry: ifnone specify paths"
3258 << " are not supported." << endl
;
3259 cerr
<< get_line() << ": : Use -g no-specify to ignore"
3260 << " specify blocks." << endl
;
3265 ivl_assert(*this, conditional
|| (condition
==0));
3267 ndelays
= delays
.size();
3271 int shift
= scope
->time_unit() - des
->get_precision();
3273 /* Elaborate the delay values themselves. Remember to scale
3274 them for the timescale/precision of the scope. */
3275 for (unsigned idx
= 0 ; idx
< ndelays
; idx
+= 1) {
3276 PExpr
*exp
= delays
[idx
];
3277 NetExpr
*cur
= elab_and_eval(des
, scope
, exp
, 0);
3279 if (NetEConst
*cur_con
= dynamic_cast<NetEConst
*> (cur
)) {
3280 delay_value
[idx
] = cur_con
->value().as_ulong();
3281 for (int tmp
= 0 ; tmp
< shift
; tmp
+= 1)
3282 delay_value
[idx
] *= 10;
3284 } else if (NetECReal
*cur_rcon
= dynamic_cast<NetECReal
*>(cur
)) {
3285 delay_value
[idx
] = cur_rcon
->value().as_long(shift
);
3288 cerr
<< get_line() << ": error: Path delay value "
3289 << "must be constant." << endl
;
3290 delay_value
[idx
] = 0;
3304 cerr
<< get_line() << ": error: Incorrect delay configuration."
3311 NetNet
*condit_sig
= 0;
3313 ivl_assert(*this, condition
);
3315 NetExpr
*tmp
= elab_and_eval(des
, scope
, condition
, -1);
3316 ivl_assert(*condition
, tmp
);
3318 // FIXME: Look for constant expressions here?
3321 condit_sig
= tmp
->synthesize(des
);
3322 ivl_assert(*condition
, condit_sig
);
3325 /* Create all the various paths from the path specifier. */
3326 typedef std::vector
<perm_string
>::const_iterator str_vector_iter
;
3327 for (str_vector_iter cur
= dst
.begin()
3328 ; cur
!= dst
.end() ; cur
++) {
3330 if (debug_elaborate
) {
3331 cerr
<< get_line() << ": debug: Path to " << (*cur
);
3333 cerr
<< " if " << condit_sig
->name();
3337 NetNet
*dst_sig
= scope
->find_signal(*cur
);
3339 cerr
<< get_line() << ": error: No such wire "
3340 << *cur
<< " in this module." << endl
;
3345 if (dst_sig
->port_type() != NetNet::POUTPUT
3346 && dst_sig
->port_type() != NetNet::PINOUT
) {
3348 cerr
<< get_line() << ": error: Path destination "
3349 << *cur
<< " must be an output or inout port." << endl
;
3353 NetDelaySrc
*path
= new NetDelaySrc(scope
, scope
->local_symbol(),
3354 src
.size(), condit_sig
);
3355 path
->set_line(*this);
3357 // The presence of the data_source_expression indicates
3358 // that this is an edge sensitive path. If so, then set
3359 // the edges. Note that edge==0 is BOTH edges.
3360 if (data_source_expression
) {
3361 if (edge
>= 0) path
->set_posedge();
3362 if (edge
<= 0) path
->set_negedge();
3367 path
->set_delays(delay_value
[0], delay_value
[1],
3368 delay_value
[2], delay_value
[3],
3369 delay_value
[4], delay_value
[5],
3370 delay_value
[6], delay_value
[7],
3371 delay_value
[8], delay_value
[9],
3372 delay_value
[10], delay_value
[11]);
3375 path
->set_delays(delay_value
[0], delay_value
[1],
3376 delay_value
[2], delay_value
[3],
3377 delay_value
[4], delay_value
[5]);
3380 path
->set_delays(delay_value
[0], delay_value
[1],
3384 path
->set_delays(delay_value
[0], delay_value
[1]);
3387 path
->set_delays(delay_value
[0]);
3392 for (str_vector_iter cur_src
= src
.begin()
3393 ; cur_src
!= src
.end() ; cur_src
++) {
3394 NetNet
*src_sig
= scope
->find_signal(*cur_src
);
3397 if (src_sig
->port_type() != NetNet::PINPUT
3398 & src_sig
->port_type() != NetNet::PINOUT
) {
3400 cerr
<< get_line() << ": error: Path source "
3401 << *cur_src
<< " must be an input or inout port."
3406 connect(src_sig
->pin(0), path
->pin(idx
));
3411 connect(condit_sig
->pin(0), path
->pin(idx
));
3413 dst_sig
->add_delay_path(path
);
3419 * When a module is instantiated, it creates the scope then uses this
3420 * method to elaborate the contents of the module.
3422 bool Module::elaborate(Design
*des
, NetScope
*scope
) const
3424 bool result_flag
= true;
3426 if (gn_specify_blocks_flag
) {
3427 // Elaborate specparams
3428 typedef map
<perm_string
,PExpr
*>::const_iterator specparam_it_t
;
3429 for (specparam_it_t cur
= specparams
.begin()
3430 ; cur
!= specparams
.end() ; cur
++ ) {
3432 NetExpr
*val
= elab_and_eval(des
, scope
, (*cur
).second
, -1);
3433 NetScope::spec_val_t value
;
3435 if (NetECReal
*val_c
= dynamic_cast<NetECReal
*> (val
)) {
3437 value
.type
= IVL_VT_REAL
;
3438 value
.real_val
= val_c
->value().as_double();
3440 if (debug_elaborate
)
3441 cerr
<< get_line() << ": debug: Elaborate "
3442 << "specparam " << (*cur
).first
3443 << " value=" << value
.real_val
<< endl
;
3445 } else if (NetEConst
*val_c
= dynamic_cast<NetEConst
*> (val
)) {
3447 value
.type
= IVL_VT_BOOL
;
3448 value
.integer
= val_c
->value().as_long();
3450 if (debug_elaborate
)
3451 cerr
<< get_line() << ": debug: Elaborate "
3452 << "specparam " << (*cur
).first
3453 << " value=" << value
.integer
<< endl
;
3456 value
.type
= IVL_VT_NO_TYPE
;
3457 cerr
<< (*cur
).second
->get_line() << ": error: "
3458 << "specparam " << (*cur
).first
<< " value"
3459 << " is not constant: " << *val
<< endl
;
3465 scope
->specparams
[(*cur
).first
] = value
;
3469 // Elaborate within the generate blocks.
3470 typedef list
<PGenerate
*>::const_iterator generate_it_t
;
3471 for (generate_it_t cur
= generate_schemes
.begin()
3472 ; cur
!= generate_schemes
.end() ; cur
++ ) {
3473 (*cur
)->elaborate(des
, scope
);
3476 // Elaborate functions.
3477 typedef map
<perm_string
,PFunction
*>::const_iterator mfunc_it_t
;
3478 for (mfunc_it_t cur
= funcs_
.begin()
3479 ; cur
!= funcs_
.end() ; cur
++) {
3481 hname_t
use_name ( (*cur
).first
);
3482 NetScope
*fscope
= scope
->child(use_name
);
3484 (*cur
).second
->elaborate(des
, fscope
);
3487 // Elaborate the task definitions. This is done before the
3488 // behaviors so that task calls may reference these, and after
3489 // the signals so that the tasks can reference them.
3490 typedef map
<perm_string
,PTask
*>::const_iterator mtask_it_t
;
3491 for (mtask_it_t cur
= tasks_
.begin()
3492 ; cur
!= tasks_
.end() ; cur
++) {
3494 hname_t
use_name ( (*cur
).first
);
3495 NetScope
*tscope
= scope
->child(use_name
);
3497 (*cur
).second
->elaborate(des
, tscope
);
3500 // Get all the gates of the module and elaborate them by
3501 // connecting them to the signals. The gate may be simple or
3503 const list
<PGate
*>&gl
= get_gates();
3505 for (list
<PGate
*>::const_iterator gt
= gl
.begin()
3509 (*gt
)->elaborate(des
, scope
);
3512 // Elaborate the behaviors, making processes out of them. This
3513 // involves scanning the PProcess* list, creating a NetProcTop
3514 // for each process.
3515 const list
<PProcess
*>&sl
= get_behaviors();
3517 for (list
<PProcess
*>::const_iterator st
= sl
.begin()
3518 ; st
!= sl
.end() ; st
++ ) {
3520 result_flag
&= (*st
)->elaborate(des
, scope
);
3523 // Elaborate the specify paths of the module.
3525 for (list
<PSpecPath
*>::const_iterator sp
= specify_paths
.begin()
3526 ; sp
!= specify_paths
.end() ; sp
++) {
3528 (*sp
)->elaborate(des
, scope
);
3534 bool PGenerate::elaborate(Design
*des
, NetScope
*container
) const
3538 typedef list
<NetScope
*>::const_iterator scope_list_it_t
;
3539 for (scope_list_it_t cur
= scope_list_
.begin()
3540 ; cur
!= scope_list_
.end() ; cur
++ ) {
3542 NetScope
*scope
= *cur
;
3543 // Check that this scope is one that is contained in the
3544 // container that the caller passed in.
3545 if (scope
->parent() != container
)
3548 if (debug_elaborate
)
3549 cerr
<< get_line() << ": debug: Elaborate in "
3550 << "scope " << scope_path(scope
) << endl
;
3552 flag
= elaborate_(des
, scope
) & flag
;
3558 bool PGenerate::elaborate_(Design
*des
, NetScope
*scope
) const
3560 typedef list
<PGate
*>::const_iterator gates_it_t
;
3561 for (gates_it_t cur
= gates
.begin() ; cur
!= gates
.end() ; cur
++ )
3562 (*cur
)->elaborate(des
, scope
);
3564 typedef list
<PProcess
*>::const_iterator proc_it_t
;
3565 for (proc_it_t cur
= behaviors
.begin(); cur
!= behaviors
.end(); cur
++)
3566 (*cur
)->elaborate(des
, scope
);
3576 Design
* elaborate(list
<perm_string
>roots
)
3578 svector
<root_elem
*> root_elems(roots
.size());
3582 // This is the output design. I fill it in as I scan the root
3583 // module and elaborate what I find.
3584 Design
*des
= new Design
;
3586 // Scan the root modules, and elaborate their scopes.
3587 for (list
<perm_string
>::const_iterator root
= roots
.begin()
3588 ; root
!= roots
.end()
3591 // Look for the root module in the list.
3592 map
<perm_string
,Module
*>::const_iterator mod
= pform_modules
.find(*root
);
3593 if (mod
== pform_modules
.end()) {
3594 cerr
<< "error: Unable to find the root module \""
3595 << (*root
) << "\" in the Verilog source." << endl
;
3596 cerr
<< " : Perhaps ``-s " << (*root
)
3597 << "'' is incorrect?" << endl
;
3602 // Get the module definition for this root instance.
3603 Module
*rmod
= (*mod
).second
;
3605 // Make the root scope.
3606 NetScope
*scope
= des
->make_root_scope(*root
);
3607 scope
->time_unit(rmod
->time_unit
);
3608 scope
->time_precision(rmod
->time_precision
);
3609 scope
->default_nettype(rmod
->default_nettype
);
3610 des
->set_precision(rmod
->time_precision
);
3612 Module::replace_t stub
;
3614 // Recursively elaborate from this root scope down. This
3615 // does a lot of the grunt work of creating sub-scopes, etc.
3616 if (! rmod
->elaborate_scope(des
, scope
, stub
)) {
3621 struct root_elem
*r
= new struct root_elem
;
3624 root_elems
[i
++] = r
;
3627 // Errors already? Probably missing root modules. Just give up
3628 // now and return nothing.
3629 if (des
->errors
> 0)
3632 // This method recurses through the scopes, looking for
3633 // defparam assignments to apply to the parameters in the
3634 // various scopes. This needs to be done after all the scopes
3635 // and basic parameters are taken care of because the defparam
3636 // can assign to a parameter declared *after* it.
3637 des
->run_defparams();
3640 // At this point, all parameter overrides are done. Scan the
3641 // scopes and evaluate the parameters all the way down to
3643 des
->evaluate_parameters();
3645 // With the parameters evaluated down to constants, we have
3646 // what we need to elaborate signals and memories. This pass
3647 // creates all the NetNet and NetMemory objects for declared
3649 for (i
= 0; i
< root_elems
.count(); i
++) {
3650 Module
*rmod
= root_elems
[i
]->mod
;
3651 NetScope
*scope
= root_elems
[i
]->scope
;
3653 if (! rmod
->elaborate_sig(des
, scope
)) {
3659 // Now that the structure and parameters are taken care of,
3660 // run through the pform again and generate the full netlist.
3661 for (i
= 0; i
< root_elems
.count(); i
++) {
3662 Module
*rmod
= root_elems
[i
]->mod
;
3663 NetScope
*scope
= root_elems
[i
]->scope
;
3665 rc
&= rmod
->elaborate(des
, scope
);