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)
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 $"
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.
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
)
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());
85 /* Elaborate the l-value. */
86 NetNet
*lval
= pin(0)->elaborate_lnet(des
, path
);
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
,
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
);
114 /* Elaborate the r-value. Account for the initial decays,
115 which are going to be attached to the last gate before the
117 NetNet
*rval
= pin(1)->elaborate_net(des
, path
,
119 rise_time
, fall_time
, decay_time
,
122 cerr
<< get_line() << ": error: Unable to elaborate r-value: "
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
;
140 for (unsigned idx
= 0 ; idx
< lval
->pin_count() ; idx
+= 1)
141 connect(lval
->pin(idx
), rval
->pin(idx
));
143 if (lval
->local_flag())
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
155 unsigned low
= 0, high
= 0;
156 string name
= get_name();
158 name
= des
->local_symbol(path
);
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. */
166 verinum
*msb
= msb_
->eval_const(des
, path
);
167 verinum
*lsb
= lsb_
->eval_const(des
, path
);
170 cerr
<< get_line() << ": error: Unable to evaluate "
171 "expression " << *msb_
<< endl
;
177 cerr
<< get_line() << ": error: Unable to evaluate "
178 "expression " << *lsb_
<< endl
;
183 if (msb
->as_long() > lsb
->as_long())
184 count
= msb
->as_long() - lsb
->as_long() + 1;
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
];
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) {
224 tmp
<< name
<< "<" << index
<< ">" << ends
;
225 const string inm
= tmp
.str();
229 cur
[idx
] = new NetLogic(inm
, pin_count(), NetLogic::AND
);
232 cur
[idx
] = new NetLogic(inm
, pin_count(), NetLogic::BUF
);
235 cur
[idx
] = new NetLogic(inm
, pin_count(), NetLogic::BUFIF0
);
238 cur
[idx
] = new NetLogic(inm
, pin_count(), NetLogic::BUFIF1
);
241 cur
[idx
] = new NetLogic(inm
, pin_count(), NetLogic::NAND
);
244 cur
[idx
] = new NetLogic(inm
, pin_count(), NetLogic::NOR
);
247 cur
[idx
] = new NetLogic(inm
, pin_count(), NetLogic::NOT
);
250 cur
[idx
] = new NetLogic(inm
, pin_count(), NetLogic::OR
);
253 cur
[idx
] = new NetLogic(inm
, pin_count(), NetLogic::XNOR
);
256 cur
[idx
] = new NetLogic(inm
, pin_count(), NetLogic::XOR
);
259 cerr
<< get_line() << ": internal error: unhandled "
260 "gate type." << endl
;
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);
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
));
296 cerr
<< get_line() << ": error: Gate count of " <<
297 count
<< " does not match net width of " <<
298 sig
->pin_count() << " at pin " << idx
<< "."
303 if (NetTmp
*tmp
= dynamic_cast<NetTmp
*>(sig
))
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() != "");
321 cerr
<< get_line() << ": sorry: Module instantiation arrays "
322 "are not yet supported." << endl
;
327 NetScope
*scope
= des
->find_scope(path
);
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());
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.
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
356 cerr
<< get_line() << ": error: port ``" <<
357 pins_
[idx
].name
<< "'' is not a port of "
358 << get_name() << "." << endl
;
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.
367 cerr
<< get_line() << ": error: port ``" <<
368 pins_
[idx
].name
<< "'' already bound." <<
374 // OK, do the binding by placing the expression in
376 (*exp
)[pidx
] = pins_
[idx
].parm
;
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() << "."
392 // No named bindings, just use the positional list I
394 assert(pin_count() == rmod
->port_count());
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
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)
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: "
432 prts_pin_count
+= prts
[ldx
]->pin_count();
435 NetNet
*sig
= (*pins
)[idx
]->elaborate_net(des
, path
,
439 cerr
<< "internal error: Expression too complicated "
440 "for elaboration." << endl
;
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
;
457 // Connect the sig expression that is the context of the
458 // module instance to the ports of the elaborated
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) {
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
))
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) {
488 NetNet
*sig
= pin(idx
)->elaborate_net(des
, path
, 1, 0, 0, 0);
490 cerr
<< "internal error: Expression too complicated "
491 "for elaboration:" << *pin(idx
) << endl
;
495 connect(sig
->pin(0), net
->pin(idx
));
497 // Delete excess holding signal.
498 if (NetTmp
*tmp
= dynamic_cast<NetTmp
*>(sig
))
502 /* Build up the truth table for the netlist from the input
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.
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) {
534 NetNet
*sig
= pin(idx
)->elaborate_net(des
, path
, 1, 0, 0, 0);
536 cerr
<< "internal error: Expression too complicated "
537 "for elaboration:" << *pin(idx
) << endl
;
541 connect(sig
->pin(0), net
->pin(idx
));
543 // Delete excess holding signal.
544 if (NetTmp
*tmp
= dynamic_cast<NetTmp
*>(sig
))
548 /* Build up the truth table for the netlist from the input
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
) {
559 net
->set_initial('0');
562 net
->set_initial('1');
566 net
->set_initial('x');
570 // All done. Add the object to the design.
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
);
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
);
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
);
601 elaborate_cudp_(des
, (*udp
).second
, path
);
605 cerr
<< get_line() << ": internal error: Unknown module type: " <<
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
);
618 // Try a primitive type
619 map
<string
,PUdp
*>::const_iterator udp
= udplist
->find(type_
);
620 if (udp
!= udplist
->end())
624 cerr
<< get_line() << ": error: Unknown module type: " << type_
<< endl
;
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
);
637 svector
<NetNet
*>nets (parms_
.count());
642 cerr
<< get_line() << ": sorry: I do not know how to"
643 " elaborate repeat concatenation nets." << endl
;
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
);
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. */
659 for (unsigned idx
= 0 ; idx
< nets
.count() ; idx
+= 1) {
660 if (nets
[idx
]) delete nets
[idx
];
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
);
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
));
681 osig
->local_flag(true);
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
;
693 NetProc
* PAssign::assign_to_memory_(NetMemory
*mem
, PExpr
*ix
,
694 Design
*des
, const string
&path
) const
696 NetScope
*scope
= des
->find_scope(path
);
698 NetExpr
*rv
= rval()->elaborate_expr(des
, scope
);
704 rv
->set_width(mem
->width());
706 cerr
<< get_line() << ": internal error: No index in lval "
707 << "of assignment to memory?" << endl
;
712 NetNet
*idx
= ix
->elaborate_net(des
, path
, 0, 0, 0, 0);
715 if (rv
->expr_width() < mem
->width())
716 rv
= pad_to_width(rv
, mem
->width());
718 NetAssignMem
*am
= new NetAssignMem(mem
, idx
, rv
);
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
,
731 NetScope
*scope
= des
->find_scope(path
);
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. */
741 NetNet
*ll
= lval_
->elaborate_net(des
, path
, 0, 0, 0, 0);
743 cerr
<< get_line() << ": Assignment l-value too complex."
749 msb
= ll
->pin_count()-1;
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());
761 cerr
<< get_line() << ": error: Could not match signal ``" <<
762 id
->name() << "'' in ``" << path
<< "''" << endl
;
768 if ((reg
->type() != NetNet::REG
) && (reg
->type() != NetNet::INTEGER
)) {
769 cerr
<< get_line() << ": error: " << *lval() <<
770 " is not a register." << endl
;
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
780 verinum
*vl
= id
->lsb_
->eval_const(des
, path
);
782 cerr
<< id
->lsb_
->get_line() << ": error: "
783 "Expression must be constant in this context: "
788 verinum
*vm
= id
->msb_
->eval_const(des
, path
);
790 cerr
<< id
->msb_
->get_line() << ": error: "
791 "Expression must be constant in this context: "
797 msb
= vm
->as_ulong();
798 lsb
= vl
->as_ulong();
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
);
811 NetExpr
*m
= id
->msb_
->elaborate_expr(des
, scope
);
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);
839 NetProc
* PAssign::elaborate(Design
*des
, const string
&path
) const
841 NetScope
*scope
= des
->find_scope(path
);
844 /* Catch the case where the lvalue is a reference to a memory
845 item. These are handled differently. */
847 const PEIdent
*id
= dynamic_cast<const PEIdent
*>(lval());
850 NetNet
*net
= des
->find_signal(scope
, id
->name());
851 if (net
&& (net
->scope() == scope
))
854 if (NetMemory
*mem
= des
->find_memory(scope
, id
->name()))
855 return assign_to_memory_(mem
, id
->msb_
, des
, path
);
860 /* elaborate the lval. This detects any part selects and mux
861 expressions that might exist. */
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. */
877 if (verinum
*val
= rval()->eval_const(des
,path
)) {
878 rv
= new NetEConst(*val
);
881 } else if (rv
= rval()->elaborate_expr(des
, scope
)) {
886 /* Unable to elaborate expression. Retreat. */
892 /* Try to evaluate the expression, at least as far as possible. */
893 if (NetExpr
*tmp
= rv
->eval_tree()) {
900 /* Rewrite delayed assignments as assignments that are
901 delayed. For example, a = #<d> b; becomes:
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
;
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
);
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
);
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. */
959 st
= event_
->elaborate_st(des
, path
, a2
);
961 cerr
<< event_
->get_line() << ": error: "
962 "unable to elaborate event expression."
970 NetPDelay
*de
= new NetPDelay(rise_time
, a2
);
974 /* And build up the complex statement. */
975 NetBlock
*bl
= new NetBlock(NetBlock::SEQU
);
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());
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
));
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);
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
);
1028 /* Elaborate the r-value expression, ... */
1029 NetExpr
*rv
= rval()->elaborate_expr(des
, scope
);
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);
1040 /* And connect them together in an assignment NetProc. */
1041 NetAssignMemNB
*am
= new NetAssignMemNB(mem
, idx
, rv
);
1042 am
->set_line(*this);
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
);
1060 /* Catch the case where the lvalue is a reference to a memory
1061 item. These are handled differently. */
1063 const PEIdent
*id
= dynamic_cast<const PEIdent
*>(lval());
1066 if (NetMemory
*mem
= des
->find_memory(scope
, id
->name()))
1067 return assign_to_memory_(mem
, id
->msb_
, des
, path
);
1074 NetNet
*reg
= elaborate_lval(des
, path
, msb
, lsb
, mux
);
1075 if (reg
== 0) return 0;
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
);
1089 unsigned wid
= msb
- lsb
+ 1;
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
)));
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);
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
);
1138 NetBlock::Type type
= (bl_type_
==PBlock::BL_PAR
)
1141 NetBlock
*cur
= new NetBlock(type
);
1142 bool fail_flag
= false;
1146 if (name_
.length()) {
1147 nscope
= scope
->child(name_
);
1149 cerr
<< get_line() << ": internal error: "
1150 "unable to find block scope " << scope
->name()
1151 << "<" << name_
<< ">" << endl
;
1158 npath
= nscope
->name();
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
);
1172 for (unsigned idx
= 0 ; idx
< list_
.count() ; idx
+= 1) {
1173 NetProc
*tmp
= list_
[idx
]->elaborate(des
, npath
);
1190 * Elaborate a case statement.
1192 NetProc
* PCase::elaborate(Design
*des
, const string
&path
) const
1194 NetScope
*scope
= des
->find_scope(path
);
1197 NetExpr
*expr
= expr_
->elaborate_expr(des
, scope
);
1199 cerr
<< get_line() << ": error: Unable to elaborate this case"
1200 " expression." << endl
;
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)
1211 icount
+= cur
->expr
.count();
1214 NetCase
*res
= new NetCase(type_
, expr
, icount
);
1215 res
->set_line(*this);
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
1228 st
= cur
->stat
->elaborate(des
, path
);
1230 res
->set_case(inum
, 0, st
);
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.) */
1241 assert(cur
->expr
[e
]);
1242 gu
= cur
->expr
[e
]->elaborate_expr(des
, scope
);
1245 st
= cur
->stat
->elaborate(des
, path
);
1247 res
->set_case(inum
, gu
, st
);
1255 NetProc
* PCondit::elaborate(Design
*des
, const string
&path
) const
1257 NetScope
*scope
= des
->find_scope(path
);
1260 // Elaborate and try to evaluate the conditional expression.
1261 NetExpr
*expr
= expr_
->elaborate_expr(des
, scope
);
1263 cerr
<< get_line() << ": error: Unable to elaborate"
1264 " condition expression." << endl
;
1268 NetExpr
*tmp
= expr
->eval_tree();
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();
1281 if (val
[0] == verinum::V1
)
1282 return if_
->elaborate(des
, path
);
1284 return else_
->elaborate(des
, path
);
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
;
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
);
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);
1318 NetProc
* PCallTask::elaborate(Design
*des
, const string
&path
) const
1320 if (name_
[0] == '$')
1321 return elaborate_sys(des
, path
);
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.
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
1335 NetProc
* PCallTask::elaborate_sys(Design
*des
, const string
&path
) const
1337 NetScope
*scope
= des
->find_scope(path
);
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
);
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:
1380 NetProc
* PCallTask::elaborate_usr(Design
*des
, const string
&path
) const
1382 NetScope
*scope
= des
->find_scope(path
);
1385 NetTaskDef
*def
= des
->find_task(path
, name_
);
1387 cerr
<< get_line() << ": error: Enable of unknown task ``" <<
1388 path
<< "." << name_
<< "''." << endl
;
1393 if (nparms() != def
->port_count()) {
1394 cerr
<< get_line() << ": error: Port count mismatch in call to ``"
1395 << name_
<< "''." << endl
;
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
);
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)
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
)
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
));
1442 /* Generate the task call proper... */
1443 cur
= new NetUTask(def
);
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
)
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. */
1477 NetNet
*ix
= id
->msb_
->elaborate_net(des
, path
,
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);
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. */
1500 val
= parms_
[idx
]->elaborate_net(des
, path
,
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
1509 NetESignal
*sig
= new NetESignal(port
);
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);
1520 con
->set_width(val
->pin_count());
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
));
1537 NetCAssign
* PCAssign::elaborate(Design
*des
, const string
&path
) const
1539 NetScope
*scope
= des
->find_scope(path
);
1542 NetNet
*lval
= lval_
->elaborate_net(des
, path
, 0, 0, 0, 0);
1546 NetNet
*rval
= expr_
->elaborate_net(des
, path
, lval
->pin_count(),
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
);
1557 for (unsigned idx
= 0 ; idx
< dev
->pin_count() ; idx
+= 1)
1558 connect(dev
->pin(idx
), rval
->pin(idx
));
1563 NetDeassign
* PDeassign::elaborate(Design
*des
, const string
&path
) const
1565 NetScope
*scope
= des
->find_scope(path
);
1568 NetNet
*lval
= lval_
->elaborate_net(des
, path
, 0, 0, 0, 0);
1572 NetDeassign
*dev
= new NetDeassign(lval
);
1573 dev
->set_line( *this );
1577 NetProc
* PDelayStatement::elaborate(Design
*des
, const string
&path
) const
1579 verinum
*num
= delay_
->eval_const(des
, path
);
1581 cerr
<< get_line() << ": sorry: delay expression "
1582 "must be constant." << endl
;
1587 unsigned long val
= num
->as_ulong();
1589 return new NetPDelay(val
, statement_
->elaborate(des
, path
));
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
1610 * The basic data structure is:
1612 * NetEvWait ---/---> NetEvent <----\---- NetEvProbe
1614 * NetEvWait ---+ +---- NetEvProbe
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:
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:
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
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.
1646 * always @foo <stmt>;
1655 * Each trigger statement in the source generates a separate NetEvTrig
1656 * object in the netlist. Those trigger objects are elaborated
1659 * Additional complications arise when named events show up in
1660 * conjunctions. An example of such a case is:
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
,
1677 NetScope
*scope
= des
->find_scope(path
);
1681 /* The Verilog wait (<expr>) <statement> statement is a level
1682 sensitive wait. Handle this special case by elaborating
1683 something like this:
1686 if (! <expr>) @(posedge <expr>)
1690 This is equivilent, and uses the existing capapilities of
1691 the netlist format. The resulting netlist should look like
1694 NetBlock ---+---> NetCondit --+--> <expr>
1696 | +--> NetEvWait--> NetEvent
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
,
1711 expr_
[0]->dump(cerr
);
1717 NetEvent
*ev
= new NetEvent(scope
->local_symbol());
1718 scope
->add_event(ev
);
1720 NetEvWait
*we
= new NetEvWait(0);
1723 NetEvProbe
*po
= new NetEvProbe(path
+"."+scope
->local_symbol(),
1724 ev
, NetEvProbe::POSEDGE
, 1);
1725 connect(po
->pin(0), ex
->pin(0));
1729 NetESignal
*ce
= new NetESignal(ex
);
1730 NetCondit
*co
= new NetCondit(new NetEUnary('!', ce
), we
, 0);
1734 ev
->set_line(*this);
1735 bl
->set_line(*this);
1736 we
->set_line(*this);
1737 co
->set_line(*this);
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());
1750 if (id
&& (ev
= scope
->find_event(id
->name()))) {
1751 NetEvWait
*pr
= new NetEvWait(enet
);
1753 pr
->set_line(*this);
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
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());
1786 /* So now we have a normal event expression. Elaborate
1787 the sub-expression as a net and decide how to handle
1790 NetNet
*expr
= expr_
[idx
]->expr()->elaborate_net(des
, path
,
1793 expr_
[idx
]->dump(cerr
);
1800 unsigned pins
= (expr_
[idx
]->type() == PEEvent::ANYEDGE
)
1801 ? expr
->pin_count() : 1;
1804 switch (expr_
[idx
]->type()) {
1805 case PEEvent::POSEDGE
:
1806 pr
= new NetEvProbe(des
->local_symbol(path
), ev
,
1807 NetEvProbe::POSEDGE
, pins
);
1810 case PEEvent::NEGEDGE
:
1811 pr
= new NetEvProbe(des
->local_symbol(path
), ev
,
1812 NetEvProbe::NEGEDGE
, pins
);
1815 case PEEvent::ANYEDGE
:
1816 pr
= new NetEvProbe(des
->local_symbol(path
), ev
,
1817 NetEvProbe::ANYEDGE
, pins
);
1824 for (unsigned p
= 0 ; p
< pr
->pin_count() ; p
+= 1)
1825 connect(pr
->pin(p
), expr
->pin(p
));
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 " <<
1839 wa
->add_event(match
);
1843 scope
->add_event(ev
);
1853 NetProc
* PEventStatement::elaborate(Design
*des
, const string
&path
) const
1857 enet
= statement_
->elaborate(des
, path
);
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
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
);
1880 NetProc
* PForce::elaborate(Design
*des
, const string
&path
) const
1882 NetScope
*scope
= des
->find_scope(path
);
1885 NetNet
*lval
= lval_
->elaborate_net(des
, path
, 0, 0, 0, 0);
1889 NetNet
*rval
= expr_
->elaborate_net(des
, path
, lval
->pin_count(),
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
);
1900 for (unsigned idx
= 0 ; idx
< dev
->pin_count() ; idx
+= 1)
1901 connect(dev
->pin(idx
), rval
->pin(idx
));
1907 * elaborate the for loop as the equivalent while loop. This eases the
1908 * task for the target code generator. The structure is:
1912 * while (cond_) begin : body
1918 NetProc
* PForStatement::elaborate(Design
*des
, const string
&path
) const
1920 NetScope
*scope
= des
->find_scope(path
);
1923 const PEIdent
*id1
= dynamic_cast<const PEIdent
*>(name1_
);
1925 const PEIdent
*id2
= dynamic_cast<const PEIdent
*>(name2_
);
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());
1935 cerr
<< id1
->get_line() << ": register ``" << id1
->name()
1936 << "'' unknown in this context." << endl
;
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
));
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
);
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());
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
));
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
);
1981 if (NetExpr
*tmp
= ce
->eval_tree()) {
1982 if (dynamic_cast<NetEConst
*>(tmp
))
1983 cerr
<< get_line() << ": warning: condition expression "
1984 "is constant." << endl
;
1990 /* All done, build up the loop. */
1992 NetWhile
*loop
= new NetWhile(ce
, body
);
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;
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
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
;
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
;
2053 NetNet
*tmp
= scope
->find_signal(pname
);
2055 cerr
<< get_line() << ": internal error: function "
2056 << scope
->name() << " is missing port "
2057 << pname
<< "." << endl
;
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());
2074 NetProc
*st
= statement_
->elaborate(des
, scope
->name());
2076 cerr
<< statement_
->get_line() << ": error: Unable to elaborate "
2077 "statement in function " << def
->name() << "." << endl
;
2085 NetProc
* PRelease::elaborate(Design
*des
, const string
&path
) const
2087 NetScope
*scope
= des
->find_scope(path
);
2090 NetNet
*lval
= lval_
->elaborate_net(des
, path
, 0, 0, 0, 0);
2094 NetRelease
*dev
= new NetRelease(lval
);
2095 dev
->set_line( *this );
2099 NetProc
* PRepeat::elaborate(Design
*des
, const string
&path
) const
2101 NetScope
*scope
= des
->find_scope(path
);
2104 NetExpr
*expr
= expr_
->elaborate_expr(des
, scope
);
2106 cerr
<< get_line() << ": Unable to elaborate"
2107 " repeat expression." << endl
;
2111 NetExpr
*tmp
= expr
->eval_tree();
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()) {
2128 return new NetBlock(NetBlock::SEQU
);
2137 NetRepeat
*proc
= new NetRepeat(expr
, stat
);
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.
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
);
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()
2195 NetNet
*tmp
= scope
->find_signal(pname
);
2198 cerr
<< get_line() << ": internal error: "
2199 << "Could not find port " << pname
2200 << " in scope " << scope
->name() << endl
;
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
);
2216 if (statement_
== 0) {
2217 cerr
<< get_line() << ": warning: task has no statement." << endl
;
2218 st
= new NetBlock(NetBlock::SEQU
);
2222 st
= statement_
->elaborate(des
, path
);
2224 cerr
<< statement_
->get_line() << ": Unable to elaborate "
2225 "statement in task " << path
<< " at " << get_line()
2234 NetProc
* PTrigger::elaborate(Design
*des
, const string
&path
) const
2236 NetScope
*scope
= des
->find_scope(path
);
2239 NetEvent
*ev
= scope
->find_event(event_
);
2241 cerr
<< get_line() << ": error: event <" << event_
<< ">"
2242 << " not found." << endl
;
2247 NetEvTrig
*trig
= new NetEvTrig(ev
);
2248 trig
->set_line(*this);
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
);
2260 NetWhile
*loop
= new NetWhile(cond_
->elaborate_expr(des
, scope
),
2261 statement_
->elaborate(des
, path
));
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;
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()
2283 (*wt
).second
->elaborate(des
, scope
);
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
);
2294 cerr
<< (*cur
).second
->get_line() << ": internal error: "
2295 << "Child scope for function " << (*cur
).first
2296 << " missing in " << scope
->name() << "." << endl
;
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
);
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
2332 const list
<PGate
*>&gl
= get_gates();
2334 for (list
<PGate
*>::const_iterator gt
= gl
.begin()
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()
2348 NetProc
*cur
= (*st
)->statement()->elaborate(des
, path
);
2350 cerr
<< (*st
)->get_line() << ": error: Elaboration "
2351 "failed for this process." << endl
;
2352 result_flag
= false;
2357 switch ((*st
)->type()) {
2358 case PProcess::PR_INITIAL
:
2359 top
= new NetProcTop(NetProcTop::KINITIAL
, cur
);
2361 case PProcess::PR_ALWAYS
:
2362 top
= new NetProcTop(NetProcTop::KALWAYS
, cur
);
2366 top
->set_line(*(*st
));
2367 des
->add_process(top
);
2373 Design
* elaborate(const map
<string
,Module
*>&modules
,
2374 const map
<string
,PUdp
*>&primitives
,
2377 // Look for the root module in the list.
2378 map
<string
,Module
*>::const_iterator mod
= modules
.find(root
);
2379 if (mod
== modules
.end())
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
;
2389 udplist
= &primitives
;
2391 // Make the root scope, then scan the pform looking for scopes
2393 NetScope
*scope
= des
->make_root_scope(root
);
2394 if (! rmod
->elaborate_scope(des
, scope
)) {
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
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
2417 if (! rmod
->elaborate_sig(des
, scope
)) {
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
);
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
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.