DIRECTORY BitOps, Core, CoreClasses, CoreCreate, CoreOps, PatchWork, PipalSisyph, Rope, Tiling; TestPatchWork: CEDAR PROGRAM IMPORTS BitOps, CoreClasses, CoreCreate, CoreOps, PatchWork, PipalSisyph, Rope, Tiling = BEGIN OPEN CoreCreate; CellType: TYPE = Core.CellType; Wire: TYPE = Core.Wire; CreateInverter: PROC [] RETURNS [cellType: CellType] = { In: Wire _ CoreOps.CreateWire[name: "In"]; Out: Wire _ CoreOps.CreateWire[name: "Out"]; Gnd: Wire _ CoreOps.CreateWire[name: "Gnd"]; Vdd: Wire _ CoreOps.CreateWire[name: "Vdd"]; ntrans: CoreClasses.CellInstance _ NEW [CoreClasses.CellInstanceRec _ [ actual: CoreOps.CreateWire[LIST [In, Out, Gnd]], type: CoreClasses.CreateTransistor[nE] ]]; ptrans: CoreClasses.CellInstance _ NEW [CoreClasses.CellInstanceRec _ [ actual: CoreOps.CreateWire[LIST [In, Out, Vdd, Vdd]], type: CoreClasses.CreateTransistor[pE] ]]; cellType _ CoreClasses.CreateRecordCell[ public: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd]], internal: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd]], instances: LIST [ntrans, ptrans], name: "TestPatchWork.Inverter" ]; PatchWork.SetGet[cellType]; }; Create2Inverter: PROC [] RETURNS [cellType: CellType] = { In: Wire _ CoreOps.CreateWire[name: "In"]; Out: Wire _ CoreOps.CreateWire[name: "Out"]; Gnd: Wire _ CoreCreate.Seq[size:2, name: "Gnd"]; Vdd: Wire _ CoreCreate.Seq[size:2, name: "Vdd"]; Intern: Wire _ CoreOps.CreateWire[name: "Intern"]; inverter: CellType _ CreateInverter[]; first: CoreClasses.CellInstance _ NEW [CoreClasses.CellInstanceRec _ [ actual: CoreOps.CreateWire[LIST [In, Intern, Gnd[0], Vdd[0]]], type: inverter ]]; second: CoreClasses.CellInstance _ NEW [CoreClasses.CellInstanceRec _ [ actual: CoreOps.CreateWire[LIST [Intern, Out, Gnd[1], Vdd[1]]], type: inverter ]]; cellType _ CoreClasses.CreateRecordCell[ public: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd]], internal: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd, Intern]], instances: LIST [first, second], name: "TestPatchWork.Inverter2" ]; PatchWork.SetAbutX[cellType]; }; XthBitOfN: PUBLIC PROC [x, n: INT] RETURNS [BOOL] = {RETURN [IF x<0 THEN FALSE ELSE (n/BitOps.TwoToThe[x]) MOD 2 =1]}; Extract: PROC [name: Core.ROPE] RETURNS [cellType: CellType] = { cellType _ PipalSisyph.Extract[Rope.Cat["TestPatchWork.", name, ".sch"]]; }; AlpsDecoderLine: PROC [nbBits: NAT, index: NAT, pWellEach: NAT _ 4] RETURNS [cellType: CellType] = { PlusI: PROC [i: NAT] RETURNS [WR] = {RETURN [IF i=0 THEN "Gnd" ELSE IF i=nbBits THEN "Plus" ELSE Index["InternalPlus", i]]}; Input: Wire _ Seq[size: nbBits, name: "Input"]; NotInput: Wire _ Seq[size: nbBits, name: "NotInput"]; Plus: Wire _ CoreOps.CreateWire[name: "Plus"]; Minus: Wire _ CoreOps.CreateWire[name: "Minus"]; InternalPlus: Wire _ Seq[size: nbBits, name: "InternalPlus"]; Gnd: Wire _ CoreOps.CreateWire[name: "Gnd"]; instances: LIST OF CellInstance _ NIL; FOR i: NAT IN [0 .. nbBits) DO IF (i MOD pWellEach) = 0 THEN instances _ CONS [Instance[Extract["AlpsPWell"], ["Plus", PlusI[i]]], instances]; instances _ CONS [ Instance[ IF XthBitOfN[i, index] THEN Extract["AlpsOne"] ELSE Extract["AlpsZero"], ["PlusLeft", PlusI[i]], ["PlusRight", PlusI[i+1]], ["Input", Index["Input", i]], ["NotInput", Index["NotInput", i]]], instances]; ENDLOOP; cellType _ Cell[ public: Wires[Input, NotInput, Plus, Minus, Gnd], onlyInternal: Wires[InternalPlus], instances: CoreClasses.ReverseCellInstances[instances] ]; PatchWork.SetAbutX[cellType]; }; AlpsDecoderArray: PROC [nbBits: NAT, indexMin: NAT _ 0, indexSize: NAT _ 0, pWellEach: NAT _ 4] RETURNS [cellType: CellType] = { size: NAT _ IF indexSize=0 THEN NAT[BitOps.TwoToThe[nbBits]] ELSE indexSize; Input: Wire _ Seq[size: nbBits, name: "Input"]; NotInput: Wire _ Seq[size: nbBits, name: "NotInput"]; Plus: Wire _ Seq[size: size, name: "Plus"]; Minus: Wire _ Seq[size: size, name: "Minus"]; Gnd: Wire _ CoreOps.CreateWire[name: "Gnd"]; instances: LIST OF CellInstance _ NIL; FOR i: NAT IN [0 .. size) DO instances _ CONS [ Instance[ AlpsDecoderLine[nbBits, i + indexMin, pWellEach], ["Plus", Index["Plus", i]], ["Minus", Index["Minus", i]]], instances]; ENDLOOP; cellType _ Cell[ public: Wires[Input, NotInput, Plus, Minus, Gnd], instances: CoreClasses.ReverseCellInstances[instances], name: "AlpsDecoderArray" ]; PatchWork.SetAbutY[cellType]; }; AlpsDecoderOutputInverters: PROC [nbBits: NAT, indexSize: NAT _ 0] RETURNS [cellType: CellType] = { size: NAT _ IF indexSize=0 THEN NAT[BitOps.TwoToThe[nbBits]] ELSE indexSize; cellType _ SequenceCell[Extract["AlpsCascode"], size, Wires["Plus", "Minus"]]; PatchWork.SetArrayY[cellType]; }; AlpsDecoderFullArray: PROC [nbBits: NAT, indexMin: NAT _ 0, indexSize: NAT _ 0, pWellEach: NAT _ 4] RETURNS [cellType: CellType] = { size: NAT _ IF indexSize=0 THEN NAT[BitOps.TwoToThe[nbBits]] ELSE indexSize; Input: Wire _ Seq[size: nbBits, name: "Input"]; NotInput: Wire _ Seq[size: nbBits, name: "NotInput"]; Plus: Wire _ Seq[size: size, name: "Plus"]; Output: Wire _ Seq[size: size, name: "Output"]; Gnd: Wire _ CoreOps.CreateWire[name: "Gnd"]; Vdd: Wire _ CoreOps.CreateWire[name: "Vdd"]; cellType _ Cell[ public: Wires[Input, NotInput, Output, Gnd, Vdd], onlyInternal: Wires[Plus], instances: LIST [ Instance[AlpsDecoderArray[nbBits, indexMin, size, pWellEach], ["Minus", "Output"]], Instance[AlpsDecoderOutputInverters[nbBits, size], ["Minus", "Output"]]], name: "AlpsDecoderFullArray" ]; PatchWork.SetAbutX[cellType]; }; AlpsDecoderLineRowTiling: PROC [nbBits: NAT, index: NAT] RETURNS [cellType: CellType] = { tileArray: Tiling.TileArray = NEW [Tiling.TileArrayRec[1]]; tileRow: Tiling.TileRow = NEW [Tiling.TileRowRec[nbBits+2]]; tileRow[nbBits+1] _ NEW [Tiling.TileRec _ [ type: Extract["AlpsCascode"], renaming: LIST [["Minus", "Output"], ["Vdd", "Vdd"]] ]]; tileRow[0] _ NEW [Tiling.TileRec _ [ type: Extract["AlpsPWell"], renaming: LIST [["Gnd", "Gnd"], ["Plus", "Gnd"]] ]]; tileArray[0] _ tileRow; FOR i: NAT IN [0 .. nbBits) DO tileRow[i+1] _ NEW [Tiling.TileRec _ [ type: IF XthBitOfN[i, index] THEN Extract["AlpsOne"] ELSE Extract["AlpsZero"], renaming: LIST [["Gnd", "Gnd"], ["Input", Index["Input", i]], ["NotInput", Index["NotInput", i]]] ]]; ENDLOOP; cellType _ Tiling.CreateTiling[ public: Wires[Seq[size: nbBits, name: "Input"], Seq[size: nbBits, name: "NotInput"], "Output", "Gnd", "Vdd"], tileArray: tileArray, neighborX: CustomNeighborInX, neighborY: NIL ]; }; CustomNeighborInX: Tiling.NeighborProc = { publicPairs _ LIST [ [FindWire[ct1.public, IF ct1=Extract["AlpsPWell"] THEN "Plus" ELSE "PlusRight"], FindWire[ct2.public, IF ct2=Extract["AlpsCascode"] THEN "Plus" ELSE "PlusLeft"]], [FindWire[ct1.public, "Minus"], FindWire[ct2.public, "Minus"]] ]; }; AlpsDecoderFullArrayRowTiling: PROC [nbBits: NAT, indexMin: NAT _ 0, indexSize: NAT _ 0] RETURNS [cellType: CellType] = { size: NAT _ IF indexSize=0 THEN NAT[BitOps.TwoToThe[nbBits]] ELSE indexSize; tileArray: Tiling.TileArray = NEW [Tiling.TileArrayRec[size]]; FOR i: NAT IN [0 .. size) DO tileRow: Tiling.TileRow = NEW [Tiling.TileRowRec[1]]; tileArray[i] _ tileRow; tileRow[0] _ NEW [Tiling.TileRec _ [ type: AlpsDecoderLineRowTiling[nbBits, i + indexMin], renaming: LIST [["Gnd", "Gnd"], ["Vdd", "Vdd"], ["Input", "Input"], ["NotInput", "NotInput"], ["Output", Index["Output", i]]] ]]; ENDLOOP; cellType _ Tiling.CreateTiling[ public: Wires[Seq[size: nbBits, name: "Input"], Seq[size: nbBits, name: "NotInput"], Seq[size: size, name: "Output"], "Gnd", "Vdd"], tileArray: tileArray, neighborX: NIL, neighborY: CustomNeighborInY, name: "AlpsDecoderFullArrayRowTiling" ]; }; CustomNeighborInY: Tiling.NeighborProc = {}; AlpsDecoderFullArrayTiling: PROC [nbBits: NAT, indexMin: NAT _ 0, indexSize: NAT _ 0] RETURNS [cellType: CellType] = { size: NAT _ IF indexSize=0 THEN NAT[BitOps.TwoToThe[nbBits]] ELSE indexSize; tileArray: Tiling.TileArray = NEW [Tiling.TileArrayRec[size]]; FOR i: NAT IN [0 .. size) DO tileRow: Tiling.TileRow = NEW [Tiling.TileRowRec[nbBits+2]]; tileRow[nbBits+1] _ NEW [Tiling.TileRec _ [ type: Extract["AlpsCascode"], renaming: LIST [["Minus", Index["Output", i]], ["Vdd", "Vdd"]] ]]; tileRow[0] _ NEW [Tiling.TileRec _ [ type: Extract["AlpsPWell"], renaming: LIST [["Gnd", "Gnd"], ["Plus", "Gnd"]] ]]; FOR j: NAT IN [0 .. nbBits) DO tileRow[j+1] _ NEW [Tiling.TileRec _ [ type: IF XthBitOfN[j, i] THEN Extract["AlpsOne"] ELSE Extract["AlpsZero"], renaming: LIST [["Gnd", "Gnd"], ["Input", Index["Input", j]], ["NotInput", Index["NotInput", j]]] ]]; ENDLOOP; tileArray[i] _ tileRow; ENDLOOP; cellType _ Tiling.CreateTiling[ public: Wires[Seq[size: nbBits, name: "Input"], Seq[size: nbBits, name: "NotInput"], Seq[size: size, name: "Output"], "Gnd", "Vdd"], tileArray: tileArray, neighborX: Tiling.SchematicsNeighborX, neighborY: Tiling.LayoutNeighborY, name: "AlpsDecoderFullArrayTiling" ]; }; END. τTestPatchWork.mesa Copyright Σ 1988 by Xerox Corporation. All rights reversed. Created by Bertrand Serlet, May 9, 1988 0:06:38 am PDT Bertrand Serlet May 13, 1988 4:01:27 pm PDT Basics Inverters Decoder Basic Cells Decoder CoreCreate Method A simple line without the cascode inverter at the end A simple array without the cascode inverters at the end indexSize=0 means in fact 2^nbBits A column of inverters indexSize=0 means in fact 2^nbBits A simple array with the cascode inverters at the end indexSize=0 means in fact 2^nbBits Decoder with 2 Tilings and custom NeighborProc A simple line with the cascode inverter at the end indexSize=0 means in fact 2^nbBits Decoder with Tiling and standard NeighborProc indexSize=0 means in fact 2^nbBits Κ ˜codešœ™Kšœ<™šœœœ ˜Jšœœ˜5Jšœ˜šœ œ˜$Jšœ6˜6Jšœ œo˜}Jšœ˜—Jšœ˜—šœ˜Jšœ…˜…Kšœ˜Jšœ œ˜Jšœ˜Jšœ%˜%Jšœ˜—J˜J˜—Jšžœ˜,—™-š žœœ œ œœœ˜vJšœ"™"Jš œœœ œœœ ˜LJšœœ˜>šœœœ ˜Jšœœ˜<šœœ˜+Jšœ(œ0˜\Jšœ˜—šœ œ˜$Jšœ&œ"˜LJšœ˜—šœœœ˜šœœ˜&Jšœœœœ˜KJšœ œS˜aJšœ˜—Jšœ˜—J˜Jšœ˜Jšœ˜—šœ˜Jšœ…˜…Kšœ˜Kšœ&˜&Kšœ"˜"Jšœ"˜"J˜—J˜—J˜—šœ˜K˜——…—"t.χ