$finish() now stops at the end of the time step not immediately.
[iverilog.git] / elab_sig.cc
blob788cd7bd9a70f5a5dd0ad55d2944f3d294e37cd7
1 /*
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)
8 * any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 #ifdef HAVE_CVS_IDENT
20 #ident "$Id: elab_sig.cc,v 1.52 2007/06/02 03:42:12 steve Exp $"
21 #endif
23 # include "config.h"
25 # include <iostream>
27 # include "Module.h"
28 # include "PExpr.h"
29 # include "PGate.h"
30 # include "PGenerate.h"
31 # include "PTask.h"
32 # include "PWire.h"
33 # include "compiler.h"
34 # include "netlist.h"
35 # include "netmisc.h"
36 # include "util.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,
45 NetNet*sig)
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.
53 if (pp == 0)
54 continue;
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());
66 assert(pp->expr[cc]);
67 if (pname == name)
68 return true;
72 return false;
75 #if 0
76 static NetNet*find_signal_in_scope(NetScope*scope, const hname_t&path)
78 NetScope*cur = scope;
79 unsigned idx = 0;
81 while (path.peek_name(idx+1)) {
82 cur = cur->child(path.peek_name(idx));
83 if (cur == 0)
84 return 0;
86 idx += 1;
89 return cur->find_signal(path.peek_name(idx));
91 #endif
93 bool Module::elaborate_sig(Design*des, NetScope*scope) const
95 bool flag = true;
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];
101 if (pp == 0)
102 continue;
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;
114 des->errors += 1;
115 continue;
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."
123 << endl;
124 des->errors += 1;
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
140 // has hierarchy.
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;
150 des->errors += 1;
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;
166 des->errors += 1;
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;
177 des->errors += 1;
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
185 // scope in.
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()
200 ; gt != gl.end()
201 ; gt ++ ) {
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);
214 if (scope == 0) {
215 cerr << (*cur).second->get_line() << ": internal error: "
216 << "Child scope for function " << (*cur).first
217 << " missing in " << scope_path(scope) << "." << endl;
218 des->errors += 1;
219 continue;
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) );
235 assert(tscope);
236 (*cur).second->elaborate_sig(des, tscope);
239 return flag;
242 bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
243 Module*rmod) const
245 bool flag = true;
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];
253 assert(my_scope);
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)
260 << endl;
262 assert(my_scope->parent() == scope);
264 if (! rmod->elaborate_sig(des, my_scope))
265 flag = false;
269 return flag;
272 bool PGenerate::elaborate_sig(Design*des, NetScope*container) const
274 bool flag = true;
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)
283 continue;
285 if (debug_elaborate)
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;
292 return 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;
305 if (debug_elaborate)
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);
318 return true;
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. */
336 if (ports_ == 0) {
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;
341 des->errors += 1;
344 NetNet*ret_sig = 0;
346 /* Create the signals/variables of the return value and write
347 them into the function scope. */
348 switch (return_type_.type) {
350 case PTF_REG:
351 case PTF_REG_S:
352 if (return_type_.range) {
353 NetExpr*me = elab_and_eval(des, scope,
354 (*return_type_.range)[0], -1);
355 assert(me);
356 NetExpr*le = elab_and_eval(des, scope,
357 (*return_type_.range)[1], -1);
358 assert(le);
360 long mnum = 0, lnum = 0;
361 if (NetEConst*tmp = dynamic_cast<NetEConst*>(me)) {
362 mnum = tmp->value().as_long();
363 } else {
364 cerr << me->get_line() << ": error: "
365 "Unable to evaluate constant expression "
366 << *me << "." << endl;
367 des->errors += 1;
370 if (NetEConst*tmp = dynamic_cast<NetEConst*>(le)) {
371 lnum = tmp->value().as_long();
372 } else {
373 cerr << le->get_line() << ": error: "
374 "Unable to evaluate constant expression "
375 << *le << "." << endl;
376 des->errors += 1;
379 ret_sig = new NetNet(scope, fname, NetNet::REG, mnum, lnum);
381 } else {
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);
388 break;
390 case PTF_INTEGER:
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);
397 break;
399 case PTF_TIME:
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);
406 break;
408 case PTF_REAL:
409 case PTF_REALTIME:
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);
416 break;
418 default:
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);
426 if (ports_)
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;
444 des->errors += 1;
447 NetNet*tmp = scope->find_signal(pname);
448 if (tmp == 0) {
449 cerr << get_line() << ": internal error: function "
450 << scope_path(scope) << " is missing port "
451 << pname << "." << endl;
452 scope->dump(cerr);
453 cerr << get_line() << ": Continuing..." << endl;
454 des->errors += 1;
457 ports[idx] = tmp;
461 NetFuncDef*def = 0;
462 if (ret_sig) def = new NetFuncDef(scope, ret_sig, ports);
464 assert(def);
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
502 the scope. */
503 NetNet*tmp = scope->find_signal(port_name);
505 if (tmp == 0) {
506 cerr << get_line() << ": internal error: "
507 << "Could not find port " << port_name
508 << " in scope " << scope_path(scope) << endl;
509 scope->dump(cerr);
512 ports[idx] = tmp;
515 NetTaskDef*def = new NetTaskDef(scope, ports);
516 scope->set_task_def(def);
519 bool PGate::elaborate_sig(Design*des, NetScope*scope) const
521 return true;
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
529 * defined item.
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_;
538 tmp_path.pop_back();
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) );
545 if (scope == 0) {
546 cerr << get_line() << ": internal error: "
547 << "Bad scope component for name "
548 << hname_ << endl;
549 assert(scope);
554 NetNet::Type wtype = type_;
555 if (wtype == NetNet::IMPLICIT)
556 wtype = NetNet::WIRE;
557 if (wtype == NetNet::IMPLICIT_REG)
558 wtype = NetNet::REG;
560 unsigned wid = 1;
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;
575 des->errors += 1;
576 return 0;
579 delete texpr;
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;
587 des->errors += 1;
588 return 0;
591 delete texpr;
592 nmsb = pmsb;
593 nlsb = plsb;
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;
607 des->errors += 1;
608 return 0;
611 delete texpr;
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;
619 des->errors += 1;
620 return 0;
623 delete texpr;
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) {
635 cerr << get_line()
636 << ": warning: Scalar port ``" << hname_
637 << "'' has a vectored net declaration ["
638 << nmsb << ":" << nlsb << "]." << endl;
639 } else {
640 cerr << get_line()
641 << ": error: Scalar port ``" << hname_
642 << "'' has a vectored net declaration ["
643 << nmsb << ":" << nlsb << "]." << endl;
644 des->errors += 1;
645 return 0;
649 /* Vectored port with a scalar net/etc. definition */
650 if (net_msb_ == 0) {
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;
656 des->errors += 1;
657 return 0;
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;
668 des->errors += 1;
669 return 0;
673 lsb = nlsb;
674 msb = nmsb;
675 if (nmsb > nlsb)
676 wid = nmsb - nlsb + 1;
677 else
678 wid = nlsb - nmsb + 1;
683 unsigned nattrib = 0;
684 attrib_list_t*attrib_list = evaluate_attributes(attributes, nattrib,
685 des, scope);
687 long array_s0 = 0;
688 long array_e0 = 0;
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,
694 it has both. */
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;
705 des->errors += 1;
706 return 0;
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;
716 des->errors += 1;
717 return 0;
720 verinum lval = lcon->value();
721 verinum rval = rcon->value();
723 delete lexp;
724 delete rexp;
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:
735 supply0 foo;
739 wire foo;
740 pulldown #(supply0) (foo);
742 This reduces the backend burden, and behaves exactly
743 the same. */
745 NetLogic*pull = 0;
746 if (wtype == NetNet::SUPPLY0 || wtype == NetNet::SUPPLY1) {
747 NetLogic::TYPE pull_type = (wtype==NetNet::SUPPLY1)
748 ? NetLogic::PULLUP
749 : NetLogic::PULLDOWN;
750 pull = new NetLogic(scope, scope->local_symbol(),
751 1, pull_type, wid);
752 pull->set_line(*this);
753 pull->pin(0).drive0(Link::SUPPLY);
754 pull->pin(0).drive1(Link::SUPPLY);
755 des->add_node(pull);
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: "
782 << "Signal " << name
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());
794 if (pull)
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);
800 return sig;