2001-09-06 06:28:39 +02:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2001 Stephen 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
|
|
|
|
|
*/
|
2002-08-12 03:34:58 +02:00
|
|
|
#ifdef HAVE_CVS_IDENT
|
2002-09-15 23:52:19 +02:00
|
|
|
#ident "$Id: d-virtex.c,v 1.15 2002/09/15 21:52:19 steve Exp $"
|
2002-08-12 01:47:04 +02:00
|
|
|
#endif
|
2001-09-06 06:28:39 +02:00
|
|
|
|
|
|
|
|
# include "device.h"
|
|
|
|
|
# include "fpga_priv.h"
|
|
|
|
|
# include <stdlib.h>
|
|
|
|
|
# include <string.h>
|
2001-09-15 20:27:04 +02:00
|
|
|
#ifdef HAVE_MALLOC_H
|
2001-09-06 06:28:39 +02:00
|
|
|
# include <malloc.h>
|
2001-09-15 20:27:04 +02:00
|
|
|
#endif
|
2001-09-06 06:28:39 +02:00
|
|
|
# include <assert.h>
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* This is the EDIF code generator for VIRTEX style parts. It uses the
|
2001-09-10 00:23:28 +02:00
|
|
|
* 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
|
|
|
|
|
*
|
2002-09-15 23:52:19 +02:00
|
|
|
* MUXF5 O, S, I0, I1
|
|
|
|
|
* MUXF6 O, S, I0, I1
|
|
|
|
|
*
|
2001-09-10 00:23:28 +02:00
|
|
|
* XORCY O, LI, CI
|
2001-09-06 06:28:39 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static const char*virtex_library_text =
|
|
|
|
|
" (external VIRTEX (edifLevel 0) (technology (numberDefinition))\n"
|
|
|
|
|
" (cell BUF (cellType GENERIC)\n"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (view net\n"
|
2001-09-06 06:28:39 +02:00
|
|
|
" (viewType NETLIST)\n"
|
|
|
|
|
" (interface\n"
|
|
|
|
|
" (port O (direction OUTPUT))\n"
|
|
|
|
|
" (port I (direction INPUT)))))\n"
|
|
|
|
|
" (cell FDCE (cellType GENERIC)\n"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (view net\n"
|
2001-09-06 06:28:39 +02:00
|
|
|
" (viewType NETLIST)\n"
|
|
|
|
|
" (interface\n"
|
|
|
|
|
" (port Q (direction OUTPUT))\n"
|
|
|
|
|
" (port D (direction INPUT))\n"
|
|
|
|
|
" (port C (direction INPUT))\n"
|
|
|
|
|
" (port CE (direction INPUT)))))\n"
|
2001-09-17 00:26:47 +02:00
|
|
|
" (cell GBUF (cellType GENERIC)\n"
|
|
|
|
|
" (view net\n"
|
|
|
|
|
" (viewType NETLIST)\n"
|
|
|
|
|
" (interface\n"
|
|
|
|
|
" (port O (direction OUTPUT))\n"
|
|
|
|
|
" (port I (direction INPUT)))))\n"
|
2001-09-06 06:28:39 +02:00
|
|
|
" (cell GND (cellType GENERIC)\n"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (view net\n"
|
2001-09-06 06:28:39 +02:00
|
|
|
" (viewType NETLIST)\n"
|
2001-09-12 06:35:25 +02:00
|
|
|
" (interface (port GROUND (direction OUTPUT)))))\n"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (cell INV (cellType GENERIC)\n"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (view net\n"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (viewType NETLIST)\n"
|
|
|
|
|
" (interface\n"
|
|
|
|
|
" (port O (direction OUTPUT))\n"
|
|
|
|
|
" (port I (direction INPUT)))))\n"
|
2001-09-16 03:48:16 +02:00
|
|
|
" (cell IBUF (cellType GENERIC)\n"
|
|
|
|
|
" (view net\n"
|
|
|
|
|
" (viewType NETLIST)\n"
|
|
|
|
|
" (interface\n"
|
|
|
|
|
" (port O (direction OUTPUT))\n"
|
|
|
|
|
" (port I (direction INPUT)))))\n"
|
|
|
|
|
" (cell IPAD (cellType GENERIC)\n"
|
|
|
|
|
" (view net\n"
|
|
|
|
|
" (viewType NETLIST)\n"
|
|
|
|
|
" (interface\n"
|
|
|
|
|
" (port IPAD (direction OUTPUT)))))\n"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (cell LUT2 (cellType GENERIC)\n"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (view net\n"
|
2001-09-06 06:28:39 +02:00
|
|
|
" (viewType NETLIST)\n"
|
|
|
|
|
" (interface\n"
|
|
|
|
|
" (port O (direction OUTPUT))\n"
|
|
|
|
|
" (port I0 (direction INPUT))\n"
|
|
|
|
|
" (port I1 (direction INPUT)))))\n"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (cell LUT3 (cellType GENERIC)\n"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (view net\n"
|
2001-09-06 06:28:39 +02:00
|
|
|
" (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"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (cell LUT4 (cellType GENERIC)\n"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (view net\n"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (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"
|
2001-09-11 07:52:31 +02:00
|
|
|
" (cell MUXCY (cellType GENERIC)\n"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (view net\n"
|
2001-09-11 07:52:31 +02:00
|
|
|
" (viewType NETLIST)\n"
|
|
|
|
|
" (interface\n"
|
|
|
|
|
" (port O (direction OUTPUT))\n"
|
|
|
|
|
" (port S (direction INPUT))\n"
|
|
|
|
|
" (port DI (direction INPUT))\n"
|
|
|
|
|
" (port CI (direction INPUT)))))\n"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (cell MUXCY_L (cellType GENERIC)\n"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (view net\n"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (viewType NETLIST)\n"
|
|
|
|
|
" (interface\n"
|
|
|
|
|
" (port LO (direction OUTPUT))\n"
|
2002-09-15 23:52:19 +02:00
|
|
|
" (port S (direction INPUT))\n"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (port DI (direction INPUT))\n"
|
|
|
|
|
" (port CI (direction INPUT)))))\n"
|
2002-09-15 23:52:19 +02:00
|
|
|
" (cell MUXF5 (cellType GENERIC)\n"
|
|
|
|
|
" (view net\n"
|
|
|
|
|
" (viewType NETLIST)\n"
|
|
|
|
|
" (interface\n"
|
|
|
|
|
" (port O (direction OUTPUT))\n"
|
|
|
|
|
" (port S (direction INPUT))\n"
|
|
|
|
|
" (port I0 (direction INPUT))\n"
|
|
|
|
|
" (port I1 (direction INPUT)))))\n"
|
|
|
|
|
" (cell MUXF6 (cellType GENERIC)\n"
|
|
|
|
|
" (view net\n"
|
|
|
|
|
" (viewType NETLIST)\n"
|
|
|
|
|
" (interface\n"
|
|
|
|
|
" (port O (direction OUTPUT))\n"
|
|
|
|
|
" (port S (direction INPUT))\n"
|
|
|
|
|
" (port I0 (direction INPUT))\n"
|
|
|
|
|
" (port I1 (direction INPUT)))))\n"
|
2001-09-16 03:48:16 +02:00
|
|
|
" (cell OBUF (cellType GENERIC)\n"
|
|
|
|
|
" (view net\n"
|
|
|
|
|
" (viewType NETLIST)\n"
|
|
|
|
|
" (interface\n"
|
|
|
|
|
" (port O (direction OUTPUT))\n"
|
|
|
|
|
" (port I (direction INPUT)))))\n"
|
|
|
|
|
" (cell OPAD (cellType GENERIC)\n"
|
|
|
|
|
" (view net\n"
|
|
|
|
|
" (viewType NETLIST)\n"
|
|
|
|
|
" (interface\n"
|
|
|
|
|
" (port OPAD (direction INPUT)))))\n"
|
2001-09-06 06:28:39 +02:00
|
|
|
" (cell VCC (cellType GENERIC)\n"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (view net\n"
|
2001-09-06 06:28:39 +02:00
|
|
|
" (viewType NETLIST)\n"
|
2001-09-12 06:35:25 +02:00
|
|
|
" (interface (port VCC (direction OUTPUT)))))\n"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (cell XORCY (cellType GENERIC)\n"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (view net\n"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (viewType NETLIST)\n"
|
|
|
|
|
" (interface\n"
|
|
|
|
|
" (port O (direction OUTPUT))\n"
|
|
|
|
|
" (port LI (direction INPUT))\n"
|
|
|
|
|
" (port CI (direction INPUT)))))\n"
|
2001-09-06 06:28:39 +02:00
|
|
|
" )\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void edif_show_header(ivl_design_t des)
|
|
|
|
|
{
|
|
|
|
|
edif_show_header_generic(des, virtex_library_text);
|
|
|
|
|
}
|
|
|
|
|
|
2001-09-16 03:48:16 +02:00
|
|
|
static void edif_show_virtex_pad(ivl_signal_t sig, const char*str)
|
|
|
|
|
{
|
|
|
|
|
unsigned idx;
|
|
|
|
|
unsigned*pins;
|
|
|
|
|
char jbuf[1024];
|
|
|
|
|
|
|
|
|
|
pins = calloc(ivl_signal_pins(sig), sizeof(unsigned));
|
|
|
|
|
|
|
|
|
|
for (idx = 0 ; idx < ivl_signal_pins(sig) ; idx += 1) {
|
|
|
|
|
char*tmp;
|
|
|
|
|
pins[idx] = strtoul(str, &tmp, 10);
|
|
|
|
|
switch (*tmp) {
|
|
|
|
|
case ',':
|
|
|
|
|
tmp += 1;
|
|
|
|
|
break;
|
|
|
|
|
case 0:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
str = tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (idx = 0 ; idx < ivl_signal_pins(sig) ; idx += 1) {
|
|
|
|
|
|
|
|
|
|
edif_uref += 1;
|
|
|
|
|
|
|
|
|
|
switch (ivl_signal_port(sig)) {
|
|
|
|
|
case IVL_SIP_INPUT:
|
|
|
|
|
fprintf(xnf, "(instance U%uPAD"
|
|
|
|
|
" (viewRef net (cellRef IPAD (libraryRef VIRTEX)))",
|
|
|
|
|
edif_uref);
|
|
|
|
|
if (pins[idx] != 0)
|
|
|
|
|
fprintf(xnf, " (property LOC (string \"P%u\"))",
|
|
|
|
|
pins[idx]);
|
|
|
|
|
fprintf(xnf, ")\n");
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance U%u"
|
|
|
|
|
" (viewRef net "
|
|
|
|
|
" (cellRef IBUF (libraryRef VIRTEX))))\n",
|
|
|
|
|
edif_uref);
|
|
|
|
|
fprintf(xnf, "(net U%uN (joined"
|
|
|
|
|
" (portRef IPAD (instanceRef U%uPAD))"
|
|
|
|
|
" (portRef I (instanceRef U%u))))\n",
|
|
|
|
|
edif_uref, edif_uref, edif_uref);
|
|
|
|
|
|
|
|
|
|
sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_signal_pin(sig, idx), jbuf);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case IVL_SIP_OUTPUT:
|
|
|
|
|
fprintf(xnf, "(instance U%uPAD"
|
|
|
|
|
" (viewRef net (cellRef OPAD (libraryRef VIRTEX)))",
|
|
|
|
|
edif_uref);
|
|
|
|
|
if (pins[idx] != 0)
|
|
|
|
|
fprintf(xnf, " (property LOC (string \"P%u\"))",
|
|
|
|
|
pins[idx]);
|
|
|
|
|
fprintf(xnf, ")\n");
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance U%u"
|
|
|
|
|
" (viewRef net "
|
|
|
|
|
" (cellRef OBUF (libraryRef VIRTEX))))\n",
|
|
|
|
|
edif_uref);
|
|
|
|
|
fprintf(xnf, "(net U%uN (joined"
|
|
|
|
|
" (portRef OPAD (instanceRef U%uPAD))"
|
|
|
|
|
" (portRef O (instanceRef U%u))))\n",
|
|
|
|
|
edif_uref, edif_uref, edif_uref);
|
|
|
|
|
|
|
|
|
|
sprintf(jbuf, "(portRef I (instanceRef U%u))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_signal_pin(sig, idx), jbuf);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(pins);
|
|
|
|
|
}
|
|
|
|
|
|
2001-09-10 00:23:28 +02:00
|
|
|
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];
|
2001-09-11 07:52:31 +02:00
|
|
|
|
2001-09-10 00:23:28 +02:00
|
|
|
fprintf(xnf, "(instance (rename U%u \"%s\")"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (viewRef net"
|
2001-09-11 07:52:31 +02:00
|
|
|
" (cellRef LUT2 (libraryRef VIRTEX)))"
|
|
|
|
|
" (property INIT (string \"%s\")))\n",
|
2001-09-10 00:23:28 +02:00
|
|
|
uref, name, truth_table);
|
|
|
|
|
|
|
|
|
|
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];
|
2001-09-11 07:52:31 +02:00
|
|
|
|
2001-09-10 00:23:28 +02:00
|
|
|
fprintf(xnf, "(instance (rename U%u \"%s\")"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (viewRef net"
|
2001-09-11 07:52:31 +02:00
|
|
|
" (cellRef LUT3 (libraryRef VIRTEX)))"
|
|
|
|
|
" (property INIT (string \"%s\")))\n",
|
2001-09-10 00:23:28 +02:00
|
|
|
uref, name, truth_table);
|
|
|
|
|
|
|
|
|
|
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];
|
2001-09-11 07:52:31 +02:00
|
|
|
|
2001-09-10 00:23:28 +02:00
|
|
|
fprintf(xnf, "(instance (rename U%u \"%s\")"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (viewRef net"
|
2001-09-11 07:52:31 +02:00
|
|
|
" (cellRef LUT4 (libraryRef VIRTEX)))"
|
|
|
|
|
" (property INIT (string \"%s\")))\n",
|
2001-09-10 00:23:28 +02:00
|
|
|
uref, name, truth_table);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2001-09-17 00:26:47 +02:00
|
|
|
void edif_show_cellref_logic(ivl_net_logic_t net, const char*cellref)
|
|
|
|
|
{
|
|
|
|
|
char jbuf[1024];
|
|
|
|
|
unsigned idx;
|
|
|
|
|
const char*cp;
|
|
|
|
|
char*tmpname;
|
|
|
|
|
|
|
|
|
|
edif_uref += 1;
|
|
|
|
|
|
|
|
|
|
cp = strchr(cellref, ':');
|
|
|
|
|
assert(cp);
|
|
|
|
|
|
|
|
|
|
tmpname = malloc(cp - cellref + 1);
|
|
|
|
|
strncpy(tmpname, cellref, cp-cellref);
|
|
|
|
|
tmpname[cp-cellref] = 0;
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance (rename U%u (string \"%s\"))"
|
|
|
|
|
" (viewRef net (cellRef %s (libraryRef VIRTEX))))\n",
|
|
|
|
|
edif_uref, ivl_logic_name(net), tmpname);
|
|
|
|
|
|
|
|
|
|
free(tmpname);
|
|
|
|
|
|
|
|
|
|
cellref = cp + 1;
|
|
|
|
|
|
|
|
|
|
for (idx = 0 ; idx < ivl_logic_pins(net) ; idx += 1) {
|
|
|
|
|
ivl_nexus_t nex = ivl_logic_pin(net, idx);
|
|
|
|
|
|
|
|
|
|
cp = strchr(cellref, ',');
|
|
|
|
|
if (cp == 0)
|
|
|
|
|
cp = cellref+strlen(cellref);
|
|
|
|
|
|
|
|
|
|
tmpname = malloc(cp - cellref + 1);
|
|
|
|
|
strncpy(tmpname, cellref, cp-cellref);
|
|
|
|
|
tmpname[cp-cellref] = 0;
|
|
|
|
|
|
|
|
|
|
sprintf(jbuf, "(portRef %s (instanceRef U%u))",
|
|
|
|
|
tmpname, edif_uref);
|
|
|
|
|
edif_set_nexus_joint(nex, jbuf);
|
|
|
|
|
|
|
|
|
|
free(tmpname);
|
|
|
|
|
cellref = *cp? cp+1 : cp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-09-10 00:23:28 +02:00
|
|
|
static void edif_show_virtex_logic(ivl_net_logic_t net)
|
2001-09-06 06:28:39 +02:00
|
|
|
{
|
|
|
|
|
char jbuf[1024];
|
|
|
|
|
|
2001-09-17 00:26:47 +02:00
|
|
|
{ const char*dev = ivl_logic_attr(net, "cellref");
|
|
|
|
|
if (dev != 0) {
|
|
|
|
|
edif_show_cellref_logic(net, dev);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-09-06 06:28:39 +02:00
|
|
|
edif_uref += 1;
|
|
|
|
|
|
|
|
|
|
switch (ivl_logic_type(net)) {
|
|
|
|
|
|
|
|
|
|
case IVL_LO_AND:
|
2001-09-10 00:23:28 +02:00
|
|
|
assert(ivl_logic_pins(net) <= 5);
|
2001-09-06 06:28:39 +02:00
|
|
|
assert(ivl_logic_pins(net) >= 3);
|
|
|
|
|
|
2001-09-10 00:23:28 +02:00
|
|
|
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;
|
2001-09-06 06:28:39 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case IVL_LO_BUF:
|
2001-10-11 02:12:28 +02:00
|
|
|
case IVL_LO_BUFZ:
|
2001-09-06 06:28:39 +02:00
|
|
|
assert(ivl_logic_pins(net) == 2);
|
|
|
|
|
fprintf(xnf, "(instance (rename U%u \"%s\")",
|
|
|
|
|
edif_uref, ivl_logic_name(net));
|
2001-09-15 07:06:04 +02:00
|
|
|
fprintf(xnf, " (viewRef net"
|
2001-09-06 06:28:39 +02:00
|
|
|
" (cellRef BUF (libraryRef VIRTEX))))\n");
|
|
|
|
|
|
|
|
|
|
sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_logic_pin(net, 0), jbuf);
|
|
|
|
|
|
|
|
|
|
sprintf(jbuf, "(portRef I (instanceRef U%u))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_logic_pin(net, 1), jbuf);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case IVL_LO_NOR:
|
2001-09-10 00:23:28 +02:00
|
|
|
assert(ivl_logic_pins(net) <= 5);
|
2001-09-06 06:28:39 +02:00
|
|
|
assert(ivl_logic_pins(net) >= 3);
|
|
|
|
|
|
2001-09-10 00:23:28 +02:00
|
|
|
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);
|
2001-09-06 06:28:39 +02:00
|
|
|
fprintf(xnf, "(instance (rename U%u \"%s\")",
|
|
|
|
|
edif_uref, ivl_logic_name(net));
|
2001-09-15 07:06:04 +02:00
|
|
|
fprintf(xnf, " (viewRef net"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (cellRef INV (libraryRef VIRTEX))))\n");
|
2001-09-06 06:28:39 +02:00
|
|
|
|
|
|
|
|
sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_logic_pin(net, 0), jbuf);
|
|
|
|
|
|
2001-09-10 00:23:28 +02:00
|
|
|
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;
|
2001-09-06 06:28:39 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2001-09-14 06:17:20 +02:00
|
|
|
case IVL_LO_XNOR:
|
|
|
|
|
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), "9");
|
|
|
|
|
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), "69");
|
|
|
|
|
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), "9669");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case IVL_LO_XOR:
|
|
|
|
|
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), "6");
|
|
|
|
|
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), "96");
|
|
|
|
|
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), "6996");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2001-09-06 06:28:39 +02:00
|
|
|
default:
|
2001-09-10 00:23:28 +02:00
|
|
|
fprintf(stderr, "UNSUPPORTED LOGIC TYPE: %u\n",
|
|
|
|
|
ivl_logic_type(net));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-09-15 07:06:04 +02:00
|
|
|
/*
|
|
|
|
|
* This method handles both == and != operators, the identity
|
|
|
|
|
* comparison operators.
|
|
|
|
|
*
|
|
|
|
|
* If the identity compare is applied to small enough input vectors,
|
|
|
|
|
* it is shoved into a single LUT. Otherwise, it is strung out into a
|
|
|
|
|
* row of LUT devices chained together by carry muxes. The output of
|
|
|
|
|
* the comparison is the output of the last mux.
|
|
|
|
|
*
|
|
|
|
|
* When the compare is small, a LUT is generated with the appropriate
|
|
|
|
|
* truth table to cause an == or != result.
|
|
|
|
|
*
|
|
|
|
|
* When the compare is too wide for a single LUT, then it is made into
|
|
|
|
|
* a chain connected by a string of carry mux devices. Each LUT
|
|
|
|
|
* implements == for up to two pairs of bits, even if the final output
|
|
|
|
|
* is supposed to be !=. The LUT output is connected to an associated
|
|
|
|
|
* MUX select input. The CO output of each muxcy is passed up to the
|
|
|
|
|
* next higher order bits of the compare.
|
|
|
|
|
*
|
|
|
|
|
* For identity == compare, a != output from the LUT selects the DI
|
|
|
|
|
* input of the muxcy, generating a 0 output that is passed up. Since
|
|
|
|
|
* the next higher muxcy now gets a 0 input to both DI and CI, the
|
|
|
|
|
* output of the next higher muxcy is guaranteed to be 0, and so on to
|
|
|
|
|
* the final output of the carry chain. If the output from a LUT is ==,
|
|
|
|
|
* then the CI input of the muxcy is selected and the truth of this
|
|
|
|
|
* level depends on lower order bits. The least significan muxcy is
|
|
|
|
|
* connected to GND and VCC so that its CO follows the least
|
|
|
|
|
* significant LUT.
|
|
|
|
|
*
|
|
|
|
|
* Identity != is the same as == except that the output is
|
|
|
|
|
* inverted. To get that effect without putting an inverter on the
|
|
|
|
|
* output of the top muxcy pin CO (which would cost a LUT) the DI
|
|
|
|
|
* inputs are all connected to VCC instead of GND, and the CI of the
|
|
|
|
|
* least significant muxcy is connected to GND instead of VCC.
|
|
|
|
|
*/
|
2001-09-10 00:23:28 +02:00
|
|
|
static void edif_show_virtex_eq(ivl_lpm_t net)
|
|
|
|
|
{
|
2001-09-15 07:06:04 +02:00
|
|
|
/* True if I'm implementing CMP_EQ instead of CMP_NE */
|
|
|
|
|
int eq = 1;
|
2001-09-10 00:23:28 +02:00
|
|
|
assert(ivl_lpm_width(net) >= 1);
|
|
|
|
|
|
2001-09-15 07:06:04 +02:00
|
|
|
if (ivl_lpm_type(net) == IVL_LPM_CMP_NE)
|
|
|
|
|
eq = 0;
|
|
|
|
|
|
2001-09-10 00:23:28 +02:00
|
|
|
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),
|
2001-09-15 07:06:04 +02:00
|
|
|
ivl_lpm_datab(net, 0), eq? "9" : "6");
|
2001-09-10 00:23:28 +02:00
|
|
|
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),
|
2001-09-15 07:06:04 +02:00
|
|
|
eq? "9009" : "6FF6");
|
2001-09-10 00:23:28 +02:00
|
|
|
break;
|
|
|
|
|
|
2001-09-11 07:52:31 +02:00
|
|
|
default: {
|
2001-09-10 05:48:34 +02:00
|
|
|
char jbuf[1024];
|
2001-09-11 07:52:31 +02:00
|
|
|
unsigned idx;
|
|
|
|
|
unsigned pairs = ivl_lpm_width(net) / 2;
|
|
|
|
|
unsigned tail = ivl_lpm_width(net) % 2;
|
|
|
|
|
|
2001-09-15 07:06:04 +02:00
|
|
|
|
2001-09-11 07:52:31 +02:00
|
|
|
if (tail == 0) {
|
|
|
|
|
tail = 2;
|
|
|
|
|
pairs -= 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance U%uL0"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (viewRef net"
|
2001-09-11 07:52:31 +02:00
|
|
|
" (cellRef LUT4 (libraryRef VIRTEX)))"
|
|
|
|
|
" (property INIT (string \"9009\")))\n",
|
|
|
|
|
edif_uref);
|
|
|
|
|
fprintf(xnf, "(instance U%uM0"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (viewRef net"
|
2001-09-11 07:52:31 +02:00
|
|
|
" (cellRef MUXCY_L (libraryRef VIRTEX))))\n",
|
|
|
|
|
edif_uref);
|
|
|
|
|
fprintf(xnf, "(instance U%uG0"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (viewRef net"
|
2001-09-11 07:52:31 +02:00
|
|
|
" (cellRef GND (libraryRef VIRTEX))))\n",
|
|
|
|
|
edif_uref);
|
2001-09-15 07:06:04 +02:00
|
|
|
|
2001-09-11 07:52:31 +02:00
|
|
|
fprintf(xnf, "(instance U%uV0"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (viewRef net"
|
2001-09-11 07:52:31 +02:00
|
|
|
" (cellRef VCC (libraryRef VIRTEX))))\n",
|
2001-09-10 05:48:34 +02:00
|
|
|
edif_uref);
|
|
|
|
|
|
2001-09-15 07:06:04 +02:00
|
|
|
if (eq) {
|
|
|
|
|
fprintf(xnf, "(net U%uVM0 (joined"
|
|
|
|
|
" (portRef VCC (instanceRef U%uV0))"
|
|
|
|
|
" (portRef CI (instanceRef U%uM0))))\n",
|
|
|
|
|
edif_uref, edif_uref, edif_uref);
|
|
|
|
|
fprintf(xnf, "(net U%uGM0 (joined"
|
|
|
|
|
" (portRef GROUND (instanceRef U%uG0))"
|
|
|
|
|
" (portRef DI (instanceRef U%uM0))))\n",
|
|
|
|
|
edif_uref, edif_uref, edif_uref);
|
|
|
|
|
} else {
|
|
|
|
|
fprintf(xnf, "(net U%uVM0 (joined"
|
|
|
|
|
" (portRef VCC (instanceRef U%uV0))"
|
|
|
|
|
" (portRef DI (instanceRef U%uM0))))\n",
|
|
|
|
|
edif_uref, edif_uref, edif_uref);
|
|
|
|
|
fprintf(xnf, "(net U%uGM0 (joined"
|
|
|
|
|
" (portRef GROUND (instanceRef U%uG0))"
|
|
|
|
|
" (portRef CI (instanceRef U%uM0))))\n",
|
|
|
|
|
edif_uref, edif_uref, edif_uref);
|
|
|
|
|
}
|
|
|
|
|
|
2001-09-11 07:52:31 +02:00
|
|
|
fprintf(xnf, "(net U%uLM0 (joined"
|
|
|
|
|
" (portRef O (instanceRef U%uL0))"
|
|
|
|
|
" (portRef S (instanceRef U%uM0))))\n",
|
2001-09-10 05:48:34 +02:00
|
|
|
edif_uref, edif_uref, edif_uref);
|
|
|
|
|
|
2001-09-11 07:52:31 +02:00
|
|
|
sprintf(jbuf, "(portRef I0 (instanceRef U%uL0))", edif_uref);
|
2001-09-10 05:48:34 +02:00
|
|
|
edif_set_nexus_joint(ivl_lpm_data(net, 0), jbuf);
|
|
|
|
|
|
2001-09-11 07:52:31 +02:00
|
|
|
sprintf(jbuf, "(portRef I1 (instanceRef U%uL0))", edif_uref);
|
2001-09-10 05:48:34 +02:00
|
|
|
edif_set_nexus_joint(ivl_lpm_datab(net, 0), jbuf);
|
|
|
|
|
|
2001-09-11 07:52:31 +02:00
|
|
|
sprintf(jbuf, "(portRef I2 (instanceRef U%uL0))", edif_uref);
|
2001-09-10 05:48:34 +02:00
|
|
|
edif_set_nexus_joint(ivl_lpm_data(net, 1), jbuf);
|
|
|
|
|
|
2001-09-11 07:52:31 +02:00
|
|
|
sprintf(jbuf, "(portRef I3 (instanceRef U%uL0))", edif_uref);
|
2001-09-10 05:48:34 +02:00
|
|
|
edif_set_nexus_joint(ivl_lpm_datab(net, 1), jbuf);
|
|
|
|
|
|
|
|
|
|
|
2001-09-11 07:52:31 +02:00
|
|
|
for (idx = 1 ; idx < pairs ; idx += 1) {
|
|
|
|
|
fprintf(xnf, "(instance U%uL%u"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (viewRef net"
|
2001-09-11 07:52:31 +02:00
|
|
|
" (cellRef LUT4 (libraryRef VIRTEX)))"
|
|
|
|
|
" (property INIT (string \"9009\")))\n",
|
|
|
|
|
edif_uref, idx);
|
|
|
|
|
fprintf(xnf, "(instance U%uM%u"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (viewRef net"
|
2001-09-11 07:52:31 +02:00
|
|
|
" (cellRef MUXCY_L (libraryRef VIRTEX))))\n",
|
|
|
|
|
edif_uref, idx);
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(net U%uVM%u (joined"
|
|
|
|
|
" (portRef LO (instanceRef U%uM%u))"
|
|
|
|
|
" (portRef CI (instanceRef U%uM%u))))\n",
|
|
|
|
|
edif_uref, idx, edif_uref, idx-1,
|
|
|
|
|
edif_uref, idx);
|
2001-09-15 07:06:04 +02:00
|
|
|
if (eq) {
|
|
|
|
|
fprintf(xnf, "(instance U%uG%u"
|
|
|
|
|
" (viewRef net"
|
|
|
|
|
" (cellRef GND (libraryRef VIRTEX))))\n",
|
|
|
|
|
edif_uref, idx);
|
|
|
|
|
fprintf(xnf, "(net U%uGM%u (joined"
|
|
|
|
|
" (portRef GROUND (instanceRef U%uG%u))"
|
|
|
|
|
" (portRef DI (instanceRef U%uM%u))))\n",
|
|
|
|
|
edif_uref, idx, edif_uref, idx,
|
|
|
|
|
edif_uref, idx);
|
|
|
|
|
} else {
|
|
|
|
|
fprintf(xnf, "(instance U%uG%u"
|
|
|
|
|
" (viewRef net"
|
|
|
|
|
" (cellRef VCC (libraryRef VIRTEX))))\n",
|
|
|
|
|
edif_uref, idx);
|
|
|
|
|
fprintf(xnf, "(net U%uGM%u (joined"
|
|
|
|
|
" (portRef VCC (instanceRef U%uG%u))"
|
|
|
|
|
" (portRef DI (instanceRef U%uM%u))))\n",
|
|
|
|
|
edif_uref, idx, edif_uref, idx,
|
|
|
|
|
edif_uref, idx);
|
|
|
|
|
}
|
2001-09-11 07:52:31 +02:00
|
|
|
fprintf(xnf, "(net U%uLM%u (joined"
|
|
|
|
|
" (portRef O (instanceRef U%uL%u))"
|
|
|
|
|
" (portRef S (instanceRef U%uM%u))))\n",
|
|
|
|
|
edif_uref, idx, edif_uref, idx,
|
|
|
|
|
edif_uref, idx);
|
|
|
|
|
|
|
|
|
|
sprintf(jbuf, "(portRef I0 (instanceRef U%uL%u))",
|
|
|
|
|
edif_uref, idx);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_data(net, idx*2), jbuf);
|
|
|
|
|
|
|
|
|
|
sprintf(jbuf, "(portRef I1 (instanceRef U%uL%u))",
|
|
|
|
|
edif_uref, idx);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_datab(net, idx*2), jbuf);
|
|
|
|
|
|
|
|
|
|
sprintf(jbuf, "(portRef I2 (instanceRef U%uL%u))",
|
|
|
|
|
edif_uref, idx);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_data(net, idx*2+1), jbuf);
|
|
|
|
|
|
|
|
|
|
sprintf(jbuf, "(portRef I3 (instanceRef U%uL%u))",
|
|
|
|
|
edif_uref, idx);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_datab(net, idx*2+1), jbuf);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tail == 2) {
|
|
|
|
|
fprintf(xnf, "(instance U%uL%u"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (viewRef net"
|
2001-09-11 07:52:31 +02:00
|
|
|
" (cellRef LUT4 (libraryRef VIRTEX)))"
|
|
|
|
|
" (property INIT (string \"9009\")))\n",
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
fprintf(xnf, "(instance (rename U%uM%u \"%s\")"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (viewRef net"
|
2001-09-11 07:52:31 +02:00
|
|
|
" (cellRef MUXCY (libraryRef VIRTEX))))\n",
|
|
|
|
|
edif_uref, pairs, ivl_lpm_name(net));
|
2001-09-15 07:06:04 +02:00
|
|
|
|
|
|
|
|
if (eq) {
|
|
|
|
|
fprintf(xnf, "(instance U%uG%u"
|
|
|
|
|
" (viewRef net"
|
|
|
|
|
" (cellRef GND (libraryRef VIRTEX))))\n",
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
fprintf(xnf, "(net U%uGM%u (joined"
|
|
|
|
|
" (portRef GROUND (instanceRef U%uG%u))"
|
|
|
|
|
" (portRef DI (instanceRef U%uM%u))))\n",
|
|
|
|
|
edif_uref, pairs, edif_uref, pairs,
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
} else {
|
|
|
|
|
fprintf(xnf, "(instance U%uG%u"
|
|
|
|
|
" (viewRef net"
|
|
|
|
|
" (cellRef VCC (libraryRef VIRTEX))))\n",
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
fprintf(xnf, "(net U%uGM%u (joined"
|
|
|
|
|
" (portRef VCC (instanceRef U%uG%u))"
|
|
|
|
|
" (portRef DI (instanceRef U%uM%u))))\n",
|
|
|
|
|
edif_uref, pairs, edif_uref, pairs,
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
}
|
2001-09-11 07:52:31 +02:00
|
|
|
|
|
|
|
|
fprintf(xnf, "(net U%uVM%u (joined"
|
|
|
|
|
" (portRef LO (instanceRef U%uM%u))"
|
|
|
|
|
" (portRef CI (instanceRef U%uM%u))))\n",
|
|
|
|
|
edif_uref, pairs, edif_uref, pairs-1,
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
fprintf(xnf, "(net U%uLM%u (joined"
|
|
|
|
|
" (portRef O (instanceRef U%uL%u))"
|
|
|
|
|
" (portRef S (instanceRef U%uM%u))))\n",
|
|
|
|
|
edif_uref, pairs, edif_uref, pairs,
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
|
|
|
|
|
sprintf(jbuf, "(portRef I0 (instanceRef U%uL%u))",
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_data(net, pairs*2), jbuf);
|
|
|
|
|
|
|
|
|
|
sprintf(jbuf, "(portRef I1 (instanceRef U%uL%u))",
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_datab(net, pairs*2), jbuf);
|
|
|
|
|
|
|
|
|
|
sprintf(jbuf, "(portRef I2 (instanceRef U%uL%u))",
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_data(net, pairs*2+1), jbuf);
|
|
|
|
|
|
|
|
|
|
sprintf(jbuf, "(portRef I3 (instanceRef U%uL%u))",
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_datab(net, pairs*2+1), jbuf);
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
assert(tail == 1);
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance (rename U%uL%u \"%s\")"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (viewRef net"
|
2001-09-11 07:52:31 +02:00
|
|
|
" (cellRef LUT2 (libraryRef VIRTEX)))"
|
|
|
|
|
" (property INIT (string \"9\")))\n",
|
|
|
|
|
edif_uref, pairs, ivl_lpm_name(net));
|
|
|
|
|
fprintf(xnf, "(instance U%uM%u"
|
2001-09-15 07:06:04 +02:00
|
|
|
" (viewRef net"
|
2001-09-11 07:52:31 +02:00
|
|
|
" (cellRef MUXCY (libraryRef VIRTEX))))\n",
|
|
|
|
|
edif_uref, pairs);
|
2001-09-15 07:06:04 +02:00
|
|
|
|
|
|
|
|
if (eq) {
|
|
|
|
|
fprintf(xnf, "(instance U%uG%u"
|
|
|
|
|
" (viewRef net"
|
|
|
|
|
" (cellRef GND (libraryRef VIRTEX))))\n",
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
fprintf(xnf, "(net U%uGM%u (joined"
|
|
|
|
|
" (portRef GROUND (instanceRef U%uG%u))"
|
|
|
|
|
" (portRef DI (instanceRef U%uM%u))))\n",
|
|
|
|
|
edif_uref, pairs, edif_uref, pairs,
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
} else {
|
|
|
|
|
fprintf(xnf, "(instance U%uG%u"
|
|
|
|
|
" (viewRef net"
|
|
|
|
|
" (cellRef VCC (libraryRef VIRTEX))))\n",
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
fprintf(xnf, "(net U%uGM%u (joined"
|
|
|
|
|
" (portRef VCC (instanceRef U%uG%u))"
|
|
|
|
|
" (portRef DI (instanceRef U%uM%u))))\n",
|
|
|
|
|
edif_uref, pairs, edif_uref, pairs,
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
}
|
2001-09-11 07:52:31 +02:00
|
|
|
|
|
|
|
|
fprintf(xnf, "(net U%uVM%u (joined"
|
|
|
|
|
" (portRef LO (instanceRef U%uM%u))"
|
|
|
|
|
" (portRef CI (instanceRef U%uM%u))))\n",
|
|
|
|
|
edif_uref, pairs, edif_uref, pairs-1,
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
fprintf(xnf, "(net U%uLM%u (joined"
|
|
|
|
|
" (portRef O (instanceRef U%uL%u))"
|
|
|
|
|
" (portRef S (instanceRef U%uM%u))))\n",
|
|
|
|
|
edif_uref, pairs, edif_uref, pairs,
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
|
|
|
|
|
sprintf(jbuf, "(portRef I0 (instanceRef U%uL%u))",
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_data(net, pairs*2), jbuf);
|
|
|
|
|
|
|
|
|
|
sprintf(jbuf, "(portRef I1 (instanceRef U%uL%u))",
|
|
|
|
|
edif_uref, pairs);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_datab(net, pairs*2), jbuf);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2001-09-12 06:35:25 +02:00
|
|
|
sprintf(jbuf, "(portRef O (instanceRef U%uM%u))",
|
2001-09-11 07:52:31 +02:00
|
|
|
edif_uref, pairs);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_q(net, 0), jbuf);
|
2001-09-10 05:48:34 +02:00
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-09-06 06:28:39 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-09-10 00:23:28 +02:00
|
|
|
/*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2002-09-14 07:19:19 +02:00
|
|
|
static void edif_show_virtex_muxs1(ivl_lpm_t net)
|
2001-09-10 00:23:28 +02:00
|
|
|
{
|
|
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-14 07:19:19 +02:00
|
|
|
/*
|
|
|
|
|
* This supports the general mux with two select inputs. This is a 4:1
|
|
|
|
|
* mux. Use two LUT3 devices and a MUXF5 to form each bit slice of the
|
|
|
|
|
* full mux. By using a MUXF5, we pretty much confine the bit slice to
|
|
|
|
|
* a Virtex CLB slice.
|
|
|
|
|
*/
|
|
|
|
|
static void edif_show_virtex_muxs2(ivl_lpm_t net)
|
|
|
|
|
{
|
|
|
|
|
unsigned idx;
|
|
|
|
|
|
|
|
|
|
assert(ivl_lpm_width(net) >= 1);
|
|
|
|
|
assert(ivl_lpm_selects(net) == 2);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance U%uA"
|
|
|
|
|
" (viewRef net"
|
|
|
|
|
" (cellRef LUT3 (libraryRef VIRTEX)))"
|
|
|
|
|
" (property INIT (string \"CA\")))\n", edif_uref);
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance U%uB"
|
|
|
|
|
" (viewRef net"
|
|
|
|
|
" (cellRef LUT3 (libraryRef VIRTEX)))"
|
|
|
|
|
" (property INIT (string \"CA\")))\n", edif_uref);
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance (rename U%uF \"%s\")"
|
|
|
|
|
" (viewRef net"
|
2002-09-15 23:52:19 +02:00
|
|
|
" (cellRef MUXF5 (libraryRef VIRTEX))))\n",
|
2002-09-14 07:19:19 +02:00
|
|
|
edif_uref, tmp_name);
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(net U%uAF (joined"
|
|
|
|
|
" (portRef O (instanceRef U%uA))"
|
|
|
|
|
" (portRef I0 (instanceRef U%uF))))\n",
|
|
|
|
|
edif_uref, edif_uref, edif_uref);
|
|
|
|
|
fprintf(xnf, "(net U%uBF (joined"
|
|
|
|
|
" (portRef O (instanceRef U%uB))"
|
|
|
|
|
" (portRef I1 (instanceRef U%uF))))\n",
|
|
|
|
|
edif_uref, edif_uref, edif_uref);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I0 (instanceRef U%uA))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_data2(net, 0, idx), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I1 (instanceRef U%uA))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_data2(net, 1, idx), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I0 (instanceRef U%uB))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_data2(net, 2, idx), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I1 (instanceRef U%uB))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_data2(net, 3, idx), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I2 (instanceRef U%uA))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_select(net, 0), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I2 (instanceRef U%uB))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_select(net, 0), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef S (instanceRef U%uF))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_select(net, 1), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef O (instanceRef U%uF))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_q(net, idx), tmp_name);
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-09-15 23:52:19 +02:00
|
|
|
static void edif_show_virtex_muxs3(ivl_lpm_t net)
|
|
|
|
|
{
|
|
|
|
|
unsigned idx;
|
|
|
|
|
|
|
|
|
|
assert(ivl_lpm_width(net) >= 1);
|
|
|
|
|
assert(ivl_lpm_selects(net) == 3);
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance U%uAA"
|
|
|
|
|
" (viewRef net"
|
|
|
|
|
" (cellRef LUT3 (libraryRef VIRTEX)))"
|
|
|
|
|
" (property INIT (string \"CA\")))\n", edif_uref);
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance U%uBA"
|
|
|
|
|
" (viewRef net"
|
|
|
|
|
" (cellRef LUT3 (libraryRef VIRTEX)))"
|
|
|
|
|
" (property INIT (string \"CA\")))\n", edif_uref);
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance U%uFA"
|
|
|
|
|
" (viewRef net"
|
|
|
|
|
" (cellRef MUXF5 (libraryRef VIRTEX))))\n",
|
|
|
|
|
edif_uref);
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(net U%uAFA (joined"
|
|
|
|
|
" (portRef O (instanceRef U%uAA))"
|
|
|
|
|
" (portRef I0 (instanceRef U%uFA))))\n",
|
|
|
|
|
edif_uref, edif_uref, edif_uref);
|
|
|
|
|
fprintf(xnf, "(net U%uBFA (joined"
|
|
|
|
|
" (portRef O (instanceRef U%uBA))"
|
|
|
|
|
" (portRef I1 (instanceRef U%uFA))))\n",
|
|
|
|
|
edif_uref, edif_uref, edif_uref);
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance U%uAB"
|
|
|
|
|
" (viewRef net"
|
|
|
|
|
" (cellRef LUT3 (libraryRef VIRTEX)))"
|
|
|
|
|
" (property INIT (string \"CA\")))\n", edif_uref);
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance U%uBB"
|
|
|
|
|
" (viewRef net"
|
|
|
|
|
" (cellRef LUT3 (libraryRef VIRTEX)))"
|
|
|
|
|
" (property INIT (string \"CA\")))\n", edif_uref);
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance U%uFB"
|
|
|
|
|
" (viewRef net"
|
|
|
|
|
" (cellRef MUXF5 (libraryRef VIRTEX))))\n",
|
|
|
|
|
edif_uref);
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(net U%uAFB (joined"
|
|
|
|
|
" (portRef O (instanceRef U%uAB))"
|
|
|
|
|
" (portRef I0 (instanceRef U%uFB))))\n",
|
|
|
|
|
edif_uref, edif_uref, edif_uref);
|
|
|
|
|
fprintf(xnf, "(net U%uBFB (joined"
|
|
|
|
|
" (portRef O (instanceRef U%uBB))"
|
|
|
|
|
" (portRef I1 (instanceRef U%uFB))))\n",
|
|
|
|
|
edif_uref, edif_uref, edif_uref);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Connect the two MUXF5 devices to the MUXF6. */
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance (rename U%uF \"%s\")"
|
|
|
|
|
" (viewRef net"
|
|
|
|
|
" (cellRef MUXF6 (libraryRef VIRTEX))))\n",
|
|
|
|
|
edif_uref, tmp_name);
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(net U%uFA (joined"
|
|
|
|
|
" (portRef O (instanceRef U%uFA))"
|
|
|
|
|
" (portRef I0 (instanceRef U%uF))))\n",
|
|
|
|
|
edif_uref, edif_uref, edif_uref);
|
|
|
|
|
fprintf(xnf, "(net U%uFB (joined"
|
|
|
|
|
" (portRef O (instanceRef U%uFB))"
|
|
|
|
|
" (portRef I1 (instanceRef U%uF))))\n",
|
|
|
|
|
edif_uref, edif_uref, edif_uref);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I0 (instanceRef U%uAA))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_data2(net, 0, idx), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I1 (instanceRef U%uAA))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_data2(net, 1, idx), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I0 (instanceRef U%uBA))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_data2(net, 2, idx), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I1 (instanceRef U%uBA))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_data2(net, 3, idx), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I0 (instanceRef U%uAB))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_data2(net, 4, idx), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I1 (instanceRef U%uAB))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_data2(net, 5, idx), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I0 (instanceRef U%uBB))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_data2(net, 6, idx), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I1 (instanceRef U%uBB))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_data2(net, 7, idx), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I2 (instanceRef U%uAA))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_select(net, 0), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I2 (instanceRef U%uBA))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_select(net, 0), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I2 (instanceRef U%uAB))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_select(net, 0), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef I2 (instanceRef U%uBB))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_select(net, 0), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef S (instanceRef U%uFA))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_select(net, 1), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef S (instanceRef U%uFB))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_select(net, 1), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef S (instanceRef U%uF))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_select(net, 2), tmp_name);
|
|
|
|
|
|
|
|
|
|
sprintf(tmp_name, "(portRef O (instanceRef U%uF))", edif_uref);
|
|
|
|
|
edif_set_nexus_joint(ivl_lpm_q(net, idx), tmp_name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-14 07:19:19 +02:00
|
|
|
|
|
|
|
|
static void edif_show_virtex_mux(ivl_lpm_t net)
|
|
|
|
|
{
|
|
|
|
|
switch (ivl_lpm_selects(net)) {
|
|
|
|
|
case 1:
|
|
|
|
|
edif_show_virtex_muxs1(net);
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
edif_show_virtex_muxs2(net);
|
|
|
|
|
break;
|
2002-09-15 23:52:19 +02:00
|
|
|
case 3:
|
|
|
|
|
edif_show_virtex_muxs3(net);
|
|
|
|
|
break;
|
2002-09-14 07:19:19 +02:00
|
|
|
default:
|
|
|
|
|
assert(0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-09-10 00:23:28 +02:00
|
|
|
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));
|
2001-09-15 07:06:04 +02:00
|
|
|
fprintf(xnf, " (viewRef net"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (cellRef LUT2 (libraryRef VIRTEX))))\n");
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance U%u_M0", edif_uref);
|
2001-09-15 07:06:04 +02:00
|
|
|
fprintf(xnf, " (viewRef net"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (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);
|
2001-09-15 07:06:04 +02:00
|
|
|
fprintf(xnf, " (viewRef net"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (cellRef LUT2 (libraryRef VIRTEX))))\n");
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance U%u_M%u", edif_uref, idx);
|
2001-09-15 07:06:04 +02:00
|
|
|
fprintf(xnf, " (viewRef net"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (cellRef MUXCY_L (libraryRef VIRTEX))))\n");
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance (rename U%u_X%u \"%s[%u]\")",
|
|
|
|
|
edif_uref, idx, ivl_lpm_name(net), idx);
|
2001-09-15 07:06:04 +02:00
|
|
|
fprintf(xnf, " (viewRef net"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (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);
|
2001-09-15 07:06:04 +02:00
|
|
|
fprintf(xnf, " (viewRef net"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (cellRef LUT2 (libraryRef VIRTEX))))\n");
|
|
|
|
|
|
|
|
|
|
fprintf(xnf, "(instance (rename U%u_X%u \"%s[%u]\")",
|
|
|
|
|
edif_uref, idx, ivl_lpm_name(net), idx);
|
2001-09-15 07:06:04 +02:00
|
|
|
fprintf(xnf, " (viewRef net"
|
2001-09-10 00:23:28 +02:00
|
|
|
" (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);
|
|
|
|
|
}
|
2001-09-06 06:28:39 +02:00
|
|
|
|
|
|
|
|
const struct device_s d_virtex_edif = {
|
|
|
|
|
edif_show_header,
|
|
|
|
|
edif_show_footer,
|
2001-09-16 03:48:16 +02:00
|
|
|
edif_show_virtex_pad,
|
2001-09-10 00:23:28 +02:00
|
|
|
edif_show_virtex_logic,
|
2001-09-06 06:28:39 +02:00
|
|
|
edif_show_generic_dff,
|
2001-09-10 00:23:28 +02:00
|
|
|
edif_show_virtex_eq,
|
2001-09-15 07:06:04 +02:00
|
|
|
edif_show_virtex_eq,
|
2001-09-10 00:23:28 +02:00
|
|
|
edif_show_virtex_mux,
|
|
|
|
|
edif_show_virtex_add
|
2001-09-06 06:28:39 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* $Log: d-virtex.c,v $
|
2002-09-15 23:52:19 +02:00
|
|
|
* Revision 1.15 2002/09/15 21:52:19 steve
|
|
|
|
|
* Generate code for 8:1 muxes msing F5 and F6 muxes.
|
|
|
|
|
*
|
2002-09-14 07:19:19 +02:00
|
|
|
* Revision 1.14 2002/09/14 05:19:19 steve
|
|
|
|
|
* Generate Virtex code for 4:1 mux slices.
|
|
|
|
|
*
|
2002-08-12 03:34:58 +02:00
|
|
|
* Revision 1.13 2002/08/12 01:35:02 steve
|
|
|
|
|
* conditional ident string using autoconfig.
|
|
|
|
|
*
|
2002-08-12 01:47:04 +02:00
|
|
|
* Revision 1.12 2002/08/11 23:47:04 steve
|
|
|
|
|
* Add missing Log and Ident strings.
|
|
|
|
|
*
|
2001-10-11 02:12:28 +02:00
|
|
|
* Revision 1.11 2001/10/11 00:12:28 steve
|
|
|
|
|
* Generate BUF devices for bufz logic.
|
|
|
|
|
*
|
2001-09-17 00:26:47 +02:00
|
|
|
* Revision 1.10 2001/09/16 22:26:47 steve
|
|
|
|
|
* Support the cellref attribute.
|
|
|
|
|
*
|
2001-09-16 03:48:16 +02:00
|
|
|
* Revision 1.9 2001/09/16 01:48:16 steve
|
|
|
|
|
* Suppor the PAD attribute on signals.
|
|
|
|
|
*
|
2001-09-15 20:27:04 +02:00
|
|
|
* Revision 1.8 2001/09/15 18:27:04 steve
|
|
|
|
|
* Make configure detect malloc.h
|
|
|
|
|
*
|
2001-09-15 07:06:04 +02:00
|
|
|
* Revision 1.7 2001/09/15 05:06:04 steve
|
|
|
|
|
* Support != in virtex code generator.
|
|
|
|
|
*
|
2001-09-14 06:17:20 +02:00
|
|
|
* Revision 1.6 2001/09/14 04:17:20 steve
|
|
|
|
|
* Add XOR and XNOR gates.
|
|
|
|
|
*
|
2001-09-12 06:35:25 +02:00
|
|
|
* Revision 1.5 2001/09/12 04:35:25 steve
|
|
|
|
|
* Xilinx uses GROUND and VCC as pin names for the
|
|
|
|
|
* GND and VCC devices.
|
|
|
|
|
*
|
|
|
|
|
* Connect the top end of the EQ chain to the MUXCY
|
|
|
|
|
* instead of to the LUT. The MUXCY has the real output.
|
|
|
|
|
*
|
2001-09-11 07:52:31 +02:00
|
|
|
* Revision 1.4 2001/09/11 05:52:31 steve
|
|
|
|
|
* Use carry mux to implement wide identity compare,
|
|
|
|
|
* Place property item in correct place in LUT cell list.
|
|
|
|
|
*
|
2001-09-10 05:48:34 +02:00
|
|
|
* Revision 1.3 2001/09/10 03:48:34 steve
|
|
|
|
|
* Add 4 wide identity compare.
|
|
|
|
|
*
|
2001-09-10 00:23:28 +02:00
|
|
|
* 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.
|
|
|
|
|
*
|
2001-09-06 06:28:39 +02:00
|
|
|
* Revision 1.1 2001/09/06 04:28:40 steve
|
|
|
|
|
* Separate the virtex and generic-edif code generators.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|