Virtex and Virtex2 share much code.
This commit is contained in:
parent
f7162eb538
commit
0e797dc7bc
|
|
@ -16,7 +16,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.9 2003/04/05 05:53:34 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.10 2003/06/25 02:55:57 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -53,7 +53,7 @@ dep:
|
|||
mv $*.d dep
|
||||
|
||||
D = d-generic.o d-generic-edif.o d-virtex.o d-virtex2.o
|
||||
O = edif.o fpga.o gates.o mangle.o tables.o xilinx.o $D
|
||||
O = edif.o fpga.o gates.o mangle.o tables.o generic.o xilinx.o $D
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
TGTLDFLAGS=-L.. -livl
|
||||
|
|
|
|||
2348
tgt-fpga/d-virtex.c
2348
tgt-fpga/d-virtex.c
File diff suppressed because it is too large
Load Diff
1045
tgt-fpga/d-virtex2.c
1045
tgt-fpga/d-virtex2.c
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2003 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
|
||||
*/
|
||||
#ifndef HAVE_CVS_IDENT
|
||||
#ident "$Id: generic.c,v 1.1 2003/06/25 02:55:57 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "generic.h"
|
||||
|
||||
edif_t edf = 0;
|
||||
edif_xlibrary_t xlib = 0;
|
||||
|
||||
edif_cell_t cell_0 = 0;
|
||||
edif_cell_t cell_1 = 0;
|
||||
|
||||
edif_cell_t cell_ipad = 0;
|
||||
edif_cell_t cell_opad = 0;
|
||||
|
||||
|
||||
/*
|
||||
* $Log: generic.c,v $
|
||||
* Revision 1.1 2003/06/25 02:55:57 steve
|
||||
* Virtex and Virtex2 share much code.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef __generic_H
|
||||
#define __generic_H
|
||||
/*
|
||||
* Copyright (c) 2003 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
|
||||
*/
|
||||
#ifndef HAVE_CVS_IDENT
|
||||
#ident "$Id: generic.h,v 1.1 2003/06/25 02:55:57 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "edif.h"
|
||||
|
||||
extern edif_t edf;
|
||||
extern edif_xlibrary_t xlib;
|
||||
|
||||
/*
|
||||
* The cell_* variables below are the various kinds of devices that
|
||||
* this family supports as primitives. If the cell type is used at
|
||||
* least once, then the edif_cell_t is non-zero and will also be
|
||||
* included in the library declaration. The constants underneath are
|
||||
* pin assignments for the cell.
|
||||
*/
|
||||
|
||||
extern edif_cell_t cell_0;
|
||||
extern edif_cell_t cell_1;
|
||||
|
||||
extern edif_cell_t cell_ipad;
|
||||
extern edif_cell_t cell_opad;
|
||||
|
||||
|
||||
/*
|
||||
* $Log: generic.h,v $
|
||||
* Revision 1.1 2003/06/25 02:55:57 steve
|
||||
* Virtex and Virtex2 share much code.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
|
@ -17,10 +17,18 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: xilinx.c,v 1.1 2003/04/05 05:53:34 steve Exp $"
|
||||
#ident "$Id: xilinx.c,v 1.2 2003/06/25 02:55:57 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "edif.h"
|
||||
# include "generic.h"
|
||||
# include "xilinx.h"
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
# include <assert.h>
|
||||
|
||||
edif_cell_t xilinx_cell_buf(edif_xlibrary_t xlib)
|
||||
{
|
||||
|
|
@ -198,10 +206,485 @@ edif_cell_t xilinx_cell_xorcy(edif_xlibrary_t xlib)
|
|||
return cell;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make (or retrieve) a cell in the external library that reflects the
|
||||
* scope with its ports.
|
||||
*/
|
||||
void xilinx_show_scope(ivl_scope_t scope)
|
||||
{
|
||||
edif_cell_t cell;
|
||||
edif_cellref_t ref;
|
||||
|
||||
unsigned port, idx;
|
||||
|
||||
cell = edif_xlibrary_scope_cell(xlib, scope);
|
||||
ref = edif_cellref_create(edf, cell);
|
||||
|
||||
for (idx = 0 ; idx < ivl_scope_sigs(scope) ; idx += 1) {
|
||||
edif_joint_t jnt;
|
||||
ivl_signal_t sig = ivl_scope_sig(scope, idx);
|
||||
|
||||
if (ivl_signal_port(sig) == IVL_SIP_NONE)
|
||||
continue;
|
||||
|
||||
port = edif_cell_port_byname(cell, ivl_signal_basename(sig));
|
||||
jnt = edif_joint_of_nexus(edf, ivl_signal_pin(sig, 0));
|
||||
edif_add_to_joint(jnt, ref, port);
|
||||
}
|
||||
}
|
||||
|
||||
void xilinx_pad(ivl_signal_t sig, const char*str)
|
||||
{
|
||||
unsigned idx;
|
||||
unsigned*pins;
|
||||
|
||||
if (cell_ipad == 0) {
|
||||
cell_ipad = edif_xcell_create(xlib, "IPAD", 1);
|
||||
edif_cell_portconfig(cell_ipad, 0, "IPAD", IVL_SIP_OUTPUT);
|
||||
}
|
||||
|
||||
if (cell_opad == 0) {
|
||||
cell_opad = edif_xcell_create(xlib, "OPAD", 1);
|
||||
edif_cell_portconfig(cell_opad, 0, "OPAD", IVL_SIP_OUTPUT);
|
||||
}
|
||||
|
||||
/* Collect an array of pin assignments from the attribute
|
||||
string passed in as str. The format is a comma separated
|
||||
list of unsigned decimal integers. */
|
||||
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;
|
||||
}
|
||||
|
||||
/* Now go through the pins of the signal, creating pads and
|
||||
bufs and joining them to the signal nexus. */
|
||||
for (idx = 0 ; idx < ivl_signal_pins(sig) ; idx += 1) {
|
||||
edif_joint_t jnt;
|
||||
edif_cellref_t pad, buf;
|
||||
|
||||
const char*name_str = ivl_signal_basename(sig);
|
||||
if (ivl_signal_pins(sig) > 1) {
|
||||
char name_buf[128];
|
||||
sprintf(name_buf, "%s[%u]", name_str, idx);
|
||||
name_str = strdup(name_buf);
|
||||
}
|
||||
|
||||
switch (ivl_signal_port(sig)) {
|
||||
case IVL_SIP_INPUT:
|
||||
pad = edif_cellref_create(edf, cell_ipad);
|
||||
buf = edif_cellref_create(edf, xilinx_cell_ibuf(xlib));
|
||||
|
||||
jnt = edif_joint_create(edf);
|
||||
edif_joint_rename(jnt, name_str);
|
||||
edif_add_to_joint(jnt, pad, 0);
|
||||
edif_add_to_joint(jnt, buf, BUF_I);
|
||||
|
||||
jnt = edif_joint_of_nexus(edf, ivl_signal_pin(sig, idx));
|
||||
edif_add_to_joint(jnt, buf, BUF_O);
|
||||
break;
|
||||
|
||||
case IVL_SIP_OUTPUT:
|
||||
pad = edif_cellref_create(edf, cell_opad);
|
||||
buf = edif_cellref_create(edf, xilinx_cell_obuf(xlib));
|
||||
|
||||
jnt = edif_joint_create(edf);
|
||||
edif_joint_rename(jnt, name_str);
|
||||
edif_add_to_joint(jnt, pad, 0);
|
||||
edif_add_to_joint(jnt, buf, BUF_O);
|
||||
|
||||
jnt = edif_joint_of_nexus(edf, ivl_signal_pin(sig, idx));
|
||||
edif_add_to_joint(jnt, buf, BUF_I);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
free(pins);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function handles the case where the user specifies the cell to
|
||||
* use by attribute.
|
||||
*/
|
||||
static void edif_cellref_logic(ivl_net_logic_t net, const char*def)
|
||||
{
|
||||
char*str = strdup(def);
|
||||
char*pins;
|
||||
edif_cell_t cell;
|
||||
edif_cellref_t ref;
|
||||
edif_joint_t jnt;
|
||||
unsigned idx, port;
|
||||
|
||||
pins = strchr(str, ':');
|
||||
assert(pins);
|
||||
*pins++ = 0;
|
||||
|
||||
/* Locate the cell in the library, lookup by name. */
|
||||
cell = edif_xlibrary_findcell(xlib, str);
|
||||
assert(cell);
|
||||
|
||||
ref = edif_cellref_create(edf, cell);
|
||||
|
||||
for (idx = 0 ; idx < ivl_logic_pins(net) ; idx += 1) {
|
||||
char*tmp;
|
||||
|
||||
assert(pins);
|
||||
tmp = strchr(pins,',');
|
||||
if (tmp != 0)
|
||||
*tmp++ = 0;
|
||||
else
|
||||
tmp = 0;
|
||||
|
||||
port = edif_cell_port_byname(cell, pins);
|
||||
jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx));
|
||||
edif_add_to_joint(jnt, ref, port);
|
||||
|
||||
pins = tmp;
|
||||
}
|
||||
|
||||
free(str);
|
||||
}
|
||||
|
||||
static void lut_logic(ivl_net_logic_t net, const char*init3,
|
||||
const char*init4, const char*init5)
|
||||
{
|
||||
edif_cellref_t lut;
|
||||
edif_joint_t jnt;
|
||||
const char* init;
|
||||
|
||||
assert(ivl_logic_pins(net) <= 5);
|
||||
assert(ivl_logic_pins(net) >= 3);
|
||||
|
||||
switch (ivl_logic_pins(net)) {
|
||||
case 3:
|
||||
lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
|
||||
init = init3;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
lut = edif_cellref_create(edf, xilinx_cell_lut3(xlib));
|
||||
init = init4;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
lut = edif_cellref_create(edf, xilinx_cell_lut4(xlib));
|
||||
init = init5;
|
||||
break;
|
||||
}
|
||||
|
||||
edif_cellref_pstring(lut, "INIT", init);
|
||||
|
||||
switch (ivl_logic_pins(net)) {
|
||||
case 5:
|
||||
jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 4));
|
||||
edif_add_to_joint(jnt, lut, LUT_I3);
|
||||
case 4:
|
||||
jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 3));
|
||||
edif_add_to_joint(jnt, lut, LUT_I2);
|
||||
case 3:
|
||||
jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 2));
|
||||
edif_add_to_joint(jnt, lut, LUT_I1);
|
||||
}
|
||||
|
||||
jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1));
|
||||
edif_add_to_joint(jnt, lut, LUT_I0);
|
||||
|
||||
jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0));
|
||||
edif_add_to_joint(jnt, lut, LUT_O);
|
||||
}
|
||||
|
||||
|
||||
void xilinx_logic(ivl_net_logic_t net)
|
||||
{
|
||||
edif_cellref_t obj;
|
||||
edif_joint_t jnt;
|
||||
|
||||
{ const char*cellref_attribute = ivl_logic_attr(net, "cellref");
|
||||
if (cellref_attribute != 0) {
|
||||
edif_cellref_logic(net, cellref_attribute);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ivl_logic_type(net)) {
|
||||
|
||||
case IVL_LO_BUF:
|
||||
case IVL_LO_BUFZ:
|
||||
assert(ivl_logic_pins(net) == 2);
|
||||
|
||||
obj = edif_cellref_create(edf, xilinx_cell_buf(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);
|
||||
break;
|
||||
|
||||
case IVL_LO_NOT:
|
||||
assert(ivl_logic_pins(net) == 2);
|
||||
|
||||
obj = edif_cellref_create(edf, xilinx_cell_inv(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);
|
||||
break;
|
||||
|
||||
case IVL_LO_AND:
|
||||
assert(ivl_logic_pins(net) <= 5);
|
||||
assert(ivl_logic_pins(net) >= 3);
|
||||
lut_logic(net, "8", "80", "8000");
|
||||
break;
|
||||
|
||||
case IVL_LO_NOR:
|
||||
assert(ivl_logic_pins(net) <= 5);
|
||||
assert(ivl_logic_pins(net) >= 3);
|
||||
lut_logic(net, "1", "01", "0001");
|
||||
break;
|
||||
|
||||
case IVL_LO_OR:
|
||||
assert(ivl_logic_pins(net) <= 5);
|
||||
assert(ivl_logic_pins(net) >= 3);
|
||||
lut_logic(net, "E", "FE", "FFFE");
|
||||
break;
|
||||
|
||||
case IVL_LO_XNOR:
|
||||
assert(ivl_logic_pins(net) <= 5);
|
||||
assert(ivl_logic_pins(net) >= 3);
|
||||
lut_logic(net, "9", "69", "9669");
|
||||
break;
|
||||
|
||||
case IVL_LO_XOR:
|
||||
assert(ivl_logic_pins(net) <= 5);
|
||||
assert(ivl_logic_pins(net) >= 3);
|
||||
lut_logic(net, "6", "96", "6996");
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "UNSUPPORTED LOGIC TYPE: %u\n",
|
||||
ivl_logic_type(net));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Any Xilinx device works with this adder.
|
||||
* Generic Xilinx add only works for single bit slices.
|
||||
*/
|
||||
void xilinx_add(ivl_lpm_t net)
|
||||
{
|
||||
const char*ha_init = 0;
|
||||
edif_cellref_t lut;
|
||||
edif_joint_t jnt;
|
||||
|
||||
switch (ivl_lpm_type(net)) {
|
||||
case IVL_LPM_ADD:
|
||||
ha_init = "6";
|
||||
break;
|
||||
case IVL_LPM_SUB:
|
||||
ha_init = "9";
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* If this is a single bit wide, then generate only a
|
||||
half-adder. Normally this is an XOR, but if this is a SUB
|
||||
then it is an XNOR. */
|
||||
if (ivl_lpm_width(net) == 1) {
|
||||
|
||||
lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib));
|
||||
|
||||
jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0));
|
||||
edif_add_to_joint(jnt, lut, LUT_O);
|
||||
|
||||
jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0));
|
||||
edif_add_to_joint(jnt, lut, LUT_I0);
|
||||
|
||||
jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0));
|
||||
edif_add_to_joint(jnt, lut, LUT_I1);
|
||||
|
||||
edif_cellref_pstring(lut, "INIT", ha_init);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* The left shift is implemented as a matrix of MUX2_1 devices. The
|
||||
* matrix has as many rows as the device width, and a column for each
|
||||
* select.
|
||||
*/
|
||||
void xilinx_shiftl(ivl_lpm_t net)
|
||||
{
|
||||
unsigned width = ivl_lpm_width(net);
|
||||
unsigned nsel = 0, swid = 0;
|
||||
unsigned sdx, qdx;
|
||||
|
||||
edif_cellref_t* cells;
|
||||
edif_cellref_t**table;
|
||||
|
||||
edif_cellref_t pad0_cell;
|
||||
edif_joint_t pad0;
|
||||
|
||||
|
||||
/* First, find out how many select inputs we really need. We
|
||||
can only use the selects that are enough to shift out the
|
||||
entire width of the device. The excess can be used as an
|
||||
enable for the last column. When disabled, the last column
|
||||
emits zeros. */
|
||||
|
||||
while (nsel < ivl_lpm_selects(net)) {
|
||||
|
||||
nsel += 1;
|
||||
|
||||
swid = 1 << nsel;
|
||||
if (swid >= width)
|
||||
break;
|
||||
}
|
||||
|
||||
assert(nsel > 0);
|
||||
|
||||
/* Allocate a matrix of edif_cellref_t variables. A devices
|
||||
will be addressed by the expression table[sdx][qdx];
|
||||
This should make the algorighm code easier to read. */
|
||||
cells = calloc(nsel * width, sizeof(edif_cellref_t));
|
||||
table = calloc(nsel, sizeof(edif_cellref_t*));
|
||||
|
||||
for (sdx = 0 ; sdx < nsel ; sdx += 1)
|
||||
table[sdx] = cells + sdx*width;
|
||||
|
||||
/* Make a 0 valued pad bit. I wlil use this for all the shifin
|
||||
values that are beyond the input. */
|
||||
pad0_cell = edif_cellref_create(edf, cell_0);
|
||||
pad0 = edif_joint_create(edf);
|
||||
edif_add_to_joint(pad0, pad0_cell, 0);
|
||||
|
||||
/* The LUT matrix is <nsel> columns of <width> devices, with
|
||||
the last column a LUT4 devices. The extra input of the
|
||||
LUT4s in the last column are used as an enable to collect
|
||||
all the excess select inputs. */
|
||||
|
||||
/* Allocate the LUT devices of the matrix, and connect the
|
||||
select inputs to I2 of all the devices of the column. */
|
||||
for (sdx = 0 ; sdx < nsel ; sdx += 1) {
|
||||
const char*init_string = 0;
|
||||
ivl_nexus_t nex = ivl_lpm_select(net,sdx);
|
||||
edif_joint_t sdx_jnt = edif_joint_of_nexus(edf, nex);
|
||||
|
||||
edif_cell_t lut;
|
||||
|
||||
if (((sdx+1) == nsel) && (nsel < ivl_lpm_selects(net))) {
|
||||
lut = xilinx_cell_lut4(xlib);
|
||||
init_string = "00CA";
|
||||
} else {
|
||||
lut = xilinx_cell_lut3(xlib);
|
||||
init_string = "CA";
|
||||
}
|
||||
|
||||
for (qdx = 0 ; qdx < width ; qdx += 1) {
|
||||
table[sdx][qdx] = edif_cellref_create(edf, lut);
|
||||
edif_add_to_joint(sdx_jnt, table[sdx][qdx], LUT_I2);
|
||||
|
||||
edif_cellref_pstring(table[sdx][qdx], "INIT", init_string);
|
||||
}
|
||||
}
|
||||
|
||||
/* Connect the inputs of the SHIFTL device to the column 0 LUT
|
||||
inputs. The slice on the low end shifts in a 0 for a select
|
||||
input. */
|
||||
for (qdx = 0 ; qdx < width ; qdx += 1) {
|
||||
ivl_nexus_t nex0, nex1;
|
||||
edif_joint_t jnt0;
|
||||
edif_joint_t jnt1;
|
||||
|
||||
nex0 = ivl_lpm_data(net,qdx);
|
||||
jnt0 = edif_joint_of_nexus(edf, nex0);
|
||||
|
||||
if (qdx > 0) {
|
||||
nex1 = ivl_lpm_data(net,qdx-1);
|
||||
jnt1 = edif_joint_of_nexus(edf, nex1);
|
||||
} else {
|
||||
jnt1 = pad0;
|
||||
}
|
||||
|
||||
edif_add_to_joint(jnt0, table[0][qdx], LUT_I0);
|
||||
edif_add_to_joint(jnt1, table[0][qdx], LUT_I1);
|
||||
}
|
||||
|
||||
/* Make the inner connections between LUT devices. Each column
|
||||
connects to the previous column, shifted by the power of
|
||||
the column value. If the shifted input falls off the end,
|
||||
then pad with zero. */
|
||||
for (sdx = 1 ; sdx < nsel ; sdx += 1) {
|
||||
|
||||
for (qdx = 0 ; qdx < width ; qdx += 1) {
|
||||
unsigned shift = 1 << sdx;
|
||||
edif_joint_t jnt0 = edif_joint_create(edf);
|
||||
edif_joint_t jnt1 = (qdx >= shift)
|
||||
? edif_joint_create(edf)
|
||||
: pad0;
|
||||
|
||||
edif_add_to_joint(jnt0, table[sdx][qdx], LUT_I0);
|
||||
edif_add_to_joint(jnt1, table[sdx][qdx], LUT_I1);
|
||||
|
||||
edif_add_to_joint(jnt0, table[sdx-1][qdx], LUT_O);
|
||||
if (qdx >= shift)
|
||||
edif_add_to_joint(jnt1, table[sdx-1][qdx-shift], LUT_O);
|
||||
}
|
||||
}
|
||||
|
||||
/* Connect the output of the last column to the output of the
|
||||
SHIFTL device. */
|
||||
for (qdx = 0 ; qdx < width ; qdx += 1) {
|
||||
ivl_nexus_t nex = ivl_lpm_q(net,qdx);
|
||||
edif_joint_t jnt = edif_joint_of_nexus(edf, nex);
|
||||
|
||||
edif_add_to_joint(jnt, table[nsel-1][qdx], LUT_O);
|
||||
}
|
||||
|
||||
/* Connect the excess select inputs to the enable inputs of
|
||||
the LUT4 devices in the last column. */
|
||||
if (nsel < ivl_lpm_selects(net)) {
|
||||
edif_joint_t jnt;
|
||||
|
||||
/* XXXX Only support 1 excess bit for now. */
|
||||
assert((nsel + 1) == ivl_lpm_selects(net));
|
||||
|
||||
jnt = edif_joint_of_nexus(edf, ivl_lpm_select(net,nsel));
|
||||
for (qdx = 0 ; qdx < width ; qdx += 1)
|
||||
edif_add_to_joint(jnt, table[nsel-1][qdx], LUT_I3);
|
||||
}
|
||||
|
||||
free(cells);
|
||||
free(table);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: xilinx.c,v $
|
||||
* Revision 1.2 2003/06/25 02:55:57 steve
|
||||
* Virtex and Virtex2 share much code.
|
||||
*
|
||||
* Revision 1.1 2003/04/05 05:53:34 steve
|
||||
* Move library cell management to common file.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.1 2003/04/05 05:53:34 steve Exp $"
|
||||
#ident "$Id: xilinx.h,v 1.2 2003/06/25 02:55:57 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -93,8 +93,25 @@ extern edif_cell_t xilinx_cell_xorcy(edif_xlibrary_t xlib);
|
|||
#define XORCY_CI 1
|
||||
#define XORCY_LI 2
|
||||
|
||||
/* === Inheritable Methods === */
|
||||
|
||||
extern void virtex_show_footer(ivl_design_t des);
|
||||
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);
|
||||
extern void virtex_add(ivl_lpm_t net);
|
||||
|
||||
extern void xilinx_show_scope(ivl_scope_t scope);
|
||||
extern void xilinx_pad(ivl_signal_t, const char*str);
|
||||
extern void xilinx_logic(ivl_net_logic_t net);
|
||||
extern void xilinx_add(ivl_lpm_t net);
|
||||
extern void xilinx_shiftl(ivl_lpm_t net);
|
||||
|
||||
/*
|
||||
* $Log: xilinx.h,v $
|
||||
* Revision 1.2 2003/06/25 02:55:57 steve
|
||||
* Virtex and Virtex2 share much code.
|
||||
*
|
||||
* Revision 1.1 2003/04/05 05:53:34 steve
|
||||
* Move library cell management to common file.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue