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)
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
20 #ident "$Id: edif.c,v 1.8 2003/09/03 23:34:09 steve Exp $"
31 typedef enum property_e
{
37 struct cellref_property_
{
44 struct cellref_property_
*next
;
49 /* List the ports of the design. */
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. */
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
;
77 struct cellref_property_
*property
;
78 ivl_signal_port_t dir
;
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
;
95 struct cellref_property_
*property
;
96 struct edif_cellref_s
* next
;
100 struct edif_cellref_s
*cell
;
102 struct joint_cell_
*next
;
105 struct edif_joint_s
{
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"
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
;
126 edf
->ports
= nports
? calloc(nports
, sizeof(struct __cell_port
)) : 0;
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;
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_
));
159 jc
->next
= jnt
->links
;
163 void edif_pstring(edif_t edf
, const char*name
, const char*value
)
165 struct cellref_property_
*prp
= malloc(sizeof(struct cellref_property_
));
167 prp
->ptype
= PRP_STRING
;
168 prp
->value_
.str
= value
;
169 prp
->next
= edf
->property
;
173 edif_xlibrary_t
edif_xlibrary_create(edif_t edf
, const char*name
)
175 edif_xlibrary_t xlib
= malloc(sizeof(struct edif_xlibrary_s
));
180 xlib
->next
= edf
->xlibs
;
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
;
199 for (cur
= xlib
->cells
; cur
; cur
= cur
->next
) {
200 if (strcmp(cell_name
, cur
->name
) == 0)
204 if (xlib
->celltable
== 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
);
215 edif_cell_t
edif_xlibrary_scope_cell(edif_xlibrary_t xlib
,
218 unsigned port_count
, idx
;
221 /* Check to see if the cell is already somehow defined. */
222 cur
= edif_xlibrary_findcell(xlib
, ivl_scope_tname(scope
));
225 /* Count the ports of the scope. */
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
)
236 cur
= edif_xcell_create(xlib
, ivl_scope_tname(scope
), port_count
);
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
)
245 edif_cell_portconfig(cur
, port_count
,
246 ivl_signal_basename(sig
),
247 ivl_signal_port(sig
));
254 edif_cell_t
edif_xcell_create(edif_xlibrary_t xlib
, const char*name
,
258 edif_cell_t cell
= malloc(sizeof(struct edif_cell_s
));
262 cell
->nports
= nports
;
263 cell
->ports
= calloc(nports
, sizeof(struct __cell_port
));
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
;
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_
));
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
)
301 for (idx
= 0 ; idx
< cell
->nports
; idx
+= 1)
302 if (strcmp(name
, cell
->ports
[idx
].name
) == 0)
308 void edif_cell_pstring(edif_cell_t cell
, const char*name
,
311 struct cellref_property_
*prp
= malloc(sizeof(struct cellref_property_
));
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
,
322 struct cellref_property_
*prp
= malloc(sizeof(struct cellref_property_
));
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
));
343 ref
->next
= edf
->celref
;
349 void edif_cellref_pstring(edif_cellref_t ref
, const char*name
,
352 struct cellref_property_
*prp
= malloc(sizeof(struct cellref_property_
));
354 prp
->ptype
= PRP_STRING
;
355 prp
->value_
.str
= value
;
356 prp
->next
= ref
->property
;
360 void edif_cellref_pinteger(edif_cellref_t ref
, const char*name
, int value
)
362 struct cellref_property_
*prp
= malloc(sizeof(struct cellref_property_
));
364 prp
->ptype
= PRP_INTEGER
;
365 prp
->value_
.num
= value
;
366 prp
->next
= ref
->property
;
370 edif_joint_t
edif_joint_create(edif_t edf
)
372 edif_joint_t jnt
= malloc(sizeof(struct edif_joint_s
));
376 jnt
->next
= edf
->nexa
;
381 edif_joint_t
edif_joint_of_nexus(edif_t edf
, ivl_nexus_t nex
)
383 void*tmp
= ivl_nexus_get_private(nex
);
387 jnt
= edif_joint_create(edf
);
388 ivl_nexus_set_private(nex
, jnt
);
392 jnt
= (edif_joint_t
) tmp
;
396 void edif_joint_rename(edif_joint_t jnt
, const char*name
)
398 assert(jnt
->name
== 0);
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_
));
408 jc
->next
= jnt
->links
;
412 static void fprint_property(FILE*fd
, const struct cellref_property_
*prp
)
414 fprintf(fd
, "(property %s ", prp
->name
);
415 switch (prp
->ptype
) {
419 fprintf(fd
, "(string \"%s\")", prp
->value_
.str
);
422 fprintf(fd
, "(integer %ld)", prp
->value_
.num
);
429 * This function takes all the data structures that have been
430 * assembled by the code generator, and writes them into an EDIF
433 void edif_print(FILE*fd
, edif_t edf
)
435 edif_xlibrary_t xlib
;
439 struct cellref_property_
*prp
;
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");
453 for (xlib
= edf
->xlibs
; xlib
; xlib
= xlib
->next
) {
455 fprintf(fd
, " (external %s "
457 "(technology (numberDefinition))\n",
460 for (cell
= xlib
->cells
; cell
; cell
= cell
->next
) {
461 fprintf(fd
, " (cell %s (cellType GENERIC)\n",
463 fprintf(fd
, " (view net\n"
464 " (viewType NETLIST)\n"
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
);
472 fprintf(fd
, " (direction INPUT)");
475 fprintf(fd
, " (direction OUTPUT)");
478 fprintf(fd
, " (direction INOUT)");
484 for (prp
= pp
->property
; prp
; prp
=prp
->next
) {
486 fprint_property(fd
, prp
);
492 for (prp
= cell
->property
; prp
; prp
= prp
->next
) {
494 fprint_property(fd
, prp
);
496 fprintf(fd
, ")))\n");
499 fprintf(fd
, " )\n"); /* terminate (external ...) sexp */
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
);
520 fprintf(fd
, "(rename %s \"%s\") ",
521 edf
->ports
[idx
].ename
,
522 edf
->ports
[idx
].name
);
524 switch (edf
->ports
[idx
].dir
) {
526 fprintf(fd
, "(direction INPUT)");
529 fprintf(fd
, "(direction OUTPUT)");
532 fprintf(fd
, "(direction INOUT)");
540 fprintf(fd
, " )\n"); /* end the (interface ) sexp */
543 fprintf(fd
, " (contents\n");
545 /* Display all the instances. */
546 for (ref
= edf
->celref
; ref
; ref
= ref
->next
) {
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
) {
556 fprint_property(fd
, prp
);
564 /* Display all the joints. */
566 for (jnt
= edf
->nexa
; jnt
; jnt
= jnt
->next
, idx
+= 1) {
567 struct joint_cell_
*jc
;
569 fprintf(fd
, "(net ");
571 fprintf(fd
, "(rename N%u \"%s\")", idx
, jnt
->name
);
573 fprintf(fd
, "N%u", idx
);
574 fprintf(fd
, " (joined");
576 for (jc
= jnt
->links
; jc
; jc
= jc
->next
) {
578 fprintf(fd
, " (portRef %s (instanceRef U%u))",
579 jc
->cell
->cell
->ports
[jc
->port
].name
,
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
);
587 fprintf(fd
, " (portRef %s)",
588 edf
->ports
[jc
->port
].name
);
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
) {
606 fprint_property(fd
, prp
);
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.