1 /*
2 * Copyright (c) 2003-2010 Stephen Williams (steve@icarus.com)
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20 # include "device.h"
21 # include "fpga_priv.h"
22 # include "edif.h"
23 # include "generic.h"
24 # include "xilinx.h"
25 # include <stdlib.h>
26 # include <string.h>
27 # include <assert.h>
28
29 /*
30 * This is a table of cell types that are accessible via the cellref
31 * attribute to a gate.
32 */
33 const static struct edif_xlib_celltable virtex_celltable[] = {
34 { "BUFG", xilinx_cell_bufg },
35 { "MULT_AND", xilinx_cell_mult_and },
36 { 0, 0}
37 };
38
39 /*
40 * The show_header function is called before any of the devices of the
41 * netlist are scanned.
42 *
43 * In this function, we look at the ports of the root module to decide
44 * if they are to be made into ports. Modules that have PAD attributes
45 * are *not* to be used as ports, they will be connected to special
46 * PAD devices instead.
47 */
virtex_show_header(ivl_design_t des)48 static void virtex_show_header(ivl_design_t des)
49 {
50 const char*part_str = 0;
51
52 xilinx_common_header(des);
53
54 xlib = edif_xlibrary_create(edf, "VIRTEX");
55 edif_xlibrary_set_celltable(xlib, virtex_celltable);
56
57
58 if ( (part_str = ivl_design_flag(des, "part")) && (part_str[0] != 0) ) {
59 edif_pstring(edf, "PART", part_str);
60 }
61
62 cell_0 = edif_xcell_create(xlib, "GND", 1);
63 edif_cell_portconfig(cell_0, 0, "GROUND", IVL_SIP_OUTPUT);
64
65 cell_1 = edif_xcell_create(xlib, "VCC", 1);
66 edif_cell_portconfig(cell_1, 0, "VCC", IVL_SIP_OUTPUT);
67
68 }
69
virtex_or_wide(ivl_net_logic_t net)70 static void virtex_or_wide(ivl_net_logic_t net)
71 {
72 edif_cell_t cell_muxcy_l = xilinx_cell_muxcy_l(xlib);
73 edif_cell_t cell_muxcy = xilinx_cell_muxcy(xlib);
74 edif_cell_t cell_lut4 = xilinx_cell_lut4(xlib);
75
76 edif_cellref_t true_out, false_out;
77 edif_cellref_t lut, muxcy, muxcy_down=NULL;
78 edif_joint_t jnt;
79
80 unsigned idx, inputs, lut4_cnt;
81
82 if (ivl_logic_type(net) == IVL_LO_OR) {
83 true_out = edif_cellref_create(edf, cell_1);
84 false_out = edif_cellref_create(edf, cell_0);
85 } else {
86 true_out = edif_cellref_create(edf, cell_0);
87 false_out = edif_cellref_create(edf, cell_1);
88 }
89
90 inputs = ivl_logic_pins(net) - 1;
91 lut4_cnt = (inputs-1)/4;
92
93 for (idx = 0 ; idx < lut4_cnt ; idx += 1) {
94 muxcy = edif_cellref_create(edf, cell_muxcy_l);
95 lut = edif_cellref_create(edf, cell_lut4);
96
97 edif_cellref_pstring(lut, "INIT", "0001");
98
99 jnt = edif_joint_create(edf);
100 edif_add_to_joint(jnt, lut, LUT_O);
101 edif_add_to_joint(jnt, muxcy, MUXCY_S);
102
103 jnt = edif_joint_create(edf);
104 edif_add_to_joint(jnt, true_out, 0);
105 edif_add_to_joint(jnt, muxcy, MUXCY_DI);
106
107 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx*4+1+0));
108 edif_add_to_joint(jnt, lut, LUT_I0);
109
110 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx*4+1+1));
111 edif_add_to_joint(jnt, lut, LUT_I1);
112
113 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx*4+1+2));
114 edif_add_to_joint(jnt, lut, LUT_I2);
115
116 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx*4+1+3));
117 edif_add_to_joint(jnt, lut, LUT_I3);
118
119 if (idx > 0) {
120 jnt = edif_joint_create(edf);
121 edif_add_to_joint(jnt, muxcy, MUXCY_CI);
122 edif_add_to_joint(jnt, muxcy_down, MUXCY_O);
123 } else {
124 jnt = edif_joint_create(edf);
125 edif_add_to_joint(jnt, muxcy, MUXCY_CI);
126 edif_add_to_joint(jnt, false_out, 0);
127 }
128
129 muxcy_down = muxcy;
130 }
131
132 muxcy = edif_cellref_create(edf, cell_muxcy);
133 jnt = edif_joint_create(edf);
134 edif_add_to_joint(jnt, true_out, 0);
135 edif_add_to_joint(jnt, muxcy, MUXCY_DI);
136
137 jnt = edif_joint_create(edf);
138 edif_add_to_joint(jnt, muxcy, MUXCY_CI);
139 edif_add_to_joint(jnt, muxcy_down, MUXCY_O);
140
141 switch (ivl_logic_pins(net) - 1 - lut4_cnt*4) {
142
143 case 1:
144 lut = edif_cellref_create(edf, xilinx_cell_inv(xlib));
145
146 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+0));
147 edif_add_to_joint(jnt, lut, BUF_I);
148 break;
149
150 case 2:
151 lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
152
153 edif_cellref_pstring(lut, "INIT", "1");
154
155 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+0));
156 edif_add_to_joint(jnt, lut, LUT_I0);
157
158 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+1));
159 edif_add_to_joint(jnt, lut, LUT_I1);
160 break;
161
162 case 3:
163 lut = edif_cellref_create(edf, xilinx_cell_lut3(xlib));
164
165 edif_cellref_pstring(lut, "INIT", "01");
166
167 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+0));
168 edif_add_to_joint(jnt, lut, LUT_I0);
169
170 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+1));
171 edif_add_to_joint(jnt, lut, LUT_I1);
172
173 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+2));
174 edif_add_to_joint(jnt, lut, LUT_I2);
175 break;
176
177 case 4:
178 lut = edif_cellref_create(edf, cell_lut4);
179
180 edif_cellref_pstring(lut, "INIT", "0001");
181
182 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+0));
183 edif_add_to_joint(jnt, lut, LUT_I0);
184
185 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+1));
186 edif_add_to_joint(jnt, lut, LUT_I1);
187
188 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+2));
189 edif_add_to_joint(jnt, lut, LUT_I2);
190
191 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+3));
192 edif_add_to_joint(jnt, lut, LUT_I3);
193 break;
194
195 default:
196 assert(0);
197 }
198
199 jnt = edif_joint_create(edf);
200 edif_add_to_joint(jnt, lut, LUT_O);
201 edif_add_to_joint(jnt, muxcy, MUXCY_S);
202
203 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0));
204 edif_add_to_joint(jnt, muxcy, MUXCY_O);
205 }
206
207 /*
208 * Pick off the cases where there is a Virtex specific implementation
209 * that is better than the generic Xilinx implementation. Route the
210 * remaining to the base xilinx_logic implementation.
211 */
virtex_logic(ivl_net_logic_t net)212 void virtex_logic(ivl_net_logic_t net)
213 {
214 /* Nothing I can do if the user expresses a specific
215 opinion. The cellref attribute forces me to let the base
216 xilinx_logic take care of it. */
217 if (ivl_logic_attr(net, "cellref")) {
218 xilinx_logic(net);
219 return;
220 }
221
222 switch (ivl_logic_type(net)) {
223
224 case IVL_LO_OR:
225 case IVL_LO_NOR:
226 if (ivl_logic_pins(net) <= 5) {
227 xilinx_logic(net);
228
229 } else {
230 virtex_or_wide(net);
231 }
232 break;
233
234 default:
235 xilinx_logic(net);
236 break;
237 }
238 }
239
virtex_generic_dff(ivl_lpm_t net)240 void virtex_generic_dff(ivl_lpm_t net)
241 {
242 unsigned idx;
243
244 ivl_nexus_t aclr = ivl_lpm_async_clr(net);
245 ivl_nexus_t aset = ivl_lpm_async_set(net);
246 ivl_nexus_t sclr = ivl_lpm_sync_clr(net);
247 ivl_nexus_t sset = ivl_lpm_sync_set(net);
248 const char*abits = 0;
249
250 if (aset) {
251 ivl_expr_t avalue = ivl_lpm_aset_value(net);
252 assert(avalue);
253 abits = ivl_expr_bits(avalue);
254 assert(abits);
255 }
256
257 /* XXXX Can't handle both synchronous and asynchronous clear. */
258 assert( ! (aclr && sclr) );
259 /* XXXX Can't handle synchronous set at all. */
260 assert( ! sset );
261
262 for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) {
263 edif_cellref_t obj;
264 ivl_nexus_t nex;
265 edif_joint_t jnt;
266
267 /* If there is a preset, then select an FDCPE instead of
268 an FDCE device. */
269 if (aset && (abits[idx] == '1')) {
270 obj = edif_cellref_create(edf, xilinx_cell_fdcpe(xlib));
271 } else if (aclr) {
272 obj = edif_cellref_create(edf, xilinx_cell_fdce(xlib));
273 } else if (sclr) {
274 obj = edif_cellref_create(edf, xilinx_cell_fdre(xlib));
275 } else {
276 obj = edif_cellref_create(edf, xilinx_cell_fdce(xlib));
277 }
278
279
280 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx));
281 edif_add_to_joint(jnt, obj, FDCE_Q);
282
283 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, idx));
284 edif_add_to_joint(jnt, obj, FDCE_D);
285
286 jnt = edif_joint_of_nexus(edf, ivl_lpm_clk(net));
287 edif_add_to_joint(jnt, obj, FDCE_C);
288
289 if ( (nex = ivl_lpm_enable(net)) ) {
290 jnt = edif_joint_of_nexus(edf, nex);
291 edif_add_to_joint(jnt, obj, FDCE_CE);
292 }
293
294 if (aclr) {
295 jnt = edif_joint_of_nexus(edf, aclr);
296 edif_add_to_joint(jnt, obj, FDCE_CLR);
297 } else if (sclr) {
298 jnt = edif_joint_of_nexus(edf, sclr);
299 edif_add_to_joint(jnt, obj, FDCE_CLR);
300 }
301
302 if (aset) {
303 if (abits[idx] == '1') {
304 jnt = edif_joint_of_nexus(edf, aset);
305 edif_add_to_joint(jnt, obj, FDCE_PRE);
306 } else {
307 assert(aclr == 0);
308 jnt = edif_joint_of_nexus(edf, aset);
309 edif_add_to_joint(jnt, obj, FDCE_CLR);
310 }
311 }
312 }
313 }
314
315 /*
316 * This method handles both == and != operators, the identity
317 * comparison operators.
318 *
319 * If the identity compare is applied to small enough input vectors,
320 * it is shoved into a single LUT. Otherwise, it is strung out into a
321 * row of LUT devices chained together by carry muxes. The output of
322 * the comparison is the output of the last mux.
323 *
324 * When the compare is small, a LUT is generated with the appropriate
325 * truth table to cause an == or != result.
326 *
327 * When the compare is too wide for a single LUT, then it is made into
328 * a chain connected by a string of carry mux devices. Each LUT
329 * implements == for up to two pairs of bits, even if the final output
330 * is supposed to be !=. The LUT output is connected to an associated
331 * MUX select input. The CO output of each muxcy is passed up to the
332 * next higher order bits of the compare.
333 *
334 * For identity == compare, a != output from the LUT selects the DI
335 * input of the muxcy, generating a 0 output that is passed up. Since
336 * the next higher muxcy now gets a 0 input to both DI and CI, the
337 * output of the next higher muxcy is guaranteed to be 0, and so on to
338 * the final output of the carry chain. If the output from a LUT is ==,
339 * then the CI input of the muxcy is selected and the truth of this
340 * level depends on lower order bits. The least significant muxcy is
341 * connected to GND and VCC so that its CO follows the least
342 * significant LUT.
343 *
344 * Identity != is the same as == except that the output is
345 * inverted. To get that effect without putting an inverter on the
346 * output of the top muxcy pin CO (which would cost a LUT) the DI
347 * inputs are all connected to VCC instead of GND, and the CI of the
348 * least significant muxcy is connected to GND instead of VCC. The LUT
349 * expressions for the chained compare are configured for ==, with the
350 * changed CI/DI inputs performing the inversion.
351 */
virtex_eq(ivl_lpm_t net)352 void virtex_eq(ivl_lpm_t net)
353 {
354 edif_cellref_t lut, mux, mux_prev;
355 edif_joint_t jnt, jnt_di;
356 unsigned idx;
357
358 /* True if I'm implementing CMP_EQ instead of CMP_NE */
359 int eq = 1;
360
361 assert(ivl_lpm_width(net) >= 1);
362
363 if (ivl_lpm_type(net) == IVL_LPM_CMP_NE)
364 eq = 0;
365
366 switch (ivl_lpm_width(net)) {
367
368 case 1:
369 lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
370 edif_cellref_pstring(lut, "INIT", eq? "9" : "6");
371
372 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0));
373 edif_add_to_joint(jnt, lut, LUT_O);
374
375 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0));
376 edif_add_to_joint(jnt, lut, LUT_I0);
377
378 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0));
379 edif_add_to_joint(jnt, lut, LUT_I1);
380 return;
381
382 case 2:
383 lut = edif_cellref_create(edf, xilinx_cell_lut4(xlib));
384 edif_cellref_pstring(lut, "INIT", eq? "9009" : "6FF6");
385
386 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0));
387 edif_add_to_joint(jnt, lut, LUT_O);
388
389 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0));
390 edif_add_to_joint(jnt, lut, LUT_I0);
391
392 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0));
393 edif_add_to_joint(jnt, lut, LUT_I1);
394
395 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 1));
396 edif_add_to_joint(jnt, lut, LUT_I2);
397
398 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 1));
399 edif_add_to_joint(jnt, lut, LUT_I3);
400 return;
401
402 default:
403 { edif_cellref_t di;
404 di = edif_cellref_create(edf, eq? cell_0 : cell_1);
405 jnt_di = edif_joint_create(edf);
406 edif_add_to_joint(jnt_di, di, 0);
407 }
408
409 mux_prev = 0;
410 for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 2) {
411 int subwid = 2;
412 if ((idx + 1) == ivl_lpm_width(net))
413 subwid = 1;
414
415 mux = edif_cellref_create(edf, xilinx_cell_muxcy(xlib));
416 if (subwid == 2) {
417 lut = edif_cellref_create(edf, xilinx_cell_lut4(xlib));
418 edif_cellref_pstring(lut, "INIT", "9009");
419 } else {
420 lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
421 edif_cellref_pstring(lut, "INIT", "9");
422 }
423
424 jnt = edif_joint_create(edf);
425 edif_add_to_joint(jnt, lut, LUT_O);
426 edif_add_to_joint(jnt, mux, MUXCY_S);
427
428 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, idx));
429 edif_add_to_joint(jnt, lut, LUT_I0);
430
431 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, idx));
432 edif_add_to_joint(jnt, lut, LUT_I1);
433
434 if (subwid > 1) {
435 jnt = edif_joint_of_nexus(edf,
436 ivl_lpm_data(net, idx+1));
437 edif_add_to_joint(jnt, lut, LUT_I2);
438
439 jnt = edif_joint_of_nexus(edf,
440 ivl_lpm_datab(net, idx+1));
441 edif_add_to_joint(jnt, lut, LUT_I3);
442 }
443
444 edif_add_to_joint(jnt_di, mux, MUXCY_DI);
445
446 if (mux_prev) {
447 jnt = edif_joint_create(edf);
448 edif_add_to_joint(jnt, mux, MUXCY_CI);
449 edif_add_to_joint(jnt, mux_prev, MUXCY_O);
450 } else {
451 edif_cellref_t ci;
452 ci = edif_cellref_create(edf, eq? cell_1 : cell_0);
453 jnt = edif_joint_create(edf);
454 edif_add_to_joint(jnt, ci, 0);
455 edif_add_to_joint(jnt, mux, MUXCY_CI);
456 }
457
458 mux_prev = mux;
459 }
460
461 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0));
462 edif_add_to_joint(jnt, mux_prev, MUXCY_O);
463 return;
464 }
465 }
466
467 /*
468 * Implement hardware for the device (A >= B). We use LUT devices if
469 * it can handle the slices, or carry chain logic if the slices must
470 * span LUT devices.
471 */
virtex_ge(ivl_lpm_t net)472 void virtex_ge(ivl_lpm_t net)
473 {
474 edif_cellref_t muxcy_prev;
475 edif_cellref_t lut;
476 edif_joint_t jnt;
477 unsigned idx;
478
479 if (ivl_lpm_width(net) == 1) {
480
481 /* If the comparator is a single bit, then use a LUT2
482 with this truth table:
483
484 Q A B
485 --+----
486 1 | 0 0
487 0 | 0 1
488 1 | 1 0
489 1 | 1 1
490
491 Connect the A value to I1 and the B value to I0. */
492
493 lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
494 edif_cellref_pstring(lut, "INIT", "D");
495
496 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0));
497 edif_add_to_joint(jnt, lut, LUT_O);
498
499 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0));
500 edif_add_to_joint(jnt, lut, LUT_I1);
501
502 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0));
503 edif_add_to_joint(jnt, lut, LUT_I2);
504 return;
505 }
506
507 /* Handle the case where the device is two slices
508 wide. In this case, we can use a LUT4 to do all
509 the calculation. Use this truth table:
510
511 Q AA BB
512 --+------
513 1 | 00 00
514 0 | 00 01
515 0 | 00 10
516 0 | 00 11
517 1 | 01 00
518 1 | 01 01
519 0 | 01 10
520 0 | 01 11
521 1 | 10 00
522 1 | 10 01
523 1 | 10 10
524 0 | 10 11
525 1 | 11 xx
526
527 The I3-I0 inputs are A1 A0 B1 B0 in that order. */
528
529 assert(ivl_lpm_width(net) >= 2);
530
531 lut = edif_cellref_create(edf, xilinx_cell_lut4(xlib));
532 edif_cellref_pstring(lut, "INIT", "F731");
533
534 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0));
535 edif_add_to_joint(jnt, lut, LUT_I2);
536
537 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0));
538 edif_add_to_joint(jnt, lut, LUT_I0);
539
540 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 1));
541 edif_add_to_joint(jnt, lut, LUT_I3);
542
543 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 1));
544 edif_add_to_joint(jnt, lut, LUT_I1);
545
546 /* There are only two slices, so this is all we need. */
547 if (ivl_lpm_width(net) == 2) {
548 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0));
549 edif_add_to_joint(jnt, lut, LUT_O);
550 return;
551 }
552
553 /* The general case requires that we make the >= comparator
554 from slices. This is an iterative design. Each slice has
555 the truth table:
556
557 An Bn | A >= B
558 ------+-------
559 0 0 | CI
560 0 1 | 0
561 1 0 | 1
562 1 1 | CI
563
564 The CI for each slice is the output of the compare of the
565 next less significant bits. We get this truth table by
566 connecting a LUT2 to the S input of a MUXCY. When the S
567 input is (1), it propagates its CI. This suggests that the
568 init value for the LUT be "9" (XNOR).
569
570 When the MUXCY S input is 0, it propagates a local
571 input. We connect to that input An, and we get the desired
572 and complete truth table for a slice.
573
574 This iterative definition needs to terminate at the least
575 significant bits. In fact, we have a non-iterative was to
576 deal with the two least significant slices. We take the
577 output of the LUT4 device for the least significant bits,
578 and use that to generate the initial CI for the chain. */
579
580
581 muxcy_prev = edif_cellref_create(edf, xilinx_cell_muxcy_l(xlib));
582 jnt = edif_joint_create(edf);
583
584 edif_add_to_joint(jnt, lut, LUT_O);
585 edif_add_to_joint(jnt, muxcy_prev, MUXCY_S);
586 { edif_cellref_t p0 = edif_cellref_create(edf, cell_0);
587 edif_cellref_t p1 = edif_cellref_create(edf, cell_1);
588
589 jnt = edif_joint_create(edf);
590 edif_add_to_joint(jnt, p0, 0);
591 edif_add_to_joint(jnt, muxcy_prev, MUXCY_DI);
592
593 jnt = edif_joint_create(edf);
594 edif_add_to_joint(jnt, p1, 0);
595 edif_add_to_joint(jnt, muxcy_prev, MUXCY_CI);
596 }
597
598 for (idx = 2 ; idx < ivl_lpm_width(net) ; idx += 1) {
599 edif_cellref_t muxcy;
600
601 lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
602 muxcy = edif_cellref_create(edf, xilinx_cell_muxcy(xlib));
603 edif_cellref_pstring(lut, "INIT", "9");
604
605 jnt = edif_joint_create(edf);
606 edif_add_to_joint(jnt, lut, LUT_O);
607 edif_add_to_joint(jnt, muxcy, MUXCY_S);
608
609 jnt = edif_joint_create(edf);
610 edif_add_to_joint(jnt, muxcy, MUXCY_CI);
611 edif_add_to_joint(jnt, muxcy_prev, MUXCY_O);
612
613 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, idx));
614 edif_add_to_joint(jnt, lut, LUT_I0);
615 edif_add_to_joint(jnt, muxcy, MUXCY_DI);
616
617 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, idx));
618 edif_add_to_joint(jnt, lut, LUT_I1);
619
620 muxcy_prev = muxcy;
621 }
622
623 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0));
624 edif_add_to_joint(jnt, muxcy_prev, MUXCY_O);
625 }
626
627 /*
628 * A 4-input N-wide mux can be made on Virtex devices using MUXF5 and
629 * LUT devices. The MUXF5 selects a LUT device (and is connected to
630 * S[1]) and the LUT devices, connected to S[0], select the input.
631 */
virtex_mux4(ivl_lpm_t net)632 static void virtex_mux4(ivl_lpm_t net)
633 {
634 unsigned idx;
635 assert(ivl_lpm_selects(net) == 2);
636
637 for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) {
638 edif_joint_t jnt;
639 edif_cellref_t lut01;
640 edif_cellref_t lut23;
641 edif_cellref_t muxf5;
642
643 lut01 = edif_cellref_create(edf, xilinx_cell_lut3(xlib));
644 edif_cellref_pstring(lut01, "INIT", "CA");
645
646 lut23 = edif_cellref_create(edf, xilinx_cell_lut3(xlib));
647 edif_cellref_pstring(lut23, "INIT", "CA");
648
649 muxf5 = edif_cellref_create(edf, xilinx_cell_muxf5(xlib));
650
651 jnt = edif_joint_of_nexus(edf, ivl_lpm_data2(net, 0, idx));
652 edif_add_to_joint(jnt, lut01, LUT_I0);
653
654 jnt = edif_joint_of_nexus(edf, ivl_lpm_data2(net, 1, idx));
655 edif_add_to_joint(jnt, lut01, LUT_I1);
656
657 jnt = edif_joint_of_nexus(edf, ivl_lpm_data2(net, 2, idx));
658 edif_add_to_joint(jnt, lut23, LUT_I0);
659
660 jnt = edif_joint_of_nexus(edf, ivl_lpm_data2(net, 3, idx));
661 edif_add_to_joint(jnt, lut23, LUT_I1);
662
663 jnt = edif_joint_of_nexus(edf, ivl_lpm_select(net, 0));
664 edif_add_to_joint(jnt, lut01, LUT_I2);
665 edif_add_to_joint(jnt, lut23, LUT_I2);
666
667 jnt = edif_joint_create(edf);
668 edif_add_to_joint(jnt, muxf5, MUXF_I0);
669 edif_add_to_joint(jnt, lut01, LUT_O);
670
671 jnt = edif_joint_create(edf);
672 edif_add_to_joint(jnt, muxf5, MUXF_I1);
673 edif_add_to_joint(jnt, lut23, LUT_O);
674
675 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx));
676 edif_add_to_joint(jnt, muxf5, MUXF_O);
677
678 jnt = edif_joint_of_nexus(edf, ivl_lpm_select(net, 1));
679 edif_add_to_joint(jnt, muxf5, MUXF_S);
680 }
681 }
682
virtex_mux(ivl_lpm_t net)683 void virtex_mux(ivl_lpm_t net)
684 {
685
686 switch (ivl_lpm_selects(net)) {
687
688 case 2:
689 virtex_mux4(net);
690 break;
691
692 default:
693 xilinx_mux(net);
694 break;
695 }
696 }
697
698 /*
699 * This function generates ADD/SUB devices for Virtex devices,
700 * based on the documented implementations of ADD8/ADD16, etc., from
701 * the Libraries Guide.
702 *
703 * Each slice of the ADD/SUB device is made from a LUT2 device, an
704 * XORCY device that mixes with the LUT2 to make a full adder, and a
705 * MUXCY_L to propagate the carry. The most significant slice does not
706 * have a carry to propagate, so has no MUXCY_L.
707 *
708 * If the device is a wide adder, then the LUT2 devices are configured
709 * to implement an XOR function and a zero is pumped into the least
710 * significant carry input.
711 *
712 * If the device is really an adder, then the input is turned into an
713 * XNOR, which takes a 1-s complement of the B input. Pump a 1 into
714 * the LSB carry input to finish converting the B input into the 2s
715 * complement.
716 */
virtex_add(ivl_lpm_t net)717 void virtex_add(ivl_lpm_t net)
718 {
719 const char*ha_init = 0;
720 edif_cellref_t lut, xorcy, muxcy, pad;
721 edif_joint_t jnt;
722
723 unsigned idx;
724
725 if (ivl_lpm_width(net) < 2) {
726 xilinx_add(net);
727 return;
728 }
729
730 switch (ivl_lpm_type(net)) {
731 case IVL_LPM_ADD:
732 ha_init = "6";
733 break;
734 case IVL_LPM_SUB:
735 ha_init = "9";
736 break;
737 default:
738 assert(0);
739 }
740
741 assert(ivl_lpm_width(net) > 1);
742
743 lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
744 xorcy = edif_cellref_create(edf, xilinx_cell_xorcy(xlib));
745 muxcy = edif_cellref_create(edf, xilinx_cell_muxcy_l(xlib));
746 edif_cellref_pstring(lut, "INIT", ha_init);
747
748 /* The bottom carry-in takes a constant that primes the add or
749 subtract. */
750 switch (ivl_lpm_type(net)) {
751 case IVL_LPM_ADD:
752 pad = edif_cellref_create(edf, cell_0);
753 break;
754
755 case IVL_LPM_SUB:
756 pad = edif_cellref_create(edf, cell_1);
757 break;
758
759 default:
760 assert(0);
761 }
762
763 jnt = edif_joint_create(edf);
764 edif_add_to_joint(jnt, pad, 0);
765 edif_add_to_joint(jnt, muxcy, MUXCY_CI);
766 edif_add_to_joint(jnt, xorcy, XORCY_CI);
767
768 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0));
769 edif_add_to_joint(jnt, xorcy, XORCY_O);
770
771 jnt = edif_joint_create(edf);
772 edif_add_to_joint(jnt, xorcy, XORCY_LI);
773 edif_add_to_joint(jnt, muxcy, MUXCY_S);
774 edif_add_to_joint(jnt, lut, LUT_O);
775
776 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0));
777 edif_add_to_joint(jnt, lut, LUT_I0);
778 edif_add_to_joint(jnt, muxcy, MUXCY_DI);
779
780 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0));
781 edif_add_to_joint(jnt, lut, LUT_I1);
782
783 for (idx = 1 ; idx < ivl_lpm_width(net) ; idx += 1) {
784 edif_cellref_t muxcy0 = muxcy;
785
786 lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
787 xorcy = edif_cellref_create(edf, xilinx_cell_xorcy(xlib));
788 edif_cellref_pstring(lut, "INIT", ha_init);
789
790 /* If this is the last bit, then there is no further
791 propagation in the carry chain, and I can skip the
792 carry mux MUXCY. */
793 if ((idx+1) < ivl_lpm_width(net))
794 muxcy = edif_cellref_create(edf, xilinx_cell_muxcy_l(xlib));
795 else
796 muxcy = 0;
797
798 jnt = edif_joint_create(edf);
799 edif_add_to_joint(jnt, muxcy0, MUXCY_O);
800 edif_add_to_joint(jnt, xorcy, XORCY_CI);
801 if (muxcy) edif_add_to_joint(jnt, muxcy, MUXCY_CI);
802
803 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx));
804 edif_add_to_joint(jnt, xorcy, XORCY_O);
805
806 jnt = edif_joint_create(edf);
807 edif_add_to_joint(jnt, xorcy, XORCY_LI);
808 if (muxcy) edif_add_to_joint(jnt, muxcy, MUXCY_S);
809 edif_add_to_joint(jnt, lut, LUT_O);
810
811 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, idx));
812 edif_add_to_joint(jnt, lut, LUT_I0);
813 if (muxcy) edif_add_to_joint(jnt, muxcy, MUXCY_DI);
814
815 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, idx));
816 edif_add_to_joint(jnt, lut, LUT_I1);
817 }
818
819 }
820
821
822 const struct device_s d_virtex_edif = {
823 virtex_show_header,
824 xilinx_show_footer,
825 xilinx_show_scope,
826 xilinx_pad,
827 virtex_logic,
828 virtex_generic_dff,
829 virtex_eq,
830 virtex_eq,
831 virtex_ge,
832 0, /* show_cmp_gt */
833 virtex_mux,
834 virtex_add,
835 virtex_add,
836 xilinx_shiftl,
837 0 /* show_shiftr */
838 };
839