Skip to content
This repository
Newer
Older
100644 699 lines (595 sloc) 21.238 kb
e1bbbe56 » steve
1999-10-31 Include subtraction in LPM_ADD_SUB device.
1 /*
5d7f8c97 » caryr
2009-01-08 Update copyright in files changed in 2009
2 * Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com)
e1bbbe56 » steve
1999-10-31 Include subtraction in LPM_ADD_SUB device.
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
b825f8d2 » steve
2001-07-25 Create a config.h.in file to hold all the config
20 # include "config.h"
21
e1bbbe56 » steve
1999-10-31 Include subtraction in LPM_ADD_SUB device.
22 # include "PExpr.h"
23 # include "netlist.h"
b354cf68 » steve
2000-02-16 Fix up width matching in structural bitwise operators.
24 # include "netmisc.h"
48de7395 » steve
2000-03-17 Switch to control warnings.
25 # include "compiler.h"
e1bbbe56 » steve
1999-10-31 Include subtraction in LPM_ADD_SUB device.
26
8ea3b6b0 » ldoolitt
2008-01-04 header includes for gcc-4.3 compatibility
27 # include <cstdlib>
28 # include <cstring>
b825f8d2 » steve
2001-07-25 Create a config.h.in file to hold all the config
29 # include <iostream>
b2e1db6a » steve
2007-01-31 Add method to bind assertions to verilog source lines.
30 # include "ivl_assert.h"
b825f8d2 » steve
2001-07-25 Create a config.h.in file to hold all the config
31
d1f0bcf6 » steve
2003-09-23 Catch unsized expressions in continuous assigns.
32 /*
cfd8cbf8 » steve
2002-11-09 Port expressions for output ports are lnets, not nets.
33 * The concatenation is also OK an an l-value. This method elaborates
65e9b6be » steve
2004-12-11 Rework of internals to carry vectors through nexus instead
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.
cfd8cbf8 » steve
2002-11-09 Port expressions for output ports are lnets, not nets.
38 */
a2c036d5 » steve
2006-04-28 Allow concatenations as arguments to inout ports.
39 NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
40 bool bidirectional_flag) const
cfd8cbf8 » steve
2002-11-09 Port expressions for output ports are lnets, not nets.
41 {
42 assert(scope);
43
44 svector<NetNet*>nets (parms_.count());
65e9b6be » steve
2004-12-11 Rework of internals to carry vectors through nexus instead
45 unsigned width = 0;
cfd8cbf8 » steve
2002-11-09 Port expressions for output ports are lnets, not nets.
46 unsigned errors = 0;
47
48 if (repeat_) {
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
49 cerr << get_fileline() << ": sorry: I do not know how to"
cfd8cbf8 » steve
2002-11-09 Port expressions for output ports are lnets, not nets.
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) {
07a427bf » steve
2003-01-19 Detect null arguments to concatenation operator.
56
65e9b6be » steve
2004-12-11 Rework of internals to carry vectors through nexus instead
57 if (debug_elaborate) {
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
58 cerr << get_fileline() << ": debug: Elaborate subexpression "
65e9b6be » steve
2004-12-11 Rework of internals to carry vectors through nexus instead
59 << idx << " of " << nets.count() << " l-values: "
60 << *parms_[idx] << endl;
61 }
62
07a427bf » steve
2003-01-19 Detect null arguments to concatenation operator.
63 if (parms_[idx] == 0) {
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
64 cerr << get_fileline() << ": error: Empty expressions "
07a427bf » steve
2003-01-19 Detect null arguments to concatenation operator.
65 << "not allowed in concatenations." << endl;
66 errors += 1;
67 continue;
68 }
69
a2c036d5 » steve
2006-04-28 Allow concatenations as arguments to inout ports.
70 if (bidirectional_flag) {
71 nets[idx] = parms_[idx]->elaborate_bi_net(des, scope);
72 } else {
d26ae866 »
2008-03-18 Move implicit net creation from elaboration to elaborate_sig
73 nets[idx] = parms_[idx]->elaborate_lnet(des, scope);
a2c036d5 » steve
2006-04-28 Allow concatenations as arguments to inout ports.
74 }
464310f5 » caryr
2009-04-02 Report an error when trying to take the concatenation of a real value.
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;
cfd8cbf8 » steve
2002-11-09 Port expressions for output ports are lnets, not nets.
81 errors += 1;
464310f5 » caryr
2009-04-02 Report an error when trying to take the concatenation of a real value.
82 continue;
83 } else width += nets[idx]->vector_width();
84
cfd8cbf8 » steve
2002-11-09 Port expressions for output ports are lnets, not nets.
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 }
fac1cc5a » caryr
2008-02-22 Add user function synth and clean up expression code.
93 des->errors += errors;
cfd8cbf8 » steve
2002-11-09 Port expressions for output ports are lnets, not nets.
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
65e9b6be » steve
2004-12-11 Rework of internals to carry vectors through nexus instead
99 concat operator from most significant to least significant,
100 which is the order they are given in the concat list. */
101
badad63a » steve
2003-03-06 All NetObj objects have lex_string base names.
102 NetNet*osig = new NetNet(scope, scope->local_symbol(),
65e9b6be » steve
2004-12-11 Rework of internals to carry vectors through nexus instead
103 NetNet::IMPLICIT, width);
104
0c9fb766 » steve
2006-04-30 Get the data type of part select results right.
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());
326329d4 » steve
2007-02-05 Set some missing local flags.
108 osig->local_flag(true);
109 osig->set_line(*this);
65e9b6be » steve
2004-12-11 Rework of internals to carry vectors through nexus instead
110
73e2b297 »
2008-06-03 Replace the NetPartSelect:BI with NetTran(VP).
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 }
cfd8cbf8 » steve
2002-11-09 Port expressions for output ports are lnets, not nets.
117
73e2b297 »
2008-06-03 Replace the NetPartSelect:BI with NetTran(VP).
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);
a2c036d5 » steve
2006-04-28 Allow concatenations as arguments to inout ports.
125
73e2b297 »
2008-06-03 Replace the NetPartSelect:BI with NetTran(VP).
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);
65e9b6be » steve
2004-12-11 Rework of internals to carry vectors through nexus instead
148
73e2b297 »
2008-06-03 Replace the NetPartSelect:BI with NetTran(VP).
149 connect(ps->pin(1), osig->pin(0));
150 connect(ps->pin(0), nets[idx]->pin(0));
65e9b6be » steve
2004-12-11 Rework of internals to carry vectors through nexus instead
151
73e2b297 »
2008-06-03 Replace the NetPartSelect:BI with NetTran(VP).
152 assert(wid <= width);
153 width -= wid;
154 }
155 assert(width == 0);
65e9b6be » steve
2004-12-11 Rework of internals to carry vectors through nexus instead
156 }
157
a8b86ea3 » steve
2006-05-01 More explicit datatype setup.
158 osig->data_type(nets[0]->data_type());
cfd8cbf8 » steve
2002-11-09 Port expressions for output ports are lnets, not nets.
159 osig->local_flag(true);
160 return osig;
161 }
162
d26ae866 »
2008-03-18 Move implicit net creation from elaboration to elaborate_sig
163 NetNet* PEConcat::elaborate_lnet(Design*des, NetScope*scope) const
a2c036d5 » steve
2006-04-28 Allow concatenations as arguments to inout ports.
164 {
d26ae866 »
2008-03-18 Move implicit net creation from elaboration to elaborate_sig
165 return elaborate_lnet_common_(des, scope, false);
a2c036d5 » steve
2006-04-28 Allow concatenations as arguments to inout ports.
166 }
167
168 NetNet* PEConcat::elaborate_bi_net(Design*des, NetScope*scope) const
169 {
d26ae866 »
2008-03-18 Move implicit net creation from elaboration to elaborate_sig
170 return elaborate_lnet_common_(des, scope, true);
a2c036d5 » steve
2006-04-28 Allow concatenations as arguments to inout ports.
171 }
172
cfd8cbf8 » steve
2002-11-09 Port expressions for output ports are lnets, not nets.
173 /*
4a8be3db » steve
2005-08-06 Implement bi-directional part selects.
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();
13d4a735 »
2008-03-18 Elaborate implicit signals that are arguments to module instances.
179 assert(nettype != NetNet::NONE);
180
181 NetNet*sig = new NetNet(scope, peek_tail_name(path_),
182 NetNet::IMPLICIT, 1);
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;
4a8be3db » steve
2005-08-06 Implement bi-directional part selects.
191 }
192
193 return sig;
194 }
195
196 /*
9e94afe3 » steve
2005-01-09 Use PartSelect/PV and VP to handle part selects through ports.
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,
dfb7bf52 »
2008-05-09 Handle part selects of nets that fall of the ends of the identifier.
204 long&midx, long&lidx) const
9e94afe3 » steve
2005-01-09 Use PartSelect/PV and VP to handle part selects through ports.
205 {
ddd36ecb » steve
2007-05-24 Rework the heirarchical identifier parse syntax and pform
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) {
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
221 default:
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
222 cerr << get_fileline() << ": internal error: "
ddd36ecb » steve
2007-05-24 Rework the heirarchical identifier parse syntax and pform
223 << "Unexpected sel_ value = " << index_tail.sel << endl;
224 ivl_assert(*this, 0);
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
225 break;
9e94afe3 » steve
2005-01-09 Use PartSelect/PV and VP to handle part selects through ports.
226
ddd36ecb » steve
2007-05-24 Rework the heirarchical identifier parse syntax and pform
227 case index_component_t::SEL_IDX_DO:
228 case index_component_t::SEL_IDX_UP: {
944495b9 » caryr
2009-03-02 More constant function not supported warnings.
229 need_constant_expr = true;
ddd36ecb » steve
2007-05-24 Rework the heirarchical identifier parse syntax and pform
230 NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1);
944495b9 » caryr
2009-03-02 More constant function not supported warnings.
231 need_constant_expr = false;
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
232 NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
e26b9e72 » caryr
2007-11-07 More array fixes and down indexed part selects can be a lval.
233 if (!tmp) {
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
234 cerr << get_fileline() << ": error: indexed part select of "
e26b9e72 » caryr
2007-11-07 More array fixes and down indexed part selects can be a lval.
235 << sig->name()
236 << " must be a constant in this context." << endl;
237 des->errors += 1;
238 return 0;
239 }
9e94afe3 » steve
2005-01-09 Use PartSelect/PV and VP to handle part selects through ports.
240
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
241 long midx_val = tmp->value().as_long();
242 midx = sig->sb_to_idx(midx_val);
243 delete tmp_ex;
9e94afe3 » steve
2005-01-09 Use PartSelect/PV and VP to handle part selects through ports.
244
018f1a6e »
2007-07-02 Handle indexed part select in continuous assign.
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;
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
250
ddd36ecb » steve
2007-05-24 Rework the heirarchical identifier parse syntax and pform
251 if (index_tail.sel == index_component_t::SEL_IDX_UP)
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
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) {
3adcbb56 » ldoolitt
2008-10-13 Shadow reduction part 2
257 long tmpx = midx;
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
258 midx = lidx;
3adcbb56 » ldoolitt
2008-10-13 Shadow reduction part 2
259 lidx = tmpx;
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
260 }
261
b0e57a1a » caryr
2008-10-14 Ignore PS that are outside the signal and allow PS to extend past the…
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
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
283 break;
284 }
285
ddd36ecb » steve
2007-05-24 Rework the heirarchical identifier parse syntax and pform
286 case index_component_t::SEL_PART: {
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
287
018f1a6e »
2007-07-02 Handle indexed part select in continuous assign.
288 long msb, lsb;
b45834f0 »
2009-01-01 Handle part selects with bad (xz) bits.
289 bool part_defined_flag;
290 /* bool flag = */ calculate_parts_(des, scope, msb, lsb, part_defined_flag);
291 ivl_assert(*this, part_defined_flag);
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
292
dfb7bf52 »
2008-05-09 Handle part selects of nets that fall of the ends of the identifier.
293 long lidx_tmp = sig->sb_to_idx(lsb);
294 long midx_tmp = sig->sb_to_idx(msb);
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
295 /* Detect reversed indices of a part select. */
dfb7bf52 »
2008-05-09 Handle part selects of nets that fall of the ends of the identifier.
296 if (lidx_tmp > midx_tmp) {
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
297 cerr << get_fileline() << ": error: Part select "
018f1a6e »
2007-07-02 Handle indexed part select in continuous assign.
298 << sig->name() << "[" << msb << ":"
299 << lsb << "] indices reversed." << endl;
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
300 cerr << get_fileline() << ": : Did you mean "
018f1a6e »
2007-07-02 Handle indexed part select in continuous assign.
301 << sig->name() << "[" << lsb << ":"
302 << msb << "]?" << endl;
dfb7bf52 »
2008-05-09 Handle part selects of nets that fall of the ends of the identifier.
303 long tmp = midx_tmp;
304 midx_tmp = lidx_tmp;
305 lidx_tmp = tmp;
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
306 des->errors += 1;
307 }
308
b0e57a1a » caryr
2008-10-14 Ignore PS that are outside the signal and allow PS to extend past the…
309 /* Warn about a part select that is out of range. */
dfb7bf52 »
2008-05-09 Handle part selects of nets that fall of the ends of the identifier.
310 if (midx_tmp >= (long)sig->vector_width() || lidx_tmp < 0) {
311 cerr << get_fileline() << ": warning: Part select "
b0e57a1a » caryr
2008-10-14 Ignore PS that are outside the signal and allow PS to extend past the…
312 << sig->name();
313 if (sig->array_dimensions() > 0) {
314 cerr << "[]";
315 }
316 cerr << "[" << msb << ":" << lsb
317 << "] is out of range." << endl;
dfb7bf52 »
2008-05-09 Handle part selects of nets that fall of the ends of the identifier.
318 #if 0
319 midx_tmp = sig->vector_width() - 1;
320 lidx_tmp = 0;
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
321 des->errors += 1;
dfb7bf52 »
2008-05-09 Handle part selects of nets that fall of the ends of the identifier.
322 #endif
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
323 }
b0e57a1a » caryr
2008-10-14 Ignore PS that are outside the signal and allow PS to extend past the…
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 }
dfb7bf52 »
2008-05-09 Handle part selects of nets that fall of the ends of the identifier.
328
329 midx = midx_tmp;
330 lidx = lidx_tmp;
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
331 break;
332 }
333
ddd36ecb » steve
2007-05-24 Rework the heirarchical identifier parse syntax and pform
334 case index_component_t::SEL_BIT:
335 if (name_tail.index.size() > sig->array_dimensions()) {
129a064e » steve
2007-06-04 Handle bit/part select of array words in nets.
336 verinum*mval = index_tail.msb->eval_const(des, scope);
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
337 if (mval == 0) {
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
338 cerr << get_fileline() << ": error: Index of " << path_ <<
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
339 " needs to be constant in this context." <<
340 endl;
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
341 cerr << get_fileline() << ": : Index expression is: "
129a064e » steve
2007-06-04 Handle bit/part select of array words in nets.
342 << *index_tail.msb << endl;
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
343 cerr << get_fileline() << ": : Context scope is: "
8ec6d998 » steve
2007-06-12 Put instantiated modules in the proper generated scope.
344 << scope_path(scope) << endl;
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
345 des->errors += 1;
346 return false;
347 }
348 assert(mval);
349
350 midx = sig->sb_to_idx(mval->as_long());
dfb7bf52 »
2008-05-09 Handle part selects of nets that fall of the ends of the identifier.
351 if (midx >= (long)sig->vector_width()) {
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
352 cerr << get_fileline() << ": error: Index " << sig->name()
b0e57a1a » caryr
2008-10-14 Ignore PS that are outside the signal and allow PS to extend past the…
353 << "[" << mval->as_long() << "] is out of range."
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
354 << endl;
355 des->errors += 1;
356 midx = 0;
357 }
358 lidx = midx;
359
360 } else {
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
361 cerr << get_fileline() << ": internal error: "
ddd36ecb » steve
2007-05-24 Rework the heirarchical identifier parse syntax and pform
362 << "Bit select " << path_ << endl;
363 ivl_assert(*this, 0);
c2ff3d50 » steve
2006-04-24 Fix support for indexed part select in continuous assign l-values.
364 midx = sig->vector_width() - 1;
365 lidx = 0;
366 }
367 break;
9e94afe3 » steve
2005-01-09 Use PartSelect/PV and VP to handle part selects through ports.
368 }
369
370 return true;
371 }
372
373 /*
4a8be3db » steve
2005-08-06 Implement bi-directional part selects.
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.
a81dcd79 » steve
1999-11-21 Support memories in continuous assignments.
377 */
4a8be3db » steve
2005-08-06 Implement bi-directional part selects.
378 NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
379 bool bidirectional_flag) const
a81dcd79 » steve
1999-11-21 Support memories in continuous assignments.
380 {
69379455 » steve
2003-09-19 Remove find_memory method from Design class.
381 assert(scope);
382
383 NetNet* sig = 0;
384 const NetExpr*par = 0;
385 NetEvent* eve = 0;
386
18edf2f1 » Martin Whitaker
2008-10-28 Rework of automatic task/function support.
387 symbol_search(this, des, scope, path_, sig, par, eve);
69379455 » steve
2003-09-19 Remove find_memory method from Design class.
388
389 if (eve != 0) {
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
390 cerr << get_fileline() << ": error: named events (" << path_
69379455 » steve
2003-09-19 Remove find_memory method from Design class.
391 << ") cannot be l-values in continuous "
392 << "assignments." << endl;
393 des->errors += 1;
394 return 0;
395 }
396
a81dcd79 » steve
1999-11-21 Support memories in continuous assignments.
397 if (sig == 0) {
d26ae866 »
2008-03-18 Move implicit net creation from elaboration to elaborate_sig
398 cerr << get_fileline() << ": error: Net " << path_
399 << " is not defined in this context." << endl;
400 des->errors += 1;
401 return 0;
a81dcd79 » steve
1999-11-21 Support memories in continuous assignments.
402 }
403
404 assert(sig);
405
406 /* Don't allow registers as assign l-values. */
407 if (sig->type() == NetNet::REG) {
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
408 cerr << get_fileline() << ": error: reg " << sig->name()
c96598a4 » steve
2003-08-05 Primitive outputs have same limitations as continuous assignment.
409 << "; cannot be driven by primitives"
410 << " or continuous assignment." << endl;
411 des->errors += 1;
a81dcd79 » steve
1999-11-21 Support memories in continuous assignments.
412 return 0;
413 }
414
4d0b840c » steve
2001-11-10 Coerse input to inout when assigned to.
415 if (sig->port_type() == NetNet::PINPUT) {
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
416 cerr << get_fileline() << ": warning: L-value ``"
c0321861 » steve
2002-12-06 Reword some error messages for clarity.
417 << sig->name() << "'' is also an input port." << endl;
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
418 cerr << sig->get_fileline() << ": warning: input "
c0321861 » steve
2002-12-06 Reword some error messages for clarity.
419 << sig->name() << "; is coerced to inout." << endl;
4d0b840c » steve
2001-11-10 Coerse input to inout when assigned to.
420 sig->port_type(NetNet::PINOUT);
421 }
422
91d84e7d » steve
2007-01-16 Major rework of array handling. Memories are replaced with the
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.
426 unsigned widx = 0;
427
ddd36ecb » steve
2007-05-24 Rework the heirarchical identifier parse syntax and pform
428 const name_component_t&name_tail = path_.back();
429
91d84e7d » steve
2007-01-16 Major rework of array handling. Memories are replaced with the
430 if (sig->array_dimensions() > 0) {
431
e26b9e72 » caryr
2007-11-07 More array fixes and down indexed part selects can be a lval.
432 if (name_tail.index.empty()) {
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
433 cerr << get_fileline() << ": error: array " << sig->name()
e26b9e72 » caryr
2007-11-07 More array fixes and down indexed part selects can be a lval.
434 << " must be used with an index." << endl;
435 des->errors += 1;
436 return 0;
437 }
ddd36ecb » steve
2007-05-24 Rework the heirarchical identifier parse syntax and pform
438
439 const index_component_t&index_head = name_tail.index.front();
e39b3fea » caryr
2007-11-06 Display a warning for a part select of an array.
440 if (index_head.sel == index_component_t::SEL_PART) {
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
441 cerr << get_fileline() << ": error: cannot perform a part "
e39b3fea » caryr
2007-11-06 Display a warning for a part select of an array.
442 << "select on array " << sig->name() << "." << endl;
443 des->errors += 1;
444 return 0;
445 }
ddd36ecb » steve
2007-05-24 Rework the heirarchical identifier parse syntax and pform
446 ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
447
944495b9 » caryr
2009-03-02 More constant function not supported warnings.
448 need_constant_expr = true;
ddd36ecb » steve
2007-05-24 Rework the heirarchical identifier parse syntax and pform
449 NetExpr*tmp_ex = elab_and_eval(des, scope, index_head.msb, -1);
944495b9 » caryr
2009-03-02 More constant function not supported warnings.
450 need_constant_expr = false;
91d84e7d » steve
2007-01-16 Major rework of array handling. Memories are replaced with the
451 NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
51293b6e » caryr
2007-11-06 Fix/enhance array part select code.
452 if (!tmp) {
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
453 cerr << get_fileline() << ": error: array " << sig->name()
51293b6e » caryr
2007-11-06 Fix/enhance array part select code.
454 << " index must be a constant in this context." << endl;
455 des->errors += 1;
456 return 0;
457 }
91d84e7d » steve
2007-01-16 Major rework of array handling. Memories are replaced with the
458
459 long widx_val = tmp->value().as_long();
460 widx = sig->array_index_to_address(widx_val);
461 delete tmp_ex;
462
463 if (debug_elaborate)
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
464 cerr << get_fileline() << ": debug: Use [" << widx << "]"
91d84e7d » steve
2007-01-16 Major rework of array handling. Memories are replaced with the
465 << " to index l-value array." << endl;
466
51293b6e » caryr
2007-11-06 Fix/enhance array part select code.
467 /* The array has a part/bit select at the end. */
e26b9e72 » caryr
2007-11-07 More array fixes and down indexed part selects can be a lval.
468 if (name_tail.index.size() > sig->array_dimensions()) {
5852f1eb » caryr
2009-04-01 Report an error when trying to take the select of a real value.
469 if (sig->data_type() == IVL_VT_REAL) {
470 cerr << get_fileline() << ": error: "
3517f11c » caryr
2009-04-02 Enhance the real selection is invalid error messages.
471 << "can not select part of real array word: "
472 << sig->name() << "[" << widx_val << "]" << endl;
5852f1eb » caryr
2009-04-01 Report an error when trying to take the select of a real value.
473 des->errors += 1;
474 return 0;
475 }
476
dfb7bf52 »
2008-05-09 Handle part selects of nets that fall of the ends of the identifier.
477 long midx_tmp, lidx_tmp;
478 if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
51293b6e » caryr
2007-11-06 Fix/enhance array part select code.
479 return 0;
b0e57a1a » caryr
2008-10-14 Ignore PS that are outside the signal and allow PS to extend past the…
480
481 if (lidx_tmp < 0) {
482 cerr << get_fileline() << ": sorry: part selects "
483 "straddling the start of signal (" << path_
484 << ") are not currently supported." << endl;
485 des->errors += 1;
486 return 0;
487 }
dfb7bf52 »
2008-05-09 Handle part selects of nets that fall of the ends of the identifier.
488 midx = midx_tmp;
489 lidx = lidx_tmp;
51293b6e » caryr
2007-11-06 Fix/enhance array part select code.
490 }
ddd36ecb » steve
2007-05-24 Rework the heirarchical identifier parse syntax and pform
491 } else if (!name_tail.index.empty()) {
5852f1eb » caryr
2009-04-01 Report an error when trying to take the select of a real value.
492 if (sig->data_type() == IVL_VT_REAL) {
493 cerr << get_fileline() << ": error: "
3517f11c » caryr
2009-04-02 Enhance the real selection is invalid error messages.
494 << "can not select part of real: "
495 << sig->name() << endl;
5852f1eb » caryr
2009-04-01 Report an error when trying to take the select of a real value.
496 des->errors += 1;
497 return 0;
498 }
499
dfb7bf52 »
2008-05-09 Handle part selects of nets that fall of the ends of the identifier.
500 long midx_tmp, lidx_tmp;
501 if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
91d84e7d » steve
2007-01-16 Major rework of array handling. Memories are replaced with the
502 return 0;
dfb7bf52 »
2008-05-09 Handle part selects of nets that fall of the ends of the identifier.
503
b0e57a1a » caryr
2008-10-14 Ignore PS that are outside the signal and allow PS to extend past the…
504 if (lidx_tmp < 0) {
505 cerr << get_fileline() << ": sorry: part selects "
506 "straddling the start of signal (" << path_
507 << ") are not currently supported." << endl;
508 des->errors += 1;
509 return 0;
510 }
dfb7bf52 »
2008-05-09 Handle part selects of nets that fall of the ends of the identifier.
511 midx = midx_tmp;
512 lidx = lidx_tmp;
91d84e7d » steve
2007-01-16 Major rework of array handling. Memories are replaced with the
513 }
4eed86d5 » steve
2000-12-01 Detect part select errors on l-values.
514
9e94afe3 » steve
2005-01-09 Use PartSelect/PV and VP to handle part selects through ports.
515 unsigned subnet_wid = midx-lidx+1;
516
91d84e7d » steve
2007-01-16 Major rework of array handling. Memories are replaced with the
517 if (sig->pin_count() > 1) {
518 assert(widx < sig->pin_count());
519
520 NetNet*tmp = new NetNet(scope, scope->local_symbol(),
521 sig->type(), sig->vector_width());
522 tmp->set_line(*this);
523 tmp->local_flag(true);
4919b70d »
2008-09-25 Give l-value nets their proper type.
524 tmp->data_type( sig->data_type() );
91d84e7d » steve
2007-01-16 Major rework of array handling. Memories are replaced with the
525 connect(sig->pin(widx), tmp->pin(0));
526 sig = tmp;
527 }
528
9e94afe3 » steve
2005-01-09 Use PartSelect/PV and VP to handle part selects through ports.
529 /* If the desired l-value vector is narrower then the
530 signal itself, then use a NetPartSelect node to
531 arrange for connection to the desired bits. All this
532 can be skipped if the desired with matches the
533 original vector. */
534
535 if (subnet_wid != sig->vector_width()) {
4a8be3db » steve
2005-08-06 Implement bi-directional part selects.
536 /* If we are processing a tran or inout, then the
537 partselect is bi-directional. Otherwise, it is a
538 Part-to-Vector select. */
539
9e94afe3 » steve
2005-01-09 Use PartSelect/PV and VP to handle part selects through ports.
540 if (debug_elaborate)
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
541 cerr << get_fileline() << ": debug: "
9e94afe3 » steve
2005-01-09 Use PartSelect/PV and VP to handle part selects through ports.
542 << "Elaborate lnet part select "
543 << sig->name()
544 << "[base=" << lidx
545 << " wid=" << subnet_wid <<"]"
546 << endl;
a81dcd79 » steve
1999-11-21 Support memories in continuous assignments.
547
9e94afe3 » steve
2005-01-09 Use PartSelect/PV and VP to handle part selects through ports.
548 NetNet*subsig = new NetNet(sig->scope(),
549 sig->scope()->local_symbol(),
550 NetNet::WIRE, subnet_wid);
9a16e030 » steve
2005-07-15 Match data type of PV select input/output.
551 subsig->data_type( sig->data_type() );
326329d4 » steve
2007-02-05 Set some missing local flags.
552 subsig->local_flag(true);
553 subsig->set_line(*this);
a81dcd79 » steve
1999-11-21 Support memories in continuous assignments.
554
73e2b297 »
2008-06-03 Replace the NetPartSelect:BI with NetTran(VP).
555 if (bidirectional_flag) {
556 // Make a tran(VP)
557 NetTran*sub = new NetTran(scope, scope->local_symbol(),
558 sig->vector_width(),
559 subnet_wid, lidx);
560 sub->set_line(*this);
561 des->add_node(sub);
562 connect(sub->pin(0), sig->pin(0));
563 connect(sub->pin(1), subsig->pin(0));
cd940197 » steve
2002-06-19 Remove NetTmp and add NetSubnet class.
564
73e2b297 »
2008-06-03 Replace the NetPartSelect:BI with NetTran(VP).
565 } else {
566 NetPartSelect*sub = new NetPartSelect(sig, lidx, subnet_wid,
567 NetPartSelect::PV);
568 des->add_node(sub);
569 sub->set_line(*this);
570 connect(sub->pin(0), subsig->pin(0));
571 }
9e94afe3 » steve
2005-01-09 Use PartSelect/PV and VP to handle part selects through ports.
572 sig = subsig;
a81dcd79 » steve
1999-11-21 Support memories in continuous assignments.
573 }
574
575 return sig;
576 }
577
206b37e5 » steve
1999-11-05 Fix NetConst being set to zero width, and clean
578 /*
4a8be3db » steve
2005-08-06 Implement bi-directional part selects.
579 * Identifiers in continuous assignment l-values are limited to wires
580 * and that ilk. Detect registers and memories here and report errors.
581 */
d26ae866 »
2008-03-18 Move implicit net creation from elaboration to elaborate_sig
582 NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope) const
4a8be3db » steve
2005-08-06 Implement bi-directional part selects.
583 {
d26ae866 »
2008-03-18 Move implicit net creation from elaboration to elaborate_sig
584 return elaborate_lnet_common_(des, scope, false);
4a8be3db » steve
2005-08-06 Implement bi-directional part selects.
585 }
586
587 NetNet* PEIdent::elaborate_bi_net(Design*des, NetScope*scope) const
588 {
d26ae866 »
2008-03-18 Move implicit net creation from elaboration to elaborate_sig
589 return elaborate_lnet_common_(des, scope, true);
4a8be3db » steve
2005-08-06 Implement bi-directional part selects.
590 }
591
592 /*
3676d664 » steve
2000-05-16 Module ports are really special PEIdent
593 * This method is used to elaborate identifiers that are ports to a
594 * scope. The scope is presumed to be that of the module that has the
9e94afe3 » steve
2005-01-09 Use PartSelect/PV and VP to handle part selects through ports.
595 * port. This elaboration is done inside the module, and is only done
596 * to PEIdent objects. This method is used by elaboration of a module
597 * instantiation (PGModule::elaborate_mod_) to get NetNet objects for
598 * the port.
3676d664 » steve
2000-05-16 Module ports are really special PEIdent
599 */
600 NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
601 {
ab6c8cb4 » steve
2001-12-03 Parser and pform use hierarchical names as hname_t
602 NetNet*sig = des->find_signal(scope, path_);
3676d664 » steve
2000-05-16 Module ports are really special PEIdent
603 if (sig == 0) {
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
604 cerr << get_fileline() << ": error: no wire/reg " << path_
c7d97f41 » steve
2007-06-02 Properly evaluate scope path expressions.
605 << " in module " << scope_path(scope) << "." << endl;
3676d664 » steve
2000-05-16 Module ports are really special PEIdent
606 des->errors += 1;
607 return 0;
608 }
609
9e94afe3 » steve
2005-01-09 Use PartSelect/PV and VP to handle part selects through ports.
610 /* Check the port_type of the signal to make sure it is really
611 a port, and its direction is resolved. */
a59bbdeb » steve
2000-08-18 Proper error messages when port direction is missing.
612 switch (sig->port_type()) {
613 case NetNet::PINPUT:
614 case NetNet::POUTPUT:
615 case NetNet::PINOUT:
616 break;
617
618 /* If the name matches, but the signal is not a port,
619 then the user declared the object but there is no
620 matching input/output/inout declaration. */
621
622 case NetNet::NOT_A_PORT:
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
623 cerr << get_fileline() << ": error: signal " << path_ << " in"
c7d97f41 » steve
2007-06-02 Properly evaluate scope path expressions.
624 << " module " << scope_path(scope) << " is not a port." << endl;
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
625 cerr << get_fileline() << ": : Are you missing an input/"
a59bbdeb » steve
2000-08-18 Proper error messages when port direction is missing.
626 << "output/inout declaration?" << endl;
627 des->errors += 1;
628 return 0;
629
630 /* This should not happen. A PWire can only become
1ff31db2 » caryr
2008-01-15 Add real comparisons in continuous assignments.
631 PIMPLICIT if this is a UDP reg port, and the make_udp
a59bbdeb » steve
2000-08-18 Proper error messages when port direction is missing.
632 function should turn it into an output.... I think. */
633
634 case NetNet::PIMPLICIT:
7975e14b »
2007-12-20 LineInfo uses perm_string for path.
635 cerr << get_fileline() << ": internal error: signal " << path_
c7d97f41 » steve
2007-06-02 Properly evaluate scope path expressions.
636 << " in module " << scope_path(scope) << " is left as "
a59bbdeb » steve
2000-08-18 Proper error messages when port direction is missing.
637 << "port type PIMPLICIT." << endl;
638 des->errors += 1;
639 return 0;
640 }
641
dfb7bf52 »
2008-05-09 Handle part selects of nets that fall of the ends of the identifier.
642 long midx;
643 long lidx;
3676d664 » steve
2000-05-16 Module ports are really special PEIdent
644
9e94afe3 » steve
2005-01-09 Use PartSelect/PV and VP to handle part selects through ports.
645 /* Evaluate the part/bit select expressions, to get the part
646 select of the signal that attaches to the port. Also handle
647 range and direction checking here. */
3676d664 » steve
2000-05-16 Module ports are really special PEIdent
648
9e94afe3 » steve
2005-01-09 Use PartSelect/PV and VP to handle part selects through ports.
649 if (! eval_part_select_(des, scope, sig, midx, lidx))
650 return 0;
cd940197 » steve
2002-06-19 Remove NetTmp and add NetSubnet class.
651
f7ee3fe1 »
2008-12-11 Fix elaboration of part-select ports.
652 /* If this is a part select of the entire signal (or no part
653 select at all) then we're done. */
654 if ((lidx == 0) && (midx == (long)sig->vector_width()-1))
655 return sig;
656
657 unsigned swid = abs(midx - lidx) + 1;
658 ivl_assert(*this, swid > 0 && swid < sig->vector_width());
659
660 NetNet*tmp = new NetNet(scope, scope->local_symbol(),
661 NetNet::WIRE, swid);
662 tmp->port_type(sig->port_type());
663 tmp->data_type(sig->data_type());
664 tmp->set_line(*this);
665 NetNode*ps = 0;
666 switch (sig->port_type()) {
667
668 case NetNet::PINPUT:
669 ps = new NetPartSelect(sig, sig->sb_to_idx(lidx), swid,
670 NetPartSelect::PV);
671 connect(tmp->pin(0), ps->pin(0));
672 sig = tmp;
673 break;
674
675 case NetNet::POUTPUT:
676 ps = new NetPartSelect(sig, sig->sb_to_idx(lidx), swid,
677 NetPartSelect::VP);
678 connect(tmp->pin(0), ps->pin(0));
679 sig = tmp;
680 break;
3676d664 » steve
2000-05-16 Module ports are really special PEIdent
681
f7ee3fe1 »
2008-12-11 Fix elaboration of part-select ports.
682 case NetNet::PINOUT:
683 ps = new NetTran(scope, scope->local_symbol(), sig->vector_width(),
684 swid, sig->sb_to_idx(lidx));
685 connect(sig->pin(0), ps->pin(0));
686 connect(tmp->pin(0), ps->pin(1));
687 sig = tmp;
688 break;
3676d664 » steve
2000-05-16 Module ports are really special PEIdent
689
f7ee3fe1 »
2008-12-11 Fix elaboration of part-select ports.
690 default:
691 ivl_assert(*this, 0);
692 break;
3676d664 » steve
2000-05-16 Module ports are really special PEIdent
693 }
694
f7ee3fe1 »
2008-12-11 Fix elaboration of part-select ports.
695 ps->set_line(*this);
696 des->add_node(ps);
697
3676d664 » steve
2000-05-16 Module ports are really special PEIdent
698 return sig;
699 }
Something went wrong with that request. Please try again.