Merge branch 'master' into verilog-ams
[sverilog.git] / elab_anet.cc
blob35bc2cf6880ed869739887d4939f61c426383ba7
1 /*
2 * Copyright (c) 2000-2003 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_anet.cc,v 1.13 2007/03/22 16:08:14 steve Exp $"
21 #endif
23 # include "config.h"
26 * The elaborate_anet methods elaborate expressions that are intended
27 * to be the left side of procedural continuous assignments.
30 # include "PExpr.h"
31 # include "netlist.h"
32 # include "netmisc.h"
33 # include <iostream>
35 NetNet* PExpr::elaborate_anet(Design*des, NetScope*scope) const
37 cerr << get_line() << ": error: Invalid expression on left side "
38 << "of procedural continuous assignment." << endl;
39 return 0;
43 NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const
45 if (repeat_) {
46 cerr << get_line() << ": error: Repeat concatenations make "
47 "no sense in l-value expressions. I refuse." << endl;
48 des->errors += 1;
49 return 0;
52 svector<NetNet*>nets (parms_.count());
53 unsigned pins = 0;
54 unsigned errors = 0;
56 for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
58 if (parms_[idx] == 0) {
59 cerr << get_line() << ": error: Empty expressions "
60 << "not allowed in concatenations." << endl;
61 errors += 1;
62 continue;
65 nets[idx] = parms_[idx]->elaborate_anet(des, scope);
66 if (nets[idx] == 0)
67 errors += 1;
68 else
69 pins += nets[idx]->pin_count();
72 /* If any of the sub expressions failed to elaborate, then
73 delete all those that did and abort myself. */
74 if (errors) {
75 for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
76 if (nets[idx]) delete nets[idx];
78 des->errors += 1;
79 return 0;
82 /* Make the temporary signal that connects to all the
83 operands, and connect it up. Scan the operands of the
84 concat operator from least significant to most significant,
85 which is opposite from how they are given in the list.
87 Allow for a repeat count other than 1 by repeating the
88 connect loop as many times as necessary. */
90 NetNet*osig = new NetNet(scope, scope->local_symbol(),
91 NetNet::IMPLICIT_REG, pins);
92 /* Assume that all the data types are the same. */
93 osig->data_type(nets[0]->data_type());
95 pins = 0;
96 for (unsigned idx = nets.count() ; idx > 0 ; idx -= 1) {
97 NetNet*cur = nets[idx-1];
98 assert(cur->data_type() == osig->data_type());
99 for (unsigned pin = 0; pin < cur->pin_count(); pin += 1) {
100 connect(osig->pin(pins), cur->pin(pin));
101 pins += 1;
105 osig->local_flag(true);
106 return osig;
109 NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
111 assert(scope);
113 NetNet* sig = 0;
114 NetMemory* mem = 0;
115 const NetExpr*par = 0;
116 NetEvent* eve = 0;
118 symbol_search(des, scope, path_, sig, mem, par, eve);
121 if (mem != 0) {
122 cerr << get_line() << ": error: memories not allowed "
123 << "on left side of procedural continuous "
124 << "assignment." << endl;
125 des->errors += 1;
126 return 0;
129 if (eve != 0) {
130 cerr << get_line() << ": error: named events not allowed "
131 << "on left side of procedural continuous "
132 << "assignment." << endl;
133 des->errors += 1;
134 return 0;
137 if (sig == 0) {
138 cerr << get_line() << ": error: reg ``" << path_ << "'' "
139 << "is undefined in this scope." << endl;
140 des->errors += 1;
141 return 0;
144 switch (sig->type()) {
145 case NetNet::REG:
146 case NetNet::IMPLICIT_REG:
147 break;
149 default:
150 cerr << get_line() << ": error: " << path_ << " is not "
151 << "a reg in this context." << endl;
152 des->errors += 1;
153 return 0;
156 assert(sig);
158 if (msb_ || lsb_) {
160 cerr << get_line() << ": error: bit/part selects not allowed "
161 << "on left side of procedural continuous assignment."
162 << endl;
163 des->errors += 1;
164 return 0;
167 return sig;
171 * $Log: elab_anet.cc,v $
172 * Revision 1.13 2007/03/22 16:08:14 steve
173 * Spelling fixes from Larry
175 * Revision 1.12 2006/05/01 20:47:58 steve
176 * More explicit datatype setup.
178 * Revision 1.11 2005/07/11 16:56:50 steve
179 * Remove NetVariable and ivl_variable_t structures.
181 * Revision 1.10 2004/10/04 01:10:52 steve
182 * Clean up spurious trailing white space.
184 * Revision 1.9 2003/09/19 03:50:12 steve
185 * Remove find_memory method from Design class.
187 * Revision 1.8 2003/06/21 01:21:43 steve
188 * Harmless fixup of warnings.
190 * Revision 1.7 2003/03/06 00:28:41 steve
191 * All NetObj objects have lex_string base names.
193 * Revision 1.6 2003/01/27 05:09:17 steve
194 * Spelling fixes.
196 * Revision 1.5 2002/08/12 01:34:58 steve
197 * conditional ident string using autoconfig.
199 * Revision 1.4 2001/12/03 04:47:14 steve
200 * Parser and pform use hierarchical names as hname_t
201 * objects instead of encoded strings.
203 * Revision 1.3 2001/07/25 03:10:48 steve
204 * Create a config.h.in file to hold all the config
205 * junk, and support gcc 3.0. (Stephan Boettcher)
207 * Revision 1.2 2001/01/06 02:29:36 steve
208 * Support arrays of integers.
210 * Revision 1.1 2000/12/06 06:31:09 steve
211 * Check lvalue of procedural continuous assign (PR#29)