Merge similar probes within a module.
[iverilog.git] / elaborate.cc
blob84a58099458db5ab1cdb9cf57d9b3eb9883bfd98
1 /*
2 * Copyright (c) 1998-2000 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)
8 * any later version.
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
19 #if !defined(WINNT) && !defined(macintosh)
20 #ident "$Id: elaborate.cc,v 1.174 2000/05/27 19:33:23 steve Exp $"
21 #endif
24 * Elaboration takes as input a complete parse tree and the name of a
25 * root module, and generates as output the elaborated design. This
26 * elaborated design is presented as a Module, which does not
27 * reference any other modules. It is entirely self contained.
30 # include <typeinfo>
31 # include <strstream>
32 # include "pform.h"
33 # include "PEvent.h"
34 # include "netlist.h"
35 # include "netmisc.h"
36 # include "util.h"
38 // Urff, I don't like this global variable. I *will* figure out a
39 // way to get rid of it. But, for now the PGModule::elaborate method
40 // needs it to find the module definition.
41 static const map<string,Module*>* modlist = 0;
42 static const map<string,PUdp*>* udplist = 0;
44 static Link::strength_t drive_type(PGate::strength_t drv)
46 switch (drv) {
47 case PGate::HIGHZ:
48 return Link::HIGHZ;
49 case PGate::WEAK:
50 return Link::WEAK;
51 case PGate::PULL:
52 return Link::PULL;
53 case PGate::STRONG:
54 return Link::STRONG;
55 case PGate::SUPPLY:
56 return Link::SUPPLY;
57 default:
58 assert(0);
60 return Link::STRONG;
64 void PGate::elaborate(Design*des, const string&path) const
66 cerr << "internal error: what kind of gate? " <<
67 typeid(*this).name() << endl;
71 * Elaborate the continuous assign. (This is *not* the procedural
72 * assign.) Elaborate the lvalue and rvalue, and do the assignment.
74 void PGAssign::elaborate(Design*des, const string&path) const
76 unsigned long rise_time, fall_time, decay_time;
77 eval_delays(des, path, rise_time, fall_time, decay_time);
79 Link::strength_t drive0 = drive_type(strength0());
80 Link::strength_t drive1 = drive_type(strength1());
82 assert(pin(0));
83 assert(pin(1));
85 /* Elaborate the l-value. */
86 NetNet*lval = pin(0)->elaborate_lnet(des, path);
87 if (lval == 0) {
88 des->errors += 1;
89 return;
93 /* Handle the special case that the rval is simply an
94 identifier. Get the rval as a NetNet, then use NetBUFZ
95 objects to connect it to the l-value. This is necessary to
96 direct drivers. This is how I attach strengths to the
97 assignment operation. */
98 if (const PEIdent*id = dynamic_cast<const PEIdent*>(pin(1))) {
99 NetNet*rid = id->elaborate_net(des, path, lval->pin_count(),
100 0, 0, 0, Link::STRONG,
101 Link::STRONG);
102 assert(rid);
103 for (unsigned idx = 0 ; idx < lval->pin_count() ; idx += 1) {
104 NetBUFZ*dev = new NetBUFZ(des->local_symbol(path));
105 connect(lval->pin(idx), dev->pin(0));
106 connect(rid->pin(idx), dev->pin(1));
107 dev->pin(0).drive0(drive0);
108 dev->pin(0).drive1(drive1);
109 des->add_node(dev);
111 return;
114 /* Elaborate the r-value. Account for the initial decays,
115 which are going to be attached to the last gate before the
116 generated NetNet. */
117 NetNet*rval = pin(1)->elaborate_net(des, path,
118 lval->pin_count(),
119 rise_time, fall_time, decay_time,
120 drive0, drive1);
121 if (rval == 0) {
122 cerr << get_line() << ": error: Unable to elaborate r-value: "
123 << *pin(1) << endl;
124 des->errors += 1;
125 return;
128 assert(lval && rval);
130 if (lval->pin_count() > rval->pin_count()) {
131 cerr << get_line() << ": sorry: lval width (" <<
132 lval->pin_count() << ") > rval width (" <<
133 rval->pin_count() << ")." << endl;
134 delete lval;
135 delete rval;
136 des->errors += 1;
137 return;
140 for (unsigned idx = 0 ; idx < lval->pin_count() ; idx += 1)
141 connect(lval->pin(idx), rval->pin(idx));
143 if (lval->local_flag())
144 delete lval;
149 * Elaborate a Builtin gate. These normally get translated into
150 * NetLogic nodes that reflect the particular logic function.
152 void PGBuiltin::elaborate(Design*des, const string&path) const
154 unsigned count = 1;
155 unsigned low = 0, high = 0;
156 string name = get_name();
157 if (name == "")
158 name = des->local_symbol(path);
159 else
160 name = path+"."+name;
162 /* If the verilog source has a range specification for the
163 gates, then I am expected to make more then one
164 gate. Figure out how many are desired. */
165 if (msb_) {
166 verinum*msb = msb_->eval_const(des, path);
167 verinum*lsb = lsb_->eval_const(des, path);
169 if (msb == 0) {
170 cerr << get_line() << ": error: Unable to evaluate "
171 "expression " << *msb_ << endl;
172 des->errors += 1;
173 return;
176 if (lsb == 0) {
177 cerr << get_line() << ": error: Unable to evaluate "
178 "expression " << *lsb_ << endl;
179 des->errors += 1;
180 return;
183 if (msb->as_long() > lsb->as_long())
184 count = msb->as_long() - lsb->as_long() + 1;
185 else
186 count = lsb->as_long() - msb->as_long() + 1;
188 low = lsb->as_long();
189 high = msb->as_long();
193 /* Allocate all the getlist nodes for the gates. */
194 NetLogic**cur = new NetLogic*[count];
195 assert(cur);
197 /* Calculate the gate delays from the delay expressions
198 given in the source. For logic gates, the decay time
199 is meaningless because it can never go to high
200 impedence. However, the bufif devices can generate
201 'bz output, so we will pretend that anything can.
203 If only one delay value expression is given (i.e. #5
204 nand(foo,...)) then rise, fall and decay times are
205 all the same value. If two values are given, rise and
206 fall times are use, and the decay time is the minimum
207 of the rise and fall times. Finally, if all three
208 values are given, they are taken as specified. */
210 unsigned long rise_time, fall_time, decay_time;
211 eval_delays(des, path, rise_time, fall_time, decay_time);
213 /* Now make as many gates as the bit count dictates. Give each
214 a unique name, and set the delay times. */
216 for (unsigned idx = 0 ; idx < count ; idx += 1) {
217 strstream tmp;
218 unsigned index;
219 if (low < high)
220 index = low + idx;
221 else
222 index = low - idx;
224 tmp << name << "<" << index << ">" << ends;
225 const string inm = tmp.str();
227 switch (type()) {
228 case AND:
229 cur[idx] = new NetLogic(inm, pin_count(), NetLogic::AND);
230 break;
231 case BUF:
232 cur[idx] = new NetLogic(inm, pin_count(), NetLogic::BUF);
233 break;
234 case BUFIF0:
235 cur[idx] = new NetLogic(inm, pin_count(), NetLogic::BUFIF0);
236 break;
237 case BUFIF1:
238 cur[idx] = new NetLogic(inm, pin_count(), NetLogic::BUFIF1);
239 break;
240 case NAND:
241 cur[idx] = new NetLogic(inm, pin_count(), NetLogic::NAND);
242 break;
243 case NOR:
244 cur[idx] = new NetLogic(inm, pin_count(), NetLogic::NOR);
245 break;
246 case NOT:
247 cur[idx] = new NetLogic(inm, pin_count(), NetLogic::NOT);
248 break;
249 case OR:
250 cur[idx] = new NetLogic(inm, pin_count(), NetLogic::OR);
251 break;
252 case XNOR:
253 cur[idx] = new NetLogic(inm, pin_count(), NetLogic::XNOR);
254 break;
255 case XOR:
256 cur[idx] = new NetLogic(inm, pin_count(), NetLogic::XOR);
257 break;
258 default:
259 cerr << get_line() << ": internal error: unhandled "
260 "gate type." << endl;
261 des->errors += 1;
262 return;
265 cur[idx]->set_attributes(attributes);
266 cur[idx]->rise_time(rise_time);
267 cur[idx]->fall_time(fall_time);
268 cur[idx]->decay_time(decay_time);
270 cur[idx]->pin(0).drive0(drive_type(strength0()));
271 cur[idx]->pin(0).drive1(drive_type(strength1()));
273 des->add_node(cur[idx]);
276 /* The gates have all been allocated, this loop runs through
277 the parameters and attaches the ports of the objects. */
279 for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
280 const PExpr*ex = pin(idx);
281 NetNet*sig = ex->elaborate_net(des, path, 0, 0, 0, 0);
282 if (sig == 0)
283 continue;
285 assert(sig);
287 if (sig->pin_count() == 1)
288 for (unsigned gdx = 0 ; gdx < count ; gdx += 1)
289 connect(cur[gdx]->pin(idx), sig->pin(0));
291 else if (sig->pin_count() == count)
292 for (unsigned gdx = 0 ; gdx < count ; gdx += 1)
293 connect(cur[gdx]->pin(idx), sig->pin(gdx));
295 else {
296 cerr << get_line() << ": error: Gate count of " <<
297 count << " does not match net width of " <<
298 sig->pin_count() << " at pin " << idx << "."
299 << endl;
300 des->errors += 1;
303 if (NetTmp*tmp = dynamic_cast<NetTmp*>(sig))
304 delete tmp;
309 * Instantiate a module by recursively elaborating it. Set the path of
310 * the recursive elaboration so that signal names get properly
311 * set. Connect the ports of the instantiated module to the signals of
312 * the parameters. This is done with BUFZ gates so that they look just
313 * like continuous assignment connections.
315 void PGModule::elaborate_mod_(Design*des, Module*rmod, const string&path) const
317 // Missing module instance names have already been rejected.
318 assert(get_name() != "");
320 if (msb_) {
321 cerr << get_line() << ": sorry: Module instantiation arrays "
322 "are not yet supported." << endl;
323 des->errors += 1;
324 return;
327 NetScope*scope = des->find_scope(path);
328 assert(scope);
330 // I know a priori that the elaborate_scope created the scope
331 // already, so just look it up as a child of the current scope.
332 NetScope*my_scope = scope->child(get_name());
333 assert(my_scope);
335 const svector<PExpr*>*pins;
337 // Detect binding by name. If I am binding by name, then make
338 // up a pins array that reflects the positions of the named
339 // ports. If this is simply positional binding in the first
340 // place, then get the binding from the base class.
341 if (pins_) {
342 unsigned nexp = rmod->port_count();
343 svector<PExpr*>*exp = new svector<PExpr*>(nexp);
345 // Scan the bindings, matching them with port names.
346 for (unsigned idx = 0 ; idx < npins_ ; idx += 1) {
348 // Given a binding, look at the module port names
349 // for the position that matches the binding name.
350 unsigned pidx = rmod->find_port(pins_[idx].name);
352 // If the port name doesn't exist, the find_port
353 // method will return the port count. Detect that
354 // as an error.
355 if (pidx == nexp) {
356 cerr << get_line() << ": error: port ``" <<
357 pins_[idx].name << "'' is not a port of "
358 << get_name() << "." << endl;
359 des->errors += 1;
360 continue;
363 // If I already bound something to this port, then
364 // the (*exp) array will already have a pointer
365 // value where I want to place this expression.
366 if ((*exp)[pidx]) {
367 cerr << get_line() << ": error: port ``" <<
368 pins_[idx].name << "'' already bound." <<
369 endl;
370 des->errors += 1;
371 continue;
374 // OK, do the binding by placing the expression in
375 // the right place.
376 (*exp)[pidx] = pins_[idx].parm;
379 pins = exp;
381 } else {
383 if (pin_count() != rmod->port_count()) {
384 cerr << get_line() << ": error: Wrong number "
385 "of parameters. Expecting " << rmod->port_count() <<
386 ", got " << pin_count() << "."
387 << endl;
388 des->errors += 1;
389 return;
392 // No named bindings, just use the positional list I
393 // already have.
394 assert(pin_count() == rmod->port_count());
395 pins = get_pins();
398 // Elaborate this instance of the module. The recursive
399 // elaboration causes the module to generate a netlist with
400 // the ports represented by NetNet objects. I will find them
401 // later.
402 rmod->elaborate(des, my_scope);
404 // Now connect the ports of the newly elaborated designs to
405 // the expressions that are the instantiation parameters. Scan
406 // the pins, elaborate the expressions attached to them, and
407 // bind them to the port of the elaborated module.
409 for (unsigned idx = 0 ; idx < pins->count() ; idx += 1) {
410 // Skip unconnected module ports.
411 if ((*pins)[idx] == 0)
412 continue;
414 // Inside the module, the port is one or more signals,
415 // that were already elaborated. List all those signals,
416 // and I will connect them up later.
417 svector<PEIdent*> mport = rmod->get_port(idx);
418 svector<NetNet*>prts (mport.count());
420 unsigned prts_pin_count = 0;
421 for (unsigned ldx = 0 ; ldx < mport.count() ; ldx += 1) {
422 PEIdent*pport = mport[ldx];
423 prts[ldx] = pport->elaborate_port(des, my_scope);
424 if (prts[ldx] == 0) {
425 cerr << pport->get_line() << ": internal error: "
426 << "Failed to elaborate port expr: "
427 << *pport << endl;
428 des->errors += 1;
429 continue;
431 assert(prts[ldx]);
432 prts_pin_count += prts[ldx]->pin_count();
435 NetNet*sig = (*pins)[idx]->elaborate_net(des, path,
436 prts_pin_count,
437 0, 0, 0);
438 if (sig == 0) {
439 cerr << "internal error: Expression too complicated "
440 "for elaboration." << endl;
441 continue;
444 assert(sig);
446 // Check that the parts have matching pin counts. If
447 // not, they are different widths.
448 if (prts_pin_count != sig->pin_count()) {
449 cerr << get_line() << ": error: Port " << idx << " of "
450 << type_ << " expects " << prts_pin_count <<
451 " pins, got " << sig->pin_count() << " from "
452 << sig->name() << endl;
453 des->errors += 1;
454 continue;
457 // Connect the sig expression that is the context of the
458 // module instance to the ports of the elaborated
459 // module.
461 assert(prts_pin_count == sig->pin_count());
462 for (unsigned ldx = 0 ; ldx < prts.count() ; ldx += 1) {
463 for (unsigned p = 0 ; p < prts[ldx]->pin_count() ; p += 1) {
464 prts_pin_count -= 1;
465 connect(sig->pin(prts_pin_count),
466 prts[ldx]->pin(prts[ldx]->pin_count()-p-1));
470 if (NetTmp*tmp = dynamic_cast<NetTmp*>(sig))
471 delete tmp;
475 void PGModule::elaborate_cudp_(Design*des, PUdp*udp, const string&path) const
477 const string my_name = path+"."+get_name();
478 NetUDP_COMB*net = new NetUDP_COMB(my_name, udp->ports.count());
479 net->set_attributes(udp->attributes);
481 /* Run through the pins, making netlists for the pin
482 expressions and connecting them to the pin in question. All
483 of this is independent of the nature of the UDP. */
484 for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
485 if (pin(idx) == 0)
486 continue;
488 NetNet*sig = pin(idx)->elaborate_net(des, path, 1, 0, 0, 0);
489 if (sig == 0) {
490 cerr << "internal error: Expression too complicated "
491 "for elaboration:" << *pin(idx) << endl;
492 continue;
495 connect(sig->pin(0), net->pin(idx));
497 // Delete excess holding signal.
498 if (NetTmp*tmp = dynamic_cast<NetTmp*>(sig))
499 delete tmp;
502 /* Build up the truth table for the netlist from the input
503 strings. */
504 for (unsigned idx = 0 ; idx < udp->tinput.count() ; idx += 1) {
505 string input = udp->tinput[idx];
507 net->set_table(input, udp->toutput[idx]);
510 net->cleanup_table();
512 // All done. Add the object to the design.
513 des->add_node(net);
517 * From a UDP definition in the source, make a NetUDP
518 * object. Elaborate the pin expressions as netlists, then connect
519 * those networks to the pins.
521 void PGModule::elaborate_sudp_(Design*des, PUdp*udp, const string&path) const
523 const string my_name = path+"."+get_name();
524 NetUDP*net = new NetUDP(my_name, udp->ports.count(), udp->sequential);
525 net->set_attributes(udp->attributes);
527 /* Run through the pins, making netlists for the pin
528 expressions and connecting them to the pin in question. All
529 of this is independent of the nature of the UDP. */
530 for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
531 if (pin(idx) == 0)
532 continue;
534 NetNet*sig = pin(idx)->elaborate_net(des, path, 1, 0, 0, 0);
535 if (sig == 0) {
536 cerr << "internal error: Expression too complicated "
537 "for elaboration:" << *pin(idx) << endl;
538 continue;
541 connect(sig->pin(0), net->pin(idx));
543 // Delete excess holding signal.
544 if (NetTmp*tmp = dynamic_cast<NetTmp*>(sig))
545 delete tmp;
548 /* Build up the truth table for the netlist from the input
549 strings. */
550 for (unsigned idx = 0 ; idx < udp->tinput.count() ; idx += 1) {
551 string input = string("") + udp->tcurrent[idx] + udp->tinput[idx];
552 net->set_table(input, udp->toutput[idx]);
555 net->cleanup_table();
557 switch (udp->initial) {
558 case verinum::V0:
559 net->set_initial('0');
560 break;
561 case verinum::V1:
562 net->set_initial('1');
563 break;
564 case verinum::Vx:
565 case verinum::Vz:
566 net->set_initial('x');
567 break;
570 // All done. Add the object to the design.
571 des->add_node(net);
575 bool PGModule::elaborate_sig(Design*des, NetScope*scope) const
577 // Look for the module type
578 map<string,Module*>::const_iterator mod = modlist->find(type_);
579 if (mod != modlist->end())
580 return elaborate_sig_mod_(des, scope, (*mod).second);
582 return true;
586 void PGModule::elaborate(Design*des, const string&path) const
588 // Look for the module type
589 map<string,Module*>::const_iterator mod = modlist->find(type_);
590 if (mod != modlist->end()) {
591 elaborate_mod_(des, (*mod).second, path);
592 return;
595 // Try a primitive type
596 map<string,PUdp*>::const_iterator udp = udplist->find(type_);
597 if (udp != udplist->end()) {
598 if ((*udp).second->sequential)
599 elaborate_sudp_(des, (*udp).second, path);
600 else
601 elaborate_cudp_(des, (*udp).second, path);
602 return;
605 cerr << get_line() << ": internal error: Unknown module type: " <<
606 type_ << endl;
609 void PGModule::elaborate_scope(Design*des, NetScope*sc) const
611 // Look for the module type
612 map<string,Module*>::const_iterator mod = modlist->find(type_);
613 if (mod != modlist->end()) {
614 elaborate_scope_mod_(des, (*mod).second, sc);
615 return;
618 // Try a primitive type
619 map<string,PUdp*>::const_iterator udp = udplist->find(type_);
620 if (udp != udplist->end())
621 return;
624 cerr << get_line() << ": error: Unknown module type: " << type_ << endl;
625 des->errors += 1;
629 * The concatenation is also OK an an l-value. This method elaborates
630 * it as a structural l-value.
632 NetNet* PEConcat::elaborate_lnet(Design*des, const string&path) const
634 NetScope*scope = des->find_scope(path);
635 assert(scope);
637 svector<NetNet*>nets (parms_.count());
638 unsigned pins = 0;
639 unsigned errors = 0;
641 if (repeat_) {
642 cerr << get_line() << ": sorry: I do not know how to"
643 " elaborate repeat concatenation nets." << endl;
644 return 0;
647 /* Elaborate the operands of the concatenation. */
648 for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
649 nets[idx] = parms_[idx]->elaborate_lnet(des, path);
650 if (nets[idx] == 0)
651 errors += 1;
652 else
653 pins += nets[idx]->pin_count();
656 /* If any of the sub expressions failed to elaborate, then
657 delete all those that did and abort myself. */
658 if (errors) {
659 for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
660 if (nets[idx]) delete nets[idx];
662 des->errors += 1;
663 return 0;
666 /* Make the temporary signal that connects to all the
667 operands, and connect it up. Scan the operands of the
668 concat operator from least significant to most significant,
669 which is opposite from how they are given in the list. */
670 NetNet*osig = new NetNet(scope, des->local_symbol(path),
671 NetNet::IMPLICIT, pins);
672 pins = 0;
673 for (unsigned idx = nets.count() ; idx > 0 ; idx -= 1) {
674 NetNet*cur = nets[idx-1];
675 for (unsigned pin = 0 ; pin < cur->pin_count() ; pin += 1) {
676 connect(osig->pin(pins), cur->pin(pin));
677 pins += 1;
681 osig->local_flag(true);
682 return osig;
685 NetProc* Statement::elaborate(Design*des, const string&path) const
687 cerr << "internal error: elaborate: What kind of statement? " <<
688 typeid(*this).name() << endl;
689 NetProc*cur = new NetProc;
690 return cur;
693 NetProc* PAssign::assign_to_memory_(NetMemory*mem, PExpr*ix,
694 Design*des, const string&path) const
696 NetScope*scope = des->find_scope(path);
697 assert(scope);
698 NetExpr*rv = rval()->elaborate_expr(des, scope);
699 if (rv == 0)
700 return 0;
702 assert(rv);
704 rv->set_width(mem->width());
705 if (ix == 0) {
706 cerr << get_line() << ": internal error: No index in lval "
707 << "of assignment to memory?" << endl;
708 return 0;
711 assert(ix);
712 NetNet*idx = ix->elaborate_net(des, path, 0, 0, 0, 0);
713 assert(idx);
715 if (rv->expr_width() < mem->width())
716 rv = pad_to_width(rv, mem->width());
718 NetAssignMem*am = new NetAssignMem(mem, idx, rv);
719 am->set_line(*this);
720 return am;
724 * Elaborate an l-value as a NetNet (it may already exist) and make up
725 * the part select stuff for where the assignment is going to be made.
727 NetNet* PAssign_::elaborate_lval(Design*des, const string&path,
728 unsigned&msb, unsigned&lsb,
729 NetExpr*&mux) const
731 NetScope*scope = des->find_scope(path);
732 assert(scope);
734 /* Get the l-value, and assume that it is an identifier. */
735 const PEIdent*id = dynamic_cast<const PEIdent*>(lval());
737 /* If the l-value is not a register, then make a structural
738 elaboration. Make a synthetic register that connects to the
739 generated circuit and return that as the l-value. */
740 if (id == 0) {
741 NetNet*ll = lval_->elaborate_net(des, path, 0, 0, 0, 0);
742 if (ll == 0) {
743 cerr << get_line() << ": Assignment l-value too complex."
744 << endl;
745 return 0;
748 lsb = 0;
749 msb = ll->pin_count()-1;
750 mux = 0;
751 return ll;
754 assert(id);
756 /* Get the signal referenced by the identifier, and make sure
757 it is a register. (Wires are not allows in this context. */
758 NetNet*reg = des->find_signal(scope, id->name());
760 if (reg == 0) {
761 cerr << get_line() << ": error: Could not match signal ``" <<
762 id->name() << "'' in ``" << path << "''" << endl;
763 des->errors += 1;
764 return 0;
766 assert(reg);
768 if ((reg->type() != NetNet::REG) && (reg->type() != NetNet::INTEGER)) {
769 cerr << get_line() << ": error: " << *lval() <<
770 " is not a register." << endl;
771 des->errors += 1;
772 return 0;
775 if (id->msb_ && id->lsb_) {
776 /* This handles part selects. In this case, there are
777 two bit select expressions, and both must be
778 constant. Evaluate them and pass the results back to
779 the caller. */
780 verinum*vl = id->lsb_->eval_const(des, path);
781 if (vl == 0) {
782 cerr << id->lsb_->get_line() << ": error: "
783 "Expression must be constant in this context: "
784 << *id->lsb_;
785 des->errors += 1;
786 return 0;
788 verinum*vm = id->msb_->eval_const(des, path);
789 if (vl == 0) {
790 cerr << id->msb_->get_line() << ": error: "
791 "Expression must be constant in this context: "
792 << *id->msb_;
793 des->errors += 1;
794 return 0;
797 msb = vm->as_ulong();
798 lsb = vl->as_ulong();
799 mux = 0;
801 } else if (id->msb_) {
803 /* If there is only a single select expression, it is a
804 bit select. Evaluate the constant value and treat it
805 as a part select with a bit width of 1. If the
806 expression it not constant, then return the
807 expression as a mux. */
808 assert(id->lsb_ == 0);
809 verinum*v = id->msb_->eval_const(des, path);
810 if (v == 0) {
811 NetExpr*m = id->msb_->elaborate_expr(des, scope);
812 assert(m);
813 msb = 0;
814 lsb = 0;
815 mux = m;
817 } else {
819 msb = v->as_ulong();
820 lsb = v->as_ulong();
821 mux = 0;
824 } else {
826 /* No select expressions, so presume a part select the
827 width of the register. */
829 assert(id->msb_ == 0);
830 assert(id->lsb_ == 0);
831 msb = reg->msb();
832 lsb = reg->lsb();
833 mux = 0;
836 return reg;
839 NetProc* PAssign::elaborate(Design*des, const string&path) const
841 NetScope*scope = des->find_scope(path);
842 assert(scope);
844 /* Catch the case where the lvalue is a reference to a memory
845 item. These are handled differently. */
846 do {
847 const PEIdent*id = dynamic_cast<const PEIdent*>(lval());
848 if (id == 0) break;
850 NetNet*net = des->find_signal(scope, id->name());
851 if (net && (net->scope() == scope))
852 break;
854 if (NetMemory*mem = des->find_memory(scope, id->name()))
855 return assign_to_memory_(mem, id->msb_, des, path);
857 } while(0);
860 /* elaborate the lval. This detects any part selects and mux
861 expressions that might exist. */
862 unsigned lsb, msb;
863 NetExpr*mux;
864 NetNet*reg = elaborate_lval(des, path, msb, lsb, mux);
865 if (reg == 0) return 0;
867 /* If there is a delay expression, elaborate it. */
868 unsigned long rise_time, fall_time, decay_time;
869 delay_.eval_delays(des, path, rise_time, fall_time, decay_time);
872 /* Elaborate the r-value expression. */
873 assert(rval());
875 NetExpr*rv;
877 if (verinum*val = rval()->eval_const(des,path)) {
878 rv = new NetEConst(*val);
879 delete val;
881 } else if (rv = rval()->elaborate_expr(des, scope)) {
883 /* OK, go on. */
885 } else {
886 /* Unable to elaborate expression. Retreat. */
887 return 0;
890 assert(rv);
892 /* Try to evaluate the expression, at least as far as possible. */
893 if (NetExpr*tmp = rv->eval_tree()) {
894 delete rv;
895 rv = tmp;
898 NetAssign*cur;
900 /* Rewrite delayed assignments as assignments that are
901 delayed. For example, a = #<d> b; becomes:
903 begin
904 tmp = b;
905 #<d> a = tmp;
908 If the delay is an event delay, then the transform is
909 similar, with the event delay replacing the time delay. It
910 is an event delay if the event_ member has a value.
912 This rewriting of the expression allows me to not bother to
913 actually and literally represent the delayed assign in the
914 netlist. The compound statement is exactly equivalent. */
916 if (rise_time || event_) {
917 string n = des->local_symbol(path);
918 unsigned wid = reg->pin_count();
920 rv->set_width(reg->pin_count());
921 rv = pad_to_width(rv, reg->pin_count());
923 if (! rv->set_width(reg->pin_count())) {
924 cerr << get_line() << ": error: Unable to match "
925 "expression width of " << rv->expr_width() <<
926 " to l-value width of " << wid << "." << endl;
927 //XXXX delete rv;
928 return 0;
931 NetNet*tmp = new NetNet(scope, n, NetNet::REG, wid);
932 tmp->set_line(*this);
934 /* Generate an assignment of the l-value to the temporary... */
935 n = des->local_symbol(path);
936 NetAssign*a1 = new NetAssign(n, des, wid, rv);
937 a1->set_line(*this);
938 des->add_node(a1);
940 for (unsigned idx = 0 ; idx < wid ; idx += 1)
941 connect(a1->pin(idx), tmp->pin(idx));
943 /* Generate an assignment of the temporary to the r-value... */
944 n = des->local_symbol(path);
945 NetESignal*sig = new NetESignal(tmp);
946 NetAssign*a2 = new NetAssign(n, des, wid, sig);
947 a2->set_line(*this);
948 des->add_node(a2);
950 for (unsigned idx = 0 ; idx < wid ; idx += 1)
951 connect(a2->pin(idx), reg->pin(idx));
953 /* Generate the delay statement with the final
954 assignment attached to it. If this is an event delay,
955 elaborate the PEventStatement. Otherwise, create the
956 right NetPDelay object. */
957 NetProc*st;
958 if (event_) {
959 st = event_->elaborate_st(des, path, a2);
960 if (st == 0) {
961 cerr << event_->get_line() << ": error: "
962 "unable to elaborate event expression."
963 << endl;
964 des->errors += 1;
965 return 0;
967 assert(st);
969 } else {
970 NetPDelay*de = new NetPDelay(rise_time, a2);
971 st = de;
974 /* And build up the complex statement. */
975 NetBlock*bl = new NetBlock(NetBlock::SEQU);
976 bl->append(a1);
977 bl->append(st);
979 return bl;
982 if (mux == 0) {
983 /* This is a simple assign to a register. There may be a
984 part select, so take care that the width is of the
985 part, and using the lsb, make sure the correct range
986 of bits is assigned. */
987 unsigned wid = (msb >= lsb)? (msb-lsb+1) : (lsb-msb+1);
988 assert(wid <= reg->pin_count());
990 rv->set_width(wid);
991 rv = pad_to_width(rv, wid);
992 assert(rv->expr_width() >= wid);
994 cur = new NetAssign(des->local_symbol(path), des, wid, rv);
995 unsigned off = reg->sb_to_idx(lsb);
996 assert((off+wid) <= reg->pin_count());
997 for (unsigned idx = 0 ; idx < wid ; idx += 1)
998 connect(cur->pin(idx), reg->pin(idx+off));
1000 } else {
1002 assert(msb == lsb);
1003 cur = new NetAssign(des->local_symbol(path), des,
1004 reg->pin_count(), mux, rv);
1005 for (unsigned idx = 0 ; idx < reg->pin_count() ; idx += 1)
1006 connect(cur->pin(idx), reg->pin(idx));
1010 cur->set_line(*this);
1011 des->add_node(cur);
1013 return cur;
1017 * I do not really know how to elaborate mem[x] <= expr, so this
1018 * method pretends it is a blocking assign and elaborates
1019 * that. However, I report an error so that the design isn't actually
1020 * executed by anyone.
1022 NetProc* PAssignNB::assign_to_memory_(NetMemory*mem, PExpr*ix,
1023 Design*des, const string&path) const
1025 NetScope*scope = des->find_scope(path);
1026 assert(scope);
1028 /* Elaborate the r-value expression, ... */
1029 NetExpr*rv = rval()->elaborate_expr(des, scope);
1030 if (rv == 0)
1031 return 0;
1033 assert(rv);
1034 rv->set_width(mem->width());
1036 /* Elaborate the expression to calculate the index, ... */
1037 NetNet*idx = ix->elaborate_net(des, path, 0, 0, 0, 0);
1038 assert(idx);
1040 /* And connect them together in an assignment NetProc. */
1041 NetAssignMemNB*am = new NetAssignMemNB(mem, idx, rv);
1042 am->set_line(*this);
1044 return am;
1048 * The l-value of a procedural assignment is a very much constrained
1049 * expression. To wit, only identifiers, bit selects and part selects
1050 * are allowed. I therefore can elaborate the l-value by hand, without
1051 * the help of recursive elaboration.
1053 * (For now, this does not yet support concatenation in the l-value.)
1055 NetProc* PAssignNB::elaborate(Design*des, const string&path) const
1057 NetScope*scope = des->find_scope(path);
1058 assert(scope);
1060 /* Catch the case where the lvalue is a reference to a memory
1061 item. These are handled differently. */
1062 do {
1063 const PEIdent*id = dynamic_cast<const PEIdent*>(lval());
1064 if (id == 0) break;
1066 if (NetMemory*mem = des->find_memory(scope, id->name()))
1067 return assign_to_memory_(mem, id->msb_, des, path);
1069 } while(0);
1072 unsigned lsb, msb;
1073 NetExpr*mux;
1074 NetNet*reg = elaborate_lval(des, path, msb, lsb, mux);
1075 if (reg == 0) return 0;
1077 assert(rval());
1079 /* Elaborate the r-value expression. This generates a
1080 procedural expression that I attach to the assignment. */
1081 NetExpr*rv = rval()->elaborate_expr(des, scope);
1082 if (rv == 0)
1083 return 0;
1085 assert(rv);
1087 NetAssignNB*cur;
1088 if (mux == 0) {
1089 unsigned wid = msb - lsb + 1;
1091 rv->set_width(wid);
1092 rv = pad_to_width(rv, wid);
1093 assert(wid <= rv->expr_width());
1095 cur = new NetAssignNB(des->local_symbol(path), des, wid, rv);
1096 for (unsigned idx = 0 ; idx < wid ; idx += 1)
1097 connect(cur->pin(idx), reg->pin(reg->sb_to_idx(idx+lsb)));
1099 } else {
1101 /* In this case, there is a mux expression (detected by
1102 the elaborate_lval method) that selects where the bit
1103 value goes. Create a NetAssignNB object that carries
1104 that mux expression, and connect it to the entire
1105 width of the lval. */
1106 cur = new NetAssignNB(des->local_symbol(path), des,
1107 reg->pin_count(), mux, rv);
1108 for (unsigned idx = 0 ; idx < reg->pin_count() ; idx += 1)
1109 connect(cur->pin(idx), reg->pin(idx));
1113 unsigned long rise_time, fall_time, decay_time;
1114 delay_.eval_delays(des, path, rise_time, fall_time, decay_time);
1115 cur->rise_time(rise_time);
1116 cur->fall_time(fall_time);
1117 cur->decay_time(decay_time);
1120 /* All done with this node. mark its line number and check it in. */
1121 cur->set_line(*this);
1122 des->add_node(cur);
1123 return cur;
1128 * This is the elaboration method for a begin-end block. Try to
1129 * elaborate the entire block, even if it fails somewhere. This way I
1130 * get all the error messages out of it. Then, if I detected a failure
1131 * then pass the failure up.
1133 NetProc* PBlock::elaborate(Design*des, const string&path) const
1135 NetScope*scope = des->find_scope(path);
1136 assert(scope);
1138 NetBlock::Type type = (bl_type_==PBlock::BL_PAR)
1139 ? NetBlock::PARA
1140 : NetBlock::SEQU;
1141 NetBlock*cur = new NetBlock(type);
1142 bool fail_flag = false;
1144 string npath;
1145 NetScope*nscope;
1146 if (name_.length()) {
1147 nscope = scope->child(name_);
1148 if (nscope == 0) {
1149 cerr << get_line() << ": internal error: "
1150 "unable to find block scope " << scope->name()
1151 << "<" << name_ << ">" << endl;
1152 des->errors += 1;
1153 delete cur;
1154 return 0;
1157 assert(nscope);
1158 npath = nscope->name();
1160 } else {
1161 nscope = scope;
1162 npath = path;
1165 // Handle the special case that the block contains only one
1166 // statement. There is no need to keep the block node.
1167 if (list_.count() == 1) {
1168 NetProc*tmp = list_[0]->elaborate(des, npath);
1169 return tmp;
1172 for (unsigned idx = 0 ; idx < list_.count() ; idx += 1) {
1173 NetProc*tmp = list_[idx]->elaborate(des, npath);
1174 if (tmp == 0) {
1175 fail_flag = true;
1176 continue;
1178 cur->append(tmp);
1181 if (fail_flag) {
1182 delete cur;
1183 cur = 0;
1186 return cur;
1190 * Elaborate a case statement.
1192 NetProc* PCase::elaborate(Design*des, const string&path) const
1194 NetScope*scope = des->find_scope(path);
1195 assert(scope);
1197 NetExpr*expr = expr_->elaborate_expr(des, scope);
1198 if (expr == 0) {
1199 cerr << get_line() << ": error: Unable to elaborate this case"
1200 " expression." << endl;
1201 return 0;
1204 unsigned icount = 0;
1205 for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) {
1206 PCase::Item*cur = (*items_)[idx];
1208 if (cur->expr.count() == 0)
1209 icount += 1;
1210 else
1211 icount += cur->expr.count();
1214 NetCase*res = new NetCase(type_, expr, icount);
1215 res->set_line(*this);
1217 unsigned inum = 0;
1218 for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) {
1220 assert(inum < icount);
1221 PCase::Item*cur = (*items_)[idx];
1223 if (cur->expr.count() == 0) {
1224 /* If there are no expressions, then this is the
1225 default case. */
1226 NetProc*st = 0;
1227 if (cur->stat)
1228 st = cur->stat->elaborate(des, path);
1230 res->set_case(inum, 0, st);
1231 inum += 1;
1233 } else for (unsigned e = 0; e < cur->expr.count(); e += 1) {
1235 /* If there are one or more expressions, then
1236 iterate over the guard expressions, elaborating
1237 a separate case for each. (Yes, the statement
1238 will be elaborated again for each.) */
1239 NetExpr*gu = 0;
1240 NetProc*st = 0;
1241 assert(cur->expr[e]);
1242 gu = cur->expr[e]->elaborate_expr(des, scope);
1244 if (cur->stat)
1245 st = cur->stat->elaborate(des, path);
1247 res->set_case(inum, gu, st);
1248 inum += 1;
1252 return res;
1255 NetProc* PCondit::elaborate(Design*des, const string&path) const
1257 NetScope*scope = des->find_scope(path);
1258 assert(scope);
1260 // Elaborate and try to evaluate the conditional expression.
1261 NetExpr*expr = expr_->elaborate_expr(des, scope);
1262 if (expr == 0) {
1263 cerr << get_line() << ": error: Unable to elaborate"
1264 " condition expression." << endl;
1265 des->errors += 1;
1266 return 0;
1268 NetExpr*tmp = expr->eval_tree();
1269 if (tmp) {
1270 delete expr;
1271 expr = tmp;
1274 // If the condition of the conditional statement is constant,
1275 // then look at the value and elaborate either the if statement
1276 // or the else statement. I don't need both. If there is no
1277 // else_ statement, the use an empty block as a noop.
1278 if (NetEConst*ce = dynamic_cast<NetEConst*>(expr)) {
1279 verinum val = ce->value();
1280 delete expr;
1281 if (val[0] == verinum::V1)
1282 return if_->elaborate(des, path);
1283 else if (else_)
1284 return else_->elaborate(des, path);
1285 else
1286 return new NetBlock(NetBlock::SEQU);
1289 // If the condition expression is more then 1 bits, then
1290 // generate a comparison operator to get the result down to
1291 // one bit. Turn <e> into <e> != 0;
1293 if (expr->expr_width() < 1) {
1294 cerr << get_line() << ": internal error: "
1295 "incomprehensible expression width (0)." << endl;
1296 return 0;
1299 if (! expr->set_width(1)) {
1300 assert(expr->expr_width() > 1);
1301 verinum zero (verinum::V0, expr->expr_width());
1302 NetEConst*ezero = new NetEConst(zero);
1303 ezero->set_width(expr->expr_width());
1304 NetEBComp*cmp = new NetEBComp('n', expr, ezero);
1305 expr = cmp;
1308 // Well, I actually need to generate code to handle the
1309 // conditional, so elaborate.
1310 NetProc*i = if_? if_->elaborate(des, path) : 0;
1311 NetProc*e = else_? else_->elaborate(des, path) : 0;
1313 NetCondit*res = new NetCondit(expr, i, e);
1314 res->set_line(*this);
1315 return res;
1318 NetProc* PCallTask::elaborate(Design*des, const string&path) const
1320 if (name_[0] == '$')
1321 return elaborate_sys(des, path);
1322 else
1323 return elaborate_usr(des, path);
1327 * A call to a system task involves elaborating all the parameters,
1328 * then passing the list to the NetSTask object.
1329 *XXXX
1330 * There is a single special in the call to a system task. Normally,
1331 * an expression cannot take an unindexed memory. However, it is
1332 * possible to take a system task parameter a memory if the expression
1333 * is trivial.
1335 NetProc* PCallTask::elaborate_sys(Design*des, const string&path) const
1337 NetScope*scope = des->find_scope(path);
1338 assert(scope);
1340 svector<NetExpr*>eparms (nparms());
1342 for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
1343 PExpr*ex = parm(idx);
1345 eparms[idx] = ex? ex->elaborate_expr(des, scope) : 0;
1348 NetSTask*cur = new NetSTask(name(), eparms);
1349 return cur;
1353 * A call to a user defined task is different from a call to a system
1354 * task because a user task in a netlist has no parameters: the
1355 * assignments are done by the calling thread. For example:
1357 * task foo;
1358 * input a;
1359 * output b;
1360 * [...]
1361 * endtask;
1363 * [...] foo(x, y);
1365 * is really:
1367 * task foo;
1368 * reg a;
1369 * reg b;
1370 * [...]
1371 * endtask;
1373 * [...]
1374 * begin
1375 * a = x;
1376 * foo;
1377 * y = b;
1378 * end
1380 NetProc* PCallTask::elaborate_usr(Design*des, const string&path) const
1382 NetScope*scope = des->find_scope(path);
1383 assert(scope);
1385 NetTaskDef*def = des->find_task(path, name_);
1386 if (def == 0) {
1387 cerr << get_line() << ": error: Enable of unknown task ``" <<
1388 path << "." << name_ << "''." << endl;
1389 des->errors += 1;
1390 return 0;
1393 if (nparms() != def->port_count()) {
1394 cerr << get_line() << ": error: Port count mismatch in call to ``"
1395 << name_ << "''." << endl;
1396 des->errors += 1;
1397 return 0;
1400 NetUTask*cur;
1402 /* Handle tasks with no parameters specially. There is no need
1403 to make a sequential block to hold the generated code. */
1404 if (nparms() == 0) {
1405 cur = new NetUTask(def);
1406 return cur;
1409 NetBlock*block = new NetBlock(NetBlock::SEQU);
1412 /* Detect the case where the definition of the task is known
1413 empty. In this case, we need not bother with calls to the
1414 task, all the assignments, etc. Just return a no-op. */
1416 if (const NetBlock*tp = dynamic_cast<const NetBlock*>(def->proc())) {
1417 if (tp->proc_first() == 0)
1418 return block;
1421 /* Generate assignment statement statements for the input and
1422 INOUT ports of the task. These are managed by writing
1423 assignments with the task port the l-value and the passed
1424 expression the r-value. We know by definition that the port
1425 is a reg type, so this elaboration is pretty obvious. */
1427 for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
1429 NetNet*port = def->port(idx);
1430 assert(port->port_type() != NetNet::NOT_A_PORT);
1431 if (port->port_type() == NetNet::POUTPUT)
1432 continue;
1434 NetExpr*rv = parms_[idx]->elaborate_expr(des, scope);
1435 NetAssign*pr = new NetAssign("@", des, port->pin_count(), rv);
1436 for (unsigned pi = 0 ; pi < port->pin_count() ; pi += 1)
1437 connect(port->pin(pi), pr->pin(pi));
1438 des->add_node(pr);
1439 block->append(pr);
1442 /* Generate the task call proper... */
1443 cur = new NetUTask(def);
1444 block->append(cur);
1447 /* Generate assignment statements for the output and INOUT
1448 ports of the task. The l-value in this case is the
1449 expression passed as a parameter, and the r-value is the
1450 port to be copied out.
1452 We know by definition that the r-value of this copy-out is
1453 the port, which is a reg. The l-value, however, may be any
1454 expression that can be a target to a procedural
1455 assignment, including a memory word. */
1457 for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
1459 NetNet*port = def->port(idx);
1461 /* Skip input ports. */
1462 assert(port->port_type() != NetNet::NOT_A_PORT);
1463 if (port->port_type() == NetNet::PINPUT)
1464 continue;
1466 const PEIdent*id;
1467 NetNet*val = 0;
1468 NetMemory*mem = 0;
1469 if ( (id = dynamic_cast<const PEIdent*>(parms_[idx])) )
1470 des->find_symbol(scope, id->name(), val, mem);
1472 /* Catch the case of memory words passed as an out
1473 parameter. Generate an assignment to memory instead
1474 of a normal assignment. */
1475 if (mem != 0) {
1476 assert(id->msb_);
1477 NetNet*ix = id->msb_->elaborate_net(des, path,
1478 0, 0, 0, 0);
1479 assert(ix);
1481 NetExpr*rv = new NetESignal(port);
1482 if (rv->expr_width() < mem->width())
1483 rv = pad_to_width(rv, mem->width());
1485 NetAssignMem*am = new NetAssignMem(mem, ix, rv);
1486 am->set_line(*this);
1487 block->append(am);
1488 continue;
1492 /* Elaborate the parameter expression as a net so that
1493 it can be used as an l-value. Then check that the
1494 parameter width match up.
1496 XXXX FIXME XXXX This goes nuts if the parameter is a
1497 memory word. that must be handled by generating
1498 NetAssignMem objects instead. */
1499 if (val == 0)
1500 val = parms_[idx]->elaborate_net(des, path,
1501 0, 0, 0, 0);
1502 assert(val);
1505 /* Make an expression out of the actual task port. If
1506 the port is smaller then the expression to receive
1507 the result, then expand the port by padding with
1508 zeros. */
1509 NetESignal*sig = new NetESignal(port);
1510 NetExpr*pexp = sig;
1511 if (sig->expr_width() < val->pin_count()) {
1512 unsigned cwid = val->pin_count()-sig->expr_width();
1513 verinum pad (verinum::V0, cwid);
1514 NetEConst*cp = new NetEConst(pad);
1515 cp->set_width(cwid);
1517 NetEConcat*con = new NetEConcat(2);
1518 con->set(0, cp);
1519 con->set(1, sig);
1520 con->set_width(val->pin_count());
1521 pexp = con;
1525 /* Generate the assignment statement. */
1526 NetAssign*ass = new NetAssign("@", des, val->pin_count(), pexp);
1527 for (unsigned pi = 0 ; pi < val->pin_count() ; pi += 1)
1528 connect(val->pin(pi), ass->pin(pi));
1530 des->add_node(ass);
1531 block->append(ass);
1534 return block;
1537 NetCAssign* PCAssign::elaborate(Design*des, const string&path) const
1539 NetScope*scope = des->find_scope(path);
1540 assert(scope);
1542 NetNet*lval = lval_->elaborate_net(des, path, 0, 0, 0, 0);
1543 if (lval == 0)
1544 return 0;
1546 NetNet*rval = expr_->elaborate_net(des, path, lval->pin_count(),
1547 0, 0, 0);
1548 if (rval == 0)
1549 return 0;
1551 if (rval->pin_count() < lval->pin_count())
1552 rval = pad_to_width(des, path, rval, lval->pin_count());
1554 NetCAssign* dev = new NetCAssign(des->local_symbol(path), lval);
1555 des->add_node(dev);
1557 for (unsigned idx = 0 ; idx < dev->pin_count() ; idx += 1)
1558 connect(dev->pin(idx), rval->pin(idx));
1560 return dev;
1563 NetDeassign* PDeassign::elaborate(Design*des, const string&path) const
1565 NetScope*scope = des->find_scope(path);
1566 assert(scope);
1568 NetNet*lval = lval_->elaborate_net(des, path, 0, 0, 0, 0);
1569 if (lval == 0)
1570 return 0;
1572 NetDeassign*dev = new NetDeassign(lval);
1573 dev->set_line( *this );
1574 return dev;
1577 NetProc* PDelayStatement::elaborate(Design*des, const string&path) const
1579 verinum*num = delay_->eval_const(des, path);
1580 if (num == 0) {
1581 cerr << get_line() << ": sorry: delay expression "
1582 "must be constant." << endl;
1583 return 0;
1585 assert(num);
1587 unsigned long val = num->as_ulong();
1588 if (statement_)
1589 return new NetPDelay(val, statement_->elaborate(des, path));
1590 else
1591 return new NetPDelay(val, 0);
1595 * An event statement is an event delay of some sort, attached to a
1596 * statement. Some Verilog examples are:
1598 * @(posedge CLK) $display("clock rise");
1599 * @event_1 $display("event triggered.");
1600 * @(data or negedge clk) $display("data or clock fall.");
1602 * The elaborated netlist uses the NetEvent, NetEvWait and NetEvProbe
1603 * classes. The NetEvWait class represents the part of the netlist
1604 * that is executed by behavioral code. The process starts waiting on
1605 * the NetEvent when it executes the NetEvWait step. Net NetEvProbe
1606 * and NetEvTrig are structural and behavioral equivilents that
1607 * trigger the event, and awakens any processes blocking in the
1608 * associated wait.
1610 * The basic data structure is:
1612 * NetEvWait ---/---> NetEvent <----\---- NetEvProbe
1613 * ... | | ...
1614 * NetEvWait ---+ +---- NetEvProbe
1615 * | ...
1616 * +---- NetEvTrig
1618 * That is, many NetEvWait statements may wait on a single NetEvent
1619 * object, and Many NetEvProbe objects may trigger the NetEvent
1620 * object. The many NetEvWait objects pointing to the NetEvent object
1621 * reflects the possibility of different places in the code blocking
1622 * on the same named event, like so:
1624 * event foo;
1625 * [...]
1626 * always begin @foo <statement1>; @foo <statement2> end
1628 * This tends to not happen with signal edges. The multiple probes
1629 * pointing to the same event reflect the possibility of many
1630 * expressions in the same blocking statement, like so:
1632 * wire reset, clk;
1633 * [...]
1634 * always @(reset or posedge clk) <stmt>;
1636 * Conjunctions like this cause a NetEvent object be created to
1637 * represent the overall conjuction, and NetEvProbe objects for each
1638 * event expression.
1640 * If the NetEvent object represents a named event from the source,
1641 * then there are NetEvTrig objects that represent the trigger
1642 * statements instead of the NetEvProbe objects representing signals.
1643 * For example:
1645 * event foo;
1646 * always @foo <stmt>;
1647 * initial begin
1648 * [...]
1649 * -> foo;
1650 * [...]
1651 * -> foo;
1652 * [...]
1653 * end
1655 * Each trigger statement in the source generates a separate NetEvTrig
1656 * object in the netlist. Those trigger objects are elaborated
1657 * elsewhere.
1659 * Additional complications arise when named events show up in
1660 * conjunctions. An example of such a case is:
1662 * event foo;
1663 * wire bar;
1664 * always @(foo or posedge bar) <stmt>;
1666 * Since there is by definition a NetEvent object for the foo object,
1667 * this is handled by allowing the NetEvWait object to point to
1668 * multiple NetEvent objects. All the NetEvProbe based objects are
1669 * collected and pointed as the synthetic NetEvent object, and all the
1670 * named events are added into the list of NetEvent object that the
1671 * NetEvWait object can refer to.
1674 NetProc* PEventStatement::elaborate_st(Design*des, const string&path,
1675 NetProc*enet) const
1677 NetScope*scope = des->find_scope(path);
1678 assert(scope);
1681 /* The Verilog wait (<expr>) <statement> statement is a level
1682 sensitive wait. Handle this special case by elaborating
1683 something like this:
1685 begin
1686 if (! <expr>) @(posedge <expr>)
1687 <statement>
1690 This is equivilent, and uses the existing capapilities of
1691 the netlist format. The resulting netlist should look like
1692 this:
1694 NetBlock ---+---> NetCondit --+--> <expr>
1696 | +--> NetEvWait--> NetEvent
1698 +---> <statement>
1700 This is quite a mouthful. Should I not move wait handling
1701 to specialized objects? */
1704 if ((expr_.count() == 1) && (expr_[0]->type() == PEEvent::POSITIVE)) {
1706 NetBlock*bl = new NetBlock(NetBlock::SEQU);
1708 NetNet*ex = expr_[0]->expr()->elaborate_net(des, path,
1709 1, 0, 0, 0);
1710 if (ex == 0) {
1711 expr_[0]->dump(cerr);
1712 cerr << endl;
1713 des->errors += 1;
1714 return 0;
1717 NetEvent*ev = new NetEvent(scope->local_symbol());
1718 scope->add_event(ev);
1720 NetEvWait*we = new NetEvWait(0);
1721 we->add_event(ev);
1723 NetEvProbe*po = new NetEvProbe(path+"."+scope->local_symbol(),
1724 ev, NetEvProbe::POSEDGE, 1);
1725 connect(po->pin(0), ex->pin(0));
1727 des->add_node(po);
1729 NetESignal*ce = new NetESignal(ex);
1730 NetCondit*co = new NetCondit(new NetEUnary('!', ce), we, 0);
1731 bl->append(co);
1732 bl->append(enet);
1734 ev->set_line(*this);
1735 bl->set_line(*this);
1736 we->set_line(*this);
1737 co->set_line(*this);
1739 return bl;
1743 /* Handle the special case of an event name as an identifier
1744 in an expression. Make a named event reference. */
1746 if (expr_.count() == 1) {
1747 assert(expr_[0]->expr());
1748 PEIdent*id = dynamic_cast<PEIdent*>(expr_[0]->expr());
1749 NetEvent*ev;
1750 if (id && (ev = scope->find_event(id->name()))) {
1751 NetEvWait*pr = new NetEvWait(enet);
1752 pr->add_event(ev);
1753 pr->set_line(*this);
1754 return pr;
1758 /* Create A single NetEvent and NetEvWait. Then, create a
1759 NetEvProbe for each conjunctive event in the event
1760 list. The NetEvProbe object al refer back to the NetEvent
1761 object. */
1763 NetEvent*ev = new NetEvent(scope->local_symbol());
1764 ev->set_line(*this);
1765 unsigned expr_count = 0;
1767 NetEvWait*wa = new NetEvWait(enet);
1768 wa->set_line(*this);
1770 for (unsigned idx = 0 ; idx < expr_.count() ; idx += 1) {
1772 assert(expr_[idx]->expr());
1774 /* If the expression is an identifier that matches a
1775 named event, then handle this case all at once at
1776 skip the rest of the expression handling. */
1778 if (PEIdent*id = dynamic_cast<PEIdent*>(expr_[idx]->expr())) {
1779 NetEvent*tmp = scope->find_event(id->name());
1780 if (tmp) {
1781 wa->add_event(tmp);
1782 continue;
1786 /* So now we have a normal event expression. Elaborate
1787 the sub-expression as a net and decide how to handle
1788 the edge. */
1790 NetNet*expr = expr_[idx]->expr()->elaborate_net(des, path,
1791 0, 0, 0, 0);
1792 if (expr == 0) {
1793 expr_[idx]->dump(cerr);
1794 cerr << endl;
1795 des->errors += 1;
1796 continue;
1798 assert(expr);
1800 unsigned pins = (expr_[idx]->type() == PEEvent::ANYEDGE)
1801 ? expr->pin_count() : 1;
1803 NetEvProbe*pr;
1804 switch (expr_[idx]->type()) {
1805 case PEEvent::POSEDGE:
1806 pr = new NetEvProbe(des->local_symbol(path), ev,
1807 NetEvProbe::POSEDGE, pins);
1808 break;
1810 case PEEvent::NEGEDGE:
1811 pr = new NetEvProbe(des->local_symbol(path), ev,
1812 NetEvProbe::NEGEDGE, pins);
1813 break;
1815 case PEEvent::ANYEDGE:
1816 pr = new NetEvProbe(des->local_symbol(path), ev,
1817 NetEvProbe::ANYEDGE, pins);
1818 break;
1820 default:
1821 assert(0);
1824 for (unsigned p = 0 ; p < pr->pin_count() ; p += 1)
1825 connect(pr->pin(p), expr->pin(p));
1827 des->add_node(pr);
1828 expr_count += 1;
1831 /* If there was at least one conjunction that was an
1832 expression (and not a named event) then add this
1833 event. Otherwise, we didn't use it so delete it. */
1834 if (expr_count > 0) {
1835 if (NetEvent*match = ev->find_similar_event()) {
1836 cerr << "XXXX Found similar event for " <<
1837 ev->name() << endl;
1838 delete ev;
1839 wa->add_event(match);
1841 } else {
1843 scope->add_event(ev);
1844 wa->add_event(ev);
1846 } else {
1847 delete ev;
1850 return wa;
1853 NetProc* PEventStatement::elaborate(Design*des, const string&path) const
1855 NetProc*enet = 0;
1856 if (statement_) {
1857 enet = statement_->elaborate(des, path);
1858 if (enet == 0)
1859 return 0;
1862 return elaborate_st(des, path, enet);
1866 * Forever statements are represented directly in the netlist. It is
1867 * theoretically possible to use a while structure with a constant
1868 * expression to represent the loop, but why complicate the code
1869 * generators so?
1871 NetProc* PForever::elaborate(Design*des, const string&path) const
1873 NetProc*stat = statement_->elaborate(des, path);
1874 if (stat == 0) return 0;
1876 NetForever*proc = new NetForever(stat);
1877 return proc;
1880 NetProc* PForce::elaborate(Design*des, const string&path) const
1882 NetScope*scope = des->find_scope(path);
1883 assert(scope);
1885 NetNet*lval = lval_->elaborate_net(des, path, 0, 0, 0, 0);
1886 if (lval == 0)
1887 return 0;
1889 NetNet*rval = expr_->elaborate_net(des, path, lval->pin_count(),
1890 0, 0, 0);
1891 if (rval == 0)
1892 return 0;
1894 if (rval->pin_count() < lval->pin_count())
1895 rval = pad_to_width(des, path, rval, lval->pin_count());
1897 NetForce* dev = new NetForce(des->local_symbol(path), lval);
1898 des->add_node(dev);
1900 for (unsigned idx = 0 ; idx < dev->pin_count() ; idx += 1)
1901 connect(dev->pin(idx), rval->pin(idx));
1903 return dev;
1907 * elaborate the for loop as the equivalent while loop. This eases the
1908 * task for the target code generator. The structure is:
1910 * begin : top
1911 * name1_ = expr1_;
1912 * while (cond_) begin : body
1913 * statement_;
1914 * name2_ = expr2_;
1915 * end
1916 * end
1918 NetProc* PForStatement::elaborate(Design*des, const string&path) const
1920 NetScope*scope = des->find_scope(path);
1921 assert(scope);
1923 const PEIdent*id1 = dynamic_cast<const PEIdent*>(name1_);
1924 assert(id1);
1925 const PEIdent*id2 = dynamic_cast<const PEIdent*>(name2_);
1926 assert(id2);
1928 NetBlock*top = new NetBlock(NetBlock::SEQU);
1930 /* make the expression, and later the initial assignment to
1931 the condition variable. The statement in the for loop is
1932 very specifically an assignment. */
1933 NetNet*sig = des->find_signal(scope, id1->name());
1934 if (sig == 0) {
1935 cerr << id1->get_line() << ": register ``" << id1->name()
1936 << "'' unknown in this context." << endl;
1937 des->errors += 1;
1938 return 0;
1940 assert(sig);
1941 NetAssign*init = new NetAssign("@for-assign", des, sig->pin_count(),
1942 expr1_->elaborate_expr(des, scope));
1943 for (unsigned idx = 0 ; idx < init->pin_count() ; idx += 1)
1944 connect(init->pin(idx), sig->pin(idx));
1946 top->append(init);
1948 NetBlock*body = new NetBlock(NetBlock::SEQU);
1950 /* Elaborate the statement that is contained in the for
1951 loop. If there is an error, this will return 0 and I should
1952 skip the append. No need to worry, the error has been
1953 reported so it's OK that the netlist is bogus. */
1954 NetProc*tmp = statement_->elaborate(des, path);
1955 if (tmp)
1956 body->append(tmp);
1959 /* Elaborate the increment assignment statement at the end of
1960 the for loop. This is also a very specific assignment
1961 statement. Put this into the "body" block. */
1962 sig = des->find_signal(scope, id2->name());
1963 assert(sig);
1964 NetAssign*step = new NetAssign("@for-assign", des, sig->pin_count(),
1965 expr2_->elaborate_expr(des, scope));
1966 for (unsigned idx = 0 ; idx < step->pin_count() ; idx += 1)
1967 connect(step->pin(idx), sig->pin(idx));
1969 body->append(step);
1972 /* Elaborate the condition expression. Try to evaluate it too,
1973 in case it is a constant. This is an interesting case
1974 worthy of a warning. */
1975 NetExpr*ce = cond_->elaborate_expr(des, scope);
1976 if (ce == 0) {
1977 delete top;
1978 return 0;
1981 if (NetExpr*tmp = ce->eval_tree()) {
1982 if (dynamic_cast<NetEConst*>(tmp))
1983 cerr << get_line() << ": warning: condition expression "
1984 "is constant." << endl;
1986 ce = tmp;
1990 /* All done, build up the loop. */
1992 NetWhile*loop = new NetWhile(ce, body);
1993 top->append(loop);
1994 return top;
1998 * (See the PTask::elaborate methods for basic common stuff.)
2000 * The return value of a function is represented as a reg variable
2001 * within the scope of the function that has the name of the
2002 * function. So for example with the function:
2004 * function [7:0] incr;
2005 * input [7:0] in1;
2006 * incr = in1 + 1;
2007 * endfunction
2009 * The scope of the function is <parent>.incr and there is a reg
2010 * variable <parent>.incr.incr. The elaborate_1 method is called with
2011 * the scope of the function, so the return reg is easily located.
2013 * The function parameters are all inputs, except for the synthetic
2014 * output parameter that is the return value. The return value goes
2015 * into port 0, and the parameters are all the remaining ports.
2017 void PFunction::elaborate_1(Design*des, NetScope*scope) const
2019 string fname = scope->basename();
2021 svector<NetNet*>ports (ports_? ports_->count()+1 : 1);
2023 /* Get the reg for the return value. I know the name of the
2024 reg variable, and I know that it is in this scope, so look
2025 it up directly. */
2026 ports[0] = scope->find_signal(scope->basename());
2027 if (ports[0] == 0) {
2028 cerr << get_line() << ": internal error: function scope "
2029 << scope->name() << " is missing return reg "
2030 << fname << "." << endl;
2031 scope->dump(cerr);
2032 des->errors += 1;
2033 return;
2036 for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
2038 /* Parse the port name into the task name and the reg
2039 name. We know by design that the port name is given
2040 as two components: <func>.<port>. */
2042 string pname = (*ports_)[idx]->name();
2043 string ppath = parse_first_name(pname);
2045 if (ppath != scope->basename()) {
2046 cerr << get_line() << ": internal error: function "
2047 << "port " << (*ports_)[idx]->name()
2048 << " has wrong name for function "
2049 << scope->name() << "." << endl;
2050 des->errors += 1;
2053 NetNet*tmp = scope->find_signal(pname);
2054 if (tmp == 0) {
2055 cerr << get_line() << ": internal error: function "
2056 << scope->name() << " is missing port "
2057 << pname << "." << endl;
2058 scope->dump(cerr);
2059 des->errors += 1;
2062 ports[idx+1] = tmp;
2065 NetFuncDef*def = new NetFuncDef(scope, ports);
2066 des->add_function(scope->name(), def);
2069 void PFunction::elaborate_2(Design*des, NetScope*scope) const
2071 NetFuncDef*def = des->find_function(scope->name());
2072 assert(def);
2074 NetProc*st = statement_->elaborate(des, scope->name());
2075 if (st == 0) {
2076 cerr << statement_->get_line() << ": error: Unable to elaborate "
2077 "statement in function " << def->name() << "." << endl;
2078 des->errors += 1;
2079 return;
2082 def->set_proc(st);
2085 NetProc* PRelease::elaborate(Design*des, const string&path) const
2087 NetScope*scope = des->find_scope(path);
2088 assert(scope);
2090 NetNet*lval = lval_->elaborate_net(des, path, 0, 0, 0, 0);
2091 if (lval == 0)
2092 return 0;
2094 NetRelease*dev = new NetRelease(lval);
2095 dev->set_line( *this );
2096 return dev;
2099 NetProc* PRepeat::elaborate(Design*des, const string&path) const
2101 NetScope*scope = des->find_scope(path);
2102 assert(scope);
2104 NetExpr*expr = expr_->elaborate_expr(des, scope);
2105 if (expr == 0) {
2106 cerr << get_line() << ": Unable to elaborate"
2107 " repeat expression." << endl;
2108 des->errors += 1;
2109 return 0;
2111 NetExpr*tmp = expr->eval_tree();
2112 if (tmp) {
2113 delete expr;
2114 expr = tmp;
2117 NetProc*stat = statement_->elaborate(des, path);
2118 if (stat == 0) return 0;
2120 // If the expression is a constant, handle certain special
2121 // iteration counts.
2122 if (NetEConst*ce = dynamic_cast<NetEConst*>(expr)) {
2123 verinum val = ce->value();
2124 switch (val.as_ulong()) {
2125 case 0:
2126 delete expr;
2127 delete stat;
2128 return new NetBlock(NetBlock::SEQU);
2129 case 1:
2130 delete expr;
2131 return stat;
2132 default:
2133 break;
2137 NetRepeat*proc = new NetRepeat(expr, stat);
2138 return proc;
2142 * A task definition is elaborated by elaborating the statement that
2143 * it contains, and connecting its ports to NetNet objects. The
2144 * netlist doesn't really need the array of parameters once elaboration
2145 * is complete, but this is the best place to store them.
2147 * The first elaboration pass finds the reg objects that match the
2148 * port names, and creates the NetTaskDef object. The port names are
2149 * in the form task.port.
2151 * task foo;
2152 * output blah;
2153 * begin <body> end
2154 * endtask
2156 * So in the foo example, the PWire objects that represent the ports
2157 * of the task will include a foo.blah for the blah port. This port is
2158 * bound to a NetNet object by looking up the name.
2160 * Elaboration pass 2 for the task definition causes the statement of
2161 * the task to be elaborated and attached to the NetTaskDef object
2162 * created in pass 1.
2164 * NOTE: I am not sure why I bothered to prepend the task name to the
2165 * port name when making the port list. It is not really useful, but
2166 * that is what I did in pform_make_task_ports, so there it is.
2168 void PTask::elaborate_1(Design*des, const string&path) const
2170 NetScope*scope = des->find_scope(path);
2171 assert(scope);
2173 svector<NetNet*>ports (ports_? ports_->count() : 0);
2174 for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
2176 /* Parse the port name into the task name and the reg
2177 name. We know by design that the port name is given
2178 as two components: <task>.<port>. */
2180 string pname = (*ports_)[idx]->name();
2181 string ppath = parse_first_name(pname);
2182 assert(pname != "");
2184 /* check that the current scope really does have the
2185 name of the first component of the task port name. Do
2186 this by looking up the task scope in the parent of
2187 the current scope. */
2188 if (scope->parent()->child(ppath) != scope) {
2189 cerr << "internal error: task scope " << ppath
2190 << " not the same as scope " << scope->name()
2191 << "?!" << endl;
2192 return;
2195 NetNet*tmp = scope->find_signal(pname);
2197 if (tmp == 0) {
2198 cerr << get_line() << ": internal error: "
2199 << "Could not find port " << pname
2200 << " in scope " << scope->name() << endl;
2201 scope->dump(cerr);
2203 ports[idx] = tmp;
2206 NetTaskDef*def = new NetTaskDef(path, ports);
2207 des->add_task(path, def);
2210 void PTask::elaborate_2(Design*des, const string&path) const
2212 NetTaskDef*def = des->find_task(path);
2213 assert(def);
2215 NetProc*st;
2216 if (statement_ == 0) {
2217 cerr << get_line() << ": warning: task has no statement." << endl;
2218 st = new NetBlock(NetBlock::SEQU);
2220 } else {
2222 st = statement_->elaborate(des, path);
2223 if (st == 0) {
2224 cerr << statement_->get_line() << ": Unable to elaborate "
2225 "statement in task " << path << " at " << get_line()
2226 << "." << endl;
2227 return;
2231 def->set_proc(st);
2234 NetProc* PTrigger::elaborate(Design*des, const string&path) const
2236 NetScope*scope = des->find_scope(path);
2237 assert(scope);
2239 NetEvent*ev = scope->find_event(event_);
2240 if (ev == 0) {
2241 cerr << get_line() << ": error: event <" << event_ << ">"
2242 << " not found." << endl;
2243 des->errors += 1;
2244 return 0;
2247 NetEvTrig*trig = new NetEvTrig(ev);
2248 trig->set_line(*this);
2249 return trig;
2253 * The while loop is fairly directly represented in the netlist.
2255 NetProc* PWhile::elaborate(Design*des, const string&path) const
2257 NetScope*scope = des->find_scope(path);
2258 assert(scope);
2260 NetWhile*loop = new NetWhile(cond_->elaborate_expr(des, scope),
2261 statement_->elaborate(des, path));
2262 return loop;
2266 * When a module is instantiated, it creates the scope then uses this
2267 * method to elaborate the contents of the module.
2269 bool Module::elaborate(Design*des, NetScope*scope) const
2271 const string path = scope->name();
2272 bool result_flag = true;
2274 #if 0
2275 // Get all the explicitly declared wires of the module and
2276 // start the signals list with them.
2277 const map<string,PWire*>&wl = get_wires();
2279 for (map<string,PWire*>::const_iterator wt = wl.begin()
2280 ; wt != wl.end()
2281 ; wt ++ ) {
2283 (*wt).second->elaborate(des, scope);
2285 #endif
2287 // Elaborate functions.
2288 typedef map<string,PFunction*>::const_iterator mfunc_it_t;
2290 for (mfunc_it_t cur = funcs_.begin()
2291 ; cur != funcs_.end() ; cur ++) {
2292 NetScope*fscope = scope->child((*cur).first);
2293 if (scope == 0) {
2294 cerr << (*cur).second->get_line() << ": internal error: "
2295 << "Child scope for function " << (*cur).first
2296 << " missing in " << scope->name() << "." << endl;
2297 des->errors += 1;
2298 continue;
2301 (*cur).second->elaborate_1(des, fscope);
2304 for (mfunc_it_t cur = funcs_.begin()
2305 ; cur != funcs_.end() ; cur ++) {
2307 NetScope*fscope = scope->child((*cur).first);
2308 assert(fscope);
2309 (*cur).second->elaborate_2(des, fscope);
2312 // Elaborate the task definitions. This is done before the
2313 // behaviors so that task calls may reference these, and after
2314 // the signals so that the tasks can reference them.
2315 typedef map<string,PTask*>::const_iterator mtask_it_t;
2317 for (mtask_it_t cur = tasks_.begin()
2318 ; cur != tasks_.end() ; cur ++) {
2319 string pname = path + "." + (*cur).first;
2320 (*cur).second->elaborate_1(des, pname);
2323 for (mtask_it_t cur = tasks_.begin()
2324 ; cur != tasks_.end() ; cur ++) {
2325 string pname = path + "." + (*cur).first;
2326 (*cur).second->elaborate_2(des, pname);
2329 // Get all the gates of the module and elaborate them by
2330 // connecting them to the signals. The gate may be simple or
2331 // complex.
2332 const list<PGate*>&gl = get_gates();
2334 for (list<PGate*>::const_iterator gt = gl.begin()
2335 ; gt != gl.end()
2336 ; gt ++ ) {
2338 (*gt)->elaborate(des, path);
2341 // Elaborate the behaviors, making processes out of them.
2342 const list<PProcess*>&sl = get_behaviors();
2344 for (list<PProcess*>::const_iterator st = sl.begin()
2345 ; st != sl.end()
2346 ; st ++ ) {
2348 NetProc*cur = (*st)->statement()->elaborate(des, path);
2349 if (cur == 0) {
2350 cerr << (*st)->get_line() << ": error: Elaboration "
2351 "failed for this process." << endl;
2352 result_flag = false;
2353 continue;
2356 NetProcTop*top;
2357 switch ((*st)->type()) {
2358 case PProcess::PR_INITIAL:
2359 top = new NetProcTop(NetProcTop::KINITIAL, cur);
2360 break;
2361 case PProcess::PR_ALWAYS:
2362 top = new NetProcTop(NetProcTop::KALWAYS, cur);
2363 break;
2366 top->set_line(*(*st));
2367 des->add_process(top);
2370 return result_flag;
2373 Design* elaborate(const map<string,Module*>&modules,
2374 const map<string,PUdp*>&primitives,
2375 const string&root)
2377 // Look for the root module in the list.
2378 map<string,Module*>::const_iterator mod = modules.find(root);
2379 if (mod == modules.end())
2380 return 0;
2382 Module*rmod = (*mod).second;
2384 // This is the output design. I fill it in as I scan the root
2385 // module and elaborate what I find.
2386 Design*des = new Design;
2388 modlist = &modules;
2389 udplist = &primitives;
2391 // Make the root scope, then scan the pform looking for scopes
2392 // and parameters.
2393 NetScope*scope = des->make_root_scope(root);
2394 if (! rmod->elaborate_scope(des, scope)) {
2395 delete des;
2396 return 0;
2399 // This method recurses through the scopes, looking for
2400 // defparam assignments to apply to the parameters in the
2401 // various scopes. This needs to be done after all the scopes
2402 // and basic parameters are taken care of because the defparam
2403 // can assign to a paramter declared *after* it.
2404 des->run_defparams();
2407 // At this point, all parameter overrides are done. Scane the
2408 // scopes and evaluate the parameters all the way down to
2409 // constants.
2410 des->evaluate_parameters();
2413 // With the parameters evaluated down to constants, we have
2414 // what we need to elaborate signals and memories. This pass
2415 // creates all the NetNet and NetMemory objects for declared
2416 // objects.
2417 if (! rmod->elaborate_sig(des, scope)) {
2418 delete des;
2419 return 0;
2422 // Now that the structure and parameters are taken care of,
2423 // run through the pform again and generate the full netlist.
2424 bool rc = rmod->elaborate(des, scope);
2427 modlist = 0;
2428 udplist = 0;
2430 if (rc == false) {
2431 delete des;
2432 des = 0;
2435 return des;
2440 * $Log: elaborate.cc,v $
2441 * Revision 1.174 2000/05/27 19:33:23 steve
2442 * Merge similar probes within a module.
2444 * Revision 1.173 2000/05/16 04:05:16 steve
2445 * Module ports are really special PEIdent
2446 * expressions, because a name can be used
2447 * many places in the port list.
2449 * Revision 1.172 2000/05/11 23:37:27 steve
2450 * Add support for procedural continuous assignment.
2452 * Revision 1.171 2000/05/08 05:28:29 steve
2453 * Use bufz to make assignments directional.
2455 * Revision 1.170 2000/05/07 21:17:21 steve
2456 * non-blocking assignment to a bit select.
2458 * Revision 1.169 2000/05/07 04:37:56 steve
2459 * Carry strength values from Verilog source to the
2460 * pform and netlist for gates.
2462 * Change vvm constants to use the driver_t to drive
2463 * a constant value. This works better if there are
2464 * multiple drivers on a signal.
2466 * Revision 1.168 2000/05/02 16:27:38 steve
2467 * Move signal elaboration to a seperate pass.
2469 * Revision 1.167 2000/05/02 03:13:31 steve
2470 * Move memories to the NetScope object.
2472 * Revision 1.166 2000/05/02 00:58:11 steve
2473 * Move signal tables to the NetScope class.
2475 * Revision 1.165 2000/04/28 23:12:12 steve
2476 * Overly aggressive eliding of task calls.
2478 * Revision 1.164 2000/04/28 22:17:47 steve
2479 * Skip empty tasks.
2481 * Revision 1.163 2000/04/28 16:50:53 steve
2482 * Catch memory word parameters to tasks.
2484 * Revision 1.162 2000/04/23 03:45:24 steve
2485 * Add support for the procedural release statement.
2487 * Revision 1.161 2000/04/22 04:20:19 steve
2488 * Add support for force assignment.
2490 * Revision 1.160 2000/04/21 04:38:15 steve
2491 * Bit padding in assignment to memory.
2493 * Revision 1.159 2000/04/18 01:02:53 steve
2494 * Minor cleanup of NetTaskDef.
2496 * Revision 1.158 2000/04/12 04:23:58 steve
2497 * Named events really should be expressed with PEIdent
2498 * objects in the pform,
2500 * Handle named events within the mix of net events
2501 * and edges. As a unified lot they get caught together.
2502 * wait statements are broken into more complex statements
2503 * that include a conditional.
2505 * Do not generate NetPEvent or NetNEvent objects in
2506 * elaboration. NetEvent, NetEvWait and NetEvProbe
2507 * take over those functions in the netlist.
2509 * Revision 1.157 2000/04/10 05:26:06 steve
2510 * All events now use the NetEvent class.