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)
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 #ident "$Id: net_nex_input.cc,v 1.16 2007/01/16 05:44:15 steve Exp $"
32 NexusSet
* NetExpr::nex_input(bool rem_out
)
35 << ": internal error: nex_input not implemented: "
40 NexusSet
* NetProc::nex_input(bool rem_out
)
43 << ": internal error: NetProc::nex_input not implemented"
48 NexusSet
* NetEBinary::nex_input(bool rem_out
)
50 NexusSet
*result
= left_
->nex_input(rem_out
);
51 NexusSet
*tmp
= right_
->nex_input(rem_out
);
57 NexusSet
* NetEConcat::nex_input(bool rem_out
)
59 NexusSet
*result
= parms_
[0]->nex_input(rem_out
);
60 for (unsigned idx
= 1 ; idx
< parms_
.count() ; idx
+= 1) {
61 NexusSet
*tmp
= parms_
[idx
]->nex_input(rem_out
);
69 * A constant has not inputs, so always return an empty set.
71 NexusSet
* NetEConst::nex_input(bool rem_out
)
76 NexusSet
* NetECReal::nex_input(bool rem_out
)
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(bool rem_out
)
90 NexusSet
* NetEEvent::nex_input(bool rem_out
)
95 NexusSet
* NetEScope::nex_input(bool rem_out
)
100 NexusSet
* NetESelect::nex_input(bool rem_out
)
102 NexusSet
*result
= base_
? base_
->nex_input(rem_out
) : new NexusSet();
103 NexusSet
*tmp
= expr_
->nex_input(rem_out
);
109 NexusSet
* NetESFunc::nex_input(bool rem_out
)
114 NexusSet
*result
= parms_
[0]->nex_input(rem_out
);
115 for (unsigned idx
= 1 ; idx
< nparms_
; idx
+= 1) {
116 NexusSet
*tmp
= parms_
[idx
]->nex_input(rem_out
);
123 NexusSet
* NetESignal::nex_input(bool rem_out
)
125 NexusSet
*result
= new NexusSet
;
126 for (unsigned idx
= 0 ; idx
< net_
->pin_count() ; idx
+= 1)
127 result
->add(net_
->pin(idx
).nexus());
132 NexusSet
* NetETernary::nex_input(bool rem_out
)
135 NexusSet
*result
= cond_
->nex_input(rem_out
);
137 tmp
= true_val_
->nex_input(rem_out
);
141 tmp
= false_val_
->nex_input(rem_out
);
148 NexusSet
* NetEUFunc::nex_input(bool rem_out
)
150 NexusSet
*result
= new NexusSet
;
151 for (unsigned idx
= 0 ; idx
< parms_
.count() ; idx
+= 1) {
152 NexusSet
*tmp
= parms_
[idx
]->nex_input(rem_out
);
160 NexusSet
* NetEUnary::nex_input(bool rem_out
)
162 return expr_
->nex_input(rem_out
);
165 NexusSet
* NetAssign_::nex_input(bool rem_out
)
167 NexusSet
*result
= new NexusSet
;
169 NexusSet
*tmp
= word_
->nex_input(rem_out
);
174 NexusSet
*tmp
= base_
->nex_input(rem_out
);
182 NexusSet
* NetAssignBase::nex_input(bool rem_out
)
184 NexusSet
*result
= rval_
->nex_input(rem_out
);
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(rem_out
);
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:
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(bool rem_out
)
221 cerr
<< get_line() << ": internal error: Sorry, "
222 << "I don't know how to synthesize fork/join blocks."
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
;
234 /* Get the inputs for the current statement. */
235 NexusSet
*tmp
= cur
->nex_input(rem_out
);
237 /* Add the current input set to the accumulated input set. */
241 /* Add the current outputs to the accumulated output set,
242 so they can be removed from the input set below. */
243 cur
->nex_output(*prev
);
246 } while (cur
!= last_
->next_
);
248 /* Remove from the input set those bits that are outputs
249 from other statements. They aren't really inputs
250 to the block, just internal intermediate values. */
251 if (rem_out
) result
->rem(*prev
);
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
261 NexusSet
* NetCase::nex_input(bool rem_out
)
263 NexusSet
*result
= expr_
->nex_input(rem_out
);
267 for (unsigned idx
= 0 ; idx
< nitems_
; idx
+= 1) {
269 /* Skip cases that have empty statements. */
270 if (items_
[idx
].statement
== 0)
273 NexusSet
*tmp
= items_
[idx
].statement
->nex_input(rem_out
);
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(rem_out
);
292 NexusSet
* NetCAssign::nex_input(bool rem_out
)
294 cerr
<< get_line() << ": internal warning: NetCAssign::nex_input()"
295 << " not implemented." << endl
;
299 NexusSet
* NetCondit::nex_input(bool rem_out
)
301 NexusSet
*result
= expr_
->nex_input(rem_out
);
303 NexusSet
*tmp
= if_
->nex_input(rem_out
);
309 NexusSet
*tmp
= else_
->nex_input(rem_out
);
317 NexusSet
* NetForce::nex_input(bool rem_out
)
319 cerr
<< get_line() << ": internal warning: NetForce::nex_input()"
320 << " not implemented." << endl
;
324 NexusSet
* NetForever::nex_input(bool rem_out
)
326 NexusSet
*result
= statement_
->nex_input(rem_out
);
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
339 NexusSet
* NetPDelay::nex_input(bool rem_out
)
341 NexusSet
*result
= statement_
->nex_input(rem_out
);
345 NexusSet
* NetRepeat::nex_input(bool rem_out
)
347 NexusSet
*result
= statement_
->nex_input(rem_out
);
348 NexusSet
*tmp
= expr_
->nex_input(rem_out
);
354 NexusSet
* NetSTask::nex_input(bool rem_out
)
356 if (parms_
.count() == 0)
359 NexusSet
*result
= parms_
[0]->nex_input(rem_out
);
360 for (unsigned idx
= 1 ; idx
< parms_
.count() ; idx
+= 1) {
361 NexusSet
*tmp
= parms_
[idx
]->nex_input(rem_out
);
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(bool rem_out
)
379 NexusSet
* NetWhile::nex_input(bool rem_out
)
381 NexusSet
*result
= proc_
->nex_input(rem_out
);
382 NexusSet
*tmp
= cond_
->nex_input(rem_out
);