Reformulate number-to-real on vvp code generator
[iverilog.git] / net_nex_input.cc
blobea62af9ef5dbff6e4b070e4341234ee4e90c8cab
1 /*
2 * Copyright (c) 2002 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: net_nex_input.cc,v 1.16 2007/01/16 05:44:15 steve Exp $"
21 #endif
23 # include "config.h"
25 # include <iostream>
27 # include <cassert>
28 # include <typeinfo>
29 # include "netlist.h"
30 # include "netmisc.h"
32 NexusSet* NetExpr::nex_input()
34 cerr << get_line()
35 << ": internal error: nex_input not implemented: "
36 << *this << endl;
37 return 0;
40 NexusSet* NetProc::nex_input()
42 cerr << get_line()
43 << ": internal error: NetProc::nex_input not implemented"
44 << endl;
45 return 0;
48 NexusSet* NetEBinary::nex_input()
50 NexusSet*result = left_->nex_input();
51 NexusSet*tmp = right_->nex_input();
52 result->add(*tmp);
53 delete tmp;
54 return result;
57 NexusSet* NetEConcat::nex_input()
59 NexusSet*result = parms_[0]->nex_input();
60 for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
61 NexusSet*tmp = parms_[idx]->nex_input();
62 result->add(*tmp);
63 delete tmp;
65 return result;
69 * A constant has not inputs, so always return an empty set.
71 NexusSet* NetEConst::nex_input()
73 return new NexusSet;
76 NexusSet* NetECReal::nex_input()
78 return new NexusSet;
82 * A parameter by definition has no inputs. It represents a constant
83 * value, even if that value is a constant expression.
85 NexusSet* NetEParam::nex_input()
87 return new NexusSet;
90 NexusSet* NetEEvent::nex_input()
92 return new NexusSet;
95 NexusSet* NetEScope::nex_input()
97 return new NexusSet;
100 NexusSet* NetESelect::nex_input()
102 NexusSet*result = base_? base_->nex_input() : new NexusSet();
103 NexusSet*tmp = expr_->nex_input();
104 result->add(*tmp);
105 delete tmp;
106 return result;
109 NexusSet* NetESFunc::nex_input()
111 if (nparms_ == 0)
112 return new NexusSet;
114 NexusSet*result = parms_[0]->nex_input();
115 for (unsigned idx = 1 ; idx < nparms_ ; idx += 1) {
116 NexusSet*tmp = parms_[idx]->nex_input();
117 result->add(*tmp);
118 delete tmp;
120 return result;
123 NexusSet* NetESignal::nex_input()
125 NexusSet*result = new NexusSet;
126 for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1)
127 result->add(net_->pin(idx).nexus());
129 return result;
132 NexusSet* NetETernary::nex_input()
134 NexusSet*tmp;
135 NexusSet*result = cond_->nex_input();
137 tmp = true_val_->nex_input();
138 result->add(*tmp);
139 delete tmp;
141 tmp = false_val_->nex_input();
142 result->add(*tmp);
143 delete tmp;
145 return result;
148 NexusSet* NetEUFunc::nex_input()
150 NexusSet*result = new NexusSet;
151 for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
152 NexusSet*tmp = parms_[idx]->nex_input();
153 result->add(*tmp);
154 delete tmp;
157 return result;
160 NexusSet* NetEUnary::nex_input()
162 return expr_->nex_input();
165 NexusSet* NetAssign_::nex_input()
167 NexusSet*result = new NexusSet;
168 if (word_) {
169 NexusSet*tmp = word_->nex_input();
170 result->add(*tmp);
171 delete tmp;
173 if (base_) {
174 NexusSet*tmp = base_->nex_input();
175 result->add(*tmp);
176 delete tmp;
179 return result;
182 NexusSet* NetAssignBase::nex_input()
184 NexusSet*result = rval_->nex_input();
186 /* It is possible that the lval_ can hav nex_input values. In
187 particular, index expressions are statement inputs as well,
188 so should be addressed here. */
189 for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) {
190 NexusSet*tmp = cur->nex_input();
191 result->add(*tmp);
192 delete tmp;
195 return result;
199 * The nex_input of a begin/end block is the NexusSet of bits that the
200 * block reads from outside the block. That means it is the union of
201 * the nex_input for all the substatements.
203 * The input set for a sequential set is not exactly the union of the
204 * input sets because there is the possibility of intermediate values,
205 * that don't deserve to be in the input set. To wit:
207 * begin
208 * t = a + b;
209 * c = ~t;
210 * end
212 * In this example, "t" should not be in the input set because it is
213 * used by the sequence as a temporary value.
215 NexusSet* NetBlock::nex_input()
217 if (last_ == 0)
218 return new NexusSet;
220 if (type_ == PARA) {
221 cerr << get_line() << ": internal error: Sorry, "
222 << "I don't know how to synthesize fork/join blocks."
223 << endl;
224 return 0;
227 NetProc*cur = last_->next_;
228 /* This is the accumulated input set. */
229 NexusSet*result = new NexusSet;
230 /* This is an accumulated output set. */
231 NexusSet*prev = new NexusSet;
233 do {
234 /* Get the inputs for the current statement. */
235 NexusSet*tmp = cur->nex_input();
237 /* Remove from the input set those bits that are outputs
238 from previous statements. They aren't really inputs
239 to the block, just internal intermediate values. */
240 tmp->rem(*prev);
242 /* Add the corrected set to the accumulated input set. */
243 result->add(*tmp);
244 delete tmp;
246 /* Add the current outputs to the accumulated output
247 set, for processing of later statements. */
248 cur->nex_output(*prev);
250 cur = cur->next_;
251 } while (cur != last_->next_);
253 return result;
257 * The inputs to a case statement are the inputs to the expression,
258 * the inputs to all the guards, and the inputs to all the guarded
259 * statements.
261 NexusSet* NetCase::nex_input()
263 NexusSet*result = expr_->nex_input();
264 if (result == 0)
265 return 0;
267 for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) {
269 /* Skip cases that have empty statements. */
270 if (items_[idx].statement == 0)
271 continue;
273 NexusSet*tmp = items_[idx].statement->nex_input();
274 assert(tmp);
275 result->add(*tmp);
276 delete tmp;
278 /* Usually, this is the guard expression. The default
279 case is special and is identified by a null
280 guard. The default guard obviously has no input. */
281 if (items_[idx].guard) {
282 tmp = items_[idx].guard->nex_input();
283 assert(tmp);
284 result->add(*tmp);
285 delete tmp;
289 return result;
292 NexusSet* NetCAssign::nex_input()
294 cerr << get_line() << ": internal warning: NetCAssign::nex_input()"
295 << " not implemented." << endl;
296 return new NexusSet;
299 NexusSet* NetCondit::nex_input()
301 NexusSet*result = expr_->nex_input();
302 if (if_ != 0) {
303 NexusSet*tmp = if_->nex_input();
304 result->add(*tmp);
305 delete tmp;
308 if (else_ != 0) {
309 NexusSet*tmp = else_->nex_input();
310 result->add(*tmp);
311 delete tmp;
314 return result;
317 NexusSet* NetForce::nex_input()
319 cerr << get_line() << ": internal warning: NetForce::nex_input()"
320 << " not implemented." << endl;
321 return new NexusSet;
324 NexusSet* NetForever::nex_input()
326 NexusSet*result = statement_->nex_input();
327 return result;
331 * The NetPDelay statement is a statement of the form
333 * #<expr> <statement>
335 * The nex_input set is the input set of the <statement>. Do *not*
336 * include the input set of the <expr> because it does not affect the
337 * result.
339 NexusSet* NetPDelay::nex_input()
341 NexusSet*result = statement_->nex_input();
342 return result;
345 NexusSet* NetRepeat::nex_input()
347 NexusSet*result = statement_->nex_input();
348 NexusSet*tmp = expr_->nex_input();
349 result->add(*tmp);
350 delete tmp;
351 return result;
354 NexusSet* NetSTask::nex_input()
356 if (parms_.count() == 0)
357 return new NexusSet;
359 NexusSet*result = parms_[0]->nex_input();
360 for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
361 NexusSet*tmp = parms_[idx]->nex_input();
362 result->add(*tmp);
363 delete tmp;
366 return result;
370 * The NetUTask represents a call to a user defined task. There are no
371 * parameters to consider, because the compiler already removed them
372 * and converted them to blocking assignments.
374 NexusSet* NetUTask::nex_input()
376 return new NexusSet;
379 NexusSet* NetWhile::nex_input()
381 NexusSet*result = proc_->nex_input();
382 NexusSet*tmp = cond_->nex_input();
383 result->add(*tmp);
384 delete tmp;
385 return result;
389 * $Log: net_nex_input.cc,v $
390 * Revision 1.16 2007/01/16 05:44:15 steve
391 * Major rework of array handling. Memories are replaced with the
392 * more general concept of arrays. The NetMemory and NetEMemory
393 * classes are removed from the ivl core program, and the IVL_LPM_RAM
394 * lpm type is removed from the ivl_target API.
396 * Revision 1.15 2006/04/16 00:15:43 steve
397 * Fix part selects in l-values.
399 * Revision 1.14 2005/07/11 16:56:50 steve
400 * Remove NetVariable and ivl_variable_t structures.
402 * Revision 1.13 2005/01/24 05:28:30 steve
403 * Remove the NetEBitSel and combine all bit/part select
404 * behavior into the NetESelect node and IVL_EX_SELECT
405 * ivl_target expression type.
407 * Revision 1.12 2004/09/04 04:24:15 steve
408 * PR1026: assignment statements can have sensitivities in the l-values.
410 * Revision 1.11 2003/10/26 04:50:46 steve
411 * Case with empty statements has no inputs.
413 * Revision 1.10 2003/07/26 03:34:42 steve
414 * Start handling pad of expressions in code generators.
416 * Revision 1.9 2003/04/22 04:48:29 steve
417 * Support event names as expressions elements.
419 * Revision 1.8 2003/01/26 21:15:58 steve
420 * Rework expression parsing and elaboration to
421 * accommodate real/realtime values and expressions.
423 * Revision 1.7 2002/11/16 05:45:41 steve
424 * Handle default: case in net_inputs for NetCase.
426 * Revision 1.6 2002/08/18 22:07:16 steve
427 * Detect temporaries in sequential block synthesis.
429 * Revision 1.5 2002/08/12 01:34:59 steve
430 * conditional ident string using autoconfig.
432 * Revision 1.4 2002/07/14 23:47:58 steve
433 * Infinite loop in nex_input of NetBlock objects.
435 * Revision 1.3 2002/06/05 03:44:25 steve
436 * Add support for memory words in l-value of
437 * non-blocking assignments, and remove the special
438 * NetAssignMem_ and NetAssignMemNB classes.
440 * Revision 1.2 2002/04/21 17:43:12 steve
441 * implement nex_input for behavioral statements.
443 * Revision 1.1 2002/04/21 04:59:08 steve
444 * Add support for conbinational events by finding
445 * the inputs to expressions and some statements.
446 * Get case and assignment statements working.