Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 821 lines (697 sloc) 24.968 kB
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
1 /*
761a38d @caryr Spelling fix
caryr authored
2 * Copyright (c) 1999-2012 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 {
3e4f8b6 @steveicarus Get packed signals working through to simulation in some situations.
authored
203 list<long> prefix_indices;
204 bool rc = calculate_packed_indices_(des, scope, sig, prefix_indices);
205 ivl_assert(*this, rc);
206
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
207 const name_component_t&name_tail = path_.back();
208 // Only treat as part/bit selects any index that is beyond the
209 // word selects for an array. This is not an array, then
210 // dimensions==0 and any index is treated as a select.
211 if (name_tail.index.size() <= sig->array_dimensions()) {
212 midx = sig->vector_width()-1;
213 lidx = 0;
214 return true;
215 }
216
217 ivl_assert(*this, !name_tail.index.empty());
218
219 const index_component_t&index_tail = name_tail.index.back();
220
221 switch (index_tail.sel) {
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
222 default:
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
223 cerr << get_fileline() << ": internal error: "
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
224 << "Unexpected sel_ value = " << index_tail.sel << endl;
225 ivl_assert(*this, 0);
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
226 break;
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
227
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
228 case index_component_t::SEL_IDX_DO:
229 case index_component_t::SEL_IDX_UP: {
9306714 @martinwhitaker Rework of constant expression error reporting.
martinwhitaker authored
230 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
231 NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
e26b9e7 @caryr More array fixes and down indexed part selects can be a lval.
caryr authored
232 if (!tmp) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
233 cerr << get_fileline() << ": error: indexed part select of "
e26b9e7 @caryr More array fixes and down indexed part selects can be a lval.
caryr authored
234 << sig->name()
235 << " must be a constant in this context." << endl;
236 des->errors += 1;
237 return 0;
238 }
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
239
018f1a6 @steveicarus Handle indexed part select in continuous assign.
authored
240 /* The width (a constant) is calculated here. */
241 unsigned long wid = 0;
242 bool flag = calculate_up_do_width_(des, scope, wid);
2b17366 @caryr Major rewrite of indexed part selects.
caryr authored
243 if (! flag) return false;
244
245 /* We have an undefined index and that is out of range. */
246 if (! tmp->value().is_defined()) {
247 if (warn_ob_select) {
248 cerr << get_fileline() << ": warning: "
249 << sig->name();
250 if (sig->array_dimensions() > 0) cerr << "[]";
251 cerr << "['bx";
252 if (index_tail.sel ==
253 index_component_t::SEL_IDX_UP) {
254 cerr << "+:";
255 } else {
256 cerr << "-:";
257 }
258 cerr << wid << "] is always outside vector."
259 << endl;
260 }
018f1a6 @steveicarus Handle indexed part select in continuous assign.
authored
261 return false;
2b17366 @caryr Major rewrite of indexed part selects.
caryr authored
262 }
263
264 long midx_val = tmp->value().as_long();
3e4f8b6 @steveicarus Get packed signals working through to simulation in some situations.
authored
265 midx = sig->sb_to_idx(prefix_indices, midx_val);
2b17366 @caryr Major rewrite of indexed part selects.
caryr authored
266 delete tmp_ex;
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
267
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
268 if (index_tail.sel == index_component_t::SEL_IDX_UP)
3e4f8b6 @steveicarus Get packed signals working through to simulation in some situations.
authored
269 lidx = sig->sb_to_idx(prefix_indices, midx_val+wid-1);
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
270 else
3e4f8b6 @steveicarus Get packed signals working through to simulation in some situations.
authored
271 lidx = sig->sb_to_idx(prefix_indices, midx_val-wid+1);
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
272
273 if (midx < lidx) {
3adcbb5 @ldoolitt Shadow reduction part 2
ldoolitt authored
274 long tmpx = midx;
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
275 midx = lidx;
3adcbb5 @ldoolitt Shadow reduction part 2
ldoolitt authored
276 lidx = tmpx;
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
277 }
278
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the…
caryr authored
279 /* Warn about an indexed part select that is out of range. */
2b17366 @caryr Major rewrite of indexed part selects.
caryr authored
280 if (warn_ob_select && (lidx < 0)) {
281 cerr << get_fileline() << ": warning: " << sig->name();
282 if (sig->array_dimensions() > 0) cerr << "[]";
283 cerr << "[" << midx_val;
284 if (index_tail.sel == index_component_t::SEL_IDX_UP) {
285 cerr << "+:";
286 } else {
287 cerr << "-:";
288 }
289 cerr << wid << "] is selecting before vector." << endl;
290 }
291 if (warn_ob_select && (midx >= (long)sig->vector_width())) {
292 cerr << get_fileline() << ": warning: " << sig->name();
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the…
caryr authored
293 if (sig->array_dimensions() > 0) {
294 cerr << "[]";
295 }
296 cerr << "[" << midx_val;
297 if (index_tail.sel == index_component_t::SEL_IDX_UP) {
298 cerr << "+:";
299 } else {
300 cerr << "-:";
301 }
2b17366 @caryr Major rewrite of indexed part selects.
caryr authored
302 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
303 }
304
305 /* This is completely out side the signal so just skip it. */
306 if (lidx >= (long)sig->vector_width() || midx < 0) {
307 return false;
308 }
309
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
310 break;
311 }
312
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
313 case index_component_t::SEL_PART: {
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
314
018f1a6 @steveicarus Handle indexed part select in continuous assign.
authored
315 long msb, lsb;
b45834f @steveicarus Handle part selects with bad (xz) bits.
authored
316 bool part_defined_flag;
317 /* bool flag = */ calculate_parts_(des, scope, msb, lsb, part_defined_flag);
318 ivl_assert(*this, part_defined_flag);
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
319
3e4f8b6 @steveicarus Get packed signals working through to simulation in some situations.
authored
320 long lidx_tmp = sig->sb_to_idx(prefix_indices, lsb);
321 long midx_tmp = sig->sb_to_idx(prefix_indices, msb);
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
322 /* Detect reversed indices of a part select. */
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
323 if (lidx_tmp > midx_tmp) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
324 cerr << get_fileline() << ": error: Part select "
018f1a6 @steveicarus Handle indexed part select in continuous assign.
authored
325 << sig->name() << "[" << msb << ":"
326 << lsb << "] indices reversed." << endl;
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
327 cerr << get_fileline() << ": : Did you mean "
018f1a6 @steveicarus Handle indexed part select in continuous assign.
authored
328 << sig->name() << "[" << lsb << ":"
329 << msb << "]?" << endl;
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
330 long tmp = midx_tmp;
331 midx_tmp = lidx_tmp;
332 lidx_tmp = tmp;
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
333 des->errors += 1;
334 }
335
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the…
caryr authored
336 /* 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
337 if (midx_tmp >= (long)sig->vector_width() || lidx_tmp < 0) {
338 cerr << get_fileline() << ": warning: Part select "
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the…
caryr authored
339 << sig->name();
340 if (sig->array_dimensions() > 0) {
341 cerr << "[]";
342 }
343 cerr << "[" << msb << ":" << lsb
344 << "] is out of range." << endl;
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
345 #if 0
346 midx_tmp = sig->vector_width() - 1;
347 lidx_tmp = 0;
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
348 des->errors += 1;
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
349 #endif
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
350 }
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the…
caryr authored
351 /* This is completely out side the signal so just skip it. */
352 if (lidx_tmp >= (long)sig->vector_width() || midx_tmp < 0) {
353 return false;
354 }
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
355
356 midx = midx_tmp;
357 lidx = lidx_tmp;
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
358 break;
359 }
360
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
361 case index_component_t::SEL_BIT:
362 if (name_tail.index.size() > sig->array_dimensions()) {
8ea1e49 @steveicarus Improve net bit select calculations.
authored
363 long msb;
364 bool bit_defined_flag;
365 /* bool flag = */ calculate_bits_(des, scope, msb, bit_defined_flag);
366 ivl_assert(*this, bit_defined_flag);
367 midx = sig->sb_to_idx(prefix_indices, msb);
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
368 if (midx >= (long)sig->vector_width()) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
369 cerr << get_fileline() << ": error: Index " << sig->name()
8ea1e49 @steveicarus Improve net bit select calculations.
authored
370 << "[" << msb << "] is out of range."
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
371 << endl;
372 des->errors += 1;
373 midx = 0;
374 }
375 lidx = midx;
376
377 } else {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
378 cerr << get_fileline() << ": internal error: "
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
379 << "Bit select " << path_ << endl;
380 ivl_assert(*this, 0);
c2ff3d5 Fix support for indexed part select in continuous assign l-values.
steve authored
381 midx = sig->vector_width() - 1;
382 lidx = 0;
383 }
384 break;
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
385 }
386
387 return true;
388 }
389
390 /*
4a8be3d Implement bi-directional part selects.
steve authored
391 * This is the common code for l-value nets and bi-directional
392 * nets. There is very little that is different between the two cases,
393 * so most of the work for both is done here.
a81dcd7 Support memories in continuous assignments.
steve authored
394 */
4a8be3d Implement bi-directional part selects.
steve authored
395 NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
396 bool bidirectional_flag) const
a81dcd7 Support memories in continuous assignments.
steve authored
397 {
6937945 Remove find_memory method from Design class.
steve authored
398 assert(scope);
399
400 NetNet* sig = 0;
401 const NetExpr*par = 0;
402 NetEvent* eve = 0;
d2c3ff7 @steveicarus Handle struct members in continuous assign l-values.
authored
403 perm_string method_name;
6937945 Remove find_memory method from Design class.
steve authored
404
18edf2f Rework of automatic task/function support.
Martin Whitaker authored
405 symbol_search(this, des, scope, path_, sig, par, eve);
6937945 Remove find_memory method from Design class.
steve authored
406
407 if (eve != 0) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
408 cerr << get_fileline() << ": error: named events (" << path_
6937945 Remove find_memory method from Design class.
steve authored
409 << ") cannot be l-values in continuous "
410 << "assignments." << endl;
411 des->errors += 1;
412 return 0;
413 }
414
d2c3ff7 @steveicarus Handle struct members in continuous assign l-values.
authored
415 /* If the signal is not found, check to see if this is a
416 member of a struct. Take the name of the form "a.b.member",
417 remove the member and store it into method_name, and retry
418 the search with "a.b". */
419 if (sig == 0 && path_.size() >= 2) {
420 pform_name_t use_path = path_;
421 method_name = peek_tail_name(use_path);
422 use_path.pop_back();
423 symbol_search(this, des, scope, use_path, sig, par, eve);
1243145 @steveicarus Packed struct members in behavioral assign l-values.
authored
424
425 // Whoops, not a struct signal, so give up on this avenue.
426 if (sig && sig->struct_type() == 0) {
427 method_name = perm_string();
428 sig = 0;
429 }
d2c3ff7 @steveicarus Handle struct members in continuous assign l-values.
authored
430 }
431
a81dcd7 Support memories in continuous assignments.
steve authored
432 if (sig == 0) {
d26ae86 @steveicarus Move implicit net creation from elaboration to elaborate_sig
authored
433 cerr << get_fileline() << ": error: Net " << path_
434 << " is not defined in this context." << endl;
435 des->errors += 1;
436 return 0;
a81dcd7 Support memories in continuous assignments.
steve authored
437 }
438
439 assert(sig);
440
568ee44 @steveicarus Allow variables to implicitly convert to unresolved nets.
authored
441 /* If this is SystemVerilog and the variable is not yet
442 assigned by anything, then convert it to an unresolved
443 wire. */
444 if (gn_var_can_be_uwire()
445 && (sig->type() == NetNet::REG)
2013add @steveicarus Fix check for SV continuous assign to variable.
authored
446 && (sig->peek_lref() == 0) ) {
568ee44 @steveicarus Allow variables to implicitly convert to unresolved nets.
authored
447 sig->type(NetNet::UNRESOLVED_WIRE);
448 }
449
a81dcd7 Support memories in continuous assignments.
steve authored
450 /* Don't allow registers as assign l-values. */
451 if (sig->type() == NetNet::REG) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
452 cerr << get_fileline() << ": error: reg " << sig->name()
c96598a Primitive outputs have same limitations as continuous assignment.
steve authored
453 << "; cannot be driven by primitives"
454 << " or continuous assignment." << endl;
455 des->errors += 1;
a81dcd7 Support memories in continuous assignments.
steve authored
456 return 0;
457 }
458
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
459 // Default part select is the entire word.
460 unsigned midx = sig->vector_width()-1, lidx = 0;
461 // The default word select is the first.
c9f6bd6 @caryr Add compiler warnings for more constant out of bounds array accesses.
caryr authored
462 long widx = 0;
37b11e0 @steveicarus Fix index out of bounds error message.
authored
463 // The widx_val is the word select as entered in the source
464 // code. It's used for error messages.
465 long widx_val = 0;
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
466
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
467 const name_component_t&name_tail = path_.back();
468
d2c3ff7 @steveicarus Handle struct members in continuous assign l-values.
authored
469 netstruct_t*struct_type = 0;
470 if ((struct_type = sig->struct_type()) && !method_name.nil()) {
471
472 // Detect the variable is a structure and there was a
761a38d @caryr Spelling fix
caryr authored
473 // method name detected.
d2c3ff7 @steveicarus Handle struct members in continuous assign l-values.
authored
474 if (debug_elaborate)
475 cerr << get_fileline() << ": debug: "
476 << "Signal " << sig->name() << " is a structure, "
477 << "try to match member " << method_name << endl;
478
479 unsigned long member_off = 0;
480 const struct netstruct_t::member_t*member = struct_type->packed_member(method_name, member_off);
481 ivl_assert(*this, member);
482
483 // Rewrite a member select of a packed structure as a
484 // part select of the base variable.
485 lidx = member_off;
486 midx = lidx + member->width() - 1;
487
488 } else if (sig->array_dimensions() > 0) {
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
489
e26b9e7 @caryr More array fixes and down indexed part selects can be a lval.
caryr authored
490 if (name_tail.index.empty()) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
491 cerr << get_fileline() << ": error: array " << sig->name()
e26b9e7 @caryr More array fixes and down indexed part selects can be a lval.
caryr authored
492 << " must be used with an index." << endl;
493 des->errors += 1;
494 return 0;
495 }
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
496
497 const index_component_t&index_head = name_tail.index.front();
e39b3fe @caryr Display a warning for a part select of an array.
caryr authored
498 if (index_head.sel == index_component_t::SEL_PART) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
499 cerr << get_fileline() << ": error: cannot perform a part "
e39b3fe @caryr Display a warning for a part select of an array.
caryr authored
500 << "select on array " << sig->name() << "." << endl;
501 des->errors += 1;
502 return 0;
503 }
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
504 ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
505
9306714 @martinwhitaker Rework of constant expression error reporting.
martinwhitaker authored
506 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
507 NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
51293b6 @caryr Fix/enhance array part select code.
caryr authored
508 if (!tmp) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
509 cerr << get_fileline() << ": error: array " << sig->name()
51293b6 @caryr Fix/enhance array part select code.
caryr authored
510 << " index must be a constant in this context." << endl;
511 des->errors += 1;
512 return 0;
513 }
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
514
37b11e0 @steveicarus Fix index out of bounds error message.
authored
515 widx_val = tmp->value().as_long();
516 if (sig->array_index_is_valid(widx_val))
517 widx = sig->array_index_to_address(widx_val);
518 else
519 widx = -1;
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
520 delete tmp_ex;
521
522 if (debug_elaborate)
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
523 cerr << get_fileline() << ": debug: Use [" << widx << "]"
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
524 << " to index l-value array." << endl;
525
51293b6 @caryr Fix/enhance array part select code.
caryr authored
526 /* 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
527 if (name_tail.index.size() > sig->array_dimensions()) {
b1dd0b1 @caryr It is an error to select part of a scalar value.
caryr authored
528 if (sig->get_scalar()) {
ec49f10 @steveicarus Revert bad merge from vhdl branch
authored
529 cerr << get_fileline() << ": error: "
b1dd0b1 @caryr It is an error to select part of a scalar value.
caryr authored
530 << "can not select part of ";
531 if (sig->data_type() == IVL_VT_REAL) cerr << "real";
532 else cerr << "scalar";
533 cerr << " array word: " << sig->name()
534 << "[" << widx_val << "]" << endl;
5852f1e @caryr 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 @steveicarus 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))
51293b6 @caryr Fix/enhance array part select code.
caryr authored
541 return 0;
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the…
caryr authored
542
543 if (lidx_tmp < 0) {
ec49f10 @steveicarus Revert bad merge from vhdl branch
authored
544 cerr << get_fileline() << ": sorry: part selects "
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the…
caryr authored
545 "straddling the start of signal (" << path_
546 << ") are not currently supported." << endl;
547 des->errors += 1;
548 return 0;
549 }
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
550 midx = midx_tmp;
551 lidx = lidx_tmp;
51293b6 @caryr Fix/enhance array part select code.
caryr authored
552 }
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
553 } else if (!name_tail.index.empty()) {
b1dd0b1 @caryr It is an error to select part of a scalar value.
caryr authored
554 if (sig->get_scalar()) {
ec49f10 @steveicarus Revert bad merge from vhdl branch
authored
555 cerr << get_fileline() << ": error: "
b1dd0b1 @caryr It is an error to select part of a scalar value.
caryr authored
556 << "can not select part of ";
557 if (sig->data_type() == IVL_VT_REAL) cerr << "real: ";
558 else cerr << "scalar: ";
559 cerr << sig->name() << endl;
5852f1e @caryr Report an error when trying to take the select of a real value.
caryr authored
560 des->errors += 1;
561 return 0;
562 }
563
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
564 long midx_tmp, lidx_tmp;
565 if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
566 return 0;
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
567
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the…
caryr authored
568 if (lidx_tmp < 0) {
ec49f10 @steveicarus Revert bad merge from vhdl branch
authored
569 cerr << get_fileline() << ": sorry: part selects "
b0e57a1 @caryr Ignore PS that are outside the signal and allow PS to extend past the…
caryr authored
570 "straddling the start of signal (" << path_
571 << ") are not currently supported." << endl;
572 des->errors += 1;
573 return 0;
574 }
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
575 midx = midx_tmp;
576 lidx = lidx_tmp;
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
577 }
4eed86d Detect part select errors on l-values.
steve authored
578
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
579 unsigned subnet_wid = midx-lidx+1;
580
5d35ad8 @steveicarus Support uwire resolved writes to non-overlapping parts
authored
581 /* Check if the l-value bits are double-driven. */
582 if (sig->type() == NetNet::UNRESOLVED_WIRE && sig->test_part_lref(midx,lidx)) {
583 cerr << get_fileline() << ": error: Unresolved net/uwire "
584 << sig->name() << " cannot have multiple drivers." << endl;
585 des->errors += 1;
586 return 0;
587 }
588
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
589 if (sig->pin_count() > 1) {
c9f6bd6 @caryr Add compiler warnings for more constant out of bounds array accesses.
caryr authored
590 if (widx < 0 || widx >= (long) sig->pin_count()) {
591 cerr << get_fileline() << ": warning: ignoring out of "
592 "bounds l-value array access "
37b11e0 @steveicarus Fix index out of bounds error message.
authored
593 << sig->name() << "[" << widx_val << "]." << endl;
c9f6bd6 @caryr Add compiler warnings for more constant out of bounds array accesses.
caryr authored
594 return 0;
595 }
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
596
597 NetNet*tmp = new NetNet(scope, scope->local_symbol(),
598 sig->type(), sig->vector_width());
599 tmp->set_line(*this);
600 tmp->local_flag(true);
4919b70 @steveicarus Give l-value nets their proper type.
authored
601 tmp->data_type( sig->data_type() );
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
602 connect(sig->pin(widx), tmp->pin(0));
603 sig = tmp;
604 }
605
e9fda22 @ldoolitt Spelling fixes
ldoolitt authored
606 /* If the desired l-value vector is narrower than the
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
607 signal itself, then use a NetPartSelect node to
608 arrange for connection to the desired bits. All this
e9fda22 @ldoolitt Spelling fixes
ldoolitt authored
609 can be skipped if the desired width matches the
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
610 original vector. */
611
612 if (subnet_wid != sig->vector_width()) {
4a8be3d Implement bi-directional part selects.
steve authored
613 /* If we are processing a tran or inout, then the
614 partselect is bi-directional. Otherwise, it is a
615 Part-to-Vector select. */
616
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
617 if (debug_elaborate)
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
618 cerr << get_fileline() << ": debug: "
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
619 << "Elaborate lnet part select "
620 << sig->name()
621 << "[base=" << lidx
622 << " wid=" << subnet_wid <<"]"
623 << endl;
a81dcd7 Support memories in continuous assignments.
steve authored
624
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
625 NetNet*subsig = new NetNet(sig->scope(),
626 sig->scope()->local_symbol(),
627 NetNet::WIRE, subnet_wid);
9a16e03 Match data type of PV select input/output.
steve authored
628 subsig->data_type( sig->data_type() );
326329d Set some missing local flags.
steve authored
629 subsig->local_flag(true);
630 subsig->set_line(*this);
a81dcd7 Support memories in continuous assignments.
steve authored
631
73e2b29 @steveicarus Replace the NetPartSelect:BI with NetTran(VP).
authored
632 if (bidirectional_flag) {
633 // Make a tran(VP)
634 NetTran*sub = new NetTran(scope, scope->local_symbol(),
635 sig->vector_width(),
636 subnet_wid, lidx);
637 sub->set_line(*this);
638 des->add_node(sub);
639 connect(sub->pin(0), sig->pin(0));
640 connect(sub->pin(1), subsig->pin(0));
cd94019 Remove NetTmp and add NetSubnet class.
steve authored
641
73e2b29 @steveicarus Replace the NetPartSelect:BI with NetTran(VP).
authored
642 } else {
643 NetPartSelect*sub = new NetPartSelect(sig, lidx, subnet_wid,
644 NetPartSelect::PV);
645 des->add_node(sub);
646 sub->set_line(*this);
647 connect(sub->pin(0), subsig->pin(0));
098bbee @steveicarus Support collapse of PartSelect::PV to concatenation
authored
648 collapse_partselect_pv_to_concat(des, sig);
73e2b29 @steveicarus Replace the NetPartSelect:BI with NetTran(VP).
authored
649 }
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
650 sig = subsig;
a81dcd7 Support memories in continuous assignments.
steve authored
651 }
652
653 return sig;
654 }
655
206b37e Fix NetConst being set to zero width, and clean
steve authored
656 /*
4a8be3d Implement bi-directional part selects.
steve authored
657 * Identifiers in continuous assignment l-values are limited to wires
658 * and that ilk. Detect registers and memories here and report errors.
659 */
d26ae86 @steveicarus Move implicit net creation from elaboration to elaborate_sig
authored
660 NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope) const
4a8be3d Implement bi-directional part selects.
steve authored
661 {
d26ae86 @steveicarus Move implicit net creation from elaboration to elaborate_sig
authored
662 return elaborate_lnet_common_(des, scope, false);
4a8be3d Implement bi-directional part selects.
steve authored
663 }
664
665 NetNet* PEIdent::elaborate_bi_net(Design*des, NetScope*scope) const
666 {
d26ae86 @steveicarus Move implicit net creation from elaboration to elaborate_sig
authored
667 return elaborate_lnet_common_(des, scope, true);
4a8be3d Implement bi-directional part selects.
steve authored
668 }
669
670 /*
3676d66 Module ports are really special PEIdent
steve authored
671 * This method is used to elaborate identifiers that are ports to a
672 * 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
673 * port. This elaboration is done inside the module, and is only done
674 * to PEIdent objects. This method is used by elaboration of a module
675 * instantiation (PGModule::elaborate_mod_) to get NetNet objects for
676 * the port.
3676d66 Module ports are really special PEIdent
steve authored
677 */
678 NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
679 {
1e3af45 @caryr Pass some module port information and fix a few bugs.
caryr authored
680 assert(scope->type() == NetScope::MODULE);
ab6c8cb Parser and pform use hierarchical names as hname_t
steve authored
681 NetNet*sig = des->find_signal(scope, path_);
3676d66 Module ports are really special PEIdent
steve authored
682 if (sig == 0) {
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
683 cerr << get_fileline() << ": error: no wire/reg " << path_
c7d97f4 Properly evaluate scope path expressions.
steve authored
684 << " in module " << scope_path(scope) << "." << endl;
3676d66 Module ports are really special PEIdent
steve authored
685 des->errors += 1;
686 return 0;
687 }
688
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
689 /* Check the port_type of the signal to make sure it is really
690 a port, and its direction is resolved. */
a59bbde Proper error messages when port direction is missing.
steve authored
691 switch (sig->port_type()) {
692 case NetNet::PINPUT:
693 case NetNet::POUTPUT:
694 case NetNet::PINOUT:
dd3a741 @steveicarus Parse SystemVerilog ref ports.
authored
695 case NetNet::PREF:
a59bbde Proper error messages when port direction is missing.
steve authored
696 break;
697
698 /* If the name matches, but the signal is not a port,
699 then the user declared the object but there is no
700 matching input/output/inout declaration. */
701
702 case NetNet::NOT_A_PORT:
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
703 cerr << get_fileline() << ": error: signal " << path_ << " in"
c7d97f4 Properly evaluate scope path expressions.
steve authored
704 << " module " << scope_path(scope) << " is not a port." << endl;
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
705 cerr << get_fileline() << ": : Are you missing an input/"
a59bbde Proper error messages when port direction is missing.
steve authored
706 << "output/inout declaration?" << endl;
707 des->errors += 1;
708 return 0;
709
710 /* This should not happen. A PWire can only become
1ff31db @caryr Add real comparisons in continuous assignments.
caryr authored
711 PIMPLICIT if this is a UDP reg port, and the make_udp
a59bbde Proper error messages when port direction is missing.
steve authored
712 function should turn it into an output.... I think. */
713
714 case NetNet::PIMPLICIT:
7975e14 @steveicarus LineInfo uses perm_string for path.
authored
715 cerr << get_fileline() << ": internal error: signal " << path_
c7d97f4 Properly evaluate scope path expressions.
steve authored
716 << " in module " << scope_path(scope) << " is left as "
a59bbde Proper error messages when port direction is missing.
steve authored
717 << "port type PIMPLICIT." << endl;
718 des->errors += 1;
719 return 0;
720 }
721
dfb7bf5 @steveicarus Handle part selects of nets that fall of the ends of the identifier.
authored
722 long midx;
723 long lidx;
3676d66 Module ports are really special PEIdent
steve authored
724
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
725 /* Evaluate the part/bit select expressions, to get the part
726 select of the signal that attaches to the port. Also handle
727 range and direction checking here. */
3676d66 Module ports are really special PEIdent
steve authored
728
9e94afe Use PartSelect/PV and VP to handle part selects through ports.
steve authored
729 if (! eval_part_select_(des, scope, sig, midx, lidx))
730 return 0;
cd94019 Remove NetTmp and add NetSubnet class.
steve authored
731
f7ee3fe @steveicarus Fix elaboration of part-select ports.
authored
732 /* If this is a part select of the entire signal (or no part
733 select at all) then we're done. */
1e3af45 @caryr Pass some module port information and fix a few bugs.
caryr authored
734 if ((lidx == 0) && (midx == (long)sig->vector_width()-1)) {
735 scope->add_module_port(sig);
f7ee3fe @steveicarus Fix elaboration of part-select ports.
authored
736 return sig;
1e3af45 @caryr Pass some module port information and fix a few bugs.
caryr authored
737 }
f7ee3fe @steveicarus Fix elaboration of part-select ports.
authored
738
739 unsigned swid = abs(midx - lidx) + 1;
740 ivl_assert(*this, swid > 0 && swid < sig->vector_width());
741
742 NetNet*tmp = new NetNet(scope, scope->local_symbol(),
743 NetNet::WIRE, swid);
744 tmp->port_type(sig->port_type());
745 tmp->data_type(sig->data_type());
746 tmp->set_line(*this);
1e3af45 @caryr Pass some module port information and fix a few bugs.
caryr authored
747 tmp->local_flag(true);
f7ee3fe @steveicarus Fix elaboration of part-select ports.
authored
748 NetNode*ps = 0;
749 switch (sig->port_type()) {
750
751 case NetNet::PINPUT:
4a4a2ee @caryr Don't normalize the port base (lidx) twice.
caryr authored
752 ps = new NetPartSelect(sig, lidx, swid, NetPartSelect::PV);
f7ee3fe @steveicarus Fix elaboration of part-select ports.
authored
753 connect(tmp->pin(0), ps->pin(0));
754 sig = tmp;
755 break;
756
757 case NetNet::POUTPUT:
4a4a2ee @caryr Don't normalize the port base (lidx) twice.
caryr authored
758 ps = new NetPartSelect(sig, lidx, swid, NetPartSelect::VP);
f7ee3fe @steveicarus Fix elaboration of part-select ports.
authored
759 connect(tmp->pin(0), ps->pin(0));
760 sig = tmp;
761 break;
3676d66 Module ports are really special PEIdent
steve authored
762
dd3a741 @steveicarus Parse SystemVerilog ref ports.
authored
763 case NetNet::PREF:
764 // For the purposes of module ports, treat ref ports
765 // just like inout ports.
f7ee3fe @steveicarus Fix elaboration of part-select ports.
authored
766 case NetNet::PINOUT:
767 ps = new NetTran(scope, scope->local_symbol(), sig->vector_width(),
4a4a2ee @caryr Don't normalize the port base (lidx) twice.
caryr authored
768 swid, lidx);
f7ee3fe @steveicarus Fix elaboration of part-select ports.
authored
769 connect(sig->pin(0), ps->pin(0));
770 connect(tmp->pin(0), ps->pin(1));
771 sig = tmp;
772 break;
3676d66 Module ports are really special PEIdent
steve authored
773
f7ee3fe @steveicarus Fix elaboration of part-select ports.
authored
774 default:
775 ivl_assert(*this, 0);
776 break;
3676d66 Module ports are really special PEIdent
steve authored
777 }
778
f7ee3fe @steveicarus Fix elaboration of part-select ports.
authored
779 ps->set_line(*this);
780 des->add_node(ps);
781
1e3af45 @caryr Pass some module port information and fix a few bugs.
caryr authored
782 scope->add_module_port(sig);
3676d66 Module ports are really special PEIdent
steve authored
783 return sig;
784 }
e01358b @martinwhitaker Fix for pr3194155.
martinwhitaker authored
785
786 bool PEIdent::is_collapsible_net(Design*des, NetScope*scope) const
787 {
788 assert(scope);
789
790 NetNet* sig = 0;
791 const NetExpr*par = 0;
792 NetEvent* eve = 0;
793
794 symbol_search(this, des, scope, path_, sig, par, eve);
795
796 if (eve != 0)
797 return false;
798
799 if (sig == 0)
800 return false;
801
802 assert(sig);
803
804 /* If this is SystemVerilog and the variable is not yet
805 assigned by anything, then convert it to an unresolved
806 wire. */
807 if (gn_var_can_be_uwire()
808 && (sig->type() == NetNet::REG)
809 && (sig->peek_eref() == 0) ) {
810 sig->type(NetNet::UNRESOLVED_WIRE);
811 }
812
813 if (sig->type() == NetNet::UNRESOLVED_WIRE && sig->pin(0).is_linked())
814 return false;
815
816 if (sig->type() == NetNet::REG)
817 return false;
818
819 return true;
820 }
Something went wrong with that request. Please try again.