diff --git a/tgt-fpga/d-generic-edif.c b/tgt-fpga/d-generic-edif.c index 147cb0855..7eecb65af 100644 --- a/tgt-fpga/d-generic-edif.c +++ b/tgt-fpga/d-generic-edif.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ident "$Id: d-generic-edif.c,v 1.3 2001/09/06 04:28:40 steve Exp $" +#ident "$Id: d-generic-edif.c,v 1.4 2001/09/09 22:23:28 steve Exp $" # include "device.h" # include "fpga_priv.h" @@ -347,30 +347,33 @@ void edif_show_generic_dff(ivl_lpm_t net) { ivl_nexus_t nex; char jbuf[1024]; + unsigned idx; - assert(ivl_lpm_width(net) == 1); + for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { - edif_uref += 1; + edif_uref += 1; - fprintf(xnf, "(instance (rename U%u \"%s\")", edif_uref, ivl_lpm_name(net)); - fprintf(xnf, " (viewRef Netlist_representation" + fprintf(xnf, "(instance (rename U%u \"%s[%u]\")", + edif_uref, ivl_lpm_name(net), idx); + fprintf(xnf, " (viewRef Netlist_representation" " (cellRef FDCE (libraryRef VIRTEX))))\n"); - nex = ivl_lpm_q(net, 0); - sprintf(jbuf, "(portRef Q (instanceRef U%u))", edif_uref); - edif_set_nexus_joint(nex, jbuf); - - nex = ivl_lpm_data(net, 0); - sprintf(jbuf, "(portRef D (instanceRef U%u))", edif_uref); - edif_set_nexus_joint(nex, jbuf); - - nex = ivl_lpm_clk(net); - sprintf(jbuf, "(portRef C (instanceRef U%u))", edif_uref); - edif_set_nexus_joint(nex, jbuf); - - if ((nex = ivl_lpm_enable(net))) { - sprintf(jbuf, "(portRef CE (instanceRef U%u))", edif_uref); + nex = ivl_lpm_q(net, idx); + sprintf(jbuf, "(portRef Q (instanceRef U%u))", edif_uref); edif_set_nexus_joint(nex, jbuf); + + nex = ivl_lpm_data(net, idx); + sprintf(jbuf, "(portRef D (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(nex, jbuf); + + nex = ivl_lpm_clk(net); + sprintf(jbuf, "(portRef C (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(nex, jbuf); + + if ((nex = ivl_lpm_enable(net))) { + sprintf(jbuf, "(portRef CE (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(nex, jbuf); + } } } @@ -389,6 +392,11 @@ const struct device_s d_generic_edif = { /* * $Log: d-generic-edif.c,v $ + * Revision 1.4 2001/09/09 22:23:28 steve + * Virtex support for mux devices and adders + * with carry chains. Also, make Virtex specific + * implementations of primitive logic. + * * Revision 1.3 2001/09/06 04:28:40 steve * Separate the virtex and generic-edif code generators. * diff --git a/tgt-fpga/d-virtex.c b/tgt-fpga/d-virtex.c index bb88f59f5..53a685b2c 100644 --- a/tgt-fpga/d-virtex.c +++ b/tgt-fpga/d-virtex.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ident "$Id: d-virtex.c,v 1.1 2001/09/06 04:28:40 steve Exp $" +#ident "$Id: d-virtex.c,v 1.2 2001/09/09 22:23:28 steve Exp $" # include "device.h" # include "fpga_priv.h" @@ -27,18 +27,34 @@ /* * This is the EDIF code generator for VIRTEX style parts. It uses the - * VIRTEX primitives from the unified library. + * following VIRTEX primitives from the unified library. + * + * BUF O, I + * non-inverting buffer. This device is typically removed by the + * place-and-route step, as it is not normally needed within an + * FPGA net. + * + * INV O, I + * Inverting buffer. + * + * LUT2 O, I0, I1 + * LUT3 O, I0, I1, I2 + * LUT4 O, I0, I1, I2, I3 + * These are look-up tables. They represent the LUT sub-devices + * that live in the CLBs, 2 per slice. The logic value of the + * device itself is given by an INIT property. + * + * The INIT property is a string of hex digits. The binary value + * that the digits represents is the outputs addressed by the + * inputs. For example, to get an AND2 from LUT2, INIT=8. + * + * MUXCY_L LO, S, DI, CI + * + * XORCY O, LI, CI */ static const char*virtex_library_text = " (external VIRTEX (edifLevel 0) (technology (numberDefinition))\n" -" (cell AND2 (cellType GENERIC)\n" -" (view Netlist_representation\n" -" (viewType NETLIST)\n" -" (interface\n" -" (port O (direction OUTPUT))\n" -" (port I0 (direction INPUT))\n" -" (port I1 (direction INPUT)))))\n" " (cell BUF (cellType GENERIC)\n" " (view Netlist_representation\n" " (viewType NETLIST)\n" @@ -57,14 +73,20 @@ static const char*virtex_library_text = " (view Netlist_representation\n" " (viewType NETLIST)\n" " (interface (port G (direction OUTPUT)))))\n" -" (cell NOR2 (cellType GENERIC)\n" +" (cell INV (cellType GENERIC)\n" +" (view Netlist_representation\n" +" (viewType NETLIST)\n" +" (interface\n" +" (port O (direction OUTPUT))\n" +" (port I (direction INPUT)))))\n" +" (cell LUT2 (cellType GENERIC)\n" " (view Netlist_representation\n" " (viewType NETLIST)\n" " (interface\n" " (port O (direction OUTPUT))\n" " (port I0 (direction INPUT))\n" " (port I1 (direction INPUT)))))\n" -" (cell NOR3 (cellType GENERIC)\n" +" (cell LUT3 (cellType GENERIC)\n" " (view Netlist_representation\n" " (viewType NETLIST)\n" " (interface\n" @@ -72,10 +94,34 @@ static const char*virtex_library_text = " (port I0 (direction INPUT))\n" " (port I1 (direction INPUT))\n" " (port I2 (direction INPUT)))))\n" +" (cell LUT4 (cellType GENERIC)\n" +" (view Netlist_representation\n" +" (viewType NETLIST)\n" +" (interface\n" +" (port O (direction OUTPUT))\n" +" (port I0 (direction INPUT))\n" +" (port I1 (direction INPUT))\n" +" (port I2 (direction INPUT))\n" +" (port I3 (direction INPUT)))))\n" +" (cell MUXCY_L (cellType GENERIC)\n" +" (view Netlist_representation\n" +" (viewType NETLIST)\n" +" (interface\n" +" (port LO (direction OUTPUT))\n" +" (port S (direction INPUT))\n" +" (port DI (direction INPUT))\n" +" (port CI (direction INPUT)))))\n" " (cell VCC (cellType GENERIC)\n" " (view Netlist_representation\n" " (viewType NETLIST)\n" " (interface (port P (direction OUTPUT)))))\n" +" (cell XORCY (cellType GENERIC)\n" +" (view Netlist_representation\n" +" (viewType NETLIST)\n" +" (interface\n" +" (port O (direction OUTPUT))\n" +" (port LI (direction INPUT))\n" +" (port CI (direction INPUT)))))\n" " )\n" ; @@ -85,32 +131,120 @@ static void edif_show_header(ivl_design_t des) edif_show_header_generic(des, virtex_library_text); } -static void edif_show_logic(ivl_net_logic_t net) +static void edif_show_lut2(const char*name, unsigned uref, + ivl_nexus_t O, ivl_nexus_t I0, ivl_nexus_t I1, + const char*truth_table) +{ + char jbuf[1024]; + fprintf(xnf, "(instance (rename U%u \"%s\")" + " (property INIT (string \"%s\"))", + uref, name, truth_table); + + fprintf(xnf, " (viewRef Netlist_representation" + " (cellRef LUT2 (libraryRef VIRTEX))))\n"); + + sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(O, jbuf); + + sprintf(jbuf, "(portRef I0 (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(I0, jbuf); + + sprintf(jbuf, "(portRef I1 (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(I1, jbuf); +} + +static void edif_show_lut3(const char*name, unsigned uref, + ivl_nexus_t O, + ivl_nexus_t I0, + ivl_nexus_t I1, + ivl_nexus_t I2, + const char*truth_table) +{ + char jbuf[1024]; + fprintf(xnf, "(instance (rename U%u \"%s\")" + " (property INIT (string \"%s\"))", + uref, name, truth_table); + + fprintf(xnf, " (viewRef Netlist_representation" + " (cellRef LUT3 (libraryRef VIRTEX))))\n"); + + sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(O, jbuf); + + sprintf(jbuf, "(portRef I0 (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(I0, jbuf); + + sprintf(jbuf, "(portRef I1 (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(I1, jbuf); + + sprintf(jbuf, "(portRef I2 (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(I2, jbuf); +} + +static void edif_show_lut4(const char*name, unsigned uref, + ivl_nexus_t O, + ivl_nexus_t I0, ivl_nexus_t I1, + ivl_nexus_t I2, ivl_nexus_t I3, + const char*truth_table) +{ + char jbuf[1024]; + fprintf(xnf, "(instance (rename U%u \"%s\")" + " (property INIT (string \"%s\"))", + uref, name, truth_table); + + fprintf(xnf, " (viewRef Netlist_representation" + " (cellRef LUT4 (libraryRef VIRTEX))))\n"); + + sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(O, jbuf); + + sprintf(jbuf, "(portRef I0 (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(I0, jbuf); + + sprintf(jbuf, "(portRef I1 (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(I1, jbuf); + + sprintf(jbuf, "(portRef I2 (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(I2, jbuf); + + sprintf(jbuf, "(portRef I3 (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(I3, jbuf); +} + +static void edif_show_virtex_logic(ivl_net_logic_t net) { char jbuf[1024]; - unsigned idx; edif_uref += 1; switch (ivl_logic_type(net)) { case IVL_LO_AND: - assert(ivl_logic_pins(net) <= 10); + assert(ivl_logic_pins(net) <= 5); assert(ivl_logic_pins(net) >= 3); - fprintf(xnf, "(instance (rename U%u \"%s\")", - edif_uref, ivl_logic_name(net)); - fprintf(xnf, " (viewRef Netlist_representation" - " (cellRef AND%u (libraryRef VIRTEX))))\n", - ivl_logic_pins(net) - 1); - - sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref); - edif_set_nexus_joint(ivl_logic_pin(net, 0), jbuf); - - for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { - sprintf(jbuf, "(portRef I%u (instanceRef U%u))", - idx-1, edif_uref); - edif_set_nexus_joint(ivl_logic_pin(net, idx), jbuf); + switch (ivl_logic_pins(net)) { + case 3: + edif_show_lut2(ivl_logic_name(net), edif_uref, + ivl_logic_pin(net, 0), + ivl_logic_pin(net, 1), + ivl_logic_pin(net, 2), "8"); + break; + case 4: + edif_show_lut3(ivl_logic_name(net), edif_uref, + ivl_logic_pin(net, 0), + ivl_logic_pin(net, 1), + ivl_logic_pin(net, 2), + ivl_logic_pin(net, 3), "80"); + break; + case 5: + edif_show_lut4(ivl_logic_name(net), edif_uref, + ivl_logic_pin(net, 0), + ivl_logic_pin(net, 1), + ivl_logic_pin(net, 2), + ivl_logic_pin(net, 3), + ivl_logic_pin(net, 4), "8000"); + break; } break; @@ -129,45 +263,292 @@ static void edif_show_logic(ivl_net_logic_t net) break; case IVL_LO_NOR: - assert(ivl_logic_pins(net) <= 10); + assert(ivl_logic_pins(net) <= 5); assert(ivl_logic_pins(net) >= 3); + switch (ivl_logic_pins(net)) { + case 3: + edif_show_lut2(ivl_logic_name(net), edif_uref, + ivl_logic_pin(net, 0), + ivl_logic_pin(net, 1), + ivl_logic_pin(net, 2), "1"); + break; + case 4: + edif_show_lut3(ivl_logic_name(net), edif_uref, + ivl_logic_pin(net, 0), + ivl_logic_pin(net, 1), + ivl_logic_pin(net, 2), + ivl_logic_pin(net, 3), "01"); + break; + case 5: + edif_show_lut4(ivl_logic_name(net), edif_uref, + ivl_logic_pin(net, 0), + ivl_logic_pin(net, 1), + ivl_logic_pin(net, 2), + ivl_logic_pin(net, 3), + ivl_logic_pin(net, 4), "0001"); + break; + } + break; + + case IVL_LO_NOT: + assert(ivl_logic_pins(net) == 2); fprintf(xnf, "(instance (rename U%u \"%s\")", edif_uref, ivl_logic_name(net)); fprintf(xnf, " (viewRef Netlist_representation" - " (cellRef NOR%u (libraryRef VIRTEX))))\n", - ivl_logic_pins(net) - 1); + " (cellRef INV (libraryRef VIRTEX))))\n"); sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref); edif_set_nexus_joint(ivl_logic_pin(net, 0), jbuf); - for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { - sprintf(jbuf, "(portRef I%u (instanceRef U%u))", - idx-1, edif_uref); - edif_set_nexus_joint(ivl_logic_pin(net, idx), jbuf); + sprintf(jbuf, "(portRef I (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(ivl_logic_pin(net, 1), jbuf); + break; + + case IVL_LO_OR: + assert(ivl_logic_pins(net) <= 5); + assert(ivl_logic_pins(net) >= 3); + + switch (ivl_logic_pins(net)) { + case 3: + edif_show_lut2(ivl_logic_name(net), edif_uref, + ivl_logic_pin(net, 0), + ivl_logic_pin(net, 1), + ivl_logic_pin(net, 2), "E"); + break; + case 4: + edif_show_lut3(ivl_logic_name(net), edif_uref, + ivl_logic_pin(net, 0), + ivl_logic_pin(net, 1), + ivl_logic_pin(net, 2), + ivl_logic_pin(net, 3), "FE"); + break; + case 5: + edif_show_lut4(ivl_logic_name(net), edif_uref, + ivl_logic_pin(net, 0), + ivl_logic_pin(net, 1), + ivl_logic_pin(net, 2), + ivl_logic_pin(net, 3), + ivl_logic_pin(net, 4), "FFFE"); + break; } break; default: - fprintf(stderr, "UNSUPPORT LOGIC TYPE: %u\n", ivl_logic_type(net)); + fprintf(stderr, "UNSUPPORTED LOGIC TYPE: %u\n", + ivl_logic_type(net)); } } +static void edif_show_virtex_eq(ivl_lpm_t net) +{ + assert(ivl_lpm_width(net) >= 1); + + edif_uref += 1; + + switch (ivl_lpm_width(net)) { + case 1: + edif_show_lut2(ivl_lpm_name(net), edif_uref, + ivl_lpm_q(net, 0), + ivl_lpm_data(net, 0), + ivl_lpm_datab(net, 0), "9"); + break; + + case 2: + edif_show_lut4(ivl_lpm_name(net), edif_uref, + ivl_lpm_q(net, 0), + ivl_lpm_data(net, 0), ivl_lpm_datab(net, 0), + ivl_lpm_data(net, 1), ivl_lpm_datab(net, 1), + "9009"); + break; + + default: + fprintf(stderr, "internal error: IVL_LPM_CMP_EQ: " + "Unsupported width (%u)\n", ivl_lpm_width(net)); + assert(0); + } +} + +/* + * This supports the general MUX with a single select input. The + * output is selected from one of two inputs. + * + * This implements the mux a bit slice at a time. Each slice is a + * 1-bit mux implemented with a three input LUT: I0 and I1 are the + * alternative inputs, and I2 is the select. + * + * FIXME: In the long run, it would be cool to detect that the inputs + * of the mux are themselves LUT devices and generate MUXF5 devices in + * those cases. This currently does *not* do that. + */ +static void edif_show_virtex_mux(ivl_lpm_t net) +{ + unsigned idx; + assert(ivl_lpm_width(net) >= 1); + assert(ivl_lpm_selects(net) == 1); + + for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { + char tmp_name[1024]; + + edif_uref += 1; + sprintf(tmp_name, "%s<%u>", ivl_lpm_name(net), idx); + + edif_show_lut3(tmp_name, edif_uref, + ivl_lpm_q(net, idx), + ivl_lpm_data2(net, 0, idx), + ivl_lpm_data2(net, 1, idx), + ivl_lpm_select(net, 0), + "CA"); + } +} + +static void edif_show_virtex_add(ivl_lpm_t net) +{ + char jbuf [1024]; + unsigned idx; + unsigned nref = 0; + + /* Handle the special case that the adder is only one bit + wide. Generate an XOR gate to perform the half-add. */ + if (ivl_lpm_width(net) == 1) { + edif_uref += 1; + + edif_show_lut2(ivl_lpm_name(net), edif_uref, + ivl_lpm_q(net, 0), + ivl_lpm_data(net, 0), + ivl_lpm_datab(net, 0), + "6"); + return; + } + + assert(ivl_lpm_width(net) > 1); + edif_uref += 1; + + /* First, draw the bottom bit slice of the adder. This + includes the LUT2 device to perform the addition, and a + MUXCY_L device to send the carry up to the next bit. */ + fprintf(xnf, "(instance (rename U%u_L0 \"%s\"[0])" + " (property INIT (string \"6\"))", edif_uref, + ivl_lpm_name(net)); + fprintf(xnf, " (viewRef Netlist_representation" + " (cellRef LUT2 (libraryRef VIRTEX))))\n"); + + fprintf(xnf, "(instance U%u_M0", edif_uref); + fprintf(xnf, " (viewRef Netlist_representation" + " (cellRef MUXCY_L (libraryRef VIRTEX))))\n"); + + sprintf(jbuf, "(portRef I0 (instanceRef U%u_L0))", edif_uref); + edif_set_nexus_joint(ivl_lpm_data(net, 0), jbuf); + + sprintf(jbuf, "(portRef I1 (instanceRef U%u_L0))", edif_uref); + edif_set_nexus_joint(ivl_lpm_datab(net, 0), jbuf); + + sprintf(jbuf, "(portRef O (instanceRef U%u_L0))" + " (portRef S (instanceRef U%u_M0))", + edif_uref, edif_uref); + edif_set_nexus_joint(ivl_lpm_q(net, 0), jbuf); + + /* Now draw all the inside bit slices. These include the LUT2 + device for the basic add, the MUXCY_L device to propagate + the carry, and an XORCY device to generate the real + output. The XORCY device carries the name of the LPM + device, the other devices have local names. */ + for (idx = 1 ; idx < (ivl_lpm_width(net)-1) ; idx += 1) { + + fprintf(xnf, "(instance U%u_L%u) (property INIT (string \"6\"))", + edif_uref, idx); + fprintf(xnf, " (viewRef Netlist_representation" + " (cellRef LUT2 (libraryRef VIRTEX))))\n"); + + fprintf(xnf, "(instance U%u_M%u", edif_uref, idx); + fprintf(xnf, " (viewRef Netlist_representation" + " (cellRef MUXCY_L (libraryRef VIRTEX))))\n"); + + fprintf(xnf, "(instance (rename U%u_X%u \"%s[%u]\")", + edif_uref, idx, ivl_lpm_name(net), idx); + fprintf(xnf, " (viewRef Netlist_representation" + " (cellRef XORCY (libraryRef VIRTEX))))\n"); + + fprintf(xnf, "(net U%uN%u (joined" + " (portRef O (instanceRef U%u_L%u))" + " (portRef S (instanceRef U%u_M%u))" + " (portRef LI (instanceRef U%u_X%u))))\n", + edif_uref, nref++, edif_uref, idx, edif_uref, idx, + edif_uref, idx); + + fprintf(xnf, "(net U%uN%u (joined" + " (portRef CI (instanceRef U%u_M%u))" + " (portRef CI (instanceRef U%u_X%u))" + " (portRef LO (instanceRef U%u_M%u))))\n", + edif_uref, nref++, edif_uref, idx, edif_uref, idx, + edif_uref, idx-1); + + sprintf(jbuf, "(portRef I0 (instanceRef U%u_L%u))", + edif_uref, idx); + edif_set_nexus_joint(ivl_lpm_data(net, idx), jbuf); + + sprintf(jbuf, "(portRef I1 (instanceRef U%u_L%u))", + edif_uref, idx); + edif_set_nexus_joint(ivl_lpm_datab(net, idx), jbuf); + + sprintf(jbuf, "(portRef O (instanceRef U%u_X%u))", + edif_uref, idx); + edif_set_nexus_joint(ivl_lpm_q(net, idx), jbuf); + } + + + fprintf(xnf, "(instance U%u_L%u) (property INIT (string \"6\"))", + edif_uref, idx); + fprintf(xnf, " (viewRef Netlist_representation" + " (cellRef LUT2 (libraryRef VIRTEX))))\n"); + + fprintf(xnf, "(instance (rename U%u_X%u \"%s[%u]\")", + edif_uref, idx, ivl_lpm_name(net), idx); + fprintf(xnf, " (viewRef Netlist_representation" + " (cellRef XORCY (libraryRef VIRTEX))))\n"); + + fprintf(xnf, "(net U%uN%u (joined" + " (portRef O (instanceRef U%u_L%u))" + " (portRef LI (instanceRef U%u_X%u))))\n", + edif_uref, nref++, edif_uref, idx, edif_uref, idx); + + fprintf(xnf, "(net U%uN%u (joined" + " (portRef CI (instanceRef U%u_X%u))" + " (portRef LO (instanceRef U%u_M%u))))\n", + edif_uref, nref++, edif_uref, idx, edif_uref, idx-1); + + sprintf(jbuf, "(portRef I0 (instanceRef U%u_L%u))", + edif_uref, idx); + edif_set_nexus_joint(ivl_lpm_data(net, idx), jbuf); + + sprintf(jbuf, "(portRef I1 (instanceRef U%u_L%u))", + edif_uref, idx); + edif_set_nexus_joint(ivl_lpm_datab(net, idx), jbuf); + + sprintf(jbuf, "(portRef O (instanceRef U%u_X%u))", + edif_uref, idx); + edif_set_nexus_joint(ivl_lpm_q(net, idx), jbuf); +} const struct device_s d_virtex_edif = { edif_show_header, edif_show_footer, - edif_show_logic, + edif_show_virtex_logic, edif_show_generic_dff, + edif_show_virtex_eq, 0, - 0, - 0, - 0 + edif_show_virtex_mux, + edif_show_virtex_add }; /* * $Log: d-virtex.c,v $ + * Revision 1.2 2001/09/09 22:23:28 steve + * Virtex support for mux devices and adders + * with carry chains. Also, make Virtex specific + * implementations of primitive logic. + * * Revision 1.1 2001/09/06 04:28:40 steve * Separate the virtex and generic-edif code generators. * diff --git a/tgt-fpga/gates.c b/tgt-fpga/gates.c index 25fc27fa5..76ab11463 100644 --- a/tgt-fpga/gates.c +++ b/tgt-fpga/gates.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ident "$Id: gates.c,v 1.6 2001/09/02 21:33:07 steve Exp $" +#ident "$Id: gates.c,v 1.7 2001/09/09 22:23:28 steve Exp $" # include # include "fpga_priv.h" @@ -32,22 +32,47 @@ static void show_gate_lpm(ivl_lpm_t net) switch (ivl_lpm_type(net)) { case IVL_LPM_ADD: + if (device->show_add == 0) { + fprintf(stderr, "fpga.tgt: IVL_LPM_ADD not supported" + " by this target.\n"); + return; + } device->show_add(net); break; case IVL_LPM_CMP_EQ: + if (device->show_cmp_eq == 0) { + fprintf(stderr, "fpga.tgt: IVL_LPM_CMP_EQ not supported" + " by this target.\n"); + return; + } device->show_cmp_eq(net); break; case IVL_LPM_CMP_NE: + if (device->show_cmp_ne == 0) { + fprintf(stderr, "fpga.tgt: IVL_LPM_CMP_NE not supported" + " by this target.\n"); + return; + } device->show_cmp_ne(net); break; case IVL_LPM_FF: + if (device->show_dff == 0) { + fprintf(stderr, "fpga.tgt: IVL_LPM_FF not supported" + " by this target.\n"); + return; + } device->show_dff(net); break; case IVL_LPM_MUX: + if (device->show_mux == 0) { + fprintf(stderr, "fpga.tgt: IVL_LPM_MUX not supported" + " by this target.\n"); + return; + } device->show_mux(net); break; @@ -73,6 +98,11 @@ int show_scope_gates(ivl_scope_t net, void*x) /* * $Log: gates.c,v $ + * Revision 1.7 2001/09/09 22:23:28 steve + * Virtex support for mux devices and adders + * with carry chains. Also, make Virtex specific + * implementations of primitive logic. + * * Revision 1.6 2001/09/02 21:33:07 steve * Rearrange the XNF code generator to be generic-xnf * so that non-XNF code generation is also possible.