Adding DPGEN_SHROT to support both shifts and rotations.

Layout is quite larger when rotation is involved, so use only when
necessary.
This commit is contained in:
Frederic Petrot 2002-06-17 09:40:27 +00:00
parent 0614cb6005
commit 4c3c211ea5
3 changed files with 217 additions and 39 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: dgn.h,v 1.1 2002/04/29 13:40:54 jpc Exp $ * $Id: dgn.h,v 1.2 2002/06/17 09:40:27 fred Exp $
* *
* /----------------------------------------------------------------\ * /----------------------------------------------------------------\
* | | * | |
@ -97,7 +97,8 @@
# define DPGEN_SFFT 40 # define DPGEN_SFFT 40
# define DPGEN_ROM2 41 # define DPGEN_ROM2 41
# define DPGEN_ROM4 42 # define DPGEN_ROM4 42
# define DPGEN_UNKNOWN 43 # define DPGEN_SHROT 43
# define DPGEN_UNKNOWN 44
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -1,5 +1,5 @@
/* /*
* $Id: dpgen_Macro.c,v 1.1 2002/04/29 13:40:54 jpc Exp $ * $Id: dpgen_Macro.c,v 1.2 2002/06/17 09:40:27 fred Exp $
* *
* /----------------------------------------------------------------\ * /----------------------------------------------------------------\
* | | * | |
@ -138,6 +138,9 @@ extern void GENLIB_MACRO __FPV((long aFunction, ...))
case DPGEN_SHIFT: case DPGEN_SHIFT:
dpgen_Shifter (aFunction, aAL); dpgen_Shifter (aFunction, aAL);
break; break;
case DPGEN_SHROT:
dpgen_Shifter (aFunction, aAL);
break;
case DPGEN_NUL: case DPGEN_NUL:
dpgen_Nul (aFunction, aAL); dpgen_Nul (aFunction, aAL);
break; break;

View File

@ -25,6 +25,11 @@
Author: Frédéric Pétrot Author: Frédéric Pétrot
Date : 1/10/2000 Date : 1/10/2000
$Log: dpgen_Shifter.c,v $ $Log: dpgen_Shifter.c,v $
Revision 1.5 2002/06/17 09:40:27 fred
Adding DPGEN_SHROT to support both shifts and rotations.
Layout is quite larger when rotation is involved, so use only when
necessary.
Revision 1.4 2002/06/14 15:40:29 fred Revision 1.4 2002/06/14 15:40:29 fred
Adding rotation. Adding rotation.
Some test this week end and that should be it. Some test this week end and that should be it.
@ -91,7 +96,7 @@
*/ */
static char rcsid[]="$Id: dpgen_Shifter.c,v 1.4 2002/06/14 15:40:29 fred Exp $"; static char rcsid[]="$Id: dpgen_Shifter.c,v 1.5 2002/06/17 09:40:27 fred Exp $";
#include "util_Defs.h" #include "util_Defs.h"
@ -140,6 +145,8 @@ namegen(op)
namegen(x) namegen(x)
/* Behavior: /* Behavior:
Shift: Shifter
Shrot: Includes also rotation
o = (i op shamt); o = (i op shamt);
@ -164,16 +171,14 @@ extern void dpgen_Shifter(aFunction, aAL)
int ops; int ops;
char *LSB, *MSB; char *LSB, *MSB;
char *MuxInput0, *MuxInput1, *MuxInput2; /* Mux inputs */ char *MuxInput0, *MuxInput1, *MuxInput2; /* Mux inputs */
char *Cell;
int sym, mys; int sym, mys;
modelName = va_arg (aAL, char*); modelName = va_arg (aAL, char*);
/* 0: Shifter
1: Includes also rotation */
flags = va_arg (aAL, long ); flags = va_arg (aAL, long );
flags = 0;
n = (int)va_arg (aAL, long ); n = (int)va_arg (aAL, long );
Slices = ln2p(n - 1); Slices = ln2p(n);
#define XX_NAME GENLIB_NAME #define XX_NAME GENLIB_NAME
@ -181,17 +186,14 @@ extern void dpgen_Shifter(aFunction, aAL)
#define MX3(c0, c1, i0, i1, i2, q) \ #define MX3(c0, c1, i0, i1, i2, q) \
GENLIB_LOINS("mx3_x2", XX_NAME("m_%d", SliceIndex * n + BitIndex), c0, c1, i0, i1, i2, q, "vdd", "vss", NULL) GENLIB_LOINS("mx3_x2", XX_NAME("m_%d", SliceIndex * n + BitIndex), c0, c1, i0, i1, i2, q, "vdd", "vss", NULL)
#define MX2(k, c0, i0, i1, q) \
GENLIB_LOINS("mx2_x2", XX_NAME("c_%d", 2 * SliceIndex + k), c0, i0, i1, q, "vdd", "vss", NULL)
#define A2(k, i0, i1, q) \ #define A2(k, i0, i1, q) \
GENLIB_LOINS("a2_x2", XX_NAME("a_%d", k), i0, i1, q, "vdd", "vss", NULL) GENLIB_LOINS("a2_x2", XX_NAME("a_%d", k), i0, i1, q, "vdd", "vss", NULL)
#define A3(k, i0, i1, i2, q) \ #define A3(k, i0, i1, i2, q) \
GENLIB_LOINS("a3_x2", XX_NAME("a3_%d", k), i0, i1, i2, q, "vdd", "vss", NULL) GENLIB_LOINS("a3_x2", XX_NAME("a3_%d", k), i0, i1, i2, q, "vdd", "vss", NULL)
#define OA(k, i0, i1, i2, q) \ #define OA(i0, i1, i2, q) \
GENLIB_LOINS("oa22_x4", XX_NAME("oa_%d", k), i0, i1, i2, q, "vdd", "vss", NULL) GENLIB_LOINS("oa22_x4", XX_NAME("oa_%d", SliceIndex * n + BitIndex), i0, i1, i2, q, "vdd", "vss", NULL)
#define O2(k, i0, i1, q) \ #define O2(k, i0, i1, q) \
GENLIB_LOINS("o2_x2", XX_NAME("o_%d", k), i0, i1, q, "vdd", "vss", NULL) GENLIB_LOINS("o2_x2", XX_NAME("o_%d", k), i0, i1, q, "vdd", "vss", NULL)
@ -199,7 +201,9 @@ extern void dpgen_Shifter(aFunction, aAL)
#define INV(k, i, nq) \ #define INV(k, i, nq) \
GENLIB_LOINS("inv_x2", XX_NAME("i_%d", k), i, nq, "vdd", "vss", NULL) GENLIB_LOINS("inv_x2", XX_NAME("i_%d", k), i, nq, "vdd", "vss", NULL)
if (flags == 0) #define SYM (BitIndex & 1 ? mys : sym)
if (aFunction == DPGEN_SHIFT)
ops = 1; ops = 1;
else else
ops = 2; ops = 2;
@ -218,11 +222,11 @@ extern void dpgen_Shifter(aFunction, aAL)
MSB = "msb"; /* intermediate signal for arith sh */ MSB = "msb"; /* intermediate signal for arith sh */
/* Arithmetic or input extension */ /* Arithmetic or input extension */
if (flags == 1) { if (aFunction == DPGEN_SHROT) {
INV(123, op(2), "op2b"); INV(Slices, op(2), "op2b");
A3(123, i(n - 1), "op2b", op(1), MSB); A3(Slices, i(n - 1), "op2b", op(1), MSB);
} else { } else {
A2(123, i(n - 1), op(1), MSB); A2(0, i(n - 1), op(1), MSB);
} }
/* Normalizing the input signals names */ /* Normalizing the input signals names */
@ -234,9 +238,7 @@ extern void dpgen_Shifter(aFunction, aAL)
for (BitIndex = 0; BitIndex < n; BitIndex++) { for (BitIndex = 0; BitIndex < n; BitIndex++) {
LeftIndex = BitIndex - (1 << SliceIndex); LeftIndex = BitIndex - (1 << SliceIndex);
RightIndex = BitIndex + (1 << SliceIndex); RightIndex = BitIndex + (1 << SliceIndex);
printf("Slice: %d, Bit: %d, Li: %d, Ri: %d\n", SliceIndex, if (aFunction == DPGEN_SHIFT) {
BitIndex, LeftIndex, RightIndex);
if (flags == 0) {
MuxInput0 = LeftIndex >= 0 ? MuxOutput(SliceIndex * n + LeftIndex) : LSB; MuxInput0 = LeftIndex >= 0 ? MuxOutput(SliceIndex * n + LeftIndex) : LSB;
MuxInput1 = MuxOutput(SliceIndex * n + BitIndex); MuxInput1 = MuxOutput(SliceIndex * n + BitIndex);
MuxInput2 = RightIndex < n ? MuxOutput(SliceIndex * n + RightIndex) : MSB; MuxInput2 = RightIndex < n ? MuxOutput(SliceIndex * n + RightIndex) : MSB;
@ -245,15 +247,14 @@ extern void dpgen_Shifter(aFunction, aAL)
MuxInput0 = MuxOutput(SliceIndex * n + LeftIndex); MuxInput0 = MuxOutput(SliceIndex * n + LeftIndex);
else { else {
MuxInput0 = x(AndIndex); MuxInput0 = x(AndIndex);
A2(AndIndex, op(2), MuxOutput(SliceIndex * n + n + LeftIndex), x(AndIndex)); AndIndex++; A2(SliceIndex * n + BitIndex, op(2), MuxOutput(SliceIndex * n + n + LeftIndex), x(AndIndex)); AndIndex++;
} }
MuxInput1 = MuxOutput(SliceIndex * n + BitIndex); MuxInput1 = MuxOutput(SliceIndex * n + BitIndex);
if (RightIndex < n) if (RightIndex < n)
MuxInput2 = MuxOutput(SliceIndex * n + RightIndex); MuxInput2 = MuxOutput(SliceIndex * n + RightIndex);
else { else {
MuxInput2 = x(AndIndex); MuxInput2 = x(AndIndex);
//A2(AndIndex, op(2), MuxOutput(SliceIndex * n + RightIndex - n), x(AndIndex)); AndIndex++; OA(op(2), MuxOutput(SliceIndex * n + RightIndex - n), MSB, x(AndIndex)); AndIndex++;
OA(AndIndex, op(2), MuxOutput(SliceIndex * n + RightIndex - n), MSB, x(AndIndex)); AndIndex++;
} }
} }
MX3(c0(SliceIndex), c1(SliceIndex), MuxInput0, MuxInput1, MuxInput2, MuxOutput((SliceIndex + 1) * n + BitIndex)); MX3(c0(SliceIndex), c1(SliceIndex), MuxInput0, MuxInput1, MuxInput2, MuxOutput((SliceIndex + 1) * n + BitIndex));
@ -279,26 +280,199 @@ extern void dpgen_Shifter(aFunction, aAL)
sym = NOSYM, mys = SYM_Y; sym = NOSYM, mys = SYM_Y;
GENLIB_DEF_PHSC(modelName); GENLIB_DEF_PHSC(modelName);
GENLIB_SC_PLACE(XX_NAME("a_%d", 0), sym, 0, 0);
for (SliceIndex = 0; SliceIndex < Slices; SliceIndex++) {
GENLIB_SC_RIGHT(XX_NAME("i_%d", SliceIndex), sym);
GENLIB_SC_RIGHT(XX_NAME("o_%d", SliceIndex), sym);
}
GENLIB_DEF_PHINS("a_0");
BitIndex = n - 1; BitIndex = n - 1;
for (SliceIndex = 0; SliceIndex < Slices; SliceIndex++) { SliceIndex = 0;
if (SliceIndex == 0) if (aFunction == DPGEN_SHROT) {
GENLIB_SC_BOTTOM(XX_NAME("m_%d", SliceIndex * n + BitIndex), mys); GENLIB_SC_PLACE(XX_NAME("oa_%d", SliceIndex * n + BitIndex), SYM, 0, 0);
else GENLIB_SC_RIGHT(XX_NAME("m_%d", SliceIndex * n + BitIndex), SYM);
GENLIB_SC_RIGHT(XX_NAME("m_%d", SliceIndex * n + BitIndex), mys); } else
GENLIB_SC_PLACE(XX_NAME("m_%d", SliceIndex * n + BitIndex), SYM, 0, 0);
for (SliceIndex = 1; SliceIndex < Slices; SliceIndex++) {
if (aFunction == DPGEN_SHROT) {
GENLIB_SC_RIGHT(XX_NAME("oa_%d", SliceIndex * n + BitIndex), SYM);
}
GENLIB_SC_RIGHT(XX_NAME("m_%d", SliceIndex * n + BitIndex), SYM);
} }
for (SliceIndex = 0; SliceIndex < Slices; SliceIndex++) { for (SliceIndex = 0; SliceIndex < Slices; SliceIndex++) {
GENLIB_DEF_PHINS(XX_NAME("m_%d", SliceIndex * n + n-1)); if (aFunction == DPGEN_SHROT) {
GENLIB_DEF_PHINS(XX_NAME("oa_%d", SliceIndex * n + n - 1));
for (BitIndex = n-1; BitIndex >= 0; BitIndex--) {
int l = 0, r = 0;
LeftIndex = BitIndex - (1 << SliceIndex);
RightIndex = BitIndex + (1 << SliceIndex);
if (RightIndex >= n) {
if (BitIndex != n - 1)
GENLIB_SC_BOTTOM(XX_NAME("oa_%d", SliceIndex * n + BitIndex), SYM);
r = 1;
}
if (LeftIndex < 0) {
if (r == 1) {
GENLIB_SC_RIGHT(Cell = XX_NAME("a_%d", SliceIndex * n + BitIndex), SYM);
GENLIB_DEF_PHINS(XX_NAME("oa_%d", SliceIndex * n + BitIndex));
} else
GENLIB_SC_BOTTOM(XX_NAME("a_%d", SliceIndex * n + BitIndex), SYM);
l = 1;
}
if (l == 0 && r == 0)
GENLIB_PLACE_BOTTOM("tie_x0", XX_NAME("tie_%d", SliceIndex * n + BitIndex), SYM);
}
}
GENLIB_DEF_PHINS(XX_NAME("m_%d", SliceIndex * n + n - 1));
for (BitIndex = n-2; BitIndex >= 0; BitIndex--) { for (BitIndex = n-2; BitIndex >= 0; BitIndex--) {
GENLIB_SC_BOTTOM(XX_NAME("m_%d", SliceIndex * n + BitIndex), GENLIB_SC_BOTTOM(XX_NAME("m_%d", SliceIndex * n + BitIndex), SYM);
BitIndex & 1 ? mys : sym);
} }
} }
GENLIB_SAVE_PHSC();
if (flags & F_PLACE) {
BitIndex = n; /* Upper line, this is necessary for the computation of the symmetry */
SliceIndex = 0;
if (aFunction == DPGEN_SHROT) {
GENLIB_DEF_PHINS(XX_NAME("oa_%d", SliceIndex * n + n - 1));
GENLIB_SC_TOP(XX_NAME("i_%d", Slices), SYM);
GENLIB_SC_RIGHT(XX_NAME("a3_%d", Slices), SYM);
} else {
GENLIB_DEF_PHINS(XX_NAME("m_%d", SliceIndex * n + n - 1));
GENLIB_SC_TOP(XX_NAME("a_%d", 0), SYM);
}
for (SliceIndex = 0; SliceIndex < Slices; SliceIndex++) {
if (SliceIndex > 0)
if (aFunction == DPGEN_SHROT)
GENLIB_DEF_PHINS(XX_NAME("oa_%d", SliceIndex * n + n - 1));
else
GENLIB_DEF_PHINS(XX_NAME("m_%d", SliceIndex * n + n - 1));
if (SliceIndex == 0)
GENLIB_SC_RIGHT(XX_NAME("i_%d", SliceIndex), SYM);
else
GENLIB_SC_TOP(XX_NAME("i_%d", SliceIndex), SYM);
GENLIB_SC_RIGHT(XX_NAME("o_%d", SliceIndex), SYM);
}
/* I've done my best with genlib, but I need to realign overlapping
* cells using some more powerfull tools, ... */
{
phins_list *i, *f = getphins(WORK_PHFIG, Cell);
phfig_list *p = getphfig(f->FIGNAME, 'P');
for (i = WORK_PHFIG->PHINS; i; i = i->NEXT)
if (i->XINS == f->XINS)
if (!strncmp(i->INSNAME, "m_", 2))
i->XINS += p->XAB2 - p->XAB1;
}
GENLIB_SAVE_PHSC();
}
if (flags & F_BEHAV) {
printf("Shifter behavior no yet implemented\n");
}
freestr(); freestr();
} }
#ifdef DEBUG_DPGEN_SHIFT
char *d2b(char *s, int x, int n)
{
int i;
for (i = 0; i < n; i++)
s[i] = '0' + ((x >> (n - 1 - i)) & 1);
s[i] = 0;
return s;
}
int ln2p(int n)
{
int i = 0, j = n & 1;
if (n)
for (i = -1; n > 0; n >>= 1) {
j += (n & 1);
i++;
}
return i + (j > 1);
}
int main(int argc, char *argv[])
{
int a, b, sh, op, i, n, l, r;
int mask;
char s[33], t[33], u[33], v[33];
if (argc != 3)
exit(1);
if (!strcmp(argv[1], "-s"))
r = 1;
else if (!strcmp(argv[1], "-r"))
r = 2;
else
exit(1);
n = atoi(argv[2]);
if (n == 0)
exit(1);
if (n < 32)
mask = ~(~0<<n); /* This bugs when n = 32! Why ? */
else
mask = 0xffffffff;
l = ln2p(n);
printf("in op(%d downto 0);;\n", r);
printf("in shamt(%d downto 0);;\n", l - 1);
printf("in i(%d to 0);;\n", n - 1);
printf("out o(%d to 0);;\n", n - 1);
printf("in vdd;;\n");
printf("in vss;\n");
printf("begin\n");
for (i = 0; i < 10000; i++) {
a = random() & mask;
sh = random() & ~(~0<<l);
/* No tests for out of bound shift */
if (sh > n - 1)
sh = n - 1;
op = random() & ~(~0<<r);
switch (op) {
case 0:
case 2:
printf("# sll ");
b = (a << sh) & mask;
break;
case 1:
printf("# srl ");
b = (((unsigned int)a) >> sh) & mask;
break;
case 3:
printf("# sra ");
if (((1<<(n-1)) & a & mask) == (1<<(n-1)))
b = ((a >> sh) | (~0<<(n-sh))) & mask;
else
b = (a >> sh) & mask;
break;
case 4:
case 6:
printf("# rol ");
b = ((a << sh) | (a >> (n - sh))) & mask;
break;
case 5:
case 7:
printf("# ror ");
b = ((a >> sh) | (a << (n - sh))) & mask;
}
a &= mask;
printf("\npat%04d: %s %s %s ?%s 1 0;\n", i,
d2b(u, op, r + 1),
d2b(v, sh, l),
d2b(s, a, n),
d2b(t, b, n));
}
printf("end;\n");
exit(0);
}
#endif