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)
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
29 NexusSet
* NetExpr::nex_input(bool rem_out
)
31 cerr
<< get_fileline()
32 << ": internal error: nex_input not implemented: "
37 NexusSet
* NetProc::nex_input(bool rem_out
)
39 cerr
<< get_fileline()
40 << ": internal error: NetProc::nex_input not implemented"
45 NexusSet
* NetEBinary::nex_input(bool rem_out
)
47 NexusSet
*result
= left_
->nex_input(rem_out
);
48 NexusSet
*tmp
= right_
->nex_input(rem_out
);
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
);
66 * A constant has not inputs, so always return an empty set.
68 NexusSet
* NetEConst::nex_input(bool rem_out
)
73 NexusSet
* NetECReal::nex_input(bool rem_out
)
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
)
87 NexusSet
* NetEEvent::nex_input(bool rem_out
)
92 NexusSet
* NetEScope::nex_input(bool rem_out
)
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
);
106 NexusSet
* NetESFunc::nex_input(bool rem_out
)
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
);
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());
129 NexusSet
* NetETernary::nex_input(bool rem_out
)
132 NexusSet
*result
= cond_
->nex_input(rem_out
);
134 tmp
= true_val_
->nex_input(rem_out
);
138 tmp
= false_val_
->nex_input(rem_out
);
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
);
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
;
166 NexusSet
*tmp
= word_
->nex_input(rem_out
);
171 NexusSet
*tmp
= base_
->nex_input(rem_out
);
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
);
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:
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
)
218 cerr
<< get_fileline() << ": internal error: Sorry, "
219 << "I don't know how to synthesize fork/join blocks."
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
;
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. */
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
);
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
);
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
258 NexusSet
* NetCase::nex_input(bool rem_out
)
260 NexusSet
*result
= expr_
->nex_input(rem_out
);
264 for (unsigned idx
= 0 ; idx
< nitems_
; idx
+= 1) {
266 /* Skip cases that have empty statements. */
267 if (items_
[idx
].statement
== 0)
270 NexusSet
*tmp
= items_
[idx
].statement
->nex_input(rem_out
);
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
);
289 NexusSet
* NetCAssign::nex_input(bool rem_out
)
291 cerr
<< get_fileline() << ": internal warning: NetCAssign::nex_input()"
292 << " not implemented." << endl
;
296 NexusSet
* NetCondit::nex_input(bool rem_out
)
298 NexusSet
*result
= expr_
->nex_input(rem_out
);
300 NexusSet
*tmp
= if_
->nex_input(rem_out
);
306 NexusSet
*tmp
= else_
->nex_input(rem_out
);
314 NexusSet
* NetForce::nex_input(bool rem_out
)
316 cerr
<< get_fileline() << ": internal warning: NetForce::nex_input()"
317 << " not implemented." << endl
;
321 NexusSet
* NetForever::nex_input(bool rem_out
)
323 NexusSet
*result
= statement_
->nex_input(rem_out
);
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
336 NexusSet
* NetPDelay::nex_input(bool rem_out
)
338 NexusSet
*result
= statement_
->nex_input(rem_out
);
342 NexusSet
* NetRepeat::nex_input(bool rem_out
)
344 NexusSet
*result
= statement_
->nex_input(rem_out
);
345 NexusSet
*tmp
= expr_
->nex_input(rem_out
);
351 NexusSet
* NetSTask::nex_input(bool rem_out
)
353 if (parms_
.count() == 0)
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
);
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
)
376 NexusSet
* NetWhile::nex_input(bool rem_out
)
378 NexusSet
*result
= proc_
->nex_input(rem_out
);
379 NexusSet
*tmp
= cond_
->nex_input(rem_out
);