Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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