DIRECTORY BitOps, CD, CoreCreate, EUInner, EUUtils, PWCore, Rope, Sisyph, TilingClass; EUFUImpl: CEDAR PROGRAM IMPORTS BitOps, CoreCreate, EUUtils, PWCore, Rope, Sisyph, TilingClass EXPORTS EUInner = BEGIN OPEN CoreCreate, EUInner; CreateFieldUnit: PUBLIC PROC [cx: Sisyph.Context] RETURNS [cellType: CellType] = { cellType _ Sisyph.ES["FieldUnit.sch", cx]; }; CreateBarrelShifter: PUBLIC PROC [cx: Sisyph.Context] RETURNS [cellType: CellType] = { sh: Wire _ Seq["sh", 32+1]; shOut: Wire _ Seq["shOut", 32]; left: Wire _ Seq["left", 32]; st2A: Wire _ Seq["st2A", 32]; r2B: Wire _ Seq["r2B", 32]; cBus: Wire _ Seq["cBus", 32]; fuOut: Wire _ Seq["fuOut", 32]; tileArray: TilingClass.TileArray _ NEW[TilingClass.TileArrayRec[35]]; tileArray[0] _ NEW[TilingClass.TileRowRec[32]]; FOR i: NAT IN [0..32) DO tileArray[0][i] _ NEW[TilingClass.TileRec _ [ type: Sisyph.ES["shRightConnect.sch", cx], renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"], ["st2A", st2A[i]], ["r2B", r2B[i]], ["cBus", cBus[i]], ["fuOut", fuOut[i]], ["shOut", shOut[i]] ] ]]; ENDLOOP; FOR row: NAT IN [1..33] DO tileArray[row] _ NEW[TilingClass.TileRowRec[32]]; FOR i: NAT IN [0..32) DO tileArray[row][i] _ NEW[TilingClass.TileRec _ [ type: Sisyph.ES["ShifterCell.sch", cx], renaming: LIST[["sh", sh[33-row]]] ]]; ENDLOOP; ENDLOOP; tileArray[34] _ NEW[TilingClass.TileRowRec[32]]; FOR i: NAT IN [0..32) DO tileArray[34][i] _ NEW[TilingClass.TileRec _ [ type: Sisyph.ES["shLeftConnect.sch", cx], renaming: LIST[ ["left", left[i]] ] ]]; ENDLOOP; cellType _ TilingClass.CreateTiling[ name: "BarrelShifter", public: Wires[shOut, sh, "Vdd", "Gnd", left, st2A, r2B, cBus, fuOut], tileArray: tileArray, neighborX: TilingClass.LayoutNeighborX, neighborY: TilingClass.LayoutNeighborY ]; }; CreateMask: PUBLIC PROC [cx: Sisyph.Context] RETURNS [cellType: CellType] = { instances: CellInstances _ NIL; FOR i: [0..32) DECREASING IN [0..32) DO instances _ CONS[ Instance[CreateMasksCell[i, cx], ["m1", Index["m1", i]], ["m2", Index["m2", i]], ["st2A", Index["st2A", i]], ["r2B", Index["r2B", i]], ["cBus", Index["cBus", i]], ["fuOut", Index["fuOut", i]]], instances]; ENDLOOP; cellType _ Cell[ name: "Mask", public: Wires["Vdd", "Gnd", Seq["mask", 6], Seq["shift", 6], Seq["m1", 32], Seq["m2", 32], Seq["st2A", 32], Seq["r2B", 32], Seq["cBus", 32], Seq["fuOut", 32]], instances: instances]; PWCore.SetAbutX[cellType]; }; CreateMasksCell: PROC [pos: [0..32), cx: Sisyph.Context] RETURNS [cellType: CellType] = { m1: CellType _ CreateMaskCell["mask", "m1", 31-pos, cx]; m2: CellType _ CreateMaskCell["shift", "m2", 31-pos, cx]; bottom: CellType _ Sisyph.ES["masksBottomSep.sch", cx]; cellType _ Cell[ name: "Masks", public: Wires["Vdd", "Gnd", Seq["mask", 6], Seq["shift", 6], "m1", "m2", "st2A", "r2B", "cBus", "fuOut" ], instances: LIST[Instance[bottom], Instance[m2], Instance[m1]]]; PWCore.SetAbutY[cellType]; }; Trits: TYPE = {P, S, F, X}; Pat: TYPE = ARRAY [0..6) OF Trits; Pattern: PROC [k: NAT] RETURNS [lowToHi: Pat] ~ { isOne: BOOL _ BitOps.EBFD[k, 31]; -- low-order bit I believe lowToHi[0] _ IF isOne THEN X ELSE F; FOR bit: NAT IN [1..6) DO isOne _ BitOps.EBFD[k, 31-bit]; lowToHi[bit] _ SELECT TRUE FROM isOne AND lowToHi[bit-1]=X => X, isOne => S, ~isOne AND lowToHi[bit-1]=X => F, ~isOne => P, ENDCASE => ERROR; ENDLOOP; }; CreateMaskCell: PROC [selName, outName: ROPE, pos: [0..32), cx: Sisyph.Context] RETURNS [cellType: CellType] = { pas: LIST OF CoreCreate.PA _ LIST[["Vdd", "Vdd"], ["m1", "m1"], ["m2", "m2"], ["Gnd", "Gnd"], ["st2A", "st2A"], ["r2B", "r2B"], ["cBus", "cBus"], ["fuOut", "fuOut"]]; public: Wire _ Wires["Vdd", "Gnd", Seq[selName, 6], "m1", "m2", "st2A", "r2B", "cBus", "fuOut"]; tiles: TilingClass.TileArray _ NEW [TilingClass.TileArrayRec[8]]; lowToHi: Pat _ Pattern[pos]; tiles[7] _ NEW [TilingClass.TileRowRec[1]]; tiles[7][0] _ NEW [TilingClass.TileRec _ [ type: Sisyph.ES[Rope.Cat[outName, "top.sch"], cx], renaming: pas ]]; FOR bit: NAT IN [0..6) DO tiles[bit+1] _ NEW [TilingClass.TileRowRec[1]]; tiles[bit+1][0] _ NEW [TilingClass.TileRec _ [ type: Sisyph.ES[ SELECT lowToHi[bit] FROM X => "maskX.sch", F => "maskF.sch", S => "maskS.sch", P => "maskP.sch", ENDCASE => ERROR, cx], renaming: CONS [["sel", Index[selName, 5-bit]], pas] ]]; ENDLOOP; tiles[0] _ NEW [TilingClass.TileRowRec[1]]; tiles[0][0] _ NEW [TilingClass.TileRec _ [ type: Sisyph.ES["maskBot.sch", cx], renaming: pas ]]; cellType _ TilingClass.CreateTiling[public: public, tileArray: tiles, neighborX: TilingClass.LayoutNeighborX, neighborY: TilingClass.LayoutNeighborY, name: "Mask"]; }; CreateCompose: PUBLIC PROC [cx: Sisyph.Context] RETURNS [cellType: CellType] = { cellType _ EUUtils.CSeqX["Compose", Sisyph.ES["ComposeCell.sch", cx], 32, LIST["st2A", "r2B", "cBus", "m1", "m2", "shOut", "fuOut"]]; }; END. ΔEUFUImpl.mesa Copyright Σ 1985, 1986, 1987 by Xerox Corporation. All rights reserved. Louis Monier June 9, 1986 5:19:45 pm PDT Bertrand Serlet May 18, 1987 10:31:39 pm PDT Last Edited by: Louis Monier February 19, 1987 1:31:12 pm PST -- (left, st2A, r2B, cBus, fuOut)[0..32), insert, (mask, shift)[0..6), sh[0..33) -- A barrel shifter; two inputs (left and st2A), one output (fuOut) -- sh=0 => out_left; sh=32 => out_st2A; shift by zero is on top; -- shOut[0..32), sh[0..33), pass, (left, st2A, r2B, cBus, fuOut)[0..32), Vdd, Gnd -- 0 is the bottom -- line n of shifter is tileArray[n+1] -- 34 is the top -- The field unit uses a mask generator which takes two 6-bit quantities ("shift" and "mask") and a boolean (insert), and produces a mask of the form: if ~insert: 0001111 with exactly "mask" ones on the low-order side if insert: 00011000 with exactly "mask-shift" ones followed by "shift" zeros on the low-order side So the slice "i" has output (ii. By recurring on the high-order bit, we find that F[n, k, i]=k[n].~i[n]+(k[n]=i[n]).F[n-1, k, i], and for 1-bit numbers F[0, k, i]=k[0].~i[0] In every slice, i is a constant and k an input. Let's decompose according to the value of i[n]: i[n]=0: F[0, k, i]=k[0] (use k[0]) F[n, k, i]=k[n] + F[n-1, k, i]=Nand [~k[n], ~F[n-1, k, i]] (NOR to Gnd) i[n]=1: F[0, k, i]=0 (no transistor) F[n, k, i]=k[n] . F[n-1, k, i]=Nor [~k[n], ~F[n-1, k, i]] (NAND branch) -- Note: a NAND branch starting with no tr. still has no tr., i.e. if i=xx0111 then the three bottom transistors are missing! -- mask[0..6), shift[0..6), (m1, m2, st2A, r2B, cBus, fuOut)[0..32), Vdd, Gnd, -- "Vdd", "Gnd", "shift[0..6)", "mask[0..6)", "m1", "m2", "st2A", "r2B", "cBus", "fuOut" isOne: BOOL _ BitHacks.XthBitOfN[0, k]; isOne _ BitHacks.XthBitOfN[bit, k]; -- Using a generator of static gates, program maskOut=F(a, pos) -- "Vdd", "Gnd", "selName[0..6)", "maskOut" -- (selName, outName) can be (mask, m1) or (shift, m2); -- The composition cell: two masks, two words, insert, and an output -- Vdd, Gnd, insert, (st2A, r2B, cBus, fuOut, shOut, m1, m2)[0..32) Κx– "cedar" style˜codešœ ™ KšœH™HKšœ%Οk™(Kšœ,™,Kšœ:™=—K˜Kš œ œB˜VK˜•StartOfExpansion[]šΠbnœœ˜Kšœ?˜FKšœ ˜Kšœœ˜—K˜KšΟcP™PšΟnœœœœ˜RKšœœ˜*Kšœ˜—K™KšŸC™CKšŸA™AKšŸQ™Qš œœœœ˜VKšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ#œ˜EKšŸ™Kšœœ˜/šœœœ ˜šœœ˜-Kšœ œ˜*Kšœ œ‚˜—Kšœ˜Kšœ˜—KšŸ&™&šœœœ ˜Kšœœ˜1šœœœ ˜šœœ˜/Kšœ œ˜'Kšœ œ˜"—Kšœ˜Kšœ˜—Kšœ˜—KšŸ™Kšœœ˜0šœœœ ˜šœœ˜.Kšœ œ˜)Kšœ œ˜#—Kšœ˜Kšœ˜—K˜šœ$˜$Kšœ˜KšœF˜FKšœ˜Kšœ'˜'Kšœ&˜&Kšœ˜—Kšœ˜—K™šŸ–™–KšœB™BKšœb™bKšœN™N—šŸ™K™[™_K™%Kšœ=œ™HK™(Kšœ<œ™H—KšŸ~™~K™KšŸO™Oš  œœœœ˜MKšœœ˜šœ  œœ ˜'šœ œ˜šœ!˜!KšœL˜LKšœW˜W—Kšœ ˜ —Kšœ˜—šœ˜Kšœ ˜ šœ=˜=Kšœb˜b—Kšœ˜—Kšœ˜Kšœ˜K˜—KšŸX™Xš œœ$œ˜YKšœ8˜8Kšœ9˜9Kšœœ˜7šœ˜Kšœ˜Kšœj˜jKšœ œ0˜?—Kšœ˜Kšœ˜K˜—Kšœœ˜Kšœœœœ˜"š œœœœ˜1Kšœœ™'Kšœœ œ Ÿ˜