Merge branch 'master' into verilog-ams
[sverilog.git] / elab_sig.cc
blob371f1759aa3c4ae14e8e690927d34c4c79b8853d
1 /*
2 * Copyright (c) 2000-2008 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
20 # include "config.h"
22 # include <cstdlib>
23 # include <iostream>
25 # include "Module.h"
26 # include "PExpr.h"
27 # include "PGate.h"
28 # include "PGenerate.h"
29 # include "PTask.h"
30 # include "PWire.h"
31 # include "Statement.h"
32 # include "compiler.h"
33 # include "netlist.h"
34 # include "netmisc.h"
35 # include "util.h"
36 # include "ivl_assert.h"
38 static bool get_const_argument(NetExpr*exp, verinum&res)
40 switch (exp->expr_type()) {
41 case IVL_VT_REAL: {
42 NetECReal*cv = dynamic_cast<NetECReal*>(exp);
43 if (cv == 0) return false;
44 verireal tmp = cv->value();
45 res = verinum(tmp.as_long());
46 break;
49 case IVL_VT_BOOL:
50 case IVL_VT_LOGIC: {
51 NetEConst*cv = dynamic_cast<NetEConst*>(exp);
52 if (cv == 0) return false;
53 res = cv->value();
54 break;
57 default:
58 assert(0);;
61 return true;
64 void Statement::elaborate_sig(Design*des, NetScope*scope) const
68 bool PScope::elaborate_sig_wires_(Design*des, NetScope*scope) const
70 bool flag = true;
72 for (map<perm_string,PWire*>::const_iterator wt = wires.begin()
73 ; wt != wires.end() ; wt ++ ) {
75 PWire*cur = (*wt).second;
76 NetNet*sig = cur->elaborate_sig(des, scope);
79 /* If the signal is an input and is also declared as a
80 reg, then report an error. */
82 if (sig && (sig->scope() == scope)
83 && (scope->type() == NetScope::MODULE)
84 && (sig->port_type() == NetNet::PINPUT)
85 && (sig->type() == NetNet::REG)) {
87 cerr << cur->get_fileline() << ": error: "
88 << cur->basename() << " in "
89 << scope->module_name()
90 << " declared as input and as a reg type." << endl;
91 des->errors += 1;
94 if (sig && (sig->scope() == scope)
95 && (scope->type() == NetScope::MODULE)
96 && (sig->port_type() == NetNet::PINOUT)
97 && (sig->type() == NetNet::REG)) {
99 cerr << cur->get_fileline() << ": error: "
100 << cur->basename() << " in "
101 << scope->module_name()
102 << " declared as inout and as a reg type." << endl;
103 des->errors += 1;
108 return flag;
111 bool Module::elaborate_sig(Design*des, NetScope*scope) const
113 bool flag = true;
115 // Scan all the ports of the module, and make sure that each
116 // is connected to wires that have port declarations.
117 for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
118 Module::port_t*pp = ports[idx];
119 if (pp == 0)
120 continue;
122 // The port has a name and an array of expressions. The
123 // expression are all identifiers that should reference
124 // wires within the scope.
125 map<perm_string,PWire*>::const_iterator wt;
126 for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
127 pform_name_t port_path (pp->expr[cc]->path());
128 // A concatenated wire of a port really should not
129 // have any hierarchy.
130 if (port_path.size() != 1) {
131 cerr << get_fileline() << ": internal error: "
132 << "Port " << port_path << " has a funny name?"
133 << endl;
134 des->errors += 1;
137 wt = wires.find(peek_tail_name(port_path));
139 if (wt == wires.end()) {
140 cerr << get_fileline() << ": error: "
141 << "Port " << port_path << " ("
142 << (idx+1) << ") of module " << mod_name()
143 << " is not declared within module." << endl;
144 des->errors += 1;
145 continue;
148 if ((*wt).second->get_port_type() == NetNet::NOT_A_PORT) {
149 cerr << get_fileline() << ": error: "
150 << "Port " << pp->expr[cc]->path() << " ("
151 << (idx+1) << ") of module " << mod_name()
152 << " has no direction declaration."
153 << endl;
154 des->errors += 1;
159 flag = elaborate_sig_wires_(des, scope) && flag;
161 // Run through all the generate schemes to elaborate the
162 // signals that they hold. Note that the generate schemes hold
163 // the scopes that they instantiated, so we don't pass any
164 // scope in.
165 typedef list<PGenerate*>::const_iterator generate_it_t;
166 for (generate_it_t cur = generate_schemes.begin()
167 ; cur != generate_schemes.end() ; cur ++ ) {
168 (*cur) -> elaborate_sig(des, scope);
171 // Get all the gates of the module and elaborate them by
172 // connecting them to the signals. The gate may be simple or
173 // complex. What we are looking for is gates that are modules
174 // that can create scopes and signals.
176 const list<PGate*>&gl = get_gates();
178 for (list<PGate*>::const_iterator gt = gl.begin()
179 ; gt != gl.end()
180 ; gt ++ ) {
182 flag &= (*gt)->elaborate_sig(des, scope);
186 typedef map<perm_string,PFunction*>::const_iterator mfunc_it_t;
188 for (mfunc_it_t cur = funcs_.begin()
189 ; cur != funcs_.end() ; cur ++) {
191 hname_t use_name ( (*cur).first );
192 NetScope*fscope = scope->child(use_name);
193 if (scope == 0) {
194 cerr << (*cur).second->get_fileline() << ": internal error: "
195 << "Child scope for function " << (*cur).first
196 << " missing in " << scope_path(scope) << "." << endl;
197 des->errors += 1;
198 continue;
201 (*cur).second->elaborate_sig(des, fscope);
205 // After all the wires are elaborated, we are free to
206 // elaborate the ports of the tasks defined within this
207 // module. Run through them now.
209 typedef map<perm_string,PTask*>::const_iterator mtask_it_t;
211 for (mtask_it_t cur = tasks_.begin()
212 ; cur != tasks_.end() ; cur ++) {
213 NetScope*tscope = scope->child( hname_t((*cur).first) );
214 assert(tscope);
215 (*cur).second->elaborate_sig(des, tscope);
218 // initial and always blocks may contain begin-end and
219 // fork-join blocks that can introduce scopes. Therefore, I
220 // get to scan processes here.
222 typedef list<PProcess*>::const_iterator proc_it_t;
224 for (proc_it_t cur = behaviors.begin()
225 ; cur != behaviors.end() ; cur ++ ) {
227 (*cur) -> statement() -> elaborate_sig(des, scope);
230 return flag;
233 bool PExpr::elaborate_sig(Design*des, NetScope*scope) const
235 return true;
238 bool PEConcat::elaborate_sig(Design*des, NetScope*scope) const
240 bool flag = true;
241 for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
242 flag = parms_[idx]->elaborate_sig(des, scope) && flag;
244 return flag;
247 bool PEIdent::elaborate_sig(Design*des, NetScope*scope) const
249 NetNet* sig = 0;
250 const NetExpr*par = 0;
251 NetEvent* eve = 0;
253 // If implicit net creation is turned off, then stop now.
254 if (scope->default_nettype() == NetNet::NONE)
255 return true;
256 if (error_implicit)
257 return true;
259 symbol_search(des, scope, path_, sig, par, eve);
261 if (eve != 0)
262 return false;
264 if (par != 0)
265 return true;
267 if (sig == 0)
268 sig = make_implicit_net_(des, scope);
270 return sig != 0;
273 bool PEBinary::elaborate_sig(Design*des, NetScope*scope) const
275 bool flag = true;
277 flag = left_->elaborate_sig(des, scope) && flag;
278 flag = right_->elaborate_sig(des, scope) && flag;
279 return flag;
282 bool PETernary::elaborate_sig(Design*des, NetScope*scope) const
284 bool flag = true;
285 flag = tru_->elaborate_sig(des, scope) && flag;
286 flag = fal_->elaborate_sig(des, scope) && flag;
287 return flag;
290 bool PEUnary::elaborate_sig(Design*des, NetScope*scope) const
292 return expr_->elaborate_sig(des, scope);
295 bool PGate::elaborate_sig(Design*des, NetScope*scope) const
297 return true;
300 bool PGBuiltin::elaborate_sig(Design*des, NetScope*scope) const
302 bool flag = true;
304 for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
305 const PExpr* pin_expr = pin(idx);
306 if (pin_expr == 0) {
307 // If there is no pin expression for this port,
308 // then skip it. Do not bother generating an error
309 // message here, that will be done during
310 // elaboration where these semantic details are tested.
311 continue;
313 ivl_assert(*this, pin_expr);
314 flag = pin_expr->elaborate_sig(des, scope) && flag;
317 return flag;
320 bool PGAssign::elaborate_sig(Design*des, NetScope*scope) const
322 /* Normally, l-values to continuous assignments are NOT allowed
323 to implicitly declare nets. However, so many tools do allow
324 it that Icarus Verilog will allow it, at least if extensions
325 are enabled. */
326 if (gn_icarus_misc_flag)
327 return pin(0)->elaborate_sig(des, scope);
329 return true;
332 bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
333 Module*rmod) const
335 bool flag = true;
337 // First, elaborate the signals that may be created implicitly
338 // by ports to this module instantiation. Handle the case that
339 // the ports are passed by name (pins_ != 0) or position.
340 if (pins_)
341 for (unsigned idx = 0 ; idx < npins_ ; idx += 1) {
342 const PExpr*tmp = pins_[idx].parm;
343 if (tmp == 0)
344 continue;
345 flag = tmp->elaborate_sig(des, scope) && flag;
347 else
348 for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
349 const PExpr*tmp = pin(idx);
350 if (tmp == 0)
351 continue;
352 flag = tmp->elaborate_sig(des, scope) && flag;
356 NetScope::scope_vec_t instance = scope->instance_arrays[get_name()];
358 for (unsigned idx = 0 ; idx < instance.count() ; idx += 1) {
359 // I know a priori that the elaborate_scope created the scope
360 // already, so just look it up as a child of the current scope.
361 NetScope*my_scope = instance[idx];
362 assert(my_scope);
364 if (my_scope->parent() != scope) {
365 cerr << get_fileline() << ": internal error: "
366 << "Instance " << scope_path(my_scope)
367 << " is in parent " << scope_path(my_scope->parent())
368 << " instead of " << scope_path(scope)
369 << endl;
371 assert(my_scope->parent() == scope);
373 if (! rmod->elaborate_sig(des, my_scope))
374 flag = false;
378 return flag;
381 bool PGModule::elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const
383 bool flag = true;
385 if (pins_)
386 for (unsigned idx = 0 ; idx < npins_ ; idx += 1) {
387 const PExpr*tmp = pins_[idx].parm;
388 if (tmp == 0)
389 continue;
390 flag = tmp->elaborate_sig(des, scope) && flag;
392 else
393 for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
394 const PExpr*tmp = pin(idx);
395 if (tmp == 0)
396 continue;
397 flag = tmp->elaborate_sig(des, scope) && flag;
400 return flag;
403 bool PGenerate::elaborate_sig(Design*des, NetScope*container) const
405 bool flag = true;
407 // Handle the special case that this is a CASE scheme. In this
408 // case the PGenerate itself does not have the generated
409 // item. Look instead for the case ITEM that has a scope
410 // generated for it.
411 if (scheme_type == PGenerate::GS_CASE) {
412 if (debug_elaborate)
413 cerr << get_fileline() << ": debug: generate case"
414 << " elaborate_sig in scope "
415 << scope_path(container) << "." << endl;
417 typedef list<PGenerate*>::const_iterator generate_it_t;
418 for (generate_it_t cur = generates.begin()
419 ; cur != generates.end() ; cur ++) {
420 PGenerate*item = *cur;
421 if (! item->scope_list_.empty()) {
422 flag &= item->elaborate_sig(des, container);
425 return flag;
428 typedef list<NetScope*>::const_iterator scope_list_it_t;
429 for (scope_list_it_t cur = scope_list_.begin()
430 ; cur != scope_list_.end() ; cur ++ ) {
432 NetScope*scope = *cur;
434 if (scope->parent() != container)
435 continue;
437 if (debug_elaborate)
438 cerr << get_fileline() << ": debug: Elaborate nets in "
439 << "scope " << scope_path(*cur)
440 << " in generate " << id_number << endl;
441 flag = elaborate_sig_(des, *cur) & flag;
444 return flag;
447 bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
449 // Scan the declared PWires to elaborate the obvious signals
450 // in the current scope.
451 typedef map<perm_string,PWire*>::const_iterator wires_it_t;
452 for (wires_it_t wt = wires.begin()
453 ; wt != wires.end() ; wt ++ ) {
455 PWire*cur = (*wt).second;
457 if (debug_elaborate)
458 cerr << get_fileline() << ": debug: Elaborate PWire "
459 << cur->basename() << " in scope " << scope_path(scope) << endl;
461 cur->elaborate_sig(des, scope);
464 typedef list<PGenerate*>::const_iterator generate_it_t;
465 for (generate_it_t cur = generates.begin()
466 ; cur != generates.end() ; cur ++ ) {
467 (*cur) -> elaborate_sig(des, scope);
470 typedef list<PGate*>::const_iterator pgate_list_it_t;
471 for (pgate_list_it_t cur = gates.begin()
472 ; cur != gates.end() ; cur ++) {
473 (*cur) ->elaborate_sig(des, scope);
476 return true;
481 * A function definition exists within an elaborated module. This
482 * matters when elaborating signals, as the ports of the function are
483 * created as signals/variables for each instance of the
484 * function. That is why PFunction has an elaborate_sig method.
486 void PFunction::elaborate_sig(Design*des, NetScope*scope) const
488 perm_string fname = scope->basename();
489 assert(scope->type() == NetScope::FUNC);
491 elaborate_sig_wires_(des, scope);
493 /* Make sure the function has at least one input port. If it
494 fails this test, print an error message. Keep going so we
495 can find more errors. */
496 if (ports_ == 0) {
497 cerr << get_fileline() << ": error: Function " << fname
498 << " has no ports." << endl;
499 cerr << get_fileline() << ": : Functions must have"
500 << " at least one input port." << endl;
501 des->errors += 1;
504 NetNet*ret_sig = 0;
506 /* Create the signals/variables of the return value and write
507 them into the function scope. */
508 switch (return_type_.type) {
510 case PTF_REG:
511 case PTF_REG_S:
512 if (return_type_.range) {
513 NetExpr*me = elab_and_eval(des, scope,
514 (*return_type_.range)[0], -1);
515 assert(me);
516 NetExpr*le = elab_and_eval(des, scope,
517 (*return_type_.range)[1], -1);
518 assert(le);
520 long mnum = 0, lnum = 0;
521 if (NetEConst*tmp = dynamic_cast<NetEConst*>(me)) {
522 mnum = tmp->value().as_long();
523 } else {
524 cerr << me->get_fileline() << ": error: "
525 "Unable to evaluate constant expression "
526 << *me << "." << endl;
527 des->errors += 1;
530 if (NetEConst*tmp = dynamic_cast<NetEConst*>(le)) {
531 lnum = tmp->value().as_long();
532 } else {
533 cerr << le->get_fileline() << ": error: "
534 "Unable to evaluate constant expression "
535 << *le << "." << endl;
536 des->errors += 1;
539 ret_sig = new NetNet(scope, fname, NetNet::REG, mnum, lnum);
541 } else {
542 ret_sig = new NetNet(scope, fname, NetNet::REG);
544 ret_sig->set_line(*this);
545 ret_sig->set_signed(return_type_.type == PTF_REG_S);
546 ret_sig->port_type(NetNet::POUTPUT);
547 ret_sig->data_type(IVL_VT_LOGIC);
548 break;
550 case PTF_INTEGER:
551 ret_sig = new NetNet(scope, fname, NetNet::REG, integer_width);
552 ret_sig->set_line(*this);
553 ret_sig->set_signed(true);
554 ret_sig->set_isint(true);
555 ret_sig->port_type(NetNet::POUTPUT);
556 ret_sig->data_type(IVL_VT_LOGIC);
557 break;
559 case PTF_TIME:
560 ret_sig = new NetNet(scope, fname, NetNet::REG, 64);
561 ret_sig->set_line(*this);
562 ret_sig->set_signed(false);
563 ret_sig->set_isint(false);
564 ret_sig->port_type(NetNet::POUTPUT);
565 ret_sig->data_type(IVL_VT_LOGIC);
566 break;
568 case PTF_REAL:
569 case PTF_REALTIME:
570 ret_sig = new NetNet(scope, fname, NetNet::REG, 1);
571 ret_sig->set_line(*this);
572 ret_sig->set_signed(true);
573 ret_sig->set_isint(false);
574 ret_sig->port_type(NetNet::POUTPUT);
575 ret_sig->data_type(IVL_VT_REAL);
576 break;
578 default:
579 cerr << get_fileline() << ": internal error: I don't know how "
580 << "to deal with return type of function "
581 << scope->basename() << "." << endl;
584 svector<NetNet*>ports (ports_? ports_->count() : 0);
586 if (ports_)
587 for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
589 /* Parse the port name into the task name and the reg
590 name. We know by design that the port name is given
591 as two components: <func>.<port>. */
593 perm_string pname = (*ports_)[idx]->basename();
595 NetNet*tmp = scope->find_signal(pname);
596 ports[idx] = 0;
598 if (tmp == 0) {
599 cerr << get_fileline() << ": internal error: function "
600 << scope_path(scope) << " is missing port "
601 << pname << "." << endl;
602 scope->dump(cerr);
603 cerr << get_fileline() << ": Continuing..." << endl;
604 des->errors += 1;
605 continue;
608 if (tmp->port_type() == NetNet::NOT_A_PORT) {
609 cerr << get_fileline() << ": internal error: function "
610 << scope_path(scope) << " port " << pname
611 << " is a port but is not a port?" << endl;
612 des->errors += 1;
613 scope->dump(cerr);
614 continue;
617 ports[idx] = tmp;
618 if (tmp->port_type() != NetNet::PINPUT) {
619 cerr << tmp->get_fileline() << ": error: function "
620 << scope_path(scope) << " port " << pname
621 << " is not an input port." << endl;
622 cerr << tmp->get_fileline() << ": : Function arguments "
623 << "must be input ports." << endl;
624 des->errors += 1;
629 NetFuncDef*def = 0;
630 if (ret_sig) def = new NetFuncDef(scope, ret_sig, ports);
632 assert(def);
633 if (debug_elaborate)
634 cerr << get_fileline() << ": debug: "
635 << "Attach function definition to scope "
636 << scope_path(scope) << "." << endl;
638 scope->set_func_def(def);
640 // Look for further signals in the sub-statement
641 if (statement_)
642 statement_->elaborate_sig(des, scope);
646 * A task definition is a scope within an elaborated module. When we
647 * are elaborating signals, the scopes have already been created, as
648 * have the reg objects that are the parameters of this task. The
649 * elaborate_sig method of PTask is therefore left to connect the
650 * signals to the ports of the NetTaskDef definition. We know for
651 * certain that signals exist (They are in my scope!) so the port
652 * binding is sure to work.
654 void PTask::elaborate_sig(Design*des, NetScope*scope) const
656 assert(scope->type() == NetScope::TASK);
658 elaborate_sig_wires_(des, scope);
660 svector<NetNet*>ports (ports_? ports_->count() : 0);
661 for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
663 perm_string port_name = (*ports_)[idx]->basename();
665 /* Find the signal for the port. We know by definition
666 that it is in the scope of the task, so look only in
667 the scope. */
668 NetNet*tmp = scope->find_signal(port_name);
670 if (tmp == 0) {
671 cerr << get_fileline() << ": internal error: "
672 << "Could not find port " << port_name
673 << " in scope " << scope_path(scope) << endl;
674 scope->dump(cerr);
675 des->errors += 1;
678 ports[idx] = tmp;
681 NetTaskDef*def = new NetTaskDef(scope, ports);
682 scope->set_task_def(def);
684 // Look for further signals in the sub-statement
685 if (statement_)
686 statement_->elaborate_sig(des, scope);
689 void PBlock::elaborate_sig(Design*des, NetScope*scope) const
691 NetScope*my_scope = scope;
693 if (pscope_name() != 0) {
694 hname_t use_name (pscope_name());
695 my_scope = scope->child(use_name);
696 if (my_scope == 0) {
697 cerr << get_fileline() << ": internal error: "
698 << "Unable to find child scope " << pscope_name()
699 << " in this context?" << endl;
700 des->errors += 1;
701 my_scope = scope;
702 } else {
703 if (debug_elaborate)
704 cerr << get_fileline() << ": debug: "
705 << "elaborate_sig descending into "
706 << scope_path(my_scope) << "." << endl;
708 elaborate_sig_wires_(des, my_scope);
712 // elaborate_sig in the statements included in the
713 // block. There may be named blocks in there.
714 for (unsigned idx = 0 ; idx < list_.count() ; idx += 1)
715 list_[idx] -> elaborate_sig(des, my_scope);
718 void PCase::elaborate_sig(Design*des, NetScope*scope) const
720 if (items_ == 0)
721 return;
723 for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) {
724 if ( (*items_)[idx]->stat )
725 (*items_)[idx]->stat ->elaborate_sig(des,scope);
729 void PCondit::elaborate_sig(Design*des, NetScope*scope) const
731 if (if_)
732 if_->elaborate_sig(des, scope);
733 if (else_)
734 else_->elaborate_sig(des, scope);
737 void PDelayStatement::elaborate_sig(Design*des, NetScope*scope) const
739 if (statement_)
740 statement_->elaborate_sig(des, scope);
743 void PEventStatement::elaborate_sig(Design*des, NetScope*scope) const
745 if (statement_)
746 statement_->elaborate_sig(des, scope);
749 void PForever::elaborate_sig(Design*des, NetScope*scope) const
751 if (statement_)
752 statement_->elaborate_sig(des, scope);
755 void PForStatement::elaborate_sig(Design*des, NetScope*scope) const
757 if (statement_)
758 statement_->elaborate_sig(des, scope);
761 void PRepeat::elaborate_sig(Design*des, NetScope*scope) const
763 if (statement_)
764 statement_->elaborate_sig(des, scope);
767 void PWhile::elaborate_sig(Design*des, NetScope*scope) const
769 if (statement_)
770 statement_->elaborate_sig(des, scope);
774 * Elaborate a source wire. The "wire" is the declaration of wires,
775 * registers, ports and memories. The parser has already merged the
776 * multiple properties of a wire (i.e., "input wire") so come the
777 * elaboration this creates an object in the design that represent the
778 * defined item.
780 NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
782 NetNet::Type wtype = type_;
783 if (wtype == NetNet::IMPLICIT)
784 wtype = NetNet::WIRE;
785 if (wtype == NetNet::IMPLICIT_REG)
786 wtype = NetNet::REG;
788 unsigned wid = 1;
789 long lsb = 0, msb = 0;
791 des->errors += error_cnt_;
793 if (port_set_ || net_set_) {
794 long pmsb = 0, plsb = 0, nmsb = 0, nlsb = 0;
795 /* If they exist get the port definition MSB and LSB */
796 if (port_set_ && port_msb_ != 0) {
797 NetExpr*texpr = elab_and_eval(des, scope, port_msb_, -1);
799 if (! eval_as_long(pmsb, texpr)) {
800 cerr << port_msb_->get_fileline() << ": error: "
801 "Unable to evaluate MSB constant expression ``"
802 << *port_msb_ << "''." << endl;
803 des->errors += 1;
804 return 0;
807 delete texpr;
809 texpr = elab_and_eval(des, scope, port_lsb_, -1);
811 if (! eval_as_long(plsb, texpr)) {
812 cerr << port_lsb_->get_fileline() << ": error: "
813 "Unable to evaluate LSB constant expression ``"
814 << *port_lsb_ << "''." << endl;
815 des->errors += 1;
816 return 0;
819 delete texpr;
820 nmsb = pmsb;
821 nlsb = plsb;
823 if (!port_set_) assert(port_msb_ == 0 && port_lsb_ == 0);
824 if (port_msb_ == 0) assert(port_lsb_ == 0);
825 if (port_lsb_ == 0) assert(port_msb_ == 0);
827 /* If they exist get the net/etc. definition MSB and LSB */
828 if (net_set_ && net_msb_ != 0) {
829 NetExpr*texpr = elab_and_eval(des, scope, net_msb_, -1);
831 if (! eval_as_long(nmsb, texpr)) {
832 cerr << net_msb_->get_fileline() << ": error: "
833 "Unable to evaluate MSB constant expression ``"
834 << *net_msb_ << "''." << endl;
835 des->errors += 1;
836 return 0;
839 delete texpr;
841 texpr = elab_and_eval(des, scope, net_lsb_, -1);
843 if (! eval_as_long(nlsb, texpr)) {
844 cerr << net_lsb_->get_fileline() << ": error: "
845 "Unable to evaluate LSB constant expression ``"
846 << *net_lsb_ << "''." << endl;
847 des->errors += 1;
848 return 0;
851 delete texpr;
853 if (!net_set_) assert(net_msb_ == 0 && net_lsb_ == 0);
854 if (net_msb_ == 0) assert(net_lsb_ == 0);
855 if (net_lsb_ == 0) assert(net_msb_ == 0);
857 /* We have a port size error */
858 if (port_set_ && net_set_ && (pmsb != nmsb || plsb != nlsb)) {
860 /* Scalar port with a vector net/etc. definition */
861 if (port_msb_ == 0) {
862 if (!gn_io_range_error_flag) {
863 cerr << get_fileline()
864 << ": warning: Scalar port ``" << name_
865 << "'' has a vectored net declaration ["
866 << nmsb << ":" << nlsb << "]." << endl;
867 } else {
868 cerr << get_fileline()
869 << ": error: Scalar port ``" << name_
870 << "'' has a vectored net declaration ["
871 << nmsb << ":" << nlsb << "]." << endl;
872 des->errors += 1;
873 return 0;
877 /* Vectored port with a scalar net/etc. definition */
878 if (net_msb_ == 0) {
879 cerr << port_msb_->get_fileline()
880 << ": error: Vectored port ``"
881 << name_ << "'' [" << pmsb << ":" << plsb
882 << "] has a scalar net declaration at "
883 << get_fileline() << "." << endl;
884 des->errors += 1;
885 return 0;
888 /* Both vectored, but they have different ranges. */
889 if (port_msb_ != 0 && net_msb_ != 0) {
890 cerr << port_msb_->get_fileline()
891 << ": error: Vectored port ``"
892 << name_ << "'' [" << pmsb << ":" << plsb
893 << "] has a net declaration [" << nmsb << ":"
894 << nlsb << "] at " << net_msb_->get_fileline()
895 << " that does not match." << endl;
896 des->errors += 1;
897 return 0;
901 lsb = nlsb;
902 msb = nmsb;
903 if (nmsb > nlsb)
904 wid = nmsb - nlsb + 1;
905 else
906 wid = nlsb - nmsb + 1;
911 unsigned nattrib = 0;
912 attrib_list_t*attrib_list = evaluate_attributes(attributes, nattrib,
913 des, scope);
915 long array_s0 = 0;
916 long array_e0 = 0;
917 unsigned array_dimensions = 0;
919 /* If the ident has idx expressions, then this is a
920 memory. It can only have the idx registers after the msb
921 and lsb expressions are filled. And, if it has one index,
922 it has both. */
923 if (lidx_ || ridx_) {
924 assert(lidx_ && ridx_);
926 NetExpr*lexp = elab_and_eval(des, scope, lidx_, -1);
927 NetExpr*rexp = elab_and_eval(des, scope, ridx_, -1);
929 if ((lexp == 0) || (rexp == 0)) {
930 cerr << get_fileline() << ": internal error: There is "
931 << "a problem evaluating indices for ``"
932 << name_ << "''." << endl;
933 des->errors += 1;
934 return 0;
937 bool const_flag = true;
938 verinum lval, rval;
939 const_flag &= get_const_argument(lexp, lval);
940 const_flag &= get_const_argument(rexp, rval);
941 delete rexp;
942 delete lexp;
944 if (!const_flag) {
945 cerr << get_fileline() << ": internal error: The indices "
946 << "are not constant for array ``"
947 << name_ << "''." << endl;
948 des->errors += 1;
949 return 0;
952 array_dimensions = 1;
953 array_s0 = lval.as_long();
954 array_e0 = rval.as_long();
957 /* If the net type is supply0 or supply1, replace it
958 with a simple wire with a pulldown/pullup with supply
959 strength. In other words, transform:
961 supply0 foo;
965 wire foo;
966 pulldown #(supply0) (foo);
968 This reduces the backend burden, and behaves exactly
969 the same. */
971 NetLogic*pull = 0;
972 if (wtype == NetNet::SUPPLY0 || wtype == NetNet::SUPPLY1) {
973 NetLogic::TYPE pull_type = (wtype==NetNet::SUPPLY1)
974 ? NetLogic::PULLUP
975 : NetLogic::PULLDOWN;
976 pull = new NetLogic(scope, scope->local_symbol(),
977 1, pull_type, wid);
978 pull->set_line(*this);
979 pull->pin(0).drive0(Link::SUPPLY);
980 pull->pin(0).drive1(Link::SUPPLY);
981 des->add_node(pull);
982 wtype = NetNet::WIRE;
984 if (debug_elaborate) {
985 cerr << get_fileline() << ": debug: "
986 << "Generate a SUPPLY pulldown for the "
987 << "supply0 net." << endl;
991 if (debug_elaborate) {
992 cerr << get_fileline() << ": debug: Create signal "
993 << wtype << " ["<<msb<<":"<<lsb<<"] " << name_
994 << " in scope " << scope_path(scope) << endl;
998 NetNet*sig = array_dimensions > 0
999 ? new NetNet(scope, name_, wtype, msb, lsb, array_s0, array_e0)
1000 : new NetNet(scope, name_, wtype, msb, lsb);
1002 ivl_variable_type_t use_data_type = data_type_;
1003 if (use_data_type == IVL_VT_NO_TYPE) {
1004 use_data_type = IVL_VT_LOGIC;
1005 if (debug_elaborate) {
1006 cerr << get_fileline() << ": debug: "
1007 << "Signal " << name_
1008 << " in scope " << scope_path(scope)
1009 << " defaults to data type " << use_data_type << endl;
1013 sig->data_type(use_data_type);
1014 sig->set_line(*this);
1015 sig->port_type(port_type_);
1016 sig->set_signed(get_signed());
1017 sig->set_isint(get_isint());
1019 if (pull)
1020 connect(sig->pin(0), pull->pin(0));
1022 for (unsigned idx = 0 ; idx < nattrib ; idx += 1)
1023 sig->attribute(attrib_list[idx].key, attrib_list[idx].val);
1025 return sig;