Support for wide modulus operations.
[iverilog.git] / tgt-fpga / edif.c
blob2cba3bc071d129ac418cc7c9e7a52215fe3024e7
1 /*
2 * Copyright (c) 200Stephen 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: edif.c,v 1.8 2003/09/03 23:34:09 steve Exp $"
21 #endif
23 # include "edif.h"
24 # include <stdlib.h>
25 # include <string.h>
26 #ifdef HAVE_MALLOC_H
27 # include <malloc.h>
28 #endif
29 # include <assert.h>
31 typedef enum property_e {
32 PRP_NONE = 0,
33 PRP_STRING,
34 PRP_INTEGER
35 } property_t;
37 struct cellref_property_ {
38 const char*name;
39 property_t ptype;
40 union {
41 const char*str;
42 long num;
43 } value_;
44 struct cellref_property_*next;
47 struct edif_s {
48 const char*name;
49 /* List the ports of the design. */
50 unsigned nports;
51 struct __cell_port*ports;
52 /* All the external libraries attached to me. */
53 edif_xlibrary_t xlibs;
54 /* list the cellref instances. */
55 edif_cellref_t celref;
56 /* The root instance has cellref properties as well. */
57 struct cellref_property_*property;
58 /* Keep a list of all the nexa */
59 struct edif_joint_s*nexa;
62 struct edif_xlibrary_s {
63 /* Name of this library. */
64 const char*name;
65 /* The cells that are contained in this library. */
66 struct edif_cell_s*cells;
67 /* point to the optional celltable. */
68 const struct edif_xlib_celltable*celltable;
69 /* used to list libraries in an edif_t. */
70 struct edif_xlibrary_s*next;
74 struct __cell_port {
75 const char*name;
76 const char*ename;
77 struct cellref_property_*property;
78 ivl_signal_port_t dir;
81 struct edif_cell_s {
82 const char*name;
83 edif_xlibrary_t xlib;
85 unsigned nports;
86 struct __cell_port*ports;
88 struct cellref_property_*property;
89 struct edif_cell_s*next;
92 struct edif_cellref_s {
93 struct edif_cell_s* cell;
94 unsigned u;
95 struct cellref_property_*property;
96 struct edif_cellref_s* next;
99 struct joint_cell_ {
100 struct edif_cellref_s*cell;
101 unsigned port;
102 struct joint_cell_*next;
105 struct edif_joint_s {
106 const char*name;
107 struct joint_cell_*links;
108 struct edif_joint_s*next;
112 static int is_edif_name(const char*text)
114 static const char*edif_name_chars = "abcdefghijklmnopqrstuvwxyz"
115 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
116 "0123456789";
117 return (strspn(text, edif_name_chars) == strlen(text));
120 edif_t edif_create(const char*design_name, unsigned nports)
122 edif_t edf = malloc(sizeof(struct edif_s));
124 edf->name = design_name;
125 edf->nports= nports;
126 edf->ports = nports? calloc(nports, sizeof(struct __cell_port)) : 0;
127 edf->celref= 0;
128 edf->xlibs = 0;
129 edf->property = 0;
130 edf->nexa = 0;
132 return edf;
135 void edif_portconfig(edif_t edf, unsigned idx,
136 const char*name, ivl_signal_port_t dir)
138 assert(idx < edf->nports);
140 edf->ports[idx].name = name;
141 if (is_edif_name(name)) {
142 edf->ports[idx].ename = 0;
144 } else {
145 char buf[16];
146 sprintf(buf, "PORT%u", idx);
147 edf->ports[idx].ename = strdup(buf);
150 edf->ports[idx].dir = dir;
153 void edif_port_to_joint(edif_joint_t jnt, edif_t edf, unsigned port)
155 struct joint_cell_* jc = malloc(sizeof(struct joint_cell_));
157 jc->cell = 0;
158 jc->port = port;
159 jc->next = jnt->links;
160 jnt->links = jc;
163 void edif_pstring(edif_t edf, const char*name, const char*value)
165 struct cellref_property_*prp = malloc(sizeof(struct cellref_property_));
166 prp->name = name;
167 prp->ptype = PRP_STRING;
168 prp->value_.str = value;
169 prp->next = edf->property;
170 edf->property = prp;
173 edif_xlibrary_t edif_xlibrary_create(edif_t edf, const char*name)
175 edif_xlibrary_t xlib = malloc(sizeof(struct edif_xlibrary_s));
177 xlib->name = name;
178 xlib->cells = 0;
179 xlib->celltable = 0;
180 xlib->next = edf->xlibs;
181 edf->xlibs = xlib;
183 return xlib;
186 void edif_xlibrary_set_celltable(edif_xlibrary_t xlib,
187 const struct edif_xlib_celltable*tab)
189 assert(xlib->celltable == 0);
190 xlib->celltable = tab;
193 edif_cell_t edif_xlibrary_findcell(edif_xlibrary_t xlib,
194 const char*cell_name)
196 const struct edif_xlib_celltable*tcur;
197 edif_cell_t cur;
199 for (cur = xlib->cells ; cur ; cur = cur->next) {
200 if (strcmp(cell_name, cur->name) == 0)
201 return cur;
204 if (xlib->celltable == 0)
205 return 0;
207 for (tcur = xlib->celltable ; tcur->cell_name ; tcur += 1)
208 if (strcmp(cell_name, tcur->cell_name) == 0) {
209 return (tcur->cell_func)(xlib);
212 return 0;
215 edif_cell_t edif_xlibrary_scope_cell(edif_xlibrary_t xlib,
216 ivl_scope_t scope)
218 unsigned port_count, idx;
219 edif_cell_t cur;
221 /* Check to see if the cell is already somehow defined. */
222 cur = edif_xlibrary_findcell(xlib, ivl_scope_tname(scope));
223 if (cur) return cur;
225 /* Count the ports of the scope. */
226 port_count = 0;
227 for (idx = 0 ; idx < ivl_scope_sigs(scope) ; idx += 1) {
228 ivl_signal_t sig = ivl_scope_sig(scope, idx);
230 if (ivl_signal_port(sig) == IVL_SIP_NONE)
231 continue;
233 port_count += 1;
236 cur = edif_xcell_create(xlib, ivl_scope_tname(scope), port_count);
238 port_count = 0;
239 for (idx = 0 ; idx < ivl_scope_sigs(scope) ; idx += 1) {
240 ivl_signal_t sig = ivl_scope_sig(scope, idx);
242 if (ivl_signal_port(sig) == IVL_SIP_NONE)
243 continue;
245 edif_cell_portconfig(cur, port_count,
246 ivl_signal_basename(sig),
247 ivl_signal_port(sig));
248 port_count += 1;
251 return cur;
254 edif_cell_t edif_xcell_create(edif_xlibrary_t xlib, const char*name,
255 unsigned nports)
257 unsigned idx;
258 edif_cell_t cell = malloc(sizeof(struct edif_cell_s));
260 cell->name = name;
261 cell->xlib = xlib;
262 cell->nports = nports;
263 cell->ports = calloc(nports, sizeof(struct __cell_port));
264 cell->property = 0;
266 for (idx = 0 ; idx < nports ; idx += 1) {
267 cell->ports[idx].name = "?";
268 cell->ports[idx].dir = IVL_SIP_NONE;
269 cell->ports[idx].property = 0;
272 cell->next = xlib->cells;
273 xlib->cells = cell;
275 return cell;
278 void edif_cell_portconfig(edif_cell_t cell, unsigned idx,
279 const char*name, ivl_signal_port_t dir)
281 assert(idx < cell->nports);
283 cell->ports[idx].name = name;
284 cell->ports[idx].dir = dir;
287 void edif_cell_port_pstring(edif_cell_t cell, unsigned idx,
288 const char*name, const char*value)
290 struct cellref_property_*prp = malloc(sizeof(struct cellref_property_));
291 prp->name = name;
292 prp->ptype = PRP_STRING;
293 prp->value_.str = value;
294 prp->next = cell->ports[idx].property;
295 cell->ports[idx].property = prp;
298 unsigned edif_cell_port_byname(edif_cell_t cell, const char*name)
300 unsigned idx = 0;
301 for (idx = 0 ; idx < cell->nports ; idx += 1)
302 if (strcmp(name, cell->ports[idx].name) == 0)
303 break;
305 return idx;
308 void edif_cell_pstring(edif_cell_t cell, const char*name,
309 const char*value)
311 struct cellref_property_*prp = malloc(sizeof(struct cellref_property_));
312 prp->name = name;
313 prp->ptype = PRP_STRING;
314 prp->value_.str = value;
315 prp->next = cell->property;
316 cell->property = prp;
319 void edif_cell_pinteger(edif_cell_t cell, const char*name,
320 int value)
322 struct cellref_property_*prp = malloc(sizeof(struct cellref_property_));
323 prp->name = name;
324 prp->ptype = PRP_INTEGER;
325 prp->value_.num = value;
326 prp->next = cell->property;
327 cell->property = prp;
330 edif_cellref_t edif_cellref_create(edif_t edf, edif_cell_t cell)
332 static unsigned u_number = 0;
333 edif_cellref_t ref = malloc(sizeof(struct edif_cellref_s));
335 u_number += 1;
337 assert(cell);
338 assert(edf);
340 ref->u = u_number;
341 ref->cell = cell;
342 ref->property = 0;
343 ref->next = edf->celref;
344 edf->celref = ref;
346 return ref;
349 void edif_cellref_pstring(edif_cellref_t ref, const char*name,
350 const char*value)
352 struct cellref_property_*prp = malloc(sizeof(struct cellref_property_));
353 prp->name = name;
354 prp->ptype = PRP_STRING;
355 prp->value_.str = value;
356 prp->next = ref->property;
357 ref->property = prp;
360 void edif_cellref_pinteger(edif_cellref_t ref, const char*name, int value)
362 struct cellref_property_*prp = malloc(sizeof(struct cellref_property_));
363 prp->name = name;
364 prp->ptype = PRP_INTEGER;
365 prp->value_.num = value;
366 prp->next = ref->property;
367 ref->property = prp;
370 edif_joint_t edif_joint_create(edif_t edf)
372 edif_joint_t jnt = malloc(sizeof(struct edif_joint_s));
374 jnt->name = 0;
375 jnt->links = 0;
376 jnt->next = edf->nexa;
377 edf->nexa = jnt;
378 return jnt;
381 edif_joint_t edif_joint_of_nexus(edif_t edf, ivl_nexus_t nex)
383 void*tmp = ivl_nexus_get_private(nex);
384 edif_joint_t jnt;
386 if (tmp == 0) {
387 jnt = edif_joint_create(edf);
388 ivl_nexus_set_private(nex, jnt);
389 return jnt;
392 jnt = (edif_joint_t) tmp;
393 return jnt;
396 void edif_joint_rename(edif_joint_t jnt, const char*name)
398 assert(jnt->name == 0);
399 jnt->name = name;
402 void edif_add_to_joint(edif_joint_t jnt, edif_cellref_t cell, unsigned port)
404 struct joint_cell_* jc = malloc(sizeof(struct joint_cell_));
406 jc->cell = cell;
407 jc->port = port;
408 jc->next = jnt->links;
409 jnt->links = jc;
412 static void fprint_property(FILE*fd, const struct cellref_property_*prp)
414 fprintf(fd, "(property %s ", prp->name);
415 switch (prp->ptype) {
416 case PRP_NONE:
417 break;
418 case PRP_STRING:
419 fprintf(fd, "(string \"%s\")", prp->value_.str);
420 break;
421 case PRP_INTEGER:
422 fprintf(fd, "(integer %ld)", prp->value_.num);
423 break;
425 fprintf(fd, ")");
429 * This function takes all the data structures that have been
430 * assembled by the code generator, and writes them into an EDIF
431 * formatted file.
433 void edif_print(FILE*fd, edif_t edf)
435 edif_xlibrary_t xlib;
436 edif_cell_t cell;
437 edif_cellref_t ref;
438 edif_joint_t jnt;
439 struct cellref_property_*prp;
440 unsigned idx;
442 fprintf(fd, "(edif %s\n", edf->name);
443 fprintf(fd, " (edifVersion 2 0 0)\n");
444 fprintf(fd, " (edifLevel 0)\n");
445 fprintf(fd, " (keywordMap (keywordLevel 0))\n");
446 fprintf(fd, " (status\n");
447 fprintf(fd, " (written\n");
448 fprintf(fd, " (timeStamp 0 0 0 0 0 0)\n");
449 fprintf(fd, " (author \"unknown\")\n");
450 fprintf(fd, " (program \"Icarus Verilog/fpga.tgt\")))\n");
451 fflush(fd);
453 for (xlib = edf->xlibs ; xlib ; xlib = xlib->next) {
455 fprintf(fd, " (external %s "
456 "(edifLevel 0) "
457 "(technology (numberDefinition))\n",
458 xlib->name);
460 for (cell = xlib->cells ; cell ; cell = cell->next) {
461 fprintf(fd, " (cell %s (cellType GENERIC)\n",
462 cell->name);
463 fprintf(fd, " (view net\n"
464 " (viewType NETLIST)\n"
465 " (interface");
467 for (idx = 0 ; idx < cell->nports ; idx += 1) {
468 struct __cell_port*pp = cell->ports + idx;
469 fprintf(fd, "\n (port %s", pp->name);
470 switch (pp->dir) {
471 case IVL_SIP_INPUT:
472 fprintf(fd, " (direction INPUT)");
473 break;
474 case IVL_SIP_OUTPUT:
475 fprintf(fd, " (direction OUTPUT)");
476 break;
477 case IVL_SIP_INOUT:
478 fprintf(fd, " (direction INOUT)");
479 break;
480 default:
481 break;
484 for (prp = pp->property ; prp ; prp=prp->next) {
485 fprintf(fd, " ");
486 fprint_property(fd, prp);
489 fprintf(fd, ")");
492 for (prp = cell->property ; prp ; prp = prp->next) {
493 fprintf(fd, "\n ");
494 fprint_property(fd, prp);
496 fprintf(fd, ")))\n");
499 fprintf(fd, " )\n"); /* terminate (external ...) sexp */
501 fflush(fd);
503 /* Write out the library header */
504 fprintf(fd, " (library DESIGN\n");
505 fprintf(fd, " (edifLevel 0)\n");
506 fprintf(fd, " (technology (numberDefinition))\n");
508 /* The root module is a cell in the library. */
509 fprintf(fd, " (cell %s\n", edf->name);
510 fprintf(fd, " (cellType GENERIC)\n");
511 fprintf(fd, " (view net\n");
512 fprintf(fd, " (viewType NETLIST)\n");
513 fprintf(fd, " (interface\n");
515 for (idx = 0 ; idx < edf->nports ; idx += 1) {
516 fprintf(fd, " (port ");
517 if (edf->ports[idx].ename == 0)
518 fprintf(fd, "%s ", edf->ports[idx].name);
519 else
520 fprintf(fd, "(rename %s \"%s\") ",
521 edf->ports[idx].ename,
522 edf->ports[idx].name);
524 switch (edf->ports[idx].dir) {
525 case IVL_SIP_INPUT:
526 fprintf(fd, "(direction INPUT)");
527 break;
528 case IVL_SIP_OUTPUT:
529 fprintf(fd, "(direction OUTPUT)");
530 break;
531 case IVL_SIP_INOUT:
532 fprintf(fd, "(direction INOUT)");
533 break;
534 default:
535 break;
537 fprintf(fd, ")\n");
540 fprintf(fd, " )\n"); /* end the (interface ) sexp */
541 fflush(fd);
543 fprintf(fd, " (contents\n");
545 /* Display all the instances. */
546 for (ref = edf->celref ; ref ; ref = ref->next) {
548 assert(ref->cell);
550 fprintf(fd, "(instance U%u (viewRef net "
551 "(cellRef %s (libraryRef %s)))",
552 ref->u, ref->cell->name, ref->cell->xlib->name);
554 for (prp = ref->property ; prp ; prp = prp->next) {
555 fprintf(fd, " ");
556 fprint_property(fd, prp);
559 fprintf(fd, ")\n");
562 fflush(fd);
564 /* Display all the joints. */
565 idx = 0;
566 for (jnt = edf->nexa ; jnt ; jnt = jnt->next, idx += 1) {
567 struct joint_cell_*jc;
569 fprintf(fd, "(net ");
570 if (jnt->name != 0)
571 fprintf(fd, "(rename N%u \"%s\")", idx, jnt->name);
572 else
573 fprintf(fd, "N%u", idx);
574 fprintf(fd, " (joined");
576 for (jc = jnt->links ; jc ; jc = jc->next) {
577 if (jc->cell) {
578 fprintf(fd, " (portRef %s (instanceRef U%u))",
579 jc->cell->cell->ports[jc->port].name,
580 jc->cell->u);
581 } else {
582 /* Reference to a port of the main cell. */
583 if (edf->ports[jc->port].ename)
584 fprintf(fd, " (portRef %s)",
585 edf->ports[jc->port].ename);
586 else
587 fprintf(fd, " (portRef %s)",
588 edf->ports[jc->port].name);
591 fprintf(fd, "))\n");
594 fprintf(fd, " )\n"); /* end the (contents...) sexp */
596 fprintf(fd, " )\n"); /* end the (view ) sexp */
597 fprintf(fd, " )\n"); /* end the (cell ) sexp */
598 fprintf(fd, " )\n"); /* end the (library DESIGN) sexp */
600 /* Make an instance of the defined object */
601 fprintf(fd, " (design %s\n", edf->name);
602 fprintf(fd, " (cellRef %s (libraryRef DESIGN))\n", edf->name);
604 for (prp = edf->property ; prp ; prp = prp->next) {
605 fprintf(fd, " ");
606 fprint_property(fd, prp);
607 fprintf(fd, "\n");
610 fprintf(fd, " )\n");
614 fprintf(fd, ")\n");
615 fflush(fd);
619 * $Log: edif.c,v $
620 * Revision 1.8 2003/09/03 23:34:09 steve
621 * Support synchronous set of LPM_FF devices.
623 * Revision 1.7 2003/08/07 05:18:04 steve
624 * Add support for OR/NOR/bufif0/bufif1.
626 * Revision 1.6 2003/08/07 04:04:01 steve
627 * Add an LPM device type.
629 * Revision 1.5 2003/06/24 03:55:00 steve
630 * Add ivl_synthesis_cell support for virtex2.
632 * Revision 1.4 2003/04/04 04:59:03 steve
633 * Add xlibrary celltable.
635 * Revision 1.3 2003/03/30 03:43:44 steve
636 * Handle wide ports of macros.
638 * Revision 1.2 2003/03/24 02:29:04 steve
639 * Give proper basenames to PAD signals.
641 * Revision 1.1 2003/03/24 00:47:54 steve
642 * Add new virtex2 architecture family, and
643 * also the new edif.h EDIF management functions.