DIRECTORY CD, Core, CoreClasses, CoreCreate, CoreOps, IO, PW, PWCore, Sisyph, TilingClass; PWCoreDecoder: CEDAR PROGRAM IMPORTS CoreClasses, CoreCreate, CoreOps, IO, PW, PWCore, Sisyph, TilingClass = BEGIN OPEN CoreCreate; schDesign: CD.Design _ PW.OpenDesign["PWCoreDecoder"]; layoutDesign: CD.Design _ schDesign; cx: Sisyph.Context _ Sisyph.Create[schDesign]; Extract: PROC [name: ROPE] RETURNS [cellType: CellType] = { cellType _ Sisyph.ExtractSchematicByName[IO.PutR[IO.rope[name], IO.rope[".sch"]], cx]; PWCore.SetGet[cellType, layoutDesign]; }; alpsOne: CellType _ Extract["AlpsOne"]; alpsZero: CellType _ Extract["AlpsZero"]; alpsPWell: CellType _ Extract["AlpsPWell"]; alpsCascode: CellType _ Extract["AlpsCascode"]; AlpsDecoderLine: PROC [nbBits: NAT, index: NAT, pWellEach: NAT _ 4] RETURNS [cellType: CellType] = { PlusI: PROC [i: NAT] RETURNS [WR] = {RETURN [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[alpsPWell, ["Plus", PlusI[i]]], instances]; instances _ CONS [ Instance[ IF PW.XthBitOfN[i, index] THEN alpsOne ELSE 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] ]; PWCore.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[PW.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" ]; PWCore.SetAbutY[cellType]; }; AlpsDecoderOutputInverters: PROC [nbBits: NAT, indexSize: NAT _ 0] RETURNS [cellType: CellType] = { size: NAT _ IF indexSize=0 THEN NAT[PW.TwoToThe[nbBits]] ELSE indexSize; cellType _ SequenceCell[alpsCascode, size, Wires["Plus", "Minus"]]; PWCore.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[PW.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" ]; PWCore.SetAbutX[cellType]; }; AlpsDecoderLineQuick: PROC [nbBits: NAT, index: NAT, pWellEach: NAT _ 4] RETURNS [cellType: CellType] = { abutInstances: LIST OF PWCore.AbutInstance _ LIST [ [PWCore.Layout[alpsCascode], LIST [["Minus", "Output"], ["Vdd", "Vdd"]]] ]; FOR i: NAT DECREASING IN [0 .. nbBits) DO abutInstances _ CONS [ [PWCore.Layout[IF PW.XthBitOfN[i, index] THEN alpsOne ELSE alpsZero], LIST [["Gnd", "Gnd"], ["Input", Index["Input", i]], ["NotInput", Index["NotInput", i]]] ], abutInstances]; IF (i MOD pWellEach) = 0 THEN abutInstances _ CONS [[PWCore.Layout[alpsPWell]], abutInstances]; ENDLOOP; cellType _ PWCore.AbutCell[ public: Wires[Seq[size: nbBits, name: "Input"], Seq[size: nbBits, name: "NotInput"], "Output", "Gnd", "Vdd"], abutInstances: abutInstances, inX: TRUE ]; }; AlpsDecoderFullArrayQuick: PROC [nbBits: NAT, indexMin: NAT _ 0, indexSize: NAT _ 0, pWellEach: NAT _ 4] RETURNS [cellType: CellType] = { size: NAT _ IF indexSize=0 THEN NAT[PW.TwoToThe[nbBits]] ELSE indexSize; instances: LIST OF CellInstance _ NIL; FOR i: NAT DECREASING IN [0 .. size) DO instances _ CONS [ Instance[ AlpsDecoderLineQuick[nbBits, i + indexMin, pWellEach], ["Output", Index["Output", i]]], instances]; ENDLOOP; cellType _ Cell[ public: Wires[Seq[size: nbBits, name: "Input"], Seq[size: nbBits, name: "NotInput"], Seq[size: size, name: "Output"], "Gnd", "Vdd"], instances: instances, name: "AlpsDecoderFullArrayQuick" ]; PWCore.SetAbutY[cellType]; }; AlpsDecoderLineRowTiling: PROC [nbBits: NAT, index: NAT] RETURNS [cellType: CellType] = { tileArray: TilingClass.TileArray = NEW [TilingClass.TileArrayRec[1]]; tileRow: TilingClass.TileRow = NEW [TilingClass.TileRowRec[nbBits+2]]; tileRow[nbBits+1] _ NEW [TilingClass.TileRec _ [ type: alpsCascode, renaming: LIST [["Minus", "Output"], ["Vdd", "Vdd"]] ]]; tileRow[0] _ NEW [TilingClass.TileRec _ [ type: alpsPWell , renaming: LIST [["Gnd", "Gnd"]] ]]; tileArray[0] _ tileRow; FOR i: NAT IN [0 .. nbBits) DO tileRow[i+1] _ NEW [TilingClass.TileRec _ [ type: IF PW.XthBitOfN[i, index] THEN alpsOne ELSE alpsZero, renaming: LIST [["Gnd", "Gnd"], ["Input", Index["Input", i]], ["NotInput", Index["NotInput", i]]] ]]; ENDLOOP; cellType _ TilingClass.CreateTiling[ public: Wires[Seq[size: nbBits, name: "Input"], Seq[size: nbBits, name: "NotInput"], "Output", "Gnd", "Vdd"], tileArray: tileArray, neighborX: CustomNeighborInX, neighborY: NIL ]; }; CustomNeighborInX: TilingClass.NeighborProc = { publicPairs _ LIST [ [IF ct1=alpsPWell THEN "Plus" ELSE "PlusRight", IF ct2=alpsCascode THEN "Plus" ELSE "PlusLeft"], ["Minus", "Minus"] ]; }; AlpsDecoderFullArrayRowTiling: PROC [nbBits: NAT, indexMin: NAT _ 0, indexSize: NAT _ 0] RETURNS [cellType: CellType] = { size: NAT _ IF indexSize=0 THEN NAT[PW.TwoToThe[nbBits]] ELSE indexSize; tileArray: TilingClass.TileArray = NEW [TilingClass.TileArrayRec[size]]; FOR i: NAT IN [0 .. size) DO tileRow: TilingClass.TileRow = NEW [TilingClass.TileRowRec[1]]; tileArray[i] _ tileRow; tileRow[0] _ NEW [TilingClass.TileRec _ [ type: AlpsDecoderLineRowTiling[nbBits, i + indexMin], renaming: LIST [["Gnd", "Gnd"], ["Vdd", "Vdd"], ["Input", "Input"], ["NotInput", "NotInput"], ["Output", Index["Output", i]]] ]]; ENDLOOP; cellType _ TilingClass.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: TilingClass.NeighborProc = {}; AlpsDecoderFullArrayTiling: PROC [nbBits: NAT, indexMin: NAT _ 0, indexSize: NAT _ 0] RETURNS [cellType: CellType] = { size: NAT _ IF indexSize=0 THEN NAT[PW.TwoToThe[nbBits]] ELSE indexSize; tileArray: TilingClass.TileArray = NEW [TilingClass.TileArrayRec[size]]; FOR i: NAT IN [0 .. size) DO tileRow: TilingClass.TileRow = NEW [TilingClass.TileRowRec[nbBits+2]]; tileRow[nbBits+1] _ NEW [TilingClass.TileRec _ [ type: alpsCascode, renaming: LIST [["Minus", Index["Output", i]], ["Vdd", "Vdd"]] ]]; tileRow[0] _ NEW [TilingClass.TileRec _ [ type: alpsPWell, flatten: TRUE , renaming: LIST [["Gnd", "Gnd"]] ]]; FOR j: NAT IN [0 .. nbBits) DO tileRow[j+1] _ NEW [TilingClass.TileRec _ [ type: IF PW.XthBitOfN[j, i] THEN alpsOne ELSE alpsZero, flatten: TRUE, renaming: LIST [["Gnd", "Gnd"], ["Input", Index["Input", j]], ["NotInput", Index["NotInput", j]]] ]]; ENDLOOP; tileArray[i] _ tileRow; ENDLOOP; cellType _ TilingClass.CreateTiling[ public: Wires[Seq[size: nbBits, name: "Input"], Seq[size: nbBits, name: "NotInput"], Seq[size: size, name: "Output"], "Gnd", "Vdd"], tileArray: tileArray, neighborX: TilingClass.LayoutNeighborX, neighborY: TilingClass.LayoutNeighborY, name: "AlpsDecoderFullArrayTiling" ]; }; END. XPWCoreDecoder.mesa Copyright c 1985 by Xerox Corporation. All rights reversed. Created by Bertrand Serlet, February 7, 1986 5:47:29 pm PST Bertrand Serlet December 17, 1986 5:37:38 am PST 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 PWCore.AbutCell A simple line with the cascode inverter 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šœ Οmœ1™