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