Merge branch 'master' into verilog-ams
[sverilog.git] / elab_lval.cc
blob14402801b2aa23dd76b64406532ef40eb3a7a141
1 /*
2 * Copyright (c) 2000-2008 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
20 # include "config.h"
22 # include "PExpr.h"
23 # include "netlist.h"
24 # include "netmisc.h"
25 # include "compiler.h"
26 # include <cstdlib>
27 # include <iostream>
28 # include <climits>
29 # include "ivl_assert.h"
32 * These methods generate a NetAssign_ object for the l-value of the
33 * assignment. This is common code for the = and <= statements.
35 * What gets generated depends on the structure of the l-value. If the
36 * l-value is a simple name (i.e., foo <= <value>) then the NetAssign_
37 * is created the width of the foo reg and connected to all the
38 * bits.
40 * If there is a part select (i.e., foo[3:1] <= <value>) the NetAssign_
41 * is made only as wide as it needs to be (3 bits in this example) and
42 * connected to the correct bits of foo. A constant bit select is a
43 * special case of the part select.
45 * If the bit-select is non-constant (i.e., foo[<expr>] = <value>) the
46 * NetAssign_ is made wide enough to connect to all the bits of foo,
47 * then the mux expression is elaborated and attached to the
48 * NetAssign_ node as a b_mux value. The target must interpret the
49 * presence of a bmux value as taking a single bit and assigning it to
50 * the bit selected by the bmux expression.
52 * If the l-value expression is non-trivial, but can be fully
53 * evaluated at compile time (meaning any bit selects are constant)
54 * then elaboration will make a single NetAssign_ that connects to a
55 * synthetic reg that in turn connects to all the proper pins of the
56 * l-value.
58 * This last case can turn up in statements like: {a, b[1]} = c;
59 * rather then create a NetAssign_ for each item in the concatenation,
60 * elaboration makes a single NetAssign_ and connects it up properly.
65 * The default interpretation of an l-value to a procedural assignment
66 * is to try to make a net elaboration, and see if the result is
67 * suitable for assignment.
69 NetAssign_* PExpr::elaborate_lval(Design*des,
70 NetScope*scope,
71 bool is_force) const
73 NetNet*ll = 0;
74 if (ll == 0) {
75 cerr << get_fileline() << ": Assignment l-value too complex."
76 << endl;
77 return 0;
80 NetAssign_*lv = new NetAssign_(ll);
81 return lv;
85 * Concatenation expressions can appear as l-values. Handle them here.
87 * If adjacent l-values in the concatenation are not bit selects, then
88 * merge them into a single NetAssign_ object. This can happen is code
89 * like ``{ ...a, b, ...}''. As long as "a" and "b" do not have bit
90 * selects (or the bit selects are constant) we can merge the
91 * NetAssign_ objects.
93 * Be careful to get the bit order right. In the expression ``{a, b}''
94 * a is the MSB and b the LSB. Connect the LSB to the low pins of the
95 * NetAssign_ object.
97 NetAssign_* PEConcat::elaborate_lval(Design*des,
98 NetScope*scope,
99 bool is_force) const
101 if (repeat_) {
102 cerr << get_fileline() << ": error: Repeat concatenations make "
103 "no sense in l-value expressions. I refuse." << endl;
104 des->errors += 1;
105 return 0;
108 NetAssign_*res = 0;
110 for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
112 if (parms_[idx] == 0) {
113 cerr << get_fileline() << ": error: Empty expressions "
114 << "not allowed in concatenations." << endl;
115 des->errors += 1;
116 continue;
119 NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope, is_force);
121 /* If the l-value doesn't elaborate, the error was
122 already detected and printed. We just skip it and let
123 the compiler catch more errors. */
124 if (tmp == 0)
125 continue;
127 assert(tmp);
130 /* Link the new l-value to the previous one. */
132 NetAssign_*last = tmp;
133 while (last->more)
134 last = last->more;
136 last->more = res;
137 res = tmp;
140 return res;
144 * Handle the ident as an l-value. This includes bit and part selects
145 * of that ident.
147 NetAssign_* PEIdent::elaborate_lval(Design*des,
148 NetScope*scope,
149 bool is_force) const
151 NetNet* reg = 0;
152 const NetExpr*par = 0;
153 NetEvent* eve = 0;
155 symbol_search(des, scope, path_, reg, par, eve);
156 if (reg == 0) {
157 cerr << get_fileline() << ": error: Could not find variable ``"
158 << path_ << "'' in ``" << scope_path(scope) <<
159 "''" << endl;
161 des->errors += 1;
162 return 0;
165 ivl_assert(*this, reg);
167 const name_component_t&name_tail = path_.back();
169 index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
170 if (!name_tail.index.empty())
171 use_sel = name_tail.index.back().sel;
173 // This is the special case that the l-value is an entire
174 // memory. This is, in fact, an error.
175 if (reg->array_dimensions() > 0 && name_tail.index.empty()) {
176 cerr << get_fileline() << ": error: Cannot assign to array "
177 << path_ << ". Did you forget a word index?" << endl;
178 des->errors += 1;
179 return 0;
182 if (reg->array_dimensions() > 0)
183 return elaborate_lval_net_word_(des, scope, reg);
185 if (use_sel == index_component_t::SEL_PART) {
186 NetAssign_*lv = new NetAssign_(reg);
187 elaborate_lval_net_part_(des, scope, lv);
188 return lv;
191 if (use_sel == index_component_t::SEL_IDX_UP ||
192 use_sel == index_component_t::SEL_IDX_DO) {
193 NetAssign_*lv = new NetAssign_(reg);
194 elaborate_lval_net_idx_(des, scope, lv, use_sel);
195 return lv;
198 /* Get the signal referenced by the identifier, and make sure
199 it is a register. Wires are not allows in this context,
200 unless this is the l-value of a force. */
201 if ((reg->type() != NetNet::REG) && !is_force) {
202 cerr << get_fileline() << ": error: " << path_ <<
203 " is not a valid l-value in " << scope_path(scope) <<
204 "." << endl;
205 cerr << reg->get_fileline() << ": : " << path_ <<
206 " is declared here as " << reg->type() << "." << endl;
207 des->errors += 1;
208 return 0;
211 long msb, lsb;
212 NetExpr*mux;
214 if (use_sel == index_component_t::SEL_BIT) {
216 const index_component_t&index_tail = name_tail.index.back();
217 ivl_assert(*this, index_tail.msb != 0);
218 ivl_assert(*this, index_tail.lsb == 0);
220 /* If there is only a single select expression, it is a
221 bit select. Evaluate the constant value and treat it
222 as a part select with a bit width of 1. If the
223 expression it not constant, then return the
224 expression as a mux. */
226 NetExpr*index_expr = elab_and_eval(des, scope, index_tail.msb, -1);
228 if (NetEConst*index_con = dynamic_cast<NetEConst*> (index_expr)) {
229 msb = index_con->value().as_long();
230 lsb = index_con->value().as_long();
231 mux = 0;
233 } else {
234 msb = 0;
235 lsb = 0;
236 mux = index_expr;
239 } else {
241 /* No select expressions, so presume a part select the
242 width of the register. */
244 msb = reg->msb();
245 lsb = reg->lsb();
246 mux = 0;
250 NetAssign_*lv;
251 if (mux) {
253 /* If there is a non-constant bit select, make a
254 NetAssign_ to the target reg and attach a
255 bmux to select the target bit. */
256 lv = new NetAssign_(reg);
258 /* Correct the mux for the range of the vector. */
259 if (reg->msb() < reg->lsb())
260 mux = make_sub_expr(reg->lsb(), mux);
261 else if (reg->lsb() != 0)
262 mux = make_add_expr(mux, - reg->lsb());
264 lv->set_part(mux, 1);
266 } else if (msb == reg->msb() && lsb == reg->lsb()) {
268 /* No bit select, and part select covers the entire
269 vector. Simplest case. */
270 lv = new NetAssign_(reg);
272 } else {
274 /* If the bit/part select is constant, then make the
275 NetAssign_ only as wide as it needs to be and connect
276 only to the selected bits of the reg. */
277 unsigned loff = reg->sb_to_idx(lsb);
278 unsigned moff = reg->sb_to_idx(msb);
279 unsigned wid = moff - loff + 1;
281 if (moff < loff) {
282 cerr << get_fileline() << ": error: part select "
283 << reg->name() << "[" << msb<<":"<<lsb<<"]"
284 << " is reversed." << endl;
285 des->errors += 1;
286 return 0;
289 /* If the part select extends beyond the extreme of the
290 variable, then report an error. Note that loff is
291 converted to normalized form so is relative the
292 variable pins. */
294 if ((wid + loff) > reg->vector_width()) {
295 cerr << get_fileline() << ": error: bit/part select "
296 << reg->name() << "[" << msb<<":"<<lsb<<"]"
297 << " is out of range." << endl;
298 des->errors += 1;
299 return 0;
302 lv = new NetAssign_(reg);
303 lv->set_part(new NetEConst(verinum(loff)), wid);
307 return lv;
310 NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
311 NetScope*scope,
312 NetNet*reg) const
314 const name_component_t&name_tail = path_.back();
315 ivl_assert(*this, !name_tail.index.empty());
317 const index_component_t&index_head = name_tail.index.front();
318 if (index_head.sel == index_component_t::SEL_PART) {
319 cerr << get_fileline() << ": error: cannot perform a part "
320 << "select on array " << reg->name() << "." << endl;
321 des->errors += 1;
322 return 0;
325 ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
326 ivl_assert(*this, index_head.msb != 0);
327 ivl_assert(*this, index_head.lsb == 0);
329 NetExpr*word = elab_and_eval(des, scope, index_head.msb, -1);
331 // If there is a non-zero base to the memory, then build an
332 // expression to calculate the canonical address.
333 if (long base = reg->array_first()) {
335 word = make_add_expr(word, 0-base);
336 eval_expr(word);
339 NetAssign_*lv = new NetAssign_(reg);
340 lv->set_word(word);
342 if (debug_elaborate)
343 cerr << get_fileline() << ": debug: Set array word=" << *word << endl;
345 // Test for the case that the index is a constant, and is out
346 // of bounds. The "word" expression is the word index already
347 // converted to canonical address, so this just needs to check
348 // that the address is not too big.
349 if (NetEConst*word_const = dynamic_cast<NetEConst*>(word)) {
350 verinum word_val = word_const->value();
351 long index = word_val.as_long();
352 assert (reg->array_count() <= LONG_MAX);
353 if (index < 0 || index >= (long) reg->array_count()) {
354 cerr << get_fileline() << ": warning: Constant array index "
355 << (index + reg->array_first())
356 << " is out of range for array "
357 << reg->name() << "." << endl;
361 /* An array word may also have part selects applied to them. */
363 index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
364 if (name_tail.index.size() > 1)
365 use_sel = name_tail.index.back().sel;
367 if (use_sel == index_component_t::SEL_PART)
368 elaborate_lval_net_part_(des, scope, lv);
370 if (use_sel == index_component_t::SEL_IDX_UP ||
371 use_sel == index_component_t::SEL_IDX_DO)
372 elaborate_lval_net_idx_(des, scope, lv, use_sel);
374 return lv;
377 bool PEIdent::elaborate_lval_net_part_(Design*des,
378 NetScope*scope,
379 NetAssign_*lv) const
381 long msb, lsb;
382 bool flag = calculate_parts_(des, scope, msb, lsb);
383 if (!flag)
384 return false;
386 NetNet*reg = lv->sig();
387 assert(reg);
389 if (msb == reg->msb() && lsb == reg->lsb()) {
391 /* No bit select, and part select covers the entire
392 vector. Simplest case. */
394 } else {
396 /* If the bit/part select is constant, then make the
397 NetAssign_ only as wide as it needs to be and connect
398 only to the selected bits of the reg. */
399 unsigned loff = reg->sb_to_idx(lsb);
400 unsigned moff = reg->sb_to_idx(msb);
401 unsigned wid = moff - loff + 1;
403 if (moff < loff) {
404 cerr << get_fileline() << ": error: part select "
405 << reg->name() << "[" << msb<<":"<<lsb<<"]"
406 << " is reversed." << endl;
407 des->errors += 1;
408 return false;
411 /* If the part select extends beyond the extreme of the
412 variable, then report an error. Note that loff is
413 converted to normalized form so is relative the
414 variable pins. */
416 if ((wid + loff) > reg->vector_width()) {
417 cerr << get_fileline() << ": error: bit/part select "
418 << reg->name() << "[" << msb<<":"<<lsb<<"]"
419 << " is out of range." << endl;
420 des->errors += 1;
421 return false;
424 lv->set_part(new NetEConst(verinum(loff)), wid);
427 return true;
430 bool PEIdent::elaborate_lval_net_idx_(Design*des,
431 NetScope*scope,
432 NetAssign_*lv,
433 index_component_t::ctype_t use_sel) const
435 const name_component_t&name_tail = path_.back();;
436 ivl_assert(*this, !name_tail.index.empty());
438 const index_component_t&index_tail = name_tail.index.back();
439 ivl_assert(*this, index_tail.msb != 0);
440 ivl_assert(*this, index_tail.lsb != 0);
442 NetNet*reg = lv->sig();
443 assert(reg);
445 if (reg->type() != NetNet::REG) {
446 cerr << get_fileline() << ": error: " << path_ <<
447 " is not a reg/integer/time in " << scope_path(scope) <<
448 "." << endl;
449 cerr << reg->get_fileline() << ": : " << path_ <<
450 " is declared here as " << reg->type() << "." << endl;
451 des->errors += 1;
452 return false;
455 unsigned long wid;
456 calculate_up_do_width_(des, scope, wid);
458 NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
460 /* Correct the mux for the range of the vector. */
461 if (reg->msb() < reg->lsb())
462 base = make_sub_expr(reg->lsb(), base);
463 else if (reg->lsb() != 0)
464 base = make_add_expr(base, - reg->lsb());
466 if (use_sel == index_component_t::SEL_IDX_DO && wid > 1 ) {
467 base = make_add_expr(base, 1-(long)wid);
470 if (debug_elaborate)
471 cerr << get_fileline() << ": debug: Set part select width="
472 << wid << ", base=" << *base << endl;
474 lv->set_part(base, wid);
476 return true;
479 NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
481 cerr << get_fileline() << ": error: Constant values not allowed "
482 << "in l-value expressions." << endl;
483 des->errors += 1;
484 return 0;