2 * Copyright (c) 2000-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)
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 #ident "$Id: elab_lval.cc,v 1.44 2007/06/02 03:42:12 steve Exp $"
28 # include "compiler.h"
30 # include "ivl_assert.h"
33 * These methods generate a NetAssign_ object for the l-value of the
34 * assignment. This is common code for the = and <= statements.
36 * What gets generated depends on the structure of the l-value. If the
37 * l-value is a simple name (i.e., foo <= <value>) the the NetAssign_
38 * is created the width of the foo reg and connected to all the
41 * If there is a part select (i.e., foo[3:1] <= <value>) the NetAssign_
42 * is made only as wide as it needs to be (3 bits in this example) and
43 * connected to the correct bits of foo. A constant bit select is a
44 * special case of the part select.
46 * If the bit-select is non-constant (i.e., foo[<expr>] = <value>) the
47 * NetAssign_ is made wide enough to connect to all the bits of foo,
48 * then the mux expression is elaborated and attached to the
49 * NetAssign_ node as a b_mux value. The target must interpret the
50 * presence of a bmux value as taking a single bit and assigning it to
51 * the bit selected by the bmux expression.
53 * If the l-value expression is non-trivial, but can be fully
54 * evaluated at compile time (meaning any bit selects are constant)
55 * then elaboration will make a single NetAssign_ that connects to a
56 * synthetic reg that in turn connects to all the proper pins of the
59 * This last case can turn up in statements like: {a, b[1]} = c;
60 * rather then create a NetAssign_ for each item in the concatenation,
61 * elaboration makes a single NetAssign_ and connects it up properly.
66 * The default interpretation of an l-value to a procedural assignment
67 * is to try to make a net elaboration, and see if the result is
68 * suitable for assignment.
70 NetAssign_
* PExpr::elaborate_lval(Design
*des
,
76 cerr
<< get_line() << ": Assignment l-value too complex."
81 NetAssign_
*lv
= new NetAssign_(ll
);
86 * Concatenation expressions can appear as l-values. Handle them here.
88 * If adjacent l-values in the concatenation are not bit selects, then
89 * merge them into a single NetAssign_ object. This can happen is code
90 * like ``{ ...a, b, ...}''. As long as "a" and "b" do not have bit
91 * selects (or the bit selects are constant) we can merge the
94 * Be careful to get the bit order right. In the expression ``{a, b}''
95 * a is the MSB and b the LSB. Connect the LSB to the low pins of the
98 NetAssign_
* PEConcat::elaborate_lval(Design
*des
,
103 cerr
<< get_line() << ": error: Repeat concatenations make "
104 "no sense in l-value expressions. I refuse." << endl
;
111 for (unsigned idx
= 0 ; idx
< parms_
.count() ; idx
+= 1) {
113 if (parms_
[idx
] == 0) {
114 cerr
<< get_line() << ": error: Empty expressions "
115 << "not allowed in concatenations." << endl
;
120 NetAssign_
*tmp
= parms_
[idx
]->elaborate_lval(des
, scope
, is_force
);
122 /* If the l-value doesn't elaborate, the error was
123 already detected and printed. We just skip it and let
124 the compiler catch more errors. */
131 /* Link the new l-value to the previous one. */
133 NetAssign_
*last
= tmp
;
145 * Handle the ident as an l-value. This includes bit and part selects
148 NetAssign_
* PEIdent::elaborate_lval(Design
*des
,
153 const NetExpr
*par
= 0;
156 symbol_search(des
, scope
, path_
, reg
, par
, eve
);
158 cerr
<< get_line() << ": error: Could not find variable ``"
159 << path_
<< "'' in ``" << scope_path(scope
) <<
166 ivl_assert(*this, reg
);
168 const name_component_t
&name_tail
= path_
.back();
170 index_component_t::ctype_t use_sel
= index_component_t::SEL_NONE
;
171 if (!name_tail
.index
.empty())
172 use_sel
= name_tail
.index
.back().sel
;
174 // This is the special case that the l-value is an entire
175 // memory. This is, in fact, an error.
176 if (reg
->array_dimensions() > 0 && name_tail
.index
.empty()) {
177 cerr
<< get_line() << ": error: Cannot assign to array "
178 << path_
<< ". Did you forget a word index?" << endl
;
183 if (reg
->array_dimensions() > 0)
184 return elaborate_lval_net_word_(des
, scope
, reg
);
186 if (use_sel
== index_component_t::SEL_PART
) {
187 NetAssign_
*lv
= new NetAssign_(reg
);
188 elaborate_lval_net_part_(des
, scope
, lv
);
192 if (use_sel
== index_component_t::SEL_IDX_UP
||
193 use_sel
== index_component_t::SEL_IDX_DO
) {
194 NetAssign_
*lv
= new NetAssign_(reg
);
195 elaborate_lval_net_idx_(des
, scope
, lv
, use_sel
);
199 /* Get the signal referenced by the identifier, and make sure
200 it is a register. Wires are not allows in this context,
201 unless this is the l-value of a force. */
202 if ((reg
->type() != NetNet::REG
) && !is_force
) {
203 cerr
<< get_line() << ": error: " << path_
<<
204 " is not a valid l-value in " << scope_path(scope
) <<
206 cerr
<< reg
->get_line() << ": : " << path_
<<
207 " is declared here as " << reg
->type() << "." << endl
;
215 if (use_sel
== index_component_t::SEL_BIT
) {
217 const index_component_t
&index_tail
= name_tail
.index
.back();
218 ivl_assert(*this, index_tail
.msb
!= 0);
219 ivl_assert(*this, index_tail
.lsb
== 0);
221 /* If there is only a single select expression, it is a
222 bit select. Evaluate the constant value and treat it
223 as a part select with a bit width of 1. If the
224 expression it not constant, then return the
225 expression as a mux. */
227 NetExpr
*index_expr
= elab_and_eval(des
, scope
, index_tail
.msb
, -1);
229 if (NetEConst
*index_con
= dynamic_cast<NetEConst
*> (index_expr
)) {
230 msb
= index_con
->value().as_long();
231 lsb
= index_con
->value().as_long();
242 /* No select expressions, so presume a part select the
243 width of the register. */
254 /* If there is a non-constant bit select, make a
255 NetAssign_ to the target reg and attach a
256 bmux to select the target bit. */
257 lv
= new NetAssign_(reg
);
259 /* Correct the mux for the range of the vector. */
260 if (reg
->msb() < reg
->lsb())
261 mux
= make_sub_expr(reg
->lsb(), mux
);
262 else if (reg
->lsb() != 0)
263 mux
= make_add_expr(mux
, - reg
->lsb());
265 lv
->set_part(mux
, 1);
267 } else if (msb
== reg
->msb() && lsb
== reg
->lsb()) {
269 /* No bit select, and part select covers the entire
270 vector. Simplest case. */
271 lv
= new NetAssign_(reg
);
275 /* If the bit/part select is constant, then make the
276 NetAssign_ only as wide as it needs to be and connect
277 only to the selected bits of the reg. */
278 unsigned loff
= reg
->sb_to_idx(lsb
);
279 unsigned moff
= reg
->sb_to_idx(msb
);
280 unsigned wid
= moff
- loff
+ 1;
283 cerr
<< get_line() << ": error: part select "
284 << reg
->name() << "[" << msb
<<":"<<lsb
<<"]"
285 << " is reversed." << endl
;
290 /* If the part select extends beyond the extreme of the
291 variable, then report an error. Note that loff is
292 converted to normalized form so is relative the
295 if ((wid
+ loff
) > reg
->vector_width()) {
296 cerr
<< get_line() << ": error: bit/part select "
297 << reg
->name() << "[" << msb
<<":"<<lsb
<<"]"
298 << " is out of range." << endl
;
303 lv
= new NetAssign_(reg
);
304 lv
->set_part(new NetEConst(verinum(loff
)), wid
);
311 NetAssign_
* PEIdent::elaborate_lval_net_word_(Design
*des
,
315 const name_component_t
&name_tail
= path_
.back();
316 ivl_assert(*this, !name_tail
.index
.empty());
318 const index_component_t
&index_head
= name_tail
.index
.front();
319 if (index_head
.sel
== index_component_t::SEL_PART
) {
320 cerr
<< get_line() << ": error: cannot perform a part "
321 << "select on array " << reg
->name() << "." << endl
;
326 ivl_assert(*this, index_head
.sel
== index_component_t::SEL_BIT
);
327 ivl_assert(*this, index_head
.msb
!= 0);
328 ivl_assert(*this, index_head
.lsb
== 0);
330 NetExpr
*word
= elab_and_eval(des
, scope
, index_head
.msb
, -1);
332 // If there is a non-zero base to the memory, then build an
333 // expression to calculate the canonical address.
334 if (long base
= reg
->array_first()) {
336 word
= make_add_expr(word
, 0-base
);
337 if (NetExpr
*tmp
= word
->eval_tree()) {
342 NetAssign_
*lv
= new NetAssign_(reg
);
346 cerr
<< get_line() << ": debug: Set array word=" << *word
<< endl
;
348 // Test for the case that the index is a constant, and is out
349 // of bounds. The "word" expression is the word index already
350 // converted to canonical address, so this just needs to check
351 // that the address is not too big.
352 if (NetEConst
*word_const
= dynamic_cast<NetEConst
*>(word
)) {
353 verinum word_val
= word_const
->value();
354 long index
= word_val
.as_long();
355 if (index
< 0 || index
>= reg
->array_count()) {
356 cerr
<< get_line() << ": warning: Constant array index "
357 << (index
+ reg
->array_first())
358 << " is out of range for array "
359 << reg
->name() << "." << endl
;
363 /* An array word may also have part selects applied to them. */
365 index_component_t::ctype_t use_sel
= index_component_t::SEL_NONE
;
366 if (name_tail
.index
.size() > 1)
367 use_sel
= name_tail
.index
.back().sel
;
369 if (use_sel
== index_component_t::SEL_PART
)
370 elaborate_lval_net_part_(des
, scope
, lv
);
372 if (use_sel
== index_component_t::SEL_IDX_UP
||
373 use_sel
== index_component_t::SEL_IDX_DO
)
374 elaborate_lval_net_idx_(des
, scope
, lv
, use_sel
);
379 bool PEIdent::elaborate_lval_net_part_(Design
*des
,
384 bool flag
= calculate_parts_(des
, scope
, msb
, lsb
);
388 NetNet
*reg
= lv
->sig();
391 if (msb
== reg
->msb() && lsb
== reg
->lsb()) {
393 /* No bit select, and part select covers the entire
394 vector. Simplest case. */
398 /* If the bit/part select is constant, then make the
399 NetAssign_ only as wide as it needs to be and connect
400 only to the selected bits of the reg. */
401 unsigned loff
= reg
->sb_to_idx(lsb
);
402 unsigned moff
= reg
->sb_to_idx(msb
);
403 unsigned wid
= moff
- loff
+ 1;
406 cerr
<< get_line() << ": error: part select "
407 << reg
->name() << "[" << msb
<<":"<<lsb
<<"]"
408 << " is reversed." << endl
;
413 /* If the part select extends beyond the extreme of the
414 variable, then report an error. Note that loff is
415 converted to normalized form so is relative the
418 if ((wid
+ loff
) > reg
->vector_width()) {
419 cerr
<< get_line() << ": error: bit/part select "
420 << reg
->name() << "[" << msb
<<":"<<lsb
<<"]"
421 << " is out of range." << endl
;
426 lv
->set_part(new NetEConst(verinum(loff
)), wid
);
432 bool PEIdent::elaborate_lval_net_idx_(Design
*des
,
435 index_component_t::ctype_t use_sel
) const
437 const name_component_t
&name_tail
= path_
.back();;
438 ivl_assert(*this, !name_tail
.index
.empty());
440 const index_component_t
&index_tail
= name_tail
.index
.back();
441 ivl_assert(*this, index_tail
.msb
!= 0);
442 ivl_assert(*this, index_tail
.lsb
!= 0);
444 NetNet
*reg
= lv
->sig();
447 if (reg
->type() != NetNet::REG
) {
448 cerr
<< get_line() << ": error: " << path_
<<
449 " is not a reg/integer/time in " << scope_path(scope
) <<
451 cerr
<< reg
->get_line() << ": : " << path_
<<
452 " is declared here as " << reg
->type() << "." << endl
;
458 calculate_up_do_width_(des
, scope
, wid
);
460 NetExpr
*base
= elab_and_eval(des
, scope
, index_tail
.msb
, -1);
462 /* Correct the mux for the range of the vector. */
463 if (reg
->msb() < reg
->lsb())
464 base
= make_sub_expr(reg
->lsb(), base
);
465 else if (reg
->lsb() != 0)
466 base
= make_add_expr(base
, - reg
->lsb());
468 if (use_sel
== index_component_t::SEL_IDX_DO
&& wid
> 1 ) {
469 base
= make_add_expr(base
, 1-(long)wid
);
473 cerr
<< get_line() << ": debug: Set part select width="
474 << wid
<< ", base=" << *base
<< endl
;
476 lv
->set_part(base
, wid
);
481 NetAssign_
* PENumber::elaborate_lval(Design
*des
, NetScope
*, bool) const
483 cerr
<< get_line() << ": error: Constant values not allowed "
484 << "in l-value expressions." << endl
;