Add support for conditional generate. In the process, fix bugs
[iverilog.git] / set_width.cc
blob1c1bdae8b5998f7bbee444da8c65f5fe53f6edb1
1 /*
2 * Copyright (c) 1999-2006 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)
8 * any later version.
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
19 #ifdef HAVE_CVS_IDENT
20 #ident "$Id: set_width.cc,v 1.42 2007/01/16 05:44:15 steve Exp $"
21 #endif
23 # include "config.h"
25 # include <iostream>
28 * This file contains set_width methods for the various NetExpr
29 * classes. The set_width method is used by elaboration to ask the
30 * expression to resize itself. If the expression can't, then the
31 * set_width method will return false and the caller will arrange for
32 * whatever is needed to deal with the size mismatch.
34 # include "netlist.h"
35 # include "netmisc.h"
36 # include "compiler.h"
37 # include <typeinfo>
40 bool NetExpr::set_width(unsigned w, bool)
42 cerr << get_line() << ": internal warning: "
43 <<typeid(*this).name() << ": set_width(unsigned) "
44 << "not implemented." << endl;
45 expr_width(w);
46 return false;
49 bool NetEBinary::set_width(unsigned w, bool)
51 bool flag = true;
52 switch (op_) {
54 case 'l': // left shift (<<)
55 case 'r': // right shift (>>)
56 /* these operators are handled in the derived class. */
57 assert(0);
58 break;
60 /* The default rule is that the operands of the binary
61 operator might as well use the same width as the
62 output from the binary operation. */
63 default:
64 expr_width(left_->expr_width() > right_->expr_width()
65 ? left_->expr_width() : right_->expr_width());
66 cerr << "NetEBinary::set_width(): Using default for " <<
67 op_ << "." << endl;
68 flag = false;
70 case '%':
71 case '/':
72 flag = left_->set_width(w) && flag;
73 flag = right_->set_width(w) && flag;
74 expr_width(w);
75 break;
77 return flag;
81 * The bitwise logical operators have operands the same size as the
82 * result. Anything else is a mess.
84 bool NetEBAdd::set_width(unsigned w, bool)
87 unsigned wid = w;
88 if (left_->expr_width() > wid)
89 wid = left_->expr_width();
90 if (right_->expr_width() > wid)
91 wid = right_->expr_width();
93 left_->set_width(wid);
94 right_->set_width(wid);
96 if (left_->expr_width() < wid) {
97 NetExpr*tmp = new NetESelect(left_, 0, wid);
98 tmp->cast_signed(left_->has_sign());
99 left_ = tmp;
102 if (right_->expr_width() < wid) {
103 NetExpr*tmp = new NetESelect(right_, 0, wid);
104 tmp->cast_signed(right_->has_sign());
105 right_ = tmp;
108 expr_width(wid);
109 return wid == w;
113 * The bitwise logical operators have operands the same size as the
114 * result. Anything else is a mess. I first try to get the operands to
115 * shrink to the desired size. I then expand operands that are too small.
117 bool NetEBBits::set_width(unsigned w, bool)
119 /* First, give the operands a chance to adjust themselves to
120 the requested width. */
121 left_->set_width(w);
122 right_->set_width(w);
125 /* */
127 unsigned use_width = w;
130 /* If the operands end up too small, then pad them to suit. */
132 if (left_->expr_width() < use_width) {
133 NetExpr*tmp = pad_to_width(left_, use_width);
134 assert(tmp);
135 left_ = tmp;
138 if (right_->expr_width() < w) {
139 NetExpr*tmp = pad_to_width(right_, use_width);
140 assert(tmp);
141 right_ = tmp;
145 /* And here is the final width. If this is not the size the
146 caller requested, then return false. Otherwise, return
147 true. */
148 expr_width(use_width);
149 return w == use_width;
153 * Comparison operators allow the subexpressions to have
154 * their own natural width, but the comparison operator result has a
155 * fixed width of 1.
157 bool NetEBComp::set_width(unsigned w, bool)
159 return (w == 1);
163 * There is nothing we can do to the operands of a division to make it
164 * confirm to the requested width. Force the context to pad or truncate.
166 bool NetEBDiv::set_width(unsigned w, bool)
168 return w == expr_width();
171 bool NetEBLogic::set_width(unsigned w, bool)
173 bool flag;
174 flag = left_->set_width(right_->expr_width());
175 if (!flag)
176 flag = right_->set_width(left_->expr_width());
177 return (w == 1);
181 * There is nothing we can do to the operands of a multiply to make it
182 * confirm to the requested width. Force the context to pad or truncate.
184 bool NetEBMult::set_width(unsigned w, bool)
186 return w == expr_width();
189 bool NetEBPow::set_width(unsigned w, bool last_chance)
191 bool flag = left_->set_width(w, last_chance);
192 return flag;
196 * The shift operator allows the shift amount to have its own
197 * natural width. The width of the operator result is the width of the
198 * left operand, the value that is to be shifted.
200 bool NetEBShift::set_width(unsigned w, bool)
202 bool flag = true;
204 switch (op()) {
206 case 'l':
207 left_->set_width(w);
208 if (left_->expr_width() < w)
209 left_ = pad_to_width(left_, w);
210 break;
212 case 'r':
213 case 'R':
214 if (left_->expr_width() < w)
215 left_ = pad_to_width(left_, w);
216 break;
218 default:
219 assert(0);
222 expr_width(left_->expr_width());
223 flag = expr_width() == w;
225 return flag;
229 * Add up the widths from all the expressions that are concatenated
230 * together. This is the width of the expression, tough luck if you
231 * want it otherwise.
233 * If during the course of elaboration one of the sub-expressions is
234 * broken, then don't count it in the width. This doesn't really
235 * matter because the null expression is indication of an error and
236 * the compiler will not go beyond elaboration.
238 bool NetEConcat::set_width(unsigned w, bool)
240 unsigned sum = 0;
241 for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
242 if (parms_[idx] != 0)
243 sum += parms_[idx]->expr_width();
245 sum *= repeat();
246 expr_width(sum);
247 if (sum != w) return false;
248 return true;
251 bool NetEConst::set_width(unsigned w, bool last_chance)
253 if (w == value_.len()) {
254 expr_width(w);
255 return true;
258 assert(w != 0);
260 if (w > value_.len()) {
261 verinum::V pad = verinum::V0;
262 if (value_.has_sign()) {
263 pad = value_.get(value_.len()-1);
265 } else if (value_.len() == 0) {
266 pad = verinum::V0;
268 } else switch (value_.get(value_.len()-1)) {
269 case verinum::V1:
270 case verinum::V0:
271 break;
272 case verinum::Vx:
273 pad = verinum::Vx;
274 break;
275 case verinum::Vz:
276 pad = verinum::Vz;
277 break;
280 verinum tmp (verinum::V0, w, has_width());
281 for (unsigned idx = 0 ; idx < value_.len() ; idx += 1)
282 tmp.set(idx, value_[idx]);
283 for (unsigned idx = value_.len() ; idx < w ; idx += 1)
284 tmp.set(idx, pad);
286 tmp.has_sign(value_.has_sign());
287 value_ = tmp;
289 expr_width(w);
290 return true;
292 } else {
293 unsigned use_w = w;
295 verinum::V pad_bit = value_.has_sign()
296 ? value_[value_.len() - 1]
297 : verinum::V0;
299 if (! last_chance) {
300 // Don't reduce a number too small to hold all the
301 // significant bits.
302 for (unsigned idx = w ; idx < value_.len() ; idx += 1)
303 if (value_[idx] != pad_bit)
304 use_w = idx+1;
306 // Correct for the special case of signed value. We
307 // cannot have the result change sign on us.
308 if (value_.has_sign() && (use_w < value_.len())
309 && (value_[use_w-1] != pad_bit))
310 use_w += 1;
313 verinum tmp (verinum::V0, use_w, has_width());
314 for (unsigned idx = 0 ; idx < use_w ; idx += 1)
315 tmp.set(idx, value_[idx]);
317 tmp.has_sign(value_.has_sign());
318 value_ = tmp;
319 expr_width(use_w);
320 return use_w == w;
325 * Parameter vectors cannot be resized because they refer to a common
326 * value.
328 bool NetEConstParam::set_width(unsigned w, bool)
330 return w == expr_width();
334 * Real constants can have whatever width the environment wants,
335 * because it isn't really a vector. The environment will convert this
336 * to a vector at the right time.
338 bool NetECReal::set_width(unsigned w, bool)
340 expr_width(w);
341 return true;
343 #if 0
344 bool NetEMemory::set_width(unsigned w, bool)
346 if (w != mem_->width())
347 return false;
349 expr_width(w);
350 return true;
352 #endif
353 bool NetEParam::set_width(unsigned, bool)
355 return false;
358 bool NetESelect::set_width(unsigned w, bool)
360 if (expr_width() == 1)
361 return true;
362 else
363 return false;
366 bool NetESFunc::set_width(unsigned w, bool)
368 return w == expr_width();
372 * The signal should automatically pad with zeros to get to the desired
373 * width. Do not allow signal bits to be truncated, however.
375 bool NetESignal::set_width(unsigned w, bool)
377 if (w != vector_width())
378 return false;
380 return true;
383 bool NetETernary::set_width(unsigned w, bool last_chance)
385 bool flag = true;
386 flag = flag && true_val_->set_width(w, last_chance);
387 flag = flag && false_val_->set_width(w, last_chance);
389 /* The ternary really insists that the true and false clauses
390 have the same width. Even if we fail to make the width that
391 the user requests, at least pad the smaller width to suit
392 the larger. */
393 if (true_val_->expr_width() < false_val_->expr_width())
394 true_val_ = pad_to_width(true_val_, false_val_->expr_width());
395 if (false_val_->expr_width() < true_val_->expr_width())
396 false_val_ = pad_to_width(false_val_, true_val_->expr_width());
398 expr_width(true_val_->expr_width());
399 return flag;
403 * XXXX FIX ME: For now, just take whatever the caller says as my
404 * width. What I really need to do is note the width of the output
405 * parameter of the function definition and take that into account.
407 bool NetEUFunc::set_width(unsigned wid, bool)
409 expr_width(wid);
410 return true;
413 bool NetEUnary::set_width(unsigned w, bool)
415 bool flag = true;
416 switch (op_) {
417 case '~':
418 case '-':
419 flag = expr_->set_width(w);
420 expr_width(w);
421 break;
422 case '!':
423 return w == 1;
424 default:
425 flag = expr_width() == w;
426 break;
429 return flag;
433 * Unary reduction operators allow its operand to have any width. The
434 * result is defined to be 1.
436 bool NetEUReduce::set_width(unsigned w, bool)
438 return w == 1;
443 * $Log: set_width.cc,v $
444 * Revision 1.42 2007/01/16 05:44:15 steve
445 * Major rework of array handling. Memories are replaced with the
446 * more general concept of arrays. The NetMemory and NetEMemory
447 * classes are removed from the ivl core program, and the IVL_LPM_RAM
448 * lpm type is removed from the ivl_target API.
450 * Revision 1.41 2006/11/04 06:19:25 steve
451 * Remove last bits of relax_width methods, and use test_width
452 * to calculate the width of an r-value expression that may
453 * contain unsized numbers.
455 * Revision 1.40 2006/10/30 05:44:49 steve
456 * Expression widths with unsized literals are pseudo-infinite width.
458 * Revision 1.39 2006/07/31 03:50:17 steve
459 * Add support for power in constant expressions.
461 * Revision 1.38 2006/05/02 04:29:42 steve
462 * Be more stubborn about widths.
464 * Revision 1.37 2005/11/26 00:35:44 steve
465 * More precise about r-value width of constants.
467 * Revision 1.36 2005/05/17 20:56:55 steve
468 * Parameters cannot have their width changed.
470 * Revision 1.35 2005/01/24 05:28:31 steve
471 * Remove the NetEBitSel and combine all bit/part select
472 * behavior into the NetESelect node and IVL_EX_SELECT
473 * ivl_target expression type.
475 * Revision 1.34 2003/08/28 04:11:19 steve
476 * Spelling patch.
478 * Revision 1.33 2003/07/26 03:34:42 steve
479 * Start handling pad of expressions in code generators.
481 * Revision 1.32 2003/06/21 01:21:43 steve
482 * Harmless fixup of warnings.
484 * Revision 1.31 2003/06/18 03:55:19 steve
485 * Add arithmetic shift operators.
487 * Revision 1.30 2003/05/20 15:05:33 steve
488 * Do not try to set constants to width 0.
490 * Revision 1.29 2003/05/04 20:04:09 steve
491 * Fix truncation of signed constant in constant addition.
493 * Revision 1.28 2003/04/02 04:25:26 steve
494 * Fix xz extension of constants.
496 * Revision 1.27 2003/02/06 17:50:23 steve
497 * Real constants have no defined vector width
499 * Revision 1.26 2003/01/26 21:02:21 steve
500 * Remember to save signedness of number.
502 * Revision 1.25 2002/11/13 03:03:08 steve
503 * Do not truncate high bits of right shift.
505 * Revision 1.24 2002/11/06 02:25:13 steve
506 * No need to keep excess width from an
507 * unsigned constant value, if it can
508 * be trimmed safely.
510 * Revision 1.23 2002/08/12 01:35:00 steve
511 * conditional ident string using autoconfig.
513 * Revision 1.22 2002/05/05 21:11:50 steve
514 * Put off evaluation of concatenation repeat expresions
515 * until after parameters are defined. This allows parms
516 * to be used in repeat expresions.
518 * Add the builtin $signed system function.
520 * Revision 1.21 2002/04/27 04:49:27 steve
521 * If the verinum is already right, no need to reset it.
523 * Revision 1.20 2001/11/19 04:26:46 steve
524 * Unary reduction operators are all 1-bit results.
526 * Revision 1.19 2001/07/27 04:51:44 steve
527 * Handle part select expressions as variants of
528 * NetESignal/IVL_EX_SIGNAL objects, instead of
529 * creating new and useless temporary signals.
531 * Revision 1.18 2001/07/25 03:10:49 steve
532 * Create a config.h.in file to hold all the config
533 * junk, and support gcc 3.0. (Stephan Boettcher)
535 * Revision 1.17 2001/02/08 01:10:30 steve
536 * Remove dead code.
538 * Revision 1.16 2001/02/07 21:47:13 steve
539 * Fix expression widths for rvalues and parameters (PR#131,132)
541 * Revision 1.15 2001/01/27 05:41:48 steve
542 * Fix sign extension of evaluated constants. (PR#91)
544 * Revision 1.14 2000/06/18 03:29:52 steve
545 * Handle width expansion of shift operators.
547 * Revision 1.13 2000/05/04 03:37:59 steve
548 * Add infrastructure for system functions, move
549 * $time to that structure and add $random.
551 * Revision 1.12 2000/04/28 18:43:23 steve
552 * integer division in expressions properly get width.
554 * Revision 1.11 2000/04/26 03:33:32 steve
555 * Do not set width too small to hold significant bits.
557 * Revision 1.10 2000/04/21 02:46:42 steve
558 * Many Unary operators have known widths.
560 * Revision 1.9 2000/02/23 02:56:55 steve
561 * Macintosh compilers do not support ident.
563 * Revision 1.8 2000/01/13 03:35:35 steve
564 * Multiplication all the way to simulation.
566 * Revision 1.7 2000/01/01 19:56:51 steve
567 * Properly expand/shrink constants in expressions.
569 * Revision 1.6 1999/10/05 06:19:46 steve
570 * Add support for reduction NOR.
572 * Revision 1.5 1999/10/05 04:02:10 steve
573 * Relaxed width handling for <= assignment.
575 * Revision 1.4 1999/09/29 00:42:51 steve
576 * Allow expanding of additive operators.
578 * Revision 1.3 1999/09/23 03:56:57 steve
579 * Support shift operators.
581 * Revision 1.2 1999/09/23 02:27:50 steve
582 * comparison parameter width is self determined.
584 * Revision 1.1 1999/09/23 00:21:55 steve
585 * Move set_width methods into a single file,
586 * Add the NetEBLogic class for logic expressions,
587 * Fix error setting with of && in if statements.