diff --git a/tgt-fpga/d-virtex.c b/tgt-fpga/d-virtex.c index 90bbbe920..e98045d77 100644 --- a/tgt-fpga/d-virtex.c +++ b/tgt-fpga/d-virtex.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: d-virtex.c,v 1.26 2003/06/26 03:57:05 steve Exp $" +#ident "$Id: d-virtex.c,v 1.27 2003/06/28 04:18:47 steve Exp $" #endif # include "device.h" @@ -163,6 +163,170 @@ void virtex_show_footer(ivl_design_t des) edif_print(xnf, edf); } +static void virtex_or_wide(ivl_net_logic_t net) +{ + edif_cell_t cell_muxcy_l = xilinx_cell_muxcy_l(xlib); + edif_cell_t cell_muxcy = xilinx_cell_muxcy(xlib); + edif_cell_t cell_lut4 = xilinx_cell_lut4(xlib); + + edif_cellref_t true_out, false_out; + edif_cellref_t lut, muxcy, muxcy_down; + edif_joint_t jnt; + + unsigned idx, inputs, lut4_cnt; + + if (ivl_logic_type(net) == IVL_LO_OR) { + true_out = edif_cellref_create(edf, cell_1); + false_out = edif_cellref_create(edf, cell_0); + } else { + true_out = edif_cellref_create(edf, cell_0); + false_out = edif_cellref_create(edf, cell_1); + } + + inputs = ivl_logic_pins(net) - 1; + lut4_cnt = (inputs-1)/4; + + for (idx = 0 ; idx < lut4_cnt ; idx += 1) { + muxcy = edif_cellref_create(edf, cell_muxcy_l); + lut = edif_cellref_create(edf, cell_lut4); + + edif_cellref_pstring(lut, "INIT", "0001"); + + jnt = edif_joint_create(edf); + edif_add_to_joint(jnt, lut, LUT_O); + edif_add_to_joint(jnt, muxcy, MUXCY_S); + + jnt = edif_joint_create(edf); + edif_add_to_joint(jnt, true_out, 0); + edif_add_to_joint(jnt, muxcy, MUXCY_DI); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx*4+1+0)); + edif_add_to_joint(jnt, lut, LUT_I0); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx*4+1+1)); + edif_add_to_joint(jnt, lut, LUT_I1); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx*4+1+2)); + edif_add_to_joint(jnt, lut, LUT_I2); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx*4+1+3)); + edif_add_to_joint(jnt, lut, LUT_I3); + + if (idx > 0) { + jnt = edif_joint_create(edf); + edif_add_to_joint(jnt, muxcy, MUXCY_CI); + edif_add_to_joint(jnt, muxcy_down, MUXCY_O); + } else { + jnt = edif_joint_create(edf); + edif_add_to_joint(jnt, muxcy, MUXCY_CI); + edif_add_to_joint(jnt, false_out, 0); + } + + muxcy_down = muxcy; + } + + muxcy = edif_cellref_create(edf, cell_muxcy); + jnt = edif_joint_create(edf); + edif_add_to_joint(jnt, true_out, 0); + edif_add_to_joint(jnt, muxcy, MUXCY_DI); + + jnt = edif_joint_create(edf); + edif_add_to_joint(jnt, muxcy, MUXCY_CI); + edif_add_to_joint(jnt, muxcy_down, MUXCY_O); + + switch (ivl_logic_pins(net) - 1 - lut4_cnt*4) { + + case 1: + lut = edif_cellref_create(edf, xilinx_cell_inv(xlib)); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+0)); + edif_add_to_joint(jnt, lut, BUF_I); + break; + + case 2: + lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib)); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+0)); + edif_add_to_joint(jnt, lut, LUT_I0); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+1)); + edif_add_to_joint(jnt, lut, LUT_I1); + break; + + case 3: + lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib)); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+0)); + edif_add_to_joint(jnt, lut, LUT_I0); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+1)); + edif_add_to_joint(jnt, lut, LUT_I1); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+2)); + edif_add_to_joint(jnt, lut, LUT_I2); + break; + + case 4: + lut = edif_cellref_create(edf, cell_lut4); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+0)); + edif_add_to_joint(jnt, lut, LUT_I0); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+1)); + edif_add_to_joint(jnt, lut, LUT_I1); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+2)); + edif_add_to_joint(jnt, lut, LUT_I2); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+3)); + edif_add_to_joint(jnt, lut, LUT_I3); + break; + + default: + assert(0); + } + + jnt = edif_joint_create(edf); + edif_add_to_joint(jnt, lut, LUT_O); + edif_add_to_joint(jnt, muxcy, MUXCY_S); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0)); + edif_add_to_joint(jnt, muxcy, MUXCY_O); +} + +/* + * Pick off the cases where there is a Virtex specific implementation + * that is better then the generic Xilinx implementation. Route the + * remaining to the base xilinx_logic implementation. + */ +void virtex_logic(ivl_net_logic_t net) +{ + /* Nothing I can do if the user expresses a specific + opinion. The cellref attribute forces me to let the base + xilinx_logic take care of it. */ + if (ivl_logic_attr(net, "cellref")) { + xilinx_logic(net); + return; + } + + switch (ivl_logic_type(net)) { + + case IVL_LO_OR: + case IVL_LO_NOR: + if (ivl_logic_pins(net) <= 5) { + xilinx_logic(net); + + } else { + virtex_or_wide(net); + } + break; + + default: + xilinx_logic(net); + break; + } +} + void virtex_generic_dff(ivl_lpm_t net) { unsigned idx; @@ -665,7 +829,7 @@ const struct device_s d_virtex_edif = { virtex_show_footer, xilinx_show_scope, xilinx_pad, - xilinx_logic, + virtex_logic, virtex_generic_dff, virtex_eq, virtex_eq, @@ -680,6 +844,9 @@ const struct device_s d_virtex_edif = { /* * $Log: d-virtex.c,v $ + * Revision 1.27 2003/06/28 04:18:47 steve + * Add support for wide OR/NOR gates. + * * Revision 1.26 2003/06/26 03:57:05 steve * Add Xilinx support for A/B MUX devices. * diff --git a/tgt-fpga/d-virtex2.c b/tgt-fpga/d-virtex2.c index c920e74e1..566fe0920 100644 --- a/tgt-fpga/d-virtex2.c +++ b/tgt-fpga/d-virtex2.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: d-virtex2.c,v 1.15 2003/06/26 03:57:05 steve Exp $" +#ident "$Id: d-virtex2.c,v 1.16 2003/06/28 04:18:47 steve Exp $" #endif # include "device.h" @@ -136,7 +136,7 @@ const struct device_s d_virtex2_edif = { virtex_show_footer, xilinx_show_scope, xilinx_pad, - xilinx_logic, + virtex_logic, virtex_generic_dff, virtex_eq, virtex_eq, @@ -151,6 +151,9 @@ const struct device_s d_virtex2_edif = { /* * $Log: d-virtex2.c,v $ + * Revision 1.16 2003/06/28 04:18:47 steve + * Add support for wide OR/NOR gates. + * * Revision 1.15 2003/06/26 03:57:05 steve * Add Xilinx support for A/B MUX devices. * diff --git a/tgt-fpga/xilinx.c b/tgt-fpga/xilinx.c index a2510ff16..aa4327721 100644 --- a/tgt-fpga/xilinx.c +++ b/tgt-fpga/xilinx.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: xilinx.c,v 1.3 2003/06/26 03:57:05 steve Exp $" +#ident "$Id: xilinx.c,v 1.4 2003/06/28 04:18:47 steve Exp $" #endif # include "edif.h" @@ -52,6 +52,18 @@ edif_cell_t xilinx_cell_bufg(edif_xlibrary_t xlib) return cell; } +edif_cell_t xilinx_cell_buft(edif_xlibrary_t xlib) +{ + static edif_cell_t cell = 0; + if (cell) return cell; + + cell = edif_xcell_create(xlib, "BUFT", 3); + edif_cell_portconfig(cell, BUF_O, "O", IVL_SIP_OUTPUT); + edif_cell_portconfig(cell, BUF_I, "I", IVL_SIP_INPUT); + edif_cell_portconfig(cell, BUF_T, "T", IVL_SIP_INPUT); + return cell; +} + edif_cell_t xilinx_cell_ibuf(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; @@ -436,6 +448,24 @@ void xilinx_logic(ivl_net_logic_t net) edif_add_to_joint(jnt, obj, BUF_I); break; + case IVL_LO_BUFIF0: + /* The Xilinx BUFT devices is a BUF that adds a T + input. The output is tri-stated if the T input is + 1. In other words, it acts just like bufif0. */ + assert(ivl_logic_pins(net) == 3); + + obj = edif_cellref_create(edf, xilinx_cell_buft(xlib)); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0)); + edif_add_to_joint(jnt, obj, BUF_O); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1)); + edif_add_to_joint(jnt, obj, BUF_I); + + jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 2)); + edif_add_to_joint(jnt, obj, BUF_T); + break; + case IVL_LO_NOT: assert(ivl_logic_pins(net) == 2); @@ -732,6 +762,9 @@ void xilinx_shiftl(ivl_lpm_t net) /* * $Log: xilinx.c,v $ + * Revision 1.4 2003/06/28 04:18:47 steve + * Add support for wide OR/NOR gates. + * * Revision 1.3 2003/06/26 03:57:05 steve * Add Xilinx support for A/B MUX devices. * diff --git a/tgt-fpga/xilinx.h b/tgt-fpga/xilinx.h index 26edc6491..6eca38d35 100644 --- a/tgt-fpga/xilinx.h +++ b/tgt-fpga/xilinx.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: xilinx.h,v 1.3 2003/06/26 03:57:05 steve Exp $" +#ident "$Id: xilinx.h,v 1.4 2003/06/28 04:18:47 steve Exp $" #endif /* @@ -39,12 +39,14 @@ this category. */ extern edif_cell_t xilinx_cell_buf (edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_bufg(edif_xlibrary_t xlib); +extern edif_cell_t xilinx_cell_buft(edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_inv (edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_ibuf(edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_obuf(edif_xlibrary_t xlib); #define BUF_O 0 #define BUF_I 1 - + /* Only some buffers have this input. */ +#define BUF_T 2 /* === LUT Devices === */ @@ -96,6 +98,7 @@ extern edif_cell_t xilinx_cell_xorcy(edif_xlibrary_t xlib); /* === Inheritable Methods === */ extern void virtex_show_footer(ivl_design_t des); +extern void virtex_logic(ivl_net_logic_t net); extern void virtex_generic_dff(ivl_lpm_t net); extern void virtex_eq(ivl_lpm_t net); extern void virtex_ge(ivl_lpm_t net); @@ -110,6 +113,9 @@ extern void xilinx_shiftl(ivl_lpm_t net); /* * $Log: xilinx.h,v $ + * Revision 1.4 2003/06/28 04:18:47 steve + * Add support for wide OR/NOR gates. + * * Revision 1.3 2003/06/26 03:57:05 steve * Add Xilinx support for A/B MUX devices. *