Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 521 lines (428 sloc) 11.476 kb
5796524 Add ne_expr.cc
steve authored
1 /*
2 * Copyright (c) 2002 Stephen Williams (steve@icarus.com)
3 *
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.
9 *
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.
14 *
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
18 */
52bf4e6 conditional ident string using autoconfig.
steve authored
19 #ifdef HAVE_CVS_IDENT
c602d94 Comparison operators do have defined width.
steve authored
20 #ident "$Id: net_expr.cc,v 1.16 2003/03/15 18:08:43 steve Exp $"
5796524 Add ne_expr.cc
steve authored
21 #endif
22
928df5c include config.h to eliminate warnings.
steve authored
23 # include "config.h"
5796524 Add ne_expr.cc
steve authored
24 # include "netlist.h"
4c67de5 Add the lex_strings string handler, and put
steve authored
25 # include "compiler.h"
28e0616 Use standard name for iostream.
steve authored
26 # include <iostream>
5796524 Add ne_expr.cc
steve authored
27
46253ed Rework expression parsing and elaboration to
steve authored
28 NetExpr::TYPE NetExpr::expr_type() const
29 {
30 return ET_VECTOR;
31 }
32
de94d09 No need to keep excess width from an
steve authored
33 /*
34 * Create an add/sub node from the two operands. Make a best guess of
35 * the
36 */
37 NetEBAdd::NetEBAdd(char op, NetExpr*l, NetExpr*r)
38 : NetEBinary(op, l, r)
39 {
40 NetEConst* tmp;
41
42 /* Catch the special case that one of the operands is an
43 unsized constant number. If so, then we should set the
44 width of that number to the size of the other operand, plus
45 one. This expands the expression to account for the largest
46 possible result.
47
48 The set_width applied to a constant value will only
49 truncate the constant so far as it can still hold its
50 logical value, so this is safe to do. */
51 if ( (tmp = dynamic_cast<NetEConst*>(r))
52 && (! tmp->has_width())
53 && (tmp->expr_width() > l->expr_width()) ) {
54
55 unsigned target_width = l->expr_width() + 1;
56 r->set_width(target_width);
57
58 /* Note: This constant value will not gain a defined
59 with from this. Make sure. */
60 assert(! r->has_width() );
61
62 } else if ( (tmp = dynamic_cast<NetEConst*>(l))
63 && (! tmp->has_width())
64 && (tmp->expr_width() > r->expr_width()) ) {
65
66 unsigned target_width = r->expr_width() + 1;
67 l->set_width(target_width);
68
69 /* Note: This constant value will not gain a defined
70 with from this. Make sure. */
71 assert(! l->has_width() );
72
73 }
74
75 /* Now that we have the operand sizes the way we like, or as
76 good as we are going to get them, set the size of myself. */
77 if (r->expr_width() > l->expr_width()) {
78
79 expr_width(r->expr_width());
80
81 } else {
82 expr_width(l->expr_width());
83 }
84
85 cast_signed(l->has_sign() && r->has_sign());
86 }
87
88 NetEBAdd::~NetEBAdd()
89 {
90 }
91
92 NetEBAdd* NetEBAdd::dup_expr() const
93 {
94 NetEBAdd*result = new NetEBAdd(op_, left_->dup_expr(),
95 right_->dup_expr());
96 return result;
97 }
98
46253ed Rework expression parsing and elaboration to
steve authored
99 NetExpr::TYPE NetEBAdd::expr_type() const
100 {
101 if (left_->expr_type() == ET_REAL)
102 return ET_REAL;
103
104 if (right_->expr_type() == ET_REAL)
105 return ET_REAL;
106
107 return ET_VECTOR;
108 }
109
c602d94 Comparison operators do have defined width.
steve authored
110 /*
111 * Create a comparison operator with two sub-expressions.
112 *
113 * Handle the special case of an unsized constant on the left or right
114 * side by resizing the number to match the other
115 * expression. Otherwise, the netlist will have to allow the
116 * expressions to have different widths.
117 */
118 NetEBComp::NetEBComp(char op, NetExpr*l, NetExpr*r)
119 : NetEBinary(op, l, r)
120 {
121 if (NetEConst*tmp = dynamic_cast<NetEConst*>(r)) do {
122
123 if (tmp->has_width())
124 break;
125
126 if (tmp->expr_width() == l->expr_width())
127 break;
128
129 tmp->set_width(l->expr_width());
130
131 } while (0);
132
133 if (NetEConst*tmp = dynamic_cast<NetEConst*>(l)) do {
134
135 if (tmp->has_width())
136 break;
137
138 if (tmp->expr_width() == r->expr_width())
139 break;
140
141 tmp->set_width(r->expr_width());
142
143 } while (0);
144
145
146 expr_width(1);
147 }
148
149 NetEBComp::~NetEBComp()
150 {
151 }
152
153 bool NetEBComp::has_width() const
154 {
155 return true;
156 }
157
46253ed Rework expression parsing and elaboration to
steve authored
158 NetEBDiv::NetEBDiv(char op, NetExpr*l, NetExpr*r)
159 : NetEBinary(op, l, r)
160 {
161 unsigned w = l->expr_width();
162 if (r->expr_width() > w)
163 w = r->expr_width();
164
165 expr_width(w);
166 cast_signed(l->has_sign() && r->has_sign());
167 }
168
169 NetEBDiv::~NetEBDiv()
170 {
171 }
172
173 NetEBDiv* NetEBDiv::dup_expr() const
174 {
175 NetEBDiv*result = new NetEBDiv(op_, left_->dup_expr(),
176 right_->dup_expr());
177 return result;
178 }
179
180 NetExpr::TYPE NetEBDiv::expr_type() const
181 {
182 if (left_->expr_type() == ET_REAL)
183 return ET_REAL;
184
185 if (right_->expr_type() == ET_REAL)
186 return ET_REAL;
187
188 return ET_VECTOR;
189 }
190
191 NetEBMult::NetEBMult(char op, NetExpr*l, NetExpr*r)
192 : NetEBinary(op, l, r)
193 {
194 expr_width(l->expr_width() + r->expr_width());
195 cast_signed(l->has_sign() && r->has_sign());
196 }
197
198 NetEBMult::~NetEBMult()
199 {
200 }
201
202 NetEBMult* NetEBMult::dup_expr() const
203 {
204 NetEBMult*result = new NetEBMult(op_, left_->dup_expr(),
205 right_->dup_expr());
206 return result;
207 }
208
209 NetExpr::TYPE NetEBMult::expr_type() const
210 {
211 if (left_->expr_type() == ET_REAL)
212 return ET_REAL;
213
214 if (right_->expr_type() == ET_REAL)
215 return ET_REAL;
216
217 return ET_VECTOR;
218 }
219
8667b9a Put off evaluation of concatenation repeat expresions
steve authored
220 NetEConcat::NetEConcat(unsigned cnt, NetExpr* r)
221 : parms_(cnt), repeat_(r)
222 {
223 if (repeat_ == 0) {
224 repeat_calculated_ = true;
225 repeat_value_ = 1;
226 } else {
227 repeat_calculated_ = false;
228 }
229
230 expr_width(0);
231 }
232
233 NetEConcat::~NetEConcat()
234 {
235 for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
236 delete parms_[idx];
237 }
238
aa8869a Postpone parameter width check to evaluation.
steve authored
239 bool NetEConcat::has_width() const
240 {
241 return true;
242 }
243
8667b9a Put off evaluation of concatenation repeat expresions
steve authored
244 void NetEConcat::set(unsigned idx, NetExpr*e)
245 {
246 assert(idx < parms_.count());
247 assert(parms_[idx] == 0);
248 parms_[idx] = e;
249 expr_width( expr_width() + e->expr_width() );
250 }
251
252 NetEConcat* NetEConcat::dup_expr() const
253 {
254 NetEConcat*dup = new NetEConcat(parms_.count(), repeat_);
255 for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
256 if (parms_[idx]) {
257 NetExpr*tmp = parms_[idx]->dup_expr();
258 assert(tmp);
259 dup->parms_[idx] = tmp;
260 }
261
262
263 dup->expr_width(expr_width());
264 return dup;
265 }
266
267 unsigned NetEConcat::repeat()
268 {
269 if (repeat_calculated_)
270 return repeat_value_;
271
272 assert(repeat_);
273
274 if (! dynamic_cast<NetEConst*>(repeat_)) {
275 NetExpr*tmp = repeat_->eval_tree();
276 if (tmp != 0) {
277 delete repeat_;
278 repeat_ = tmp;
279 }
280 }
281
282 NetEConst*repeat_const = dynamic_cast<NetEConst*>(repeat_);
283
284 /* This should not be possible, as it was checked earlier to
285 assure that this is a constant expression. */
286 if (repeat_const == 0) {
287 cerr << get_line() << ": internal error: repeat expression "
288 << "is not a compile time constant." << endl;
289 cerr << get_line() << ": : Expression is: "
290 << *repeat_ << endl;
291 repeat_calculated_ = true;
292 repeat_value_ = 1;
293 return 1;
294 }
295
296 repeat_calculated_ = true;
297 repeat_value_ = repeat_const->value().as_ulong();
298
299 delete repeat_;
300 repeat_ = 0;
301
302 return repeat_value_;
303 }
304
305 unsigned NetEConcat::repeat() const
306 {
307 assert(repeat_calculated_);
308 return repeat_value_;
309 }
310
46253ed Rework expression parsing and elaboration to
steve authored
311 NetECReal::NetECReal(const verireal&val)
312 : value_(val)
313 {
314 }
315
316 NetECReal::~NetECReal()
317 {
318 }
319
320 const verireal& NetECReal::value() const
321 {
322 return value_;
323 }
324
589422b Real constants have no defined vector width
steve authored
325 bool NetECReal::has_width() const
326 {
327 return false;
328 }
329
46253ed Rework expression parsing and elaboration to
steve authored
330 NetECReal* NetECReal::dup_expr() const
331 {
332 NetECReal*tmp = new NetECReal(value_);
333 tmp->set_line(*this);
334 return tmp;
335 }
336
337 NetExpr::TYPE NetECReal::expr_type() const
338 {
339 return ET_REAL;
340 }
341
7e1e44e Properly cast signedness of parameters with ranges.
steve authored
342 NetEParam::NetEParam()
4350180 Redo the parameter vector support to allow
steve authored
343 : des_(0), scope_(0)
7e1e44e Properly cast signedness of parameters with ranges.
steve authored
344 {
345 }
346
347 NetEParam::NetEParam(Design*d, NetScope*s, const hname_t&n)
348 : des_(d), scope_(s), name_(n)
349 {
350 }
351
352 NetEParam::~NetEParam()
353 {
354 }
355
356 bool NetEParam::has_width() const
357 {
358 return false;
359 }
360
361 NetEParam* NetEParam::dup_expr() const
362 {
363 return new NetEParam(des_, scope_, name_);
364 }
365
5796524 Add ne_expr.cc
steve authored
366 NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid)
367 : expr_(exp), base_(base)
368 {
369 expr_width(wid);
370 }
371
372 NetESelect::~NetESelect()
373 {
374 delete expr_;
375 delete base_;
376 }
377
378 const NetExpr*NetESelect::sub_expr() const
379 {
380 return expr_;
381 }
382
383 const NetExpr*NetESelect::select() const
384 {
385 return base_;
386 }
387
388 bool NetESelect::has_width() const
389 {
390 return true;
391 }
392
393 bool NetESelect::set_width(unsigned w)
394 {
395 if (expr_width() == 1)
396 return true;
397 else
398 return false;
399 }
400
6d94f2e Better organize the NetESFunc return type guesses.
steve authored
401 NetESFunc::NetESFunc(const char*n, NetExpr::TYPE t,
402 unsigned width, unsigned np)
403 : name_(0), type_(t)
04ada23 Support in various contexts the $realtime
steve authored
404 {
4c67de5 Add the lex_strings string handler, and put
steve authored
405 name_ = lex_strings.add(n);
04ada23 Support in various contexts the $realtime
steve authored
406 expr_width(width);
407 nparms_ = np;
408 parms_ = new NetExpr*[np];
409 for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
410 parms_[idx] = 0;
411 }
412
413 NetESFunc::~NetESFunc()
414 {
415 for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
416 if (parms_[idx]) delete parms_[idx];
417
418 delete[]parms_;
4c67de5 Add the lex_strings string handler, and put
steve authored
419 /* name_ string ls lex_strings allocated. */
04ada23 Support in various contexts the $realtime
steve authored
420 }
421
422 const char* NetESFunc::name() const
423 {
424 return name_;
425 }
426
427 unsigned NetESFunc::nparms() const
428 {
429 return nparms_;
430 }
431
432 void NetESFunc::parm(unsigned idx, NetExpr*v)
433 {
434 assert(idx < nparms_);
435 if (parms_[idx])
436 delete parms_[idx];
437 parms_[idx] = v;
438 }
439
440 const NetExpr* NetESFunc::parm(unsigned idx) const
441 {
442 assert(idx < nparms_);
443 return parms_[idx];
444 }
445
446 NetExpr* NetESFunc::parm(unsigned idx)
447 {
448 assert(idx < nparms_);
449 return parms_[idx];
450 }
451
452 NetExpr::TYPE NetESFunc::expr_type() const
453 {
6d94f2e Better organize the NetESFunc return type guesses.
steve authored
454 return type_;
04ada23 Support in various contexts the $realtime
steve authored
455 }
456
5796524 Add ne_expr.cc
steve authored
457 /*
458 * $Log: net_expr.cc,v $
c602d94 Comparison operators do have defined width.
steve authored
459 * Revision 1.16 2003/03/15 18:08:43 steve
460 * Comparison operators do have defined width.
461 *
6d94f2e Better organize the NetESFunc return type guesses.
steve authored
462 * Revision 1.15 2003/03/15 04:46:29 steve
463 * Better organize the NetESFunc return type guesses.
464 *
4c67de5 Add the lex_strings string handler, and put
steve authored
465 * Revision 1.14 2003/03/01 06:25:30 steve
466 * Add the lex_strings string handler, and put
467 * scope names and system task/function names
468 * into this table. Also, permallocate event
469 * names from the beginning.
470 *
589422b Real constants have no defined vector width
steve authored
471 * Revision 1.13 2003/02/06 17:50:23 steve
472 * Real constants have no defined vector width
473 *
04ada23 Support in various contexts the $realtime
steve authored
474 * Revision 1.12 2003/01/27 00:14:37 steve
475 * Support in various contexts the $realtime
476 * system task.
477 *
46253ed Rework expression parsing and elaboration to
steve authored
478 * Revision 1.11 2003/01/26 21:15:58 steve
479 * Rework expression parsing and elaboration to
480 * accommodate real/realtime values and expressions.
481 *
aa8869a Postpone parameter width check to evaluation.
steve authored
482 * Revision 1.10 2002/11/09 01:40:19 steve
483 * Postpone parameter width check to evaluation.
484 *
de94d09 No need to keep excess width from an
steve authored
485 * Revision 1.9 2002/11/06 02:25:13 steve
486 * No need to keep excess width from an
487 * unsigned constant value, if it can
488 * be trimmed safely.
489 *
4350180 Redo the parameter vector support to allow
steve authored
490 * Revision 1.8 2002/10/19 22:59:49 steve
491 * Redo the parameter vector support to allow
492 * parameter names in range expressions.
493 *
7e1e44e Properly cast signedness of parameters with ranges.
steve authored
494 * Revision 1.7 2002/09/01 03:01:48 steve
495 * Properly cast signedness of parameters with ranges.
496 *
52bf4e6 conditional ident string using autoconfig.
steve authored
497 * Revision 1.6 2002/08/12 01:34:59 steve
498 * conditional ident string using autoconfig.
499 *
28e0616 Use standard name for iostream.
steve authored
500 * Revision 1.5 2002/06/06 18:57:18 steve
501 * Use standard name for iostream.
502 *
8941a59 include iostream for gcc 3.1
steve authored
503 * Revision 1.4 2002/05/25 16:51:37 steve
504 * include iostream for gcc 3.1
505 *
8667b9a Put off evaluation of concatenation repeat expresions
steve authored
506 * Revision 1.3 2002/05/05 21:11:50 steve
507 * Put off evaluation of concatenation repeat expresions
508 * until after parameters are defined. This allows parms
509 * to be used in repeat expresions.
510 *
511 * Add the builtin $signed system function.
512 *
928df5c include config.h to eliminate warnings.
steve authored
513 * Revision 1.2 2002/01/29 22:36:31 steve
514 * include config.h to eliminate warnings.
515 *
5796524 Add ne_expr.cc
steve authored
516 * Revision 1.1 2002/01/28 01:39:45 steve
517 * Add ne_expr.cc
518 *
519 */
520
Something went wrong with that request. Please try again.