Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 737 lines (633 sloc) 22.515 kb
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
1 /*
ce7a6fa @caryr Add uwire to the multiple driver error message.
caryr authored
2 * Copyright (c) 1999-2011 Stephen Williams (steve@icarus.com)
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
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 */
19
b825f8d Create a config.h.in file to hold all the config
steve authored
20 # include "config.h"
21
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
22 # include "PExpr.h"
23 # include "netlist.h"
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
24 # include "netmisc.h"
48de739 Switch to control warnings.
steve authored
25 # include "compiler.h"
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
26
8ea3b6b @ldoolitt header includes for gcc-4.3 compatibility
ldoolitt authored
27 # include <cstdlib>
28 # include <cstring>
b825f8d Create a config.h.in file to hold all the config
steve authored
29 # include <iostream>
b2e1db6 Add method to bind assertions to verilog source lines.
steve authored
30 # include "ivl_assert.h"
b825f8d Create a config.h.in file to hold all the config
steve authored
31
d1f0bcf Catch unsized expressions in continuous assigns.
steve authored
32 /*
cfd8cbf Port expressions for output ports are lnets, not nets.
steve authored
33 * The concatenation is also OK an an l-value. This method elaborates
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
34 * it as a structural l-value. The return values is the *input* net of
35 * the l-value, which may feed via part selects to the final
36 * destination. The caller can connect gate outputs to this signal to
37 * make the l-value connections.
cfd8cbf Port expressions for output ports are lnets, not nets.
steve authored
38 */
a2c036d Allow concatenations as arguments to inout ports.
steve authored
39 NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
40 bool bidirectional_flag) const
cfd8cbf Port expressions for output ports are lnets, not nets.
steve authored
41 {
42 assert(scope);
43
cced1e7 @steveicarus Remove some uses of the svector template.
authored
44 svector<NetNet*>nets (parms_.size());
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
45 unsigned width = 0;
cfd8cbf Port expressions for output ports are lnets, not nets.
steve authored
46 unsigned errors = 0;
47
48 if (repeat_) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
49 cerr << get_fileline() << ": sorry: I do not know how to"
cfd8cbf Port expressions for output ports are lnets, not nets.
steve authored
50 " elaborate repeat concatenation nets." << endl;
51 return 0;
52 }
53
54 /* Elaborate the operands of the concatenation. */
55 for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
07a427b Detect null arguments to concatenation operator.
steve authored
56
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
57 if (debug_elaborate) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
58 cerr << get_fileline() << ": debug: Elaborate subexpression "
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
59 << idx << " of " << nets.count() << " l-values: "
60 << *parms_[idx] << endl;
61 }
62
07a427b Detect null arguments to concatenation operator.
steve authored
63 if (parms_[idx] == 0) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
64 cerr << get_fileline() << ": error: Empty expressions "
07a427b Detect null arguments to concatenation operator.
steve authored
65 << "not allowed in concatenations." << endl;
66 errors += 1;
67 continue;
68 }
69
a2c036d Allow concatenations as arguments to inout ports.
steve authored
70 if (bidirectional_flag) {
71 nets[idx] = parms_[idx]->elaborate_bi_net(des, scope);
72 } else {
d26ae86 @steveicarus Move implicit net creation from elaboration to elaborate_sig
authored
73 nets[idx] = parms_[idx]->elaborate_lnet(des, scope);
a2c036d Allow concatenations as arguments to inout ports.
steve authored
74 }
464310f @caryr Report an error when trying to take the concatenation of a real value.
caryr authored
75
76 if (nets[idx] == 0) errors += 1;
77 else if (nets[idx]->data_type() == IVL_VT_REAL) {
78 cerr << parms_[idx]->get_fileline() << ": error: "
79 << "concatenation operand can no be real: "
80 << *parms_[idx] << endl;
cfd8cbf Port expressions for output ports are lnets, not nets.
steve authored
81 errors += 1;
464310f @caryr Report an error when trying to take the concatenation of a real value.
caryr authored
82 continue;
83 } else width += nets[idx]->vector_width();
84
cfd8cbf Port expressions for output ports are lnets, not nets.
steve authored
85 }
86
87 if (errors) {
fac1cc5 @caryr Add user function synth and clean up expression code.
caryr authored
88 des->errors += errors;
cfd8cbf Port expressions for output ports are lnets, not nets.
steve authored
89 return 0;
90 }
91
92 /* Make the temporary signal that connects to all the
93 operands, and connect it up. Scan the operands of the
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
94 concat operator from most significant to least significant,
95 which is the order they are given in the concat list. */
96
badad63 All NetObj objects have lex_string base names.
steve authored
97 NetNet*osig = new NetNet(scope, scope->local_symbol(),
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
98 NetNet::IMPLICIT, width);
99
0c9fb76 Get the data type of part select results right.
steve authored
100 /* Assume that the data types of the nets are all the same, so
101 we can take the data type of any, the first will do. */
102 osig->data_type(nets[0]->data_type());
326329d Set some missing local flags.
steve authored
103 osig->local_flag(true);
104 osig->set_line(*this);
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
105
73e2b29 @steveicarus Replace the NetPartSelect:BI with NetTran(VP).
authored
106 if (bidirectional_flag) {
107 if (debug_elaborate) {
108 cerr << get_fileline() << ": debug: Generating tran(VP) "
109 << "to connect input l-value to subexpressions."
110 << endl;
111 }
cfd8cbf Port expressions for output ports are lnets, not nets.
steve authored
112
73e2b29 @steveicarus Replace the NetPartSelect:BI with NetTran(VP).
authored
113 for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
114 unsigned wid = nets[idx]->vector_width();
115 unsigned off = width - wid;
116 NetTran*ps = new NetTran(scope, scope->local_symbol(),
117 osig->vector_width(), wid, off);
118 des->add_node(ps);
119 ps->set_line(*this);
a2c036d Allow concatenations as arguments to inout ports.
steve authored
120
73e2b29 @steveicarus Replace the NetPartSelect:BI with NetTran(VP).
authored
121 connect(ps->pin(0), osig->pin(0));
122 connect(ps->pin(1), nets[idx]->pin(0));
123
124 ivl_assert(*this, wid <= width);
125 width -= wid;
126 }
127
128 } else {
129 if (debug_elaborate) {
130 cerr << get_fileline() << ": debug: Generating part selects "
131 << "to connect input l-value to subexpressions."
132 << endl;
133 }
134
135 NetPartSelect::dir_t part_dir = NetPartSelect::VP;
136
137 for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
138 unsigned wid = nets[idx]->vector_width();
139 unsigned off = width - wid;
140 NetPartSelect*ps = new NetPartSelect(osig, off, wid, part_dir);
141 des->add_node(ps);
142 ps->set_line(*this);
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
143
73e2b29 @steveicarus Replace the NetPartSelect:BI with NetTran(VP).
authored
144 connect(ps->pin(1), osig->pin(0));
145 connect(ps->pin(0), nets[idx]->pin(0));
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
146
73e2b29 @steveicarus Replace the NetPartSelect:BI with NetTran(VP).
authored
147 assert(wid <= width);
148 width -= wid;
149 }
150 assert(width == 0);
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
151 }
152
a8b86ea More explicit datatype setup.
steve authored
153 osig->data_type(nets[0]->data_type());
cfd8cbf Port expressions for output ports are lnets, not nets.
steve authored
154 osig->local_flag(true);
155 return osig;
156 }
157
d26ae86 @steveicarus Move implicit net creation from elaboration to elaborate_sig
authored
158 NetNet* PEConcat::elaborate_lnet(Design*des, NetScope*scope) const
a2c036d Allow concatenations as arguments to inout ports.
steve authored
159 {
d26ae86 @steveicarus Move implicit net creation from elaboration to elaborate_sig
authored
160 return elaborate_lnet_common_(des, scope, false);
a2c036d Allow concatenations as arguments to inout ports.
steve authored
161 }
162
163 NetNet* PEConcat::elaborate_bi_net(Design*des, NetScope*scope) const
164 {
d26ae86 @steveicarus Move implicit net creation from elaboration to elaborate_sig
authored
165 return elaborate_lnet_common_(des, scope, true);
a2c036d Allow concatenations as arguments to inout ports.
steve authored
166 }
167
cfd8cbf Port expressions for output ports are lnets, not nets.
steve authored
168 /*
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
169 * This private method evaluates the part selects (if any) for the
170 * signal. The sig argument is the NetNet already located for the
171 * PEIdent name. The midx and lidx arguments are loaded with the
172 * results, which may be the whole vector, or a single bit, or
173 * anything in between. The values are in canonical indices.
174 */
175 bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
176 long&midx, long&lidx) const
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
177 {
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
178 const name_component_t&name_tail = path_.back();
179 // Only treat as part/bit selects any index that is beyond the
180 // word selects for an array. This is not an array, then
181 // dimensions==0 and any index is treated as a select.
182 if (name_tail.index.size() <= sig->array_dimensions()) {
183 midx = sig->vector_width()-1;
184 lidx = 0;
185 return true;
186 }
187
188 ivl_assert(*this, !name_tail.index.empty());
189
190 const index_component_t&index_tail = name_tail.index.back();
191
192 switch (index_tail.sel) {
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
193 default:
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
194 cerr << get_fileline() << ": internal error: "
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
195 << "Unexpected sel_ value = " << index_tail.sel << endl;
196 ivl_assert(*this, 0);
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
197 break;
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
198
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
199 case index_component_t::SEL_IDX_DO:
200 case index_component_t::SEL_IDX_UP: {
944495b @caryr More constant function not supported warnings.
caryr authored
201 need_constant_expr = true;
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
202 NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1);
944495b @caryr More constant function not supported warnings.
caryr authored
203 need_constant_expr = false;
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
204 NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
e26b9e7 @caryr More array fixes and down indexed part selects can be a lval.
caryr authored
205 if (!tmp) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
206 cerr << get_fileline() << ": error: indexed part select of "
e26b9e7 @caryr More array fixes and down indexed part selects can be a lval.
caryr authored
207 << sig->name()
208 << " must be a constant in this context." << endl;
209 des->errors += 1;
210 return 0;
211 }
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
212
018f1a6 @steveicarus Handle indexed part select in continuous assign.
authored
213 /* The width (a constant) is calculated here. */
214 unsigned long wid = 0;
215 bool flag = calculate_up_do_width_(des, scope, wid);
2b17366 @caryr Major rewrite of indexed part selects.
caryr authored
216 if (! flag) return false;
217
218 /* We have an undefined index and that is out of range. */
219 if (! tmp->value().is_defined()) {
220 if (warn_ob_select) {
221 cerr << get_fileline() << ": warning: "
222 << sig->name();
223 if (sig->array_dimensions() > 0) cerr << "[]";
224 cerr << "['bx";
225 if (index_tail.sel ==
226 index_component_t::SEL_IDX_UP) {
227 cerr << "+:";
228 } else {
229 cerr << "-:";
230 }
231 cerr << wid << "] is always outside vector."
232 << endl;
233 }
018f1a6 @steveicarus Handle indexed part select in continuous assign.
authored
234 return false;
2b17366 @caryr Major rewrite of indexed part selects.
caryr authored
235 }
236
237 long midx_val = tmp->value().as_long();
238 midx = sig->sb_to_idx(midx_val);
239 delete tmp_ex;
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
240
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
241 if (index_tail.sel == index_component_t::SEL_IDX_UP)
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
242 lidx = sig->sb_to_idx(midx_val+wid-1);
243 else
244 lidx = sig->sb_to_idx(midx_val-wid+1);
245
246 if (midx < lidx) {
3adcbb5 @ldoolitt Shadow reduction part 2
ldoolitt authored
247 long tmpx = midx;
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
248 midx = lidx;
3adcbb5 @ldoolitt Shadow reduction part 2
ldoolitt authored
249 lidx = tmpx;
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
250 }
251
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the si...
caryr authored
252 /* Warn about an indexed part select that is out of range. */
2b17366 @caryr Major rewrite of indexed part selects.
caryr authored
253 if (warn_ob_select && (lidx < 0)) {
254 cerr << get_fileline() << ": warning: " << sig->name();
255 if (sig->array_dimensions() > 0) cerr << "[]";
256 cerr << "[" << midx_val;
257 if (index_tail.sel == index_component_t::SEL_IDX_UP) {
258 cerr << "+:";
259 } else {
260 cerr << "-:";
261 }
262 cerr << wid << "] is selecting before vector." << endl;
263 }
264 if (warn_ob_select && (midx >= (long)sig->vector_width())) {
265 cerr << get_fileline() << ": warning: " << sig->name();
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the si...
caryr authored
266 if (sig->array_dimensions() > 0) {
267 cerr << "[]";
268 }
269 cerr << "[" << midx_val;
270 if (index_tail.sel == index_component_t::SEL_IDX_UP) {
271 cerr << "+:";
272 } else {
273 cerr << "-:";
274 }
2b17366 @caryr Major rewrite of indexed part selects.
caryr authored
275 cerr << wid << "] is selecting after vector." << endl;
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the si...
caryr authored
276 }
277
278 /* This is completely out side the signal so just skip it. */
279 if (lidx >= (long)sig->vector_width() || midx < 0) {
280 return false;
281 }
282
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
283 break;
284 }
285
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
286 case index_component_t::SEL_PART: {
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
287
018f1a6 @steveicarus Handle indexed part select in continuous assign.
authored
288 long msb, lsb;
b45834f @steveicarus Handle part selects with bad (xz) bits.
authored
289 bool part_defined_flag;
290 /* bool flag = */ calculate_parts_(des, scope, msb, lsb, part_defined_flag);
291 ivl_assert(*this, part_defined_flag);
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
292
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
293 long lidx_tmp = sig->sb_to_idx(lsb);
294 long midx_tmp = sig->sb_to_idx(msb);
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
295 /* Detect reversed indices of a part select. */
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
296 if (lidx_tmp > midx_tmp) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
297 cerr << get_fileline() << ": error: Part select "
018f1a6 @steveicarus Handle indexed part select in continuous assign.
authored
298 << sig->name() << "[" << msb << ":"
299 << lsb << "] indices reversed." << endl;
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
300 cerr << get_fileline() << ": : Did you mean "
018f1a6 @steveicarus Handle indexed part select in continuous assign.
authored
301 << sig->name() << "[" << lsb << ":"
302 << msb << "]?" << endl;
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
303 long tmp = midx_tmp;
304 midx_tmp = lidx_tmp;
305 lidx_tmp = tmp;
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
306 des->errors += 1;
307 }
308
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the si...
caryr authored
309 /* Warn about a part select that is out of range. */
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
310 if (midx_tmp >= (long)sig->vector_width() || lidx_tmp < 0) {
311 cerr << get_fileline() << ": warning: Part select "
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the si...
caryr authored
312 << sig->name();
313 if (sig->array_dimensions() > 0) {
314 cerr << "[]";
315 }
316 cerr << "[" << msb << ":" << lsb
317 << "] is out of range." << endl;
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
318 #if 0
319 midx_tmp = sig->vector_width() - 1;
320 lidx_tmp = 0;
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
321 des->errors += 1;
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
322 #endif
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
323 }
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the si...
caryr authored
324 /* This is completely out side the signal so just skip it. */
325 if (lidx_tmp >= (long)sig->vector_width() || midx_tmp < 0) {
326 return false;
327 }
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
328
329 midx = midx_tmp;
330 lidx = lidx_tmp;
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
331 break;
332 }
333
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
334 case index_component_t::SEL_BIT:
335 if (name_tail.index.size() > sig->array_dimensions()) {
129a064 Handle bit/part select of array words in nets.
steve authored
336 verinum*mval = index_tail.msb->eval_const(des, scope);
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
337 if (mval == 0) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
338 cerr << get_fileline() << ": error: Index of " << path_ <<
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
339 " needs to be constant in this context." <<
340 endl;
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
341 cerr << get_fileline() << ": : Index expression is: "
129a064 Handle bit/part select of array words in nets.
steve authored
342 << *index_tail.msb << endl;
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
343 cerr << get_fileline() << ": : Context scope is: "
8ec6d99 Put instantiated modules in the proper generated scope.
steve authored
344 << scope_path(scope) << endl;
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
345 des->errors += 1;
346 return false;
347 }
348 assert(mval);
349
350 midx = sig->sb_to_idx(mval->as_long());
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
351 if (midx >= (long)sig->vector_width()) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
352 cerr << get_fileline() << ": error: Index " << sig->name()
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the si...
caryr authored
353 << "[" << mval->as_long() << "] is out of range."
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
354 << endl;
355 des->errors += 1;
356 midx = 0;
357 }
358 lidx = midx;
359
360 } else {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
361 cerr << get_fileline() << ": internal error: "
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
362 << "Bit select " << path_ << endl;
363 ivl_assert(*this, 0);
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
364 midx = sig->vector_width() - 1;
365 lidx = 0;
366 }
367 break;
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
368 }
369
370 return true;
371 }
372
373 /*
4a8be3d Implement bi-directional part selects.
steve authored
374 * This is the common code for l-value nets and bi-directional
375 * nets. There is very little that is different between the two cases,
376 * so most of the work for both is done here.
a81dcd7 Support memories in continuous assignments.
steve authored
377 */
4a8be3d Implement bi-directional part selects.
steve authored
378 NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
379 bool bidirectional_flag) const
a81dcd7 Support memories in continuous assignments.
steve authored
380 {
6937945 Remove find_memory method from Design class.
steve authored
381 assert(scope);
382
383 NetNet* sig = 0;
384 const NetExpr*par = 0;
385 NetEvent* eve = 0;
386
18edf2f Rework of automatic task/function support.
Martin Whitaker authored
387 symbol_search(this, des, scope, path_, sig, par, eve);
6937945 Remove find_memory method from Design class.
steve authored
388
389 if (eve != 0) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
390 cerr << get_fileline() << ": error: named events (" << path_
6937945 Remove find_memory method from Design class.
steve authored
391 << ") cannot be l-values in continuous "
392 << "assignments." << endl;
393 des->errors += 1;
394 return 0;
395 }
396
a81dcd7 Support memories in continuous assignments.
steve authored
397 if (sig == 0) {
d26ae86 @steveicarus Move implicit net creation from elaboration to elaborate_sig
authored
398 cerr << get_fileline() << ": error: Net " << path_
399 << " is not defined in this context." << endl;
400 des->errors += 1;
401 return 0;
a81dcd7 Support memories in continuous assignments.
steve authored
402 }
403
404 assert(sig);
405
568ee44 @steveicarus Allow variables to implicitly convert to unresolved nets.
authored
406 /* If this is SystemVerilog and the variable is not yet
407 assigned by anything, then convert it to an unresolved
408 wire. */
409 if (gn_var_can_be_uwire()
410 && (sig->type() == NetNet::REG)
411 && (sig->peek_eref() == 0) ) {
412 sig->type(NetNet::UNRESOLVED_WIRE);
413 }
414
415 if (sig->type() == NetNet::UNRESOLVED_WIRE && sig->pin(0).is_linked()) {
ce7a6fa @caryr Add uwire to the multiple driver error message.
caryr authored
416 cerr << get_fileline() << ": error: Unresolved net/uwire "
417 << sig->name() << " cannot have multiple drivers." << endl;
568ee44 @steveicarus Allow variables to implicitly convert to unresolved nets.
authored
418 des->errors += 1;
419 return 0;
420 }
421
a81dcd7 Support memories in continuous assignments.
steve authored
422 /* Don't allow registers as assign l-values. */
423 if (sig->type() == NetNet::REG) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
424 cerr << get_fileline() << ": error: reg " << sig->name()
c96598a Primitive outputs have same limitations as continuous assignment.
steve authored
425 << "; cannot be driven by primitives"
426 << " or continuous assignment." << endl;
427 des->errors += 1;
a81dcd7 Support memories in continuous assignments.
steve authored
428 return 0;
429 }
430
4d0b840 Coerse input to inout when assigned to.
steve authored
431 if (sig->port_type() == NetNet::PINPUT) {
432 sig->port_type(NetNet::PINOUT);
69f3219 @steveicarus Suppress redundant warning messages about input coerced to inout
authored
433 // This map mask prevents an error message being
434 // repeated endlessly.
435 static map<string,bool> mask_map;
436 bool&flag = mask_map[sig->get_fileline() + ":" + string(sig->name())];
437 if (! flag) {
438 cerr << get_fileline() << ": warning: L-value ``"
439 << sig->name() << "'' is also an input port." << endl;
440 cerr << sig->get_fileline() << ": warning: input "
441 << sig->name() << "; is coerced to inout." << endl;
442 flag = true;
443 }
4d0b840 Coerse input to inout when assigned to.
steve authored
444 }
445
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
446 // Default part select is the entire word.
447 unsigned midx = sig->vector_width()-1, lidx = 0;
448 // The default word select is the first.
c9f6bd6 @caryr Add compiler warnings for more constant out of bounds array accesses.
caryr authored
449 long widx = 0;
37b11e0 @steveicarus Fix index out of bounds error message.
authored
450 // The widx_val is the word select as entered in the source
451 // code. It's used for error messages.
452 long widx_val = 0;
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
453
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
454 const name_component_t&name_tail = path_.back();
455
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
456 if (sig->array_dimensions() > 0) {
457
e26b9e7 @caryr More array fixes and down indexed part selects can be a lval.
caryr authored
458 if (name_tail.index.empty()) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
459 cerr << get_fileline() << ": error: array " << sig->name()
e26b9e7 @caryr More array fixes and down indexed part selects can be a lval.
caryr authored
460 << " must be used with an index." << endl;
461 des->errors += 1;
462 return 0;
463 }
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
464
465 const index_component_t&index_head = name_tail.index.front();
e39b3fe @caryr Display a warning for a part select of an array.
caryr authored
466 if (index_head.sel == index_component_t::SEL_PART) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
467 cerr << get_fileline() << ": error: cannot perform a part "
e39b3fe @caryr Display a warning for a part select of an array.
caryr authored
468 << "select on array " << sig->name() << "." << endl;
469 des->errors += 1;
470 return 0;
471 }
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
472 ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
473
944495b @caryr More constant function not supported warnings.
caryr authored
474 need_constant_expr = true;
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
475 NetExpr*tmp_ex = elab_and_eval(des, scope, index_head.msb, -1);
944495b @caryr More constant function not supported warnings.
caryr authored
476 need_constant_expr = false;
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
477 NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
51293b6 @caryr Fix/enhance array part select code.
caryr authored
478 if (!tmp) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
479 cerr << get_fileline() << ": error: array " << sig->name()
51293b6 @caryr Fix/enhance array part select code.
caryr authored
480 << " index must be a constant in this context." << endl;
481 des->errors += 1;
482 return 0;
483 }
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
484
37b11e0 @steveicarus Fix index out of bounds error message.
authored
485 widx_val = tmp->value().as_long();
486 if (sig->array_index_is_valid(widx_val))
487 widx = sig->array_index_to_address(widx_val);
488 else
489 widx = -1;
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
490 delete tmp_ex;
491
492 if (debug_elaborate)
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
493 cerr << get_fileline() << ": debug: Use [" << widx << "]"
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
494 << " to index l-value array." << endl;
495
51293b6 @caryr Fix/enhance array part select code.
caryr authored
496 /* The array has a part/bit select at the end. */
e26b9e7 @caryr More array fixes and down indexed part selects can be a lval.
caryr authored
497 if (name_tail.index.size() > sig->array_dimensions()) {
b1dd0b1 @caryr It is an error to select part of a scalar value.
caryr authored
498 if (sig->get_scalar()) {
ec49f10 @steveicarus Revert bad merge from vhdl branch
authored
499 cerr << get_fileline() << ": error: "
b1dd0b1 @caryr It is an error to select part of a scalar value.
caryr authored
500 << "can not select part of ";
501 if (sig->data_type() == IVL_VT_REAL) cerr << "real";
502 else cerr << "scalar";
503 cerr << " array word: " << sig->name()
504 << "[" << widx_val << "]" << endl;
5852f1e @caryr Report an error when trying to take the select of a real value.
caryr authored
505 des->errors += 1;
506 return 0;
507 }
508
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
509 long midx_tmp, lidx_tmp;
510 if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
51293b6 @caryr Fix/enhance array part select code.
caryr authored
511 return 0;
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the si...
caryr authored
512
513 if (lidx_tmp < 0) {
ec49f10 @steveicarus Revert bad merge from vhdl branch
authored
514 cerr << get_fileline() << ": sorry: part selects "
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the si...
caryr authored
515 "straddling the start of signal (" << path_
516 << ") are not currently supported." << endl;
517 des->errors += 1;
518 return 0;
519 }
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
520 midx = midx_tmp;
521 lidx = lidx_tmp;
51293b6 @caryr Fix/enhance array part select code.
caryr authored
522 }
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
523 } else if (!name_tail.index.empty()) {
b1dd0b1 @caryr It is an error to select part of a scalar value.
caryr authored
524 if (sig->get_scalar()) {
ec49f10 @steveicarus Revert bad merge from vhdl branch
authored
525 cerr << get_fileline() << ": error: "
b1dd0b1 @caryr It is an error to select part of a scalar value.
caryr authored
526 << "can not select part of ";
527 if (sig->data_type() == IVL_VT_REAL) cerr << "real: ";
528 else cerr << "scalar: ";
529 cerr << sig->name() << endl;
5852f1e @caryr Report an error when trying to take the select of a real value.
caryr authored
530 des->errors += 1;
531 return 0;
532 }
533
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
534 long midx_tmp, lidx_tmp;
535 if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
536 return 0;
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
537
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the si...
caryr authored
538 if (lidx_tmp < 0) {
ec49f10 @steveicarus Revert bad merge from vhdl branch
authored
539 cerr << get_fileline() << ": sorry: part selects "
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the si...
caryr authored
540 "straddling the start of signal (" << path_
541 << ") are not currently supported." << endl;
542 des->errors += 1;
543 return 0;
544 }
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
545 midx = midx_tmp;
546 lidx = lidx_tmp;
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
547 }
4eed86d Detect part select errors on l-values.
steve authored
548
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
549 unsigned subnet_wid = midx-lidx+1;
550
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
551 if (sig->pin_count() > 1) {
c9f6bd6 @caryr Add compiler warnings for more constant out of bounds array accesses.
caryr authored
552 if (widx < 0 || widx >= (long) sig->pin_count()) {
553 cerr << get_fileline() << ": warning: ignoring out of "
554 "bounds l-value array access "
37b11e0 @steveicarus Fix index out of bounds error message.
authored
555 << sig->name() << "[" << widx_val << "]." << endl;
c9f6bd6 @caryr Add compiler warnings for more constant out of bounds array accesses.
caryr authored
556 return 0;
557 }
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
558
559 NetNet*tmp = new NetNet(scope, scope->local_symbol(),
560 sig->type(), sig->vector_width());
561 tmp->set_line(*this);
562 tmp->local_flag(true);
4919b70 @steveicarus Give l-value nets their proper type.
authored
563 tmp->data_type( sig->data_type() );
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
564 connect(sig->pin(widx), tmp->pin(0));
565 sig = tmp;
566 }
567
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
568 /* If the desired l-value vector is narrower then the
569 signal itself, then use a NetPartSelect node to
570 arrange for connection to the desired bits. All this
571 can be skipped if the desired with matches the
572 original vector. */
573
574 if (subnet_wid != sig->vector_width()) {
4a8be3d Implement bi-directional part selects.
steve authored
575 /* If we are processing a tran or inout, then the
576 partselect is bi-directional. Otherwise, it is a
577 Part-to-Vector select. */
578
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
579 if (debug_elaborate)
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
580 cerr << get_fileline() << ": debug: "
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
581 << "Elaborate lnet part select "
582 << sig->name()
583 << "[base=" << lidx
584 << " wid=" << subnet_wid <<"]"
585 << endl;
a81dcd7 Support memories in continuous assignments.
steve authored
586
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
587 NetNet*subsig = new NetNet(sig->scope(),
588 sig->scope()->local_symbol(),
589 NetNet::WIRE, subnet_wid);
9a16e03 Match data type of PV select input/output.
steve authored
590 subsig->data_type( sig->data_type() );
326329d Set some missing local flags.
steve authored
591 subsig->local_flag(true);
592 subsig->set_line(*this);
a81dcd7 Support memories in continuous assignments.
steve authored
593
73e2b29 @steveicarus Replace the NetPartSelect:BI with NetTran(VP).
authored
594 if (bidirectional_flag) {
595 // Make a tran(VP)
596 NetTran*sub = new NetTran(scope, scope->local_symbol(),
597 sig->vector_width(),
598 subnet_wid, lidx);
599 sub->set_line(*this);
600 des->add_node(sub);
601 connect(sub->pin(0), sig->pin(0));
602 connect(sub->pin(1), subsig->pin(0));
cd94019 Remove NetTmp and add NetSubnet class.
steve authored
603
73e2b29 @steveicarus Replace the NetPartSelect:BI with NetTran(VP).
authored
604 } else {
605 NetPartSelect*sub = new NetPartSelect(sig, lidx, subnet_wid,
606 NetPartSelect::PV);
607 des->add_node(sub);
608 sub->set_line(*this);
609 connect(sub->pin(0), subsig->pin(0));
610 }
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
611 sig = subsig;
a81dcd7 Support memories in continuous assignments.
steve authored
612 }
613
614 return sig;
615 }
616
206b37e Fix NetConst being set to zero width, and clean
steve authored
617 /*
4a8be3d Implement bi-directional part selects.
steve authored
618 * Identifiers in continuous assignment l-values are limited to wires
619 * and that ilk. Detect registers and memories here and report errors.
620 */
d26ae86 @steveicarus Move implicit net creation from elaboration to elaborate_sig
authored
621 NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope) const
4a8be3d Implement bi-directional part selects.
steve authored
622 {
d26ae86 @steveicarus Move implicit net creation from elaboration to elaborate_sig
authored
623 return elaborate_lnet_common_(des, scope, false);
4a8be3d Implement bi-directional part selects.
steve authored
624 }
625
626 NetNet* PEIdent::elaborate_bi_net(Design*des, NetScope*scope) const
627 {
d26ae86 @steveicarus Move implicit net creation from elaboration to elaborate_sig
authored
628 return elaborate_lnet_common_(des, scope, true);
4a8be3d Implement bi-directional part selects.
steve authored
629 }
630
631 /*
3676d66 Module ports are really special PEIdent
steve authored
632 * This method is used to elaborate identifiers that are ports to a
633 * scope. The scope is presumed to be that of the module that has the
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
634 * port. This elaboration is done inside the module, and is only done
635 * to PEIdent objects. This method is used by elaboration of a module
636 * instantiation (PGModule::elaborate_mod_) to get NetNet objects for
637 * the port.
3676d66 Module ports are really special PEIdent
steve authored
638 */
639 NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
640 {
ab6c8cb Parser and pform use hierarchical names as hname_t
steve authored
641 NetNet*sig = des->find_signal(scope, path_);
3676d66 Module ports are really special PEIdent
steve authored
642 if (sig == 0) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
643 cerr << get_fileline() << ": error: no wire/reg " << path_
c7d97f4 Properly evaluate scope path expressions.
steve authored
644 << " in module " << scope_path(scope) << "." << endl;
3676d66 Module ports are really special PEIdent
steve authored
645 des->errors += 1;
646 return 0;
647 }
648
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
649 /* Check the port_type of the signal to make sure it is really
650 a port, and its direction is resolved. */
a59bbde Proper error messages when port direction is missing.
steve authored
651 switch (sig->port_type()) {
652 case NetNet::PINPUT:
653 case NetNet::POUTPUT:
654 case NetNet::PINOUT:
655 break;
656
657 /* If the name matches, but the signal is not a port,
658 then the user declared the object but there is no
659 matching input/output/inout declaration. */
660
661 case NetNet::NOT_A_PORT:
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
662 cerr << get_fileline() << ": error: signal " << path_ << " in"
c7d97f4 Properly evaluate scope path expressions.
steve authored
663 << " module " << scope_path(scope) << " is not a port." << endl;
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
664 cerr << get_fileline() << ": : Are you missing an input/"
a59bbde Proper error messages when port direction is missing.
steve authored
665 << "output/inout declaration?" << endl;
666 des->errors += 1;
667 return 0;
668
669 /* This should not happen. A PWire can only become
1ff31db @caryr Add real comparisons in continuous assignments.
caryr authored
670 PIMPLICIT if this is a UDP reg port, and the make_udp
a59bbde Proper error messages when port direction is missing.
steve authored
671 function should turn it into an output.... I think. */
672
673 case NetNet::PIMPLICIT:
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
674 cerr << get_fileline() << ": internal error: signal " << path_
c7d97f4 Properly evaluate scope path expressions.
steve authored
675 << " in module " << scope_path(scope) << " is left as "
a59bbde Proper error messages when port direction is missing.
steve authored
676 << "port type PIMPLICIT." << endl;
677 des->errors += 1;
678 return 0;
679 }
680
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
681 long midx;
682 long lidx;
3676d66 Module ports are really special PEIdent
steve authored
683
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
684 /* Evaluate the part/bit select expressions, to get the part
685 select of the signal that attaches to the port. Also handle
686 range and direction checking here. */
3676d66 Module ports are really special PEIdent
steve authored
687
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
688 if (! eval_part_select_(des, scope, sig, midx, lidx))
689 return 0;
cd94019 Remove NetTmp and add NetSubnet class.
steve authored
690
f7ee3fe @steveicarus Fix elaboration of part-select ports.
authored
691 /* If this is a part select of the entire signal (or no part
692 select at all) then we're done. */
693 if ((lidx == 0) && (midx == (long)sig->vector_width()-1))
694 return sig;
695
696 unsigned swid = abs(midx - lidx) + 1;
697 ivl_assert(*this, swid > 0 && swid < sig->vector_width());
698
699 NetNet*tmp = new NetNet(scope, scope->local_symbol(),
700 NetNet::WIRE, swid);
701 tmp->port_type(sig->port_type());
702 tmp->data_type(sig->data_type());
703 tmp->set_line(*this);
704 NetNode*ps = 0;
705 switch (sig->port_type()) {
706
707 case NetNet::PINPUT:
4a4a2ee @caryr Don't normalize the port base (lidx) twice.
caryr authored
708 ps = new NetPartSelect(sig, lidx, swid, NetPartSelect::PV);
f7ee3fe @steveicarus Fix elaboration of part-select ports.
authored
709 connect(tmp->pin(0), ps->pin(0));
710 sig = tmp;
711 break;
712
713 case NetNet::POUTPUT:
4a4a2ee @caryr Don't normalize the port base (lidx) twice.
caryr authored
714 ps = new NetPartSelect(sig, lidx, swid, NetPartSelect::VP);
f7ee3fe @steveicarus Fix elaboration of part-select ports.
authored
715 connect(tmp->pin(0), ps->pin(0));
716 sig = tmp;
717 break;
3676d66 Module ports are really special PEIdent
steve authored
718
f7ee3fe @steveicarus Fix elaboration of part-select ports.
authored
719 case NetNet::PINOUT:
720 ps = new NetTran(scope, scope->local_symbol(), sig->vector_width(),
4a4a2ee @caryr Don't normalize the port base (lidx) twice.
caryr authored
721 swid, lidx);
f7ee3fe @steveicarus Fix elaboration of part-select ports.
authored
722 connect(sig->pin(0), ps->pin(0));
723 connect(tmp->pin(0), ps->pin(1));
724 sig = tmp;
725 break;
3676d66 Module ports are really special PEIdent
steve authored
726
f7ee3fe @steveicarus Fix elaboration of part-select ports.
authored
727 default:
728 ivl_assert(*this, 0);
729 break;
3676d66 Module ports are really special PEIdent
steve authored
730 }
731
f7ee3fe @steveicarus Fix elaboration of part-select ports.
authored
732 ps->set_line(*this);
733 des->add_node(ps);
734
3676d66 Module ports are really special PEIdent
steve authored
735 return sig;
736 }
Something went wrong with that request. Please try again.