Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 557 lines (457 sloc) 12.174 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
5903f07 Support parameters in real expressions and
steve authored
20 #ident "$Id: net_expr.cc,v 1.18 2003/05/30 02:55:32 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
7e2848b Do not try to set constants to width 0.
steve authored
126 if (l->expr_width() == 0)
127 break;
128
c602d94 Comparison operators do have defined width.
steve authored
129 if (tmp->expr_width() == l->expr_width())
130 break;
131
132 tmp->set_width(l->expr_width());
133
134 } while (0);
135
136 if (NetEConst*tmp = dynamic_cast<NetEConst*>(l)) do {
137
138 if (tmp->has_width())
139 break;
140
7e2848b Do not try to set constants to width 0.
steve authored
141 if (r->expr_width() == 0)
142 break;
143
c602d94 Comparison operators do have defined width.
steve authored
144 if (tmp->expr_width() == r->expr_width())
145 break;
146
147 tmp->set_width(r->expr_width());
148
149 } while (0);
150
151
152 expr_width(1);
153 }
154
155 NetEBComp::~NetEBComp()
156 {
157 }
158
159 bool NetEBComp::has_width() const
160 {
161 return true;
162 }
163
46253ed Rework expression parsing and elaboration to
steve authored
164 NetEBDiv::NetEBDiv(char op, NetExpr*l, NetExpr*r)
165 : NetEBinary(op, l, r)
166 {
167 unsigned w = l->expr_width();
168 if (r->expr_width() > w)
169 w = r->expr_width();
170
171 expr_width(w);
172 cast_signed(l->has_sign() && r->has_sign());
173 }
174
175 NetEBDiv::~NetEBDiv()
176 {
177 }
178
179 NetEBDiv* NetEBDiv::dup_expr() const
180 {
181 NetEBDiv*result = new NetEBDiv(op_, left_->dup_expr(),
182 right_->dup_expr());
183 return result;
184 }
185
186 NetExpr::TYPE NetEBDiv::expr_type() const
187 {
188 if (left_->expr_type() == ET_REAL)
189 return ET_REAL;
190
191 if (right_->expr_type() == ET_REAL)
192 return ET_REAL;
193
194 return ET_VECTOR;
195 }
196
197 NetEBMult::NetEBMult(char op, NetExpr*l, NetExpr*r)
198 : NetEBinary(op, l, r)
199 {
200 expr_width(l->expr_width() + r->expr_width());
201 cast_signed(l->has_sign() && r->has_sign());
202 }
203
204 NetEBMult::~NetEBMult()
205 {
206 }
207
208 NetEBMult* NetEBMult::dup_expr() const
209 {
210 NetEBMult*result = new NetEBMult(op_, left_->dup_expr(),
211 right_->dup_expr());
212 return result;
213 }
214
215 NetExpr::TYPE NetEBMult::expr_type() const
216 {
217 if (left_->expr_type() == ET_REAL)
218 return ET_REAL;
219
220 if (right_->expr_type() == ET_REAL)
221 return ET_REAL;
222
223 return ET_VECTOR;
224 }
225
8667b9a Put off evaluation of concatenation repeat expresions
steve authored
226 NetEConcat::NetEConcat(unsigned cnt, NetExpr* r)
227 : parms_(cnt), repeat_(r)
228 {
229 if (repeat_ == 0) {
230 repeat_calculated_ = true;
231 repeat_value_ = 1;
232 } else {
233 repeat_calculated_ = false;
234 }
235
236 expr_width(0);
237 }
238
239 NetEConcat::~NetEConcat()
240 {
241 for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
242 delete parms_[idx];
243 }
244
aa8869a Postpone parameter width check to evaluation.
steve authored
245 bool NetEConcat::has_width() const
246 {
247 return true;
248 }
249
8667b9a Put off evaluation of concatenation repeat expresions
steve authored
250 void NetEConcat::set(unsigned idx, NetExpr*e)
251 {
252 assert(idx < parms_.count());
253 assert(parms_[idx] == 0);
254 parms_[idx] = e;
255 expr_width( expr_width() + e->expr_width() );
256 }
257
258 NetEConcat* NetEConcat::dup_expr() const
259 {
260 NetEConcat*dup = new NetEConcat(parms_.count(), repeat_);
261 for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
262 if (parms_[idx]) {
263 NetExpr*tmp = parms_[idx]->dup_expr();
264 assert(tmp);
265 dup->parms_[idx] = tmp;
266 }
267
268
269 dup->expr_width(expr_width());
270 return dup;
271 }
272
273 unsigned NetEConcat::repeat()
274 {
275 if (repeat_calculated_)
276 return repeat_value_;
277
278 assert(repeat_);
279
280 if (! dynamic_cast<NetEConst*>(repeat_)) {
281 NetExpr*tmp = repeat_->eval_tree();
282 if (tmp != 0) {
283 delete repeat_;
284 repeat_ = tmp;
285 }
286 }
287
288 NetEConst*repeat_const = dynamic_cast<NetEConst*>(repeat_);
289
290 /* This should not be possible, as it was checked earlier to
291 assure that this is a constant expression. */
292 if (repeat_const == 0) {
293 cerr << get_line() << ": internal error: repeat expression "
294 << "is not a compile time constant." << endl;
295 cerr << get_line() << ": : Expression is: "
296 << *repeat_ << endl;
297 repeat_calculated_ = true;
298 repeat_value_ = 1;
299 return 1;
300 }
301
302 repeat_calculated_ = true;
303 repeat_value_ = repeat_const->value().as_ulong();
304
305 delete repeat_;
306 repeat_ = 0;
307
308 return repeat_value_;
309 }
310
311 unsigned NetEConcat::repeat() const
312 {
313 assert(repeat_calculated_);
314 return repeat_value_;
315 }
316
46253ed Rework expression parsing and elaboration to
steve authored
317 NetECReal::NetECReal(const verireal&val)
318 : value_(val)
319 {
320 }
321
322 NetECReal::~NetECReal()
323 {
324 }
325
326 const verireal& NetECReal::value() const
327 {
328 return value_;
329 }
330
589422b Real constants have no defined vector width
steve authored
331 bool NetECReal::has_width() const
332 {
333 return false;
334 }
335
46253ed Rework expression parsing and elaboration to
steve authored
336 NetECReal* NetECReal::dup_expr() const
337 {
338 NetECReal*tmp = new NetECReal(value_);
339 tmp->set_line(*this);
340 return tmp;
341 }
342
343 NetExpr::TYPE NetECReal::expr_type() const
344 {
345 return ET_REAL;
346 }
347
5903f07 Support parameters in real expressions and
steve authored
348 NetECRealParam::NetECRealParam(NetScope*s, const char*n, const verireal&v)
349 : NetECReal(v), scope_(s), name_(n)
350 {
351 }
352
353 NetECRealParam::~NetECRealParam()
354 {
355 }
356
357 const char* NetECRealParam::name() const
358 {
359 return name_;
360 }
361
362 const NetScope* NetECRealParam::scope() const
363 {
364 return scope_;
365 }
366
367
7e1e44e Properly cast signedness of parameters with ranges.
steve authored
368 NetEParam::NetEParam()
4350180 Redo the parameter vector support to allow
steve authored
369 : des_(0), scope_(0)
7e1e44e Properly cast signedness of parameters with ranges.
steve authored
370 {
371 }
372
373 NetEParam::NetEParam(Design*d, NetScope*s, const hname_t&n)
374 : des_(d), scope_(s), name_(n)
375 {
376 }
377
378 NetEParam::~NetEParam()
379 {
380 }
381
382 bool NetEParam::has_width() const
383 {
384 return false;
385 }
386
387 NetEParam* NetEParam::dup_expr() const
388 {
5903f07 Support parameters in real expressions and
steve authored
389 NetEParam*tmp = new NetEParam(des_, scope_, name_);
390 tmp->set_line(*this);
391 return tmp;
7e1e44e Properly cast signedness of parameters with ranges.
steve authored
392 }
393
5796524 Add ne_expr.cc
steve authored
394 NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid)
395 : expr_(exp), base_(base)
396 {
397 expr_width(wid);
398 }
399
400 NetESelect::~NetESelect()
401 {
402 delete expr_;
403 delete base_;
404 }
405
406 const NetExpr*NetESelect::sub_expr() const
407 {
408 return expr_;
409 }
410
411 const NetExpr*NetESelect::select() const
412 {
413 return base_;
414 }
415
416 bool NetESelect::has_width() const
417 {
418 return true;
419 }
420
421 bool NetESelect::set_width(unsigned w)
422 {
423 if (expr_width() == 1)
424 return true;
425 else
426 return false;
427 }
428
6d94f2e Better organize the NetESFunc return type guesses.
steve authored
429 NetESFunc::NetESFunc(const char*n, NetExpr::TYPE t,
430 unsigned width, unsigned np)
431 : name_(0), type_(t)
04ada23 Support in various contexts the $realtime
steve authored
432 {
4c67de5 Add the lex_strings string handler, and put
steve authored
433 name_ = lex_strings.add(n);
04ada23 Support in various contexts the $realtime
steve authored
434 expr_width(width);
435 nparms_ = np;
436 parms_ = new NetExpr*[np];
437 for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
438 parms_[idx] = 0;
439 }
440
441 NetESFunc::~NetESFunc()
442 {
443 for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
444 if (parms_[idx]) delete parms_[idx];
445
446 delete[]parms_;
4c67de5 Add the lex_strings string handler, and put
steve authored
447 /* name_ string ls lex_strings allocated. */
04ada23 Support in various contexts the $realtime
steve authored
448 }
449
450 const char* NetESFunc::name() const
451 {
452 return name_;
453 }
454
455 unsigned NetESFunc::nparms() const
456 {
457 return nparms_;
458 }
459
460 void NetESFunc::parm(unsigned idx, NetExpr*v)
461 {
462 assert(idx < nparms_);
463 if (parms_[idx])
464 delete parms_[idx];
465 parms_[idx] = v;
466 }
467
468 const NetExpr* NetESFunc::parm(unsigned idx) const
469 {
470 assert(idx < nparms_);
471 return parms_[idx];
472 }
473
474 NetExpr* NetESFunc::parm(unsigned idx)
475 {
476 assert(idx < nparms_);
477 return parms_[idx];
478 }
479
480 NetExpr::TYPE NetESFunc::expr_type() const
481 {
6d94f2e Better organize the NetESFunc return type guesses.
steve authored
482 return type_;
04ada23 Support in various contexts the $realtime
steve authored
483 }
484
5796524 Add ne_expr.cc
steve authored
485 /*
486 * $Log: net_expr.cc,v $
5903f07 Support parameters in real expressions and
steve authored
487 * Revision 1.18 2003/05/30 02:55:32 steve
488 * Support parameters in real expressions and
489 * as real expressions, and fix multiply and
490 * divide with real results.
491 *
7e2848b Do not try to set constants to width 0.
steve authored
492 * Revision 1.17 2003/05/20 15:05:33 steve
493 * Do not try to set constants to width 0.
494 *
c602d94 Comparison operators do have defined width.
steve authored
495 * Revision 1.16 2003/03/15 18:08:43 steve
496 * Comparison operators do have defined width.
497 *
6d94f2e Better organize the NetESFunc return type guesses.
steve authored
498 * Revision 1.15 2003/03/15 04:46:29 steve
499 * Better organize the NetESFunc return type guesses.
500 *
4c67de5 Add the lex_strings string handler, and put
steve authored
501 * Revision 1.14 2003/03/01 06:25:30 steve
502 * Add the lex_strings string handler, and put
503 * scope names and system task/function names
504 * into this table. Also, permallocate event
505 * names from the beginning.
506 *
589422b Real constants have no defined vector width
steve authored
507 * Revision 1.13 2003/02/06 17:50:23 steve
508 * Real constants have no defined vector width
509 *
04ada23 Support in various contexts the $realtime
steve authored
510 * Revision 1.12 2003/01/27 00:14:37 steve
511 * Support in various contexts the $realtime
512 * system task.
513 *
46253ed Rework expression parsing and elaboration to
steve authored
514 * Revision 1.11 2003/01/26 21:15:58 steve
515 * Rework expression parsing and elaboration to
516 * accommodate real/realtime values and expressions.
517 *
aa8869a Postpone parameter width check to evaluation.
steve authored
518 * Revision 1.10 2002/11/09 01:40:19 steve
519 * Postpone parameter width check to evaluation.
520 *
de94d09 No need to keep excess width from an
steve authored
521 * Revision 1.9 2002/11/06 02:25:13 steve
522 * No need to keep excess width from an
523 * unsigned constant value, if it can
524 * be trimmed safely.
525 *
4350180 Redo the parameter vector support to allow
steve authored
526 * Revision 1.8 2002/10/19 22:59:49 steve
527 * Redo the parameter vector support to allow
528 * parameter names in range expressions.
529 *
7e1e44e Properly cast signedness of parameters with ranges.
steve authored
530 * Revision 1.7 2002/09/01 03:01:48 steve
531 * Properly cast signedness of parameters with ranges.
532 *
52bf4e6 conditional ident string using autoconfig.
steve authored
533 * Revision 1.6 2002/08/12 01:34:59 steve
534 * conditional ident string using autoconfig.
535 *
28e0616 Use standard name for iostream.
steve authored
536 * Revision 1.5 2002/06/06 18:57:18 steve
537 * Use standard name for iostream.
538 *
8941a59 include iostream for gcc 3.1
steve authored
539 * Revision 1.4 2002/05/25 16:51:37 steve
540 * include iostream for gcc 3.1
541 *
8667b9a Put off evaluation of concatenation repeat expresions
steve authored
542 * Revision 1.3 2002/05/05 21:11:50 steve
543 * Put off evaluation of concatenation repeat expresions
544 * until after parameters are defined. This allows parms
545 * to be used in repeat expresions.
546 *
547 * Add the builtin $signed system function.
548 *
928df5c include config.h to eliminate warnings.
steve authored
549 * Revision 1.2 2002/01/29 22:36:31 steve
550 * include config.h to eliminate warnings.
551 *
5796524 Add ne_expr.cc
steve authored
552 * Revision 1.1 2002/01/28 01:39:45 steve
553 * Add ne_expr.cc
554 *
555 */
556
Something went wrong with that request. Please try again.