Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 3119 lines (2600 sloc) 93.969 kb
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
1 /*
91d84e7 Major rework of array handling. Memories are replaced with the
steve authored
2 * Copyright (c) 1999-2007 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 */
52bf4e6 conditional ident string using autoconfig.
steve authored
19 #ifdef HAVE_CVS_IDENT
8ec6d99 Put instantiated modules in the proper generated scope.
steve authored
20 #ident "$Id: elab_net.cc,v 1.207 2007/06/12 04:05:45 steve Exp $"
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
21 #endif
22
b825f8d Create a config.h.in file to hold all the config
steve authored
23 # include "config.h"
24
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
25 # include "PExpr.h"
26 # include "netlist.h"
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
27 # include "netmisc.h"
48de739 Switch to control warnings.
steve authored
28 # include "compiler.h"
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
29
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 /*
34 * This is a state flag that determines whether an elaborate_net must
35 * report an error when it encounters an unsized number. Normally, it
36 * is fine to make an unsized number as small as it can be, but there
37 * are a few cases where the size must be fully self-determined. For
38 * example, within a {...} (concatenation) operator.
39 */
40 static bool must_be_self_determined_flag = false;
41
03aebd7 Support elaborate_net for PEString objects.
steve authored
42 NetNet* PExpr::elaborate_net(Design*des, NetScope*scope, unsigned,
58f182a Node delays can be more general expressions in structural contexts.
steve authored
43 const NetExpr*,
44 const NetExpr*,
45 const NetExpr*,
03aebd7 Support elaborate_net for PEString objects.
steve authored
46 Link::strength_t,
47 Link::strength_t) const
48 {
49 cerr << get_line() << ": error: Unable to elaborate `"
50 << *this << "' as gates." << endl;
51 return 0;
52 }
53
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
54 /*
55 * Elaborating binary operations generally involves elaborating the
56 * left and right expressions, then making an output wire and
57 * connecting the lot together with the right kind of gate.
58 */
7793a49 Remove string paths from PExpr elaboration.
steve authored
59 NetNet* PEBinary::elaborate_net(Design*des, NetScope*scope,
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
60 unsigned width,
58f182a Node delays can be more general expressions in structural contexts.
steve authored
61 const NetExpr* rise,
62 const NetExpr* fall,
63 const NetExpr* decay,
b90cda1 Carry strength values from Verilog source to the
steve authored
64 Link::strength_t drive0,
65 Link::strength_t drive1) const
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
66 {
67 switch (op_) {
aa8908c Multiplication all the way to simulation.
steve authored
68 case '*':
7793a49 Remove string paths from PExpr elaboration.
steve authored
69 return elaborate_net_mul_(des, scope, width, rise, fall, decay);
89d7176 Add support for modulus (Eric Aardoom)
steve authored
70 case '%':
7793a49 Remove string paths from PExpr elaboration.
steve authored
71 return elaborate_net_mod_(des, scope, width, rise, fall, decay);
694ff93 Add support for integer division.
steve authored
72 case '/':
7793a49 Remove string paths from PExpr elaboration.
steve authored
73 return elaborate_net_div_(des, scope, width, rise, fall, decay);
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
74 case '+':
75 case '-':
7793a49 Remove string paths from PExpr elaboration.
steve authored
76 return elaborate_net_add_(des, scope, width, rise, fall, decay);
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
77 case '|': // Bitwise OR
78 case '&':
79 case '^':
dac99b9 Add support for binary nand operator.
steve authored
80 case 'A': // Bitwise NAND (~&)
3d3116d Add support for binary NOR operator.
steve authored
81 case 'O': // Bitwise NOR (~|)
8f0c02c Spelling fixes.
steve authored
82 case 'X': // Exclusive NOR
7793a49 Remove string paths from PExpr elaboration.
steve authored
83 return elaborate_net_bit_(des, scope, width, rise, fall, decay);
b8c5aff Generate !== an an inverted ===
steve authored
84 case 'E': // === (case equals)
85 case 'e': // ==
86 case 'N': // !== (case not-equals)
87 case 'n': // !=
513ade9 Support combinatorial comparators.
steve authored
88 case '<':
89 case '>':
90 case 'L': // <=
91 case 'G': // >=
7793a49 Remove string paths from PExpr elaboration.
steve authored
92 return elaborate_net_cmp_(des, scope, width, rise, fall, decay);
ced7cc6 Structural logical or.
steve authored
93 case 'a': // && (logical and)
94 case 'o': // || (logical or)
7793a49 Remove string paths from PExpr elaboration.
steve authored
95 return elaborate_net_log_(des, scope, width, rise, fall, decay);
1624afe Add support for the LPM_CLSHIFT device.
steve authored
96 case 'l': // <<
97 case 'r': // >>
3dbc07f Implement signed divide and signed right shift in nets.
steve authored
98 case 'R': // >>>
7793a49 Remove string paths from PExpr elaboration.
steve authored
99 return elaborate_net_shift_(des, scope, width, rise, fall, decay);
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
100 }
101
7793a49 Remove string paths from PExpr elaboration.
steve authored
102 NetNet*lsig = left_->elaborate_net(des, scope, width, 0, 0, 0),
103 *rsig = right_->elaborate_net(des, scope, width, 0, 0, 0);
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
104 if (lsig == 0) {
105 cerr << get_line() << ": error: Cannot elaborate ";
106 left_->dump(cerr);
107 cerr << endl;
108 return 0;
109 }
110 if (rsig == 0) {
111 cerr << get_line() << ": error: Cannot elaborate ";
112 right_->dump(cerr);
113 cerr << endl;
114 return 0;
115 }
116
117 NetNet*osig;
118
119 switch (op_) {
120 case '^': // XOR
57d28e4 Support structural XNOR.
steve authored
121 case 'X': // XNOR
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
122 case '&': // AND
123 case '|': // Bitwise OR
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
124 assert(0);
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
125 break;
126
127 case 'E': // === (Case equals)
128 case 'e': // ==
129 case 'n': // !=
513ade9 Support combinatorial comparators.
steve authored
130 case '<':
131 case '>':
132 case 'G': // >=
133 case 'L': // <=
206b37e Fix NetConst being set to zero width, and clean
steve authored
134 assert(0);
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
135 break;
136
137 case '+':
138 assert(0);
139 break;
140
141 case 'l':
142 case 'r':
3dbc07f Implement signed divide and signed right shift in nets.
steve authored
143 case 'R':
1624afe Add support for the LPM_CLSHIFT device.
steve authored
144 assert(0);
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
145 break;
146 default:
147 cerr << get_line() << ": internal error: unsupported"
148 " combinational operator (" << op_ << ")." << endl;
149 des->errors += 1;
150 osig = 0;
151 }
152
153 return osig;
154 }
155
156 /*
157 * Elaborate the structural +/- as an AddSub object. Connect DataA and
158 * DataB to the parameters, and connect the output signal to the
159 * Result. In this context, the device is a combinational adder with
160 * fixed direction, so leave Add_Sub unconnected and set the
161 * LPM_Direction property.
162 */
7793a49 Remove string paths from PExpr elaboration.
steve authored
163 NetNet* PEBinary::elaborate_net_add_(Design*des, NetScope*scope,
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
164 unsigned lwidth,
58f182a Node delays can be more general expressions in structural contexts.
steve authored
165 const NetExpr* rise,
166 const NetExpr* fall,
167 const NetExpr* decay) const
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
168 {
7793a49 Remove string paths from PExpr elaboration.
steve authored
169 NetNet*lsig = left_->elaborate_net(des, scope, lwidth, 0, 0, 0),
170 *rsig = right_->elaborate_net(des, scope, lwidth, 0, 0, 0);
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
171 if (lsig == 0) {
172 cerr << get_line() << ": error: Cannot elaborate ";
173 left_->dump(cerr);
174 cerr << endl;
175 return 0;
176 }
177 if (rsig == 0) {
178 cerr << get_line() << ": error: Cannot elaborate ";
179 right_->dump(cerr);
180 cerr << endl;
181 return 0;
182 }
183
184 NetNet*osig;
185
75ad905 Generalize signals to carry types.
steve authored
186 unsigned width = lsig->vector_width();
187 if (rsig->vector_width() > lsig->vector_width())
188 width = rsig->vector_width();
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
189
d78c739 Remove dead code.
steve authored
190
4124273 Handle some special cases of unary 2's complement,
steve authored
191 /* The owidth is the output width of the lpm_add_sub
7c1401a Spelling patch.
steve authored
192 device. If the desired width is greater then the width of
4124273 Handle some special cases of unary 2's complement,
steve authored
193 the operands, then widen the adder and let code below pad
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
194 the operands. */
4124273 Handle some special cases of unary 2's complement,
steve authored
195 unsigned owidth = width;
196 switch (op_) {
197 case '+':
198 if (lwidth > owidth) {
199 owidth = lwidth;
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
200 width = lwidth;
4124273 Handle some special cases of unary 2's complement,
steve authored
201 }
202 break;
203 case '-':
204 if (lwidth > owidth) {
205 owidth = lwidth;
206 width = lwidth;
207 }
208 break;
209 default:
210 assert(0);
211 }
d78c739 Remove dead code.
steve authored
212
33a391c Sign extend operands of signed addition.
steve authored
213 bool expr_signed = lsig->get_signed() && rsig->get_signed();
d54cc14 Simulate carry output on adders.
steve authored
214
acfb5c1 Over agressive signal elimination in constant probadation.
steve authored
215 // Pad out the operands, if necessary, the match the width of
216 // the adder device.
75ad905 Generalize signals to carry types.
steve authored
217 if (lsig->vector_width() < width)
33a391c Sign extend operands of signed addition.
steve authored
218 if (expr_signed)
219 lsig = pad_to_width_signed(des, lsig, width);
220 else
221 lsig = pad_to_width(des, lsig, width);
acfb5c1 Over agressive signal elimination in constant probadation.
steve authored
222
75ad905 Generalize signals to carry types.
steve authored
223 if (rsig->vector_width() < width)
33a391c Sign extend operands of signed addition.
steve authored
224 if (expr_signed)
225 rsig = pad_to_width_signed(des, rsig, width);
226 else
227 rsig = pad_to_width(des, rsig, width);
acfb5c1 Over agressive signal elimination in constant probadation.
steve authored
228
75ad905 Generalize signals to carry types.
steve authored
229 // Check that the argument types match.
230 if (lsig->data_type() != rsig->data_type()) {
231 cerr << get_line() << ": error: Arguments of add/sub "
232 << "have different data types." << endl;
233 cerr << get_line() << ": : Left argument is "
234 << lsig->data_type() << ", right argument is "
235 << rsig->data_type() << "." << endl;
236 des->errors += 1;
237 }
238
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
239 // Make the adder as wide as the widest operand
badad63 All NetObj objects have lex_string base names.
steve authored
240 osig = new NetNet(scope, scope->local_symbol(),
4124273 Handle some special cases of unary 2's complement,
steve authored
241 NetNet::WIRE, owidth);
75ad905 Generalize signals to carry types.
steve authored
242 osig->data_type(lsig->data_type());
33a391c Sign extend operands of signed addition.
steve authored
243 osig->set_signed(expr_signed);
4124273 Handle some special cases of unary 2's complement,
steve authored
244 osig->local_flag(true);
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
245 if (debug_elaborate) {
246 cerr << get_line() << ": debug: Elaborate NetAddSub "
247 << "width=" << width << " lwidth=" << lwidth
248 << endl;
249 }
badad63 All NetObj objects have lex_string base names.
steve authored
250 NetAddSub*adder = new NetAddSub(scope, scope->local_symbol(), width);
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
251
252 // Connect the adder to the various parts.
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
253 connect(lsig->pin(0), adder->pin_DataA());
254 connect(rsig->pin(0), adder->pin_DataB());
255 connect(osig->pin(0), adder->pin_Result());
256 #ifdef XXXX
d54cc14 Simulate carry output on adders.
steve authored
257 if (owidth > width)
258 connect(osig->pin(width), adder->pin_Cout());
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
259 #endif
61195c5 Harmless fixup of warnings.
steve authored
260 NetNode*gate = adder;
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
261 gate->rise_time(rise);
262 gate->fall_time(fall);
263 gate->decay_time(decay);
264 des->add_node(gate);
265
9ee0210 Code cleanup from Larry.
steve authored
266 gate->attribute(perm_string::literal("LPM_Direction"),
267 verinum(op_ == '+' ? "ADD" : "SUB"));
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
268
269 return osig;
270 }
271
272 /*
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
273 * Elaborate various bitwise logic operators. These are all similar in
274 * that they take operants of equal width, and each bit does not
275 * affect any other bits. Also common about all this is how bit widths
276 * of the operands are handled, when they do not match.
277 */
7793a49 Remove string paths from PExpr elaboration.
steve authored
278 NetNet* PEBinary::elaborate_net_bit_(Design*des, NetScope*scope,
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
279 unsigned width,
58f182a Node delays can be more general expressions in structural contexts.
steve authored
280 const NetExpr* rise,
281 const NetExpr* fall,
282 const NetExpr* decay) const
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
283 {
7793a49 Remove string paths from PExpr elaboration.
steve authored
284 NetNet*lsig = left_->elaborate_net(des, scope, width, 0, 0, 0),
285 *rsig = right_->elaborate_net(des, scope, width, 0, 0, 0);
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
286 if (lsig == 0) {
287 cerr << get_line() << ": error: Cannot elaborate ";
288 left_->dump(cerr);
289 cerr << endl;
290 return 0;
291 }
292 if (rsig == 0) {
293 cerr << get_line() << ": error: Cannot elaborate ";
294 right_->dump(cerr);
295 cerr << endl;
296 return 0;
297 }
298
609b6a7 Netlist boolean expressions generate gate vectors.
steve authored
299 if (lsig->vector_width() < rsig->vector_width())
300 lsig = pad_to_width(des, lsig, rsig->vector_width());
301 if (rsig->vector_width() < lsig->vector_width())
302 rsig = pad_to_width(des, rsig, lsig->vector_width());
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
303
4902c22 Check operand types for compatibility.
steve authored
304 if (lsig->data_type() != rsig->data_type()) {
4dfdc14 fit type elaboration of logical not.
steve authored
305 cerr << get_line() << ": error: Types of "
306 << "operands of " << op_ << " do not match: "
307 << lsig->data_type() << " vs. " << rsig->data_type()
4902c22 Check operand types for compatibility.
steve authored
308 << endl;
309 des->errors += 1;
310 return 0;
311 }
312
609b6a7 Netlist boolean expressions generate gate vectors.
steve authored
313 if (lsig->vector_width() != rsig->vector_width()) {
314 cerr << get_line() << ": internal error: lsig width ("
315 << lsig->vector_width() << ") != rsig pin width ("
316 << rsig->vector_width() << ")." << endl;
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
317 des->errors += 1;
318 return 0;
319 }
320
609b6a7 Netlist boolean expressions generate gate vectors.
steve authored
321 assert(lsig->vector_width() == rsig->vector_width());
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
322
badad63 All NetObj objects have lex_string base names.
steve authored
323 NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE,
609b6a7 Netlist boolean expressions generate gate vectors.
steve authored
324 lsig->vector_width());
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
325 osig->local_flag(true);
4902c22 Check operand types for compatibility.
steve authored
326 osig->data_type( lsig->data_type() );
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
327
9ee0210 Code cleanup from Larry.
steve authored
328 NetLogic::TYPE gtype=NetLogic::AND;
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
329 switch (op_) {
9ee0210 Code cleanup from Larry.
steve authored
330 case '^': gtype = NetLogic::XOR; break; // XOR
331 case 'X': gtype = NetLogic::XNOR; break; // XNOR
332 case '&': gtype = NetLogic::AND; break; // AND
333 case 'A': gtype = NetLogic::NAND; break; // NAND (~&)
334 case '|': gtype = NetLogic::OR; break; // Bitwise OR
335 case 'O': gtype = NetLogic::NOR; break; // Bitwise NOR
336 default: assert(0);
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
337 }
338
609b6a7 Netlist boolean expressions generate gate vectors.
steve authored
339 NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
340 3, gtype, osig->vector_width());
341 gate->set_line(*this);
342 connect(gate->pin(0), osig->pin(0));
343 connect(gate->pin(1), lsig->pin(0));
344 connect(gate->pin(2), rsig->pin(0));
345 gate->rise_time(rise);
346 gate->fall_time(fall);
347 gate->decay_time(decay);
348 des->add_node(gate);
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
349
350 return osig;
351 }
352
353 /*
fd371a3 Handle equality compare to constants specially.
steve authored
354 * This function attempts to handle the special case of == or !=
355 * compare to a constant value. The caller has determined already that
356 * one of the operands is a NetEConst, and has already elaborated the
357 * other.
358 */
359 static NetNet* compare_eq_constant(Design*des, NetScope*scope,
360 NetNet*lsig, NetEConst*rexp,
361 char op_code,
58f182a Node delays can be more general expressions in structural contexts.
steve authored
362 const NetExpr* rise,
363 const NetExpr* fall,
364 const NetExpr* decay)
fd371a3 Handle equality compare to constants specially.
steve authored
365 {
366 if (op_code != 'e' && op_code != 'n')
367 return 0;
368
369 verinum val = rexp->value();
370
371 /* Abandon special case if there are x or z bits in the
372 constant. We can't get the right behavior out of
373 OR/NOR in this case. */
374 if (! val.is_defined())
375 return 0;
376
ead2481 Fix elaboration of == compared to constants.
steve authored
377 if (val.len() < lsig->vector_width())
378 val = verinum(val, lsig->vector_width());
fd371a3 Handle equality compare to constants specially.
steve authored
379
03d7448 compare-to-constant uses sig len, not val len.
steve authored
380 /* Look for the very special case that we know the compare
381 results a priori due to different high bits, that are
382 constant pad in the signal. */
ead2481 Fix elaboration of == compared to constants.
steve authored
383 if (val.len() > lsig->vector_width()) {
384 unsigned idx = lsig->vector_width();
03d7448 compare-to-constant uses sig len, not val len.
steve authored
385 verinum::V lpad = verinum::V0;
386
387 while (idx < val.len()) {
388 if (val.get(idx) != lpad) {
389 verinum oval (op_code == 'e'
390 ? verinum::V0
391 : verinum::V1,
392 1);
393 NetEConst*ogate = new NetEConst(oval);
394 NetNet*osig = ogate->synthesize(des);
0c9fb76 Get the data type of part select results right.
steve authored
395 osig->data_type(lsig->data_type());
03d7448 compare-to-constant uses sig len, not val len.
steve authored
396 delete ogate;
ead2481 Fix elaboration of == compared to constants.
steve authored
397
398 if (debug_elaborate)
399 cerr << lsig->get_line() << ": debug: "
400 << "Equality replaced with "
401 << oval << " due to high pad mismatch"
402 << endl;
403
03d7448 compare-to-constant uses sig len, not val len.
steve authored
404 return osig;
405 }
406
407 idx +=1;
408 }
409 }
fd371a3 Handle equality compare to constants specially.
steve authored
410
411 unsigned zeros = 0;
412 unsigned ones = 0;
ead2481 Fix elaboration of == compared to constants.
steve authored
413 for (unsigned idx = 0 ; idx < lsig->vector_width() ; idx += 1) {
fd371a3 Handle equality compare to constants specially.
steve authored
414 if (val.get(idx) == verinum::V0)
415 zeros += 1;
416 if (val.get(idx) == verinum::V1)
417 ones += 1;
418 }
419
c34e44d Make sig-eq-constant optimization more effective.
steve authored
420 /* Handle the special case that the gate is a compare that can
421 be replaces with a reduction AND or NOR. */
422
423 if (ones == 0 || zeros == 0) {
424 NetUReduce::TYPE type;
425
426 if (zeros > 0) {
427 type = op_code == 'e'? NetUReduce::NOR : NetUReduce::OR;
428
429 if (debug_elaborate)
430 cerr << lsig->get_line() << ": debug: "
431 << "Replace net==" << val << " equality with "
432 << zeros << "-input reduction [N]OR gate." << endl;
433
434 } else {
435 type = op_code == 'e'? NetUReduce::AND : NetUReduce::NAND;
436
437 if (debug_elaborate)
438 cerr << lsig->get_line() << ": debug: "
439 << "Replace net==" << val << " equality with "
440 << ones << "-input reduction AND gate." << endl;
441 }
442
443 NetUReduce*red = new NetUReduce(scope, scope->local_symbol(),
444 type, zeros+ones);
445 des->add_node(red);
446 red->set_line(*lsig);
ead2481 Fix elaboration of == compared to constants.
steve authored
447
448 NetNet*tmp = new NetNet(scope, scope->local_symbol(),
449 NetNet::WIRE, 0, 0);
0c9fb76 Get the data type of part select results right.
steve authored
450 tmp->data_type(lsig->data_type());
ead2481 Fix elaboration of == compared to constants.
steve authored
451 tmp->local_flag(true);
452 tmp->set_line(*lsig);
fd371a3 Handle equality compare to constants specially.
steve authored
453
c34e44d Make sig-eq-constant optimization more effective.
steve authored
454 connect(red->pin(1), lsig->pin(0));
455 connect(red->pin(0), tmp->pin(0));
456 return tmp;
fd371a3 Handle equality compare to constants specially.
steve authored
457 }
458
c34e44d Make sig-eq-constant optimization more effective.
steve authored
459 if (debug_elaborate)
460 cerr << lsig->get_line() << ": debug: "
461 << "Give up trying to replace net==" << val
462 << " equality with "
463 << ones << "-input AND and "
464 << zeros << "-input NOR gates." << endl;
465
466 return 0;
fd371a3 Handle equality compare to constants specially.
steve authored
467 }
468
469 /*
3d1ffce Elaborate net widths of constants to as small
steve authored
470 * Elaborate the various binary comparison operators. The comparison
471 * operators return a single bit result, no matter what, so the left
472 * and right values can have their own size. The only restriction is
473 * that they have the same size.
206b37e Fix NetConst being set to zero width, and clean
steve authored
474 */
7793a49 Remove string paths from PExpr elaboration.
steve authored
475 NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
206b37e Fix NetConst being set to zero width, and clean
steve authored
476 unsigned lwidth,
58f182a Node delays can be more general expressions in structural contexts.
steve authored
477 const NetExpr* rise,
478 const NetExpr* fall,
479 const NetExpr* decay) const
206b37e Fix NetConst being set to zero width, and clean
steve authored
480 {
d548c9a Handle synthesis of concatenation expressions.
steve authored
481
2f8a40b Fix evaluation of compare to constant expression.
steve authored
482 /* Elaborate the operands of the compare first as expressions
483 (so that the eval_tree method can reduce constant
484 expressions, including parameters) then turn those results
485 into synthesized nets. */
71faebd Make elaborate_expr methods aware of the width that the context
steve authored
486 NetExpr*lexp = elab_and_eval(des, scope, left_, lwidth);
2f8a40b Fix evaluation of compare to constant expression.
steve authored
487 if (lexp == 0) {
206b37e Fix NetConst being set to zero width, and clean
steve authored
488 cerr << get_line() << ": error: Cannot elaborate ";
489 left_->dump(cerr);
490 cerr << endl;
491 return 0;
492 }
2f8a40b Fix evaluation of compare to constant expression.
steve authored
493
71faebd Make elaborate_expr methods aware of the width that the context
steve authored
494 NetExpr*rexp = elab_and_eval(des, scope, right_, lwidth);
2f8a40b Fix evaluation of compare to constant expression.
steve authored
495 if (rexp == 0) {
206b37e Fix NetConst being set to zero width, and clean
steve authored
496 cerr << get_line() << ": error: Cannot elaborate ";
497 right_->dump(cerr);
498 cerr << endl;
499 return 0;
500 }
501
06e08db Make sure comparison widths match.
steve authored
502 /* Choose the operand width to be the width of the widest
503 self-determined operand. */
504 unsigned operand_width = lexp->expr_width();
505 if (rexp->expr_width() > operand_width)
506 operand_width = rexp->expr_width();
507
508 lexp->set_width(operand_width);
509 lexp = pad_to_width(lexp, operand_width);
510 rexp->set_width(operand_width);
511 rexp = pad_to_width(rexp, operand_width);
2f8a40b Fix evaluation of compare to constant expression.
steve authored
512
fd371a3 Handle equality compare to constants specially.
steve authored
513 NetNet*lsig = 0;
514 NetNet*rsig = 0;
515
516 /* Handle the special case that the right or left
517 sub-expression is a constant value. The compare_eq_constant
518 function will return an elaborated result if it can make
519 use of the situation, or 0 if it cannot. */
520 if (NetEConst*tmp = dynamic_cast<NetEConst*>(rexp)) {
521
522 lsig = lexp->synthesize(des);
51dd41f Fix excessive error message.
steve authored
523 if (lsig == 0) {
524 cerr << get_line() << ": internal error: "
525 "Cannot elaborate net for " << *lexp << endl;
b69f59f Handle memory references is continuous assignments.
steve authored
526 return 0;
51dd41f Fix excessive error message.
steve authored
527 }
fd371a3 Handle equality compare to constants specially.
steve authored
528 assert(lsig);
529 delete lexp;
530 lexp = 0;
531
532 NetNet*osig = compare_eq_constant(des, scope,
533 lsig, tmp, op_,
534 rise, fall, decay);
535 if (osig != 0) {
536 delete rexp;
537 return osig;
538 }
539 }
540
541 if (NetEConst*tmp = dynamic_cast<NetEConst*>(lexp)) {
542
543 rsig = rexp->synthesize(des);
544 assert(rsig);
545 delete rexp;
546
547 NetNet*osig = compare_eq_constant(des, scope,
548 rsig, tmp, op_,
549 rise, fall, decay);
550 if (osig != 0) {
551 delete lexp;
552 return osig;
553 }
554 }
555
556 if (lsig == 0) {
557 lsig = lexp->synthesize(des);
558 assert(lsig);
559 delete lexp;
560 }
561
562 if (rsig == 0) {
563 rsig = rexp->synthesize(des);
564 assert(rsig);
565 delete rexp;
566 }
2f8a40b Fix evaluation of compare to constant expression.
steve authored
567
bf6a5d0 Implement LPM_COMPARE nodes as two-input vector functors.
steve authored
568 unsigned dwidth = lsig->vector_width();
569 if (rsig->vector_width() > dwidth) dwidth = rsig->vector_width();
3d1ffce Elaborate net widths of constants to as small
steve authored
570
5d1d99a Handle signed magnitude compare all the
steve authored
571 /* Operands of binary compare need to be padded to equal
572 size. Figure the pad bit needed to extend the narrowest
573 vector. */
bf6a5d0 Implement LPM_COMPARE nodes as two-input vector functors.
steve authored
574 if (lsig->vector_width() < dwidth)
575 lsig = pad_to_width(des, lsig, dwidth);
576 if (rsig->vector_width() < dwidth)
577 rsig = pad_to_width(des, rsig, dwidth);
5d1d99a Handle signed magnitude compare all the
steve authored
578
206b37e Fix NetConst being set to zero width, and clean
steve authored
579
badad63 All NetObj objects have lex_string base names.
steve authored
580 NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
75ad905 Generalize signals to carry types.
steve authored
581 osig->data_type(IVL_VT_LOGIC);
bf6a5d0 Implement LPM_COMPARE nodes as two-input vector functors.
steve authored
582 osig->set_line(*this);
206b37e Fix NetConst being set to zero width, and clean
steve authored
583 osig->local_flag(true);
584
585 NetNode*gate;
586
587 switch (op_) {
513ade9 Support combinatorial comparators.
steve authored
588 case '<':
589 case '>':
590 case 'L':
591 case 'G': {
3d1ffce Elaborate net widths of constants to as small
steve authored
592 NetCompare*cmp = new
a275133 LPM objects store only their base names.
steve authored
593 NetCompare(scope, scope->local_symbol(), dwidth);
bf6a5d0 Implement LPM_COMPARE nodes as two-input vector functors.
steve authored
594 connect(cmp->pin_DataA(), lsig->pin(0));
595 connect(cmp->pin_DataB(), rsig->pin(0));
3d1ffce Elaborate net widths of constants to as small
steve authored
596
513ade9 Support combinatorial comparators.
steve authored
597 switch (op_) {
598 case '<':
599 connect(cmp->pin_ALB(), osig->pin(0));
600 break;
601 case '>':
602 connect(cmp->pin_AGB(), osig->pin(0));
603 break;
604 case 'L':
605 connect(cmp->pin_ALEB(), osig->pin(0));
606 break;
607 case 'G':
608 connect(cmp->pin_AGEB(), osig->pin(0));
609 break;
610 }
5d1d99a Handle signed magnitude compare all the
steve authored
611 /* If both operands are signed, then do a signed
612 compare. */
613 if (lsig->get_signed() && rsig->get_signed())
614 cmp->set_signed(true);
615
513ade9 Support combinatorial comparators.
steve authored
616 gate = cmp;
617 break;
618 }
619
206b37e Fix NetConst being set to zero width, and clean
steve authored
620 case 'E': // Case equals (===)
1c5b488 Handle case inequality in netlists.
steve authored
621 gate = new NetCaseCmp(scope, scope->local_symbol(), dwidth, true);
206b37e Fix NetConst being set to zero width, and clean
steve authored
622 connect(gate->pin(0), osig->pin(0));
e286367 Change case compare from logic to an LPM node.
steve authored
623 connect(gate->pin(1), lsig->pin(0));
624 connect(gate->pin(2), rsig->pin(0));
206b37e Fix NetConst being set to zero width, and clean
steve authored
625 break;
626
e286367 Change case compare from logic to an LPM node.
steve authored
627 case 'N': // Case equals (!==)
1c5b488 Handle case inequality in netlists.
steve authored
628 gate = new NetCaseCmp(scope, scope->local_symbol(), dwidth, false);
629 connect(gate->pin(0), osig->pin(0));
630 connect(gate->pin(1), lsig->pin(0));
631 connect(gate->pin(2), rsig->pin(0));
e286367 Change case compare from logic to an LPM node.
steve authored
632 break;
206b37e Fix NetConst being set to zero width, and clean
steve authored
633
634 case 'e': // ==
9b59001 Eleminate reduction gate for 1-bit compares.
steve authored
635
636 /* Handle the special case of single bit compare with a
637 single XNOR gate. This is easy and direct. */
638 if (dwidth == 1) {
badad63 All NetObj objects have lex_string base names.
steve authored
639 gate = new NetLogic(scope, scope->local_symbol(),
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
640 3, NetLogic::XNOR, 1);
9b59001 Eleminate reduction gate for 1-bit compares.
steve authored
641 connect(gate->pin(0), osig->pin(0));
642 connect(gate->pin(1), lsig->pin(0));
643 connect(gate->pin(2), rsig->pin(0));
644 break;
645 }
646
d548c9a Handle synthesis of concatenation expressions.
steve authored
647 if (debug_elaborate) {
648 cerr << get_line() << ": debug: Elaborate net == gate."
649 << endl;
650 }
651
3c8d598 Elaborate == to NetCompare instead of XNOR and AND
steve authored
652 /* Oh well, do the general case with a NetCompare. */
a275133 LPM objects store only their base names.
steve authored
653 { NetCompare*cmp = new NetCompare(scope, scope->local_symbol(),
3c8d598 Elaborate == to NetCompare instead of XNOR and AND
steve authored
654 dwidth);
bf6a5d0 Implement LPM_COMPARE nodes as two-input vector functors.
steve authored
655 connect(cmp->pin_DataA(), lsig->pin(0));
656 connect(cmp->pin_DataB(), rsig->pin(0));
3c8d598 Elaborate == to NetCompare instead of XNOR and AND
steve authored
657 connect(cmp->pin_AEB(), osig->pin(0));
658 gate = cmp;
206b37e Fix NetConst being set to zero width, and clean
steve authored
659 }
660 break;
661
662 case 'n': // !=
9b59001 Eleminate reduction gate for 1-bit compares.
steve authored
663
664 /* Handle the special case of single bit compare with a
665 single XOR gate. This is easy and direct. */
666 if (dwidth == 1) {
badad63 All NetObj objects have lex_string base names.
steve authored
667 gate = new NetLogic(scope, scope->local_symbol(),
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
668 3, NetLogic::XOR, 1);
9b59001 Eleminate reduction gate for 1-bit compares.
steve authored
669 connect(gate->pin(0), osig->pin(0));
670 connect(gate->pin(1), lsig->pin(0));
671 connect(gate->pin(2), rsig->pin(0));
672 break;
673 }
674
3c8d598 Elaborate == to NetCompare instead of XNOR and AND
steve authored
675 /* Oh well, do the general case with a NetCompare. */
a275133 LPM objects store only their base names.
steve authored
676 { NetCompare*cmp = new NetCompare(scope, scope->local_symbol(),
3c8d598 Elaborate == to NetCompare instead of XNOR and AND
steve authored
677 dwidth);
bf6a5d0 Implement LPM_COMPARE nodes as two-input vector functors.
steve authored
678 connect(cmp->pin_DataA(), lsig->pin(0));
679 connect(cmp->pin_DataB(), rsig->pin(0));
3c8d598 Elaborate == to NetCompare instead of XNOR and AND
steve authored
680 connect(cmp->pin_ANEB(), osig->pin(0));
681 gate = cmp;
682 }
206b37e Fix NetConst being set to zero width, and clean
steve authored
683 break;
684
685 default:
686 assert(0);
687 }
688
689 gate->rise_time(rise);
690 gate->fall_time(fall);
691 gate->decay_time(decay);
692 des->add_node(gate);
693
694 return osig;
695 }
696
694ff93 Add support for integer division.
steve authored
697 /*
8f0c02c Spelling fixes.
steve authored
698 * Elaborate a divider gate. This function create a NetDivide gate
8ee00ec Fix net division to cope with small output sizes.
steve authored
699 * which has exactly the right sized DataA, DataB and Result ports. If
700 * the l-value is wider then the result, then pad.
694ff93 Add support for integer division.
steve authored
701 */
7793a49 Remove string paths from PExpr elaboration.
steve authored
702 NetNet* PEBinary::elaborate_net_div_(Design*des, NetScope*scope,
694ff93 Add support for integer division.
steve authored
703 unsigned lwidth,
58f182a Node delays can be more general expressions in structural contexts.
steve authored
704 const NetExpr* rise,
705 const NetExpr* fall,
706 const NetExpr* decay) const
694ff93 Add support for integer division.
steve authored
707 {
d1f0bcf Catch unsized expressions in continuous assigns.
steve authored
708 NetNet*lsig = left_->elaborate_net(des, scope, lwidth, 0, 0, 0);
694ff93 Add support for integer division.
steve authored
709 if (lsig == 0) return 0;
d1f0bcf Catch unsized expressions in continuous assigns.
steve authored
710 NetNet*rsig = right_->elaborate_net(des, scope, lwidth, 0, 0, 0);
694ff93 Add support for integer division.
steve authored
711 if (rsig == 0) return 0;
712
8ee00ec Fix net division to cope with small output sizes.
steve authored
713
714 // Check the l-value width. If it is unspecified, then use the
715 // largest operand width as the l-value width. Restrict the
716 // result width to the width of the largest operand, because
717 // there is no value is excess divider.
718
719 unsigned rwidth = lwidth;
720
721 if (rwidth == 0) {
257e1f9 Support shifts and divide.
steve authored
722 rwidth = lsig->vector_width();
723 if (rsig->vector_width() > rwidth)
724 rwidth = rsig->vector_width();
8ee00ec Fix net division to cope with small output sizes.
steve authored
725
726 lwidth = rwidth;
727 }
728
257e1f9 Support shifts and divide.
steve authored
729 if ((rwidth > lsig->vector_width()) && (rwidth > rsig->vector_width())) {
730 rwidth = lsig->vector_width();
731 if (rsig->vector_width() > rwidth)
732 rwidth = rsig->vector_width();
8ee00ec Fix net division to cope with small output sizes.
steve authored
733 }
734
75ad905 Generalize signals to carry types.
steve authored
735 /* The arguments of a divide must have the same type. */
736 if (lsig->data_type() != rsig->data_type()) {
737 cerr << get_line() << ": error: Arguments of divide "
738 << "have different data types." << endl;
739 cerr << get_line() << ": : Left argument is "
740 << lsig->data_type() << ", right argument is "
741 << rsig->data_type() << "." << endl;
742 des->errors += 1;
743 }
744
745 ivl_variable_type_t data_type = lsig->data_type();
746
8ee00ec Fix net division to cope with small output sizes.
steve authored
747 // Create a device with the calculated dimensions.
a275133 LPM objects store only their base names.
steve authored
748 NetDivide*div = new NetDivide(scope, scope->local_symbol(), rwidth,
257e1f9 Support shifts and divide.
steve authored
749 lsig->vector_width(),
750 rsig->vector_width());
694ff93 Add support for integer division.
steve authored
751 des->add_node(div);
752
3dbc07f Implement signed divide and signed right shift in nets.
steve authored
753 div->set_signed(lsig->get_signed() && rsig->get_signed());
8ee00ec Fix net division to cope with small output sizes.
steve authored
754
755 // Connect the left and right inputs of the divider to the
756 // nets that are the left and right expressions.
757
257e1f9 Support shifts and divide.
steve authored
758 connect(div->pin_DataA(), lsig->pin(0));
759 connect(div->pin_DataB(), rsig->pin(0));
694ff93 Add support for integer division.
steve authored
760
8ee00ec Fix net division to cope with small output sizes.
steve authored
761
762 // Make an output signal that is the width of the l-value.
763 // Due to above calculation of rwidth, we know that the result
611d2c8 Spelling fixes from Larry
steve authored
764 // will be no more than the l-value, so it is safe to connect
8ee00ec Fix net division to cope with small output sizes.
steve authored
765 // all the result pins to the osig.
766
badad63 All NetObj objects have lex_string base names.
steve authored
767 NetNet*osig = new NetNet(scope, scope->local_symbol(),
694ff93 Add support for integer division.
steve authored
768 NetNet::IMPLICIT, lwidth);
769 osig->local_flag(true);
75ad905 Generalize signals to carry types.
steve authored
770 osig->data_type(data_type);
3dbc07f Implement signed divide and signed right shift in nets.
steve authored
771 osig->set_signed(div->get_signed());
694ff93 Add support for integer division.
steve authored
772
257e1f9 Support shifts and divide.
steve authored
773 connect(div->pin_Result(), osig->pin(0));
8ee00ec Fix net division to cope with small output sizes.
steve authored
774
694ff93 Add support for integer division.
steve authored
775
776 return osig;
777 }
778
89d7176 Add support for modulus (Eric Aardoom)
steve authored
779 /*
780 * Elaborate a modulo gate.
781 */
7793a49 Remove string paths from PExpr elaboration.
steve authored
782 NetNet* PEBinary::elaborate_net_mod_(Design*des, NetScope*scope,
89d7176 Add support for modulus (Eric Aardoom)
steve authored
783 unsigned lwidth,
58f182a Node delays can be more general expressions in structural contexts.
steve authored
784 const NetExpr* rise,
785 const NetExpr* fall,
786 const NetExpr* decay) const
89d7176 Add support for modulus (Eric Aardoom)
steve authored
787 {
7793a49 Remove string paths from PExpr elaboration.
steve authored
788 NetNet*lsig = left_->elaborate_net(des, scope, 0, 0, 0, 0);
89d7176 Add support for modulus (Eric Aardoom)
steve authored
789 if (lsig == 0) return 0;
7793a49 Remove string paths from PExpr elaboration.
steve authored
790 NetNet*rsig = right_->elaborate_net(des, scope, 0, 0, 0, 0);
89d7176 Add support for modulus (Eric Aardoom)
steve authored
791 if (rsig == 0) return 0;
792
75ad905 Generalize signals to carry types.
steve authored
793 /* The arguments of a modulus must have the same type. */
794 if (lsig->data_type() != rsig->data_type()) {
795 cerr << get_line() << ": error: Arguments of modulus "
796 << "have different data types." << endl;
797 cerr << get_line() << ": : Left argument is "
798 << lsig->data_type() << ", right argument is "
799 << rsig->data_type() << "." << endl;
800 des->errors += 1;
801 }
802
803 ivl_variable_type_t data_type = lsig->data_type();
804
ab1ca54 Update support for LPM_MOD.
steve authored
805 /* rwidth is result width. */
dd79885 Add structural modulus support down to vvp.
steve authored
806 unsigned rwidth = lwidth;
807 if (rwidth == 0) {
ab1ca54 Update support for LPM_MOD.
steve authored
808 rwidth = lsig->vector_width();
809 if (rsig->vector_width() > rwidth)
810 rwidth = rsig->vector_width();
811
812 lwidth = rwidth;
dd79885 Add structural modulus support down to vvp.
steve authored
813 }
ab1ca54 Update support for LPM_MOD.
steve authored
814
a275133 LPM objects store only their base names.
steve authored
815 NetModulo*mod = new NetModulo(scope, scope->local_symbol(), rwidth,
ab1ca54 Update support for LPM_MOD.
steve authored
816 lsig->vector_width(),
817 rsig->vector_width());
7235706 Make sure div, mod and mult nodes have line number info.
steve authored
818 mod->set_line(*this);
89d7176 Add support for modulus (Eric Aardoom)
steve authored
819 des->add_node(mod);
820
ab1ca54 Update support for LPM_MOD.
steve authored
821 connect(mod->pin_DataA(), lsig->pin(0));
822 connect(mod->pin_DataB(), rsig->pin(0));
89d7176 Add support for modulus (Eric Aardoom)
steve authored
823
badad63 All NetObj objects have lex_string base names.
steve authored
824 NetNet*osig = new NetNet(scope, scope->local_symbol(),
ab1ca54 Update support for LPM_MOD.
steve authored
825 NetNet::IMPLICIT, rwidth);
7235706 Make sure div, mod and mult nodes have line number info.
steve authored
826 osig->set_line(*this);
75ad905 Generalize signals to carry types.
steve authored
827 osig->data_type(data_type);
89d7176 Add support for modulus (Eric Aardoom)
steve authored
828 osig->local_flag(true);
829
ab1ca54 Update support for LPM_MOD.
steve authored
830 connect(mod->pin_Result(), osig->pin(0));
89d7176 Add support for modulus (Eric Aardoom)
steve authored
831
832 return osig;
833 }
834
7793a49 Remove string paths from PExpr elaboration.
steve authored
835 NetNet* PEBinary::elaborate_net_log_(Design*des, NetScope*scope,
ced7cc6 Structural logical or.
steve authored
836 unsigned lwidth,
58f182a Node delays can be more general expressions in structural contexts.
steve authored
837 const NetExpr* rise,
838 const NetExpr* fall,
839 const NetExpr* decay) const
ced7cc6 Structural logical or.
steve authored
840 {
ba309e6 Fix synthesis method for logical and/or
steve authored
841 NetNet*lsig = left_->elaborate_net(des, scope, 0, 0, 0, 0);
842 NetNet*rsig = right_->elaborate_net(des, scope, 0, 0, 0, 0);
ced7cc6 Structural logical or.
steve authored
843 if (lsig == 0) {
844 cerr << get_line() << ": error: Cannot elaborate ";
845 left_->dump(cerr);
846 cerr << endl;
847 return 0;
848 }
849 if (rsig == 0) {
850 cerr << get_line() << ": error: Cannot elaborate ";
851 right_->dump(cerr);
852 cerr << endl;
853 return 0;
854 }
855
856 NetLogic*gate;
857 switch (op_) {
858 case 'a':
badad63 All NetObj objects have lex_string base names.
steve authored
859 gate = new NetLogic(scope, scope->local_symbol(),
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
860 3, NetLogic::AND, 1);
ced7cc6 Structural logical or.
steve authored
861 break;
862 case 'o':
badad63 All NetObj objects have lex_string base names.
steve authored
863 gate = new NetLogic(scope, scope->local_symbol(),
65e9b6b Rework of internals to carry vectors through nexus instead
steve authored
864 3, NetLogic::OR, 1);
ced7cc6 Structural logical or.
steve authored
865 break;
866 default:
867 assert(0);
868 }
869 gate->rise_time(rise);
870 gate->fall_time(fall);
871 gate->decay_time(decay);
872
873 // The first OR gate returns 1 if the left value is true...
8184dfa Handle wide operands to logical AND.
steve authored
874 if (lsig->vector_width() > 1) {
875 NetUReduce*gate_tmp = new NetUReduce(scope, scope->local_symbol(),
876 NetUReduce::OR,
877 lsig->vector_width());
878 connect(gate_tmp->pin(1), lsig->pin(0));
879 connect(gate->pin(1), gate_tmp->pin(0));
2563e2b Revise the VVM backend to use nexus objects so that
steve authored
880
881 /* The reduced logical value is a new nexus, create a
882 temporary signal to represent it. */
badad63 All NetObj objects have lex_string base names.
steve authored
883 NetNet*tmp = new NetNet(scope, scope->local_symbol(),
cd94019 Remove NetTmp and add NetSubnet class.
steve authored
884 NetNet::IMPLICIT, 1);
a8b86ea More explicit datatype setup.
steve authored
885 tmp->data_type(IVL_VT_LOGIC);
cd94019 Remove NetTmp and add NetSubnet class.
steve authored
886 tmp->local_flag(true);
2563e2b Revise the VVM backend to use nexus objects so that
steve authored
887 connect(gate->pin(1), tmp->pin(0));
888
8184dfa Handle wide operands to logical AND.
steve authored
889 des->add_node(gate_tmp);
2563e2b Revise the VVM backend to use nexus objects so that
steve authored
890
ced7cc6 Structural logical or.
steve authored
891 } else {
892 connect(gate->pin(1), lsig->pin(0));
893 }
894
895 // The second OR gate returns 1 if the right value is true...
8184dfa Handle wide operands to logical AND.
steve authored
896 if (rsig->vector_width() > 1) {
897 NetUReduce*gate_tmp = new NetUReduce(scope, scope->local_symbol(),
898 NetUReduce::OR,
899 rsig->vector_width());
900 connect(gate_tmp->pin(1), rsig->pin(0));
901 connect(gate->pin(2), gate_tmp->pin(0));
2563e2b Revise the VVM backend to use nexus objects so that
steve authored
902
903 /* The reduced logical value is a new nexus, create a
904 temporary signal to represent it. */
badad63 All NetObj objects have lex_string base names.
steve authored
905 NetNet*tmp = new NetNet(scope, scope->local_symbol(),
cd94019 Remove NetTmp and add NetSubnet class.
steve authored
906 NetNet::IMPLICIT, 1);
a8b86ea More explicit datatype setup.
steve authored
907 tmp->data_type(IVL_VT_LOGIC);
cd94019 Remove NetTmp and add NetSubnet class.
steve authored
908 tmp->local_flag(true);
2563e2b Revise the VVM backend to use nexus objects so that
steve authored
909 connect(gate->pin(2), tmp->pin(0));
910
8184dfa Handle wide operands to logical AND.
steve authored
911 des->add_node(gate_tmp);
2563e2b Revise the VVM backend to use nexus objects so that
steve authored
912
ced7cc6 Structural logical or.
steve authored
913 } else {
914 connect(gate->pin(2), rsig->pin(0));
915 }
916
917 // The output is the AND/OR of the two logic values.
badad63 All NetObj objects have lex_string base names.
steve authored
918 NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
ced7cc6 Structural logical or.
steve authored
919 osig->local_flag(true);
07f345d Logical or/and return VT_LOGIC type.
steve authored
920 osig->data_type(IVL_VT_LOGIC);
ced7cc6 Structural logical or.
steve authored
921 connect(gate->pin(0), osig->pin(0));
922 des->add_node(gate);
923 return osig;
924 }
925
7793a49 Remove string paths from PExpr elaboration.
steve authored
926 NetNet* PEBinary::elaborate_net_mul_(Design*des, NetScope*scope,
aa8908c Multiplication all the way to simulation.
steve authored
927 unsigned lwidth,
58f182a Node delays can be more general expressions in structural contexts.
steve authored
928 const NetExpr* rise,
929 const NetExpr* fall,
930 const NetExpr* decay) const
aa8908c Multiplication all the way to simulation.
steve authored
931 {
4bb91c4 Elaborate multiply nets with constant operands ad NetConst.
steve authored
932 verinum*lnum = left_->eval_const(des, scope);
933 verinum*rnum = right_->eval_const(des, scope);
934
935 /* Detect and handle the special case that both the operands
8f0c02c Spelling fixes.
steve authored
936 of the multiply are constant expressions. Evaluate the
4bb91c4 Elaborate multiply nets with constant operands ad NetConst.
steve authored
937 value and make this a simple constant. */
938 if (lnum && rnum) {
939 verinum prod = *lnum * *rnum;
940 if (lwidth == 0)
941 lwidth = prod.len();
942
943 verinum res (verinum::V0, lwidth);
944 for (unsigned idx = 0
945 ; idx < prod.len() && idx < lwidth
946 ; idx += 1) {
947 res.set(idx, prod.get(idx));
948 }
949
badad63 All NetObj objects have lex_string base names.
steve authored
950 NetConst*odev = new NetConst(scope, scope->local_symbol(), res);
22efa9f Fix elaboration of multiply of two constants.
steve authored
951 des->add_node(odev);
952 odev->set_line(*this);
953
badad63 All NetObj objects have lex_string base names.
steve authored
954 NetNet*osig = new NetNet(scope, scope->local_symbol(),
4bb91c4 Elaborate multiply nets with constant operands ad NetConst.
steve authored
955 NetNet::IMPLICIT, lwidth);
22efa9f Fix elaboration of multiply of two constants.
steve authored
956 osig->set_line(*this);
4bb91c4 Elaborate multiply nets with constant operands ad NetConst.
steve authored
957 osig->local_flag(true);
22efa9f Fix elaboration of multiply of two constants.
steve authored
958 osig->data_type(IVL_VT_LOGIC);
959
960 connect(odev->pin(0), osig->pin(0));
961
4bb91c4 Elaborate multiply nets with constant operands ad NetConst.
steve authored
962 return osig;
963 }
964
7793a49 Remove string paths from PExpr elaboration.
steve authored
965 NetNet*lsig = left_->elaborate_net(des, scope, lwidth, 0, 0, 0);
aa8908c Multiplication all the way to simulation.
steve authored
966 if (lsig == 0) return 0;
7793a49 Remove string paths from PExpr elaboration.
steve authored
967 NetNet*rsig = right_->elaborate_net(des, scope, lwidth, 0, 0, 0);
aa8908c Multiplication all the way to simulation.
steve authored
968 if (rsig == 0) return 0;
969
739a183 Do sign extension of structuran nets.
steve authored
970 // The mult is signed if both its operands are signed.
971 bool arith_is_signed = lsig->get_signed() && rsig->get_signed();
972
75ad905 Generalize signals to carry types.
steve authored
973 /* The arguments of a divide must have the same type. */
974 if (lsig->data_type() != rsig->data_type()) {
975 cerr << get_line() << ": error: Arguments of multiply "
976 << "have different data types." << endl;
977 cerr << get_line() << ": : Left argument is "
978 << lsig->data_type() << ", right argument is "
979 << rsig->data_type() << "." << endl;
980 des->errors += 1;
981 }
982
983 ivl_variable_type_t data_type = lsig->data_type();
984
4124273 Handle some special cases of unary 2's complement,
steve authored
985 unsigned rwidth = lwidth;
4bb91c4 Elaborate multiply nets with constant operands ad NetConst.
steve authored
986 if (rwidth == 0) {
739a183 Do sign extension of structuran nets.
steve authored
987 rwidth = lsig->vector_width() + rsig->vector_width();
99ace10 Simplified NetMult and IVL_LPM_MULT.
steve authored
988 lwidth = rwidth;
4bb91c4 Elaborate multiply nets with constant operands ad NetConst.
steve authored
989 }
990
739a183 Do sign extension of structuran nets.
steve authored
991 if (arith_is_signed) {
992 lsig = pad_to_width_signed(des, lsig, rwidth);
993 rsig = pad_to_width_signed(des, rsig, rwidth);
994 }
995
a275133 LPM objects store only their base names.
steve authored
996 NetMult*mult = new NetMult(scope, scope->local_symbol(), rwidth,
99ace10 Simplified NetMult and IVL_LPM_MULT.
steve authored
997 lsig->vector_width(),
998 rsig->vector_width());
999 mult->set_line(*this);
aa8908c Multiplication all the way to simulation.
steve authored
1000 des->add_node(mult);
1001
739a183 Do sign extension of structuran nets.
steve authored
1002 mult->set_signed( arith_is_signed );
d18934d Sign extend NetMult inputs if result is signed.
steve authored
1003
99ace10 Simplified NetMult and IVL_LPM_MULT.
steve authored
1004 connect(mult->pin_DataA(), lsig->pin(0));
1005 connect(mult->pin_DataB(), rsig->pin(0));
aa8908c Multiplication all the way to simulation.
steve authored
1006
99ace10 Simplified NetMult and IVL_LPM_MULT.
steve authored
1007 // Make a signal to carry the output from the multiply.
badad63 All NetObj objects have lex_string base names.
steve authored
1008 NetNet*osig = new NetNet(scope, scope->local_symbol(),
99ace10 Simplified NetMult and IVL_LPM_MULT.
steve authored
1009 NetNet::IMPLICIT, rwidth);
75ad905 Generalize signals to carry types.
steve authored
1010 osig->data_type(data_type);
aa8908c Multiplication all the way to simulation.
steve authored
1011 osig->local_flag(true);
99ace10 Simplified NetMult and IVL_LPM_MULT.
steve authored
1012 connect(mult->pin_Result(), osig->pin(0));
aa8908c Multiplication all the way to simulation.
steve authored
1013
1014 return osig;
1015 }
1016
7793a49 Remove string paths from PExpr elaboration.
steve authored
1017 NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1018 unsigned lwidth,
58f182a Node delays can be more general expressions in structural contexts.
steve authored
1019 const NetExpr* rise,
1020 const NetExpr* fall,
1021 const NetExpr* decay) const
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1022 {
7793a49 Remove string paths from PExpr elaboration.
steve authored
1023 NetNet*lsig = left_->elaborate_net(des, scope, lwidth, 0, 0, 0);
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1024 if (lsig == 0) return 0;
1025
257e1f9 Support shifts and divide.
steve authored
1026 if (lsig->vector_width() > lwidth)
1027 lwidth = lsig->vector_width();
9e5ff89 Add structural reduction NAND,
steve authored
1028
3dbc07f Implement signed divide and signed right shift in nets.
steve authored
1029 bool right_flag = op_ == 'r' || op_ == 'R';
1030 bool signed_flag = op_ == 'R';
75ad905 Generalize signals to carry types.
steve authored
1031 ivl_variable_type_t data_type = lsig->data_type();
3dbc07f Implement signed divide and signed right shift in nets.
steve authored
1032
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1033 /* Handle the special case of a constant shift amount. There
1034 is no reason in this case to create a gate at all, just
1035 connect the lsig to the osig with the bit positions
257e1f9 Support shifts and divide.
steve authored
1036 shifted. Use a NetPartSelect to select the parts of the
1037 left expression that survive the shift, and a NetConcat to
1038 concatenate a constant for padding. */
bf72f39 eval_const uses scope instead of a string path.
steve authored
1039 if (verinum*rval = right_->eval_const(des, scope)) {
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1040 assert(rval->is_defined());
1041 unsigned dist = rval->as_ulong();
1042
257e1f9 Support shifts and divide.
steve authored
1043 /* Very special case: constant 0 shift. Simply return
1044 the left signal again. */
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1045 if (dist == 0) return lsig;
1046
257e1f9 Support shifts and divide.
steve authored
1047 /* Another very special case: constant shift the entire
1048 value away. The result is a const. */
1049 if (dist > lwidth) {
1050 assert(0);
1051 }
1052
1053 /* The construction that I'm making will ultimately
1054 connect its output to the osig here. This will be the
1055 result that I return from this function. */
badad63 All NetObj objects have lex_string base names.
steve authored
1056 NetNet*osig = new NetNet(scope, scope->local_symbol(),
4124273 Handle some special cases of unary 2's complement,
steve authored
1057 NetNet::WIRE, lwidth);
75ad905 Generalize signals to carry types.
steve authored
1058 osig->data_type( data_type );
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1059 osig->local_flag(true);
1060
3dbc07f Implement signed divide and signed right shift in nets.
steve authored
1061
257e1f9 Support shifts and divide.
steve authored
1062 /* Make the constant zero's that I'm going to pad to the
1063 top or bottom of the left expression. Attach a signal
1064 to its output so that I don't have to worry about it
1065 later. If the left expression is less then the
1066 desired width (and we are doing right shifts) then we
1067 can combine the expression padding with the distance
1068 padding to reduce nodes. */
1069 unsigned pad_width = dist;
1070 unsigned part_width = lwidth - dist;
1071 if (op_ == 'r' || op_ == 'R') {
1072 if (lsig->vector_width() < lwidth) {
1073 pad_width += lwidth - lsig->vector_width();
1074 part_width -= lwidth - lsig->vector_width();
1075 }
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1076 } else {
257e1f9 Support shifts and divide.
steve authored
1077
1078 /* The left net must be the same width as the
1079 result. The part select that I'm about to make relies
1080 on that. */
1081 lsig = pad_to_width(des, lsig, lwidth);
1082
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1083 }
1084
257e1f9 Support shifts and divide.
steve authored
1085 NetNet*zero = new NetNet(scope, scope->local_symbol(),
1086 NetNet::WIRE, pad_width);
75ad905 Generalize signals to carry types.
steve authored
1087 zero->data_type( data_type );
257e1f9 Support shifts and divide.
steve authored
1088 zero->local_flag(true);
1089 zero->set_line(*this);
1090
1091 if (op_ == 'R') {
1092 NetPartSelect*sign_bit
1093 = new NetPartSelect(lsig, lsig->vector_width()-1,
1094 1, NetPartSelect::VP);
1095 des->add_node(sign_bit);
1096 NetReplicate*sign_pad
1097 = new NetReplicate(scope, scope->local_symbol(),
1098 pad_width, pad_width);
1099 des->add_node(sign_pad);
1100 NetNet*tmp = new NetNet(scope, scope->local_symbol(),
1101 NetNet::WIRE, 1);
75ad905 Generalize signals to carry types.
steve authored
1102 tmp->data_type( data_type );
326329d Set some missing local flags.
steve authored
1103 tmp->local_flag(true);
1104 tmp->set_line(*this);
257e1f9 Support shifts and divide.
steve authored
1105 connect(sign_bit->pin(0), tmp->pin(0));
1106 connect(sign_bit->pin(0), sign_pad->pin(1));
1107
1108 connect(zero->pin(0), sign_pad->pin(0));
1109
1110 } else {
1111 NetConst*zero_c = new NetConst(scope, scope->local_symbol(),
1112 verinum(verinum::V0, pad_width));
1113 des->add_node(zero_c);
1114 connect(zero->pin(0), zero_c->pin(0));
1115 }
1116
1117 /* Make a concatenation operator that will join the
1118 part-selected right expression at the pad values. */
1119 NetConcat*cc = new NetConcat(scope, scope->local_symbol(),
1120 lwidth, 2);
1121 cc->set_line(*this);
1122 des->add_node(cc);
1123 connect(cc->pin(0), osig->pin(0));
1124
1125 /* Make the part select of the left expression and
1126 connect it to the lsb or msb of the concatenation,
1127 depending on the direction of the shift. */
1128 NetPartSelect*part;
1129
1130 switch (op_) {
1131 case 'l': // Left shift === {lsig, zero}
1132 part = new NetPartSelect(lsig, 0, part_width,
1133 NetPartSelect::VP);
1134 connect(cc->pin(1), zero->pin(0));
1135 connect(cc->pin(2), part->pin(0));
1136 break;
1137 case 'R':
1138 case 'r': // right-shift === {zero, lsig}
1139 part = new NetPartSelect(lsig, dist, part_width,
1140 NetPartSelect::VP);
1141 connect(cc->pin(1), part->pin(0));
1142 connect(cc->pin(2), zero->pin(0));
1143 break;
1144 default:
1145 assert(0);
1146 }
1147
1148 des->add_node(part);
1149
4b829bf Get argument widths right for shift results.
steve authored
1150 if (debug_elaborate) {
1151 cerr << get_line() << ": debug: Elaborate shift "
1152 << "(" << op_ << ") as concatenation of "
1153 << pad_width << " zeros with " << part_width
1154 << " bits of expression." << endl;
1155 }
1156
257e1f9 Support shifts and divide.
steve authored
1157 /* Attach a signal to the part select output (NetConcat
1158 input) */
1159 NetNet*tmp = new NetNet(scope, scope->local_symbol(),
1160 NetNet::WIRE, part_width);
75ad905 Generalize signals to carry types.
steve authored
1161 tmp->data_type( data_type );
257e1f9 Support shifts and divide.
steve authored
1162 tmp->local_flag(true);
1163 tmp->set_line(*this);
1164 connect(part->pin(0), tmp->pin(0));
1165
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1166 return osig;
1167 }
1168
9e5ff89 Add structural reduction NAND,
steve authored
1169 // Calculate the number of useful bits for the shift amount,
1170 // and elaborate the right_ expression as the shift amount.
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1171 unsigned dwid = 0;
61195c5 Harmless fixup of warnings.
steve authored
1172 while ((1U << dwid) < lwidth)
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1173 dwid += 1;
1174
7793a49 Remove string paths from PExpr elaboration.
steve authored
1175 NetNet*rsig = right_->elaborate_net(des, scope, dwid, 0, 0, 0);
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1176 if (rsig == 0) return 0;
1177
9e5ff89 Add structural reduction NAND,
steve authored
1178 // Make the shift device itself, and the output
1179 // NetNet. Connect the Result output pins to the osig signal
a275133 LPM objects store only their base names.
steve authored
1180 NetCLShift*gate = new NetCLShift(scope, scope->local_symbol(),
257e1f9 Support shifts and divide.
steve authored
1181 lwidth, rsig->vector_width(),
3dbc07f Implement signed divide and signed right shift in nets.
steve authored
1182 right_flag, signed_flag);
257e1f9 Support shifts and divide.
steve authored
1183 des->add_node(gate);
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1184
badad63 All NetObj objects have lex_string base names.
steve authored
1185 NetNet*osig = new NetNet(scope, scope->local_symbol(),
9e5ff89 Add structural reduction NAND,
steve authored
1186 NetNet::WIRE, lwidth);
75ad905 Generalize signals to carry types.
steve authored
1187 osig->data_type( data_type );
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1188 osig->local_flag(true);
257e1f9 Support shifts and divide.
steve authored
1189 osig->set_signed(signed_flag);
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1190
257e1f9 Support shifts and divide.
steve authored
1191 connect(osig->pin(0), gate->pin_Result());
9e5ff89 Add structural reduction NAND,
steve authored
1192
1193 // Connect the lsig (the left expression) to the Data input,
ca488df Handle LPM shifts.
steve authored
1194 // and pad it if necessary. The lwidth is the width of the
1195 // NetCLShift gate, and the D input must match.
1196 if (lsig->vector_width() < lwidth)
1197 lsig = pad_to_width(des, lsig, lwidth);
1198
1199 assert(lsig->vector_width() <= lwidth);
257e1f9 Support shifts and divide.
steve authored
1200 connect(lsig->pin(0), gate->pin_Data());
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1201
9e5ff89 Add structural reduction NAND,
steve authored
1202 // Connect the rsig (the shift amount expression) to the
1203 // Distance input.
257e1f9 Support shifts and divide.
steve authored
1204 connect(rsig->pin(0), gate->pin_Distance());
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1205
257e1f9 Support shifts and divide.
steve authored
1206 if (debug_elaborate) {
1207 cerr << get_line() << ": debug: "
1208 << "Elaborate LPM_SHIFT: width="<<gate->width()
1209 << ", swidth="<< gate->width_dist() << endl;
1210 }
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1211
1212 return osig;
1213 }
1214
cdb99e7 Elaborate net repeat concatenations.
steve authored
1215 /*
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1216 * This method elaborates a call to a function in the context of a
5472b27 Rewire/generalize parsing an elaboration of
steve authored
1217 * continuous assignment. The definition of the function contains a
1218 * list of the ports, and an output port. The NetEUFunc that I create
1219 * here has a port for all the input ports and the output port. The
1220 * ports are connected by pins.
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1221 */
5d1d99a Handle signed magnitude compare all the
steve authored
1222 NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
1223 unsigned width,
58f182a Node delays can be more general expressions in structural contexts.
steve authored
1224 const NetExpr* rise,
1225 const NetExpr* fall,
1226 const NetExpr* decay,
5d1d99a Handle signed magnitude compare all the
steve authored
1227 Link::strength_t drive0,
1228 Link::strength_t drive1) const
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1229 {
1230 unsigned errors = 0;
1231 unsigned func_pins = 0;
1232
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
1233 if (path_.front().name[0] == '$')
80f30be Add support for system functions in continuous assignments.
steve authored
1234 return elaborate_net_sfunc_(des, scope,
1235 width, rise, fall, decay,
1236 drive0, drive1);
7f67afe Add support for $unsigned.
steve authored
1237
5d1d99a Handle signed magnitude compare all the
steve authored
1238
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1239 /* Look up the function definition. */
1240 NetFuncDef*def = des->find_function(scope, path_);
1241 if (def == 0) {
1242 cerr << get_line() << ": error: No function " << path_ <<
c7d97f4 Properly evaluate scope path expressions.
steve authored
1243 " in this context (" << scope_path(scope) << ")." << endl;
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1244 des->errors += 1;
1245 return 0;
1246 }
1247 assert(def);
1248
1249 NetScope*dscope = def->scope();
1250 assert(dscope);
1251
5472b27 Rewire/generalize parsing an elaboration of
steve authored
1252 /* This must be a ufuction that returns a signal. */
1253 assert(def->return_sig());
1254
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1255 /* check the validity of the parameters. */
1256 if (! check_call_matches_definition_(des, dscope))
1257 return 0;
1258
1259 /* Elaborate all the parameters of the function call,
1260 and collect the resulting NetNet objects. All the
1261 parameters take on the size of the target port. */
1262
5472b27 Rewire/generalize parsing an elaboration of
steve authored
1263 svector<NetNet*> eparms (def->port_count());
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1264 for (unsigned idx = 0 ; idx < eparms.count() ; idx += 1) {
5472b27 Rewire/generalize parsing an elaboration of
steve authored
1265 const NetNet* port_reg = def->port(idx);
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1266 NetNet*tmp = parms_[idx]->elaborate_net(des, scope,
53da6e9 Add support for LPM_UFUNC user defined functions.
steve authored
1267 port_reg->vector_width(),
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1268 0, 0, 0,
1269 Link::STRONG,
1270 Link::STRONG);
1271 if (tmp == 0) {
1272 cerr << get_line() << ": error: Unable to elaborate "
1273 << "port " << idx << " of call to " << path_ <<
1274 "." << endl;
1275 errors += 1;
1276 continue;
1277 }
1278
1279 func_pins += tmp->pin_count();
1280 eparms[idx] = tmp;
1281 }
1282
1283 if (errors > 0)
1284 return 0;
1285
1286
1287 NetUserFunc*net = new NetUserFunc(scope,
27af95d Use perm_strings for named langiage items.
steve authored
1288 scope->local_symbol(),
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1289 dscope);
1290 des->add_node(net);
1291
1292 /* Create an output signal and connect it to the output pins
1293 of the function net. */
badad63 All NetObj objects have lex_string base names.
steve authored
1294 NetNet*osig = new NetNet(scope, scope->local_symbol(),
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1295 NetNet::WIRE,
53da6e9 Add support for LPM_UFUNC user defined functions.
steve authored
1296 def->return_sig()->vector_width());
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1297 osig->local_flag(true);
a8b86ea More explicit datatype setup.
steve authored
1298 osig->data_type(def->return_sig()->data_type());
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1299
53da6e9 Add support for LPM_UFUNC user defined functions.
steve authored
1300 connect(net->pin(0), osig->pin(0));
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1301
1302 /* Connect the parameter pins to the parameter expressions. */
1303 for (unsigned idx = 0 ; idx < eparms.count() ; idx += 1) {
5472b27 Rewire/generalize parsing an elaboration of
steve authored
1304 const NetNet* port = def->port(idx);
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1305 NetNet*cur = eparms[idx];
1306
53da6e9 Add support for LPM_UFUNC user defined functions.
steve authored
1307 NetNet*tmp = pad_to_width(des, cur, port->vector_width());
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1308
53da6e9 Add support for LPM_UFUNC user defined functions.
steve authored
1309 connect(net->pin(idx+1), tmp->pin(0));
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1310 }
1311
1312 return osig;
1313 }
1314
80f30be Add support for system functions in continuous assignments.
steve authored
1315 NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope,
1316 unsigned width,
1317 const NetExpr* rise,
1318 const NetExpr* fall,
1319 const NetExpr* decay,
1320 Link::strength_t drive0,
1321 Link::strength_t drive1) const
1322 {
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
1323 perm_string name = peek_tail_name(path_);
1324
80f30be Add support for system functions in continuous assignments.
steve authored
1325 /* Handle the special case that the function call is to
1326 $signed. This takes a single expression argument, and
1327 forces it to be a signed result. Otherwise, it is as if the
1328 $signed did not exist. */
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
1329 if (strcmp(name, "$signed") == 0) {
80f30be Add support for system functions in continuous assignments.
steve authored
1330 if ((parms_.count() != 1) || (parms_[0] == 0)) {
1331 cerr << get_line() << ": error: The $signed() function "
1332 << "takes exactly one(1) argument." << endl;
1333 des->errors += 1;
1334 return 0;
1335 }
1336
1337 PExpr*expr = parms_[0];
1338 NetNet*sub = expr->elaborate_net(des, scope, width, rise,
1339 fall, decay, drive0, drive1);
1340 sub->set_signed(true);
1341 return sub;
1342 }
1343
1344 /* handle $unsigned like $signed */
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
1345 if (strcmp(name, "$unsigned") == 0) {
80f30be Add support for system functions in continuous assignments.
steve authored
1346 if ((parms_.count() != 1) || (parms_[0] == 0)) {
1347 cerr << get_line() << ": error: The $unsigned() function "
1348 << "takes exactly one(1) argument." << endl;
1349 des->errors += 1;
1350 return 0;
1351 }
1352
1353 PExpr*expr = parms_[0];
1354 NetNet*sub = expr->elaborate_net(des, scope, width, rise,
1355 fall, decay, drive0, drive1);
1356 sub->set_signed(false);
1357 return sub;
1358 }
1359
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
1360 const struct sfunc_return_type*def = lookup_sys_func(name);
80f30be Add support for system functions in continuous assignments.
steve authored
1361
1362 if (def == 0) {
1363 cerr << get_line() << ": error: System function "
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
1364 << peek_tail_name(path_) << " not defined." << endl;
80f30be Add support for system functions in continuous assignments.
steve authored
1365 des->errors += 1;
1366 return 0;
1367 }
1368
1369 NetSysFunc*net = new NetSysFunc(scope, scope->local_symbol(),
1370 def, 1+parms_.count());
1371 des->add_node(net);
1372 net->set_line(*this);
1373
1374 NetNet*osig = new NetNet(scope, scope->local_symbol(),
1375 NetNet::WIRE, def->wid);
1376 osig->local_flag(true);
1377 osig->data_type(def->type);
1378 osig->set_line(*this);
1379
1380 connect(net->pin(0), osig->pin(0));
1381
1382 for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
1383 NetNet*tmp = parms_[idx]->elaborate_net(des, scope, 0,
1384 0, 0, 0,
1385 Link::STRONG, Link::STRONG);
1386 if (tmp == 0) {
1387 cerr << get_line() << ": error: Unable to elaborate "
1388 << "port " << idx << " of call to " << path_ <<
1389 "." << endl;
1390 continue;
1391 }
1392
1393 connect(net->pin(1+idx), tmp->pin(0));
1394 }
1395 return osig;
1396 }
1397
b7c2bd4 Add the NetUserFunc netlist node.
steve authored
1398
1399 /*
cdb99e7 Elaborate net repeat concatenations.
steve authored
1400 * The concatenation operator, as a net, is a wide signal that is
1401 * connected to all the pins of the elaborated expression nets.
1402 */
7793a49 Remove string paths from PExpr elaboration.
steve authored
1403 NetNet* PEConcat::elaborate_net(Design*des, NetScope*scope,
cdb99e7 Elaborate net repeat concatenations.
steve authored
1404 unsigned,
58f182a Node delays can be more general expressions in structural contexts.
steve authored
1405 const NetExpr* rise,
1406 const NetExpr* fall,
1407 const NetExpr* decay,
b90cda1 Carry strength values from Verilog source to the
steve authored
1408 Link::strength_t drive0,
1409 Link::strength_t drive1) const
cdb99e7 Elaborate net repeat concatenations.
steve authored
1410 {
1411 svector<NetNet*>nets (parms_.count());
20be035 Elaborate unary subtract and NOT in netlist
steve authored
1412 unsigned vector_width = 0;
cdb99e7 Elaborate net repeat concatenations.
steve authored
1413 unsigned errors = 0;
4819d54 Fix repeat concatenation with multiple expressions (PR#10)
steve authored
1414 unsigned repeat = 1;
cdb99e7 Elaborate net repeat concatenations.
steve authored
1415
20be035 Elaborate unary subtract and NOT in netlist
steve authored
1416 /* The repeat expression must evaluate to a compile-time
1417 constant. This is used to generate the width of the
1418 concatenation. */
cdb99e7 Elaborate net repeat concatenations.
steve authored
1419 if (repeat_) {
71faebd Make elaborate_expr methods aware of the width that the context
steve authored
1420 NetExpr*etmp = elab_and_eval(des, scope, repeat_, -1);
ade5bdc Integrate pr1072 fix from v0_8-branch.
steve authored
1421 assert(etmp);
1422 NetEConst*erep = dynamic_cast<NetEConst*>(etmp);
1423
1424 if (erep == 0) {
bb02da0 Better error message around repeat concatenation syntax.
steve authored
1425 cerr << get_line() << ": error: Unable to "
cdb99e7 Elaborate net repeat concatenations.
steve authored
1426 << "evaluate constant repeat expression." << endl;
1427 des->errors += 1;
1428 return 0;
1429 }
1430
ade5bdc Integrate pr1072 fix from v0_8-branch.
steve authored
1431 repeat = erep->value().as_ulong();
1432 delete etmp;
cdb99e7 Elaborate net repeat concatenations.
steve authored
1433
4819d54 Fix repeat concatenation with multiple expressions (PR#10)
steve authored
1434 if (repeat == 0) {
ade5bdc Integrate pr1072 fix from v0_8-branch.
steve authored
1435 cerr << get_line() << ": error: Concatenation epeat "
1436 "may not be 0."
4819d54 Fix repeat concatenation with multiple expressions (PR#10)
steve authored
1437 << endl;
1438 des->errors += 1;
1439 return 0;
cdb99e7 Elaborate net repeat concatenations.
steve authored
1440 }
1441 }
1442
20be035 Elaborate unary subtract and NOT in netlist
steve authored
1443 if (debug_elaborate) {
1444 cerr << get_line() <<": debug: PEConcat concat repeat="
1445 << repeat << "." << endl;
1446 }
1447
d1f0bcf Catch unsized expressions in continuous assigns.
steve authored
1448 /* The operands of the concatenation must contain all
1449 self-determined arguments. Set this flag to force an error
1450 message if this is not the case. */
1451 const bool save_flag = must_be_self_determined_flag;
1452 must_be_self_determined_flag = true;
1453
cdb99e7 Elaborate net repeat concatenations.
steve authored
1454 /* Elaborate the operands of the concatenation. */
1455 for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
79b1c51 Detect indefinite widths where definite widths are required.
steve authored
1456
f526d23 Check for missing concat subexpressions (PR#11)
steve authored
1457 if (parms_[idx] == 0) {
1458 cerr << get_line() << ": error: Empty expressions "
1459 << "not allowed in concatenations." << endl;
1460 errors += 1;
1461 continue;
1462 }
1463
79b1c51 Detect indefinite widths where definite widths are required.
steve authored
1464 /* Look for the special case of an unsized number in a
1465 concatenation expression. Mark this as an error, but
1466 allow elaboration to continue to see if I can find
1467 more errors. */
1468
1469 if (PENumber*tmp = dynamic_cast<PENumber*>(parms_[idx])) {
1470 if (tmp->value().has_len() == false) {
1471 cerr << get_line() << ": error: Number "
1472 << tmp->value() << " with indefinite size"
1473 << " in concatenation." << endl;
1474 errors += 1;
1475 }
1476 }
1477
7793a49 Remove string paths from PExpr elaboration.
steve authored
1478 nets[idx] = parms_[idx]->elaborate_net(des, scope, 0,
cdb99e7 Elaborate net repeat concatenations.
steve authored
1479 rise,fall,decay);
1480 if (nets[idx] == 0)
1481 errors += 1;
1482 else
20be035 Elaborate unary subtract and NOT in netlist
steve authored
1483 vector_width += nets[idx]->vector_width();
cdb99e7 Elaborate net repeat concatenations.
steve authored
1484 }
1485
d1f0bcf Catch unsized expressions in continuous assigns.
steve authored
1486 must_be_self_determined_flag = save_flag;
1487
cdb99e7 Elaborate net repeat concatenations.
steve authored
1488 /* If any of the sub expressions failed to elaborate, then
1489 delete all those that did and abort myself. */
1490 if (errors) {
1491 for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
1492 if (nets[idx]) delete nets[idx];
1493 }
1494 des->errors += 1;
1495 return 0;
1496 }
1497
20be035 Elaborate unary subtract and NOT in netlist
steve authored
1498 if (debug_elaborate) {
1499 cerr << get_line() <<": debug: PEConcat concat collected "
1500 << "width=" << vector_width << ", repeat=" << repeat
1501 << " of " << nets.count() << " expressions." << endl;
1502 }
1503
1504 NetConcat*dev = new NetConcat(scope, scope->local_symbol(),
1505 vector_width*repeat,
1506 nets.count()*repeat);
1507 dev->set_line(*this);
1508 des->add_node(dev);
1509
cdb99e7 Elaborate net repeat concatenations.
steve authored
1510 /* Make the temporary signal that connects to all the
1511 operands, and connect it up. Scan the operands of the
1512 concat operator from least significant to most significant,
4819d54 Fix repeat concatenation with multiple expressions (PR#10)
steve authored
1513 which is opposite from how they are given in the list.
1514
611d2c8 Spelling fixes from Larry
steve authored
1515 Allow for a repeat count other than 1 by repeating the
4819d54 Fix repeat concatenation with multiple expressions (PR#10)
steve authored
1516 connect loop as many times as necessary. */
1517
badad63 All NetObj objects have lex_string base names.
steve authored
1518 NetNet*osig = new NetNet(scope, scope->local_symbol(),
20be035 Elaborate unary subtract and NOT in netlist
steve authored
1519 NetNet::IMPLICIT, vector_width * repeat);
75ad905 Generalize signals to carry types.
steve authored
1520 osig->data_type(IVL_VT_LOGIC);
20be035 Elaborate unary subtract and NOT in netlist
steve authored
1521
1522 connect(dev->pin(0), osig->pin(0));
1523
1524 unsigned cur_pin = 1;
1525 for (unsigned rpt = 0; rpt < repeat ; rpt += 1) {
1526 for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
1527 NetNet*cur = nets[nets.count()-idx-1];
1528 connect(dev->pin(cur_pin++), cur->pin(0));
cdb99e7 Elaborate net repeat concatenations.
steve authored
1529 }
20be035 Elaborate unary subtract and NOT in netlist
steve authored
1530 }
1531
cdb99e7 Elaborate net repeat concatenations.
steve authored
1532
1533 osig->local_flag(true);
1534 return osig;
1535 }
1536
9ef4937 Add support for non-constant bit select.
steve authored
1537 /*
7b6678b Fix reverse bit ordered bit select in continuous assignment.
steve authored
1538 * This private method handles the special case that we have a
9ef4937 Add support for non-constant bit select.
steve authored
1539 * non-constant bit-select of an identifier. We already know that the
1540 * signal that is represented is "sig".
1541 */
1542 NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
1543 NetNet*sig,
58f182a Node delays can be more general expressions in structural contexts.
steve authored
1544 const NetExpr* rise,
1545 const NetExpr* fall,
1546 const NetExpr* decay,
9ef4937 Add support for non-constant bit select.
steve authored
1547 Link::strength_t drive0,
1548 Link::strength_t drive1) const
1549 {
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
1550 const name_component_t&name_tail = path_.back();
1551 ivl_assert(*this, !name_tail.index.empty());
1552
1553 const index_component_t&index_tail = name_tail.index.back();
1554 ivl_assert(*this, index_tail.sel == index_component_t::SEL_BIT);
1555 ivl_assert(*this, index_tail.msb != 0);
1556 ivl_assert(*this, index_tail.lsb == 0);
d434dd7 Allow part selects of memory words in l-values.
steve authored
1557
9ef4937 Add support for non-constant bit select.
steve authored
1558 /* Elaborate the selector. */
7dd0d25 Add support for variable part select.
steve authored
1559 NetNet*sel;
9ef4937 Add support for non-constant bit select.
steve authored
1560
7dd0d25 Add support for variable part select.
steve authored
1561 if (sig->msb() < sig->lsb()) {
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
1562 NetExpr*sel_expr = index_tail.msb->elaborate_expr(des, scope, -1, false);
7dd0d25 Add support for variable part select.
steve authored
1563 sel_expr = make_sub_expr(sig->lsb(), sel_expr);
1564 if (NetExpr*tmp = sel_expr->eval_tree()) {
1565 delete sel_expr;
1566 sel_expr = tmp;
1567 }
1568
1569 sel = sel_expr->synthesize(des);
9ef4937 Add support for non-constant bit select.
steve authored
1570
7dd0d25 Add support for variable part select.
steve authored
1571 } else if (sig->lsb() != 0) {
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
1572 NetExpr*sel_expr = index_tail.msb->elaborate_expr(des, scope, -1,false);
7dd0d25 Add support for variable part select.
steve authored
1573 sel_expr = make_add_expr(sel_expr, - sig->lsb());
1574 if (NetExpr*tmp = sel_expr->eval_tree()) {
1575 delete sel_expr;
1576 sel_expr = tmp;
1577 }
7b6678b Fix reverse bit ordered bit select in continuous assignment.
steve authored
1578
7dd0d25 Add support for variable part select.
steve authored
1579 sel = sel_expr->synthesize(des);
7b6678b Fix reverse bit ordered bit select in continuous assignment.
steve authored
1580
1581 } else {
ddd36ec Rework the heirarchical identifier parse syntax and pform
steve authored
1582 sel = index_tail.msb->elaborate_net(des, scope, 0, 0, 0, 0);
7dd0d25 Add support for variable part select.
steve authored
1583 }
7b6678b Fix reverse bit ordered bit select in continuous assignment.
steve authored
1584
7dd0d25 Add support for variable part select.
steve authored
1585 if (debug_elaborate) {
1586 cerr << get_line() << ": debug: Create NetPartSelect "
1587 << "using signal " << sel->name() << " as selector"
1588 << endl;
7b6678b Fix reverse bit ordered bit select in continuous assignment.
steve authored
1589 }
9ef4937 Add support for non-constant bit select.
steve authored
1590
7dd0d25 Add support for variable part select.
steve authored
1591 /* Create a part select that takes a non-constant offset and a
1592 width of 1. */
1593 NetPartSelect*mux = new NetPartSelect(sig, sel, 1);
1594 des->add_node(mux);
1595 mux->set_line(*this);
9ef4937 Add support for non-constant bit select.
steve authored
1596
badad63