Fix for assertion error when expanding macro.
[iverilog.git] / tgt-fpga / d-virtex.c
blob11b12ebc6210dbdc28a6fd8f757c238204ebf9a1
1 /*
2 * Copyright (c) 2003 Stephen Williams (steve@icarus.com)
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.
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.
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
19 #ifdef HAVE_CVS_IDENT
20 #ident "$Id: d-virtex.c,v 1.35 2004/10/04 01:10:56 steve Exp $"
21 #endif
23 # include "device.h"
24 # include "fpga_priv.h"
25 # include "edif.h"
26 # include "generic.h"
27 # include "xilinx.h"
28 # include <stdlib.h>
29 # include <string.h>
30 #ifdef HAVE_MALLOC_H
31 # include <malloc.h>
32 #endif
33 # include <assert.h>
36 * This is a table of cell types that are accessible via the cellref
37 * attribute to a gate.
39 const static struct edif_xlib_celltable virtex_celltable[] = {
40 { "BUFG", xilinx_cell_bufg },
41 { "MULT_AND", xilinx_cell_mult_and },
42 { 0, 0}
46 * The show_header function is called before any of the devices of the
47 * netlist are scanned.
49 * In this function, we look at the ports of the root module to decide
50 * if they are to be made into ports. Modules that have PAD attributes
51 * are *not* to be used as ports, they will be connected to special
52 * PAD devices instead.
54 static void virtex_show_header(ivl_design_t des)
56 const char*part_str = 0;
58 xilinx_common_header(des);
60 xlib = edif_xlibrary_create(edf, "VIRTEX");
61 edif_xlibrary_set_celltable(xlib, virtex_celltable);
64 if ( (part_str = ivl_design_flag(des, "part")) && (part_str[0] != 0) ) {
65 edif_pstring(edf, "PART", part_str);
68 cell_0 = edif_xcell_create(xlib, "GND", 1);
69 edif_cell_portconfig(cell_0, 0, "GROUND", IVL_SIP_OUTPUT);
71 cell_1 = edif_xcell_create(xlib, "VCC", 1);
72 edif_cell_portconfig(cell_1, 0, "VCC", IVL_SIP_OUTPUT);
76 static void virtex_or_wide(ivl_net_logic_t net)
78 edif_cell_t cell_muxcy_l = xilinx_cell_muxcy_l(xlib);
79 edif_cell_t cell_muxcy = xilinx_cell_muxcy(xlib);
80 edif_cell_t cell_lut4 = xilinx_cell_lut4(xlib);
82 edif_cellref_t true_out, false_out;
83 edif_cellref_t lut, muxcy, muxcy_down=NULL;
84 edif_joint_t jnt;
86 unsigned idx, inputs, lut4_cnt;
88 if (ivl_logic_type(net) == IVL_LO_OR) {
89 true_out = edif_cellref_create(edf, cell_1);
90 false_out = edif_cellref_create(edf, cell_0);
91 } else {
92 true_out = edif_cellref_create(edf, cell_0);
93 false_out = edif_cellref_create(edf, cell_1);
96 inputs = ivl_logic_pins(net) - 1;
97 lut4_cnt = (inputs-1)/4;
99 for (idx = 0 ; idx < lut4_cnt ; idx += 1) {
100 muxcy = edif_cellref_create(edf, cell_muxcy_l);
101 lut = edif_cellref_create(edf, cell_lut4);
103 edif_cellref_pstring(lut, "INIT", "0001");
105 jnt = edif_joint_create(edf);
106 edif_add_to_joint(jnt, lut, LUT_O);
107 edif_add_to_joint(jnt, muxcy, MUXCY_S);
109 jnt = edif_joint_create(edf);
110 edif_add_to_joint(jnt, true_out, 0);
111 edif_add_to_joint(jnt, muxcy, MUXCY_DI);
113 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx*4+1+0));
114 edif_add_to_joint(jnt, lut, LUT_I0);
116 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx*4+1+1));
117 edif_add_to_joint(jnt, lut, LUT_I1);
119 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx*4+1+2));
120 edif_add_to_joint(jnt, lut, LUT_I2);
122 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx*4+1+3));
123 edif_add_to_joint(jnt, lut, LUT_I3);
125 if (idx > 0) {
126 jnt = edif_joint_create(edf);
127 edif_add_to_joint(jnt, muxcy, MUXCY_CI);
128 edif_add_to_joint(jnt, muxcy_down, MUXCY_O);
129 } else {
130 jnt = edif_joint_create(edf);
131 edif_add_to_joint(jnt, muxcy, MUXCY_CI);
132 edif_add_to_joint(jnt, false_out, 0);
135 muxcy_down = muxcy;
138 muxcy = edif_cellref_create(edf, cell_muxcy);
139 jnt = edif_joint_create(edf);
140 edif_add_to_joint(jnt, true_out, 0);
141 edif_add_to_joint(jnt, muxcy, MUXCY_DI);
143 jnt = edif_joint_create(edf);
144 edif_add_to_joint(jnt, muxcy, MUXCY_CI);
145 edif_add_to_joint(jnt, muxcy_down, MUXCY_O);
147 switch (ivl_logic_pins(net) - 1 - lut4_cnt*4) {
149 case 1:
150 lut = edif_cellref_create(edf, xilinx_cell_inv(xlib));
152 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+0));
153 edif_add_to_joint(jnt, lut, BUF_I);
154 break;
156 case 2:
157 lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
159 edif_cellref_pstring(lut, "INIT", "1");
161 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+0));
162 edif_add_to_joint(jnt, lut, LUT_I0);
164 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+1));
165 edif_add_to_joint(jnt, lut, LUT_I1);
166 break;
168 case 3:
169 lut = edif_cellref_create(edf, xilinx_cell_lut3(xlib));
171 edif_cellref_pstring(lut, "INIT", "01");
173 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+0));
174 edif_add_to_joint(jnt, lut, LUT_I0);
176 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+1));
177 edif_add_to_joint(jnt, lut, LUT_I1);
179 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+2));
180 edif_add_to_joint(jnt, lut, LUT_I2);
181 break;
183 case 4:
184 lut = edif_cellref_create(edf, cell_lut4);
186 edif_cellref_pstring(lut, "INIT", "0001");
188 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+0));
189 edif_add_to_joint(jnt, lut, LUT_I0);
191 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+1));
192 edif_add_to_joint(jnt, lut, LUT_I1);
194 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+2));
195 edif_add_to_joint(jnt, lut, LUT_I2);
197 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+3));
198 edif_add_to_joint(jnt, lut, LUT_I3);
199 break;
201 default:
202 assert(0);
205 jnt = edif_joint_create(edf);
206 edif_add_to_joint(jnt, lut, LUT_O);
207 edif_add_to_joint(jnt, muxcy, MUXCY_S);
209 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0));
210 edif_add_to_joint(jnt, muxcy, MUXCY_O);
214 * Pick off the cases where there is a Virtex specific implementation
215 * that is better then the generic Xilinx implementation. Route the
216 * remaining to the base xilinx_logic implementation.
218 void virtex_logic(ivl_net_logic_t net)
220 /* Nothing I can do if the user expresses a specific
221 opinion. The cellref attribute forces me to let the base
222 xilinx_logic take care of it. */
223 if (ivl_logic_attr(net, "cellref")) {
224 xilinx_logic(net);
225 return;
228 switch (ivl_logic_type(net)) {
230 case IVL_LO_OR:
231 case IVL_LO_NOR:
232 if (ivl_logic_pins(net) <= 5) {
233 xilinx_logic(net);
235 } else {
236 virtex_or_wide(net);
238 break;
240 default:
241 xilinx_logic(net);
242 break;
246 void virtex_generic_dff(ivl_lpm_t net)
248 unsigned idx;
250 ivl_nexus_t aclr = ivl_lpm_async_clr(net);
251 ivl_nexus_t aset = ivl_lpm_async_set(net);
252 ivl_nexus_t sclr = ivl_lpm_sync_clr(net);
253 ivl_nexus_t sset = ivl_lpm_sync_set(net);
254 const char*abits = 0;
256 if (aset) {
257 ivl_expr_t avalue = ivl_lpm_aset_value(net);
258 assert(avalue);
259 abits = ivl_expr_bits(avalue);
260 assert(abits);
263 /* XXXX Can't handle both synchronous and asynchronous clear. */
264 assert( ! (aclr && sclr) );
265 /* XXXX Can't handle synchronous set at all. */
266 assert( ! sset );
268 for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) {
269 edif_cellref_t obj;
270 ivl_nexus_t nex;
271 edif_joint_t jnt;
273 /* If there is a preset, then select an FDCPE instead of
274 an FDCE device. */
275 if (aset && (abits[idx] == '1')) {
276 obj = edif_cellref_create(edf, xilinx_cell_fdcpe(xlib));
277 } else if (aclr) {
278 obj = edif_cellref_create(edf, xilinx_cell_fdce(xlib));
279 } else if (sclr) {
280 obj = edif_cellref_create(edf, xilinx_cell_fdre(xlib));
281 } else {
282 obj = edif_cellref_create(edf, xilinx_cell_fdce(xlib));
286 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx));
287 edif_add_to_joint(jnt, obj, FDCE_Q);
289 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, idx));
290 edif_add_to_joint(jnt, obj, FDCE_D);
292 jnt = edif_joint_of_nexus(edf, ivl_lpm_clk(net));
293 edif_add_to_joint(jnt, obj, FDCE_C);
295 if ( (nex = ivl_lpm_enable(net)) ) {
296 jnt = edif_joint_of_nexus(edf, nex);
297 edif_add_to_joint(jnt, obj, FDCE_CE);
300 if (aclr) {
301 jnt = edif_joint_of_nexus(edf, aclr);
302 edif_add_to_joint(jnt, obj, FDCE_CLR);
303 } else if (sclr) {
304 jnt = edif_joint_of_nexus(edf, sclr);
305 edif_add_to_joint(jnt, obj, FDCE_CLR);
308 if (aset) {
309 if (abits[idx] == '1') {
310 jnt = edif_joint_of_nexus(edf, aset);
311 edif_add_to_joint(jnt, obj, FDCE_PRE);
312 } else {
313 assert(aclr == 0);
314 jnt = edif_joint_of_nexus(edf, aset);
315 edif_add_to_joint(jnt, obj, FDCE_CLR);
322 * This method handles both == and != operators, the identity
323 * comparison operators.
325 * If the identity compare is applied to small enough input vectors,
326 * it is shoved into a single LUT. Otherwise, it is strung out into a
327 * row of LUT devices chained together by carry muxes. The output of
328 * the comparison is the output of the last mux.
330 * When the compare is small, a LUT is generated with the appropriate
331 * truth table to cause an == or != result.
333 * When the compare is too wide for a single LUT, then it is made into
334 * a chain connected by a string of carry mux devices. Each LUT
335 * implements == for up to two pairs of bits, even if the final output
336 * is supposed to be !=. The LUT output is connected to an associated
337 * MUX select input. The CO output of each muxcy is passed up to the
338 * next higher order bits of the compare.
340 * For identity == compare, a != output from the LUT selects the DI
341 * input of the muxcy, generating a 0 output that is passed up. Since
342 * the next higher muxcy now gets a 0 input to both DI and CI, the
343 * output of the next higher muxcy is guaranteed to be 0, and so on to
344 * the final output of the carry chain. If the output from a LUT is ==,
345 * then the CI input of the muxcy is selected and the truth of this
346 * level depends on lower order bits. The least significant muxcy is
347 * connected to GND and VCC so that its CO follows the least
348 * significant LUT.
350 * Identity != is the same as == except that the output is
351 * inverted. To get that effect without putting an inverter on the
352 * output of the top muxcy pin CO (which would cost a LUT) the DI
353 * inputs are all connected to VCC instead of GND, and the CI of the
354 * least significant muxcy is connected to GND instead of VCC. The LUT
355 * expressions for the chained compare are configured for ==, with the
356 * changed CI/DI inputs performing the inversion.
358 void virtex_eq(ivl_lpm_t net)
360 edif_cellref_t lut, mux, mux_prev;
361 edif_joint_t jnt, jnt_di;
362 unsigned idx;
364 /* True if I'm implementing CMP_EQ instead of CMP_NE */
365 int eq = 1;
367 assert(ivl_lpm_width(net) >= 1);
369 if (ivl_lpm_type(net) == IVL_LPM_CMP_NE)
370 eq = 0;
372 switch (ivl_lpm_width(net)) {
374 case 1:
375 lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
376 edif_cellref_pstring(lut, "INIT", eq? "9" : "6");
378 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0));
379 edif_add_to_joint(jnt, lut, LUT_O);
381 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0));
382 edif_add_to_joint(jnt, lut, LUT_I0);
384 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0));
385 edif_add_to_joint(jnt, lut, LUT_I1);
386 return;
388 case 2:
389 lut = edif_cellref_create(edf, xilinx_cell_lut4(xlib));
390 edif_cellref_pstring(lut, "INIT", eq? "9009" : "6FF6");
392 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0));
393 edif_add_to_joint(jnt, lut, LUT_O);
395 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0));
396 edif_add_to_joint(jnt, lut, LUT_I0);
398 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0));
399 edif_add_to_joint(jnt, lut, LUT_I1);
401 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 1));
402 edif_add_to_joint(jnt, lut, LUT_I2);
404 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 1));
405 edif_add_to_joint(jnt, lut, LUT_I3);
406 return;
408 default:
409 { edif_cellref_t di;
410 di = edif_cellref_create(edf, eq? cell_0 : cell_1);
411 jnt_di = edif_joint_create(edf);
412 edif_add_to_joint(jnt_di, di, 0);
415 mux_prev = 0;
416 for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 2) {
417 int subwid = 2;
418 if ((idx + 1) == ivl_lpm_width(net))
419 subwid = 1;
421 mux = edif_cellref_create(edf, xilinx_cell_muxcy(xlib));
422 if (subwid == 2) {
423 lut = edif_cellref_create(edf, xilinx_cell_lut4(xlib));
424 edif_cellref_pstring(lut, "INIT", "9009");
425 } else {
426 lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
427 edif_cellref_pstring(lut, "INIT", "9");
430 jnt = edif_joint_create(edf);
431 edif_add_to_joint(jnt, lut, LUT_O);
432 edif_add_to_joint(jnt, mux, MUXCY_S);
434 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, idx));
435 edif_add_to_joint(jnt, lut, LUT_I0);
437 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, idx));
438 edif_add_to_joint(jnt, lut, LUT_I1);
440 if (subwid > 1) {
441 jnt = edif_joint_of_nexus(edf,
442 ivl_lpm_data(net, idx+1));
443 edif_add_to_joint(jnt, lut, LUT_I2);
445 jnt = edif_joint_of_nexus(edf,
446 ivl_lpm_datab(net, idx+1));
447 edif_add_to_joint(jnt, lut, LUT_I3);
450 edif_add_to_joint(jnt_di, mux, MUXCY_DI);
452 if (mux_prev) {
453 jnt = edif_joint_create(edf);
454 edif_add_to_joint(jnt, mux, MUXCY_CI);
455 edif_add_to_joint(jnt, mux_prev, MUXCY_O);
456 } else {
457 edif_cellref_t ci;
458 ci = edif_cellref_create(edf, eq? cell_1 : cell_0);
459 jnt = edif_joint_create(edf);
460 edif_add_to_joint(jnt, ci, 0);
461 edif_add_to_joint(jnt, mux, MUXCY_CI);
464 mux_prev = mux;
467 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0));
468 edif_add_to_joint(jnt, mux_prev, MUXCY_O);
469 return;
474 * Implement hardware for the device (A >= B). We use LUT devices if
475 * it can handle the slices, or carry chain logic if the slices must
476 * span LUT devices.
478 void virtex_ge(ivl_lpm_t net)
480 edif_cellref_t muxcy_prev;
481 edif_cellref_t lut;
482 edif_joint_t jnt;
483 unsigned idx;
485 if (ivl_lpm_width(net) == 1) {
487 /* If the comparator is a single bit, then use a LUT2
488 with this truth table:
490 Q A B
491 --+----
492 1 | 0 0
493 0 | 0 1
494 1 | 1 0
495 1 | 1 1
497 Connect the A value to I1 and the B value to I0. */
499 lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
500 edif_cellref_pstring(lut, "INIT", "D");
502 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0));
503 edif_add_to_joint(jnt, lut, LUT_O);
505 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0));
506 edif_add_to_joint(jnt, lut, LUT_I1);
508 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0));
509 edif_add_to_joint(jnt, lut, LUT_I2);
510 return;
513 /* Handle the case where the device is two slices
514 wide. In this case, we can use a LUT4 to do all
515 the calculation. Use this truth table:
517 Q AA BB
518 --+------
519 1 | 00 00
520 0 | 00 01
521 0 | 00 10
522 0 | 00 11
523 1 | 01 00
524 1 | 01 01
525 0 | 01 10
526 0 | 01 11
527 1 | 10 00
528 1 | 10 01
529 1 | 10 10
530 0 | 10 11
531 1 | 11 xx
533 The I3-I0 inputs are A1 A0 B1 B0 in that order. */
535 assert(ivl_lpm_width(net) >= 2);
537 lut = edif_cellref_create(edf, xilinx_cell_lut4(xlib));
538 edif_cellref_pstring(lut, "INIT", "F731");
540 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0));
541 edif_add_to_joint(jnt, lut, LUT_I2);
543 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0));
544 edif_add_to_joint(jnt, lut, LUT_I0);
546 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 1));
547 edif_add_to_joint(jnt, lut, LUT_I3);
549 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 1));
550 edif_add_to_joint(jnt, lut, LUT_I1);
552 /* There are only two slices, so this is all we need. */
553 if (ivl_lpm_width(net) == 2) {
554 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0));
555 edif_add_to_joint(jnt, lut, LUT_O);
556 return;
559 /* The general case requires that we make the >= comparator
560 from slices. This is an iterative design. Each slice has
561 the truth table:
563 An Bn | A >= B
564 ------+-------
565 0 0 | CI
566 0 1 | 0
567 1 0 | 1
568 1 1 | CI
570 The CI for each slice is the output of the compare of the
571 next less significant bits. We get this truth table by
572 connecting a LUT2 to the S input of a MUXCY. When the S
573 input is (1), it propagates its CI. This suggests that the
574 init value for the LUT be "9" (XNOR).
576 When the MUXCY S input is 0, it propagates a local
577 input. We connect to that input An, and we get the desired
578 and complete truth table for a slice.
580 This iterative definition needs to terminate at the least
581 significant bits. In fact, we have a non-iterative was to
582 deal with the two least significant slices. We take the
583 output of the LUT4 device for the least significant bits,
584 and use that to generate the initial CI for the chain. */
587 muxcy_prev = edif_cellref_create(edf, xilinx_cell_muxcy_l(xlib));
588 jnt = edif_joint_create(edf);
590 edif_add_to_joint(jnt, lut, LUT_O);
591 edif_add_to_joint(jnt, muxcy_prev, MUXCY_S);
592 { edif_cellref_t p0 = edif_cellref_create(edf, cell_0);
593 edif_cellref_t p1 = edif_cellref_create(edf, cell_1);
595 jnt = edif_joint_create(edf);
596 edif_add_to_joint(jnt, p0, 0);
597 edif_add_to_joint(jnt, muxcy_prev, MUXCY_DI);
599 jnt = edif_joint_create(edf);
600 edif_add_to_joint(jnt, p1, 0);
601 edif_add_to_joint(jnt, muxcy_prev, MUXCY_CI);
604 for (idx = 2 ; idx < ivl_lpm_width(net) ; idx += 1) {
605 edif_cellref_t muxcy;
607 lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
608 muxcy = edif_cellref_create(edf, xilinx_cell_muxcy(xlib));
609 edif_cellref_pstring(lut, "INIT", "9");
611 jnt = edif_joint_create(edf);
612 edif_add_to_joint(jnt, lut, LUT_O);
613 edif_add_to_joint(jnt, muxcy, MUXCY_S);
615 jnt = edif_joint_create(edf);
616 edif_add_to_joint(jnt, muxcy, MUXCY_CI);
617 edif_add_to_joint(jnt, muxcy_prev, MUXCY_O);
619 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, idx));
620 edif_add_to_joint(jnt, lut, LUT_I0);
621 edif_add_to_joint(jnt, muxcy, MUXCY_DI);
623 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, idx));
624 edif_add_to_joint(jnt, lut, LUT_I1);
626 muxcy_prev = muxcy;
629 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0));
630 edif_add_to_joint(jnt, muxcy_prev, MUXCY_O);
634 * A 4-input N-wide mux can be made on Virtex devices using MUXF5 and
635 * LUT devices. The MUXF5 selects a LUT device (and is connected to
636 * S[1]) and the LUT devices, connected to S[0], select the input.
638 static void virtex_mux4(ivl_lpm_t net)
640 unsigned idx;
641 assert(ivl_lpm_selects(net) == 2);
643 for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) {
644 edif_joint_t jnt;
645 edif_cellref_t lut01;
646 edif_cellref_t lut23;
647 edif_cellref_t muxf5;
649 lut01 = edif_cellref_create(edf, xilinx_cell_lut3(xlib));
650 edif_cellref_pstring(lut01, "INIT", "CA");
652 lut23 = edif_cellref_create(edf, xilinx_cell_lut3(xlib));
653 edif_cellref_pstring(lut23, "INIT", "CA");
655 muxf5 = edif_cellref_create(edf, xilinx_cell_muxf5(xlib));
657 jnt = edif_joint_of_nexus(edf, ivl_lpm_data2(net, 0, idx));
658 edif_add_to_joint(jnt, lut01, LUT_I0);
660 jnt = edif_joint_of_nexus(edf, ivl_lpm_data2(net, 1, idx));
661 edif_add_to_joint(jnt, lut01, LUT_I1);
663 jnt = edif_joint_of_nexus(edf, ivl_lpm_data2(net, 2, idx));
664 edif_add_to_joint(jnt, lut23, LUT_I0);
666 jnt = edif_joint_of_nexus(edf, ivl_lpm_data2(net, 3, idx));
667 edif_add_to_joint(jnt, lut23, LUT_I1);
669 jnt = edif_joint_of_nexus(edf, ivl_lpm_select(net, 0));
670 edif_add_to_joint(jnt, lut01, LUT_I2);
671 edif_add_to_joint(jnt, lut23, LUT_I2);
673 jnt = edif_joint_create(edf);
674 edif_add_to_joint(jnt, muxf5, MUXF_I0);
675 edif_add_to_joint(jnt, lut01, LUT_O);
677 jnt = edif_joint_create(edf);
678 edif_add_to_joint(jnt, muxf5, MUXF_I1);
679 edif_add_to_joint(jnt, lut23, LUT_O);
681 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx));
682 edif_add_to_joint(jnt, muxf5, MUXF_O);
684 jnt = edif_joint_of_nexus(edf, ivl_lpm_select(net, 1));
685 edif_add_to_joint(jnt, muxf5, MUXF_S);
689 void virtex_mux(ivl_lpm_t net)
692 switch (ivl_lpm_selects(net)) {
694 case 2:
695 virtex_mux4(net);
696 break;
698 default:
699 xilinx_mux(net);
700 break;
705 * This function generates ADD/SUB devices for Virtex devices,
706 * based on the documented implementations of ADD8/ADD16, etc., from
707 * the Libraries Guide.
709 * Each slice of the ADD/SUB device is made from a LUT2 device, an
710 * XORCY device that mixes with the LUT2 to make a full adder, and a
711 * MUXCY_L to propagate the carry. The most significant slice does not
712 * have a carry to propagate, so has no MUXCY_L.
714 * If the device is a wide adder, then the LUT2 devices are configured
715 * to implement an XOR function and a zero is pumped into the least
716 * significant carry input.
718 * If the device is really an adder, then the input is turned into an
719 * XNOR, which takes a 1-s complement of the B input. Pump a 1 into
720 * the LSB carry input to finish converting the B input into the 2s
721 * complement.
723 void virtex_add(ivl_lpm_t net)
725 const char*ha_init = 0;
726 edif_cellref_t lut, xorcy, muxcy, pad;
727 edif_joint_t jnt;
729 unsigned idx;
731 if (ivl_lpm_width(net) < 2) {
732 xilinx_add(net);
733 return;
736 switch (ivl_lpm_type(net)) {
737 case IVL_LPM_ADD:
738 ha_init = "6";
739 break;
740 case IVL_LPM_SUB:
741 ha_init = "9";
742 break;
743 default:
744 assert(0);
747 assert(ivl_lpm_width(net) > 1);
749 lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
750 xorcy = edif_cellref_create(edf, xilinx_cell_xorcy(xlib));
751 muxcy = edif_cellref_create(edf, xilinx_cell_muxcy_l(xlib));
752 edif_cellref_pstring(lut, "INIT", ha_init);
754 /* The bottom carry-in takes a constant that primes the add or
755 subtract. */
756 switch (ivl_lpm_type(net)) {
757 case IVL_LPM_ADD:
758 pad = edif_cellref_create(edf, cell_0);
759 break;
761 case IVL_LPM_SUB:
762 pad = edif_cellref_create(edf, cell_1);
763 break;
765 default:
766 assert(0);
769 jnt = edif_joint_create(edf);
770 edif_add_to_joint(jnt, pad, 0);
771 edif_add_to_joint(jnt, muxcy, MUXCY_CI);
772 edif_add_to_joint(jnt, xorcy, XORCY_CI);
774 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0));
775 edif_add_to_joint(jnt, xorcy, XORCY_O);
777 jnt = edif_joint_create(edf);
778 edif_add_to_joint(jnt, xorcy, XORCY_LI);
779 edif_add_to_joint(jnt, muxcy, MUXCY_S);
780 edif_add_to_joint(jnt, lut, LUT_O);
782 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0));
783 edif_add_to_joint(jnt, lut, LUT_I0);
784 edif_add_to_joint(jnt, muxcy, MUXCY_DI);
786 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0));
787 edif_add_to_joint(jnt, lut, LUT_I1);
789 for (idx = 1 ; idx < ivl_lpm_width(net) ; idx += 1) {
790 edif_cellref_t muxcy0 = muxcy;
792 lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
793 xorcy = edif_cellref_create(edf, xilinx_cell_xorcy(xlib));
794 edif_cellref_pstring(lut, "INIT", ha_init);
796 /* If this is the last bit, then there is no further
797 propagation in the carry chain, and I can skip the
798 carry mux MUXCY. */
799 if ((idx+1) < ivl_lpm_width(net))
800 muxcy = edif_cellref_create(edf, xilinx_cell_muxcy_l(xlib));
801 else
802 muxcy = 0;
804 jnt = edif_joint_create(edf);
805 edif_add_to_joint(jnt, muxcy0, MUXCY_O);
806 edif_add_to_joint(jnt, xorcy, XORCY_CI);
807 if (muxcy) edif_add_to_joint(jnt, muxcy, MUXCY_CI);
809 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx));
810 edif_add_to_joint(jnt, xorcy, XORCY_O);
812 jnt = edif_joint_create(edf);
813 edif_add_to_joint(jnt, xorcy, XORCY_LI);
814 if (muxcy) edif_add_to_joint(jnt, muxcy, MUXCY_S);
815 edif_add_to_joint(jnt, lut, LUT_O);
817 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, idx));
818 edif_add_to_joint(jnt, lut, LUT_I0);
819 if (muxcy) edif_add_to_joint(jnt, muxcy, MUXCY_DI);
821 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, idx));
822 edif_add_to_joint(jnt, lut, LUT_I1);
828 const struct device_s d_virtex_edif = {
829 virtex_show_header,
830 xilinx_show_footer,
831 xilinx_show_scope,
832 xilinx_pad,
833 virtex_logic,
834 virtex_generic_dff,
835 virtex_eq,
836 virtex_eq,
837 virtex_ge,
838 0, /* show_cmp_gt */
839 virtex_mux,
840 virtex_add,
841 virtex_add,
842 xilinx_shiftl,
843 0 /* show_shiftr */
848 * $Log: d-virtex.c,v $
849 * Revision 1.35 2004/10/04 01:10:56 steve
850 * Clean up spurious trailing white space.
852 * Revision 1.34 2004/02/15 18:03:30 steve
853 * Cleanup of warnings.
855 * Revision 1.33 2003/11/12 03:20:14 steve
856 * devices need show_cmp_gt
858 * Revision 1.32 2003/08/15 02:23:53 steve
859 * Add synthesis support for synchronous reset.
861 * Revision 1.31 2003/07/04 00:10:09 steve
862 * Generate MUXF5 based 4-input N-wide muxes.
864 * Revision 1.30 2003/07/02 03:02:15 steve
865 * More xilinx common code.
867 * Revision 1.29 2003/07/02 02:58:18 steve
868 * Remember to set INIT on wide-or trailing luts.
870 * Revision 1.28 2003/06/30 19:21:21 steve
871 * lut3 for 3input wide or.
873 * Revision 1.27 2003/06/28 04:18:47 steve
874 * Add support for wide OR/NOR gates.
876 * Revision 1.26 2003/06/26 03:57:05 steve
877 * Add Xilinx support for A/B MUX devices.
879 * Revision 1.25 2003/06/25 02:55:57 steve
880 * Virtex and Virtex2 share much code.
882 * Revision 1.24 2003/06/25 01:49:06 steve
883 * Spelling fixes.
885 * Revision 1.23 2003/06/24 03:55:00 steve
886 * Add ivl_synthesis_cell support for virtex2.
888 * Revision 1.22 2003/02/26 01:24:42 steve
889 * ivl_lpm_name is obsolete.