<> <> <> <> <<>> DIRECTORY CD, Core, CoreClasses, CoreCreate, CoreOps, IO, PW, PWCore, Sisyph; PWCoreDecoder: CEDAR PROGRAM IMPORTS CoreClasses, CoreCreate, CoreOps, IO, PW, PWCore, Sisyph = 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]; }; END.