Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 1706 lines (1474 sloc) 51.81 kb
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
1 /*
b734ecf Macintosh compilers do not support ident.
steve authored
2 * Copyright (c) 1999-2000 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 */
b734ecf Macintosh compilers do not support ident.
steve authored
19 #if !defined(WINNT) && !defined(macintosh)
3676d66 Module ports are really special PEIdent
steve authored
20 #ident "$Id: elab_net.cc,v 1.37 2000/05/16 04:05:15 steve Exp $"
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
21 #endif
22
23 # include "PExpr.h"
24 # include "netlist.h"
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
25 # include "netmisc.h"
48de739 Switch to control warnings.
steve authored
26 # include "compiler.h"
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
27
28 /*
29 * Elaborating binary operations generally involves elaborating the
30 * left and right expressions, then making an output wire and
31 * connecting the lot together with the right kind of gate.
32 */
33 NetNet* PEBinary::elaborate_net(Design*des, const string&path,
34 unsigned width,
35 unsigned long rise,
36 unsigned long fall,
b90cda1 Carry strength values from Verilog source to the
steve authored
37 unsigned long decay,
38 Link::strength_t drive0,
39 Link::strength_t drive1) const
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
40 {
41 switch (op_) {
aa8908c Multiplication all the way to simulation.
steve authored
42 case '*':
43 return elaborate_net_mul_(des, path, width, rise, fall, decay);
694ff93 Add support for integer division.
steve authored
44 //case '%':
45 case '/':
46 return elaborate_net_div_(des, path, width, rise, fall, decay);
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
47 case '+':
48 case '-':
49 return elaborate_net_add_(des, path, width, rise, fall, decay);
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
50 case '|': // Bitwise OR
51 case '&':
52 case '^':
53 case 'X': // Exclusing NOR
54 return elaborate_net_bit_(des, path, width, rise, fall, decay);
206b37e Fix NetConst being set to zero width, and clean
steve authored
55 case 'E':
56 case 'e':
57 case 'n':
513ade9 Support combinatorial comparators.
steve authored
58 case '<':
59 case '>':
60 case 'L': // <=
61 case 'G': // >=
206b37e Fix NetConst being set to zero width, and clean
steve authored
62 return elaborate_net_cmp_(des, path, width, rise, fall, decay);
ced7cc6 Structural logical or.
steve authored
63 case 'a': // && (logical and)
64 case 'o': // || (logical or)
65 return elaborate_net_log_(des, path, width, rise, fall, decay);
1624afe Add support for the LPM_CLSHIFT device.
steve authored
66 case 'l': // <<
67 case 'r': // >>
68 return elaborate_net_shift_(des, path, width, rise, fall, decay);
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
69 }
70
71 NetNet*lsig = left_->elaborate_net(des, path, width, 0, 0, 0),
72 *rsig = right_->elaborate_net(des, path, width, 0, 0, 0);
73 if (lsig == 0) {
74 cerr << get_line() << ": error: Cannot elaborate ";
75 left_->dump(cerr);
76 cerr << endl;
77 return 0;
78 }
79 if (rsig == 0) {
80 cerr << get_line() << ": error: Cannot elaborate ";
81 right_->dump(cerr);
82 cerr << endl;
83 return 0;
84 }
85
86 NetNet*osig;
87 NetNode*gate;
88 NetNode*gate_t;
89
90 switch (op_) {
91 case '^': // XOR
57d28e4 Support structural XNOR.
steve authored
92 case 'X': // XNOR
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
93 case '&': // AND
94 case '|': // Bitwise OR
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
95 assert(0);
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
96 break;
97
98 case 'E': // === (Case equals)
99 case 'e': // ==
100 case 'n': // !=
513ade9 Support combinatorial comparators.
steve authored
101 case '<':
102 case '>':
103 case 'G': // >=
104 case 'L': // <=
206b37e Fix NetConst being set to zero width, and clean
steve authored
105 assert(0);
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
106 break;
107
108 case '+':
109 assert(0);
110 break;
111
112 case 'l':
113 case 'r':
1624afe Add support for the LPM_CLSHIFT device.
steve authored
114 assert(0);
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
115 break;
116 default:
117 cerr << get_line() << ": internal error: unsupported"
118 " combinational operator (" << op_ << ")." << endl;
119 des->errors += 1;
120 osig = 0;
121 }
122
123 if (NetTmp*tmp = dynamic_cast<NetTmp*>(lsig))
124 delete tmp;
125 if (NetTmp*tmp = dynamic_cast<NetTmp*>(rsig))
126 delete tmp;
127
128 return osig;
129 }
130
131 /*
132 * Elaborate the structural +/- as an AddSub object. Connect DataA and
133 * DataB to the parameters, and connect the output signal to the
134 * Result. In this context, the device is a combinational adder with
135 * fixed direction, so leave Add_Sub unconnected and set the
136 * LPM_Direction property.
137 */
138 NetNet* PEBinary::elaborate_net_add_(Design*des, const string&path,
139 unsigned lwidth,
140 unsigned long rise,
141 unsigned long fall,
142 unsigned long decay) const
143 {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
144 NetScope*scope = des->find_scope(path);
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
145 NetNet*lsig = left_->elaborate_net(des, path, lwidth, 0, 0, 0),
146 *rsig = right_->elaborate_net(des, path, lwidth, 0, 0, 0);
147 if (lsig == 0) {
148 cerr << get_line() << ": error: Cannot elaborate ";
149 left_->dump(cerr);
150 cerr << endl;
151 return 0;
152 }
153 if (rsig == 0) {
154 cerr << get_line() << ": error: Cannot elaborate ";
155 right_->dump(cerr);
156 cerr << endl;
157 return 0;
158 }
159
160 NetNet*osig;
161 NetNode*gate;
162 NetNode*gate_t;
163
164 string name = des->local_symbol(path);
165 unsigned width = lsig->pin_count();
166 if (rsig->pin_count() > lsig->pin_count())
167 width = rsig->pin_count();
168
d54cc14 Simulate carry output on adders.
steve authored
169 // If the desired output size if creater then the largest
170 // operand, then include the carry of the adder as an output.
171 unsigned owidth = width;
172 if (lwidth > owidth)
173 owidth = width + 1;
174
acfb5c1 Over agressive signal elimination in constant probadation.
steve authored
175 // Pad out the operands, if necessary, the match the width of
176 // the adder device.
177 if (lsig->pin_count() < width)
178 lsig = pad_to_width(des, path, lsig, width);
179
180 if (rsig->pin_count() < width)
181 rsig = pad_to_width(des, path, rsig, width);
182
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
183 // Make the adder as wide as the widest operand
8d8f1e2 Move signal tables to the NetScope class.
steve authored
184 osig = new NetNet(scope, des->local_symbol(path), NetNet::WIRE, owidth);
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
185 NetAddSub*adder = new NetAddSub(name, width);
186
187 // Connect the adder to the various parts.
188 for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
189 connect(lsig->pin(idx), adder->pin_DataA(idx));
190 for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
191 connect(rsig->pin(idx), adder->pin_DataB(idx));
d54cc14 Simulate carry output on adders.
steve authored
192 for (unsigned idx = 0 ; idx < width ; idx += 1)
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
193 connect(osig->pin(idx), adder->pin_Result(idx));
d54cc14 Simulate carry output on adders.
steve authored
194 if (owidth > width)
195 connect(osig->pin(width), adder->pin_Cout());
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
196
197 gate = adder;
198 gate->rise_time(rise);
199 gate->fall_time(fall);
200 gate->decay_time(decay);
201 des->add_node(gate);
202
203 switch (op_) {
204 case '+':
205 gate->attribute("LPM_Direction", "ADD");
206 break;
207 case '-':
208 gate->attribute("LPM_Direction", "SUB");
209 break;
210 }
211
212
213 return osig;
214 }
215
216 /*
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
217 * Elaborate various bitwise logic operators. These are all similar in
218 * that they take operants of equal width, and each bit does not
219 * affect any other bits. Also common about all this is how bit widths
220 * of the operands are handled, when they do not match.
221 */
222 NetNet* PEBinary::elaborate_net_bit_(Design*des, const string&path,
223 unsigned width,
224 unsigned long rise,
225 unsigned long fall,
226 unsigned long decay) const
227 {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
228 NetScope*scope = des->find_scope(path);
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
229 NetNet*lsig = left_->elaborate_net(des, path, width, 0, 0, 0),
230 *rsig = right_->elaborate_net(des, path, width, 0, 0, 0);
231 if (lsig == 0) {
232 cerr << get_line() << ": error: Cannot elaborate ";
233 left_->dump(cerr);
234 cerr << endl;
235 return 0;
236 }
237 if (rsig == 0) {
238 cerr << get_line() << ": error: Cannot elaborate ";
239 right_->dump(cerr);
240 cerr << endl;
241 return 0;
242 }
243
244 if (lsig->pin_count() < rsig->pin_count())
245 lsig = pad_to_width(des, path, lsig, rsig->pin_count());
246 if (rsig->pin_count() < lsig->pin_count())
247 rsig = pad_to_width(des, path, rsig, lsig->pin_count());
248
249 if (lsig->pin_count() != rsig->pin_count()) {
250 cerr << get_line() << ": internal error: lsig pin count ("
251 << lsig->pin_count() << ") != rsig pin count ("
252 << rsig->pin_count() << ")." << endl;
253 des->errors += 1;
254 return 0;
255 }
256
257 assert(lsig->pin_count() == rsig->pin_count());
258
8d8f1e2 Move signal tables to the NetScope class.
steve authored
259 NetNet*osig = new NetNet(scope, des->local_symbol(path), NetNet::WIRE,
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
260 lsig->pin_count());
261 osig->local_flag(true);
262
263 switch (op_) {
264 case '^': // XOR
265 for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
266 NetLogic*gate = new NetLogic(des->local_symbol(path), 3,
267 NetLogic::XOR);
268 connect(gate->pin(1), lsig->pin(idx));
269 connect(gate->pin(2), rsig->pin(idx));
270 connect(gate->pin(0), osig->pin(idx));
271 gate->rise_time(rise);
272 gate->fall_time(fall);
273 gate->decay_time(decay);
274 des->add_node(gate);
275 }
276 break;
277
278 case 'X': // XNOR
279 for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
280 NetLogic*gate = new NetLogic(des->local_symbol(path), 3,
281 NetLogic::XNOR);
282 connect(gate->pin(1), lsig->pin(idx));
283 connect(gate->pin(2), rsig->pin(idx));
284 connect(gate->pin(0), osig->pin(idx));
285 gate->rise_time(rise);
286 gate->fall_time(fall);
287 gate->decay_time(decay);
288 des->add_node(gate);
289 }
290 break;
291
292 case '&': // AND
293 for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
294 NetLogic*gate = new NetLogic(des->local_symbol(path), 3,
295 NetLogic::AND);
296 connect(gate->pin(1), lsig->pin(idx));
297 connect(gate->pin(2), rsig->pin(idx));
298 connect(gate->pin(0), osig->pin(idx));
299 gate->rise_time(rise);
300 gate->fall_time(fall);
301 gate->decay_time(decay);
302 des->add_node(gate);
303 }
304 break;
305
306 case '|': // Bitwise OR
307 for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
308 NetLogic*gate = new NetLogic(des->local_symbol(path),
309 3, NetLogic::OR);
310 connect(gate->pin(1), lsig->pin(idx));
311 connect(gate->pin(2), rsig->pin(idx));
312 connect(gate->pin(0), osig->pin(idx));
313 gate->rise_time(rise);
314 gate->fall_time(fall);
315 gate->decay_time(decay);
316 des->add_node(gate);
317 }
318 break;
319
320 default:
321 assert(0);
322 }
323
324 if (NetTmp*tmp = dynamic_cast<NetTmp*>(lsig))
325 delete tmp;
326 if (NetTmp*tmp = dynamic_cast<NetTmp*>(rsig))
327 delete tmp;
328
329 return osig;
330 }
331
332 /*
3d1ffce Elaborate net widths of constants to as small
steve authored
333 * Elaborate the various binary comparison operators. The comparison
334 * operators return a single bit result, no matter what, so the left
335 * and right values can have their own size. The only restriction is
336 * that they have the same size.
206b37e Fix NetConst being set to zero width, and clean
steve authored
337 */
338 NetNet* PEBinary::elaborate_net_cmp_(Design*des, const string&path,
339 unsigned lwidth,
340 unsigned long rise,
341 unsigned long fall,
342 unsigned long decay) const
343 {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
344 NetScope*scope = des->find_scope(path);
206b37e Fix NetConst being set to zero width, and clean
steve authored
345 NetNet*lsig = left_->elaborate_net(des, path, 0, 0, 0, 0),
346 *rsig = right_->elaborate_net(des, path, 0, 0, 0, 0);
347 if (lsig == 0) {
348 cerr << get_line() << ": error: Cannot elaborate ";
349 left_->dump(cerr);
350 cerr << endl;
351 return 0;
352 }
353 if (rsig == 0) {
354 cerr << get_line() << ": error: Cannot elaborate ";
355 right_->dump(cerr);
356 cerr << endl;
357 return 0;
358 }
359
3d1ffce Elaborate net widths of constants to as small
steve authored
360 unsigned dwidth = lsig->pin_count();
361 if (rsig->pin_count() > dwidth) dwidth = rsig->pin_count();
362
363 NetNet*zero = 0;
364 if (lsig->pin_count() != rsig->pin_count()) {
365 NetConst*tmp = new NetConst(des->local_symbol(path), verinum::V0);
366 des->add_node(tmp);
8d8f1e2 Move signal tables to the NetScope class.
steve authored
367 zero = new NetNet(scope, des->local_symbol(path), NetNet::WIRE);
3d1ffce Elaborate net widths of constants to as small
steve authored
368 connect(tmp->pin(0), zero->pin(0));
369 }
206b37e Fix NetConst being set to zero width, and clean
steve authored
370
8d8f1e2 Move signal tables to the NetScope class.
steve authored
371 NetNet*osig = new NetNet(scope, des->local_symbol(path), NetNet::WIRE);
206b37e Fix NetConst being set to zero width, and clean
steve authored
372 osig->local_flag(true);
373
374 NetNode*gate;
3d1ffce Elaborate net widths of constants to as small
steve authored
375 //NetNode*gate_t;
206b37e Fix NetConst being set to zero width, and clean
steve authored
376
377 switch (op_) {
513ade9 Support combinatorial comparators.
steve authored
378 case '<':
379 case '>':
380 case 'L':
381 case 'G': {
3d1ffce Elaborate net widths of constants to as small
steve authored
382 NetCompare*cmp = new
383 NetCompare(des->local_symbol(path), dwidth);
384 for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
513ade9 Support combinatorial comparators.
steve authored
385 connect(cmp->pin_DataA(idx), lsig->pin(idx));
3d1ffce Elaborate net widths of constants to as small
steve authored
386 for (unsigned idx = lsig->pin_count(); idx < dwidth ; idx += 1)
387 connect(cmp->pin_DataA(idx), zero->pin(0));
388 for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
513ade9 Support combinatorial comparators.
steve authored
389 connect(cmp->pin_DataB(idx), rsig->pin(idx));
3d1ffce Elaborate net widths of constants to as small
steve authored
390 for (unsigned idx = rsig->pin_count(); idx < dwidth ; idx += 1)
391 connect(cmp->pin_DataB(idx), zero->pin(0));
392
513ade9 Support combinatorial comparators.
steve authored
393 switch (op_) {
394 case '<':
395 connect(cmp->pin_ALB(), osig->pin(0));
396 break;
397 case '>':
398 connect(cmp->pin_AGB(), osig->pin(0));
399 break;
400 case 'L':
401 connect(cmp->pin_ALEB(), osig->pin(0));
402 break;
403 case 'G':
404 connect(cmp->pin_AGEB(), osig->pin(0));
405 break;
406 }
407 gate = cmp;
408 break;
409 }
410
206b37e Fix NetConst being set to zero width, and clean
steve authored
411 case 'E': // Case equals (===)
412 // The comparison generates gates to bitwise compare
413 // each pair, and AND all the comparison results.
414 gate = new NetLogic(des->local_symbol(path),
415 1+lsig->pin_count(),
416 NetLogic::AND);
417 connect(gate->pin(0), osig->pin(0));
3d1ffce Elaborate net widths of constants to as small
steve authored
418 for (unsigned idx = 0 ; idx < dwidth ; idx += 1) {
419 NetCaseCmp*cmp = new NetCaseCmp(des->local_symbol(path));
420
421 if (idx < lsig->pin_count())
422 connect(cmp->pin(1), lsig->pin(idx));
423 else
424 connect(cmp->pin(1), zero->pin(0));
425
426 if (idx < rsig->pin_count())
427 connect(cmp->pin(2), rsig->pin(idx));
428 else
429 connect(cmp->pin(2), zero->pin(0));
430
431 connect(cmp->pin(0), gate->pin(idx+1));
432 des->add_node(cmp);
206b37e Fix NetConst being set to zero width, and clean
steve authored
433
434 // Attach a label to this intermediate wire
8d8f1e2 Move signal tables to the NetScope class.
steve authored
435 NetNet*tmp = new NetNet(scope, des->local_symbol(path),
206b37e Fix NetConst being set to zero width, and clean
steve authored
436 NetNet::WIRE);
437 tmp->local_flag(true);
3d1ffce Elaborate net widths of constants to as small
steve authored
438 connect(cmp->pin(0), tmp->pin(0));
206b37e Fix NetConst being set to zero width, and clean
steve authored
439 }
440 break;
441
442
443 case 'e': // ==
444 gate = new NetLogic(des->local_symbol(path),
3d1ffce Elaborate net widths of constants to as small
steve authored
445 1+dwidth,NetLogic::AND);
206b37e Fix NetConst being set to zero width, and clean
steve authored
446 connect(gate->pin(0), osig->pin(0));
3d1ffce Elaborate net widths of constants to as small
steve authored
447 for (unsigned idx = 0 ; idx < dwidth ; idx += 1) {
448 NetLogic*cmp = new NetLogic(des->local_symbol(path),
449 3, NetLogic::XNOR);
450 if (idx < lsig->pin_count())
451 connect(cmp->pin(1), lsig->pin(idx));
452 else
453 connect(cmp->pin(1), zero->pin(0));
454
455 if (idx < rsig->pin_count())
456 connect(cmp->pin(2), rsig->pin(idx));
457 else
458 connect(cmp->pin(2), zero->pin(0));
459
460 connect(cmp->pin(0), gate->pin(idx+1));
461 des->add_node(cmp);
462
8d8f1e2 Move signal tables to the NetScope class.
steve authored
463 NetNet*tmp = new NetNet(scope, des->local_symbol(path),
3d1ffce Elaborate net widths of constants to as small
steve authored
464 NetNet::WIRE);
465 tmp->local_flag(true);
466 connect(cmp->pin(0), tmp->pin(0));
206b37e Fix NetConst being set to zero width, and clean
steve authored
467 }
468 break;
469
470 case 'n': // !=
471 gate = new NetLogic(des->local_symbol(path),
3d1ffce Elaborate net widths of constants to as small
steve authored
472 1+dwidth, NetLogic::OR);
206b37e Fix NetConst being set to zero width, and clean
steve authored
473 connect(gate->pin(0), osig->pin(0));
474 for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
3d1ffce Elaborate net widths of constants to as small
steve authored
475 NetLogic*cmp = new NetLogic(des->local_symbol(path), 3,
476 NetLogic::XOR);
477 if (idx < lsig->pin_count())
478 connect(cmp->pin(1), lsig->pin(idx));
479 else
480 connect(cmp->pin(1), zero->pin(0));
481
482 if (idx < rsig->pin_count())
483 connect(cmp->pin(2), rsig->pin(idx));
484 else
485 connect(cmp->pin(2), zero->pin(0));
486
487 connect(cmp->pin(0), gate->pin(idx+1));
488 des->add_node(cmp);
489
8d8f1e2 Move signal tables to the NetScope class.
steve authored
490 NetNet*tmp = new NetNet(scope, des->local_symbol(path),
3d1ffce Elaborate net widths of constants to as small
steve authored
491 NetNet::WIRE);
492 tmp->local_flag(true);
493 connect(cmp->pin(0), tmp->pin(0));
206b37e Fix NetConst being set to zero width, and clean
steve authored
494 }
495 break;
496
497 default:
498 assert(0);
499 }
500
501 gate->rise_time(rise);
502 gate->fall_time(fall);
503 gate->decay_time(decay);
504 des->add_node(gate);
505
506 return osig;
507 }
508
694ff93 Add support for integer division.
steve authored
509 /*
510 * Elaborate a divider gate.
511 */
512 NetNet* PEBinary::elaborate_net_div_(Design*des, const string&path,
513 unsigned lwidth,
514 unsigned long rise,
515 unsigned long fall,
516 unsigned long decay) const
517 {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
518 NetScope*scope = des->find_scope(path);
519 assert(scope);
694ff93 Add support for integer division.
steve authored
520 NetNet*lsig = left_->elaborate_net(des, path, 0, 0, 0, 0);
521 if (lsig == 0) return 0;
522 NetNet*rsig = right_->elaborate_net(des, path, 0, 0, 0, 0);
523 if (rsig == 0) return 0;
524
525 unsigned rwidth = lsig->pin_count();
526 if (rsig->pin_count() > rwidth)
527 rwidth = rsig->pin_count();
528 NetDivide*div = new NetDivide(des->local_symbol(path), rwidth,
529 lsig->pin_count(),
530 rsig->pin_count());
531 des->add_node(div);
532
533 for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
534 connect(div->pin_DataA(idx), lsig->pin(idx));
535 for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
536 connect(div->pin_DataB(idx), rsig->pin(idx));
537
538 if (lwidth == 0) lwidth = rwidth;
8d8f1e2 Move signal tables to the NetScope class.
steve authored
539 NetNet*osig = new NetNet(scope, des->local_symbol(path),
694ff93 Add support for integer division.
steve authored
540 NetNet::IMPLICIT, lwidth);
541 osig->local_flag(true);
542
543 unsigned cnt = osig->pin_count();
544 if (cnt > rwidth) cnt = rwidth;
545
546 for (unsigned idx = 0 ; idx < cnt ; idx += 1)
547 connect(div->pin_Result(idx), osig->pin(idx));
548
549 /* If the lvalue is larger then the result, then pad the
550 output with constant 0. */
551 if (cnt < osig->pin_count()) {
552 NetConst*tmp = new NetConst(des->local_symbol(path), verinum::V0);
553 des->add_node(tmp);
554 for (unsigned idx = cnt ; idx < osig->pin_count() ; idx += 1)
555 connect(osig->pin(idx), tmp->pin(0));
556 }
557
558 return osig;
559 }
560
ced7cc6 Structural logical or.
steve authored
561 NetNet* PEBinary::elaborate_net_log_(Design*des, const string&path,
562 unsigned lwidth,
563 unsigned long rise,
564 unsigned long fall,
565 unsigned long decay) const
566 {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
567 NetScope*scope = des->find_scope(path);
568 assert(scope);
569
ced7cc6 Structural logical or.
steve authored
570 NetNet*lsig = left_->elaborate_net(des, path, 0, 0, 0, 0),
571 *rsig = right_->elaborate_net(des, path, 0, 0, 0, 0);
572 if (lsig == 0) {
573 cerr << get_line() << ": error: Cannot elaborate ";
574 left_->dump(cerr);
575 cerr << endl;
576 return 0;
577 }
578 if (rsig == 0) {
579 cerr << get_line() << ": error: Cannot elaborate ";
580 right_->dump(cerr);
581 cerr << endl;
582 return 0;
583 }
584
585 NetLogic*gate;
586 NetLogic*gate_t;
587 switch (op_) {
588 case 'a':
589 gate = new NetLogic(des->local_symbol(path), 3, NetLogic::AND);
590 break;
591 case 'o':
592 gate = new NetLogic(des->local_symbol(path), 3, NetLogic::OR);
593 break;
594 default:
595 assert(0);
596 }
597 gate->rise_time(rise);
598 gate->fall_time(fall);
599 gate->decay_time(decay);
600
601 // The first OR gate returns 1 if the left value is true...
602 if (lsig->pin_count() > 1) {
603 gate_t = new NetLogic(des->local_symbol(path),
604 1+lsig->pin_count(), NetLogic::OR);
605 for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
606 connect(gate_t->pin(idx+1), lsig->pin(idx));
2563e2b Revise the VVM backend to use nexus objects so that
steve authored
607
ced7cc6 Structural logical or.
steve authored
608 connect(gate->pin(1), gate_t->pin(0));
2563e2b Revise the VVM backend to use nexus objects so that
steve authored
609
610 /* The reduced logical value is a new nexus, create a
611 temporary signal to represent it. */
8d8f1e2 Move signal tables to the NetScope class.
steve authored
612 NetNet*tmp = new NetTmp(scope, des->local_symbol(path));
2563e2b Revise the VVM backend to use nexus objects so that
steve authored
613 connect(gate->pin(1), tmp->pin(0));
614
ced7cc6 Structural logical or.
steve authored
615 des->add_node(gate_t);
2563e2b Revise the VVM backend to use nexus objects so that
steve authored
616
ced7cc6 Structural logical or.
steve authored
617 } else {
618 connect(gate->pin(1), lsig->pin(0));
619 }
620
621 // The second OR gate returns 1 if the right value is true...
622 if (rsig->pin_count() > 1) {
623 gate_t = new NetLogic(des->local_symbol(path),
624 1+rsig->pin_count(), NetLogic::OR);
625 for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
626 connect(gate_t->pin(idx+1), rsig->pin(idx));
627 connect(gate->pin(2), gate_t->pin(0));
2563e2b Revise the VVM backend to use nexus objects so that
steve authored
628
629 /* The reduced logical value is a new nexus, create a
630 temporary signal to represent it. */
8d8f1e2 Move signal tables to the NetScope class.
steve authored
631 NetNet*tmp = new NetTmp(scope, des->local_symbol(path));
2563e2b Revise the VVM backend to use nexus objects so that
steve authored
632 connect(gate->pin(2), tmp->pin(0));
633
ced7cc6 Structural logical or.
steve authored
634 des->add_node(gate_t);
2563e2b Revise the VVM backend to use nexus objects so that
steve authored
635
ced7cc6 Structural logical or.
steve authored
636 } else {
637 connect(gate->pin(2), rsig->pin(0));
638 }
639
640 // The output is the AND/OR of the two logic values.
8d8f1e2 Move signal tables to the NetScope class.
steve authored
641 NetNet*osig = new NetNet(scope, des->local_symbol(path), NetNet::WIRE);
ced7cc6 Structural logical or.
steve authored
642 osig->local_flag(true);
643 connect(gate->pin(0), osig->pin(0));
644 des->add_node(gate);
645 return osig;
646 }
647
aa8908c Multiplication all the way to simulation.
steve authored
648 NetNet* PEBinary::elaborate_net_mul_(Design*des, const string&path,
649 unsigned lwidth,
650 unsigned long rise,
651 unsigned long fall,
652 unsigned long decay) const
653 {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
654 NetScope*scope = des->find_scope(path);
655 assert(scope);
656
aa8908c Multiplication all the way to simulation.
steve authored
657 NetNet*lsig = left_->elaborate_net(des, path, 0, 0, 0, 0);
658 if (lsig == 0) return 0;
659 NetNet*rsig = right_->elaborate_net(des, path, 0, 0, 0, 0);
660 if (rsig == 0) return 0;
661
662 unsigned rwidth = lsig->pin_count() + rsig->pin_count();
663 NetMult*mult = new NetMult(des->local_symbol(path), rwidth,
664 lsig->pin_count(),
665 rsig->pin_count());
666 des->add_node(mult);
667
668 for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
669 connect(mult->pin_DataA(idx), lsig->pin(idx));
670 for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
671 connect(mult->pin_DataB(idx), rsig->pin(idx));
672
673 if (lwidth == 0) lwidth = rwidth;
8d8f1e2 Move signal tables to the NetScope class.
steve authored
674 NetNet*osig = new NetNet(scope, des->local_symbol(path),
aa8908c Multiplication all the way to simulation.
steve authored
675 NetNet::IMPLICIT, lwidth);
676 osig->local_flag(true);
677
678 unsigned cnt = osig->pin_count();
679 if (cnt > rwidth) cnt = rwidth;
680
681 for (unsigned idx = 0 ; idx < cnt ; idx += 1)
682 connect(mult->pin_Result(idx), osig->pin(idx));
683
684 /* If the lvalue is larger then the result, then pad the
685 output with constant 0. */
686 if (cnt < osig->pin_count()) {
687 NetConst*tmp = new NetConst(des->local_symbol(path), verinum::V0);
688 des->add_node(tmp);
689 for (unsigned idx = cnt ; idx < osig->pin_count() ; idx += 1)
690 connect(osig->pin(idx), tmp->pin(0));
691 }
692
693 return osig;
694 }
695
1624afe Add support for the LPM_CLSHIFT device.
steve authored
696 NetNet* PEBinary::elaborate_net_shift_(Design*des, const string&path,
697 unsigned lwidth,
698 unsigned long rise,
699 unsigned long fall,
700 unsigned long decay) const
701 {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
702 NetScope*scope = des->find_scope(path);
703 assert(scope);
704
1624afe Add support for the LPM_CLSHIFT device.
steve authored
705 NetNet*lsig = left_->elaborate_net(des, path, lwidth, 0, 0, 0);
706 if (lsig == 0) return 0;
707
9e5ff89 Add structural reduction NAND,
steve authored
708 if (lsig->pin_count() > lwidth)
709 lwidth = lsig->pin_count();
710
1624afe Add support for the LPM_CLSHIFT device.
steve authored
711 /* Handle the special case of a constant shift amount. There
712 is no reason in this case to create a gate at all, just
713 connect the lsig to the osig with the bit positions
714 shifted. */
715 if (verinum*rval = right_->eval_const(des, path)) {
716 assert(rval->is_defined());
717 unsigned dist = rval->as_ulong();
718 if (dist > lsig->pin_count())
719 dist = lsig->pin_count();
720
721 /* Very special case, constant 0 shift. */
722 if (dist == 0) return lsig;
723
8d8f1e2 Move signal tables to the NetScope class.
steve authored
724 NetNet*osig = new NetNet(scope, des->local_symbol(path),
725 NetNet::WIRE, lsig->pin_count());
1624afe Add support for the LPM_CLSHIFT device.
steve authored
726 osig->local_flag(true);
727
728 NetConst*zero = new NetConst(des->local_symbol(path), verinum::V0);
729 des->add_node(zero);
730
731 if (op_ == 'l') {
732 unsigned idx;
733 for (idx = 0 ; idx < dist ; idx += 1)
734 connect(osig->pin(idx), zero->pin(0));
735 for (idx = dist ; idx < lsig->pin_count() ; idx += 1)
736 connect(osig->pin(idx), lsig->pin(idx-dist));
737
738 } else {
739 assert(op_ == 'r');
740 unsigned idx;
741 unsigned keep = lsig->pin_count()-dist;
742 for (idx = 0 ; idx < keep ; idx += 1)
743 connect(osig->pin(idx), lsig->pin(idx+dist));
744 for (idx = keep ; idx < lsig->pin_count() ; idx += 1)
745 connect(osig->pin(idx), zero->pin(0));
746 }
747
748 return osig;
749 }
750
9e5ff89 Add structural reduction NAND,
steve authored
751 // Calculate the number of useful bits for the shift amount,
752 // and elaborate the right_ expression as the shift amount.
1624afe Add support for the LPM_CLSHIFT device.
steve authored
753 unsigned dwid = 0;
9e5ff89 Add structural reduction NAND,
steve authored
754 while ((1 << dwid) < lwidth)
1624afe Add support for the LPM_CLSHIFT device.
steve authored
755 dwid += 1;
756
757 NetNet*rsig = right_->elaborate_net(des, path, dwid, 0, 0, 0);
758 if (rsig == 0) return 0;
759
9e5ff89 Add structural reduction NAND,
steve authored
760 // Make the shift device itself, and the output
761 // NetNet. Connect the Result output pins to the osig signal
1624afe Add support for the LPM_CLSHIFT device.
steve authored
762 NetCLShift*gate = new NetCLShift(des->local_symbol(path),
9e5ff89 Add structural reduction NAND,
steve authored
763 lwidth, rsig->pin_count());
1624afe Add support for the LPM_CLSHIFT device.
steve authored
764
8d8f1e2 Move signal tables to the NetScope class.
steve authored
765 NetNet*osig = new NetNet(scope, des->local_symbol(path),
9e5ff89 Add structural reduction NAND,
steve authored
766 NetNet::WIRE, lwidth);
1624afe Add support for the LPM_CLSHIFT device.
steve authored
767 osig->local_flag(true);
768
9e5ff89 Add structural reduction NAND,
steve authored
769 for (unsigned idx = 0 ; idx < lwidth ; idx += 1)
1624afe Add support for the LPM_CLSHIFT device.
steve authored
770 connect(osig->pin(idx), gate->pin_Result(idx));
9e5ff89 Add structural reduction NAND,
steve authored
771
772 // Connect the lsig (the left expression) to the Data input,
773 // and pad it if necessary with constant zeros.
774 for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
1624afe Add support for the LPM_CLSHIFT device.
steve authored
775 connect(lsig->pin(idx), gate->pin_Data(idx));
9e5ff89 Add structural reduction NAND,
steve authored
776
777 if (lsig->pin_count() < lwidth) {
778 NetConst*zero = new NetConst(des->local_symbol(path), verinum::V0);
8d8f1e2 Move signal tables to the NetScope class.
steve authored
779 NetTmp*tmp = new NetTmp(scope, des->local_symbol(path));
9e5ff89 Add structural reduction NAND,
steve authored
780 des->add_node(zero);
ba7fdb5 Add a signal to nexus of padding constant.
steve authored
781 connect(zero->pin(0), tmp->pin(0));
9e5ff89 Add structural reduction NAND,
steve authored
782 for (unsigned idx = lsig->pin_count() ; idx < lwidth ; idx += 1)
783 connect(zero->pin(0), gate->pin_Data(idx));
1624afe Add support for the LPM_CLSHIFT device.
steve authored
784 }
785
9e5ff89 Add structural reduction NAND,
steve authored
786 // Connect the rsig (the shift amount expression) to the
787 // Distance input.
1624afe Add support for the LPM_CLSHIFT device.
steve authored
788 for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
789 connect(rsig->pin(idx), gate->pin_Distance(idx));
790
791 if (op_ == 'r') {
ca6631f Fix connection of Direction of LMP_CLSHIFT
steve authored
792 NetTmp*tmp = new NetTmp(scope, des->local_symbol(path));
1624afe Add support for the LPM_CLSHIFT device.
steve authored
793 NetConst*dir = new NetConst(des->local_symbol(path), verinum::V1);
794 connect(dir->pin(0), gate->pin_Direction());
ca6631f Fix connection of Direction of LMP_CLSHIFT
steve authored
795 connect(tmp->pin(0), gate->pin_Direction());
1624afe Add support for the LPM_CLSHIFT device.
steve authored
796 des->add_node(dir);
797 }
798
799 des->add_node(gate);
800
801 return osig;
802 }
803
cdb99e7 Elaborate net repeat concatenations.
steve authored
804 /*
805 * The concatenation operator, as a net, is a wide signal that is
806 * connected to all the pins of the elaborated expression nets.
807 */
808 NetNet* PEConcat::elaborate_net(Design*des, const string&path,
809 unsigned,
810 unsigned long rise,
811 unsigned long fall,
b90cda1 Carry strength values from Verilog source to the
steve authored
812 unsigned long decay,
813 Link::strength_t drive0,
814 Link::strength_t drive1) const
cdb99e7 Elaborate net repeat concatenations.
steve authored
815 {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
816 NetScope*scope = des->find_scope(path);
817 assert(scope);
818
cdb99e7 Elaborate net repeat concatenations.
steve authored
819 svector<NetNet*>nets (parms_.count());
820 unsigned pins = 0;
821 unsigned errors = 0;
822
823 if (repeat_) {
824 verinum*rep = repeat_->eval_const(des, path);
825 if (rep == 0) {
826 cerr << get_line() << ": internal error: Unable to "
827 << "evaluate constant repeat expression." << endl;
828 des->errors += 1;
829 return 0;
830 }
831
832 unsigned long repeat = rep->as_ulong();
833
35a2690 Properly elaborate repeat concatenations.
steve authored
834 /* Elaborate the expression the first time to figure out
835 how wide the expression is. Then create a NetTmp
836 object big enough to hold all the repetitions. */
837
cdb99e7 Elaborate net repeat concatenations.
steve authored
838 assert(parms_.count() == 1);
839 NetNet*obj = parms_[0]->elaborate_net(des, path, 0, rise,
840 fall, decay);
35a2690 Properly elaborate repeat concatenations.
steve authored
841
842 unsigned per_count = obj->pin_count();
8d8f1e2 Move signal tables to the NetScope class.
steve authored
843 NetTmp*tmp = new NetTmp(scope, des->local_symbol(path),
35a2690 Properly elaborate repeat concatenations.
steve authored
844 repeat * per_count);
845
846 for (unsigned pin = 0 ; pin < per_count ; pin += 1)
847 connect(tmp->pin(pin), obj->pin(pin));
cdb99e7 Elaborate net repeat concatenations.
steve authored
848
35a2690 Properly elaborate repeat concatenations.
steve authored
849 /* Now elaborate the expression again to fill out the
850 repetitions, connecting each to the tmp NetNet
851 object. */
852
853 for (unsigned idx = 1 ; idx < repeat ; idx += 1) {
854 unsigned base = per_count * idx;
855
856 obj = parms_[0]->elaborate_net(des, path, per_count,
857 rise, fall, decay);
858 for (unsigned pin = 0 ; pin < per_count ; pin += 1)
cdb99e7 Elaborate net repeat concatenations.
steve authored
859 connect(tmp->pin(base+pin), obj->pin(pin));
860 }
861
862 return tmp;
863 }
864
865 /* Elaborate the operands of the concatenation. */
866 for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
867 nets[idx] = parms_[idx]->elaborate_net(des, path, 0,
868 rise,fall,decay);
869 if (nets[idx] == 0)
870 errors += 1;
871 else
872 pins += nets[idx]->pin_count();
873 }
874
875 /* If any of the sub expressions failed to elaborate, then
876 delete all those that did and abort myself. */
877 if (errors) {
878 for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
879 if (nets[idx]) delete nets[idx];
880 }
881 des->errors += 1;
882 return 0;
883 }
884
885 /* Make the temporary signal that connects to all the
886 operands, and connect it up. Scan the operands of the
887 concat operator from least significant to most significant,
888 which is opposite from how they are given in the list. */
8d8f1e2 Move signal tables to the NetScope class.
steve authored
889 NetNet*osig = new NetNet(scope, des->local_symbol(path),
cdb99e7 Elaborate net repeat concatenations.
steve authored
890 NetNet::IMPLICIT, pins);
891 pins = 0;
892 for (unsigned idx = nets.count() ; idx > 0 ; idx -= 1) {
893 NetNet*cur = nets[idx-1];
894 for (unsigned pin = 0 ; pin < cur->pin_count() ; pin += 1) {
895 connect(osig->pin(pins), cur->pin(pin));
896 pins += 1;
897 }
898 }
899
900 osig->local_flag(true);
901 return osig;
902 }
903
a81dcd7 Support memories in continuous assignments.
steve authored
904 NetNet* PEIdent::elaborate_net(Design*des, const string&path,
905 unsigned lwidth,
906 unsigned long rise,
907 unsigned long fall,
b90cda1 Carry strength values from Verilog source to the
steve authored
908 unsigned long decay,
909 Link::strength_t drive0,
910 Link::strength_t drive1) const
a81dcd7 Support memories in continuous assignments.
steve authored
911 {
80b8ea9 Put implicitly defined signals in the scope.
steve authored
912 NetScope*scope = des->find_scope(path);
69612ce Move memories to the NetScope object.
steve authored
913 NetNet*sig = des->find_signal(scope, text_);
a81dcd7 Support memories in continuous assignments.
steve authored
914
915 if (sig == 0) {
916 /* If the identifier is a memory instead of a signal,
917 then handle it elsewhere. Create a RAM. */
69612ce Move memories to the NetScope object.
steve authored
918 if (NetMemory*mem = des->find_memory(scope, text_))
a81dcd7 Support memories in continuous assignments.
steve authored
919 return elaborate_net_ram_(des, path, mem, lwidth,
920 rise, fall, decay);
921
922
e7efc27 Redesign the implementation of scopes and parameters.
steve authored
923 if (const NetExpr*pe = des->find_parameter(scope, text_)) {
a81dcd7 Support memories in continuous assignments.
steve authored
924
925 const NetEConst*pc = dynamic_cast<const NetEConst*>(pe);
926 assert(pc);
927 verinum pvalue = pc->value();
8d8f1e2 Move signal tables to the NetScope class.
steve authored
928 sig = new NetNet(scope, path+"."+text_, NetNet::IMPLICIT,
a81dcd7 Support memories in continuous assignments.
steve authored
929 pc->expr_width());
65ae928 NetConst can now hold wide constants.
steve authored
930 NetConst*cp = new NetConst(des->local_symbol(path), pvalue);
931 des->add_node(cp);
932 for (unsigned idx = 0; idx < sig->pin_count(); idx += 1)
933 connect(sig->pin(idx), cp->pin(idx));
a81dcd7 Support memories in continuous assignments.
steve authored
934
935 } else {
936
80b8ea9 Put implicitly defined signals in the scope.
steve authored
937 sig = new NetNet(scope, path+"."+text_, NetNet::IMPLICIT, 1);
48de739 Switch to control warnings.
steve authored
938
939 if (warn_implicit)
940 cerr << get_line() << ": warning: implicit "
941 " definition of wire " << path << "." <<
942 text_ << "." << endl;
a81dcd7 Support memories in continuous assignments.
steve authored
943 }
944 }
945
946 assert(sig);
947
948 if (msb_ && lsb_) {
949 verinum*mval = msb_->eval_const(des, path);
950 if (mval == 0) {
951 cerr << msb_->get_line() << ": error: unable to "
952 "evaluate constant expression: " << *msb_ <<
953 endl;
954 des->errors += 1;
955 return 0;
956 }
957
958 verinum*lval = lsb_->eval_const(des, path);
959 if (lval == 0) {
960 cerr << lsb_->get_line() << ": error: unable to "
961 "evaluate constant expression: " << *lsb_ <<
962 endl;
963 delete mval;
964 des->errors += 1;
965 return 0;
966 }
967
968 assert(mval);
969 assert(lval);
970 unsigned midx = sig->sb_to_idx(mval->as_long());
971 unsigned lidx = sig->sb_to_idx(lval->as_long());
972
973 if (midx >= lidx) {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
974 NetTmp*tmp = new NetTmp(scope, des->local_symbol(path),
a81dcd7 Support memories in continuous assignments.
steve authored
975 midx-lidx+1);
976 if (tmp->pin_count() > sig->pin_count()) {
977 cerr << get_line() << ": bit select out of "
978 << "range for " << sig->name() << endl;
979 return sig;
980 }
981
982 for (unsigned idx = lidx ; idx <= midx ; idx += 1)
983 connect(tmp->pin(idx-lidx), sig->pin(idx));
984
985 sig = tmp;
986
987 } else {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
988 NetTmp*tmp = new NetTmp(scope, des->local_symbol(path),
a81dcd7 Support memories in continuous assignments.
steve authored
989 lidx-midx+1);
990 assert(tmp->pin_count() <= sig->pin_count());
991 for (unsigned idx = lidx ; idx >= midx ; idx -= 1)
992 connect(tmp->pin(idx-midx), sig->pin(idx));
993
994 sig = tmp;
995 }
996
997 } else if (msb_) {
998 verinum*mval = msb_->eval_const(des, path);
999 if (mval == 0) {
1000 cerr << get_line() << ": index of " << text_ <<
1001 " needs to be constant in this context." <<
1002 endl;
1003 des->errors += 1;
1004 return 0;
1005 }
1006 assert(mval);
1007 unsigned idx = sig->sb_to_idx(mval->as_long());
1008 if (idx >= sig->pin_count()) {
b9d19d3 Speling error.
steve authored
1009 cerr << get_line() << ": index " << sig->name() <<
a81dcd7 Support memories in continuous assignments.
steve authored
1010 "[" << mval->as_long() << "] out of range." << endl;
1011 des->errors += 1;
1012 idx = 0;
1013 }
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1014 NetTmp*tmp = new NetTmp(scope, des->local_symbol(path), 1);
a81dcd7 Support memories in continuous assignments.
steve authored
1015 connect(tmp->pin(0), sig->pin(idx));
1016 sig = tmp;
1017 }
1018
1019 return sig;
1020 }
1021
1022 /*
1023 * When I run into an identifier in an expression that referrs to a
1024 * memory, create a RAM port object.
1025 */
1026 NetNet* PEIdent::elaborate_net_ram_(Design*des, const string&path,
1027 NetMemory*mem, unsigned lwidth,
1028 unsigned long rise,
1029 unsigned long fall,
1030 unsigned long decay) const
1031 {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1032 NetScope*scope = des->find_scope(path);
1033 assert(scope);
1034
a81dcd7 Support memories in continuous assignments.
steve authored
1035 if (msb_ == 0) {
1036 cerr << get_line() << ": error: memory reference without"
1037 " the required index expression." << endl;
1038 des->errors += 1;
1039 return 0;
1040 }
1041
1042 NetNet*adr = msb_->elaborate_net(des, path, 0, 0, 0, 0);
1043 if (adr == 0)
1044 return 0;
1045
1046
1047 NetRamDq*ram = new NetRamDq(des->local_symbol(mem->name()),
1048 mem, adr->pin_count());
1049 des->add_node(ram);
1050
1051 for (unsigned idx = 0 ; idx < adr->pin_count() ; idx += 1)
1052 connect(ram->pin_Address(idx), adr->pin(idx));
1053
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1054 NetNet*osig = new NetTmp(scope, des->local_symbol(mem->name()),
1055 ram->width());
a81dcd7 Support memories in continuous assignments.
steve authored
1056
1057 for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1)
1058 connect(ram->pin_Q(idx), osig->pin(idx));
1059
1060 return osig;
1061 }
1062
1063 /*
1064 * Identifiers in continuous assignment l-values are limited to wires
1065 * and that ilk. Detect registers and memories here and report errors.
1066 */
1067 NetNet* PEIdent::elaborate_lnet(Design*des, const string&path) const
1068 {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1069 NetScope*scope = des->find_scope(path);
1070 assert(scope);
1071
69612ce Move memories to the NetScope object.
steve authored
1072 NetNet*sig = des->find_signal(scope, text_);
a81dcd7 Support memories in continuous assignments.
steve authored
1073 if (sig == 0) {
1074 /* Don't allow memories here. Is it a memory? */
69612ce Move memories to the NetScope object.
steve authored
1075 if (des->find_memory(scope, text_)) {
a81dcd7 Support memories in continuous assignments.
steve authored
1076 cerr << get_line() << ": error: memories (" << text_
1077 << ") cannot be l-values in continuous "
1078 << "assignments." << endl;
1079 return 0;
1080 }
1081
1082 /* Fine, create an implicit wire as an l-value. */
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1083 sig = new NetNet(scope, path+"."+text_, NetNet::IMPLICIT, 1);
48de739 Switch to control warnings.
steve authored
1084
1085 if (warn_implicit)
1086 cerr << get_line() << ": warning: implicit "
1087 " definition of wire " << path << "." <<
1088 text_ << "." << endl;
a81dcd7 Support memories in continuous assignments.
steve authored
1089 }
1090
1091 assert(sig);
1092
1093 /* Don't allow registers as assign l-values. */
1094 if (sig->type() == NetNet::REG) {
1095 cerr << get_line() << ": error: registers (" << sig->name()
1096 << ") cannot be l-values in continuous"
1097 << " assignments." << endl;
1098 return 0;
1099 }
1100
1101 if (msb_ && lsb_) {
1102 /* Detect a part select. Evaluate the bits and elaborate
1103 the l-value by creating a sub-net that links to just
1104 the right pins. */
1105 verinum*mval = msb_->eval_const(des, path);
1106 assert(mval);
1107 verinum*lval = lsb_->eval_const(des, path);
1108 assert(lval);
1109 unsigned midx = sig->sb_to_idx(mval->as_long());
1110 unsigned lidx = sig->sb_to_idx(lval->as_long());
1111
1112 if (midx >= lidx) {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1113 NetTmp*tmp = new NetTmp(scope, des->local_symbol(path),
a81dcd7 Support memories in continuous assignments.
steve authored
1114 midx-lidx+1);
1115 if (tmp->pin_count() > sig->pin_count()) {
1116 cerr << get_line() << ": bit select out of "
1117 << "range for " << sig->name() << endl;
1118 return sig;
1119 }
1120
1121 for (unsigned idx = lidx ; idx <= midx ; idx += 1)
1122 connect(tmp->pin(idx-lidx), sig->pin(idx));
1123
1124 sig = tmp;
1125
1126 } else {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1127 NetTmp*tmp = new NetTmp(scope, des->local_symbol(path),
a81dcd7 Support memories in continuous assignments.
steve authored
1128 lidx-midx+1);
1129 assert(tmp->pin_count() <= sig->pin_count());
1130 for (unsigned idx = lidx ; idx >= midx ; idx -= 1)
1131 connect(tmp->pin(idx-midx), sig->pin(idx));
1132
1133 sig = tmp;
1134 }
1135
1136 } else if (msb_) {
1137 verinum*mval = msb_->eval_const(des, path);
1138 if (mval == 0) {
1139 cerr << get_line() << ": index of " << text_ <<
1140 " needs to be constant in this context." <<
1141 endl;
1142 des->errors += 1;
1143 return 0;
1144 }
1145 assert(mval);
1146 unsigned idx = sig->sb_to_idx(mval->as_long());
1147 if (idx >= sig->pin_count()) {
1148 cerr << get_line() << "; index " << sig->name() <<
1149 "[" << mval->as_long() << "] out of range." << endl;
1150 des->errors += 1;
1151 idx = 0;
1152 }
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1153 NetTmp*tmp = new NetTmp(scope, des->local_symbol(path), 1);
a81dcd7 Support memories in continuous assignments.
steve authored
1154 connect(tmp->pin(0), sig->pin(idx));
1155 sig = tmp;
1156 }
1157
1158 return sig;
1159 }
1160
206b37e Fix NetConst being set to zero width, and clean
steve authored
1161 /*
3676d66 Module ports are really special PEIdent
steve authored
1162 * This method is used to elaborate identifiers that are ports to a
1163 * scope. The scope is presumed to be that of the module that has the
1164 * port.
1165 */
1166 NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
1167 {
1168 const string path = scope->name();
1169
1170 NetNet*sig = des->find_signal(scope, text_);
1171 if (sig == 0) {
1172 cerr << get_line() << ": error: no wire/reg " << text_
1173 << " in module " << scope->name() << "." << endl;
1174 des->errors += 1;
1175 return 0;
1176 }
1177
1178
1179 if (msb_ && lsb_) {
1180 /* Detect a part select. Evaluate the bits and elaborate
1181 the l-value by creating a sub-net that links to just
1182 the right pins. */
1183 verinum*mval = msb_->eval_const(des, path);
1184 assert(mval);
1185 verinum*lval = lsb_->eval_const(des, path);
1186 assert(lval);
1187 unsigned midx = sig->sb_to_idx(mval->as_long());
1188 unsigned lidx = sig->sb_to_idx(lval->as_long());
1189
1190 if (midx >= lidx) {
1191 NetTmp*tmp = new NetTmp(scope, des->local_symbol(path),
1192 midx-lidx+1);
1193 if (tmp->pin_count() > sig->pin_count()) {
1194 cerr << get_line() << ": bit select out of "
1195 << "range for " << sig->name() << endl;
1196 return sig;
1197 }
1198
1199 for (unsigned idx = lidx ; idx <= midx ; idx += 1)
1200 connect(tmp->pin(idx-lidx), sig->pin(idx));
1201
1202 sig = tmp;
1203
1204 } else {
1205 NetTmp*tmp = new NetTmp(scope, des->local_symbol(path),
1206 lidx-midx+1);
1207 assert(tmp->pin_count() <= sig->pin_count());
1208 for (unsigned idx = lidx ; idx >= midx ; idx -= 1)
1209 connect(tmp->pin(idx-midx), sig->pin(idx));
1210
1211 sig = tmp;
1212 }
1213
1214 } else if (msb_) {
1215 verinum*mval = msb_->eval_const(des, path);
1216 if (mval == 0) {
1217 cerr << get_line() << ": index of " << text_ <<
1218 " needs to be constant in this context." <<
1219 endl;
1220 des->errors += 1;
1221 return 0;
1222 }
1223 assert(mval);
1224 unsigned idx = sig->sb_to_idx(mval->as_long());
1225 if (idx >= sig->pin_count()) {
1226 cerr << get_line() << "; index " << sig->name() <<
1227 "[" << mval->as_long() << "] out of range." << endl;
1228 des->errors += 1;
1229 idx = 0;
1230 }
1231 NetTmp*tmp = new NetTmp(scope, des->local_symbol(path), 1);
1232 connect(tmp->pin(0), sig->pin(idx));
1233 sig = tmp;
1234 }
1235
1236 return sig;
1237 }
1238
1239
1240 /*
206b37e Fix NetConst being set to zero width, and clean
steve authored
1241 * Elaborate a number as a NetConst object.
1242 */
1243 NetNet* PENumber::elaborate_net(Design*des, const string&path,
1244 unsigned lwidth,
1245 unsigned long rise,
1246 unsigned long fall,
b90cda1 Carry strength values from Verilog source to the
steve authored
1247 unsigned long decay,
1248 Link::strength_t drive0,
1249 Link::strength_t drive1) const
206b37e Fix NetConst being set to zero width, and clean
steve authored
1250 {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1251 NetScope*scope = des->find_scope(path);
1252 assert(scope);
1253
3d1ffce Elaborate net widths of constants to as small
steve authored
1254 /* If we are constrained by a l-value size, then just make a
1255 number constant with the correct size and set as many bits
1256 in that constant as make sense. Pad excess with zeros. */
1257 if (lwidth > 0) {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1258 NetNet*net = new NetNet(scope, des->local_symbol(path),
3d1ffce Elaborate net widths of constants to as small
steve authored
1259 NetNet::IMPLICIT, lwidth);
1260 net->local_flag(true);
1261
1262 verinum num(verinum::V0, net->pin_count());
1263 unsigned idx;
1264 for (idx = 0 ; idx < num.len() && idx < value_->len(); idx += 1)
1265 num.set(idx, value_->get(idx));
1266
1267 NetConst*tmp = new NetConst(des->local_symbol(path), num);
b90cda1 Carry strength values from Verilog source to the
steve authored
1268 for (idx = 0 ; idx < net->pin_count() ; idx += 1) {
1269 tmp->pin(idx).drive0(drive0);
1270 tmp->pin(idx).drive1(drive1);
3d1ffce Elaborate net widths of constants to as small
steve authored
1271 connect(net->pin(idx), tmp->pin(idx));
b90cda1 Carry strength values from Verilog source to the
steve authored
1272 }
3d1ffce Elaborate net widths of constants to as small
steve authored
1273
1274 des->add_node(tmp);
1275 return net;
1276 }
1277
1278 /* If the number has a length, then use that to size the
1279 number. Generate a constant object of exactly the user
1280 specified size. */
1281 if (value_->has_len()) {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1282 NetNet*net = new NetNet(scope, des->local_symbol(path),
3d1ffce Elaborate net widths of constants to as small
steve authored
1283 NetNet::IMPLICIT, value_->len());
1284 net->local_flag(true);
1285 NetConst*tmp = new NetConst(des->local_symbol(path), *value_);
1286 for (unsigned idx = 0 ; idx < value_->len() ; idx += 1)
1287 connect(net->pin(idx), tmp->pin(idx));
1288
1289 des->add_node(tmp);
1290 return net;
1291 }
1292
1293 /* None of the above tight constraints are present, so make a
1294 plausible choice for the width. Try to reduce the width as
1295 much as possible by eliminating high zeros of unsigned
1296 numbers. */
206b37e Fix NetConst being set to zero width, and clean
steve authored
1297 unsigned width = value_->len();
3d1ffce Elaborate net widths of constants to as small
steve authored
1298
1299 if (value_->has_sign() && (value_->get(width-1) == verinum::V0)) {
1300
1301 /* If the number is signed, but known to be positive,
1302 then reduce it down as if it were unsigned. */
1303 while (width > 1) {
1304 if (value_->get(width-1) != verinum::V0)
1305 break;
1306 width -= 1;
1307 }
1308
1309 } else if (value_->has_sign() == false) {
1310 while ( (width > 1) && (value_->get(width-1) == verinum::V0))
1311 width -= 1;
1312 }
1313
1314 verinum num (verinum::V0, width);
1315 for (unsigned idx = 0 ; idx < width ; idx += 1)
1316 num.set(idx, value_->get(idx));
206b37e Fix NetConst being set to zero width, and clean
steve authored
1317
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1318 NetNet*net = new NetNet(scope, des->local_symbol(path),
206b37e Fix NetConst being set to zero width, and clean
steve authored
1319 NetNet::IMPLICIT, width);
1320 net->local_flag(true);
3d1ffce Elaborate net widths of constants to as small
steve authored
1321 NetConst*tmp = new NetConst(des->local_symbol(path), num);
65ae928 NetConst can now hold wide constants.
steve authored
1322 for (unsigned idx = 0 ; idx < width ; idx += 1)
1323 connect(net->pin(idx), tmp->pin(idx));
206b37e Fix NetConst being set to zero width, and clean
steve authored
1324
65ae928 NetConst can now hold wide constants.
steve authored
1325 des->add_node(tmp);
206b37e Fix NetConst being set to zero width, and clean
steve authored
1326 return net;
1327 }
1328
1329
1330 /*
cb5fc54 Patch to synthesize unary ~ and the ternary operator.
steve authored
1331 * Elaborate the ternary operator in a netlist by creating a LPM_MUX
0a70a8a Allow ternary result to be padded to result width.
steve authored
1332 * with width matching the result, size == 2 and 1 select input. These
1333 * expressions come from code like:
1334 *
1335 * res = test ? a : b;
1336 *
1337 * The res has the width requested of this method, and the a and b
1338 * expressions have their own similar widths. The test expression is
1339 * only a single bit wide. The output from this function is a NetNet
1340 * object the width of the <res> expression and connected to the
1341 * Result pins of the LPM_MUX device. Any width not covered by the
1342 * width of the mux is padded with a NetConst device.
cb5fc54 Patch to synthesize unary ~ and the ternary operator.
steve authored
1343 */
1344 NetNet* PETernary::elaborate_net(Design*des, const string&path,
1345 unsigned width,
1346 unsigned long rise,
1347 unsigned long fall,
b90cda1 Carry strength values from Verilog source to the
steve authored
1348 unsigned long decay,
1349 Link::strength_t drive0,
1350 Link::strength_t drive1) const
cb5fc54 Patch to synthesize unary ~ and the ternary operator.
steve authored
1351 {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1352 NetScope*scope = des->find_scope(path);
1353 assert(scope);
1354
cb5fc54 Patch to synthesize unary ~ and the ternary operator.
steve authored
1355 NetNet* expr_sig = expr_->elaborate_net(des, path, 0, 0, 0, 0);
1356 NetNet* tru_sig = tru_->elaborate_net(des, path, width, 0, 0, 0);
1357 NetNet* fal_sig = fal_->elaborate_net(des, path, width, 0, 0, 0);
1358 if (expr_sig == 0 || tru_sig == 0 || fal_sig == 0) {
1359 des->errors += 1;
1360 return 0;
1361 }
1362
1363 assert(tru_sig->pin_count() == fal_sig->pin_count());
0a70a8a Allow ternary result to be padded to result width.
steve authored
1364 if (width == 0)
1365 width = tru_sig->pin_count();
1366
1367 assert(width >= tru_sig->pin_count());
cb5fc54 Patch to synthesize unary ~ and the ternary operator.
steve authored
1368 assert(expr_sig->pin_count() == 1);
1369
0a70a8a Allow ternary result to be padded to result width.
steve authored
1370 /* This is the width of the LPM_MUX device that I'm about to
1371 create. It may be smaller then the desired output, but I'll
1372 handle padding below.
1373
1374 Create a NetNet object wide enough to hold the result. */
1375
1376 unsigned dwidth = tru_sig->pin_count();
1377
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1378 NetNet*sig = new NetNet(scope, des->local_symbol(path), NetNet::WIRE,
0a70a8a Allow ternary result to be padded to result width.
steve authored
1379 width);
cb5fc54 Patch to synthesize unary ~ and the ternary operator.
steve authored
1380 sig->local_flag(true);
1381
0a70a8a Allow ternary result to be padded to result width.
steve authored
1382
1383 /* Make the device and connect its outputs to the osig and
1384 inputs to the tru and false case nets. Also connect the
1385 selector bit to the sel input. */
1386
1387 NetMux*mux = new NetMux(des->local_symbol(path), dwidth, 2, 1);
cb5fc54 Patch to synthesize unary ~ and the ternary operator.
steve authored
1388 connect(mux->pin_Sel(0), expr_sig->pin(0));
1389
0a70a8a Allow ternary result to be padded to result width.
steve authored
1390 for (unsigned idx = 0 ; idx < dwidth ; idx += 1) {
cb5fc54 Patch to synthesize unary ~ and the ternary operator.
steve authored
1391 connect(mux->pin_Result(idx), sig->pin(idx));
1392 connect(mux->pin_Data(idx,0), fal_sig->pin(idx));
1393 connect(mux->pin_Data(idx,1), tru_sig->pin(idx));
1394 }
5171846 Forgot to return the mux for use after elaboration.
steve authored
1395
0a70a8a Allow ternary result to be padded to result width.
steve authored
1396 /* If the device is too narrow to fill out the desired result,
1397 pad with zeros by creating a NetConst device. */
1398
1399 if (dwidth < width) {
1400 verinum vpad (verinum::V0, width-dwidth);
1401 NetConst*pad = new NetConst(des->local_symbol(path), vpad);
1402 des->add_node(pad);
1403 for (unsigned idx = dwidth ; idx < width ; idx += 1)
1404 connect(sig->pin(idx), pad->pin(idx-dwidth));
1405 }
1406
5171846 Forgot to return the mux for use after elaboration.
steve authored
1407 des->add_node(mux);
1408
1409 return sig;
cb5fc54 Patch to synthesize unary ~ and the ternary operator.
steve authored
1410 }
1411
0d5e4b4 Structural reduction XNOR.
steve authored
1412 NetNet* PEUnary::elaborate_net(Design*des, const string&path,
1413 unsigned width,
1414 unsigned long rise,
1415 unsigned long fall,
b90cda1 Carry strength values from Verilog source to the
steve authored
1416 unsigned long decay,
1417 Link::strength_t drive0,
1418 Link::strength_t drive1) const
0d5e4b4 Structural reduction XNOR.
steve authored
1419 {
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1420 NetScope*scope = des->find_scope(path);
1421 assert(scope);
1422
a9264d7 Unary reduction operators do not set their operand width
steve authored
1423 NetNet* sub_sig = expr_->elaborate_net(des, path,
1424 op_=='~'?width:0,
0d5e4b4 Structural reduction XNOR.
steve authored
1425 0, 0, 0);
1426 if (sub_sig == 0) {
1427 des->errors += 1;
1428 return 0;
1429 }
1430 assert(sub_sig);
1431
1432 NetNet* sig;
1433 NetLogic*gate;
1434 switch (op_) {
1435 case '~': // Bitwise NOT
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1436 sig = new NetNet(scope, des->local_symbol(path), NetNet::WIRE,
0d5e4b4 Structural reduction XNOR.
steve authored
1437 sub_sig->pin_count());
1438 sig->local_flag(true);
1439 for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1) {
1440 gate = new NetLogic(des->local_symbol(path), 2,
1441 NetLogic::NOT);
1442 connect(gate->pin(1), sub_sig->pin(idx));
1443 connect(gate->pin(0), sig->pin(idx));
1444 des->add_node(gate);
1445 gate->rise_time(rise);
1446 gate->fall_time(fall);
1447 gate->decay_time(decay);
1448 }
1449 break;
1450
1451 case 'N': // Reduction NOR
1452 case '!': // Reduction NOT
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1453 sig = new NetNet(scope, des->local_symbol(path), NetNet::WIRE);
0d5e4b4 Structural reduction XNOR.
steve authored
1454 sig->local_flag(true);
1455 gate = new NetLogic(des->local_symbol(path),
1456 1+sub_sig->pin_count(),
1457 NetLogic::NOR);
1458 connect(gate->pin(0), sig->pin(0));
1459 for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
1460 connect(gate->pin(idx+1), sub_sig->pin(idx));
1461
1462 des->add_node(gate);
1463 gate->rise_time(rise);
1464 gate->fall_time(fall);
1465 gate->decay_time(decay);
1466 break;
1467
1468 case '&': // Reduction AND
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1469 sig = new NetNet(scope, des->local_symbol(path), NetNet::WIRE);
0d5e4b4 Structural reduction XNOR.
steve authored
1470 sig->local_flag(true);
1471 gate = new NetLogic(des->local_symbol(path),
1472 1+sub_sig->pin_count(),
1473 NetLogic::AND);
1474 connect(gate->pin(0), sig->pin(0));
1475 for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
1476 connect(gate->pin(idx+1), sub_sig->pin(idx));
1477
1478 des->add_node(gate);
1479 gate->rise_time(rise);
1480 gate->fall_time(fall);
1481 gate->decay_time(decay);
1482 break;
1483
1484 case '|': // Reduction OR
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1485 sig = new NetNet(scope, des->local_symbol(path), NetNet::WIRE);
0d5e4b4 Structural reduction XNOR.
steve authored
1486 sig->local_flag(true);
1487 gate = new NetLogic(des->local_symbol(path),
1488 1+sub_sig->pin_count(),
1489 NetLogic::OR);
1490 connect(gate->pin(0), sig->pin(0));
1491 for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
1492 connect(gate->pin(idx+1), sub_sig->pin(idx));
1493
1494 des->add_node(gate);
1495 gate->rise_time(rise);
1496 gate->fall_time(fall);
1497 gate->decay_time(decay);
1498 break;
1499
1500 case '^': // Reduction XOR
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1501 sig = new NetNet(scope, des->local_symbol(path), NetNet::WIRE);
0d5e4b4 Structural reduction XNOR.
steve authored
1502 sig->local_flag(true);
1503 gate = new NetLogic(des->local_symbol(path),
1504 1+sub_sig->pin_count(),
1505 NetLogic::XOR);
1506 connect(gate->pin(0), sig->pin(0));
1507 for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
1508 connect(gate->pin(idx+1), sub_sig->pin(idx));
1509
1510 des->add_node(gate);
1511 gate->rise_time(rise);
1512 gate->fall_time(fall);
1513 gate->decay_time(decay);
1514 break;
1515
9e5ff89 Add structural reduction NAND,
steve authored
1516 case 'A': // Reduction NAND (~&)
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1517 sig = new NetNet(scope, des->local_symbol(path), NetNet::WIRE);
9e5ff89 Add structural reduction NAND,
steve authored
1518 sig->local_flag(true);
1519 gate = new NetLogic(des->local_symbol(path),
1520 1+sub_sig->pin_count(),
1521 NetLogic::NAND);
1522 connect(gate->pin(0), sig->pin(0));
1523 for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
1524 connect(gate->pin(idx+1), sub_sig->pin(idx));
1525
1526 des->add_node(gate);
1527 gate->rise_time(rise);
1528 gate->fall_time(fall);
1529 gate->decay_time(decay);
1530 break;
1531
1532
1533 case 'X': // Reduction XNOR (~^)
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1534 sig = new NetNet(scope, des->local_symbol(path), NetNet::WIRE);
0d5e4b4 Structural reduction XNOR.
steve authored
1535 sig->local_flag(true);
1536 gate = new NetLogic(des->local_symbol(path),
1537 1+sub_sig->pin_count(),
1538 NetLogic::XNOR);
1539 connect(gate->pin(0), sig->pin(0));
1540 for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
1541 connect(gate->pin(idx+1), sub_sig->pin(idx));
1542
1543 des->add_node(gate);
1544 gate->rise_time(rise);
1545 gate->fall_time(fall);
1546 gate->decay_time(decay);
1547 break;
1548
1549 default:
1550 cerr << "internal error: Unhandled UNARY '" << op_ << "'" << endl;
1551 sig = 0;
1552 }
1553
1554 if (NetTmp*tmp = dynamic_cast<NetTmp*>(sub_sig))
1555 delete tmp;
1556
1557 return sig;
1558 }
1559
cb5fc54 Patch to synthesize unary ~ and the ternary operator.
steve authored
1560 /*
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
1561 * $Log: elab_net.cc,v $
3676d66 Module ports are really special PEIdent
steve authored
1562 * Revision 1.37 2000/05/16 04:05:15 steve
1563 * Module ports are really special PEIdent
1564 * expressions, because a name can be used
1565 * many places in the port list.
1566 *
35a2690 Properly elaborate repeat concatenations.
steve authored
1567 * Revision 1.36 2000/05/07 20:48:14 steve
1568 * Properly elaborate repeat concatenations.
1569 *
ca6631f Fix connection of Direction of LMP_CLSHIFT
steve authored
1570 * Revision 1.35 2000/05/07 19:40:26 steve
1571 * Fix connection of Direction of LMP_CLSHIFT
1572 * to constant values. Remember to add a signal
1573 * to the nexus and connect the receiver in vvm.
1574 *
b90cda1 Carry strength values from Verilog source to the
steve authored
1575 * Revision 1.34 2000/05/07 04:37:56 steve
1576 * Carry strength values from Verilog source to the
1577 * pform and netlist for gates.
1578 *
1579 * Change vvm constants to use the driver_t to drive
1580 * a constant value. This works better if there are
1581 * multiple drivers on a signal.
1582 *
0a70a8a Allow ternary result to be padded to result width.
steve authored
1583 * Revision 1.33 2000/05/03 21:21:36 steve
1584 * Allow ternary result to be padded to result width.
1585 *
69612ce Move memories to the NetScope object.
steve authored
1586 * Revision 1.32 2000/05/02 03:13:31 steve
1587 * Move memories to the NetScope object.
1588 *
8d8f1e2 Move signal tables to the NetScope class.
steve authored
1589 * Revision 1.31 2000/05/02 00:58:11 steve
1590 * Move signal tables to the NetScope class.
1591 *
acfb5c1 Over agressive signal elimination in constant probadation.
steve authored
1592 * Revision 1.30 2000/04/28 21:00:29 steve
1593 * Over agressive signal elimination in constant probadation.
1594 *
694ff93 Add support for integer division.
steve authored
1595 * Revision 1.29 2000/04/01 21:40:22 steve
1596 * Add support for integer division.
1597 *
b9d19d3 Speling error.
steve authored
1598 * Revision 1.28 2000/03/27 04:38:15 steve
1599 * Speling error.
1600 *
3265f3f Remove dangerous tmp signal delete.
steve authored
1601 * Revision 1.27 2000/03/20 17:54:10 steve
1602 * Remove dangerous tmp signal delete.
1603 *
48de739 Switch to control warnings.
steve authored
1604 * Revision 1.26 2000/03/17 21:50:25 steve
1605 * Switch to control warnings.
1606 *
2563e2b Revise the VVM backend to use nexus objects so that
steve authored
1607 * Revision 1.25 2000/03/16 19:03:03 steve
1608 * Revise the VVM backend to use nexus objects so that
1609 * drivers and resolution functions can be used, and
1610 * the t-vvm module doesn't need to write a zillion
1611 * output functions.
1612 *
e7efc27 Redesign the implementation of scopes and parameters.
steve authored
1613 * Revision 1.24 2000/03/08 04:36:53 steve
1614 * Redesign the implementation of scopes and parameters.
1615 * I now generate the scopes and notice the parameters
1616 * in a separate pass over the pform. Once the scopes
1617 * are generated, I can process overrides and evalutate
1618 * paremeters before elaboration begins.
1619 *
b734ecf Macintosh compilers do not support ident.
steve authored
1620 * Revision 1.23 2000/02/23 02:56:54 steve
1621 * Macintosh compilers do not support ident.
1622 *
b354cf6 Fix up width matching in structural bitwise operators.
steve authored
1623 * Revision 1.22 2000/02/16 03:58:27 steve
1624 * Fix up width matching in structural bitwise operators.
1625 *
a9264d7 Unary reduction operators do not set their operand width
steve authored
1626 * Revision 1.21 2000/02/14 06:04:52 steve
1627 * Unary reduction operators do not set their operand width
1628 *
57d28e4 Support structural XNOR.
steve authored
1629 * Revision 1.20 2000/01/18 04:53:40 steve
1630 * Support structural XNOR.
1631 *
aa8908c Multiplication all the way to simulation.
steve authored
1632 * Revision 1.19 2000/01/13 03:35:35 steve
1633 * Multiplication all the way to simulation.
1634 *
3d1ffce Elaborate net widths of constants to as small
steve authored
1635 * Revision 1.18 2000/01/11 04:20:57 steve
1636 * Elaborate net widths of constants to as small
1637 * as is possible, obeying context constraints.
1638 *
1639 * Comparison operators can handle operands with
1640 * different widths.
1641 *
ba7fdb5 Add a signal to nexus of padding constant.
steve authored
1642 * Revision 1.17 2000/01/02 22:07:09 steve
1643 * Add a signal to nexus of padding constant.
1644 *
9e5ff89 Add structural reduction NAND,
steve authored
1645 * Revision 1.16 2000/01/02 21:45:31 steve
1646 * Add structural reduction NAND,
1647 * Fix size coercion of structural shifts.
1648 *
0d5e4b4 Structural reduction XNOR.
steve authored
1649 * Revision 1.15 2000/01/02 19:39:03 steve
1650 * Structural reduction XNOR.
1651 *
65ae928 NetConst can now hold wide constants.
steve authored
1652 * Revision 1.14 1999/12/17 03:38:46 steve
1653 * NetConst can now hold wide constants.
1654 *
ced7cc6 Structural logical or.
steve authored
1655 * Revision 1.13 1999/12/16 03:46:39 steve
1656 * Structural logical or.
1657 *
d54cc14 Simulate carry output on adders.
steve authored
1658 * Revision 1.12 1999/12/16 02:42:14 steve
1659 * Simulate carry output on adders.
1660 *
cdb99e7 Elaborate net repeat concatenations.
steve authored
1661 * Revision 1.11 1999/12/02 04:08:10 steve
1662 * Elaborate net repeat concatenations.
1663 *
80b8ea9 Put implicitly defined signals in the scope.
steve authored
1664 * Revision 1.10 1999/11/30 04:33:41 steve
1665 * Put implicitly defined signals in the scope.
1666 *
4cfa3e4 Support the creation of scopes.
steve authored
1667 * Revision 1.9 1999/11/27 19:07:57 steve
1668 * Support the creation of scopes.
1669 *
4cfa715 Memory name lookup handles scopes.
steve authored
1670 * Revision 1.8 1999/11/21 17:35:37 steve
1671 * Memory name lookup handles scopes.
1672 *
a81dcd7 Support memories in continuous assignments.
steve authored
1673 * Revision 1.7 1999/11/21 00:13:08 steve
1674 * Support memories in continuous assignments.
1675 *
513ade9 Support combinatorial comparators.
steve authored
1676 * Revision 1.6 1999/11/14 23:43:45 steve
1677 * Support combinatorial comparators.
1678 *
1624afe Add support for the LPM_CLSHIFT device.
steve authored
1679 * Revision 1.5 1999/11/14 20:24:28 steve
1680 * Add support for the LPM_CLSHIFT device.
1681 *
5171846 Forgot to return the mux for use after elaboration.
steve authored
1682 * Revision 1.4 1999/11/05 23:36:31 steve
1683 * Forgot to return the mux for use after elaboration.
1684 *
206b37e Fix NetConst being set to zero width, and clean
steve authored
1685 * Revision 1.3 1999/11/05 21:45:19 steve
1686 * Fix NetConst being set to zero width, and clean
1687 * up elaborate_set_cmp_ for NetEBinary.
1688 *
cb5fc54 Patch to synthesize unary ~ and the ternary operator.
steve authored
1689 * Revision 1.2 1999/11/04 03:53:26 steve
1690 * Patch to synthesize unary ~ and the ternary operator.
1691 * Thanks to Larry Doolittle <LRDoolittle@lbl.gov>.
1692 *
1693 * Add the LPM_MUX device, and integrate it with the
1694 * ternary synthesis from Larry. Replace the lpm_mux
1695 * generator in t-xnf.cc to use XNF EQU devices to
1696 * put muxs into function units.
1697 *
1698 * Rewrite elaborate_net for the PETernary class to
1699 * also use the LPM_MUX device.
1700 *
e1bbbe5 Include subtraction in LPM_ADD_SUB device.
steve authored
1701 * Revision 1.1 1999/10/31 20:08:24 steve
1702 * Include subtraction in LPM_ADD_SUB device.
1703 *
1704 */
1705
Something went wrong with that request. Please try again.