Add support for text macros with arguments.
[iverilog.git] / tgt-fpga / d-generic-edif.c
blobb998eb35006b47a846b6e180efdd94ef05087f53
1 /*
2 * Copyright (c) 2001 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-generic-edif.c,v 1.18 2004/10/04 01:10:56 steve Exp $"
21 #endif
23 # include "device.h"
24 # include "fpga_priv.h"
25 # include <stdlib.h>
26 # include <string.h>
27 #ifdef HAVE_MALLOC_H
28 # include <malloc.h>
29 #endif
30 # include <assert.h>
32 struct nexus_recall {
33 struct nexus_recall*next;
34 ivl_nexus_t nex;
35 char* joined;
37 static struct nexus_recall*net_list = 0;
39 static unsigned edif_uref = 0;
41 static void edif_set_nexus_joint(ivl_nexus_t nex, const char*joint)
43 size_t newlen;
44 struct nexus_recall*rec;
46 rec = (struct nexus_recall*)ivl_nexus_get_private(nex);
47 if (rec == 0) {
48 rec = malloc(sizeof(struct nexus_recall));
49 rec->nex = nex;
50 rec->joined = malloc(8);
51 rec->joined[0] = 0;
52 rec->next = net_list;
53 net_list = rec;
54 ivl_nexus_set_private(nex, rec);
57 newlen = strlen(rec->joined) + strlen(joint) + 2;
58 rec->joined = realloc(rec->joined, newlen);
59 strcat(rec->joined, " ");
60 strcat(rec->joined, joint);
64 static void show_root_ports_edif(ivl_scope_t root)
66 char jbuf[1024];
67 unsigned cnt = ivl_scope_sigs(root);
68 unsigned idx;
70 for (idx = 0 ; idx < cnt ; idx += 1) {
71 ivl_signal_t sig = ivl_scope_sig(root, idx);
72 const char*use_name;
73 const char*dir = 0;
75 if (ivl_signal_attr(sig, "PAD") != 0)
76 continue;
78 switch (ivl_signal_port(sig)) {
79 case IVL_SIP_NONE:
80 continue;
82 case IVL_SIP_INPUT:
83 dir = "INPUT";
84 break;
86 case IVL_SIP_OUTPUT:
87 dir = "OUTPUT";
88 break;
90 case IVL_SIP_INOUT:
91 dir = "INOUT";
92 break;
95 use_name = ivl_signal_basename(sig);
96 if (ivl_signal_pins(sig) == 1) {
97 fprintf(xnf, " (port %s (direction %s))\n",
98 use_name, dir);
100 sprintf(jbuf, "(portRef %s)", use_name);
101 edif_set_nexus_joint(ivl_signal_pin(sig, 0), jbuf);
103 } else {
104 unsigned pin;
106 for (pin = 0 ; pin < ivl_signal_pins(sig); pin += 1) {
107 fprintf(xnf, " (port (rename %s_%u "
108 "\"%s[%u]\") (direction %s))\n", use_name,
109 pin, use_name, pin, dir);
110 sprintf(jbuf, "(portRef %s_%u)", use_name, pin);
111 edif_set_nexus_joint(ivl_signal_pin(sig, pin), jbuf);
118 static void edif_show_header_generic(ivl_design_t des, const char*library)
120 ivl_scope_t root = ivl_design_root(des);
122 /* write the primitive header */
123 fprintf(xnf, "(edif %s\n", ivl_scope_name(root));
124 fprintf(xnf, " (edifVersion 2 0 0)\n");
125 fprintf(xnf, " (edifLevel 0)\n");
126 fprintf(xnf, " (keywordMap (keywordLevel 0))\n");
127 fprintf(xnf, " (status\n");
128 fprintf(xnf, " (written\n");
129 fprintf(xnf, " (timeStamp 0 0 0 0 0 0)\n");
130 fprintf(xnf, " (author \"unknown\")\n");
131 fprintf(xnf, " (program \"Icarus Verilog/fpga.tgt\")))\n");
133 /* Write out the external references here? */
134 fputs(library, xnf);
136 /* Write out the library header */
137 fprintf(xnf, " (library DESIGN\n");
138 fprintf(xnf, " (edifLevel 0)\n");
139 fprintf(xnf, " (technology (numberDefinition))\n");
141 /* The root module is a cell in the library. */
142 fprintf(xnf, " (cell %s\n", ivl_scope_name(root));
143 fprintf(xnf, " (cellType GENERIC)\n");
144 fprintf(xnf, " (view net\n");
145 fprintf(xnf, " (viewType NETLIST)\n");
146 fprintf(xnf, " (interface\n");
148 show_root_ports_edif(root);
150 fprintf(xnf, " )\n"); /* end the (interface ) sexp */
152 fprintf(xnf, " (contents\n");
155 static const char*external_library_text =
156 " (external VIRTEX (edifLevel 0) (technology (numberDefinition))\n"
157 " (cell AND2 (cellType GENERIC)\n"
158 " (view net\n"
159 " (viewType NETLIST)\n"
160 " (interface\n"
161 " (port O (direction OUTPUT))\n"
162 " (port I0 (direction INPUT))\n"
163 " (port I1 (direction INPUT)))))\n"
164 " (cell BUF (cellType GENERIC)\n"
165 " (view net\n"
166 " (viewType NETLIST)\n"
167 " (interface\n"
168 " (port O (direction OUTPUT))\n"
169 " (port I (direction INPUT)))))\n"
170 " (cell FDCE (cellType GENERIC)\n"
171 " (view net\n"
172 " (viewType NETLIST)\n"
173 " (interface\n"
174 " (port Q (direction OUTPUT))\n"
175 " (port D (direction INPUT))\n"
176 " (port C (direction INPUT))\n"
177 " (port CE (direction INPUT))\n"
178 " (port CLR (direction INPUT)))))\n"
179 " (cell FDCPE (cellType GENERIC)\n"
180 " (view net\n"
181 " (viewType NETLIST)\n"
182 " (interface\n"
183 " (port Q (direction OUTPUT))\n"
184 " (port D (direction INPUT))\n"
185 " (port C (direction INPUT))\n"
186 " (port CE (direction INPUT))\n"
187 " (port PRE (direction INPUT))\n"
188 " (port CLR (direction INPUT)))))\n"
189 " (cell GND (cellType GENERIC)\n"
190 " (view net\n"
191 " (viewType NETLIST)\n"
192 " (interface (port G (direction OUTPUT)))))\n"
193 " (cell NOR2 (cellType GENERIC)\n"
194 " (view net\n"
195 " (viewType NETLIST)\n"
196 " (interface\n"
197 " (port O (direction OUTPUT))\n"
198 " (port I0 (direction INPUT))\n"
199 " (port I1 (direction INPUT)))))\n"
200 " (cell NOR3 (cellType GENERIC)\n"
201 " (view net\n"
202 " (viewType NETLIST)\n"
203 " (interface\n"
204 " (port O (direction OUTPUT))\n"
205 " (port I0 (direction INPUT))\n"
206 " (port I1 (direction INPUT))\n"
207 " (port I2 (direction INPUT)))))\n"
208 " (cell VCC (cellType GENERIC)\n"
209 " (view net\n"
210 " (viewType NETLIST)\n"
211 " (interface (port P (direction OUTPUT)))))\n"
212 " )\n"
215 static void edif_show_header(ivl_design_t des)
217 edif_show_header_generic(des, external_library_text);
220 static void edif_show_consts(ivl_design_t des)
222 unsigned idx;
223 char jbuf[128];
225 for (idx = 0 ; idx < ivl_design_consts(des) ; idx += 1) {
226 unsigned pin;
227 ivl_net_const_t net = ivl_design_const(des, idx);
228 const char*val = ivl_const_bits(net);
230 for (pin = 0 ; pin < ivl_const_pins(net) ; pin += 1) {
231 ivl_nexus_t nex = ivl_const_pin(net, pin);
232 const char*name;
233 const char*port;
235 edif_uref += 1;
237 switch (val[pin]) {
238 case '0':
239 name = "GND";
240 port = "GROUND";
241 break;
242 case '1':
243 name = "VCC";
244 port = "VCC";
245 break;
246 default:
247 name = "???";
248 port = "?";
249 break;
252 fprintf(xnf, "(instance U%u "
253 "(viewRef net"
254 " (cellRef %s (libraryRef VIRTEX))))\n",
255 edif_uref, name);
257 sprintf(jbuf, "(portRef %s (instanceRef U%u))",
258 port, edif_uref);
259 edif_set_nexus_joint(nex, jbuf);
265 static void edif_show_footer(ivl_design_t des)
267 unsigned nref = 0;
268 struct nexus_recall*cur;
269 ivl_scope_t root = ivl_design_root(des);
271 edif_show_consts(des);
273 for (cur = net_list ; cur ; cur = cur->next) {
274 fprintf(xnf, "(net (rename N%u \"%s\") (joined %s))\n",
275 nref, ivl_nexus_name(cur->nex), cur->joined);
276 nref += 1;
279 fprintf(xnf, " )\n"); /* end the (contents ) sexp */
280 fprintf(xnf, " )\n"); /* end the (view ) sexp */
281 fprintf(xnf, " )\n"); /* end the (cell ) sexp */
282 fprintf(xnf, " )\n"); /* end the (library ) sexp */
284 /* Make an instance of the defined object */
285 fprintf(xnf, " (design %s\n", ivl_scope_name(root));
286 fprintf(xnf, " (cellRef %s (libraryRef DESIGN))\n",
287 ivl_scope_name(root));
289 if (part)
290 fprintf(xnf, " (property PART (string \"%s\"))\n", part);
292 fprintf(xnf, " )\n");
294 fprintf(xnf, ")\n"); /* end the (edif ) sexp */
297 static void edif_show_logic(ivl_net_logic_t net)
299 char jbuf[1024];
300 unsigned idx;
302 edif_uref += 1;
304 switch (ivl_logic_type(net)) {
306 case IVL_LO_AND:
307 assert(ivl_logic_pins(net) <= 10);
308 assert(ivl_logic_pins(net) >= 3);
310 fprintf(xnf, "(instance (rename U%u \"%s\")",
311 edif_uref, ivl_logic_name(net));
312 fprintf(xnf, " (viewRef net"
313 " (cellRef AND%u (libraryRef VIRTEX))))\n",
314 ivl_logic_pins(net) - 1);
316 sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref);
317 edif_set_nexus_joint(ivl_logic_pin(net, 0), jbuf);
319 for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) {
320 sprintf(jbuf, "(portRef I%u (instanceRef U%u))",
321 idx-1, edif_uref);
322 edif_set_nexus_joint(ivl_logic_pin(net, idx), jbuf);
324 break;
326 case IVL_LO_BUF:
327 assert(ivl_logic_pins(net) == 2);
328 fprintf(xnf, "(instance (rename U%u \"%s\")",
329 edif_uref, ivl_logic_name(net));
330 fprintf(xnf, " (viewRef net"
331 " (cellRef BUF (libraryRef VIRTEX))))\n");
333 sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref);
334 edif_set_nexus_joint(ivl_logic_pin(net, 0), jbuf);
336 sprintf(jbuf, "(portRef I (instanceRef U%u))", edif_uref);
337 edif_set_nexus_joint(ivl_logic_pin(net, 1), jbuf);
338 break;
340 case IVL_LO_BUFZ:
342 static int bufz_warned_once=0;
343 if (!bufz_warned_once) {
344 fprintf (stderr,
345 "0:0: internal warning: BUFZ objects found "
346 "in EDIF netlist.\n");
347 fprintf (stderr,
348 "0:0: : I'll make BUFs for them.\n");
349 bufz_warned_once=1;
351 assert(ivl_logic_pins(net) == 2);
352 fprintf(xnf, "(instance (rename U%u \"%s\")",
353 edif_uref, ivl_logic_name(net));
354 fprintf(xnf, " (viewRef net"
355 " (cellRef BUF (libraryRef VIRTEX))))\n");
357 sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref);
358 edif_set_nexus_joint(ivl_logic_pin(net, 0), jbuf);
360 sprintf(jbuf, "(portRef I (instanceRef U%u))", edif_uref);
361 edif_set_nexus_joint(ivl_logic_pin(net, 1), jbuf);
363 break;
365 case IVL_LO_NOR:
366 assert(ivl_logic_pins(net) <= 10);
367 assert(ivl_logic_pins(net) >= 3);
369 fprintf(xnf, "(instance (rename U%u \"%s\")",
370 edif_uref, ivl_logic_name(net));
371 fprintf(xnf, " (viewRef net"
372 " (cellRef NOR%u (libraryRef VIRTEX))))\n",
373 ivl_logic_pins(net) - 1);
375 sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref);
376 edif_set_nexus_joint(ivl_logic_pin(net, 0), jbuf);
378 for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) {
379 sprintf(jbuf, "(portRef I%u (instanceRef U%u))",
380 idx-1, edif_uref);
381 edif_set_nexus_joint(ivl_logic_pin(net, idx), jbuf);
383 break;
385 default:
386 fprintf(stderr, "UNSUPPORT LOGIC TYPE: %u\n", ivl_logic_type(net));
390 static void edif_show_generic_dff(ivl_lpm_t net)
392 ivl_nexus_t nex;
393 char jbuf[1024];
394 unsigned idx;
395 ivl_nexus_t aclr = ivl_lpm_async_clr(net);
396 ivl_nexus_t aset = ivl_lpm_async_set(net);
397 ivl_expr_t avalue = 0;
398 const char*abits = 0;
399 const char*fdcell = "FDCE";
401 if (aset != 0) {
402 fdcell = "FDCPE";
403 avalue = ivl_lpm_aset_value(net);
404 assert(avalue);
405 abits = ivl_expr_bits(avalue);
406 assert(abits);
409 for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) {
411 edif_uref += 1;
413 fprintf(xnf, "(instance (rename U%u \"%s.%s[%u]\")",
414 edif_uref, ivl_scope_name(ivl_lpm_scope(net)),
415 ivl_lpm_basename(net), idx);
416 fprintf(xnf, " (viewRef net"
417 " (cellRef %s (libraryRef VIRTEX))))\n",
418 fdcell);
420 nex = ivl_lpm_q(net, idx);
421 sprintf(jbuf, "(portRef Q (instanceRef U%u))", edif_uref);
422 edif_set_nexus_joint(nex, jbuf);
424 nex = ivl_lpm_data(net, idx);
425 sprintf(jbuf, "(portRef D (instanceRef U%u))", edif_uref);
426 edif_set_nexus_joint(nex, jbuf);
428 nex = ivl_lpm_clk(net);
429 sprintf(jbuf, "(portRef C (instanceRef U%u))", edif_uref);
430 edif_set_nexus_joint(nex, jbuf);
432 if ((nex = ivl_lpm_enable(net))) {
433 sprintf(jbuf, "(portRef CE (instanceRef U%u))", edif_uref);
434 edif_set_nexus_joint(nex, jbuf);
437 if (aclr) {
438 sprintf(jbuf, "(portRef CLR (instanceRef U%u))", edif_uref);
439 edif_set_nexus_joint(aclr, jbuf);
443 if (aset) {
444 if (abits[idx] == '1') {
445 sprintf(jbuf, "(portRef PRE (instanceRef U%u))",
446 edif_uref);
447 edif_set_nexus_joint(aset, jbuf);
448 } else {
449 assert(aclr == 0);
450 sprintf(jbuf, "(portRef CLR (instanceRef U%u))",
451 edif_uref);
452 edif_set_nexus_joint(aset, jbuf);
459 const struct device_s d_generic_edif = {
460 edif_show_header,
461 edif_show_footer,
462 0, /* show_cell_scope not implemented. */
463 0, /* draw_pad not implemented */
464 edif_show_logic,
465 edif_show_generic_dff,
466 0, /* show_cmp_eq */
467 0, /* show_cmp_ne */
468 0, /* show_cmp_ge */
469 0, /* show_cmp_gt */
471 0, /* show_add */
472 0, /* show_sub */
473 0, /* show_shiftl */
474 0 /* show_shiftr */
479 * $Log: d-generic-edif.c,v $
480 * Revision 1.18 2004/10/04 01:10:56 steve
481 * Clean up spurious trailing white space.
483 * Revision 1.17 2003/11/12 03:20:14 steve
484 * devices need show_cmp_gt
486 * Revision 1.16 2003/07/02 00:48:03 steve
487 * No longer export generic-edif functions.
489 * Revision 1.15 2003/06/24 03:55:00 steve
490 * Add ivl_synthesis_cell support for virtex2.
492 * Revision 1.14 2003/06/17 03:47:41 steve
493 * Handle bufz as buf in generic fpga/edif target.
495 * Revision 1.13 2003/02/26 01:24:42 steve
496 * ivl_lpm_name is obsolete.
498 * Revision 1.12 2002/11/01 02:36:22 steve
499 * Give nets better names, if available.
501 * Revision 1.11 2002/10/30 03:58:45 steve
502 * Fix up left shift to pass compile,
503 * fix up ADD/SUB to generate missing pieces,
504 * Add the asynch set/reset to DFF devices.
506 * Revision 1.10 2002/10/28 02:05:56 steve
507 * Add Virtex code generators for left shift,
508 * subtraction, and GE comparators.
510 * Revision 1.9 2002/08/12 01:35:02 steve
511 * conditional ident string using autoconfig.
513 * Revision 1.8 2002/08/11 23:47:04 steve
514 * Add missing Log and Ident strings.
516 * Revision 1.7 2001/09/16 01:48:16 steve
517 * Suppor the PAD attribute on signals.
519 * Revision 1.6 2001/09/15 18:27:04 steve
520 * Make configure detect malloc.h
522 * Revision 1.5 2001/09/15 05:06:04 steve
523 * Support != in virtex code generator.
525 * Revision 1.4 2001/09/09 22:23:28 steve
526 * Virtex support for mux devices and adders
527 * with carry chains. Also, make Virtex specific
528 * implementations of primitive logic.
530 * Revision 1.3 2001/09/06 04:28:40 steve
531 * Separate the virtex and generic-edif code generators.
533 * Revision 1.2 2001/09/02 23:53:55 steve
534 * Add virtex support for some basic logic, the DFF
535 * and constant signals.
537 * Revision 1.1 2001/09/02 21:33:07 steve
538 * Rearrange the XNF code generator to be generic-xnf
539 * so that non-XNF code generation is also possible.
541 * Start into the virtex EDIF output driver.