Merge branch 'master' into verilog-ams
[sverilog.git] / net_nex_input.cc
blob2a68c2a8b0b96fc648361d56d0523389db0f09b4
1 /*
2 * Copyright (c) 2002-2007 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 <iostream>
24 # include <cassert>
25 # include <typeinfo>
26 # include "netlist.h"
27 # include "netmisc.h"
29 NexusSet* NetExpr::nex_input(bool rem_out)
31 cerr << get_fileline()
32 << ": internal error: nex_input not implemented: "
33 << *this << endl;
34 return 0;
37 NexusSet* NetProc::nex_input(bool rem_out)
39 cerr << get_fileline()
40 << ": internal error: NetProc::nex_input not implemented"
41 << endl;
42 return 0;
45 NexusSet* NetEBinary::nex_input(bool rem_out)
47 NexusSet*result = left_->nex_input(rem_out);
48 NexusSet*tmp = right_->nex_input(rem_out);
49 result->add(*tmp);
50 delete tmp;
51 return result;
54 NexusSet* NetEConcat::nex_input(bool rem_out)
56 NexusSet*result = parms_[0]->nex_input(rem_out);
57 for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
58 NexusSet*tmp = parms_[idx]->nex_input(rem_out);
59 result->add(*tmp);
60 delete tmp;
62 return result;
66 * A constant has not inputs, so always return an empty set.
68 NexusSet* NetEConst::nex_input(bool rem_out)
70 return new NexusSet;
73 NexusSet* NetECReal::nex_input(bool rem_out)
75 return new NexusSet;
79 * A parameter by definition has no inputs. It represents a constant
80 * value, even if that value is a constant expression.
82 NexusSet* NetEParam::nex_input(bool rem_out)
84 return new NexusSet;
87 NexusSet* NetEEvent::nex_input(bool rem_out)
89 return new NexusSet;
92 NexusSet* NetEScope::nex_input(bool rem_out)
94 return new NexusSet;
97 NexusSet* NetESelect::nex_input(bool rem_out)
99 NexusSet*result = base_? base_->nex_input(rem_out) : new NexusSet();
100 NexusSet*tmp = expr_->nex_input(rem_out);
101 result->add(*tmp);
102 delete tmp;
103 return result;
106 NexusSet* NetESFunc::nex_input(bool rem_out)
108 if (nparms_ == 0)
109 return new NexusSet;
111 NexusSet*result = parms_[0]->nex_input(rem_out);
112 for (unsigned idx = 1 ; idx < nparms_ ; idx += 1) {
113 NexusSet*tmp = parms_[idx]->nex_input(rem_out);
114 result->add(*tmp);
115 delete tmp;
117 return result;
120 NexusSet* NetESignal::nex_input(bool rem_out)
122 NexusSet*result = new NexusSet;
123 for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1)
124 result->add(net_->pin(idx).nexus());
126 return result;
129 NexusSet* NetETernary::nex_input(bool rem_out)
131 NexusSet*tmp;
132 NexusSet*result = cond_->nex_input(rem_out);
134 tmp = true_val_->nex_input(rem_out);
135 result->add(*tmp);
136 delete tmp;
138 tmp = false_val_->nex_input(rem_out);
139 result->add(*tmp);
140 delete tmp;
142 return result;
145 NexusSet* NetEUFunc::nex_input(bool rem_out)
147 NexusSet*result = new NexusSet;
148 for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
149 NexusSet*tmp = parms_[idx]->nex_input(rem_out);
150 result->add(*tmp);
151 delete tmp;
154 return result;
157 NexusSet* NetEUnary::nex_input(bool rem_out)
159 return expr_->nex_input(rem_out);
162 NexusSet* NetAssign_::nex_input(bool rem_out)
164 NexusSet*result = new NexusSet;
165 if (word_) {
166 NexusSet*tmp = word_->nex_input(rem_out);
167 result->add(*tmp);
168 delete tmp;
170 if (base_) {
171 NexusSet*tmp = base_->nex_input(rem_out);
172 result->add(*tmp);
173 delete tmp;
176 return result;
179 NexusSet* NetAssignBase::nex_input(bool rem_out)
181 NexusSet*result = rval_->nex_input(rem_out);
183 /* It is possible that the lval_ can have nex_input values. In
184 particular, index expressions are statement inputs as well,
185 so should be addressed here. */
186 for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) {
187 NexusSet*tmp = cur->nex_input(rem_out);
188 result->add(*tmp);
189 delete tmp;
192 return result;
196 * The nex_input of a begin/end block is the NexusSet of bits that the
197 * block reads from outside the block. That means it is the union of
198 * the nex_input for all the substatements.
200 * The input set for a sequential set is not exactly the union of the
201 * input sets because there is the possibility of intermediate values,
202 * that don't deserve to be in the input set. To wit:
204 * begin
205 * t = a + b;
206 * c = ~t;
207 * end
209 * In this example, "t" should not be in the input set because it is
210 * used by the sequence as a temporary value.
212 NexusSet* NetBlock::nex_input(bool rem_out)
214 if (last_ == 0)
215 return new NexusSet;
217 if (type_ == PARA) {
218 cerr << get_fileline() << ": internal error: Sorry, "
219 << "I don't know how to synthesize fork/join blocks."
220 << endl;
221 return 0;
224 NetProc*cur = last_->next_;
225 /* This is the accumulated input set. */
226 NexusSet*result = new NexusSet;
227 /* This is an accumulated output set. */
228 NexusSet*prev = new NexusSet;
230 do {
231 /* Get the inputs for the current statement. */
232 NexusSet*tmp = cur->nex_input(rem_out);
234 /* Add the current input set to the accumulated input set. */
235 result->add(*tmp);
236 delete tmp;
238 /* Add the current outputs to the accumulated output set,
239 so they can be removed from the input set below. */
240 cur->nex_output(*prev);
242 cur = cur->next_;
243 } while (cur != last_->next_);
245 /* Remove from the input set those bits that are outputs
246 from other statements. They aren't really inputs
247 to the block, just internal intermediate values. */
248 if (rem_out) result->rem(*prev);
250 return result;
254 * The inputs to a case statement are the inputs to the expression,
255 * the inputs to all the guards, and the inputs to all the guarded
256 * statements.
258 NexusSet* NetCase::nex_input(bool rem_out)
260 NexusSet*result = expr_->nex_input(rem_out);
261 if (result == 0)
262 return 0;
264 for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) {
266 /* Skip cases that have empty statements. */
267 if (items_[idx].statement == 0)
268 continue;
270 NexusSet*tmp = items_[idx].statement->nex_input(rem_out);
271 assert(tmp);
272 result->add(*tmp);
273 delete tmp;
275 /* Usually, this is the guard expression. The default
276 case is special and is identified by a null
277 guard. The default guard obviously has no input. */
278 if (items_[idx].guard) {
279 tmp = items_[idx].guard->nex_input(rem_out);
280 assert(tmp);
281 result->add(*tmp);
282 delete tmp;
286 return result;
289 NexusSet* NetCAssign::nex_input(bool rem_out)
291 cerr << get_fileline() << ": internal warning: NetCAssign::nex_input()"
292 << " not implemented." << endl;
293 return new NexusSet;
296 NexusSet* NetCondit::nex_input(bool rem_out)
298 NexusSet*result = expr_->nex_input(rem_out);
299 if (if_ != 0) {
300 NexusSet*tmp = if_->nex_input(rem_out);
301 result->add(*tmp);
302 delete tmp;
305 if (else_ != 0) {
306 NexusSet*tmp = else_->nex_input(rem_out);
307 result->add(*tmp);
308 delete tmp;
311 return result;
314 NexusSet* NetForce::nex_input(bool rem_out)
316 cerr << get_fileline() << ": internal warning: NetForce::nex_input()"
317 << " not implemented." << endl;
318 return new NexusSet;
321 NexusSet* NetForever::nex_input(bool rem_out)
323 NexusSet*result = statement_->nex_input(rem_out);
324 return result;
328 * The NetPDelay statement is a statement of the form
330 * #<expr> <statement>
332 * The nex_input set is the input set of the <statement>. Do *not*
333 * include the input set of the <expr> because it does not affect the
334 * result.
336 NexusSet* NetPDelay::nex_input(bool rem_out)
338 NexusSet*result = statement_->nex_input(rem_out);
339 return result;
342 NexusSet* NetRepeat::nex_input(bool rem_out)
344 NexusSet*result = statement_->nex_input(rem_out);
345 NexusSet*tmp = expr_->nex_input(rem_out);
346 result->add(*tmp);
347 delete tmp;
348 return result;
351 NexusSet* NetSTask::nex_input(bool rem_out)
353 if (parms_.count() == 0)
354 return new NexusSet;
356 NexusSet*result = parms_[0]->nex_input(rem_out);
357 for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
358 NexusSet*tmp = parms_[idx]->nex_input(rem_out);
359 result->add(*tmp);
360 delete tmp;
363 return result;
367 * The NetUTask represents a call to a user defined task. There are no
368 * parameters to consider, because the compiler already removed them
369 * and converted them to blocking assignments.
371 NexusSet* NetUTask::nex_input(bool rem_out)
373 return new NexusSet;
376 NexusSet* NetWhile::nex_input(bool rem_out)
378 NexusSet*result = proc_->nex_input(rem_out);
379 NexusSet*tmp = cond_->nex_input(rem_out);
380 result->add(*tmp);
381 delete tmp;
382 return result;