Skip to content

HTTPS clone URL

Subversion checkout URL

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