Skip to content

HTTPS clone URL

Subversion checkout URL

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