/* * Copyright (c) 200Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT #ident "$Id: edif.c,v 1.1 2003/03/24 00:47:54 steve Exp $" #endif # include "edif.h" # include # include #ifdef HAVE_MALLOC_H # include #endif # include struct cellref_property_ { const char*name; const char*value; struct cellref_property_*next; }; struct edif_s { const char*name; /* List the ports of the design. */ unsigned nports; struct __cell_port*ports; /* All the external libraries attached to me. */ edif_xlibrary_t xlibs; /* list the cellref instances. */ edif_cellref_t celref; /* The root instance has cellref properties as well. */ struct cellref_property_*property; /* Keep a list of all the nexa */ struct edif_joint_s*nexa; }; struct edif_xlibrary_s { /* Name of this library. */ const char*name; /* The cells that are contained in this library. */ struct edif_cell_s*cells; /* used to list libraries in an edif_t. */ struct edif_xlibrary_s*next; }; struct __cell_port { const char*name; ivl_signal_port_t dir; }; struct edif_cell_s { const char*name; edif_xlibrary_t xlib; unsigned nports; struct __cell_port*ports; struct edif_cell_s*next; }; struct edif_cellref_s { struct edif_cell_s* cell; unsigned u; struct cellref_property_*property; struct edif_cellref_s* next; }; struct joint_cell_ { struct edif_cellref_s*cell; unsigned port; struct joint_cell_*next; }; struct edif_joint_s { struct joint_cell_*links; struct edif_joint_s*next; }; edif_t edif_create(const char*design_name, unsigned nports) { edif_t edf = malloc(sizeof(struct edif_s)); edf->name = design_name; edf->nports= nports; edf->ports = nports? calloc(nports, sizeof(struct __cell_port)) : 0; edf->celref= 0; edf->xlibs = 0; edf->property = 0; edf->nexa = 0; return edf; } void edif_portconfig(edif_t edf, unsigned idx, const char*name, ivl_signal_port_t dir) { assert(idx < edf->nports); edf->ports[idx].name = name; edf->ports[idx].dir = dir; } void edif_port_to_joint(edif_joint_t jnt, edif_t edf, unsigned port) { struct joint_cell_* jc = malloc(sizeof(struct joint_cell_)); jc->cell = 0; jc->port = port; jc->next = jnt->links; jnt->links = jc; } void edif_pstring(edif_t edf, const char*name, const char*value) { struct cellref_property_*prp = malloc(sizeof(struct cellref_property_)); prp->name = name; prp->value = value; prp->next = edf->property; edf->property = prp; } edif_xlibrary_t edif_xlibrary_create(edif_t edf, const char*name) { edif_xlibrary_t xlib = malloc(sizeof(struct edif_xlibrary_s)); xlib->name = name; xlib->cells= 0; xlib->next = edf->xlibs; edf->xlibs = xlib; return xlib; } edif_cell_t edif_xlibrary_findcell(edif_xlibrary_t xlib, const char*cell_name) { edif_cell_t cur; for (cur = xlib->cells ; cur ; cur = cur->next) { if (strcmp(cell_name, cur->name) == 0) return cur; } return 0; } edif_cell_t edif_xcell_create(edif_xlibrary_t xlib, const char*name, unsigned nports) { unsigned idx; edif_cell_t cell = malloc(sizeof(struct edif_cell_s)); cell->name = name; cell->xlib = xlib; cell->nports = nports; cell->ports = calloc(nports, sizeof(struct __cell_port)); for (idx = 0 ; idx < nports ; idx += 1) { cell->ports[idx].name = "?"; cell->ports[idx].dir = IVL_SIP_NONE; } cell->next = xlib->cells; xlib->cells = cell; return cell; } void edif_cell_portconfig(edif_cell_t cell, unsigned idx, const char*name, ivl_signal_port_t dir) { assert(idx < cell->nports); cell->ports[idx].name = name; cell->ports[idx].dir = dir; } unsigned edif_cell_port_byname(edif_cell_t cell, const char*name) { unsigned idx = 0; for (idx = 0 ; idx < cell->nports ; idx += 1) if (strcmp(name, cell->ports[idx].name) == 0) break; return idx; } edif_cellref_t edif_cellref_create(edif_t edf, edif_cell_t cell) { static unsigned u_number = 0; edif_cellref_t ref = malloc(sizeof(struct edif_cellref_s)); u_number += 1; assert(cell); assert(edf); ref->u = u_number; ref->cell = cell; ref->property = 0; ref->next = edf->celref; edf->celref = ref; return ref; } void edif_cellref_pstring(edif_cellref_t ref, const char*name, const char*value) { struct cellref_property_*prp = malloc(sizeof(struct cellref_property_)); prp->name = name; prp->value = value; prp->next = ref->property; ref->property = prp; } edif_joint_t edif_joint_create(edif_t edf) { edif_joint_t jnt = malloc(sizeof(struct edif_joint_s)); jnt->links = 0; jnt->next = edf->nexa; edf->nexa = jnt; return jnt; } edif_joint_t edif_joint_of_nexus(edif_t edf, ivl_nexus_t nex) { void*tmp = ivl_nexus_get_private(nex); edif_joint_t jnt; if (tmp == 0) { jnt = edif_joint_create(edf); ivl_nexus_set_private(nex, jnt); return jnt; } jnt = (edif_joint_t) tmp; return jnt; } void edif_add_to_joint(edif_joint_t jnt, edif_cellref_t cell, unsigned port) { struct joint_cell_* jc = malloc(sizeof(struct joint_cell_)); jc->cell = cell; jc->port = port; jc->next = jnt->links; jnt->links = jc; } /* * This function takes all the data structures that have been * assembled by the code generator, and writes them into an EDIF * formatted file. */ void edif_print(FILE*fd, edif_t edf) { edif_xlibrary_t xlib; edif_cell_t cell; edif_cellref_t ref; edif_joint_t jnt; struct cellref_property_*prp; unsigned idx; fprintf(fd, "(edif %s\n", edf->name); fprintf(fd, " (edifVersion 2 0 0)\n"); fprintf(fd, " (edifLevel 0)\n"); fprintf(fd, " (keywordMap (keywordLevel 0))\n"); fprintf(fd, " (status\n"); fprintf(fd, " (written\n"); fprintf(fd, " (timeStamp 0 0 0 0 0 0)\n"); fprintf(fd, " (author \"unknown\")\n"); fprintf(fd, " (program \"Icarus Verilog/fpga.tgt\")))\n"); fflush(fd); for (xlib = edf->xlibs ; xlib ; xlib = xlib->next) { fprintf(fd, " (external %s " "(edifLevel 0) " "(technology (numberDefinition))\n", xlib->name); for (cell = xlib->cells ; cell ; cell = cell->next) { fprintf(fd, " (cell %s (cellType GENERIC)\n", cell->name); fprintf(fd, " (view net\n" " (viewType NETLIST)\n" " (interface"); for (idx = 0 ; idx < cell->nports ; idx += 1) { struct __cell_port*pp = cell->ports + idx; fprintf(fd, "\n (port %s", pp->name); switch (pp->dir) { case IVL_SIP_INPUT: fprintf(fd, " (direction INPUT)"); break; case IVL_SIP_OUTPUT: fprintf(fd, " (direction OUTPUT)"); break; case IVL_SIP_INOUT: fprintf(fd, " (direction INOUT)"); break; default: break; } fprintf(fd, ")"); } fprintf(fd, ")))\n"); } fprintf(fd, " )\n"); /* terminate (external ...) sexp */ } fflush(fd); /* Write out the library header */ fprintf(fd, " (library DESIGN\n"); fprintf(fd, " (edifLevel 0)\n"); fprintf(fd, " (technology (numberDefinition))\n"); /* The root module is a cell in the library. */ fprintf(fd, " (cell %s\n", edf->name); fprintf(fd, " (cellType GENERIC)\n"); fprintf(fd, " (view net\n"); fprintf(fd, " (viewType NETLIST)\n"); fprintf(fd, " (interface\n"); for (idx = 0 ; idx < edf->nports ; idx += 1) { fprintf(fd, " (port %s ", edf->ports[idx].name); switch (edf->ports[idx].dir) { case IVL_SIP_INPUT: fprintf(fd, "(direction INPUT)"); break; case IVL_SIP_OUTPUT: fprintf(fd, "(direction OUTPUT)"); break; case IVL_SIP_INOUT: fprintf(fd, "(direction INOUT)"); break; default: break; } fprintf(fd, ")\n"); } fprintf(fd, " )\n"); /* end the (interface ) sexp */ fflush(fd); fprintf(fd, " (contents\n"); /* Display all the instances. */ for (ref = edf->celref ; ref ; ref = ref->next) { assert(ref->cell); fprintf(fd, "(instance U%u (viewRef net " "(cellRef %s (libraryRef %s)))", ref->u, ref->cell->name, ref->cell->xlib->name); for (prp = ref->property ; prp ; prp = prp->next) fprintf(fd, " (property %s (string \"%s\"))", prp->name, prp->value); fprintf(fd, ")\n"); } fflush(fd); /* Display all the joints. */ idx = 0; for (jnt = edf->nexa ; jnt ; jnt = jnt->next, idx += 1) { struct joint_cell_*jc; fprintf(fd, "(net N%u (joined", idx); for (jc = jnt->links ; jc ; jc = jc->next) { if (jc->cell) fprintf(fd, " (portRef %s (instanceRef U%u))", jc->cell->cell->ports[jc->port].name, jc->cell->u); else fprintf(fd, " (portRef %s)", edf->ports[jc->port].name); } fprintf(fd, "))\n"); } fprintf(fd, " )\n"); /* end the (contents...) sexp */ fprintf(fd, " )\n"); /* end the (view ) sexp */ fprintf(fd, " )\n"); /* end the (cell ) sexp */ fprintf(fd, " )\n"); /* end the (library DESIGN) sexp */ /* Make an instance of the defined object */ fprintf(fd, " (design %s\n", edf->name); fprintf(fd, " (cellRef %s (libraryRef DESIGN))\n", edf->name); for (prp = edf->property ; prp ; prp = prp->next) { fprintf(fd, " (property %s (string \"%s\"))\n", prp->name, prp->value); } fprintf(fd, " )\n"); fprintf(fd, ")\n"); fflush(fd); } /* * $Log: edif.c,v $ * Revision 1.1 2003/03/24 00:47:54 steve * Add new virtex2 architecture family, and * also the new edif.h EDIF management functions. * */