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)
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
25 # include "compiler.h"
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
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
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
,
75 cerr
<< get_fileline() << ": Assignment l-value too complex."
80 NetAssign_
*lv
= new NetAssign_(ll
);
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
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
97 NetAssign_
* PEConcat::elaborate_lval(Design
*des
,
102 cerr
<< get_fileline() << ": error: Repeat concatenations make "
103 "no sense in l-value expressions. I refuse." << endl
;
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
;
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. */
130 /* Link the new l-value to the previous one. */
132 NetAssign_
*last
= tmp
;
144 * Handle the ident as an l-value. This includes bit and part selects
147 NetAssign_
* PEIdent::elaborate_lval(Design
*des
,
152 const NetExpr
*par
= 0;
155 symbol_search(des
, scope
, path_
, reg
, par
, eve
);
157 cerr
<< get_fileline() << ": error: Could not find variable ``"
158 << path_
<< "'' in ``" << scope_path(scope
) <<
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
;
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
);
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
);
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
) <<
205 cerr
<< reg
->get_fileline() << ": : " << path_
<<
206 " is declared here as " << reg
->type() << "." << endl
;
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();
241 /* No select expressions, so presume a part select the
242 width of the register. */
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
);
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;
282 cerr
<< get_fileline() << ": error: part select "
283 << reg
->name() << "[" << msb
<<":"<<lsb
<<"]"
284 << " is reversed." << endl
;
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
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
;
302 lv
= new NetAssign_(reg
);
303 lv
->set_part(new NetEConst(verinum(loff
)), wid
);
310 NetAssign_
* PEIdent::elaborate_lval_net_word_(Design
*des
,
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
;
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
);
339 NetAssign_
*lv
= new NetAssign_(reg
);
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
);
377 bool PEIdent::elaborate_lval_net_part_(Design
*des
,
382 bool flag
= calculate_parts_(des
, scope
, msb
, lsb
);
386 NetNet
*reg
= lv
->sig();
389 if (msb
== reg
->msb() && lsb
== reg
->lsb()) {
391 /* No bit select, and part select covers the entire
392 vector. Simplest case. */
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;
404 cerr
<< get_fileline() << ": error: part select "
405 << reg
->name() << "[" << msb
<<":"<<lsb
<<"]"
406 << " is reversed." << endl
;
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
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
;
424 lv
->set_part(new NetEConst(verinum(loff
)), wid
);
430 bool PEIdent::elaborate_lval_net_idx_(Design
*des
,
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();
445 if (reg
->type() != NetNet::REG
) {
446 cerr
<< get_fileline() << ": error: " << path_
<<
447 " is not a reg/integer/time in " << scope_path(scope
) <<
449 cerr
<< reg
->get_fileline() << ": : " << path_
<<
450 " is declared here as " << reg
->type() << "." << endl
;
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
);
471 cerr
<< get_fileline() << ": debug: Set part select width="
472 << wid
<< ", base=" << *base
<< endl
;
474 lv
->set_part(base
, wid
);
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
;