From 4c3c211ea528f458bc3ceb69bbf892e08f1fbc98 Mon Sep 17 00:00:00 2001 From: Frederic Petrot Date: Mon, 17 Jun 2002 09:40:27 +0000 Subject: [PATCH] Adding DPGEN_SHROT to support both shifts and rotations. Layout is quite larger when rotation is involved, so use only when necessary. --- alliance/src/genlib/src/dgn.h | 5 +- alliance/src/genlib/src/dpgen_Macro.c | 5 +- alliance/src/genlib/src/dpgen_Shifter.c | 246 ++++++++++++++++++++---- 3 files changed, 217 insertions(+), 39 deletions(-) diff --git a/alliance/src/genlib/src/dgn.h b/alliance/src/genlib/src/dgn.h index 49763c20..4adbe624 100644 --- a/alliance/src/genlib/src/dgn.h +++ b/alliance/src/genlib/src/dgn.h @@ -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_ROM2 41 # define DPGEN_ROM4 42 -# define DPGEN_UNKNOWN 43 +# define DPGEN_SHROT 43 +# define DPGEN_UNKNOWN 44 /* ---------------------------------------------------------------------- diff --git a/alliance/src/genlib/src/dpgen_Macro.c b/alliance/src/genlib/src/dpgen_Macro.c index 41607587..41f7f807 100644 --- a/alliance/src/genlib/src/dpgen_Macro.c +++ b/alliance/src/genlib/src/dpgen_Macro.c @@ -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: dpgen_Shifter (aFunction, aAL); break; + case DPGEN_SHROT: + dpgen_Shifter (aFunction, aAL); + break; case DPGEN_NUL: dpgen_Nul (aFunction, aAL); break; diff --git a/alliance/src/genlib/src/dpgen_Shifter.c b/alliance/src/genlib/src/dpgen_Shifter.c index 4657e6fa..85e4720d 100644 --- a/alliance/src/genlib/src/dpgen_Shifter.c +++ b/alliance/src/genlib/src/dpgen_Shifter.c @@ -25,6 +25,11 @@ Author: Frédéric Pétrot Date : 1/10/2000 $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 Adding rotation. 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" @@ -140,6 +145,8 @@ namegen(op) namegen(x) /* Behavior: + Shift: Shifter + Shrot: Includes also rotation o = (i op shamt); @@ -164,16 +171,14 @@ extern void dpgen_Shifter(aFunction, aAL) int ops; char *LSB, *MSB; char *MuxInput0, *MuxInput1, *MuxInput2; /* Mux inputs */ + char *Cell; int sym, mys; modelName = va_arg (aAL, char*); - /* 0: Shifter - 1: Includes also rotation */ flags = va_arg (aAL, long ); - flags = 0; n = (int)va_arg (aAL, long ); - Slices = ln2p(n - 1); + Slices = ln2p(n); #define XX_NAME GENLIB_NAME @@ -181,17 +186,14 @@ extern void dpgen_Shifter(aFunction, aAL) #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) -#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) \ GENLIB_LOINS("a2_x2", XX_NAME("a_%d", k), i0, i1, q, "vdd", "vss", NULL) #define A3(k, i0, i1, i2, q) \ GENLIB_LOINS("a3_x2", XX_NAME("a3_%d", k), i0, i1, i2, q, "vdd", "vss", NULL) -#define OA(k, i0, i1, i2, q) \ - GENLIB_LOINS("oa22_x4", XX_NAME("oa_%d", k), i0, i1, i2, q, "vdd", "vss", NULL) +#define OA(i0, i1, i2, q) \ + GENLIB_LOINS("oa22_x4", XX_NAME("oa_%d", SliceIndex * n + BitIndex), i0, i1, i2, q, "vdd", "vss", NULL) #define O2(k, i0, i1, q) \ 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) \ 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; else ops = 2; @@ -218,11 +222,11 @@ extern void dpgen_Shifter(aFunction, aAL) MSB = "msb"; /* intermediate signal for arith sh */ /* Arithmetic or input extension */ - if (flags == 1) { - INV(123, op(2), "op2b"); - A3(123, i(n - 1), "op2b", op(1), MSB); + if (aFunction == DPGEN_SHROT) { + INV(Slices, op(2), "op2b"); + A3(Slices, i(n - 1), "op2b", op(1), MSB); } else { - A2(123, i(n - 1), op(1), MSB); + A2(0, i(n - 1), op(1), MSB); } /* Normalizing the input signals names */ @@ -234,9 +238,7 @@ extern void dpgen_Shifter(aFunction, aAL) for (BitIndex = 0; BitIndex < n; BitIndex++) { LeftIndex = BitIndex - (1 << SliceIndex); RightIndex = BitIndex + (1 << SliceIndex); - printf("Slice: %d, Bit: %d, Li: %d, Ri: %d\n", SliceIndex, - BitIndex, LeftIndex, RightIndex); - if (flags == 0) { + if (aFunction == DPGEN_SHIFT) { MuxInput0 = LeftIndex >= 0 ? MuxOutput(SliceIndex * n + LeftIndex) : LSB; MuxInput1 = MuxOutput(SliceIndex * n + BitIndex); MuxInput2 = RightIndex < n ? MuxOutput(SliceIndex * n + RightIndex) : MSB; @@ -245,15 +247,14 @@ extern void dpgen_Shifter(aFunction, aAL) MuxInput0 = MuxOutput(SliceIndex * n + LeftIndex); else { 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); if (RightIndex < n) MuxInput2 = MuxOutput(SliceIndex * n + RightIndex); else { MuxInput2 = x(AndIndex); - //A2(AndIndex, op(2), MuxOutput(SliceIndex * n + RightIndex - n), x(AndIndex)); AndIndex++; - OA(AndIndex, op(2), MuxOutput(SliceIndex * n + RightIndex - n), MSB, x(AndIndex)); AndIndex++; + OA(op(2), MuxOutput(SliceIndex * n + RightIndex - n), MSB, x(AndIndex)); AndIndex++; } } 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; 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; - for (SliceIndex = 0; SliceIndex < Slices; SliceIndex++) { - if (SliceIndex == 0) - GENLIB_SC_BOTTOM(XX_NAME("m_%d", SliceIndex * n + BitIndex), mys); - else - GENLIB_SC_RIGHT(XX_NAME("m_%d", SliceIndex * n + BitIndex), mys); + SliceIndex = 0; + if (aFunction == DPGEN_SHROT) { + GENLIB_SC_PLACE(XX_NAME("oa_%d", SliceIndex * n + BitIndex), SYM, 0, 0); + GENLIB_SC_RIGHT(XX_NAME("m_%d", SliceIndex * n + BitIndex), SYM); + } 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++) { - 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--) { - GENLIB_SC_BOTTOM(XX_NAME("m_%d", SliceIndex * n + BitIndex), - BitIndex & 1 ? mys : sym); + GENLIB_SC_BOTTOM(XX_NAME("m_%d", SliceIndex * n + BitIndex), 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(); } + +#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 - 1) + sh = n - 1; + op = random() & ~(~0<> 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