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
<PGenerate
*>::const_iterator generate_it_t
;
313 for (generate_it_t cur
= generates
.begin()
314 ; cur
!= generates
.end() ; cur
++ ) {
315 (*cur
) -> elaborate_sig(des
, scope
);
318 typedef list
<PGate
*>::const_iterator pgate_list_it_t
;
319 for (pgate_list_it_t cur
= gates
.begin()
320 ; cur
!= gates
.end() ; cur
++) {
321 (*cur
) ->elaborate_sig(des
, scope
);
329 * A function definition exists within an elaborated module. This
330 * matters when elaborating signals, as the ports of the function are
331 * created as signals/variables for each instance of the
332 * function. That is why PFunction has an elaborate_sig method.
334 void PFunction::elaborate_sig(Design
*des
, NetScope
*scope
) const
336 perm_string fname
= scope
->basename();
337 assert(scope
->type() == NetScope::FUNC
);
339 /* Make sure the function has at least one input port. If it
340 fails this test, print an error message. Keep going so we
341 can find more errors. */
343 cerr
<< get_line() << ": error: Function " << fname
344 << " has no ports." << endl
;
345 cerr
<< get_line() << ": : Functions must have"
346 << " at least one input port." << endl
;
352 /* Create the signals/variables of the return value and write
353 them into the function scope. */
354 switch (return_type_
.type
) {
358 if (return_type_
.range
) {
359 NetExpr
*me
= elab_and_eval(des
, scope
,
360 (*return_type_
.range
)[0], -1);
362 NetExpr
*le
= elab_and_eval(des
, scope
,
363 (*return_type_
.range
)[1], -1);
366 long mnum
= 0, lnum
= 0;
367 if (NetEConst
*tmp
= dynamic_cast<NetEConst
*>(me
)) {
368 mnum
= tmp
->value().as_long();
370 cerr
<< me
->get_line() << ": error: "
371 "Unable to evaluate constant expression "
372 << *me
<< "." << endl
;
376 if (NetEConst
*tmp
= dynamic_cast<NetEConst
*>(le
)) {
377 lnum
= tmp
->value().as_long();
379 cerr
<< le
->get_line() << ": error: "
380 "Unable to evaluate constant expression "
381 << *le
<< "." << endl
;
385 ret_sig
= new NetNet(scope
, fname
, NetNet::REG
, mnum
, lnum
);
388 ret_sig
= new NetNet(scope
, fname
, NetNet::REG
);
390 ret_sig
->set_line(*this);
391 ret_sig
->set_signed(return_type_
.type
== PTF_REG_S
);
392 ret_sig
->port_type(NetNet::POUTPUT
);
393 ret_sig
->data_type(IVL_VT_LOGIC
);
397 ret_sig
= new NetNet(scope
, fname
, NetNet::REG
, integer_width
);
398 ret_sig
->set_line(*this);
399 ret_sig
->set_signed(true);
400 ret_sig
->set_isint(true);
401 ret_sig
->port_type(NetNet::POUTPUT
);
402 ret_sig
->data_type(IVL_VT_LOGIC
);
406 ret_sig
= new NetNet(scope
, fname
, NetNet::REG
, 64);
407 ret_sig
->set_line(*this);
408 ret_sig
->set_signed(false);
409 ret_sig
->set_isint(false);
410 ret_sig
->port_type(NetNet::POUTPUT
);
411 ret_sig
->data_type(IVL_VT_LOGIC
);
416 ret_sig
= new NetNet(scope
, fname
, NetNet::REG
, 1);
417 ret_sig
->set_line(*this);
418 ret_sig
->set_signed(true);
419 ret_sig
->set_isint(false);
420 ret_sig
->port_type(NetNet::POUTPUT
);
421 ret_sig
->data_type(IVL_VT_REAL
);
425 cerr
<< get_line() << ": internal error: I don't know how "
426 << "to deal with return type of function "
427 << scope
->basename() << "." << endl
;
430 svector
<NetNet
*>ports (ports_
? ports_
->count() : 0);
433 for (unsigned idx
= 0 ; idx
< ports_
->count() ; idx
+= 1) {
435 /* Parse the port name into the task name and the reg
436 name. We know by design that the port name is given
437 as two components: <func>.<port>. */
439 pform_name_t path
= (*ports_
)[idx
]->path();
440 ivl_assert(*this, path
.size() == 2);
442 perm_string pname
= peek_tail_name(path
);
443 perm_string ppath
= peek_head_name(path
);
445 if (ppath
!= scope
->basename()) {
446 cerr
<< get_line() << ": internal error: function "
447 << "port " << (*ports_
)[idx
]->path()
448 << " has wrong name for function "
449 << scope_path(scope
) << "." << endl
;
453 NetNet
*tmp
= scope
->find_signal(pname
);
455 cerr
<< get_line() << ": internal error: function "
456 << scope_path(scope
) << " is missing port "
457 << pname
<< "." << endl
;
459 cerr
<< get_line() << ": Continuing..." << endl
;
468 if (ret_sig
) def
= new NetFuncDef(scope
, ret_sig
, ports
);
471 scope
->set_func_def(def
);
475 * A task definition is a scope within an elaborated module. When we
476 * are elaborating signals, the scopes have already been created, as
477 * have the reg objects that are the parameters of this task. The
478 * elaborate_sig method of PTask is therefore left to connect the
479 * signals to the ports of the NetTaskDef definition. We know for
480 * certain that signals exist (They are in my scope!) so the port
481 * binding is sure to work.
483 void PTask::elaborate_sig(Design
*des
, NetScope
*scope
) const
485 assert(scope
->type() == NetScope::TASK
);
487 svector
<NetNet
*>ports (ports_
? ports_
->count() : 0);
488 for (unsigned idx
= 0 ; idx
< ports
.count() ; idx
+= 1) {
490 /* Parse the port name into the task name and the reg
491 name. We know by design that the port name is given
492 as two components: <task>.<port>. */
494 pform_name_t path
= (*ports_
)[idx
]->path();
495 ivl_assert(*this, path
.size() == 2);
497 perm_string scope_name
= peek_head_name(path
);
498 perm_string port_name
= peek_tail_name(path
);
500 /* check that the current scope really does have the
501 name of the first component of the task port name. Do
502 this by looking up the task scope in the parent of
503 the current scope. */
504 ivl_assert(*this, scope
->basename() == scope_name
);
506 /* Find the signal for the port. We know by definition
507 that it is in the scope of the task, so look only in
509 NetNet
*tmp
= scope
->find_signal(port_name
);
512 cerr
<< get_line() << ": internal error: "
513 << "Could not find port " << port_name
514 << " in scope " << scope_path(scope
) << endl
;
521 NetTaskDef
*def
= new NetTaskDef(scope
, ports
);
522 scope
->set_task_def(def
);
525 bool PGate::elaborate_sig(Design
*des
, NetScope
*scope
) const
531 * Elaborate a source wire. The "wire" is the declaration of wires,
532 * registers, ports and memories. The parser has already merged the
533 * multiple properties of a wire (i.e., "input wire") so come the
534 * elaboration this creates an object in the design that represent the
537 NetNet
* PWire::elaborate_sig(Design
*des
, NetScope
*scope
) const
540 /* The parser may produce hierarchical names for wires. I here
541 follow the scopes down to the base where I actually want to
542 elaborate the NetNet object. */
543 { pform_name_t tmp_path
= hname_
;
545 while (! tmp_path
.empty()) {
546 name_component_t cur
= tmp_path
.front();
547 tmp_path
.pop_front();
549 scope
= scope
->child( hname_t(cur
.name
) );
552 cerr
<< get_line() << ": internal error: "
553 << "Bad scope component for name "
560 NetNet::Type wtype
= type_
;
561 if (wtype
== NetNet::IMPLICIT
)
562 wtype
= NetNet::WIRE
;
563 if (wtype
== NetNet::IMPLICIT_REG
)
567 long lsb
= 0, msb
= 0;
569 des
->errors
+= error_cnt_
;
571 if (port_set_
|| net_set_
) {
572 long pmsb
= 0, plsb
= 0, nmsb
= 0, nlsb
= 0;
573 /* If they exist get the port definition MSB and LSB */
574 if (port_set_
&& port_msb_
!= 0) {
575 NetExpr
*texpr
= elab_and_eval(des
, scope
, port_msb_
, -1);
577 if (! eval_as_long(pmsb
, texpr
)) {
578 cerr
<< port_msb_
->get_line() << ": error: "
579 "Unable to evaluate MSB constant expression ``"
580 << *port_msb_
<< "''." << endl
;
587 texpr
= elab_and_eval(des
, scope
, port_lsb_
, -1);
589 if (! eval_as_long(plsb
, texpr
)) {
590 cerr
<< port_lsb_
->get_line() << ": error: "
591 "Unable to evaluate LSB constant expression ``"
592 << *port_lsb_
<< "''." << endl
;
601 if (!port_set_
) assert(port_msb_
== 0 && port_lsb_
== 0);
602 if (port_msb_
== 0) assert(port_lsb_
== 0);
603 if (port_lsb_
== 0) assert(port_msb_
== 0);
605 /* If they exist get the net/etc. definition MSB and LSB */
606 if (net_set_
&& net_msb_
!= 0) {
607 NetExpr
*texpr
= elab_and_eval(des
, scope
, net_msb_
, -1);
609 if (! eval_as_long(nmsb
, texpr
)) {
610 cerr
<< net_msb_
->get_line() << ": error: "
611 "Unable to evaluate MSB constant expression ``"
612 << *net_msb_
<< "''." << endl
;
619 texpr
= elab_and_eval(des
, scope
, net_lsb_
, -1);
621 if (! eval_as_long(nlsb
, texpr
)) {
622 cerr
<< net_lsb_
->get_line() << ": error: "
623 "Unable to evaluate LSB constant expression ``"
624 << *net_lsb_
<< "''." << endl
;
631 if (!net_set_
) assert(net_msb_
== 0 && net_lsb_
== 0);
632 if (net_msb_
== 0) assert(net_lsb_
== 0);
633 if (net_lsb_
== 0) assert(net_msb_
== 0);
635 /* We have a port size error */
636 if (port_set_
&& net_set_
&& (pmsb
!= nmsb
|| plsb
!= nlsb
)) {
638 /* Scalar port with a vector net/etc. definition */
639 if (port_msb_
== 0) {
640 if (!gn_io_range_error_flag
) {
642 << ": warning: Scalar port ``" << hname_
643 << "'' has a vectored net declaration ["
644 << nmsb
<< ":" << nlsb
<< "]." << endl
;
647 << ": error: Scalar port ``" << hname_
648 << "'' has a vectored net declaration ["
649 << nmsb
<< ":" << nlsb
<< "]." << endl
;
655 /* Vectored port with a scalar net/etc. definition */
657 cerr
<< port_msb_
->get_line()
658 << ": error: Vectored port ``"
659 << hname_
<< "'' [" << pmsb
<< ":" << plsb
660 << "] has a scalar net declaration at "
661 << get_line() << "." << endl
;
666 /* Both vectored, but they have different ranges. */
667 if (port_msb_
!= 0 && net_msb_
!= 0) {
668 cerr
<< port_msb_
->get_line()
669 << ": error: Vectored port ``"
670 << hname_
<< "'' [" << pmsb
<< ":" << plsb
671 << "] has a net declaration [" << nmsb
<< ":"
672 << nlsb
<< "] at " << net_msb_
->get_line()
673 << " that does not match." << endl
;
682 wid
= nmsb
- nlsb
+ 1;
684 wid
= nlsb
- nmsb
+ 1;
689 unsigned nattrib
= 0;
690 attrib_list_t
*attrib_list
= evaluate_attributes(attributes
, nattrib
,
695 unsigned array_dimensions
= 0;
697 /* If the ident has idx expressions, then this is a
698 memory. It can only have the idx registers after the msb
699 and lsb expressions are filled. And, if it has one index,
701 if (lidx_
|| ridx_
) {
702 assert(lidx_
&& ridx_
);
704 NetExpr
*lexp
= elab_and_eval(des
, scope
, lidx_
, -1);
705 NetExpr
*rexp
= elab_and_eval(des
, scope
, ridx_
, -1);
707 if ((lexp
== 0) || (rexp
== 0)) {
708 cerr
<< get_line() << ": internal error: There is "
709 << "a problem evaluating indices for ``"
710 << hname_
<< "''." << endl
;
715 NetEConst
*lcon
= dynamic_cast<NetEConst
*> (lexp
);
716 NetEConst
*rcon
= dynamic_cast<NetEConst
*> (rexp
);
718 if ((lcon
== 0) || (rcon
== 0)) {
719 cerr
<< get_line() << ": internal error: The indices "
720 << "are not constant for array ``"
721 << hname_
<< "''." << endl
;
726 verinum lval
= lcon
->value();
727 verinum rval
= rcon
->value();
732 array_dimensions
= 1;
733 array_s0
= lval
.as_long();
734 array_e0
= rval
.as_long();
737 /* If the net type is supply0 or supply1, replace it
738 with a simple wire with a pulldown/pullup with supply
739 strength. In other words, transform:
746 pulldown #(supply0) (foo);
748 This reduces the backend burden, and behaves exactly
752 if (wtype
== NetNet::SUPPLY0
|| wtype
== NetNet::SUPPLY1
) {
753 NetLogic::TYPE pull_type
= (wtype
==NetNet::SUPPLY1
)
755 : NetLogic::PULLDOWN
;
756 pull
= new NetLogic(scope
, scope
->local_symbol(),
758 pull
->set_line(*this);
759 pull
->pin(0).drive0(Link::SUPPLY
);
760 pull
->pin(0).drive1(Link::SUPPLY
);
762 wtype
= NetNet::WIRE
;
764 if (debug_elaborate
) {
765 cerr
<< get_line() << ": debug: "
766 << "Generate a SUPPLY pulldown for the "
767 << "supply0 net." << endl
;
771 perm_string name
= peek_tail_name(hname_
);
772 if (debug_elaborate
) {
773 cerr
<< get_line() << ": debug: Create signal "
774 << wtype
<< " ["<<msb
<<":"<<lsb
<<"] " << name
775 << " in scope " << scope_path(scope
) << endl
;
779 NetNet
*sig
= array_dimensions
> 0
780 ? new NetNet(scope
, name
, wtype
, msb
, lsb
, array_s0
, array_e0
)
781 : new NetNet(scope
, name
, wtype
, msb
, lsb
);
783 ivl_variable_type_t use_data_type
= data_type_
;
784 if (use_data_type
== IVL_VT_NO_TYPE
) {
785 use_data_type
= IVL_VT_LOGIC
;
786 if (debug_elaborate
) {
787 cerr
<< get_line() << ": debug: "
789 << " in scope " << scope_path(scope
)
790 << " defaults to data type " << use_data_type
<< endl
;
794 sig
->data_type(use_data_type
);
795 sig
->set_line(*this);
796 sig
->port_type(port_type_
);
797 sig
->set_signed(get_signed());
798 sig
->set_isint(get_isint());
801 connect(sig
->pin(0), pull
->pin(0));
803 for (unsigned idx
= 0 ; idx
< nattrib
; idx
+= 1)
804 sig
->attribute(attrib_list
[idx
].key
, attrib_list
[idx
].val
);