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. */
382 NetNet
*lval_sig
= pin(0)->elaborate_lnet(des
, scope
, true);
385 /* Detect the special case that the l-value width exactly
386 matches the gate count. In this case, we will make a single
387 gate that has the desired vector width. */
388 if (lval_sig
->vector_width() == count
) {
389 instance_width
= count
;
392 if (debug_elaborate
&& instance_width
!= 1)
393 cerr
<< get_line() << ": debug: PGBuiltin: "
394 "Collapsed gate array into single wide "
395 "(" << instance_width
<< ") instance." << endl
;
398 /* Allocate all the netlist nodes for the gates. */
399 NetLogic
**cur
= new NetLogic
*[count
];
402 /* Calculate the gate delays from the delay expressions
403 given in the source. For logic gates, the decay time
404 is meaningless because it can never go to high
405 impedance. However, the bufif devices can generate
406 'bz output, so we will pretend that anything can.
408 If only one delay value expression is given (i.e., #5
409 nand(foo,...)) then rise, fall and decay times are
410 all the same value. If two values are given, rise and
411 fall times are use, and the decay time is the minimum
412 of the rise and fall times. Finally, if all three
413 values are given, they are taken as specified. */
415 NetExpr
* rise_time
, *fall_time
, *decay_time
;
416 eval_delays(des
, scope
, rise_time
, fall_time
, decay_time
);
418 struct attrib_list_t
*attrib_list
= 0;
419 unsigned attrib_list_n
= 0;
420 attrib_list
= evaluate_attributes(attributes
, attrib_list_n
,
423 /* Now make as many gates as the bit count dictates. Give each
424 a unique name, and set the delay times. */
426 for (unsigned idx
= 0 ; idx
< count
; idx
+= 1) {
434 tmp
<< name
<< "<" << index
<< ">";
435 perm_string inm
= lex_strings
.make(tmp
.str());
439 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
440 NetLogic::AND
, instance_width
);
443 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
444 NetLogic::BUF
, instance_width
);
447 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
448 NetLogic::BUFIF0
, instance_width
);
451 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
452 NetLogic::BUFIF1
, instance_width
);
455 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
456 NetLogic::NAND
, instance_width
);
459 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
460 NetLogic::NMOS
, instance_width
);
463 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
464 NetLogic::NOR
, instance_width
);
467 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
468 NetLogic::NOT
, instance_width
);
471 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
472 NetLogic::NOTIF0
, instance_width
);
475 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
476 NetLogic::NOTIF1
, instance_width
);
479 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
480 NetLogic::OR
, instance_width
);
483 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
484 NetLogic::RNMOS
, instance_width
);
487 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
488 NetLogic::RPMOS
, instance_width
);
491 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
492 NetLogic::PMOS
, instance_width
);
495 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
496 NetLogic::PULLDOWN
, instance_width
);
499 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
500 NetLogic::PULLUP
, instance_width
);
503 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
504 NetLogic::XNOR
, instance_width
);
507 cur
[idx
] = new NetLogic(scope
, inm
, pin_count(),
508 NetLogic::XOR
, instance_width
);
511 cerr
<< get_line() << ": internal error: unhandled "
512 "gate type." << endl
;
517 for (unsigned adx
= 0 ; adx
< attrib_list_n
; adx
+= 1)
518 cur
[idx
]->attribute(attrib_list
[adx
].key
,
519 attrib_list
[adx
].val
);
521 cur
[idx
]->rise_time(rise_time
);
522 cur
[idx
]->fall_time(fall_time
);
523 cur
[idx
]->decay_time(decay_time
);
525 cur
[idx
]->pin(0).drive0(drive_type(strength0()));
526 cur
[idx
]->pin(0).drive1(drive_type(strength1()));
528 des
->add_node(cur
[idx
]);
534 /* The gates have all been allocated, this loop runs through
535 the parameters and attaches the ports of the objects. */
537 for (unsigned idx
= 0 ; idx
< pin_count() ; idx
+= 1) {
538 const PExpr
*ex
= pin(idx
);
539 NetNet
*sig
= (idx
== 0)
541 : ex
->elaborate_net(des
, scope
, 0, 0, 0, 0);
548 /* Handle the case where there is one gate that
549 carries the whole vector width. */
551 if (1 == sig
->vector_width() && instance_width
!= 1) {
553 assert(sig
->vector_width() == 1);
555 = new NetReplicate(scope
,
556 scope
->local_symbol(),
559 rep
->set_line(*this);
561 connect(rep
->pin(1), sig
->pin(0));
563 sig
= new NetNet(scope
, scope
->local_symbol(),
564 NetNet::WIRE
, instance_width
);
565 sig
->data_type(IVL_VT_LOGIC
);
566 sig
->local_flag(true);
567 sig
->set_line(*this);
568 connect(rep
->pin(0), sig
->pin(0));
572 if (instance_width
!= sig
->vector_width()) {
574 cerr
<< get_line() << ": error: "
575 << "Expression width " << sig
->vector_width()
576 << " does not match width " << instance_width
577 << " of logic gate array port " << idx
582 connect(cur
[0]->pin(idx
), sig
->pin(0));
584 } else if (sig
->vector_width() == 1) {
585 /* Handle the case where a single bit is connected
586 repetitively to all the instances. */
587 for (unsigned gdx
= 0 ; gdx
< count
; gdx
+= 1)
588 connect(cur
[gdx
]->pin(idx
), sig
->pin(0));
590 } else if (sig
->vector_width() == count
) {
592 /* Handle the general case that each bit of the
593 value is connected to a different instance. In
594 this case, the output is handled slightly
595 different from the inputs. */
597 NetConcat
*cc
= new NetConcat(scope
,
598 scope
->local_symbol(),
603 /* Connect the concat to the signal. */
604 connect(cc
->pin(0), sig
->pin(0));
606 /* Connect the outputs of the gates to the concat. */
607 for (unsigned gdx
= 0 ; gdx
< count
; gdx
+= 1) {
608 connect(cur
[gdx
]->pin(0), cc
->pin(gdx
+1));
610 NetNet
*tmp2
= new NetNet(scope
,
611 scope
->local_symbol(),
613 tmp2
->local_flag(true);
614 tmp2
->data_type(IVL_VT_LOGIC
);
615 connect(cc
->pin(gdx
+1), tmp2
->pin(0));
618 } else for (unsigned gdx
= 0 ; gdx
< count
; gdx
+= 1) {
619 /* Use part selects to get the bits
620 connected to the inputs of out gate. */
621 NetPartSelect
*tmp1
= new NetPartSelect(sig
, gdx
, 1,
623 tmp1
->set_line(*this);
625 connect(tmp1
->pin(1), sig
->pin(0));
626 NetNet
*tmp2
= new NetNet(scope
, scope
->local_symbol(),
628 tmp2
->local_flag(true);
629 tmp2
->data_type(sig
->data_type());
630 connect(tmp1
->pin(0), tmp2
->pin(0));
631 connect(cur
[gdx
]->pin(idx
), tmp1
->pin(0));
635 cerr
<< get_line() << ": error: Gate count of " <<
636 count
<< " does not match net width of " <<
637 sig
->vector_width() << " at pin " << idx
<< "."
646 * Instantiate a module by recursively elaborating it. Set the path of
647 * the recursive elaboration so that signal names get properly
648 * set. Connect the ports of the instantiated module to the signals of
649 * the parameters. This is done with BUFZ gates so that they look just
650 * like continuous assignment connections.
652 void PGModule::elaborate_mod_(Design
*des
, Module
*rmod
, NetScope
*scope
) const
657 if (debug_elaborate
) {
658 cerr
<< get_line() << ": debug: Instantiate module "
659 << rmod
->mod_name() << " with instance name "
660 << get_name() << " in scope " << scope_path(scope
) << endl
;
663 // This is the array of pin expressions, shuffled to match the
664 // order of the declaration. If the source instantiation uses
665 // bind by order, this is the same as the source list.Otherwise,
666 // the source list is rearranged by name binding into this list.
667 svector
<PExpr
*>pins (rmod
->port_count());
669 // If the instance has a pins_ member, then we know we are
670 // binding by name. Therefore, make up a pins array that
671 // reflects the positions of the named ports.
673 unsigned nexp
= rmod
->port_count();
675 // Scan the bindings, matching them with port names.
676 for (unsigned idx
= 0 ; idx
< npins_
; idx
+= 1) {
678 // Given a binding, look at the module port names
679 // for the position that matches the binding name.
680 unsigned pidx
= rmod
->find_port(pins_
[idx
].name
);
682 // If the port name doesn't exist, the find_port
683 // method will return the port count. Detect that
686 cerr
<< get_line() << ": error: port ``" <<
687 pins_
[idx
].name
<< "'' is not a port of "
688 << get_name() << "." << endl
;
693 // If I already bound something to this port, then
694 // the pins array will already have a pointer
695 // value where I want to place this expression.
697 cerr
<< get_line() << ": error: port ``" <<
698 pins_
[idx
].name
<< "'' already bound." <<
704 // OK, do the binding by placing the expression in
706 pins
[pidx
] = pins_
[idx
].parm
;
710 } else if (pin_count() == 0) {
712 /* Handle the special case that no ports are
713 connected. It is possible that this is an empty
714 connect-by-name list, so we'll allow it and assume
717 for (unsigned idx
= 0 ; idx
< rmod
->port_count() ; idx
+= 1)
722 /* Otherwise, this is a positional list of port
723 connections. In this case, the port count must be
724 right. Check that is is, the get the pin list. */
726 if (pin_count() != rmod
->port_count()) {
727 cerr
<< get_line() << ": error: Wrong number "
728 "of ports. Expecting " << rmod
->port_count() <<
729 ", got " << pin_count() << "."
735 // No named bindings, just use the positional list I
737 assert(pin_count() == rmod
->port_count());
741 // Elaborate these instances of the module. The recursive
742 // elaboration causes the module to generate a netlist with
743 // the ports represented by NetNet objects. I will find them
746 NetScope::scope_vec_t
&instance
= scope
->instance_arrays
[get_name()];
747 for (unsigned inst
= 0 ; inst
< instance
.count() ; inst
+= 1) {
748 rmod
->elaborate(des
, instance
[inst
]);
753 // Now connect the ports of the newly elaborated designs to
754 // the expressions that are the instantiation parameters. Scan
755 // the pins, elaborate the expressions attached to them, and
756 // bind them to the port of the elaborated module.
758 // This can get rather complicated because the port can be
759 // unconnected (meaning an empty parameter is passed) connected
760 // to a concatenation, or connected to an internally
763 for (unsigned idx
= 0 ; idx
< pins
.count() ; idx
+= 1) {
765 // Skip unconnected module ports. This happens when a
766 // null parameter is passed in.
768 if (pins
[idx
] == 0) {
770 // While we're here, look to see if this
771 // unconnected (from the outside) port is an
772 // input. If so, consider printing a port binding
774 if (warn_portbinding
) {
775 svector
<PEIdent
*> mport
= rmod
->get_port(idx
);
776 if (mport
.count() == 0)
779 perm_string pname
= peek_tail_name(mport
[0]->path());
781 NetNet
*tmp
= instance
[0]->find_signal(pname
);
784 if (tmp
->port_type() == NetNet::PINPUT
) {
785 cerr
<< get_line() << ": warning: "
786 << "Instantiating module "
788 << " with dangling input port "
789 << rmod
->ports
[idx
]->name
798 // Inside the module, the port is zero or more signals
799 // that were already elaborated. List all those signals
800 // and the NetNet equivalents, for all the instances.
801 svector
<PEIdent
*> mport
= rmod
->get_port(idx
);
802 svector
<NetNet
*>prts (mport
.count() * instance
.count());
804 if (debug_elaborate
) {
805 cerr
<< get_line() << ": debug: " << get_name()
806 << ": Port " << idx
<< " has " << prts
.count()
807 << " sub-ports." << endl
;
810 // Count the internal vector bits of the port.
811 unsigned prts_vector_width
= 0;
813 for (unsigned inst
= 0 ; inst
< instance
.count() ; inst
+= 1) {
814 NetScope
*inst_scope
= instance
[inst
];
816 // Scan the module sub-ports for this instance...
817 for (unsigned ldx
= 0 ; ldx
< mport
.count() ; ldx
+= 1) {
818 unsigned lbase
= inst
* mport
.count();
819 PEIdent
*pport
= mport
[ldx
];
822 = pport
->elaborate_port(des
, inst_scope
);
823 if (prts
[lbase
+ ldx
] == 0)
826 assert(prts
[lbase
+ ldx
]);
827 prts_vector_width
+= prts
[lbase
+ ldx
]->vector_width();
831 // If I find that the port is unconnected inside the
832 // module, then there is nothing to connect. Skip the
834 if (prts_vector_width
== 0) {
838 // We know by design that each instance has the same
839 // width port. Therefore, the prts_pin_count must be an
840 // even multiple of the instance count.
841 assert(prts_vector_width
% instance
.count() == 0);
843 unsigned desired_vector_width
= prts_vector_width
;
844 if (instance
.count() != 1)
845 desired_vector_width
= 0;
847 // Elaborate the expression that connects to the
848 // module[s] port. sig is the thing outside the module
849 // that connects to the port.
852 if ((prts
.count() == 0)
853 || (prts
[0]->port_type() == NetNet::PINPUT
)) {
855 /* Input to module. elaborate the expression to
856 the desired width. If this in an instance
857 array, then let the net determine it's own
858 width. We use that, then, to decide how to hook
861 NOTE that this also handles the case that the
862 port is actually empty on the inside. We assume
863 in that case that the port is input. */
865 sig
= pins
[idx
]->elaborate_net(des
, scope
,
866 desired_vector_width
,
869 cerr
<< pins
[idx
]->get_line()
870 << ": internal error: Port expression "
871 << "too complicated for elaboration." << endl
;
875 } else if (prts
[0]->port_type() == NetNet::PINOUT
) {
877 /* Inout to/from module. This is a more
878 complicated case, where the expression must be
879 an lnet, but also an r-value net.
881 Normally, this winds up being the same as if we
882 just elaborated as an lnet, as passing a simple
883 identifier elaborates to the same NetNet in
884 both cases so the extra elaboration has no
885 effect. But if the expression passed to the
886 inout port is a part select, aspecial part
887 select must be created that can paqss data in
890 Use the elaborate_bi_net method to handle all
891 the possible cases. */
893 sig
= pins
[idx
]->elaborate_bi_net(des
, scope
);
895 cerr
<< pins
[idx
]->get_line() << ": error: "
896 << "Inout port expression must support "
897 << "continuous assignment." << endl
;
898 cerr
<< pins
[idx
]->get_line() << ": : "
899 << "Port of " << rmod
->mod_name()
900 << " is " << rmod
->ports
[idx
]->name
<< endl
;
908 /* Port type must be OUTPUT here. */
910 /* Output from module. Elaborate the port
911 expression as the l-value of a continuous
912 assignment, as the port will continuous assign
915 sig
= pins
[idx
]->elaborate_lnet(des
, scope
, true);
917 cerr
<< pins
[idx
]->get_line() << ": error: "
918 << "Output port expression must support "
919 << "continuous assignment." << endl
;
920 cerr
<< pins
[idx
]->get_line() << ": : "
921 << "Port of " << rmod
->mod_name()
922 << " is " << rmod
->ports
[idx
]->name
<< endl
;
932 if ((prts
.count() >= 1)
933 && (prts
[0]->port_type() != NetNet::PINPUT
)) {
934 assert(sig
->type() != NetNet::REG
);
938 /* If we are working with an instance array, then the
939 signal width must match the port width exactly. */
940 if ((instance
.count() != 1)
941 && (sig
->vector_width() != prts_vector_width
)
942 && (sig
->vector_width() != prts_vector_width
/instance
.count())) {
943 cerr
<< pins
[idx
]->get_line() << ": error: "
944 << "Port expression width " << sig
->vector_width()
945 << " does not match expected width "<< prts_vector_width
946 << " or " << (prts_vector_width
/instance
.count())
952 if (debug_elaborate
) {
953 cerr
<< get_line() << ": debug: " << get_name()
954 << ": Port " << (idx
+1) << " has vector width of "
955 << prts_vector_width
<< "." << endl
;
958 // Check that the parts have matching pin counts. If
959 // not, they are different widths. Note that idx is 0
960 // based, but users count parameter positions from 1.
961 if ((instance
.count() == 1)
962 && (prts_vector_width
!= sig
->vector_width())) {
963 const char *tmp3
= rmod
->ports
[idx
]->name
.str();
964 if (tmp3
== 0) tmp3
= "???";
965 cerr
<< get_line() << ": warning: Port " << (idx
+1)
966 << " (" << tmp3
<< ") of "
967 << type_
<< " expects " << prts_vector_width
<<
968 " bits, got " << sig
->vector_width() << "." << endl
;
970 if (prts_vector_width
> sig
->vector_width()) {
971 cerr
<< get_line() << ": : Leaving "
972 << (prts_vector_width
-sig
->vector_width())
973 << " high bits of the port unconnected."
976 cerr
<< get_line() << ": : Leaving "
977 << (sig
->vector_width()-prts_vector_width
)
978 << " high bits of the expression dangling."
983 // Connect the sig expression that is the context of the
984 // module instance to the ports of the elaborated module.
986 // The prts_pin_count variable is the total width of the
987 // port and is the maximum number of connections to
988 // make. sig is the elaborated expression that connects
989 // to that port. If sig has too few pins, then reduce
990 // the number of connections to make.
992 // Connect this many of the port pins. If the expression
993 // is too small, then reduce the number of connects.
994 unsigned ccount
= prts_vector_width
;
995 if (instance
.count() == 1 && sig
->vector_width() < ccount
)
996 ccount
= sig
->vector_width();
998 // The spin_modulus is the width of the signal (not the
999 // port) if this is an instance array. This causes
1000 // signals wide enough for a single instance to be
1001 // connected to all the instances.
1002 unsigned spin_modulus
= prts_vector_width
;
1003 if (instance
.count() != 1)
1004 spin_modulus
= sig
->vector_width();
1006 // Now scan the concatenation that makes up the port,
1007 // connecting pins until we run out of port pins or sig
1008 // pins. The sig object is the NetNet that is connected
1009 // to the port from the outside, and the prts object is
1010 // an array of signals to be connected to the sig.
1015 if (prts
.count() == 1) {
1017 // The simplest case, there are no
1018 // parts/concatenations on the inside of the
1019 // module, so the port and sig need simply be
1020 // connected directly.
1021 connect(prts
[0]->pin(0), sig
->pin(0));
1023 } else if (sig
->vector_width()==prts_vector_width
/instance
.count()
1024 && prts
.count()/instance
.count() == 1) {
1026 if (debug_elaborate
){
1027 cerr
<< get_line() << ": debug: " << get_name()
1028 << ": Replicating " << prts_vector_width
1029 << " bits across all "
1030 << prts_vector_width
/instance
.count()
1031 << " sub-ports." << endl
;
1034 // The signal width is exactly the width of a
1035 // single instance of the port. In this case,
1036 // connect the sig to all the ports identically.
1037 for (unsigned ldx
= 0 ; ldx
< prts
.count() ; ldx
+= 1)
1038 connect(prts
[ldx
]->pin(0), sig
->pin(0));
1040 } else switch (prts
[0]->port_type()) {
1041 case NetNet::POUTPUT
:
1042 ctmp
= new NetConcat(scope
, scope
->local_symbol(),
1045 des
->add_node(ctmp
);
1046 connect(ctmp
->pin(0), sig
->pin(0));
1047 for (unsigned ldx
= 0 ; ldx
< prts
.count() ; ldx
+= 1) {
1048 connect(ctmp
->pin(ldx
+1),
1049 prts
[prts
.count()-ldx
-1]->pin(0));
1053 case NetNet::PINPUT
:
1054 if (debug_elaborate
){
1055 cerr
<< get_line() << ": debug: " << get_name()
1056 << ": Dividing " << prts_vector_width
1057 << " bits across all "
1058 << prts_vector_width
/instance
.count()
1059 << " input sub-ports of port "
1060 << idx
<< "." << endl
;
1063 for (unsigned ldx
= 0 ; ldx
< prts
.count() ; ldx
+= 1) {
1064 NetNet
*sp
= prts
[prts
.count()-ldx
-1];
1065 NetPartSelect
*ptmp
= new NetPartSelect(sig
, spin
,
1068 des
->add_node(ptmp
);
1069 connect(ptmp
->pin(0), sp
->pin(0));
1070 spin
+= sp
->vector_width();
1073 case NetNet::PINOUT
:
1074 cerr
<< get_line() << ": XXXX: "
1075 << "Forgot how to bind inout ports!" << endl
;
1078 case NetNet::PIMPLICIT
:
1079 cerr
<< get_line() << ": internal error: "
1080 << "Unexpected IMPLICIT port" << endl
;
1083 case NetNet::NOT_A_PORT
:
1084 cerr
<< get_line() << ": internal error: "
1085 << "Unexpected NOT_A_PORT port." << endl
;
1095 * From a UDP definition in the source, make a NetUDP
1096 * object. Elaborate the pin expressions as netlists, then connect
1097 * those networks to the pins.
1100 void PGModule::elaborate_udp_(Design
*des
, PUdp
*udp
, NetScope
*scope
) const
1102 NetExpr
*rise_expr
=0, *fall_expr
=0, *decay_expr
=0;
1104 perm_string my_name
= get_name();
1106 my_name
= scope
->local_symbol();
1108 /* When the parser notices delay expressions in front of a
1109 module or primitive, it interprets them as parameter
1110 overrides. Correct that misconception here. */
1113 tmp_del
.set_delays(overrides_
, false);
1114 tmp_del
.eval_delays(des
, scope
, rise_expr
, fall_expr
, decay_expr
);
1116 if (dynamic_cast<NetEConst
*> (rise_expr
)) {
1119 cerr
<< get_line() << ": error: Delay expressions must be "
1120 << "constant for primitives." << endl
;
1121 cerr
<< get_line() << ": : Cannot calculate "
1122 << *rise_expr
<< endl
;
1126 if (dynamic_cast<NetEConst
*> (fall_expr
)) {
1129 cerr
<< get_line() << ": error: Delay expressions must be "
1130 << "constant for primitives." << endl
;
1131 cerr
<< get_line() << ": : Cannot calculate "
1132 << *rise_expr
<< endl
;
1136 if (dynamic_cast<NetEConst
*> (decay_expr
)) {
1139 cerr
<< get_line() << ": error: Delay expressions must be "
1140 << "constant for primitives." << endl
;
1141 cerr
<< get_line() << ": : Cannot calculate "
1142 << *rise_expr
<< endl
;
1150 NetUDP
*net
= new NetUDP(scope
, my_name
, udp
->ports
.count(), udp
);
1151 net
->rise_time(rise_expr
);
1152 net
->fall_time(fall_expr
);
1153 net
->decay_time(decay_expr
);
1155 struct attrib_list_t
*attrib_list
= 0;
1156 unsigned attrib_list_n
= 0;
1157 attrib_list
= evaluate_attributes(attributes
, attrib_list_n
,
1160 for (unsigned adx
= 0 ; adx
< attrib_list_n
; adx
+= 1)
1161 net
->attribute(attrib_list
[adx
].key
, attrib_list
[adx
].val
);
1163 delete[]attrib_list
;
1166 // This is the array of pin expressions, shuffled to match the
1167 // order of the declaration. If the source instantiation uses
1168 // bind by order, this is the same as the source
1169 // list. Otherwise, the source list is rearranged by name
1170 // binding into this list.
1171 svector
<PExpr
*>pins
;
1173 // Detect binding by name. If I am binding by name, then make
1174 // up a pins array that reflects the positions of the named
1175 // ports. If this is simply positional binding in the first
1176 // place, then get the binding from the base class.
1178 unsigned nexp
= udp
->ports
.count();
1179 pins
= svector
<PExpr
*>(nexp
);
1181 // Scan the bindings, matching them with port names.
1182 for (unsigned idx
= 0 ; idx
< npins_
; idx
+= 1) {
1184 // Given a binding, look at the module port names
1185 // for the position that matches the binding name.
1186 unsigned pidx
= udp
->find_port(pins_
[idx
].name
);
1188 // If the port name doesn't exist, the find_port
1189 // method will return the port count. Detect that
1192 cerr
<< get_line() << ": error: port ``" <<
1193 pins_
[idx
].name
<< "'' is not a port of "
1194 << get_name() << "." << endl
;
1199 // If I already bound something to this port, then
1200 // the (*exp) array will already have a pointer
1201 // value where I want to place this expression.
1203 cerr
<< get_line() << ": error: port ``" <<
1204 pins_
[idx
].name
<< "'' already bound." <<
1210 // OK, do the binding by placing the expression in
1212 pins
[pidx
] = pins_
[idx
].parm
;
1217 /* Otherwise, this is a positional list of port
1218 connections. In this case, the port count must be
1219 right. Check that is is, the get the pin list. */
1221 if (pin_count() != udp
->ports
.count()) {
1222 cerr
<< get_line() << ": error: Wrong number "
1223 "of ports. Expecting " << udp
->ports
.count() <<
1224 ", got " << pin_count() << "."
1230 // No named bindings, just use the positional list I
1232 assert(pin_count() == udp
->ports
.count());
1237 /* Handle the output port of the primitive special. It is an
1238 output port (the only output port) so must be passed an
1241 cerr
<< get_line() << ": warning: output port unconnected."
1245 NetNet
*sig
= pins
[0]->elaborate_lnet(des
, scope
, true);
1247 cerr
<< get_line() << ": error: "
1248 << "Output port expression is not valid." << endl
;
1249 cerr
<< get_line() << ": : Output "
1250 << "port of " << udp
->name_
1251 << " is " << udp
->ports
[0] << "." << endl
;
1254 connect(sig
->pin(0), net
->pin(0));
1258 /* Run through the pins, making netlists for the pin
1259 expressions and connecting them to the pin in question. All
1260 of this is independent of the nature of the UDP. */
1261 for (unsigned idx
= 1 ; idx
< net
->pin_count() ; idx
+= 1) {
1265 NetNet
*sig
= pins
[idx
]->elaborate_net(des
, scope
, 1, 0, 0, 0);
1267 cerr
<< "internal error: Expression too complicated "
1268 "for elaboration:" << pins
[idx
] << endl
;
1272 connect(sig
->pin(0), net
->pin(idx
));
1275 // All done. Add the object to the design.
1280 bool PGModule::elaborate_sig(Design
*des
, NetScope
*scope
) const
1282 // Look for the module type
1283 map
<perm_string
,Module
*>::const_iterator mod
= pform_modules
.find(type_
);
1284 if (mod
!= pform_modules
.end())
1285 return elaborate_sig_mod_(des
, scope
, (*mod
).second
);
1291 void PGModule::elaborate(Design
*des
, NetScope
*scope
) const
1293 // Look for the module type
1294 map
<perm_string
,Module
*>::const_iterator mod
= pform_modules
.find(type_
);
1295 if (mod
!= pform_modules
.end()) {
1296 elaborate_mod_(des
, (*mod
).second
, scope
);
1300 // Try a primitive type
1301 map
<perm_string
,PUdp
*>::const_iterator udp
= pform_primitives
.find(type_
);
1302 if (udp
!= pform_primitives
.end()) {
1303 assert((*udp
).second
);
1304 elaborate_udp_(des
, (*udp
).second
, scope
);
1308 cerr
<< get_line() << ": internal error: Unknown module type: " <<
1312 void PGModule::elaborate_scope(Design
*des
, NetScope
*sc
) const
1314 // Look for the module type
1315 map
<perm_string
,Module
*>::const_iterator mod
= pform_modules
.find(type_
);
1316 if (mod
!= pform_modules
.end()) {
1317 elaborate_scope_mod_(des
, (*mod
).second
, sc
);
1321 // Try a primitive type
1322 map
<perm_string
,PUdp
*>::const_iterator udp
= pform_primitives
.find(type_
);
1323 if (udp
!= pform_primitives
.end())
1326 // Not a module or primitive that I know about yet, so try to
1327 // load a library module file (which parses some new Verilog
1328 // code) and try again.
1329 if (load_module(type_
)) {
1331 // Try again to find the module type
1332 mod
= pform_modules
.find(type_
);
1333 if (mod
!= pform_modules
.end()) {
1334 elaborate_scope_mod_(des
, (*mod
).second
, sc
);
1338 // Try again to find a primitive type
1339 udp
= pform_primitives
.find(type_
);
1340 if (udp
!= pform_primitives
.end())
1345 // Not a module or primitive that I know about or can find by
1346 // any means, so give up.
1347 cerr
<< get_line() << ": error: Unknown module type: " << type_
<< endl
;
1348 missing_modules
[type_
] += 1;
1353 NetProc
* Statement::elaborate(Design
*des
, NetScope
*) const
1355 cerr
<< get_line() << ": internal error: elaborate: "
1356 "What kind of statement? " << typeid(*this).name() << endl
;
1357 NetProc
*cur
= new NetProc
;
1363 NetAssign_
* PAssign_::elaborate_lval(Design
*des
, NetScope
*scope
) const
1366 return lval_
->elaborate_lval(des
, scope
, false);
1370 * This function elaborates delay expressions. This is a little
1371 * different from normal elaboration because the result may need to be
1374 static NetExpr
*elaborate_delay_expr(PExpr
*expr
, Design
*des
, NetScope
*scope
)
1376 NetExpr
*dex
= elab_and_eval(des
, scope
, expr
, -1);
1378 /* If the delay expression is a real constant or vector
1379 constant, then evaluate it, scale it to the local time
1380 units, and return an adjusted NetEConst. */
1382 if (NetECReal
*tmp
= dynamic_cast<NetECReal
*>(dex
)) {
1383 verireal fn
= tmp
->value();
1385 int shift
= scope
->time_unit() - des
->get_precision();
1386 int64_t delay
= fn
.as_long64(shift
);
1391 return new NetEConst(verinum(delay
));
1395 if (NetEConst
*tmp
= dynamic_cast<NetEConst
*>(dex
)) {
1396 verinum fn
= tmp
->value();
1399 des
->scale_to_precision(fn
.as_ulong64(), scope
);
1402 return new NetEConst(verinum(delay
));
1406 /* The expression is not constant, so generate an expanded
1407 expression that includes the necessary scale shifts, and
1408 return that expression. */
1409 int shift
= scope
->time_unit() - des
->get_precision();
1417 NetExpr
*scal_val
= new NetEConst(verinum(scale
));
1418 dex
= new NetEBMult('*', dex
, scal_val
);
1422 unsigned long scale
= 1;
1428 NetExpr
*scal_val
= new NetEConst(verinum(scale
));
1429 dex
= new NetEBDiv('/', dex
, scal_val
);
1435 NetProc
* PAssign::elaborate(Design
*des
, NetScope
*scope
) const
1439 /* elaborate the lval. This detects any part selects and mux
1440 expressions that might exist. */
1441 NetAssign_
*lv
= elaborate_lval(des
, scope
);
1442 if (lv
== 0) return 0;
1444 /* If there is an internal delay expression, elaborate it. */
1447 delay
= elaborate_delay_expr(delay_
, des
, scope
);
1452 /* Elaborate the r-value expression, then try to evaluate it. */
1454 /* Find out what the r-value width is going to be. We guess it
1455 will be the l-value width, but it may turn out to be
1456 something else based on self-determined widths inside. */
1457 unsigned use_width
= lv
->lwidth();
1458 bool unsized_flag
= false;
1459 use_width
= rval()->test_width(des
, scope
, use_width
, use_width
, unsized_flag
);
1461 /* Now elaborate to the expected width. Pass the lwidth to
1462 prune any constant result to fit with the lvalue at hand. */
1463 NetExpr
*rv
= elab_and_eval(des
, scope
, rval(), use_width
, lv
->lwidth());
1464 if (rv
== 0) return 0;
1468 /* Rewrite delayed assignments as assignments that are
1469 delayed. For example, a = #<d> b; becomes:
1476 If the delay is an event delay, then the transform is
1477 similar, with the event delay replacing the time delay. It
1478 is an event delay if the event_ member has a value.
1480 This rewriting of the expression allows me to not bother to
1481 actually and literally represent the delayed assign in the
1482 netlist. The compound statement is exactly equivalent. */
1484 if (delay
|| event_
) {
1485 unsigned wid
= lv
->lwidth();
1488 rv
= pad_to_width(rv
, wid
);
1490 if (wid
> rv
->expr_width()) {
1491 cerr
<< get_line() << ": error: Unable to match "
1492 "expression width of " << rv
->expr_width() <<
1493 " to l-value width of " << wid
<< "." << endl
;
1498 NetNet
*tmp
= new NetNet(scope
, scope
->local_symbol(),
1500 tmp
->set_line(*this);
1501 tmp
->data_type(rv
->expr_type());
1503 NetESignal
*sig
= new NetESignal(tmp
);
1505 /* Generate an assignment of the l-value to the temporary... */
1506 NetAssign_
*lvt
= new NetAssign_(tmp
);
1508 NetAssign
*a1
= new NetAssign(lvt
, rv
);
1509 a1
->set_line(*this);
1511 /* Generate an assignment of the temporary to the r-value... */
1512 NetAssign
*a2
= new NetAssign(lv
, sig
);
1513 a2
->set_line(*this);
1515 /* Generate the delay statement with the final
1516 assignment attached to it. If this is an event delay,
1517 elaborate the PEventStatement. Otherwise, create the
1518 right NetPDelay object. */
1521 st
= event_
->elaborate_st(des
, scope
, a2
);
1523 cerr
<< event_
->get_line() << ": error: "
1524 "unable to elaborate event expression."
1532 NetPDelay
*de
= new NetPDelay(delay
, a2
);
1533 de
->set_line(*this);
1537 /* And build up the complex statement. */
1538 NetBlock
*bl
= new NetBlock(NetBlock::SEQU
, 0);
1545 /* Based on the specific type of the l-value, do cleanup
1546 processing on the r-value. */
1547 if (rv
->expr_type() == IVL_VT_REAL
) {
1549 // The r-value is a real. Casting will happen in the
1550 // code generator, so leave it.
1553 unsigned wid
= count_lval_width(lv
);
1555 rv
= pad_to_width(rv
, wid
);
1556 assert(rv
->expr_width() >= wid
);
1559 NetAssign
*cur
= new NetAssign(lv
, rv
);
1560 cur
->set_line(*this);
1566 * Elaborate non-blocking assignments. The statement is of the general
1569 * <lval> <= #<delay> <rval> ;
1571 NetProc
* PAssignNB::elaborate(Design
*des
, NetScope
*scope
) const
1575 /* Elaborate the l-value. */
1576 NetAssign_
*lv
= elaborate_lval(des
, scope
);
1577 if (lv
== 0) return 0;
1581 /* Elaborate and precalculate the r-value. */
1582 NetExpr
*rv
= elab_and_eval(des
, scope
, rval(), count_lval_width(lv
));
1586 /* Handle the (common) case that the r-value is a vector. This
1587 includes just about everything but reals. In this case, we
1588 need to pad the r-value to match the width of the l-value.
1590 If in this case the l-val is a variable (i.e. real) then
1591 the width to pad to will be 0, so this code is harmless. */
1592 if (rv
->expr_type() == IVL_VT_REAL
) {
1595 unsigned wid
= count_lval_width(lv
);
1597 rv
= pad_to_width(rv
, wid
);
1602 delay
= elaborate_delay_expr(delay_
, des
, scope
);
1604 /* All done with this node. Mark its line number and check it in. */
1605 NetAssignNB
*cur
= new NetAssignNB(lv
, rv
);
1606 cur
->set_delay(delay
);
1607 cur
->set_line(*this);
1613 * This is the elaboration method for a begin-end block. Try to
1614 * elaborate the entire block, even if it fails somewhere. This way I
1615 * get all the error messages out of it. Then, if I detected a failure
1616 * then pass the failure up.
1618 NetProc
* PBlock::elaborate(Design
*des
, NetScope
*scope
) const
1622 NetBlock::Type type
= (bl_type_
==PBlock::BL_PAR
)
1626 NetScope
*nscope
= 0;
1627 if (name_
.str() != 0) {
1628 nscope
= scope
->child(hname_t(name_
));
1630 cerr
<< get_line() << ": internal error: "
1631 "unable to find block scope " << scope_path(scope
)
1632 << "<" << name_
<< ">" << endl
;
1641 NetBlock
*cur
= new NetBlock(type
, nscope
);
1646 // Handle the special case that the block contains only one
1647 // statement. There is no need to keep the block node. Also,
1648 // don't elide named blocks, because they might be referenced
1650 if ((list_
.count() == 1) && (name_
.str() == 0)) {
1652 NetProc
*tmp
= list_
[0]->elaborate(des
, nscope
);
1656 for (unsigned idx
= 0 ; idx
< list_
.count() ; idx
+= 1) {
1658 NetProc
*tmp
= list_
[idx
]->elaborate(des
, nscope
);
1659 // If the statement fails to elaborate, then simply
1660 // ignore it. Presumably, the elaborate for the
1661 // statement already generated an error message and
1662 // marked the error count in the design so no need to
1663 // do any of that here.
1668 // If the result turns out to be a noop, then skip it.
1669 if (NetBlock
*tbl
= dynamic_cast<NetBlock
*>(tmp
))
1670 if (tbl
->proc_first() == 0) {
1682 * Elaborate a case statement.
1684 NetProc
* PCase::elaborate(Design
*des
, NetScope
*scope
) const
1688 NetExpr
*expr
= elab_and_eval(des
, scope
, expr_
, -1);
1690 cerr
<< get_line() << ": error: Unable to elaborate this case"
1691 " expression." << endl
;
1695 /* Count the items in the case statement. Note that there may
1696 be some cases that have multiple guards. Count each as a
1698 unsigned icount
= 0;
1699 for (unsigned idx
= 0 ; idx
< items_
->count() ; idx
+= 1) {
1700 PCase::Item
*cur
= (*items_
)[idx
];
1702 if (cur
->expr
.count() == 0)
1705 icount
+= cur
->expr
.count();
1708 NetCase
*res
= new NetCase(type_
, expr
, icount
);
1709 res
->set_line(*this);
1711 /* Iterate over all the case items (guard/statement pairs)
1712 elaborating them. If the guard has no expression, then this
1713 is a "default" cause. Otherwise, the guard has one or more
1714 expressions, and each guard is a case. */
1716 for (unsigned idx
= 0 ; idx
< items_
->count() ; idx
+= 1) {
1718 assert(inum
< icount
);
1719 PCase::Item
*cur
= (*items_
)[idx
];
1721 if (cur
->expr
.count() == 0) {
1722 /* If there are no expressions, then this is the
1726 st
= cur
->stat
->elaborate(des
, scope
);
1728 res
->set_case(inum
, 0, st
);
1731 } else for (unsigned e
= 0; e
< cur
->expr
.count(); e
+= 1) {
1733 /* If there are one or more expressions, then
1734 iterate over the guard expressions, elaborating
1735 a separate case for each. (Yes, the statement
1736 will be elaborated again for each.) */
1739 assert(cur
->expr
[e
]);
1740 gu
= elab_and_eval(des
, scope
, cur
->expr
[e
], -1);
1743 st
= cur
->stat
->elaborate(des
, scope
);
1745 res
->set_case(inum
, gu
, st
);
1753 NetProc
* PCondit::elaborate(Design
*des
, NetScope
*scope
) const
1757 if (debug_elaborate
)
1758 cerr
<< get_line() << ": debug: Elaborate condition statement"
1759 << " with conditional: " << *expr_
<< endl
;
1761 // Elaborate and try to evaluate the conditional expression.
1762 NetExpr
*expr
= elab_and_eval(des
, scope
, expr_
, -1);
1764 cerr
<< get_line() << ": error: Unable to elaborate"
1765 " condition expression." << endl
;
1770 // If the condition of the conditional statement is constant,
1771 // then look at the value and elaborate either the if statement
1772 // or the else statement. I don't need both. If there is no
1773 // else_ statement, the use an empty block as a noop.
1774 if (NetEConst
*ce
= dynamic_cast<NetEConst
*>(expr
)) {
1775 verinum val
= ce
->value();
1776 if (debug_elaborate
) {
1777 cerr
<< get_line() << ": debug: Condition expression "
1778 << "is a constant " << val
<< "." << endl
;
1781 verinum::V reduced
= verinum::V0
;
1782 for (unsigned idx
= 0 ; idx
< val
.len() ; idx
+= 1)
1783 reduced
= reduced
| val
[idx
];
1786 if (reduced
== verinum::V1
)
1788 return if_
->elaborate(des
, scope
);
1790 NetBlock
*tmp
= new NetBlock(NetBlock::SEQU
, 0);
1791 tmp
->set_line(*this);
1795 return else_
->elaborate(des
, scope
);
1797 return new NetBlock(NetBlock::SEQU
, 0);
1800 // If the condition expression is more than 1 bits, then
1801 // generate a comparison operator to get the result down to
1802 // one bit. Turn <e> into <e> != 0;
1804 if (expr
->expr_width() < 1) {
1805 cerr
<< get_line() << ": internal error: "
1806 "incomprehensible expression width (0)." << endl
;
1810 if (expr
->expr_width() > 1) {
1811 assert(expr
->expr_width() > 1);
1812 verinum
zero (verinum::V0
, expr
->expr_width());
1813 NetEConst
*ezero
= new NetEConst(zero
);
1814 ezero
->set_width(expr
->expr_width());
1815 NetEBComp
*cmp
= new NetEBComp('n', expr
, ezero
);
1819 // Well, I actually need to generate code to handle the
1820 // conditional, so elaborate.
1821 NetProc
*i
= if_
? if_
->elaborate(des
, scope
) : 0;
1822 NetProc
*e
= else_
? else_
->elaborate(des
, scope
) : 0;
1824 // Detect the special cases that the if or else statements are
1825 // empty blocks. If this is the case, remove the blocks as
1827 if (NetBlock
*tmp
= dynamic_cast<NetBlock
*>(i
)) {
1828 if (tmp
->proc_first() == 0) {
1834 if (NetBlock
*tmp
= dynamic_cast<NetBlock
*>(e
)) {
1835 if (tmp
->proc_first() == 0) {
1841 NetCondit
*res
= new NetCondit(expr
, i
, e
);
1842 res
->set_line(*this);
1846 NetProc
* PCallTask::elaborate(Design
*des
, NetScope
*scope
) const
1848 if (peek_tail_name(path_
)[0] == '$')
1849 return elaborate_sys(des
, scope
);
1851 return elaborate_usr(des
, scope
);
1855 * A call to a system task involves elaborating all the parameters,
1856 * then passing the list to the NetSTask object.
1858 * There is a single special case in the call to a system
1859 * task. Normally, an expression cannot take an unindexed
1860 * memory. However, it is possible to take a system task parameter a
1861 * memory if the expression is trivial.
1863 NetProc
* PCallTask::elaborate_sys(Design
*des
, NetScope
*scope
) const
1867 unsigned parm_count
= nparms();
1869 /* Catch the special case that the system task has no
1870 parameters. The "()" string will be parsed as a single
1871 empty parameter, when we really mean no parameters at all. */
1872 if ((nparms() == 1) && (parm(0) == 0))
1875 svector
<NetExpr
*>eparms (parm_count
);
1877 for (unsigned idx
= 0 ; idx
< parm_count
; idx
+= 1) {
1878 PExpr
*ex
= parm(idx
);
1879 eparms
[idx
] = ex
? ex
->elaborate_expr(des
, scope
, -1, true) : 0;
1881 /* Attempt to pre-evaluate the parameters. It may be
1882 possible to at least partially reduce the
1885 if (NetExpr
*tmp
= eparms
[idx
]->eval_tree()) {
1892 NetSTask
*cur
= new NetSTask(peek_tail_name(path_
), eparms
);
1897 * A call to a user defined task is different from a call to a system
1898 * task because a user task in a netlist has no parameters: the
1899 * assignments are done by the calling thread. For example:
1924 NetProc
* PCallTask::elaborate_usr(Design
*des
, NetScope
*scope
) const
1928 NetScope
*task
= des
->find_task(scope
, path_
);
1930 cerr
<< get_line() << ": error: Enable of unknown task "
1931 << "``" << path_
<< "''." << endl
;
1937 assert(task
->type() == NetScope::TASK
);
1938 NetTaskDef
*def
= task
->task_def();
1940 cerr
<< get_line() << ": internal error: task " << path_
1941 << " doesn't have a definition in " << scope_path(scope
)
1948 if (nparms() != def
->port_count()) {
1949 cerr
<< get_line() << ": error: Port count mismatch in call to ``"
1950 << path_
<< "''. Got " << nparms()
1951 << " ports, expecting " << def
->port_count() << " ports." << endl
;
1958 /* Handle tasks with no parameters specially. There is no need
1959 to make a sequential block to hold the generated code. */
1960 if (nparms() == 0) {
1961 cur
= new NetUTask(task
);
1962 cur
->set_line(*this);
1966 NetBlock
*block
= new NetBlock(NetBlock::SEQU
, 0);
1969 /* Detect the case where the definition of the task is known
1970 empty. In this case, we need not bother with calls to the
1971 task, all the assignments, etc. Just return a no-op. */
1973 if (const NetBlock
*tp
= dynamic_cast<const NetBlock
*>(def
->proc())) {
1974 if (tp
->proc_first() == 0)
1978 /* Generate assignment statement statements for the input and
1979 INOUT ports of the task. These are managed by writing
1980 assignments with the task port the l-value and the passed
1981 expression the r-value. We know by definition that the port
1982 is a reg type, so this elaboration is pretty obvious. */
1984 for (unsigned idx
= 0 ; idx
< nparms() ; idx
+= 1) {
1986 NetNet
*port
= def
->port(idx
);
1987 assert(port
->port_type() != NetNet::NOT_A_PORT
);
1988 if (port
->port_type() == NetNet::POUTPUT
)
1991 NetAssign_
*lv
= new NetAssign_(port
);
1992 unsigned wid
= count_lval_width(lv
);
1994 NetExpr
*rv
= elab_and_eval(des
, scope
, parms_
[idx
], wid
);
1996 rv
= pad_to_width(rv
, wid
);
1997 NetAssign
*pr
= new NetAssign(lv
, rv
);
2001 /* Generate the task call proper... */
2002 cur
= new NetUTask(task
);
2003 cur
->set_line(*this);
2007 /* Generate assignment statements for the output and INOUT
2008 ports of the task. The l-value in this case is the
2009 expression passed as a parameter, and the r-value is the
2010 port to be copied out.
2012 We know by definition that the r-value of this copy-out is
2013 the port, which is a reg. The l-value, however, may be any
2014 expression that can be a target to a procedural
2015 assignment, including a memory word. */
2017 for (unsigned idx
= 0 ; idx
< nparms() ; idx
+= 1) {
2019 NetNet
*port
= def
->port(idx
);
2021 /* Skip input ports. */
2022 assert(port
->port_type() != NetNet::NOT_A_PORT
);
2023 if (port
->port_type() == NetNet::PINPUT
)
2027 /* Elaborate an l-value version of the port expression
2028 for output and inout ports. If the expression does
2029 not exist then quietly skip it, but if the expression
2030 is not a valid l-value print an error message. Note
2031 that the elaborate_lval method already printed a
2032 detailed message. */
2035 lv
= parms_
[idx
]->elaborate_lval(des
, scope
, false);
2037 cerr
<< parms_
[idx
]->get_line() << ": error: "
2038 << "I give up on task port " << (idx
+1)
2039 << " expression: " << *parms_
[idx
] << endl
;
2048 NetESignal
*sig
= new NetESignal(port
);
2049 NetExpr
*rv
= pad_to_width(sig
, count_lval_width(lv
));
2051 /* Generate the assignment statement. */
2052 NetAssign
*ass
= new NetAssign(lv
, rv
);
2061 * Elaborate a procedural continuous assign. This really looks very
2062 * much like other procedural assignments, at this point, but there
2063 * is no delay to worry about. The code generator will take care of
2064 * the differences between continuous assign and normal assignments.
2066 NetCAssign
* PCAssign::elaborate(Design
*des
, NetScope
*scope
) const
2071 NetAssign_
*lval
= lval_
->elaborate_lval(des
, scope
, false);
2075 unsigned lwid
= count_lval_width(lval
);
2077 NetExpr
*rexp
= elab_and_eval(des
, scope
, expr_
, lwid
);
2081 rexp
->set_width(lwid
);
2082 rexp
= pad_to_width(rexp
, lwid
);
2084 dev
= new NetCAssign(lval
, rexp
);
2086 if (debug_elaborate
) {
2087 cerr
<< get_line() << ": debug: Elaborate cassign,"
2088 << " lval width=" << lwid
2089 << " rval width=" << rexp
->expr_width()
2090 << " rval=" << *rexp
2094 dev
->set_line(*this);
2098 NetDeassign
* PDeassign::elaborate(Design
*des
, NetScope
*scope
) const
2102 NetAssign_
*lval
= lval_
->elaborate_lval(des
, scope
, false);
2106 NetDeassign
*dev
= new NetDeassign(lval
);
2107 dev
->set_line( *this );
2112 * Elaborate the delay statement (of the form #<expr> <statement>) as a
2113 * NetPDelay object. If the expression is constant, evaluate it now
2114 * and make a constant delay. If not, then pass an elaborated
2115 * expression to the constructor of NetPDelay so that the code
2116 * generator knows to evaluate the expression at run time.
2118 NetProc
* PDelayStatement::elaborate(Design
*des
, NetScope
*scope
) const
2122 /* This call evaluates the delay expression to a NetEConst, if
2123 possible. This includes transforming NetECReal values to
2124 integers, and applying the proper scaling. */
2125 NetExpr
*dex
= elaborate_delay_expr(delay_
, des
, scope
);
2127 if (NetEConst
*tmp
= dynamic_cast<NetEConst
*>(dex
)) {
2129 return new NetPDelay(tmp
->value().as_ulong64(),
2130 statement_
->elaborate(des
, scope
));
2132 return new NetPDelay(tmp
->value().as_ulong(), 0);
2138 return new NetPDelay(dex
, statement_
->elaborate(des
, scope
));
2140 return new NetPDelay(dex
, 0);
2146 * The disable statement is not yet supported.
2148 NetProc
* PDisable::elaborate(Design
*des
, NetScope
*scope
) const
2152 list
<hname_t
> spath
= eval_scope_path(des
, scope
, scope_
);
2154 NetScope
*target
= des
->find_scope(scope
, spath
);
2156 cerr
<< get_line() << ": error: Cannot find scope "
2157 << scope_
<< " in " << scope_path(scope
) << endl
;
2162 switch (target
->type()) {
2163 case NetScope::FUNC
:
2164 cerr
<< get_line() << ": error: Cannot disable functions." << endl
;
2168 case NetScope::MODULE
:
2169 cerr
<< get_line() << ": error: Cannot disable modules." << endl
;
2177 NetDisable
*obj
= new NetDisable(target
);
2178 obj
->set_line(*this);
2183 * An event statement is an event delay of some sort, attached to a
2184 * statement. Some Verilog examples are:
2186 * @(posedge CLK) $display("clock rise");
2187 * @event_1 $display("event triggered.");
2188 * @(data or negedge clk) $display("data or clock fall.");
2190 * The elaborated netlist uses the NetEvent, NetEvWait and NetEvProbe
2191 * classes. The NetEvWait class represents the part of the netlist
2192 * that is executed by behavioral code. The process starts waiting on
2193 * the NetEvent when it executes the NetEvWait step. Net NetEvProbe
2194 * and NetEvTrig are structural and behavioral equivalents that
2195 * trigger the event, and awakens any processes blocking in the
2198 * The basic data structure is:
2200 * NetEvWait ---/---> NetEvent <----\---- NetEvProbe
2202 * NetEvWait ---+ +---- NetEvProbe
2206 * That is, many NetEvWait statements may wait on a single NetEvent
2207 * object, and Many NetEvProbe objects may trigger the NetEvent
2208 * object. The many NetEvWait objects pointing to the NetEvent object
2209 * reflects the possibility of different places in the code blocking
2210 * on the same named event, like so:
2214 * always begin @foo <statement1>; @foo <statement2> end
2216 * This tends to not happen with signal edges. The multiple probes
2217 * pointing to the same event reflect the possibility of many
2218 * expressions in the same blocking statement, like so:
2222 * always @(reset or posedge clk) <stmt>;
2224 * Conjunctions like this cause a NetEvent object be created to
2225 * represent the overall conjunction, and NetEvProbe objects for each
2228 * If the NetEvent object represents a named event from the source,
2229 * then there are NetEvTrig objects that represent the trigger
2230 * statements instead of the NetEvProbe objects representing signals.
2234 * always @foo <stmt>;
2243 * Each trigger statement in the source generates a separate NetEvTrig
2244 * object in the netlist. Those trigger objects are elaborated
2247 * Additional complications arise when named events show up in
2248 * conjunctions. An example of such a case is:
2252 * always @(foo or posedge bar) <stmt>;
2254 * Since there is by definition a NetEvent object for the foo object,
2255 * this is handled by allowing the NetEvWait object to point to
2256 * multiple NetEvent objects. All the NetEvProbe based objects are
2257 * collected and pointed as the synthetic NetEvent object, and all the
2258 * named events are added into the list of NetEvent object that the
2259 * NetEvWait object can refer to.
2262 NetProc
* PEventStatement::elaborate_st(Design
*des
, NetScope
*scope
,
2267 /* Create a single NetEvent and NetEvWait. Then, create a
2268 NetEvProbe for each conjunctive event in the event
2269 list. The NetEvProbe objects all refer back to the NetEvent
2272 NetEvent
*ev
= new NetEvent(scope
->local_symbol());
2273 ev
->set_line(*this);
2274 unsigned expr_count
= 0;
2276 NetEvWait
*wa
= new NetEvWait(enet
);
2277 wa
->set_line(*this);
2279 /* If there are no expressions, this is a signal that it is an
2280 @* statement. Generate an expression to use. */
2282 if (expr_
.count() == 0) {
2284 NexusSet
*nset
= enet
->nex_input();
2286 cerr
<< get_line() << ": internal error: No NexusSet"
2287 << " from statement." << endl
;
2288 enet
->dump(cerr
, 6);
2293 if (nset
->count() == 0) {
2294 cerr
<< get_line() << ": error: No inputs to statement."
2295 << " The @* cannot execute." << endl
;
2300 NetEvProbe
*pr
= new NetEvProbe(scope
, scope
->local_symbol(),
2301 ev
, NetEvProbe::ANYEDGE
,
2303 for (unsigned idx
= 0 ; idx
< nset
->count() ; idx
+= 1)
2304 connect(nset
[0][idx
], pr
->pin(idx
));
2311 } else for (unsigned idx
= 0 ; idx
< expr_
.count() ; idx
+= 1) {
2313 assert(expr_
[idx
]->expr());
2315 /* If the expression is an identifier that matches a
2316 named event, then handle this case all at once at
2317 skip the rest of the expression handling. */
2319 if (PEIdent
*id
= dynamic_cast<PEIdent
*>(expr_
[idx
]->expr())) {
2321 const NetExpr
*par
= 0;
2324 NetScope
*found_in
= symbol_search(des
, scope
, id
->path(),
2327 if (found_in
&& eve
) {
2334 /* So now we have a normal event expression. Elaborate
2335 the sub-expression as a net and decide how to handle
2338 bool save_flag
= error_implicit
;
2339 error_implicit
= true;
2340 NetNet
*expr
= expr_
[idx
]->expr()->elaborate_net(des
, scope
,
2342 error_implicit
= save_flag
;
2344 expr_
[idx
]->dump(cerr
);
2351 unsigned pins
= (expr_
[idx
]->type() == PEEvent::ANYEDGE
)
2352 ? expr
->pin_count() : 1;
2355 switch (expr_
[idx
]->type()) {
2356 case PEEvent::POSEDGE
:
2357 pr
= new NetEvProbe(scope
, scope
->local_symbol(), ev
,
2358 NetEvProbe::POSEDGE
, pins
);
2361 case PEEvent::NEGEDGE
:
2362 pr
= new NetEvProbe(scope
, scope
->local_symbol(), ev
,
2363 NetEvProbe::NEGEDGE
, pins
);
2366 case PEEvent::ANYEDGE
:
2367 pr
= new NetEvProbe(scope
, scope
->local_symbol(), ev
,
2368 NetEvProbe::ANYEDGE
, pins
);
2375 for (unsigned p
= 0 ; p
< pr
->pin_count() ; p
+= 1)
2376 connect(pr
->pin(p
), expr
->pin(p
));
2382 /* If there was at least one conjunction that was an
2383 expression (and not a named event) then add this
2384 event. Otherwise, we didn't use it so delete it. */
2385 if (expr_count
> 0) {
2386 scope
->add_event(ev
);
2388 /* NOTE: This event that I am adding to the wait may be
2389 a duplicate of another event somewhere else. However,
2390 I don't know that until all the modules are hooked
2391 up, so it is best to leave find_similar_event to
2392 after elaboration. */
2401 * This is the special case of the event statement, the wait
2402 * statement. This is elaborated into a slightly more complicated
2403 * statement that uses non-wait statements:
2405 * wait (<expr>) <statement>
2410 * while (1 !== <expr>)
2411 * @(<expr inputs>) <noop>;
2415 NetProc
* PEventStatement::elaborate_wait(Design
*des
, NetScope
*scope
,
2419 assert(expr_
.count() == 1);
2421 const PExpr
*pe
= expr_
[0]->expr();
2423 /* Elaborate wait expression. Don't eval yet, we will do that
2424 shortly, after we apply a reduction or. */
2425 NetExpr
*expr
= pe
->elaborate_expr(des
, scope
, -1, false);
2427 cerr
<< get_line() << ": error: Unable to elaborate"
2428 " wait condition expression." << endl
;
2433 // If the condition expression is more than 1 bits, then
2434 // generate a reduction operator to get the result down to
2435 // one bit. In other words, Turn <e> into |<e>;
2437 if (expr
->expr_width() < 1) {
2438 cerr
<< get_line() << ": internal error: "
2439 "incomprehensible wait expression width (0)." << endl
;
2443 if (expr
->expr_width() > 1) {
2444 assert(expr
->expr_width() > 1);
2445 NetEUReduce
*cmp
= new NetEUReduce('|', expr
);
2449 /* precalculate as much as possible of the wait expression. */
2450 if (NetExpr
*tmp
= expr
->eval_tree()) {
2455 /* Detect the unusual case that the wait expression is
2456 constant. Constant true is OK (it becomes transparent) but
2457 constant false is almost certainly not what is intended. */
2458 assert(expr
->expr_width() == 1);
2459 if (NetEConst
*ce
= dynamic_cast<NetEConst
*>(expr
)) {
2460 verinum val
= ce
->value();
2461 assert(val
.len() == 1);
2463 /* Constant true -- wait(1) <s1> reduces to <s1>. */
2464 if (val
[0] == verinum::V1
) {
2470 /* Otherwise, false. wait(0) blocks permanently. */
2472 cerr
<< get_line() << ": warning: wait expression is "
2473 << "constant false." << endl
;
2474 cerr
<< get_line() << ": : The statement will "
2475 << "block permanently." << endl
;
2477 /* Create an event wait and an otherwise unreferenced
2478 event variable to force a perpetual wait. */
2479 NetEvent
*wait_event
= new NetEvent(scope
->local_symbol());
2480 scope
->add_event(wait_event
);
2482 NetEvWait
*wait
= new NetEvWait(0);
2483 wait
->add_event(wait_event
);
2484 wait
->set_line(*this);
2491 /* Invert the sense of the test with an exclusive NOR. In
2492 other words, if this adjusted expression returns TRUE, then
2494 assert(expr
->expr_width() == 1);
2495 expr
= new NetEBComp('N', expr
, new NetEConst(verinum(verinum::V1
)));
2496 NetExpr
*tmp
= expr
->eval_tree();
2502 NetEvent
*wait_event
= new NetEvent(scope
->local_symbol());
2503 scope
->add_event(wait_event
);
2505 NetEvWait
*wait
= new NetEvWait(0 /* noop */);
2506 wait
->add_event(wait_event
);
2507 wait
->set_line(*this);
2509 NexusSet
*wait_set
= expr
->nex_input();
2510 if (wait_set
== 0) {
2511 cerr
<< get_line() << ": internal error: No NexusSet"
2512 << " from wait expression." << endl
;
2517 if (wait_set
->count() == 0) {
2518 cerr
<< get_line() << ": internal error: Empty NexusSet"
2519 << " from wait expression." << endl
;
2524 NetEvProbe
*wait_pr
= new NetEvProbe(scope
, scope
->local_symbol(),
2525 wait_event
, NetEvProbe::ANYEDGE
,
2527 for (unsigned idx
= 0; idx
< wait_set
->count() ; idx
+= 1)
2528 connect(wait_set
[0][idx
], wait_pr
->pin(idx
));
2531 des
->add_node(wait_pr
);
2533 NetWhile
*loop
= new NetWhile(expr
, wait
);
2534 loop
->set_line(*this);
2536 /* If there is no real substatement (i.e., "wait (foo) ;") then
2541 /* Create a sequential block to combine the wait loop and the
2542 delayed statement. */
2543 NetBlock
*block
= new NetBlock(NetBlock::SEQU
, 0);
2544 block
->append(loop
);
2545 block
->append(enet
);
2546 block
->set_line(*this);
2552 NetProc
* PEventStatement::elaborate(Design
*des
, NetScope
*scope
) const
2556 enet
= statement_
->elaborate(des
, scope
);
2561 enet
= new NetBlock(NetBlock::SEQU
, 0);
2562 enet
->set_line(*this);
2565 if ((expr_
.count() == 1) && (expr_
[0]->type() == PEEvent::POSITIVE
))
2566 return elaborate_wait(des
, scope
, enet
);
2568 return elaborate_st(des
, scope
, enet
);
2572 * Forever statements are represented directly in the netlist. It is
2573 * theoretically possible to use a while structure with a constant
2574 * expression to represent the loop, but why complicate the code
2577 NetProc
* PForever::elaborate(Design
*des
, NetScope
*scope
) const
2579 NetProc
*stat
= statement_
->elaborate(des
, scope
);
2580 if (stat
== 0) return 0;
2582 NetForever
*proc
= new NetForever(stat
);
2587 * Force is like a procedural assignment, most notably prodedural
2588 * continuous assignment:
2590 * force <lval> = <rval>
2592 * The <lval> can be anything that a normal behavioral assignment can
2593 * take, plus net signals. This is a little bit more lax then the
2594 * other proceedural assignments.
2596 NetForce
* PForce::elaborate(Design
*des
, NetScope
*scope
) const
2601 NetAssign_
*lval
= lval_
->elaborate_lval(des
, scope
, true);
2605 unsigned lwid
= count_lval_width(lval
);
2607 NetExpr
*rexp
= elab_and_eval(des
, scope
, expr_
, lwid
);
2611 rexp
->set_width(lwid
, true);
2612 rexp
= pad_to_width(rexp
, lwid
);
2614 dev
= new NetForce(lval
, rexp
);
2616 if (debug_elaborate
) {
2617 cerr
<< get_line() << ": debug: ELaborate force,"
2618 << " lval width=" << lval
->lwidth()
2619 << " rval width=" << rexp
->expr_width()
2620 << " rval=" << *rexp
2624 dev
->set_line(*this);
2629 * elaborate the for loop as the equivalent while loop. This eases the
2630 * task for the target code generator. The structure is:
2634 * while (cond_) begin : body
2640 NetProc
* PForStatement::elaborate(Design
*des
, NetScope
*scope
) const
2645 const PEIdent
*id1
= dynamic_cast<const PEIdent
*>(name1_
);
2647 const PEIdent
*id2
= dynamic_cast<const PEIdent
*>(name2_
);
2650 NetBlock
*top
= new NetBlock(NetBlock::SEQU
, 0);
2651 top
->set_line(*this);
2653 /* make the expression, and later the initial assignment to
2654 the condition variable. The statement in the for loop is
2655 very specifically an assignment. */
2656 NetNet
*sig
= des
->find_signal(scope
, id1
->path());
2658 cerr
<< id1
->get_line() << ": register ``" << id1
->path()
2659 << "'' unknown in this context." << endl
;
2664 NetAssign_
*lv
= new NetAssign_(sig
);
2666 /* Calculate the width of the initialization as if this were
2667 any other assignment statement. */
2668 unsigned use_width
= lv
->lwidth();
2669 bool unsized_flag
= false;
2670 use_width
= expr1_
->test_width(des
, scope
, use_width
, use_width
, unsized_flag
);
2672 /* Make the r-value of the initial assignment, and size it
2673 properly. Then use it to build the assignment statement. */
2674 etmp
= elab_and_eval(des
, scope
, expr1_
, use_width
);
2675 etmp
->set_width(use_width
);
2676 etmp
= pad_to_width(etmp
, use_width
);
2678 if (debug_elaborate
) {
2679 cerr
<< get_line() << ": debug: FOR initial assign: "
2680 << sig
->name() << " = " << *etmp
<< endl
;
2681 assert(etmp
->expr_width() >= lv
->lwidth());
2684 NetAssign
*init
= new NetAssign(lv
, etmp
);
2685 init
->set_line(*this);
2689 NetBlock
*body
= new NetBlock(NetBlock::SEQU
, 0);
2690 body
->set_line(*this);
2692 /* Elaborate the statement that is contained in the for
2693 loop. If there is an error, this will return 0 and I should
2694 skip the append. No need to worry, the error has been
2695 reported so it's OK that the netlist is bogus. */
2696 NetProc
*tmp
= statement_
->elaborate(des
, scope
);
2701 /* Elaborate the increment assignment statement at the end of
2702 the for loop. This is also a very specific assignment
2703 statement. Put this into the "body" block. */
2704 sig
= des
->find_signal(scope
, id2
->path());
2706 cerr
<< get_line() << ": error: Unable to find variable "
2707 << id2
->path() << " in for-loop increment expressin." << endl
;
2713 lv
= new NetAssign_(sig
);
2715 /* Make the rvalue of the increment expression, and size it
2717 etmp
= elab_and_eval(des
, scope
, expr2_
, lv
->lwidth());
2718 NetAssign
*step
= new NetAssign(lv
, etmp
);
2719 step
->set_line(*this);
2724 /* Elaborate the condition expression. Try to evaluate it too,
2725 in case it is a constant. This is an interesting case
2726 worthy of a warning. */
2727 NetExpr
*ce
= elab_and_eval(des
, scope
, cond_
, -1);
2733 if (dynamic_cast<NetEConst
*>(ce
)) {
2734 cerr
<< get_line() << ": warning: condition expression "
2735 "of for-loop is constant." << endl
;
2739 /* All done, build up the loop. */
2741 NetWhile
*loop
= new NetWhile(ce
, body
);
2742 loop
->set_line(*this);
2748 * (See the PTask::elaborate methods for basic common stuff.)
2750 * The return value of a function is represented as a reg variable
2751 * within the scope of the function that has the name of the
2752 * function. So for example with the function:
2754 * function [7:0] incr;
2759 * The scope of the function is <parent>.incr and there is a reg
2760 * variable <parent>.incr.incr. The elaborate_1 method is called with
2761 * the scope of the function, so the return reg is easily located.
2763 * The function parameters are all inputs, except for the synthetic
2764 * output parameter that is the return value. The return value goes
2765 * into port 0, and the parameters are all the remaining ports.
2768 void PFunction::elaborate(Design
*des
, NetScope
*scope
) const
2770 NetFuncDef
*def
= scope
->func_def();
2772 cerr
<< get_line() << ": internal error: "
2773 << "No function definition for function "
2774 << scope_path(scope
) << endl
;
2780 NetProc
*st
= statement_
->elaborate(des
, scope
);
2782 cerr
<< statement_
->get_line() << ": error: Unable to elaborate "
2783 "statement in function " << scope
->basename() << "." << endl
;
2791 NetProc
* PRelease::elaborate(Design
*des
, NetScope
*scope
) const
2795 NetAssign_
*lval
= lval_
->elaborate_lval(des
, scope
, true);
2799 NetRelease
*dev
= new NetRelease(lval
);
2800 dev
->set_line( *this );
2804 NetProc
* PRepeat::elaborate(Design
*des
, NetScope
*scope
) const
2808 NetExpr
*expr
= elab_and_eval(des
, scope
, expr_
, -1);
2810 cerr
<< get_line() << ": Unable to elaborate"
2811 " repeat expression." << endl
;
2816 NetProc
*stat
= statement_
->elaborate(des
, scope
);
2817 if (stat
== 0) return 0;
2819 // If the expression is a constant, handle certain special
2820 // iteration counts.
2821 if (NetEConst
*ce
= dynamic_cast<NetEConst
*>(expr
)) {
2822 verinum val
= ce
->value();
2823 switch (val
.as_ulong()) {
2827 return new NetBlock(NetBlock::SEQU
, 0);
2836 NetRepeat
*proc
= new NetRepeat(expr
, stat
);
2841 * A task definition is elaborated by elaborating the statement that
2842 * it contains, and connecting its ports to NetNet objects. The
2843 * netlist doesn't really need the array of parameters once elaboration
2844 * is complete, but this is the best place to store them.
2846 * The first elaboration pass finds the reg objects that match the
2847 * port names, and creates the NetTaskDef object. The port names are
2848 * in the form task.port.
2855 * So in the foo example, the PWire objects that represent the ports
2856 * of the task will include a foo.blah for the blah port. This port is
2857 * bound to a NetNet object by looking up the name. All of this is
2858 * handled by the PTask::elaborate_sig method and the results stashed
2859 * in the created NetTaskDef attached to the scope.
2861 * Elaboration pass 2 for the task definition causes the statement of
2862 * the task to be elaborated and attached to the NetTaskDef object
2863 * created in pass 1.
2865 * NOTE: I am not sure why I bothered to prepend the task name to the
2866 * port name when making the port list. It is not really useful, but
2867 * that is what I did in pform_make_task_ports, so there it is.
2870 void PTask::elaborate(Design
*des
, NetScope
*task
) const
2872 NetTaskDef
*def
= task
->task_def();
2876 if (statement_
== 0) {
2877 st
= new NetBlock(NetBlock::SEQU
, 0);
2881 st
= statement_
->elaborate(des
, task
);
2883 cerr
<< statement_
->get_line() << ": Unable to elaborate "
2884 "statement in task " << scope_path(task
)
2885 << " at " << get_line() << "." << endl
;
2893 NetProc
* PTrigger::elaborate(Design
*des
, NetScope
*scope
) const
2898 const NetExpr
*par
= 0;
2901 NetScope
*found_in
= symbol_search(des
, scope
, event_
,
2904 if (found_in
== 0) {
2905 cerr
<< get_line() << ": error: event <" << event_
<< ">"
2906 << " not found." << endl
;
2912 cerr
<< get_line() << ": error: <" << event_
<< ">"
2913 << " is not a named event." << endl
;
2918 NetEvTrig
*trig
= new NetEvTrig(eve
);
2919 trig
->set_line(*this);
2924 * The while loop is fairly directly represented in the netlist.
2926 NetProc
* PWhile::elaborate(Design
*des
, NetScope
*scope
) const
2928 NetWhile
*loop
= new NetWhile(elab_and_eval(des
, scope
, cond_
, -1),
2929 statement_
->elaborate(des
, scope
));
2933 bool PProcess::elaborate(Design
*des
, NetScope
*scope
) const
2935 NetProc
*cur
= statement_
->elaborate(des
, scope
);
2942 case PProcess::PR_INITIAL
:
2943 top
= new NetProcTop(scope
, NetProcTop::KINITIAL
, cur
);
2945 case PProcess::PR_ALWAYS
:
2946 top
= new NetProcTop(scope
, NetProcTop::KALWAYS
, cur
);
2949 ivl_assert(*this, top
);
2951 // Evaluate the attributes for this process, if there
2952 // are any. These attributes are to be attached to the
2953 // NetProcTop object.
2954 struct attrib_list_t
*attrib_list
= 0;
2955 unsigned attrib_list_n
= 0;
2956 attrib_list
= evaluate_attributes(attributes
, attrib_list_n
, des
, scope
);
2958 for (unsigned adx
= 0 ; adx
< attrib_list_n
; adx
+= 1)
2959 top
->attribute(attrib_list
[adx
].key
,
2960 attrib_list
[adx
].val
);
2962 delete[]attrib_list
;
2964 top
->set_line(*this);
2965 des
->add_process(top
);
2967 /* Detect the special case that this is a combinational
2968 always block. We want to attach an _ivl_schedule_push
2969 attribute to this process so that it starts up and
2970 gets into its wait statement before non-combinational
2971 code is executed. */
2973 if (top
->type() != NetProcTop::KALWAYS
)
2976 NetEvWait
*st
= dynamic_cast<NetEvWait
*>(top
->statement());
2980 if (st
->nevents() != 1)
2983 NetEvent
*ev
= st
->event(0);
2985 if (ev
->nprobe() == 0)
2988 bool anyedge_test
= true;
2989 for (unsigned idx
= 0 ; anyedge_test
&& (idx
<ev
->nprobe())
2991 const NetEvProbe
*pr
= ev
->probe(idx
);
2992 if (pr
->edge() != NetEvProbe::ANYEDGE
)
2993 anyedge_test
= false;
2999 top
->attribute(perm_string::literal("_ivl_schedule_push"),
3006 void PSpecPath::elaborate(Design
*des
, NetScope
*scope
) const
3008 uint64_t delay_value
[12];
3009 unsigned ndelays
= 0;
3011 /* Do not elaborate specify delay paths if this feature is
3013 if (!gn_specify_blocks_flag
)
3016 /* Check for various path types that are not supported. */
3017 if (conditional
&& !condition
) {
3018 cerr
<< get_line() << ": sorry: ifnone specify paths"
3019 << " are not supported." << endl
;
3020 cerr
<< get_line() << ": : Use -g no-specify to ignore"
3021 << " specify blocks." << endl
;
3026 ivl_assert(*this, conditional
|| (condition
==0));
3028 ndelays
= delays
.size();
3032 int shift
= scope
->time_unit() - des
->get_precision();
3034 /* Elaborate the delay values themselves. Remember to scale
3035 them for the timescale/precision of the scope. */
3036 for (unsigned idx
= 0 ; idx
< ndelays
; idx
+= 1) {
3037 PExpr
*exp
= delays
[idx
];
3038 NetExpr
*cur
= elab_and_eval(des
, scope
, exp
, 0);
3040 if (NetEConst
*cur_con
= dynamic_cast<NetEConst
*> (cur
)) {
3041 delay_value
[idx
] = cur_con
->value().as_ulong();
3042 for (int tmp
= 0 ; tmp
< shift
; tmp
+= 1)
3043 delay_value
[idx
] *= 10;
3045 } else if (NetECReal
*cur_rcon
= dynamic_cast<NetECReal
*>(cur
)) {
3046 delay_value
[idx
] = cur_rcon
->value().as_long(shift
);
3049 cerr
<< get_line() << ": error: Path delay value "
3050 << "must be constant." << endl
;
3051 delay_value
[idx
] = 0;
3065 cerr
<< get_line() << ": error: Incorrect delay configuration."
3072 NetNet
*condit_sig
= 0;
3074 ivl_assert(*this, condition
);
3076 NetExpr
*tmp
= elab_and_eval(des
, scope
, condition
, -1);
3077 ivl_assert(*condition
, tmp
);
3079 // FIXME: Look for constant expressions here?
3082 condit_sig
= tmp
->synthesize(des
);
3083 ivl_assert(*condition
, condit_sig
);
3086 /* Create all the various paths from the path specifier. */
3087 typedef std::vector
<perm_string
>::const_iterator str_vector_iter
;
3088 for (str_vector_iter cur
= dst
.begin()
3089 ; cur
!= dst
.end() ; cur
++) {
3091 if (debug_elaborate
) {
3092 cerr
<< get_line() << ": debug: Path to " << (*cur
);
3094 cerr
<< " if " << condit_sig
->name();
3098 NetNet
*dst_sig
= scope
->find_signal(*cur
);
3100 cerr
<< get_line() << ": error: No such wire "
3101 << *cur
<< " in this module." << endl
;
3106 if (dst_sig
->port_type() != NetNet::POUTPUT
3107 && dst_sig
->port_type() != NetNet::PINOUT
) {
3109 cerr
<< get_line() << ": error: Path destination "
3110 << *cur
<< " must be an output or inout port." << endl
;
3114 NetDelaySrc
*path
= new NetDelaySrc(scope
, scope
->local_symbol(),
3115 src
.size(), condit_sig
);
3116 path
->set_line(*this);
3118 // The presence of the data_source_expression indicates
3119 // that this is an edge sensitive path. If so, then set
3120 // the edges. Note that edge==0 is BOTH edges.
3121 if (data_source_expression
) {
3122 if (edge
>= 0) path
->set_posedge();
3123 if (edge
<= 0) path
->set_negedge();
3128 path
->set_delays(delay_value
[0], delay_value
[1],
3129 delay_value
[2], delay_value
[3],
3130 delay_value
[4], delay_value
[5],
3131 delay_value
[6], delay_value
[7],
3132 delay_value
[8], delay_value
[9],
3133 delay_value
[10], delay_value
[11]);
3136 path
->set_delays(delay_value
[0], delay_value
[1],
3137 delay_value
[2], delay_value
[3],
3138 delay_value
[4], delay_value
[5]);
3141 path
->set_delays(delay_value
[0], delay_value
[1],
3145 path
->set_delays(delay_value
[0], delay_value
[1]);
3148 path
->set_delays(delay_value
[0]);
3153 for (str_vector_iter cur_src
= src
.begin()
3154 ; cur_src
!= src
.end() ; cur_src
++) {
3155 NetNet
*src_sig
= scope
->find_signal(*cur_src
);
3158 if (src_sig
->port_type() != NetNet::PINPUT
3159 & src_sig
->port_type() != NetNet::PINOUT
) {
3161 cerr
<< get_line() << ": error: Path source "
3162 << *cur_src
<< " must be an input or inout port."
3167 connect(src_sig
->pin(0), path
->pin(idx
));
3172 connect(condit_sig
->pin(0), path
->pin(idx
));
3174 dst_sig
->add_delay_path(path
);
3180 * When a module is instantiated, it creates the scope then uses this
3181 * method to elaborate the contents of the module.
3183 bool Module::elaborate(Design
*des
, NetScope
*scope
) const
3185 bool result_flag
= true;
3187 if (gn_specify_blocks_flag
) {
3188 // Elaborate specparams
3189 typedef map
<perm_string
,PExpr
*>::const_iterator specparam_it_t
;
3190 for (specparam_it_t cur
= specparams
.begin()
3191 ; cur
!= specparams
.end() ; cur
++ ) {
3193 NetExpr
*val
= elab_and_eval(des
, scope
, (*cur
).second
, -1);
3194 NetScope::spec_val_t value
;
3196 if (NetECReal
*val_c
= dynamic_cast<NetECReal
*> (val
)) {
3198 value
.type
= IVL_VT_REAL
;
3199 value
.real_val
= val_c
->value().as_double();
3201 if (debug_elaborate
)
3202 cerr
<< get_line() << ": debug: Elaborate "
3203 << "specparam " << (*cur
).first
3204 << " value=" << value
.real_val
<< endl
;
3206 } else if (NetEConst
*val_c
= dynamic_cast<NetEConst
*> (val
)) {
3208 value
.type
= IVL_VT_BOOL
;
3209 value
.integer
= val_c
->value().as_long();
3211 if (debug_elaborate
)
3212 cerr
<< get_line() << ": debug: Elaborate "
3213 << "specparam " << (*cur
).first
3214 << " value=" << value
.integer
<< endl
;
3217 value
.type
= IVL_VT_NO_TYPE
;
3218 cerr
<< (*cur
).second
->get_line() << ": error: "
3219 << "specparam " << (*cur
).first
<< " value"
3220 << " is not constant: " << *val
<< endl
;
3226 scope
->specparams
[(*cur
).first
] = value
;
3230 // Elaborate within the generate blocks.
3231 typedef list
<PGenerate
*>::const_iterator generate_it_t
;
3232 for (generate_it_t cur
= generate_schemes
.begin()
3233 ; cur
!= generate_schemes
.end() ; cur
++ ) {
3234 (*cur
)->elaborate(des
, scope
);
3237 // Elaborate functions.
3238 typedef map
<perm_string
,PFunction
*>::const_iterator mfunc_it_t
;
3239 for (mfunc_it_t cur
= funcs_
.begin()
3240 ; cur
!= funcs_
.end() ; cur
++) {
3242 hname_t
use_name ( (*cur
).first
);
3243 NetScope
*fscope
= scope
->child(use_name
);
3245 (*cur
).second
->elaborate(des
, fscope
);
3248 // Elaborate the task definitions. This is done before the
3249 // behaviors so that task calls may reference these, and after
3250 // the signals so that the tasks can reference them.
3251 typedef map
<perm_string
,PTask
*>::const_iterator mtask_it_t
;
3252 for (mtask_it_t cur
= tasks_
.begin()
3253 ; cur
!= tasks_
.end() ; cur
++) {
3255 hname_t
use_name ( (*cur
).first
);
3256 NetScope
*tscope
= scope
->child(use_name
);
3258 (*cur
).second
->elaborate(des
, tscope
);
3261 // Get all the gates of the module and elaborate them by
3262 // connecting them to the signals. The gate may be simple or
3264 const list
<PGate
*>&gl
= get_gates();
3266 for (list
<PGate
*>::const_iterator gt
= gl
.begin()
3270 (*gt
)->elaborate(des
, scope
);
3273 // Elaborate the behaviors, making processes out of them. This
3274 // involves scanning the PProcess* list, creating a NetProcTop
3275 // for each process.
3276 const list
<PProcess
*>&sl
= get_behaviors();
3278 for (list
<PProcess
*>::const_iterator st
= sl
.begin()
3279 ; st
!= sl
.end() ; st
++ ) {
3281 result_flag
&= (*st
)->elaborate(des
, scope
);
3284 // Elaborate the specify paths of the module.
3286 for (list
<PSpecPath
*>::const_iterator sp
= specify_paths
.begin()
3287 ; sp
!= specify_paths
.end() ; sp
++) {
3289 (*sp
)->elaborate(des
, scope
);
3295 bool PGenerate::elaborate(Design
*des
, NetScope
*container
) const
3299 typedef list
<NetScope
*>::const_iterator scope_list_it_t
;
3300 for (scope_list_it_t cur
= scope_list_
.begin()
3301 ; cur
!= scope_list_
.end() ; cur
++ ) {
3303 NetScope
*scope
= *cur
;
3304 // Check that this scope is one that is contained in the
3305 // container that the caller passed in.
3306 if (scope
->parent() != container
)
3309 if (debug_elaborate
)
3310 cerr
<< get_line() << ": debug: Elaborate in "
3311 << "scope " << scope_path(scope
) << endl
;
3313 flag
= elaborate_(des
, scope
) & flag
;
3319 bool PGenerate::elaborate_(Design
*des
, NetScope
*scope
) const
3321 typedef list
<PGate
*>::const_iterator gates_it_t
;
3322 for (gates_it_t cur
= gates
.begin() ; cur
!= gates
.end() ; cur
++ )
3323 (*cur
)->elaborate(des
, scope
);
3325 typedef list
<PProcess
*>::const_iterator proc_it_t
;
3326 for (proc_it_t cur
= behaviors
.begin(); cur
!= behaviors
.end(); cur
++)
3327 (*cur
)->elaborate(des
, scope
);
3337 Design
* elaborate(list
<perm_string
>roots
)
3339 svector
<root_elem
*> root_elems(roots
.size());
3343 // This is the output design. I fill it in as I scan the root
3344 // module and elaborate what I find.
3345 Design
*des
= new Design
;
3347 // Scan the root modules, and elaborate their scopes.
3348 for (list
<perm_string
>::const_iterator root
= roots
.begin()
3349 ; root
!= roots
.end()
3352 // Look for the root module in the list.
3353 map
<perm_string
,Module
*>::const_iterator mod
= pform_modules
.find(*root
);
3354 if (mod
== pform_modules
.end()) {
3355 cerr
<< "error: Unable to find the root module \""
3356 << (*root
) << "\" in the Verilog source." << endl
;
3357 cerr
<< " : Perhaps ``-s " << (*root
)
3358 << "'' is incorrect?" << endl
;
3363 // Get the module definition for this root instance.
3364 Module
*rmod
= (*mod
).second
;
3366 // Make the root scope.
3367 NetScope
*scope
= des
->make_root_scope(*root
);
3368 scope
->time_unit(rmod
->time_unit
);
3369 scope
->time_precision(rmod
->time_precision
);
3370 scope
->default_nettype(rmod
->default_nettype
);
3371 des
->set_precision(rmod
->time_precision
);
3373 Module::replace_t stub
;
3375 // Recursively elaborate from this root scope down. This
3376 // does a lot of the grunt work of creating sub-scopes, etc.
3377 if (! rmod
->elaborate_scope(des
, scope
, stub
)) {
3382 struct root_elem
*r
= new struct root_elem
;
3385 root_elems
[i
++] = r
;
3388 // Errors already? Probably missing root modules. Just give up
3389 // now and return nothing.
3390 if (des
->errors
> 0)
3393 // This method recurses through the scopes, looking for
3394 // defparam assignments to apply to the parameters in the
3395 // various scopes. This needs to be done after all the scopes
3396 // and basic parameters are taken care of because the defparam
3397 // can assign to a parameter declared *after* it.
3398 des
->run_defparams();
3401 // At this point, all parameter overrides are done. Scan the
3402 // scopes and evaluate the parameters all the way down to
3404 des
->evaluate_parameters();
3406 // With the parameters evaluated down to constants, we have
3407 // what we need to elaborate signals and memories. This pass
3408 // creates all the NetNet and NetMemory objects for declared
3410 for (i
= 0; i
< root_elems
.count(); i
++) {
3411 Module
*rmod
= root_elems
[i
]->mod
;
3412 NetScope
*scope
= root_elems
[i
]->scope
;
3414 if (! rmod
->elaborate_sig(des
, scope
)) {
3420 // Now that the structure and parameters are taken care of,
3421 // run through the pform again and generate the full netlist.
3422 for (i
= 0; i
< root_elems
.count(); i
++) {
3423 Module
*rmod
= root_elems
[i
]->mod
;
3424 NetScope
*scope
= root_elems
[i
]->scope
;
3426 rc
&= rmod
->elaborate(des
, scope
);
3440 * $Log: elaborate.cc,v $
3441 * Revision 1.374 2007/06/05 21:35:51 steve
3442 * Error resiliency (ldoolitt)
3444 * Revision 1.373 2007/06/04 02:19:07 steve
3445 * Handle bit/part select of array words in nets.
3447 * Revision 1.372 2007/06/02 03:42:12 steve
3448 * Properly evaluate scope path expressions.
3450 * Revision 1.371 2007/05/24 04:07:11 steve
3451 * Rework the heirarchical identifier parse syntax and pform
3452 * to handle more general combinations of heirarch and bit selects.
3454 * Revision 1.370 2007/04/16 01:10:07 steve
3455 * Properly ignore unsupported ifnone.
3457 * Revision 1.369 2007/04/15 20:45:40 steve
3458 * Attach line number information to task calls.
3460 * Revision 1.368 2007/04/13 02:34:35 steve
3461 * Parse edge sensitive paths without edge specifier.
3463 * Revision 1.367 2007/04/05 03:09:50 steve
3464 * Allow implicit wires in assign l-value.
3466 * Revision 1.366 2007/04/01 23:01:10 steve
3467 * Improve port mismatch error message.
3469 * Revision 1.365 2007/03/22 16:08:15 steve
3470 * Spelling fixes from Larry
3472 * Revision 1.364 2007/03/08 05:30:02 steve
3473 * Limit the calculated widths of constants.
3475 * Revision 1.363 2007/03/05 05:59:10 steve
3476 * Handle processes within generate loops.
3478 * Revision 1.362 2007/03/03 05:56:55 steve
3479 * Check that path source/destination are ports.
3481 * Revision 1.361 2007/03/02 06:13:22 steve
3482 * Add support for edge sensitive spec paths.
3484 * Revision 1.360 2007/03/01 06:19:38 steve
3485 * Add support for conditional specify delay paths.
3487 * Revision 1.359 2007/02/12 01:52:21 steve
3488 * Parse all specify paths to pform.
3490 * Revision 1.358 2007/02/01 05:52:24 steve
3491 * More generous handling of errors in blocks.
3493 * Revision 1.357 2007/01/21 04:26:36 steve
3494 * Clean up elaboration of for-loop increment expression.
3496 * Revision 1.356 2007/01/19 05:42:40 steve
3497 * Precalculate constant power expressions, and constant function arguments.
3499 * Revision 1.355 2007/01/16 05:44:15 steve
3500 * Major rework of array handling. Memories are replaced with the
3501 * more general concept of arrays. The NetMemory and NetEMemory
3502 * classes are removed from the ivl core program, and the IVL_LPM_RAM
3503 * lpm type is removed from the ivl_target API.
3505 * Revision 1.354 2006/12/09 01:59:35 steve
3506 * Fix an uninitialized variable warning.
3508 * Revision 1.353 2006/12/08 04:09:41 steve
3509 * @* without inputs is an error.
3511 * Revision 1.352 2006/11/27 02:01:07 steve
3512 * Fix crash handling constant true conditional.
3514 * Revision 1.351 2006/11/26 07:10:30 steve
3515 * Fix compile time eval of condition expresion to do reduction OR of vectors.
3517 * Revision 1.350 2006/11/26 06:29:16 steve
3518 * Fix nexus widths for direct link assign and ternary nets.
3520 * Revision 1.349 2006/11/04 06:19:25 steve
3521 * Remove last bits of relax_width methods, and use test_width
3522 * to calculate the width of an r-value expression that may
3523 * contain unsized numbers.
3525 * Revision 1.348 2006/10/30 05:44:49 steve
3526 * Expression widths with unsized literals are pseudo-infinite width.
3528 * Revision 1.347 2006/10/03 15:33:49 steve
3529 * no-specify turns of specparam elaboration.
3531 * Revision 1.346 2006/10/03 05:06:00 steve
3532 * Support real valued specify delays, properly scaled.
3534 * Revision 1.345 2006/09/28 04:35:18 steve
3535 * Support selective control of specify and xtypes features.
3537 * Revision 1.344 2006/09/26 19:48:40 steve
3538 * Missing PSpec.cc file.
3540 * Revision 1.343 2006/09/23 04:57:19 steve
3541 * Basic support for specify timing.
3543 * Revision 1.342 2006/09/22 22:14:27 steve
3544 * Proper error message when logic array pi count is bad.
3546 * Revision 1.341 2006/08/08 05:11:37 steve
3547 * Handle 64bit delay constants.
3549 * Revision 1.340 2006/06/02 04:48:50 steve
3550 * Make elaborate_expr methods aware of the width that the context
3551 * requires of it. In the process, fix sizing of the width of unary
3552 * minus is context determined sizes.
3554 * Revision 1.339 2006/05/01 20:47:59 steve
3555 * More explicit datatype setup.
3557 * Revision 1.338 2006/04/30 05:17:48 steve
3558 * Get the data type of part select results right.
3560 * Revision 1.337 2006/04/26 04:43:50 steve
3561 * Chop down assign r-values that elaborate too wide.
3563 * Revision 1.336 2006/04/10 00:37:42 steve
3564 * Add support for generate loops w/ wires and gates.
3566 * Revision 1.335 2006/03/30 01:49:07 steve
3567 * Fix instance arrays indexed by overridden parameters.
3569 * Revision 1.334 2006/01/03 05:22:14 steve
3570 * Handle complex net node delays.
3572 * Revision 1.333 2006/01/02 05:33:19 steve
3573 * Node delays can be more general expressions in structural contexts.
3575 * Revision 1.332 2005/11/26 00:35:42 steve
3576 * More precise about r-value width of constants.
3578 * Revision 1.331 2005/11/10 13:28:11 steve
3579 * Reorganize signal part select handling, and add support for
3580 * indexed part selects.
3582 * Expand expression constant propagation to eliminate extra
3583 * sums in certain cases.
3585 * Revision 1.330 2005/09/27 04:51:37 steve
3586 * Error message for invalid for-loop index variable.
3588 * Revision 1.329 2005/09/14 02:53:13 steve
3589 * Support bool expressions and compares handle them optimally.
3591 * Revision 1.328 2005/08/06 17:58:16 steve
3592 * Implement bi-directional part selects.
3594 * Revision 1.327 2005/07/15 00:41:09 steve
3595 * More debug information.
3597 * Revision 1.326 2005/07/11 16:56:50 steve
3598 * Remove NetVariable and ivl_variable_t structures.
3600 * Revision 1.325 2005/06/17 05:06:47 steve
3603 * Revision 1.324 2005/05/24 01:44:27 steve
3604 * Do sign extension of structuran nets.
3606 * Revision 1.323 2005/05/17 20:56:55 steve
3607 * Parameters cannot have their width changed.
3609 * Revision 1.322 2005/05/13 05:12:39 steve
3610 * Some debug messages.
3612 * Revision 1.321 2005/04/24 23:44:01 steve
3613 * Update DFF support to new data flow.
3615 * Revision 1.320 2005/03/05 05:38:33 steve
3616 * Get rval width right for arguments into task calls.
3618 * Revision 1.319 2005/02/19 02:43:38 steve
3619 * Support shifts and divide.
3621 * Revision 1.318 2005/02/10 04:56:58 steve
3622 * distinguish between single port namy instances, and single instances many sub-ports.
3624 * Revision 1.317 2005/02/08 00:12:36 steve
3625 * Add the NetRepeat node, and code generator support.
3627 * Revision 1.316 2005/01/30 01:42:05 steve
3628 * Debug messages for PGAssign elaboration.
3630 * Revision 1.315 2005/01/22 18:16:00 steve
3631 * Remove obsolete NetSubnet class.
3633 * Revision 1.314 2005/01/12 03:17:36 steve
3634 * Properly pad vector widths in pgassign.
3636 * Revision 1.313 2005/01/09 20:16:01 steve
3637 * Use PartSelect/PV and VP to handle part selects through ports.
3639 * Revision 1.312 2004/12/29 23:55:43 steve
3640 * Unify elaboration of l-values for all proceedural assignments,
3641 * including assing, cassign and force.
3643 * Generate NetConcat devices for gate outputs that feed into a
3644 * vector results. Use this to hande gate arrays. Also let gate
3645 * arrays handle vectors of gates when the outputs allow for it.
3647 * Revision 1.311 2004/12/15 17:09:11 steve
3648 * Force r-value padded to width.
3650 * Revision 1.310 2004/12/12 18:13:39 steve
3651 * Fix r-value width of continuous assign.
3653 * Revision 1.309 2004/12/11 02:31:25 steve
3654 * Rework of internals to carry vectors through nexus instead
3655 * of single bits. Make the ivl, tgt-vvp and vvp initial changes