DIRECTORY BitHacks, CD, CoreCreate, EU2FU, EU2LeafUtils, EU2Utils, LayoutCheckpoint, PWCore, Rope; EU2FUImpl: CEDAR PROGRAM IMPORTS BitHacks, CoreCreate, EU2LeafUtils, EU2Utils, LayoutCheckpoint, PWCore, Rope EXPORTS EU2FU = BEGIN OPEN CoreCreate, EU2FU, EU2LeafUtils, EU2Utils; CreateFieldUnit: PUBLIC PROC RETURNS [cellType: CellType] = { IF EU2Utils.useFUCheckpoint THEN RETURN [LayoutCheckpoint.Retrieve["FieldUnit"]]; PrintStart["FieldUnit"]; cellType _ Cell[ name: "FieldUnit", public: WireList[LIST["Vdd", "Gnd", Bus["left"], Bus["st2A"], Bus["r2B"], Bus["cBus"], Bus["fuOut"], "insert", Seq["mask", 6], Seq["shift", 6], Seq["sh", wordSize+1] ]], onlyInternal: Wires[Bus["m1"], Bus["m2"], Bus["shOut"], "pass"], instances: LIST [ Instance[CreateMask[]], Instance[CreateCompose[]], Instance[CreateBarrelShifter[]] ] ]; PWCore.SetAbutY[cellType]; PrintStop[]; }; CreateBarrelShifter: PROC [] RETURNS [cellType: CellType] = { shLine: CellType _ CreateBarrelShifterRow[]; instances: CellInstances _ LIST[Instance[CreateShTop[]]]; -- connect to left sh: Wire _ Seq["sh", wordSize+1]; shOut: Wire _ Bus["shOut"]; left: Wire _ Bus["left"]; st2A: Wire _ Bus["st2A"]; r2B: Wire _ Bus["r2B"]; cBus: Wire _ Bus["cBus"]; fuOut: Wire _ Bus["fuOut"]; public: Wire _ Wires[shOut, sh, "pass", "Vdd", "Gnd", left, st2A, r2B, cBus, fuOut]; FOR row: NAT IN [0..wordSize+1) DO bindings: LIST OF PA _ LIST[["sh", sh[row]], ["shOut", shOut]]; FOR column: NAT IN [0..wordSize) DO sum: NAT _ row+column; to: WR _ IF sum X, isOne => S, ~isOne AND lowToHi[bit-1]=X => F, ~isOne => P, ENDCASE => ERROR; ENDLOOP; }; CreateMaskCell: PROC [selName, outName: ROPE, pos: [0..32)] 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"]]; POb: CD.Object _ PWCore.Layout[Extract["maskP.sch"]]; SOb: CD.Object _ PWCore.Layout[Extract["maskS.sch"]]; FOb: CD.Object _ PWCore.Layout[Extract["maskF.sch"]]; XOb: CD.Object _ PWCore.Layout[Extract["maskX.sch"]]; botOb: CD.Object _ PWCore.Layout[Extract["maskBot.sch"]]; public: Wire _ Wires["Vdd", "Gnd", Seq[selName, sizeK], "m1", "m2", "st2A", "r2B", "cBus", "fuOut"]; abutInstances: LIST OF PWCore.AbutInstance _ LIST [ [PWCore.Layout[Extract[Rope.Cat[outName, "top.sch"]]], pas]]; lowToHi: Pat _ Pattern[pos]; FOR bit: NAT DECREASING IN [0..6) DO ob: CD.Object _ SELECT lowToHi[bit] FROM X => XOb, F => FOb, S => SOb, P => POb, ENDCASE => ERROR; abutInstances _ CONS [[ob, CONS[["sel", Index[selName, 5-bit]], pas]], -- check!!! abutInstances]; ENDLOOP; abutInstances _ CONS [[botOb, pas], abutInstances]; cellType _ PWCore.AbutCell[ name: "Mask", public: public, abutInstances: abutInstances, inX: FALSE]; }; CreateCompose: PROC [] RETURNS [cellType: CellType] = { cellType _ SequenceCell[name: "Compose", baseCell: Extract["ComposeCell.sch"], count: wordSize, sequencePorts: Wires["st2A", "r2B", "cBus", "m1", "m2", "shOut", "fuOut"]]; PWCore.SetArrayX[cellType]; }; END. Get the function index->mask correct Enlarge nE in shifter ΪEU2FUImpl.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Louis Monier June 9, 1986 5:19:45 pm PDT Bertrand Serlet May 11, 1986 7:45:09 pm PDT -- (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=wordSize => out_st2A; shift by zero is on top; -- The layout is explicit because the shifter is a special type of array not expressible by a Sequence cell (diagonal port is the same on the top and left side). -- shOut[0..32), sh[0..33), pass, (left, st2A, r2B, cBus, fuOut)[0..32), Vdd, Gnd -- in[0..32), shOut[0..32), sh, pass -- 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" -- 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) TO DO CreateMaskCell: PROC [selName, outName: ROPE, pos: [0..32)] RETURNS [cellType: CellType] = { internalList: LIST OF WR _ NIL; norBranch: CellType _ Extract["maskGenNor.sch"]; nandBranch: CellType _ Extract["maskGenNand.sch"]; public: Wire _ Wires["Vdd", "Gnd", Seq[selName, sizeK], "m1", "m2", "st2A", "r2B", "cBus", "fuOut"]; instances: CellInstances _ NIL; new: WR; currentN: WR _ outName; currentP: WR _ outName; instances _ LIST[Instance[Extract[Rope.Cat[outName, "top.sch"]]]]; FOR i: NAT DECREASING IN [0..sizeK) DO IF BitHacks.XthBitOfN[i, pos] THEN { IF i>0 THEN {new _ Wires[]; internalList _ CONS[new, internalList]} ELSE new _ "Vdd"; instances _ CONS[ Instance[norBranch, ["sel", Index[selName, i]], ["n", currentN], ["pHi", currentP], ["pLow", new]], instances]; } ELSE { IF i>0 THEN {new _ Wires[]; internalList _ CONS[new, internalList]} ELSE new _ "Gnd"; instances _ CONS[ Instance[nandBranch, ["sel", Index[selName, i]], ["p", currentP], ["nHi", currentN], ["nLow", new]], instances]; }; ENDLOOP; instances _ CONS[IF BitHacks.XthBitOfN[0, pos] THEN Instance[Extract["maskGenNorBot.sch"]] ELSE Instance[Extract["maskGenNandBot.sch"]], instances]; cellType _ Cell[ name: "Mask", public: public, onlyInternal: WireList[internalList], instances: instances]; PWCore.SetAbutY[cellType]; }; Κ – "cedar" style˜codešœ™Kšœ Οmœ7™BK™(K™+—K˜KšΟk œ žœL˜bK˜•StartOfExpansion[]šΟb œžœž˜KšžœM˜TKšžœ ˜Kšžœžœ+˜5—K˜KšœP™PšΟnœžœžœžœ˜=Kšžœžœžœ*˜QKšœ˜šœ˜Kšœ˜šœžœ˜$KšœA˜AKšœ@˜@Kšœ˜—Kšœ@˜@šœ žœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—K˜—Kšœ˜Kšœ ˜ Kšœ˜—K™šœC™CKšœG™GK™’K™KšœQ™Qš œžœžœ˜=Kšœ,˜,KšœžœΟc˜LKšœ!˜!Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜šœ5˜5Kšœ˜—šžœžœžœž˜"Kš œ žœžœžœžœ$˜?šžœ žœžœž˜#Kšœžœ˜Kš œžœžœžœ žœ˜@Kšœ žœ&˜5Kšžœ˜—Kšžœžœ žœ ˜DKšœ žœ,˜˜>—Kšœ˜K˜—š  œžœžœ˜2šœ&˜&Kšœ:˜:Kšœ?˜?—Kšœ˜K˜—K™Kšœ$™$š œžœžœ˜@K˜.Kšœžœ˜š žœžœž œžœž˜)šœ&˜&KšœD˜DKšœ6˜6Kšœ:˜:Kšœ žœžœžœ˜>—Kšœ žœ˜"Kšžœ˜—šœ)˜)šœB˜BKšœ5˜5—Kšœ˜—Kšœ‘(˜CKšœ˜—K˜—K™šœ–™–KšœB™BKšœb™bKšœN™N—™K™[™_K™%K™HK™(K™H—K™~K™KšœO™Oš  œžœžœ˜1Kšœžœ˜šžœž œžœž˜3šœ žœ˜šœ˜KšœL˜LKšœW˜W—Kšœ ˜ —Kšžœ˜—šœ˜Kšœ ˜ šœE˜EKšœJ˜J—Kšœ˜—Kšœ˜Kšœ˜K˜—KšœX™Xš œžœžœ˜KKšœ4˜4Kšœ5˜5šœ˜Kšœ˜Kšœr˜rKšœ žœ˜-—Kšœ˜Kšœ˜K˜—Kšœžœ˜Kšœžœžœžœ˜"š œžœžœžœ˜1Kšœ'˜'Kšœ žœžœžœ˜$šžœžœžœž˜Kšœ#˜#šœžœžœž˜Kšœžœ˜ Kšœ ˜ Kšœžœ˜!Kšœ ˜ Kšžœžœ˜—Kšžœ˜—K˜—Kšœ?™?Kšœ+™+Kšœ8™8š œžœžœžœ˜\Kš œžœžœ žœžœ…˜¦Kšœžœ.˜5Kšœžœ.˜5Kšœžœ.˜5Kšœžœ.˜5Kšœžœ0˜9Kšœd˜dšœžœžœžœ˜3Jšœ=˜=—Kšœ˜š žœžœž œžœž˜$šœžœ žœž˜(Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšžœžœ˜—šœžœžœ(‘ ˜RJšœ˜—Kšžœ˜—K˜Jšœžœ˜3šœ˜Kšœ ˜ Kšœ˜Jšœ˜Jšœžœ˜ —Kšœ˜——K™™DKšœC™Cš  œžœžœ˜7šœ(˜(Kšœ6˜6KšœK˜K—Kšœ˜Kšœ˜——K™Kšžœ˜K˜KšΠbl™K˜K˜$K˜K˜K˜K˜š œžœžœžœ™\Kš œžœžœžœžœ™Kšœ0™0Kšœ2™2Kšœd™dKšœžœ™Kšœžœ™Kšœ žœ ™Kšœ žœ ™Kšœ žœ2™Bš žœžœž œžœ ž™&šžœžœ™$Kšžœžœžœžœ™DKšžœ ™šœ žœ™šœ™KšœP™P—Kšœ ™ —Kšœ™—šžœ™Kšžœžœžœžœ™CKšžœ™šœ žœ™šœ™KšœP™P—Kšœ ™ —Kšœ™—Kšžœ™—šœ žœžœ™/Kšžœ'™+Kšžœ5™9—šœ™Kšœ ™ Kšœ™Kšœ%™%Kšœ™—Kšœ™Kšœ™——…—$/