1 /*
2 * Copyright (c) 2003-2014 Stephen Williams (steve at 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 "edif.h"
21 # include "generic.h"
22 # include "xilinx.h"
23 # include "fpga_priv.h"
24 # include <stdlib.h>
25 # include <string.h>
26 # include <assert.h>
27 # include "ivl_alloc.h"
28
xilinx_cell_buf(edif_xlibrary_t xlib)29 edif_cell_t xilinx_cell_buf(edif_xlibrary_t xlib)
30 {
31 static edif_cell_t cell = 0;
32 if (cell) return cell;
33
34 cell = edif_xcell_create(xlib, "BUF", 2);
35 edif_cell_portconfig(cell, BUF_O, "O", IVL_SIP_OUTPUT);
36 edif_cell_portconfig(cell, BUF_I, "I", IVL_SIP_INPUT);
37 return cell;
38 }
39
xilinx_cell_bufe(edif_xlibrary_t xlib)40 edif_cell_t xilinx_cell_bufe(edif_xlibrary_t xlib)
41 {
42 static edif_cell_t cell = 0;
43 if (cell) return cell;
44
45 cell = edif_xcell_create(xlib, "BUFE", 3);
46 edif_cell_portconfig(cell, BUF_O, "O", IVL_SIP_OUTPUT);
47 edif_cell_portconfig(cell, BUF_I, "I", IVL_SIP_INPUT);
48 edif_cell_portconfig(cell, BUF_T, "E", IVL_SIP_INPUT);
49 return cell;
50 }
51
xilinx_cell_bufg(edif_xlibrary_t xlib)52 edif_cell_t xilinx_cell_bufg(edif_xlibrary_t xlib)
53 {
54 static edif_cell_t cell = 0;
55 if (cell) return cell;
56
57 cell = edif_xcell_create(xlib, "BUFG", 2);
58 edif_cell_portconfig(cell, BUF_O, "O", IVL_SIP_OUTPUT);
59 edif_cell_portconfig(cell, BUF_I, "I", IVL_SIP_INPUT);
60 return cell;
61 }
62
xilinx_cell_buft(edif_xlibrary_t xlib)63 edif_cell_t xilinx_cell_buft(edif_xlibrary_t xlib)
64 {
65 static edif_cell_t cell = 0;
66 if (cell) return cell;
67
68 cell = edif_xcell_create(xlib, "BUFT", 3);
69 edif_cell_portconfig(cell, BUF_O, "O", IVL_SIP_OUTPUT);
70 edif_cell_portconfig(cell, BUF_I, "I", IVL_SIP_INPUT);
71 edif_cell_portconfig(cell, BUF_T, "T", IVL_SIP_INPUT);
72 return cell;
73 }
74
xilinx_cell_ibuf(edif_xlibrary_t xlib)75 edif_cell_t xilinx_cell_ibuf(edif_xlibrary_t xlib)
76 {
77 static edif_cell_t cell = 0;
78 if (cell) return cell;
79
80 cell = edif_xcell_create(xlib, "IBUF", 2);
81 edif_cell_portconfig(cell, BUF_O, "O", IVL_SIP_OUTPUT);
82 edif_cell_portconfig(cell, BUF_I, "I", IVL_SIP_INPUT);
83 return cell;
84 }
85
xilinx_cell_inv(edif_xlibrary_t xlib)86 edif_cell_t xilinx_cell_inv(edif_xlibrary_t xlib)
87 {
88 static edif_cell_t cell = 0;
89 if (cell) return cell;
90
91 cell = edif_xcell_create(xlib, "INV", 2);
92 edif_cell_portconfig(cell, BUF_O, "O", IVL_SIP_OUTPUT);
93 edif_cell_portconfig(cell, BUF_I, "I", IVL_SIP_INPUT);
94 return cell;
95 }
96
xilinx_cell_muxf5(edif_xlibrary_t xlib)97 edif_cell_t xilinx_cell_muxf5(edif_xlibrary_t xlib)
98 {
99 static edif_cell_t cell = 0;
100 if (cell) return cell;
101
102 cell = edif_xcell_create(xlib, "MUXF5", 4);
103 edif_cell_portconfig(cell, MUXF_O, "O", IVL_SIP_OUTPUT);
104 edif_cell_portconfig(cell, MUXF_I0, "I0", IVL_SIP_INPUT);
105 edif_cell_portconfig(cell, MUXF_I1, "I1", IVL_SIP_INPUT);
106 edif_cell_portconfig(cell, MUXF_S, "S", IVL_SIP_INPUT);
107 return cell;
108 }
109
xilinx_cell_muxf6(edif_xlibrary_t xlib)110 edif_cell_t xilinx_cell_muxf6(edif_xlibrary_t xlib)
111 {
112 static edif_cell_t cell = 0;
113 if (cell) return cell;
114
115 cell = edif_xcell_create(xlib, "MUXF6", 4);
116 edif_cell_portconfig(cell, MUXF_O, "O", IVL_SIP_OUTPUT);
117 edif_cell_portconfig(cell, MUXF_I0, "I0", IVL_SIP_INPUT);
118 edif_cell_portconfig(cell, MUXF_I1, "I1", IVL_SIP_INPUT);
119 edif_cell_portconfig(cell, MUXF_S, "S", IVL_SIP_INPUT);
120 return cell;
121 }
122
xilinx_cell_obuf(edif_xlibrary_t xlib)123 edif_cell_t xilinx_cell_obuf(edif_xlibrary_t xlib)
124 {
125 static edif_cell_t cell = 0;
126 if (cell) return cell;
127
128 cell = edif_xcell_create(xlib, "OBUF", 2);
129 edif_cell_portconfig(cell, BUF_O, "O", IVL_SIP_OUTPUT);
130 edif_cell_portconfig(cell, BUF_I, "I", IVL_SIP_INPUT);
131 return cell;
132 }
133
134
xilinx_cell_lut2(edif_xlibrary_t xlib)135 edif_cell_t xilinx_cell_lut2(edif_xlibrary_t xlib)
136 {
137 static edif_cell_t cell = 0;
138 if (cell != 0) return cell;
139
140 cell = edif_xcell_create(xlib, "LUT2", 3);
141 edif_cell_portconfig(cell, LUT_O, "O", IVL_SIP_OUTPUT);
142 edif_cell_portconfig(cell, LUT_I0, "I0", IVL_SIP_INPUT);
143 edif_cell_portconfig(cell, LUT_I1, "I1", IVL_SIP_INPUT);
144 return cell;
145 }
146
xilinx_cell_lut3(edif_xlibrary_t xlib)147 edif_cell_t xilinx_cell_lut3(edif_xlibrary_t xlib)
148 {
149 static edif_cell_t cell = 0;
150 if (cell != 0) return cell;
151
152 cell = edif_xcell_create(xlib, "LUT3", 4);
153 edif_cell_portconfig(cell, LUT_O, "O", IVL_SIP_OUTPUT);
154 edif_cell_portconfig(cell, LUT_I0, "I0", IVL_SIP_INPUT);
155 edif_cell_portconfig(cell, LUT_I1, "I1", IVL_SIP_INPUT);
156 edif_cell_portconfig(cell, LUT_I2, "I2", IVL_SIP_INPUT);
157 return cell;
158 }
159
xilinx_cell_lut4(edif_xlibrary_t xlib)160 edif_cell_t xilinx_cell_lut4(edif_xlibrary_t xlib)
161 {
162 static edif_cell_t cell = 0;
163 if (cell != 0) return cell;
164
165 cell = edif_xcell_create(xlib, "LUT4", 5);
166 edif_cell_portconfig(cell, LUT_O, "O", IVL_SIP_OUTPUT);
167 edif_cell_portconfig(cell, LUT_I0, "I0", IVL_SIP_INPUT);
168 edif_cell_portconfig(cell, LUT_I1, "I1", IVL_SIP_INPUT);
169 edif_cell_portconfig(cell, LUT_I2, "I2", IVL_SIP_INPUT);
170 edif_cell_portconfig(cell, LUT_I3, "I3", IVL_SIP_INPUT);
171 return cell;
172 }
173
174
xilinx_cell_fdce(edif_xlibrary_t xlib)175 edif_cell_t xilinx_cell_fdce(edif_xlibrary_t xlib)
176 {
177 static edif_cell_t cell = 0;
178 if (cell != 0) return cell;
179
180 cell = edif_xcell_create(xlib, "FDCE", 5);
181 edif_cell_portconfig(cell, FDCE_Q, "Q", IVL_SIP_OUTPUT);
182 edif_cell_portconfig(cell, FDCE_D, "D", IVL_SIP_INPUT);
183 edif_cell_portconfig(cell, FDCE_C, "C", IVL_SIP_INPUT);
184 edif_cell_portconfig(cell, FDCE_CE, "CE", IVL_SIP_INPUT);
185 edif_cell_portconfig(cell, FDCE_CLR,"CLR", IVL_SIP_INPUT);
186 return cell;
187 }
188
xilinx_cell_fdcpe(edif_xlibrary_t xlib)189 edif_cell_t xilinx_cell_fdcpe(edif_xlibrary_t xlib)
190 {
191 static edif_cell_t cell = 0;
192 if (cell != 0) return cell;
193
194 cell = edif_xcell_create(xlib, "FDCPE", 6);
195 edif_cell_portconfig(cell, FDCE_Q, "Q", IVL_SIP_OUTPUT);
196 edif_cell_portconfig(cell, FDCE_D, "D", IVL_SIP_INPUT);
197 edif_cell_portconfig(cell, FDCE_C, "C", IVL_SIP_INPUT);
198 edif_cell_portconfig(cell, FDCE_CE, "CE", IVL_SIP_INPUT);
199 edif_cell_portconfig(cell, FDCE_CLR,"CLR", IVL_SIP_INPUT);
200 edif_cell_portconfig(cell, FDCE_PRE,"PRE", IVL_SIP_INPUT);
201 return cell;
202 }
203
xilinx_cell_fdre(edif_xlibrary_t xlib)204 edif_cell_t xilinx_cell_fdre(edif_xlibrary_t xlib)
205 {
206 static edif_cell_t cell = 0;
207 if (cell != 0) return cell;
208
209 cell = edif_xcell_create(xlib, "FDRE", 5);
210 edif_cell_portconfig(cell, FDCE_Q, "Q", IVL_SIP_OUTPUT);
211 edif_cell_portconfig(cell, FDCE_D, "D", IVL_SIP_INPUT);
212 edif_cell_portconfig(cell, FDCE_C, "C", IVL_SIP_INPUT);
213 edif_cell_portconfig(cell, FDCE_CE, "CE", IVL_SIP_INPUT);
214 edif_cell_portconfig(cell, FDCE_CLR,"R", IVL_SIP_INPUT);
215 return cell;
216 }
217
218
xilinx_cell_mult_and(edif_xlibrary_t xlib)219 edif_cell_t xilinx_cell_mult_and(edif_xlibrary_t xlib)
220 {
221 static edif_cell_t cell = 0;
222 if (cell != 0) return cell;
223
224 cell = edif_xcell_create(xlib, "MULT_AND", 3);
225 edif_cell_portconfig(cell, MULT_AND_LO, "LO", IVL_SIP_OUTPUT);
226 edif_cell_portconfig(cell, MULT_AND_I0, "I0", IVL_SIP_INPUT);
227 edif_cell_portconfig(cell, MULT_AND_I1, "I1", IVL_SIP_INPUT);
228 return cell;
229 }
230
xilinx_cell_muxcy(edif_xlibrary_t xlib)231 edif_cell_t xilinx_cell_muxcy(edif_xlibrary_t xlib)
232 {
233 static edif_cell_t cell = 0;
234 if (cell != 0) return cell;
235
236 cell = edif_xcell_create(xlib, "MUXCY", 4);
237 edif_cell_portconfig(cell, MUXCY_O, "O", IVL_SIP_OUTPUT);
238 edif_cell_portconfig(cell, MUXCY_DI, "DI", IVL_SIP_INPUT);
239 edif_cell_portconfig(cell, MUXCY_CI, "CI", IVL_SIP_INPUT);
240 edif_cell_portconfig(cell, MUXCY_S, "S", IVL_SIP_INPUT);
241 return cell;
242 }
243
xilinx_cell_muxcy_l(edif_xlibrary_t xlib)244 edif_cell_t xilinx_cell_muxcy_l(edif_xlibrary_t xlib)
245 {
246 static edif_cell_t cell = 0;
247 if (cell != 0) return cell;
248
249 cell = edif_xcell_create(xlib, "MUXCY_L", 4);
250 edif_cell_portconfig(cell, MUXCY_O, "LO", IVL_SIP_OUTPUT);
251 edif_cell_portconfig(cell, MUXCY_DI, "DI", IVL_SIP_INPUT);
252 edif_cell_portconfig(cell, MUXCY_CI, "CI", IVL_SIP_INPUT);
253 edif_cell_portconfig(cell, MUXCY_S, "S", IVL_SIP_INPUT);
254 return cell;
255 }
256
xilinx_cell_xorcy(edif_xlibrary_t xlib)257 edif_cell_t xilinx_cell_xorcy(edif_xlibrary_t xlib)
258 {
259 static edif_cell_t cell = 0;
260 if (cell != 0) return cell;
261
262 cell = edif_xcell_create(xlib, "XORCY", 3);
263 edif_cell_portconfig(cell, XORCY_O, "O", IVL_SIP_OUTPUT);
264 edif_cell_portconfig(cell, XORCY_CI, "CI", IVL_SIP_INPUT);
265 edif_cell_portconfig(cell, XORCY_LI, "LI", IVL_SIP_INPUT);
266 return cell;
267 }
268
269 /*
270 * This function does a lot of the stuff common to the header
271 * functions of various Xilinx families. This includes creating the edf
272 * object that holds the netlist.
273 */
xilinx_common_header(ivl_design_t des)274 void xilinx_common_header(ivl_design_t des)
275 {
276 unsigned idx;
277 ivl_scope_t root = ivl_design_root(des);
278 unsigned sig_cnt = ivl_scope_sigs(root);
279 unsigned nports = 0, pidx;
280
281 /* Count the ports I'm going to use. */
282 for (idx = 0 ; idx < sig_cnt ; idx += 1) {
283 ivl_signal_t sig = ivl_scope_sig(root, idx);
284
285 if (ivl_signal_port(sig) == IVL_SIP_NONE)
286 continue;
287
288 if (ivl_signal_attr(sig, "PAD") != 0)
289 continue;
290
291 nports += ivl_signal_pins(sig);
292 }
293
294 edf = edif_create(ivl_scope_basename(root), nports);
295
296 pidx = 0;
297 for (idx = 0 ; idx < sig_cnt ; idx += 1) {
298 edif_joint_t jnt;
299 ivl_signal_t sig = ivl_scope_sig(root, idx);
300
301 if (ivl_signal_port(sig) == IVL_SIP_NONE)
302 continue;
303
304 if (ivl_signal_attr(sig, "PAD") != 0)
305 continue;
306
307 if (ivl_signal_pins(sig) == 1) {
308 edif_portconfig(edf, pidx, ivl_signal_basename(sig),
309 ivl_signal_port(sig));
310
311 assert(ivl_signal_pins(sig) == 1);
312 jnt = edif_joint_of_nexus(edf, ivl_signal_pin(sig, 0));
313 edif_port_to_joint(jnt, edf, pidx);
314
315 } else {
316 const char*name = ivl_signal_basename(sig);
317 ivl_signal_port_t dir = ivl_signal_port(sig);
318 char buf[128];
319 unsigned bit;
320 for (bit = 0 ; bit < ivl_signal_pins(sig) ; bit += 1) {
321 const char*tmp;
322 sprintf(buf, "%s[%u]", name, bit);
323 tmp = strdup(buf);
324 edif_portconfig(edf, pidx+bit, tmp, dir);
325
326 jnt = edif_joint_of_nexus(edf,ivl_signal_pin(sig,bit));
327 edif_port_to_joint(jnt, edf, pidx+bit);
328 }
329 }
330
331 pidx += ivl_signal_pins(sig);
332 }
333
334 assert(pidx == nports);
335 }
336
xilinx_show_footer(ivl_design_t des)337 void xilinx_show_footer(ivl_design_t des)
338 {
339 unsigned idx;
340
341 for (idx = 0 ; idx < ivl_design_consts(des) ; idx += 1) {
342 unsigned pin;
343 ivl_net_const_t net = ivl_design_const(des, idx);
344 const char*val = ivl_const_bits(net);
345
346 for (pin = 0 ; pin < ivl_const_pins(net) ; pin += 1) {
347 edif_joint_t jnt;
348 edif_cellref_t pad;
349
350 jnt = edif_joint_of_nexus(edf, ivl_const_pin(net, pin));
351 switch (val[pin]) {
352 case '0':
353 pad = edif_cellref_create(edf, cell_0);
354 break;
355 case '1':
356 pad = edif_cellref_create(edf, cell_1);
357 break;
358 default:
359 assert(0);
360 break;
361 }
362
363 edif_add_to_joint(jnt, pad, 0);
364 }
365 }
366
367 edif_print(xnf, edf);
368 }
369
370 /*
371 * Make (or retrieve) a cell in the external library that reflects the
372 * scope with its ports.
373 */
xilinx_show_scope(ivl_scope_t scope)374 void xilinx_show_scope(ivl_scope_t scope)
375 {
376 edif_cell_t cell;
377 edif_cellref_t ref;
378
379 unsigned port, idx;
380
381 cell = edif_xlibrary_scope_cell(xlib, scope);
382 ref = edif_cellref_create(edf, cell);
383
384 for (idx = 0 ; idx < ivl_scope_sigs(scope) ; idx += 1) {
385 edif_joint_t jnt;
386 ivl_signal_t sig = ivl_scope_sig(scope, idx);
387
388 if (ivl_signal_port(sig) == IVL_SIP_NONE)
389 continue;
390
391 port = edif_cell_port_byname(cell, ivl_signal_basename(sig));
392 jnt = edif_joint_of_nexus(edf, ivl_signal_pin(sig, 0));
393 edif_add_to_joint(jnt, ref, port);
394 }
395 }
396
xilinx_pad(ivl_signal_t sig,const char * str)397 void xilinx_pad(ivl_signal_t sig, const char*str)
398 {
399 unsigned idx;
400 char**pins;
401
402 if (cell_ipad == 0) {
403 cell_ipad = edif_xcell_create(xlib, "IPAD", 1);
404 edif_cell_portconfig(cell_ipad, 0, "IPAD", IVL_SIP_OUTPUT);
405 }
406
407 if (cell_opad == 0) {
408 cell_opad = edif_xcell_create(xlib, "OPAD", 1);
409 edif_cell_portconfig(cell_opad, 0, "OPAD", IVL_SIP_INPUT);
410 }
411
412 if (cell_iopad == 0) {
413 cell_iopad = edif_xcell_create(xlib, "IOPAD", 1);
414 edif_cell_portconfig(cell_iopad, 0, "IOPAD", IVL_SIP_INOUT);
415 }
416
417 /* Collect an array of pin assignments from the attribute
418 string passed in as str. The format is a comma separated
419 list of location names. */
420 pins = calloc(ivl_signal_pins(sig), sizeof(char*));
421 for (idx = 0 ; idx < ivl_signal_pins(sig) ; idx += 1) {
422 const char*tmp = strchr(str, ',');
423 if (tmp == 0) tmp = str+strlen(str);
424
425 pins[idx] = malloc(tmp-str+1);
426 strncpy(pins[idx], str, tmp-str);
427 pins[idx][tmp-str] = 0;
428
429 if (*tmp != 0)
430 tmp += 1;
431
432 str = tmp;
433 }
434
435 /* Now go through the pins of the signal, creating pads and
436 bufs and joining them to the signal nexus. */
437 for (idx = 0 ; idx < ivl_signal_pins(sig) ; idx += 1) {
438 edif_joint_t jnt;
439 edif_cellref_t pad, buf;
440
441 const char*name_str = ivl_signal_basename(sig);
442 if (ivl_signal_pins(sig) > 1) {
443 char name_buf[128];
444 sprintf(name_buf, "%s[%u]", name_str, idx);
445 name_str = strdup(name_buf);
446 }
447
448 switch (ivl_signal_port(sig)) {
449 case IVL_SIP_INPUT:
450 pad = edif_cellref_create(edf, cell_ipad);
451 buf = edif_cellref_create(edf, xilinx_cell_ibuf(xlib));
452
453 jnt = edif_joint_create(edf);
454 edif_joint_rename(jnt, name_str);
455 edif_add_to_joint(jnt, pad, 0);
456 edif_add_to_joint(jnt, buf, BUF_I);
457
458 jnt = edif_joint_of_nexus(edf, ivl_signal_pin(sig, idx));
459 edif_add_to_joint(jnt, buf, BUF_O);
460 break;
461
462 case IVL_SIP_OUTPUT:
463 pad = edif_cellref_create(edf, cell_opad);
464 buf = edif_cellref_create(edf, xilinx_cell_obuf(xlib));
465
466 jnt = edif_joint_create(edf);
467 edif_joint_rename(jnt, name_str);
468 edif_add_to_joint(jnt, pad, 0);
469 edif_add_to_joint(jnt, buf, BUF_O);
470
471 jnt = edif_joint_of_nexus(edf, ivl_signal_pin(sig, idx));
472 edif_add_to_joint(jnt, buf, BUF_I);
473 break;
474
475 case IVL_SIP_INOUT:
476 pad = edif_cellref_create(edf, cell_iopad);
477
478 jnt = edif_joint_of_nexus(edf, ivl_signal_pin(sig, idx));
479 edif_add_to_joint(jnt, pad, 0);
480 break;
481
482 default:
483 assert(0);
484 }
485
486 if (pins[idx])
487 edif_cellref_pstring(pad, "LOC", pins[idx]);
488
489 }
490
491 /* Don't free the allocated pad name strings. The
492 edif_cellref_pstring function attached the string to the
493 LOC attribute, so the reference is permanent. */
494
495 free(pins);
496 }
497
498 /*
499 * This function handles the case where the user specifies the cell to
500 * use by attribute.
501 */
edif_cellref_logic(ivl_net_logic_t net,const char * def)502 static void edif_cellref_logic(ivl_net_logic_t net, const char*def)
503 {
504 char*str = strdup(def);
505 char*pins;
506 edif_cell_t cell;
507 edif_cellref_t ref;
508 unsigned idx;
509
510 pins = strchr(str, ':');
511 assert(pins);
512 *pins++ = 0;
513
514 /* Locate the cell in the library, lookup by name. */
515 cell = edif_xlibrary_findcell(xlib, str);
516 assert(cell);
517
518 ref = edif_cellref_create(edf, cell);
519
520 for (idx = 0 ; idx < ivl_logic_pins(net) ; idx += 1) {
521 char*tmp;
522 edif_joint_t jnt;
523 unsigned port;
524
525 assert(pins);
526 tmp = strchr(pins,',');
527 if (tmp != 0)
528 *tmp++ = 0;
529 else
530 tmp = 0;
531
532 port = edif_cell_port_byname(cell, pins);
533 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx));
534 edif_add_to_joint(jnt, ref, port);
535
536 pins = tmp;
537 }
538
539 free(str);
540 }
541
lut_logic(ivl_net_logic_t net,const char * init3,const char * init4,const char * init5)542 static void lut_logic(ivl_net_logic_t net, const char*init3,
543 const char*init4, const char*init5)
544 {
545 edif_cellref_t lut = NULL; /* initialization shuts up gcc -Wall */
546 edif_joint_t jnt;
547 const char* init = NULL; /* ditto */
548
549 assert(ivl_logic_pins(net) <= 5);
550 assert(ivl_logic_pins(net) >= 3);
551
552 switch (ivl_logic_pins(net)) {
553 case 3:
554 lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
555 init = init3;
556 break;
557
558 case 4:
559 lut = edif_cellref_create(edf, xilinx_cell_lut3(xlib));
560 init = init4;
561 break;
562
563 case 5:
564 lut = edif_cellref_create(edf, xilinx_cell_lut4(xlib));
565 init = init5;
566 break;
567 }
568
569 edif_cellref_pstring(lut, "INIT", init);
570
571 switch (ivl_logic_pins(net)) {
572 case 5:
573 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 4));
574 edif_add_to_joint(jnt, lut, LUT_I3);
575 case 4:
576 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 3));
577 edif_add_to_joint(jnt, lut, LUT_I2);
578 case 3:
579 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 2));
580 edif_add_to_joint(jnt, lut, LUT_I1);
581 }
582
583 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1));
584 edif_add_to_joint(jnt, lut, LUT_I0);
585
586 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0));
587 edif_add_to_joint(jnt, lut, LUT_O);
588 }
589
590
xilinx_logic(ivl_net_logic_t net)591 void xilinx_logic(ivl_net_logic_t net)
592 {
593 edif_cellref_t obj;
594 edif_joint_t jnt;
595
596 { const char*cellref_attribute = ivl_logic_attr(net, "cellref");
597 if (cellref_attribute != 0) {
598 edif_cellref_logic(net, cellref_attribute);
599 return;
600 }
601 }
602
603 switch (ivl_logic_type(net)) {
604
605 case IVL_LO_BUF:
606 case IVL_LO_BUFZ:
607 assert(ivl_logic_pins(net) == 2);
608
609 obj = edif_cellref_create(edf, xilinx_cell_buf(xlib));
610
611 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0));
612 edif_add_to_joint(jnt, obj, BUF_O);
613
614 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1));
615 edif_add_to_joint(jnt, obj, BUF_I);
616 break;
617
618 case IVL_LO_BUFIF0:
619 /* The Xilinx BUFT devices is a BUF that adds a T
620 input. The output is tri-stated if the T input is
621 1. In other words, it acts just like bufif0. */
622 assert(ivl_logic_pins(net) == 3);
623
624 obj = edif_cellref_create(edf, xilinx_cell_buft(xlib));
625
626 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0));
627 edif_add_to_joint(jnt, obj, BUF_O);
628
629 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1));
630 edif_add_to_joint(jnt, obj, BUF_I);
631
632 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 2));
633 edif_add_to_joint(jnt, obj, BUF_T);
634 break;
635
636 case IVL_LO_BUFIF1:
637 /* The Xilinx BUFE devices is a BUF that adds an enable
638 input. The output is tri-stated if the E input is 0.
639 In other words, it acts just like bufif1. */
640 assert(ivl_logic_pins(net) == 3);
641
642 obj = edif_cellref_create(edf, xilinx_cell_bufe(xlib));
643
644 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0));
645 edif_add_to_joint(jnt, obj, BUF_O);
646
647 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1));
648 edif_add_to_joint(jnt, obj, BUF_I);
649
650 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 2));
651 edif_add_to_joint(jnt, obj, BUF_T);
652 break;
653
654 case IVL_LO_NOT:
655 assert(ivl_logic_pins(net) == 2);
656
657 obj = edif_cellref_create(edf, xilinx_cell_inv(xlib));
658
659 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0));
660 edif_add_to_joint(jnt, obj, BUF_O);
661
662 jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1));
663 edif_add_to_joint(jnt, obj, BUF_I);
664 break;
665
666 case IVL_LO_AND:
667 assert(ivl_logic_pins(net) <= 5);
668 assert(ivl_logic_pins(net) >= 3);
669 lut_logic(net, "8", "80", "8000");
670 break;
671
672 case IVL_LO_NOR:
673 assert(ivl_logic_pins(net) <= 5);
674 assert(ivl_logic_pins(net) >= 3);
675 lut_logic(net, "1", "01", "0001");
676 break;
677
678 case IVL_LO_OR:
679 assert(ivl_logic_pins(net) <= 5);
680 assert(ivl_logic_pins(net) >= 3);
681 lut_logic(net, "E", "FE", "FFFE");
682 break;
683
684 case IVL_LO_XNOR:
685 assert(ivl_logic_pins(net) <= 5);
686 assert(ivl_logic_pins(net) >= 3);
687 lut_logic(net, "9", "69", "9669");
688 break;
689
690 case IVL_LO_XOR:
691 assert(ivl_logic_pins(net) <= 5);
692 assert(ivl_logic_pins(net) >= 3);
693 lut_logic(net, "6", "96", "6996");
694 break;
695
696 default:
697 fprintf(stderr, "UNSUPPORTED LOGIC TYPE: %d\n",
698 ivl_logic_type(net));
699 break;
700 }
701 }
702
703 /*
704 * A fully generic Xilinx MUX is implemented entirely from LUT
705 * devices.
706 */
xilinx_mux(ivl_lpm_t net)707 void xilinx_mux(ivl_lpm_t net)
708 {
709 unsigned idx;
710
711 assert(ivl_lpm_selects(net) == 1);
712
713 /* A/B Mux devices are made from LUT3 devices. I0 is connected
714 to A, I1 to B, and I2 to the Select input. Create as many
715 as are needed to implement the requested width.
716
717 S B A | Q
718 ------+--
719 0 0 0 | 0
720 0 0 1 | 1
721 0 1 0 | 0
722 0 1 1 | 1
723 1 0 0 | 0
724 1 0 1 | 0
725 1 1 0 | 1
726 1 1 1 | 1
727
728 INIT = "CA" */
729
730 for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) {
731 edif_cellref_t lut;
732 edif_joint_t jnt;
733
734 lut = edif_cellref_create(edf, xilinx_cell_lut3(xlib));
735
736 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx));
737 edif_add_to_joint(jnt, lut, LUT_O);
738
739 jnt = edif_joint_of_nexus(edf, ivl_lpm_data2(net, 0, idx));
740 edif_add_to_joint(jnt, lut, LUT_I0);
741
742 jnt = edif_joint_of_nexus(edf, ivl_lpm_data2(net, 1, idx));
743 edif_add_to_joint(jnt, lut, LUT_I1);
744
745 jnt = edif_joint_of_nexus(edf, ivl_lpm_select(net, 0));
746 edif_add_to_joint(jnt, lut, LUT_I2);
747
748 edif_cellref_pstring(lut, "INIT", "CA");
749 }
750 }
751
752 /*
753 * Any Xilinx device works with this adder.
754 * Generic Xilinx add only works for single bit slices.
755 */
xilinx_add(ivl_lpm_t net)756 void xilinx_add(ivl_lpm_t net)
757 {
758 const char*ha_init = 0;
759
760 switch (ivl_lpm_type(net)) {
761 case IVL_LPM_ADD:
762 ha_init = "6";
763 break;
764 case IVL_LPM_SUB:
765 ha_init = "9";
766 break;
767 default:
768 assert(0);
769 }
770
771 /* If this is a single bit wide, then generate only a
772 half-adder. Normally this is an XOR, but if this is a SUB
773 then it is an XNOR. */
774 if (ivl_lpm_width(net) == 1) {
775 edif_cellref_t lut;
776 edif_joint_t jnt;
777
778 lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
779
780 jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0));
781 edif_add_to_joint(jnt, lut, LUT_O);
782
783 jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0));
784 edif_add_to_joint(jnt, lut, LUT_I0);
785
786 jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0));
787 edif_add_to_joint(jnt, lut, LUT_I1);
788
789 edif_cellref_pstring(lut, "INIT", ha_init);
790 return;
791 }
792
793 assert(0);
794 }
795
796 /*
797 * The left shift is implemented as a matrix of MUX2_1 devices. The
798 * matrix has as many rows as the device width, and a column for each
799 * select.
800 */
xilinx_shiftl(ivl_lpm_t net)801 void xilinx_shiftl(ivl_lpm_t net)
802 {
803 unsigned width = ivl_lpm_width(net);
804 unsigned nsel = 0;
805 unsigned sdx, qdx;
806
807 edif_cellref_t* cells;
808 edif_cellref_t**table;
809
810 edif_cellref_t pad0_cell;
811 edif_joint_t pad0;
812
813
814 /* First, find out how many select inputs we really need. We
815 can only use the selects that are enough to shift out the
816 entire width of the device. The excess can be used as an
817 enable for the last column. When disabled, the last column
818 emits zeros. */
819
820 while (nsel < ivl_lpm_selects(net)) {
821 unsigned swid;
822
823 nsel += 1;
824
825 swid = 1 << nsel;
826 if (swid >= width)
827 break;
828 }
829
830 assert(nsel > 0);
831
832 /* Allocate a matrix of edif_cellref_t variables. A devices
833 will be addressed by the expression table[sdx][qdx];
834 This should make the algorithm code easier to read. */
835 cells = calloc(nsel * width, sizeof(edif_cellref_t));
836 table = calloc(nsel, sizeof(edif_cellref_t*));
837
838 for (sdx = 0 ; sdx < nsel ; sdx += 1)
839 table[sdx] = cells + sdx*width;
840
841 /* Make a 0 valued pad bit. I will use this for all the shift in
842 values that are beyond the input. */
843 pad0_cell = edif_cellref_create(edf, cell_0);
844 pad0 = edif_joint_create(edf);
845 edif_add_to_joint(pad0, pad0_cell, 0);
846
847 /* The LUT matrix is <nsel> columns of <width> devices, with
848 the last column a LUT4 devices. The extra input of the
849 LUT4s in the last column are used as an enable to collect
850 all the excess select inputs. */
851
852 /* Allocate the LUT devices of the matrix, and connect the
853 select inputs to I2 of all the devices of the column. */
854 for (sdx = 0 ; sdx < nsel ; sdx += 1) {
855 const char*init_string = 0;
856 ivl_nexus_t nex = ivl_lpm_select(net,sdx);
857 edif_joint_t sdx_jnt = edif_joint_of_nexus(edf, nex);
858
859 edif_cell_t lut;
860
861 if (((sdx+1) == nsel) && (nsel < ivl_lpm_selects(net))) {
862 lut = xilinx_cell_lut4(xlib);
863 init_string = "00CA";
864 } else {
865 lut = xilinx_cell_lut3(xlib);
866 init_string = "CA";
867 }
868
869 for (qdx = 0 ; qdx < width ; qdx += 1) {
870 table[sdx][qdx] = edif_cellref_create(edf, lut);
871 edif_add_to_joint(sdx_jnt, table[sdx][qdx], LUT_I2);
872
873 edif_cellref_pstring(table[sdx][qdx], "INIT", init_string);
874 }
875 }
876
877 /* Connect the inputs of the SHIFTL device to the column 0 LUT
878 inputs. The slice on the low end shifts in a 0 for a select
879 input. */
880 for (qdx = 0 ; qdx < width ; qdx += 1) {
881 ivl_nexus_t nex0;
882 edif_joint_t jnt0;
883 edif_joint_t jnt1;
884
885 nex0 = ivl_lpm_data(net,qdx);
886 jnt0 = edif_joint_of_nexus(edf, nex0);
887
888 if (qdx > 0) {
889 ivl_nexus_t nex1;
890 nex1 = ivl_lpm_data(net,qdx-1);
891 jnt1 = edif_joint_of_nexus(edf, nex1);
892 } else {
893 jnt1 = pad0;
894 }
895
896 edif_add_to_joint(jnt0, table[0][qdx], LUT_I0);
897 edif_add_to_joint(jnt1, table[0][qdx], LUT_I1);
898 }
899
900 /* Make the inner connections between LUT devices. Each column
901 connects to the previous column, shifted by the power of
902 the column value. If the shifted input falls off the end,
903 then pad with zero. */
904 for (sdx = 1 ; sdx < nsel ; sdx += 1) {
905
906 for (qdx = 0 ; qdx < width ; qdx += 1) {
907 unsigned shift = 1 << sdx;
908 edif_joint_t jnt0 = edif_joint_create(edf);
909 edif_joint_t jnt1 = (qdx >= shift)
910 ? edif_joint_create(edf)
911 : pad0;
912
913 edif_add_to_joint(jnt0, table[sdx][qdx], LUT_I0);
914 edif_add_to_joint(jnt1, table[sdx][qdx], LUT_I1);
915
916 edif_add_to_joint(jnt0, table[sdx-1][qdx], LUT_O);
917 if (qdx >= shift)
918 edif_add_to_joint(jnt1, table[sdx-1][qdx-shift], LUT_O);
919 }
920 }
921
922 /* Connect the output of the last column to the output of the
923 SHIFTL device. */
924 for (qdx = 0 ; qdx < width ; qdx += 1) {
925 ivl_nexus_t nex = ivl_lpm_q(net,qdx);
926 edif_joint_t jnt = edif_joint_of_nexus(edf, nex);
927
928 edif_add_to_joint(jnt, table[nsel-1][qdx], LUT_O);
929 }
930
931 /* Connect the excess select inputs to the enable inputs of
932 the LUT4 devices in the last column. */
933 if (nsel < ivl_lpm_selects(net)) {
934 edif_joint_t jnt;
935
936 /* XXXX Only support 1 excess bit for now. */
937 assert((nsel + 1) == ivl_lpm_selects(net));
938
939 jnt = edif_joint_of_nexus(edf, ivl_lpm_select(net,nsel));
940 for (qdx = 0 ; qdx < width ; qdx += 1)
941 edif_add_to_joint(jnt, table[nsel-1][qdx], LUT_I3);
942 }
943
944 free(cells);
945 free(table);
946 }
947