2 * Copyright (c) 2000-2004 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 #ident "$Id: elab_sig.cc,v 1.52 2007/06/02 03:42:12 steve Exp $"
30 # include "PGenerate.h"
33 # include "compiler.h"
37 # include "ivl_assert.h"
40 * This local function checks if a named signal is connected to a
41 * port. It looks in the array of ports passed, for NetEIdent objects
42 * within the port_t that have a matching name.
44 static bool signal_is_in_port(const svector
<Module::port_t
*>&ports
,
47 perm_string name
= sig
->name();
49 for (unsigned idx
= 0 ; idx
< ports
.count() ; idx
+= 1) {
51 Module::port_t
*pp
= ports
[idx
];
52 // Skip internally unconnected ports.
56 // This port has an internal connection. In this case,
57 // the port has 0 or more NetEIdent objects concatenated
58 // together that form the port.
60 // Note that module ports should not have any heirarchy
61 // in their names: they are in the root of the module
62 // scope by definition.
64 for (unsigned cc
= 0 ; cc
< pp
->expr
.count() ; cc
+= 1) {
65 perm_string pname
= peek_tail_name(pp
->expr
[cc
]->path());
76 static NetNet
*find_signal_in_scope(NetScope
*scope
, const hname_t
&path
)
81 while (path
.peek_name(idx
+1)) {
82 cur
= cur
->child(path
.peek_name(idx
));
89 return cur
->find_signal(path
.peek_name(idx
));
93 bool Module::elaborate_sig(Design
*des
, NetScope
*scope
) const
97 // Scan all the ports of the module, and make sure that each
98 // is connected to wires that have port declarations.
99 for (unsigned idx
= 0 ; idx
< ports
.count() ; idx
+= 1) {
100 Module::port_t
*pp
= ports
[idx
];
104 map
<pform_name_t
,PWire
*>::const_iterator wt
;
105 for (unsigned cc
= 0 ; cc
< pp
->expr
.count() ; cc
+= 1) {
106 pform_name_t
port_path (pp
->expr
[cc
]->path());
107 wt
= wires_
.find(port_path
);
109 if (wt
== wires_
.end()) {
110 cerr
<< get_line() << ": error: "
111 << "Port " << pp
->expr
[cc
]->path() << " ("
112 << (idx
+1) << ") of module " << name_
113 << " is not declared within module." << endl
;
118 if ((*wt
).second
->get_port_type() == NetNet::NOT_A_PORT
) {
119 cerr
<< get_line() << ": error: "
120 << "Port " << pp
->expr
[cc
]->path() << " ("
121 << (idx
+1) << ") of module " << name_
122 << " has no direction declaration."
129 for (map
<pform_name_t
,PWire
*>::const_iterator wt
= wires_
.begin()
130 ; wt
!= wires_
.end() ; wt
++ ) {
132 PWire
*cur
= (*wt
).second
;
133 NetNet
*sig
= cur
->elaborate_sig(des
, scope
);
135 // If this wire is a signal of the module (as opposed to
136 // a port of a function) and is a port, then check that
137 // the module knows about it. We know that the signal is
138 // the name of a signal within a subscope of a module
139 // (a task, a function, etc.) if the name for the PWire
142 if (sig
&& (sig
->scope() == scope
)
143 && (cur
->get_port_type() != NetNet::NOT_A_PORT
)) {
145 if (! signal_is_in_port(ports
, sig
)) {
147 cerr
<< cur
->get_line() << ": error: Signal "
148 << sig
->name() << " has a declared direction "
149 << "but is not a port." << endl
;
155 /* If the signal is an input and is also declared as a
156 reg, then report an error. */
158 if (sig
&& (sig
->scope() == scope
)
159 && (sig
->port_type() == NetNet::PINPUT
)
160 && (sig
->type() == NetNet::REG
)) {
162 cerr
<< cur
->get_line() << ": error: "
163 << cur
->path() << " in module "
164 << scope
->module_name()
165 << " declared as input and as a reg type." << endl
;
169 if (sig
&& (sig
->scope() == scope
)
170 && (sig
->port_type() == NetNet::PINOUT
)
171 && (sig
->type() == NetNet::REG
)) {
173 cerr
<< cur
->get_line() << ": error: "
174 << cur
->path() << " in module "
175 << scope
->module_name()
176 << " declared as inout and as a reg type." << endl
;
182 // Run through all the generate schemes to enaborate the
183 // signals that they hold. Note that the generate schemes hold
184 // the scopes that they instantiated, so we don't pass any
186 typedef list
<PGenerate
*>::const_iterator generate_it_t
;
187 for (generate_it_t cur
= generate_schemes
.begin()
188 ; cur
!= generate_schemes
.end() ; cur
++ ) {
189 (*cur
) -> elaborate_sig(des
, scope
);
192 // Get all the gates of the module and elaborate them by
193 // connecting them to the signals. The gate may be simple or
194 // complex. What we are looking for is gates that are modules
195 // that can create scopes and signals.
197 const list
<PGate
*>&gl
= get_gates();
199 for (list
<PGate
*>::const_iterator gt
= gl
.begin()
203 flag
&= (*gt
)->elaborate_sig(des
, scope
);
207 typedef map
<perm_string
,PFunction
*>::const_iterator mfunc_it_t
;
209 for (mfunc_it_t cur
= funcs_
.begin()
210 ; cur
!= funcs_
.end() ; cur
++) {
212 hname_t
use_name ( (*cur
).first
);
213 NetScope
*fscope
= scope
->child(use_name
);
215 cerr
<< (*cur
).second
->get_line() << ": internal error: "
216 << "Child scope for function " << (*cur
).first
217 << " missing in " << scope_path(scope
) << "." << endl
;
222 (*cur
).second
->elaborate_sig(des
, fscope
);
226 // After all the wires are elaborated, we are free to
227 // elaborate the ports of the tasks defined within this
228 // module. Run through them now.
230 typedef map
<perm_string
,PTask
*>::const_iterator mtask_it_t
;
232 for (mtask_it_t cur
= tasks_
.begin()
233 ; cur
!= tasks_
.end() ; cur
++) {
234 NetScope
*tscope
= scope
->child( hname_t((*cur
).first
) );
236 (*cur
).second
->elaborate_sig(des
, tscope
);
242 bool PGModule::elaborate_sig_mod_(Design
*des
, NetScope
*scope
,
247 NetScope::scope_vec_t instance
= scope
->instance_arrays
[get_name()];
249 for (unsigned idx
= 0 ; idx
< instance
.count() ; idx
+= 1) {
250 // I know a priori that the elaborate_scope created the scope
251 // already, so just look it up as a child of the current scope.
252 NetScope
*my_scope
= instance
[idx
];
255 if (my_scope
->parent() != scope
) {
256 cerr
<< get_line() << ": internal error: "
257 << "Instance " << scope_path(my_scope
)
258 << " is in parent " << scope_path(my_scope
->parent())
259 << " instead of " << scope_path(scope
)
262 assert(my_scope
->parent() == scope
);
264 if (! rmod
->elaborate_sig(des
, my_scope
))
272 bool PGenerate::elaborate_sig(Design
*des
, NetScope
*container
) const
276 typedef list
<NetScope
*>::const_iterator scope_list_it_t
;
277 for (scope_list_it_t cur
= scope_list_
.begin()
278 ; cur
!= scope_list_
.end() ; cur
++ ) {
280 NetScope
*scope
= *cur
;
282 if (scope
->parent() != container
)
286 cerr
<< get_line() << ": debug: Elaborate nets in "
287 << "scope " << scope_path(*cur
)
288 << " in generate " << id_number
<< endl
;
289 flag
= elaborate_sig_(des
, *cur
) & flag
;
295 bool PGenerate::elaborate_sig_(Design
*des
, NetScope
*scope
) const
297 // Scan the declared PWires to elaborate the obvious signals
298 // in the current scope.
299 typedef map
<pform_name_t
,PWire
*>::const_iterator wires_it_t
;
300 for (wires_it_t wt
= wires
.begin()
301 ; wt
!= wires
.end() ; wt
++ ) {
303 PWire
*cur
= (*wt
).second
;
306 cerr
<< get_line() << ": debug: Elaborate PWire "
307 << cur
->path() << " in scope " << scope_path(scope
) << endl
;
309 cur
->elaborate_sig(des
, scope
);
312 typedef list
<PGate
*>::const_iterator pgate_list_it_t
;
313 for (pgate_list_it_t cur
= gates
.begin()
314 ; cur
!= gates
.end() ; cur
++) {
315 (*cur
) ->elaborate_sig(des
, scope
);
323 * A function definition exists within an elaborated module. This
324 * matters when elaborating signals, as the ports of the function are
325 * created as signals/variables for each instance of the
326 * function. That is why PFunction has an elaborate_sig method.
328 void PFunction::elaborate_sig(Design
*des
, NetScope
*scope
) const
330 perm_string fname
= scope
->basename();
331 assert(scope
->type() == NetScope::FUNC
);
333 /* Make sure the function has at least one input port. If it
334 fails this test, print an error message. Keep going so we
335 can find more errors. */
337 cerr
<< get_line() << ": error: Function " << fname
338 << " has no ports." << endl
;
339 cerr
<< get_line() << ": : Functions must have"
340 << " at least one input port." << endl
;
346 /* Create the signals/variables of the return value and write
347 them into the function scope. */
348 switch (return_type_
.type
) {
352 if (return_type_
.range
) {
353 NetExpr
*me
= elab_and_eval(des
, scope
,
354 (*return_type_
.range
)[0], -1);
356 NetExpr
*le
= elab_and_eval(des
, scope
,
357 (*return_type_
.range
)[1], -1);
360 long mnum
= 0, lnum
= 0;
361 if (NetEConst
*tmp
= dynamic_cast<NetEConst
*>(me
)) {
362 mnum
= tmp
->value().as_long();
364 cerr
<< me
->get_line() << ": error: "
365 "Unable to evaluate constant expression "
366 << *me
<< "." << endl
;
370 if (NetEConst
*tmp
= dynamic_cast<NetEConst
*>(le
)) {
371 lnum
= tmp
->value().as_long();
373 cerr
<< le
->get_line() << ": error: "
374 "Unable to evaluate constant expression "
375 << *le
<< "." << endl
;
379 ret_sig
= new NetNet(scope
, fname
, NetNet::REG
, mnum
, lnum
);
382 ret_sig
= new NetNet(scope
, fname
, NetNet::REG
);
384 ret_sig
->set_line(*this);
385 ret_sig
->set_signed(return_type_
.type
== PTF_REG_S
);
386 ret_sig
->port_type(NetNet::POUTPUT
);
387 ret_sig
->data_type(IVL_VT_LOGIC
);
391 ret_sig
= new NetNet(scope
, fname
, NetNet::REG
, integer_width
);
392 ret_sig
->set_line(*this);
393 ret_sig
->set_signed(true);
394 ret_sig
->set_isint(true);
395 ret_sig
->port_type(NetNet::POUTPUT
);
396 ret_sig
->data_type(IVL_VT_LOGIC
);
400 ret_sig
= new NetNet(scope
, fname
, NetNet::REG
, 64);
401 ret_sig
->set_line(*this);
402 ret_sig
->set_signed(false);
403 ret_sig
->set_isint(false);
404 ret_sig
->port_type(NetNet::POUTPUT
);
405 ret_sig
->data_type(IVL_VT_LOGIC
);
410 ret_sig
= new NetNet(scope
, fname
, NetNet::REG
, 1);
411 ret_sig
->set_line(*this);
412 ret_sig
->set_signed(true);
413 ret_sig
->set_isint(false);
414 ret_sig
->port_type(NetNet::POUTPUT
);
415 ret_sig
->data_type(IVL_VT_REAL
);
419 cerr
<< get_line() << ": internal error: I don't know how "
420 << "to deal with return type of function "
421 << scope
->basename() << "." << endl
;
424 svector
<NetNet
*>ports (ports_
? ports_
->count() : 0);
427 for (unsigned idx
= 0 ; idx
< ports_
->count() ; idx
+= 1) {
429 /* Parse the port name into the task name and the reg
430 name. We know by design that the port name is given
431 as two components: <func>.<port>. */
433 pform_name_t path
= (*ports_
)[idx
]->path();
434 ivl_assert(*this, path
.size() == 2);
436 perm_string pname
= peek_tail_name(path
);
437 perm_string ppath
= peek_head_name(path
);
439 if (ppath
!= scope
->basename()) {
440 cerr
<< get_line() << ": internal error: function "
441 << "port " << (*ports_
)[idx
]->path()
442 << " has wrong name for function "
443 << scope_path(scope
) << "." << endl
;
447 NetNet
*tmp
= scope
->find_signal(pname
);
449 cerr
<< get_line() << ": internal error: function "
450 << scope_path(scope
) << " is missing port "
451 << pname
<< "." << endl
;
453 cerr
<< get_line() << ": Continuing..." << endl
;
462 if (ret_sig
) def
= new NetFuncDef(scope
, ret_sig
, ports
);
465 scope
->set_func_def(def
);
469 * A task definition is a scope within an elaborated module. When we
470 * are elaborating signals, the scopes have already been created, as
471 * have the reg objects that are the parameters of this task. The
472 * elaborate_sig method of PTask is therefore left to connect the
473 * signals to the ports of the NetTaskDef definition. We know for
474 * certain that signals exist (They are in my scope!) so the port
475 * binding is sure to work.
477 void PTask::elaborate_sig(Design
*des
, NetScope
*scope
) const
479 assert(scope
->type() == NetScope::TASK
);
481 svector
<NetNet
*>ports (ports_
? ports_
->count() : 0);
482 for (unsigned idx
= 0 ; idx
< ports
.count() ; idx
+= 1) {
484 /* Parse the port name into the task name and the reg
485 name. We know by design that the port name is given
486 as two components: <task>.<port>. */
488 pform_name_t path
= (*ports_
)[idx
]->path();
489 ivl_assert(*this, path
.size() == 2);
491 perm_string scope_name
= peek_head_name(path
);
492 perm_string port_name
= peek_tail_name(path
);
494 /* check that the current scope really does have the
495 name of the first component of the task port name. Do
496 this by looking up the task scope in the parent of
497 the current scope. */
498 ivl_assert(*this, scope
->basename() == scope_name
);
500 /* Find the signal for the port. We know by definition
501 that it is in the scope of the task, so look only in
503 NetNet
*tmp
= scope
->find_signal(port_name
);
506 cerr
<< get_line() << ": internal error: "
507 << "Could not find port " << port_name
508 << " in scope " << scope_path(scope
) << endl
;
515 NetTaskDef
*def
= new NetTaskDef(scope
, ports
);
516 scope
->set_task_def(def
);
519 bool PGate::elaborate_sig(Design
*des
, NetScope
*scope
) const
525 * Elaborate a source wire. The "wire" is the declaration of wires,
526 * registers, ports and memories. The parser has already merged the
527 * multiple properties of a wire (i.e., "input wire") so come the
528 * elaboration this creates an object in the design that represent the
531 NetNet
* PWire::elaborate_sig(Design
*des
, NetScope
*scope
) const
534 /* The parser may produce hierarchical names for wires. I here
535 follow the scopes down to the base where I actually want to
536 elaborate the NetNet object. */
537 { pform_name_t tmp_path
= hname_
;
539 while (! tmp_path
.empty()) {
540 name_component_t cur
= tmp_path
.front();
541 tmp_path
.pop_front();
543 scope
= scope
->child( hname_t(cur
.name
) );
546 cerr
<< get_line() << ": internal error: "
547 << "Bad scope component for name "
554 NetNet::Type wtype
= type_
;
555 if (wtype
== NetNet::IMPLICIT
)
556 wtype
= NetNet::WIRE
;
557 if (wtype
== NetNet::IMPLICIT_REG
)
561 long lsb
= 0, msb
= 0;
563 des
->errors
+= error_cnt_
;
565 if (port_set_
|| net_set_
) {
566 long pmsb
= 0, plsb
= 0, nmsb
= 0, nlsb
= 0;
567 /* If they exist get the port definition MSB and LSB */
568 if (port_set_
&& port_msb_
!= 0) {
569 NetExpr
*texpr
= elab_and_eval(des
, scope
, port_msb_
, -1);
571 if (! eval_as_long(pmsb
, texpr
)) {
572 cerr
<< port_msb_
->get_line() << ": error: "
573 "Unable to evaluate MSB constant expression ``"
574 << *port_msb_
<< "''." << endl
;
581 texpr
= elab_and_eval(des
, scope
, port_lsb_
, -1);
583 if (! eval_as_long(plsb
, texpr
)) {
584 cerr
<< port_lsb_
->get_line() << ": error: "
585 "Unable to evaluate LSB constant expression ``"
586 << *port_lsb_
<< "''." << endl
;
595 if (!port_set_
) assert(port_msb_
== 0 && port_lsb_
== 0);
596 if (port_msb_
== 0) assert(port_lsb_
== 0);
597 if (port_lsb_
== 0) assert(port_msb_
== 0);
599 /* If they exist get the net/etc. definition MSB and LSB */
600 if (net_set_
&& net_msb_
!= 0) {
601 NetExpr
*texpr
= elab_and_eval(des
, scope
, net_msb_
, -1);
603 if (! eval_as_long(nmsb
, texpr
)) {
604 cerr
<< net_msb_
->get_line() << ": error: "
605 "Unable to evaluate MSB constant expression ``"
606 << *net_msb_
<< "''." << endl
;
613 texpr
= elab_and_eval(des
, scope
, net_lsb_
, -1);
615 if (! eval_as_long(nlsb
, texpr
)) {
616 cerr
<< net_lsb_
->get_line() << ": error: "
617 "Unable to evaluate LSB constant expression ``"
618 << *net_lsb_
<< "''." << endl
;
625 if (!net_set_
) assert(net_msb_
== 0 && net_lsb_
== 0);
626 if (net_msb_
== 0) assert(net_lsb_
== 0);
627 if (net_lsb_
== 0) assert(net_msb_
== 0);
629 /* We have a port size error */
630 if (port_set_
&& net_set_
&& (pmsb
!= nmsb
|| plsb
!= nlsb
)) {
632 /* Scalar port with a vector net/etc. definition */
633 if (port_msb_
== 0) {
634 if (!gn_io_range_error_flag
) {
636 << ": warning: Scalar port ``" << hname_
637 << "'' has a vectored net declaration ["
638 << nmsb
<< ":" << nlsb
<< "]." << endl
;
641 << ": error: Scalar port ``" << hname_
642 << "'' has a vectored net declaration ["
643 << nmsb
<< ":" << nlsb
<< "]." << endl
;
649 /* Vectored port with a scalar net/etc. definition */
651 cerr
<< port_msb_
->get_line()
652 << ": error: Vectored port ``"
653 << hname_
<< "'' [" << pmsb
<< ":" << plsb
654 << "] has a scalar net declaration at "
655 << get_line() << "." << endl
;
660 /* Both vectored, but they have different ranges. */
661 if (port_msb_
!= 0 && net_msb_
!= 0) {
662 cerr
<< port_msb_
->get_line()
663 << ": error: Vectored port ``"
664 << hname_
<< "'' [" << pmsb
<< ":" << plsb
665 << "] has a net declaration [" << nmsb
<< ":"
666 << nlsb
<< "] at " << net_msb_
->get_line()
667 << " that does not match." << endl
;
676 wid
= nmsb
- nlsb
+ 1;
678 wid
= nlsb
- nmsb
+ 1;
683 unsigned nattrib
= 0;
684 attrib_list_t
*attrib_list
= evaluate_attributes(attributes
, nattrib
,
689 unsigned array_dimensions
= 0;
691 /* If the ident has idx expressions, then this is a
692 memory. It can only have the idx registers after the msb
693 and lsb expressions are filled. And, if it has one index,
695 if (lidx_
|| ridx_
) {
696 assert(lidx_
&& ridx_
);
698 NetExpr
*lexp
= elab_and_eval(des
, scope
, lidx_
, -1);
699 NetExpr
*rexp
= elab_and_eval(des
, scope
, ridx_
, -1);
701 if ((lexp
== 0) || (rexp
== 0)) {
702 cerr
<< get_line() << ": internal error: There is "
703 << "a problem evaluating indices for ``"
704 << hname_
<< "''." << endl
;
709 NetEConst
*lcon
= dynamic_cast<NetEConst
*> (lexp
);
710 NetEConst
*rcon
= dynamic_cast<NetEConst
*> (rexp
);
712 if ((lcon
== 0) || (rcon
== 0)) {
713 cerr
<< get_line() << ": internal error: The indices "
714 << "are not constant for array ``"
715 << hname_
<< "''." << endl
;
720 verinum lval
= lcon
->value();
721 verinum rval
= rcon
->value();
726 array_dimensions
= 1;
727 array_s0
= lval
.as_long();
728 array_e0
= rval
.as_long();
731 /* If the net type is supply0 or supply1, replace it
732 with a simple wire with a pulldown/pullup with supply
733 strength. In other words, transform:
740 pulldown #(supply0) (foo);
742 This reduces the backend burden, and behaves exactly
746 if (wtype
== NetNet::SUPPLY0
|| wtype
== NetNet::SUPPLY1
) {
747 NetLogic::TYPE pull_type
= (wtype
==NetNet::SUPPLY1
)
749 : NetLogic::PULLDOWN
;
750 pull
= new NetLogic(scope
, scope
->local_symbol(),
752 pull
->set_line(*this);
753 pull
->pin(0).drive0(Link::SUPPLY
);
754 pull
->pin(0).drive1(Link::SUPPLY
);
756 wtype
= NetNet::WIRE
;
758 if (debug_elaborate
) {
759 cerr
<< get_line() << ": debug: "
760 << "Generate a SUPPLY pulldown for the "
761 << "supply0 net." << endl
;
765 perm_string name
= peek_tail_name(hname_
);
766 if (debug_elaborate
) {
767 cerr
<< get_line() << ": debug: Create signal "
768 << wtype
<< " ["<<msb
<<":"<<lsb
<<"] " << name
769 << " in scope " << scope_path(scope
) << endl
;
773 NetNet
*sig
= array_dimensions
> 0
774 ? new NetNet(scope
, name
, wtype
, msb
, lsb
, array_s0
, array_e0
)
775 : new NetNet(scope
, name
, wtype
, msb
, lsb
);
777 ivl_variable_type_t use_data_type
= data_type_
;
778 if (use_data_type
== IVL_VT_NO_TYPE
) {
779 use_data_type
= IVL_VT_LOGIC
;
780 if (debug_elaborate
) {
781 cerr
<< get_line() << ": debug: "
783 << " in scope " << scope_path(scope
)
784 << " defaults to data type " << use_data_type
<< endl
;
788 sig
->data_type(use_data_type
);
789 sig
->set_line(*this);
790 sig
->port_type(port_type_
);
791 sig
->set_signed(get_signed());
792 sig
->set_isint(get_isint());
795 connect(sig
->pin(0), pull
->pin(0));
797 for (unsigned idx
= 0 ; idx
< nattrib
; idx
+= 1)
798 sig
->attribute(attrib_list
[idx
].key
, attrib_list
[idx
].val
);