From 63fb5ea03c6ea8c18feda8ab2bf03a97fad07091 Mon Sep 17 00:00:00 2001 From: steve Date: Thu, 7 Aug 2003 05:18:04 +0000 Subject: [PATCH] Add support for OR/NOR/bufif0/bufif1. --- tgt-fpga/d-lpm.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++- tgt-fpga/edif.c | 90 ++++++++++++++------------ tgt-fpga/edif.h | 9 ++- 3 files changed, 218 insertions(+), 45 deletions(-) diff --git a/tgt-fpga/d-lpm.c b/tgt-fpga/d-lpm.c index 8facc1a5b..c7a0afec7 100644 --- a/tgt-fpga/d-lpm.c +++ b/tgt-fpga/d-lpm.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: d-lpm.c,v 1.1 2003/08/07 04:04:01 steve Exp $" +#ident "$Id: d-lpm.c,v 1.2 2003/08/07 05:18:04 steve Exp $" #endif /* @@ -47,7 +47,10 @@ static edif_cell_t lpm_cell_buf(void) edif_cell_portconfig(tmp, 0, "Result", IVL_SIP_OUTPUT); edif_cell_portconfig(tmp, 1, "Data", IVL_SIP_INPUT); - edif_cell_pstring(tmp, "LPM_TYPE", "LPM_OR"); + /* A buffer is an inverted inverter. */ + edif_cell_port_pstring(tmp, 0, "LPM_Polarity", "INVERT"); + + edif_cell_pstring(tmp, "LPM_TYPE", "LPM_INV"); edif_cell_pinteger(tmp, "LPM_Width", 1); edif_cell_pinteger(tmp, "LPM_Size", 1); return tmp; @@ -70,6 +73,99 @@ static edif_cell_t lpm_cell_inv(void) return tmp; } +static edif_cell_t lpm_cell_bufif0(void) +{ + static edif_cell_t tmp = 0; + + if (tmp != 0) + return tmp; + + tmp = edif_xcell_create(xlib, "BUFIF1", 3); + edif_cell_portconfig(tmp, 0, "TriData", IVL_SIP_OUTPUT); + edif_cell_portconfig(tmp, 1, "Data", IVL_SIP_INPUT); + edif_cell_portconfig(tmp, 2, "EnableDT", IVL_SIP_INPUT); + + edif_cell_port_pstring(tmp, 2, "LPM_Polarity", "INVERT"); + + edif_cell_pstring(tmp, "LPM_TYPE", "LPM_BUSTRI"); + edif_cell_pinteger(tmp, "LPM_Width", 1); + return tmp; +} + +static edif_cell_t lpm_cell_bufif1(void) +{ + static edif_cell_t tmp = 0; + + if (tmp != 0) + return tmp; + + tmp = edif_xcell_create(xlib, "BUFIF1", 3); + edif_cell_portconfig(tmp, 0, "TriData", IVL_SIP_OUTPUT); + edif_cell_portconfig(tmp, 1, "Data", IVL_SIP_INPUT); + edif_cell_portconfig(tmp, 2, "EnableDT", IVL_SIP_INPUT); + + edif_cell_pstring(tmp, "LPM_TYPE", "LPM_BUSTRI"); + edif_cell_pinteger(tmp, "LPM_Width", 1); + return tmp; +} + +static edif_cell_t lpm_cell_or(unsigned siz) +{ + unsigned idx; + edif_cell_t cell; + char name[32]; + + sprintf(name, "or%u", siz); + + cell = edif_xlibrary_findcell(xlib, name); + if (cell != 0) + return cell; + + cell = edif_xcell_create(xlib, strdup(name), siz+1); + + edif_cell_portconfig(cell, 0, "Result0", IVL_SIP_OUTPUT); + + for (idx = 0 ; idx < siz ; idx += 1) { + sprintf(name, "Data%ux0", idx); + edif_cell_portconfig(cell, idx+1, strdup(name), IVL_SIP_INPUT); + } + + edif_cell_pstring(cell, "LPM_TYPE", "LPM_OR"); + edif_cell_pinteger(cell, "LPM_Width", 1); + edif_cell_pinteger(cell, "LPM_Size", siz); + + return cell; +} + +static edif_cell_t lpm_cell_nor(unsigned siz) +{ + unsigned idx; + edif_cell_t cell; + char name[32]; + + sprintf(name, "nor%u", siz); + + cell = edif_xlibrary_findcell(xlib, name); + if (cell != 0) + return cell; + + cell = edif_xcell_create(xlib, strdup(name), siz+1); + + edif_cell_portconfig(cell, 0, "Result0", IVL_SIP_OUTPUT); + edif_cell_port_pstring(cell, 0, "LPM_Polarity", "INVERT"); + + for (idx = 0 ; idx < siz ; idx += 1) { + sprintf(name, "Data%ux0", idx); + edif_cell_portconfig(cell, idx+1, strdup(name), IVL_SIP_INPUT); + } + + edif_cell_pstring(cell, "LPM_TYPE", "LPM_OR"); + edif_cell_pinteger(cell, "LPM_Width", 1); + edif_cell_pinteger(cell, "LPM_Size", siz); + + return cell; +} + static void lpm_show_header(ivl_design_t des) { unsigned idx; @@ -142,6 +238,27 @@ static void lpm_show_footer(ivl_design_t des) edif_print(xnf, edf); } +static void hookup_logic_gate(ivl_net_logic_t net, edif_cell_t cell) +{ + unsigned pin, idx; + + edif_joint_t jnt; + edif_cellref_t ref = edif_cellref_create(edf, cell); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0)); + pin = edif_cell_port_byname(cell, "Result0"); + edif_add_to_joint(jnt, ref, pin); + + for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { + char name[32]; + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx)); + sprintf(name, "Data%ux0", idx-1); + pin = edif_cell_port_byname(cell, name); + edif_add_to_joint(jnt, ref, pin); + } +} + static void lpm_logic(ivl_net_logic_t net) { edif_cell_t cell; @@ -163,6 +280,36 @@ static void lpm_logic(ivl_net_logic_t net) edif_add_to_joint(jnt, ref, 1); break; + case IVL_LO_BUFIF0: + assert(ivl_logic_pins(net) == 3); + cell = lpm_cell_bufif0(); + ref = edif_cellref_create(edf, cell); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0)); + edif_add_to_joint(jnt, ref, 0); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1)); + edif_add_to_joint(jnt, ref, 1); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 2)); + edif_add_to_joint(jnt, ref, 2); + break; + + case IVL_LO_BUFIF1: + assert(ivl_logic_pins(net) == 3); + cell = lpm_cell_bufif1(); + ref = edif_cellref_create(edf, cell); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0)); + edif_add_to_joint(jnt, ref, 0); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1)); + edif_add_to_joint(jnt, ref, 1); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 2)); + edif_add_to_joint(jnt, ref, 2); + break; + case IVL_LO_NOT: assert(ivl_logic_pins(net) == 2); cell = lpm_cell_inv(); @@ -175,6 +322,16 @@ static void lpm_logic(ivl_net_logic_t net) edif_add_to_joint(jnt, ref, 1); break; + case IVL_LO_OR: + cell = lpm_cell_or(ivl_logic_pins(net)-1); + hookup_logic_gate(net, cell); + break; + + case IVL_LO_NOR: + cell = lpm_cell_nor(ivl_logic_pins(net)-1); + hookup_logic_gate(net, cell); + break; + default: fprintf(stderr, "UNSUPPORTED LOGIC TYPE: %u\n", ivl_logic_type(net)); @@ -365,6 +522,9 @@ const struct device_s d_lpm_edif = { /* * $Log: d-lpm.c,v $ + * Revision 1.2 2003/08/07 05:18:04 steve + * Add support for OR/NOR/bufif0/bufif1. + * * Revision 1.1 2003/08/07 04:04:01 steve * Add an LPM device type. * diff --git a/tgt-fpga/edif.c b/tgt-fpga/edif.c index 17c094191..12fe71f8b 100644 --- a/tgt-fpga/edif.c +++ b/tgt-fpga/edif.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: edif.c,v 1.6 2003/08/07 04:04:01 steve Exp $" +#ident "$Id: edif.c,v 1.7 2003/08/07 05:18:04 steve Exp $" #endif # include "edif.h" @@ -74,6 +74,7 @@ struct edif_xlibrary_s { struct __cell_port { const char*name; const char*ename; + struct cellref_property_*property; ivl_signal_port_t dir; }; @@ -265,6 +266,7 @@ edif_cell_t edif_xcell_create(edif_xlibrary_t xlib, const char*name, for (idx = 0 ; idx < nports ; idx += 1) { cell->ports[idx].name = "?"; cell->ports[idx].dir = IVL_SIP_NONE; + cell->ports[idx].property = 0; } cell->next = xlib->cells; @@ -282,6 +284,17 @@ void edif_cell_portconfig(edif_cell_t cell, unsigned idx, cell->ports[idx].dir = dir; } +void edif_cell_port_pstring(edif_cell_t cell, unsigned idx, + const char*name, const char*value) +{ + struct cellref_property_*prp = malloc(sizeof(struct cellref_property_)); + prp->name = name; + prp->ptype = PRP_STRING; + prp->value_.str = value; + prp->next = cell->ports[idx].property; + cell->ports[idx].property = prp; +} + unsigned edif_cell_port_byname(edif_cell_t cell, const char*name) { unsigned idx = 0; @@ -386,6 +399,22 @@ void edif_add_to_joint(edif_joint_t jnt, edif_cellref_t cell, unsigned port) jnt->links = jc; } +static void fprint_property(FILE*fd, const struct cellref_property_*prp) +{ + fprintf(fd, "(property %s ", prp->name); + switch (prp->ptype) { + case PRP_NONE: + break; + case PRP_STRING: + fprintf(fd, "(string \"%s\")", prp->value_.str); + break; + case PRP_INTEGER: + fprintf(fd, "(integer %ld)", prp->value_.num); + break; + } + fprintf(fd, ")"); +} + /* * This function takes all the data structures that have been * assembled by the code generator, and writes them into an EDIF @@ -441,26 +470,18 @@ void edif_print(FILE*fd, edif_t edf) default: break; } + + for (prp = pp->property ; prp ; prp=prp->next) { + fprintf(fd, " "); + fprint_property(fd, prp); + } + fprintf(fd, ")"); } for (prp = cell->property ; prp ; prp = prp->next) { - fprintf(fd, "\n (property %s", - prp->name); - - switch (prp->ptype) { - case PRP_NONE: - assert(0); - case PRP_STRING: - fprintf(fd, " (string \"%s\")", - prp->value_.str); - break; - case PRP_INTEGER: - fprintf(fd, " (integer %ld)", - prp->value_.num); - break; - } - fprintf(fd, ")"); + fprintf(fd, "\n "); + fprint_property(fd, prp); } fprintf(fd, ")))\n"); } @@ -520,19 +541,10 @@ void edif_print(FILE*fd, edif_t edf) "(cellRef %s (libraryRef %s)))", ref->u, ref->cell->name, ref->cell->xlib->name); - for (prp = ref->property ; prp ; prp = prp->next) - switch (prp->ptype) { - case PRP_STRING: - fprintf(fd, " (property %s (string \"%s\"))", - prp->name, prp->value_.str); - break; - case PRP_INTEGER: - fprintf(fd, " (property %s (integer %ld))", - prp->name, prp->value_.num); - break; - case PRP_NONE: - assert(0); - } + for (prp = ref->property ; prp ; prp = prp->next) { + fprintf(fd, " "); + fprint_property(fd, prp); + } fprintf(fd, ")\n"); } @@ -580,18 +592,9 @@ void edif_print(FILE*fd, edif_t edf) fprintf(fd, " (cellRef %s (libraryRef DESIGN))\n", edf->name); for (prp = edf->property ; prp ; prp = prp->next) { - switch (prp->ptype) { - case PRP_STRING: - fprintf(fd, " (property %s (string \"%s\"))\n", - prp->name, prp->value_.str); - break; - case PRP_INTEGER: - fprintf(fd, " (property %s (integer %ld))\n", - prp->name, prp->value_.num); - break; - case PRP_NONE: - assert(0); - } + fprintf(fd, " "); + fprint_property(fd, prp); + fprintf(fd, "\n"); } fprintf(fd, " )\n"); @@ -604,6 +607,9 @@ void edif_print(FILE*fd, edif_t edf) /* * $Log: edif.c,v $ + * Revision 1.7 2003/08/07 05:18:04 steve + * Add support for OR/NOR/bufif0/bufif1. + * * Revision 1.6 2003/08/07 04:04:01 steve * Add an LPM device type. * diff --git a/tgt-fpga/edif.h b/tgt-fpga/edif.h index f27819435..0fd3656d9 100644 --- a/tgt-fpga/edif.h +++ b/tgt-fpga/edif.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: edif.h,v 1.5 2003/08/07 04:04:01 steve Exp $" +#ident "$Id: edif.h,v 1.6 2003/08/07 05:18:04 steve Exp $" #endif # include @@ -172,6 +172,10 @@ extern edif_cell_t edif_xcell_create(edif_xlibrary_t, const char*name, extern void edif_cell_portconfig(edif_cell_t cell, unsigned idx, const char*name, ivl_signal_port_t dir); +/* Attach a property to a cell port. */ +extern void edif_cell_port_pstring(edif_cell_t cell, unsigned idx, + const char*name, const char*value); + /* Cells may have properties attached to them. These properties are included in the library declaration for the cell, instead of the cell instances. */ @@ -225,6 +229,9 @@ extern void edif_print(FILE*fd, edif_t design); /* * $Log: edif.h,v $ + * Revision 1.6 2003/08/07 05:18:04 steve + * Add support for OR/NOR/bufif0/bufif1. + * * Revision 1.5 2003/08/07 04:04:01 steve * Add an LPM device type. *