Skip to content

HTTPS clone URL

Subversion checkout URL

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