DIRECTORY CD, Convert, EuControl, PW, PWDescr, Rope, SymTab; EuControlImpl: CEDAR PROGRAM IMPORTS Convert, PW, PWDescr, Rope, SymTab EXPORTS EuControl = BEGIN OPEN EuControl; ControlProc: TYPE = PROC [design: CD.Design, descr: PWDescr.Descriptor] RETURNS [obj: PW.ObPtr]; ControlLine: PROC [design: CD.Design, descrPD, descrPU: PWDescr.Descriptor, DescrToPD, DescrToPU: ControlProc, gnd, sep, driver: PW.ObPtr, name: ROPE, flipY: BOOL _ FALSE] RETURNS [controlLine: PW.ObPtr] = BEGIN controlLine _ PW.AbutX[design, gnd, DescrToPD[design, descrPD], sep, DescrToPU[design, descrPU], driver]; IF flipY THEN controlLine _ PW.FlipY[design, controlLine]; PW.RenameObject[design, controlLine, "name"]; END; Nand: PUBLIC PROC [design: CD.Design, descrPD, descrPU: PWDescr.Descriptor, flipY: BOOL _ FALSE] RETURNS [nandDec: PW.ObPtr] = {nandDec _ ControlLine[design, descrPD, descrPU, DescrToNandPD, DescrToNandPU, decGround, decNPSep, decDriver, "nandDec", flipY]}; RouteTo: PUBLIC PROC [design: CD.Design, descrPD, descrPU: PWDescr.Descriptor] RETURNS [wire: PW.ObPtr] = {wire _ ControlLine[design, descrPD, descrPU, DescrToWirePD, DescrToWirePU, decWireGround, decWireNPSep, decWireDriver, "wire"]}; BiasVoltage: PUBLIC PROC [design: CD.Design, descrPD, descrPU: PWDescr.Descriptor] RETURNS [bias: PW.ObPtr] = {bias _ ControlLine[design, descrPD, descrPU, DescrToWirePD, DescrToWirePU, decWireGround, decWireNPSep, decBiasVoltage, "biasVoltage"]}; Inverters: PUBLIC PROC [design: CD.Design, descrPD, descrPU: PWDescr.Descriptor, flipY: BOOL _ FALSE] RETURNS [inverters: PW.ObPtr] = {inverters _ ControlLine[design, descrPD, descrPU, DescrToInvPD, DescrToInvPU, decInvGround, devInvNPSep, decInvDriver, "inverters", flipY]}; Gap: PUBLIC PROC [design: CD.Design, descrPD, descrPU: PWDescr.Descriptor, flipY: BOOL _ FALSE] RETURNS [gap: PW.ObPtr] = {gap _ ControlLine[design, descrPD, descrPU, DescrToGapPD, DescrToGapPU, decGapGround, decGapNPSep, decGapDriver, "gap", flipY]}; NorOfNands: PUBLIC PROC [design: CD.Design, listDescrPD: LIST OF PWDescr.Descriptor, descrPU: PWDescr.Descriptor, flipY: BOOL _ FALSE] RETURNS [norDec: PW.ObPtr] = BEGIN flipBranch: BOOL _ TRUE; listBranch: PW.ListOb _ CONS[Nand[design, listDescrPD.first, descrPU]]; FOR l: LIST OF PWDescr.Descriptor _ listDescrPD.rest, l.rest WHILE l#NIL DO listBranch _ CONS[NorBranch[design, l.first, descrPU, flipBranch], listBranch]; flipBranch _ ~flipBranch; ENDLOOP; norDec _ PW.AbutListY[design, listBranch]; IF flipY THEN norDec _ PW.FlipY[design, norDec]; PW.RenameObject[design, norDec, "norDec"]; END; NorBranch: PROC [design: CD.Design, descrPD, descrPU: PWDescr.Descriptor, flipY: BOOL _ FALSE] RETURNS [branch: PW.ObPtr] = {branch _ ControlLine[design, descrPD, descrPU, DescrToNandPD, DescrToNandPU, decGround, decNPSep, IF flipY THEN norDecAttachDown ELSE norDecAttachUp, "branch", flipY]}; DescrToNandPD: PROC [design: CD.Design, descr: PWDescr.Descriptor] RETURNS [obj: PW.ObPtr _ NIL] = BEGIN listOb: PW.ListOb _ NIL; BoolToPD: PROC [bool: PWDescr.BoolRef] RETURNS [obj: PW.ObPtr] = {obj _ SELECT TRUE FROM ~bool.val0 AND ~bool.val1 => decX, bool.val0 AND ~bool.val1 => decOne, ~bool.val0 AND bool.val1 => decZero, ENDCASE => ERROR}; -- both bits=1 has no meaning here IntToPD: PROC [int: PWDescr.IntRef] RETURNS [obj: PW.ObPtr] = BEGIN found: BOOL; ref: SymTab.Val; -- check the order of bits IntToObj: PW.XYFunction = {RETURN[BoolToPD[int.bools[x]]]}; uniqueID: INT _ int.nbBits+100*int.val+10000*int.mask; key: ROPE _ Rope.Concat["PD", Convert.RopeFromInt[uniqueID]]; [found, ref] _ SymTab.Fetch[cellCache, key]; IF ~found THEN { obj _ PW.MapFunctionX[design, IntToObj, 0, int.nbBits]; [] _ SymTab.Store[cellCache, key, obj];} ELSE obj _ NARROW[ref]; END; forEachItem: PWDescr.ForEachItemProc = {obj: PW.ObPtr _ WITH item.specificRef SELECT FROM bit: PWDescr.BitRef => obj _ IF bit.val THEN decTransistor ELSE decNoTransistor, bool: PWDescr.BoolRef => obj _ BoolToPD[bool], int: PWDescr.IntRef => obj _ IntToPD[int], ENDCASE => ERROR; listOb _ CONS[obj, listOb];}; PWDescr.EnumerateItems[descr, forEachItem]; obj _ PW.AbutListX[design, PW.Reverse[listOb]]; END; DescrToNandPU: PROC [design: CD.Design, descr: PWDescr.Descriptor] RETURNS [obj: PW.ObPtr _ NIL] = BEGIN listOb: PW.ListOb _ NIL; forEachItem: PWDescr.ForEachItemProc = {obj: PW.ObPtr _ WITH item.specificRef SELECT FROM bit: PWDescr.BitRef => obj _ IF bit.val THEN (IF flip THEN decPTransFlip ELSE decPTrans) ELSE (IF flip THEN decPNoTransFlip ELSE decPNoTrans), ENDCASE => ERROR; listOb _ CONS[obj, listOb]; flip _ ~flip;}; flip: BOOL _ FALSE; PWDescr.EnumerateItems[descr, forEachItem]; obj _ PW.AbutListX[design, PW.Reverse[listOb]]; END; DescrToWirePD: PROC [design: CD.Design, descr: PWDescr.Descriptor] RETURNS [wire: PW.ObPtr _ NIL] = BEGIN listOb: PW.ListOb _ NIL; BoolToWire: PROC [bool: PWDescr.BoolRef] RETURNS [obj: PW.ObPtr] = {obj _ SELECT TRUE FROM ~bool.val0 AND ~bool.val1 => decWireX, bool.val0 AND ~bool.val1 => decWireZeroCt, ~bool.val0 AND bool.val1 => decWireOneCt, ENDCASE => ERROR}; IntToWire: PROC [int: PWDescr.IntRef] RETURNS [obj: PW.ObPtr] = BEGIN found: BOOL; ref: SymTab.Val; IntToAdrFn: PW.XYFunction = {RETURN[BoolToWire[int.bools[x]]]}; uniqueID: INT _ int.nbBits+100*int.val+10000*int.mask; key: ROPE _ Rope.Concat["W", Convert.RopeFromInt[uniqueID]]; [found, ref] _ SymTab.Fetch[cellCache, key]; IF ~found THEN { obj _ PW.MapFunctionX[design, IntToAdrFn, 0, int.nbBits]; [] _ SymTab.Store[cellCache, key, obj];} ELSE obj _ NARROW[ref]; END; forEachItemMakeWire: PWDescr.ForEachItemProc = BEGIN obj: PW.ObPtr _ WITH item.specificRef SELECT FROM bit: PWDescr.BitRef => IF bit.val THEN decWireCt ELSE decWireNoCt, bool: PWDescr.BoolRef => BoolToWire[bool], int: PWDescr.IntRef => IntToWire[int], ENDCASE => ERROR; listOb _ CONS[obj, listOb]; END; PWDescr.EnumerateItems[descr, forEachItemMakeWire]; wire _ PW.AbutListX[design, PW.Reverse[listOb]]; END; DescrToWirePU: PROC [design: CD.Design, descr: PWDescr.Descriptor] RETURNS [wire: PW.ObPtr _ NIL] = BEGIN listOb: PW.ListOb _ NIL; forEachItemMakeWire: PWDescr.ForEachItemProc = BEGIN obj: PW.ObPtr _ WITH item.specificRef SELECT FROM bit: PWDescr.BitRef => IF bit.val THEN decWirePCt ELSE decWirePNoCt, ENDCASE => ERROR; IF flip THEN listOb _ CONS[PW.FlipX[design, obj], listOb] ELSE listOb _ CONS[obj, listOb]; flip _ ~flip; END; flip: BOOL _ FALSE; PWDescr.EnumerateItems[descr, forEachItemMakeWire]; wire _ PW.AbutListX[design, PW.Reverse[listOb]]; END; DescrToInvPD: PROC [design: CD.Design, descr: PWDescr.Descriptor] RETURNS [obj: PW.ObPtr _ NIL] = BEGIN listOb: PW.ListOb _ NIL; BoolToPD: PROC [bool: PWDescr.BoolRef] RETURNS [obj: PW.ObPtr] = {obj _ IF bool.val0 THEN decInv ELSE decNoInv2}; IntToPD: PROC [int: PWDescr.IntRef] RETURNS [obj: PW.ObPtr] = BEGIN -- check the order of bits IntToObj: PW.XYFunction = {RETURN[BoolToPD[int.bools[x]]]}; obj _ PW.MapFunctionX[design, IntToObj, 0, int.nbBits]; END; forEachItem: PWDescr.ForEachItemProc = {obj: PW.ObPtr _ WITH item.specificRef SELECT FROM bit: PWDescr.BitRef => obj _ decNoInv, bool: PWDescr.BoolRef => obj _ BoolToPD[bool], int: PWDescr.IntRef => obj _ IntToPD[int], ENDCASE => ERROR; listOb _ CONS[obj, listOb];}; PWDescr.EnumerateItems[descr, forEachItem]; obj _ PW.AbutListX[design, PW.Reverse[listOb]]; END; DescrToInvPU: PROC [design: CD.Design, descr: PWDescr.Descriptor] RETURNS [obj: PW.ObPtr _ NIL] = BEGIN listOb: PW.ListOb _ NIL; forEachItem: PWDescr.ForEachItemProc = {obj: PW.ObPtr _ WITH item.specificRef SELECT FROM bit: PWDescr.BitRef => obj _ IF flip THEN decInvPFlip ELSE decInvP, ENDCASE => ERROR; listOb _ CONS[obj, listOb]; flip _ ~flip;}; flip: BOOL _ FALSE; PWDescr.EnumerateItems[descr, forEachItem]; obj _ PW.AbutListX[design, PW.Reverse[listOb]]; END; DescrToGapPD: PROC [design: CD.Design, descr: PWDescr.Descriptor] RETURNS [gap: PW.ObPtr _ NIL] = BEGIN listOb: PW.ListOb _ NIL; BoolToGap: PROC [bool: PWDescr.BoolRef] RETURNS [obj: PW.ObPtr] = {obj _ IF ~bool.val0 THEN decPassX ELSE decPass2}; IntToGap: PROC [int: PWDescr.IntRef] RETURNS [obj: PW.ObPtr] = BEGIN IntToAdrFn: PW.XYFunction = {RETURN[BoolToGap[int.bools[x]]]}; obj _ PW.MapFunctionX[design, IntToAdrFn, 0, int.nbBits]; END; forEachItemMakeWire: PWDescr.ForEachItemProc = BEGIN obj: PW.ObPtr _ WITH item.specificRef SELECT FROM bit: PWDescr.BitRef => IF bit.val THEN decGapPass ELSE decGapNoPass, bool: PWDescr.BoolRef => BoolToGap[bool], int: PWDescr.IntRef => IntToGap[int], ENDCASE => ERROR; listOb _ CONS[obj, listOb]; END; PWDescr.EnumerateItems[descr, forEachItemMakeWire]; gap _ PW.AbutListX[design, PW.Reverse[listOb]]; END; DescrToGapPU: PROC [design: CD.Design, descr: PWDescr.Descriptor] RETURNS [gap: PW.ObPtr _ NIL] = BEGIN listOb: PW.ListOb _ NIL; forEachItemMakeWire: PWDescr.ForEachItemProc = BEGIN obj: PW.ObPtr _ WITH item.specificRef SELECT FROM bit: PWDescr.BitRef => IF bit.val THEN decGapPPass ELSE decGapPNoPass, ENDCASE => ERROR; IF flip THEN listOb _ CONS[PW.FlipX[design, obj], listOb] ELSE listOb _ CONS[obj, listOb]; flip _ ~flip; END; flip: BOOL _ FALSE; PWDescr.EnumerateItems[descr, forEachItemMakeWire]; gap _ PW.AbutListX[design, PW.Reverse[listOb]]; END; cellCache: SymTab.Ref; decGround, decTransistor, decNoTransistor, decZero, decOne, decX: PW.ObPtr; decNPSep, decPNoTrans, decPNoTransFlip, decPTrans, decPTransFlip, decLeftPrech, decRightPrech, decDriver, norDecAttachUp, norDecAttachDown: PW.ObPtr; decWireGround, decWireCt, decWireNoCt, decWireZeroCt, decWireOneCt, decWireX: PW.ObPtr; decWireNPSep, decWirePCt, decWirePNoCt, decWirePrechNoCt, decWirePrechLeftCt, decWirePrechRightCt, decWireDriver, decBiasVoltage: PW.ObPtr; decInvGround, decNoInv, decNoInv2, decInv, decInvPFlip: PW.ObPtr; devInvNPSep, decInvP, decInvDriver: PW.ObPtr; decGapGround, decGapPass, decGapNoPass, decPassX, decPass2: PW.ObPtr; decGapNPSep, decGapPPass, decGapPNoPass, decGapDriver: PW.ObPtr; InitEUControl: PUBLIC PROC [design: CD.Design] = BEGIN PW.SetDefaultSource[design, PW.OpenDesign["///eulayout.dale"]]; decTransistor _ PW.Get[design, "decTransistor"]; decNoTransistor _ PW.Get[design, "decNoTransistor"]; decDriver _ PW.Get[design, "decDriver"]; norDecAttachUp _ PW.Get[design, "norDecAttachUp"]; norDecAttachDown _ PW.Get[design, "norDecAttachDown"]; decPNoTrans _ PW.Get[design, "decPNoTrans"]; decPNoTransFlip _ PW.FlipX[design, decPNoTrans]; decPTrans _ PW.Get[design, "decPTrans"]; decPTransFlip _ PW.FlipX[design, decPTrans]; decNPSep _ PW.Get[design, "decNPSep"]; decGround _ PW.Get[design, "decGround"]; decZero _ PW.AbutX[design, decNoTransistor, decTransistor]; -- convention!!! decOne _ PW.AbutX[design, decTransistor, decNoTransistor]; decX _ PW.AbutX[design, decNoTransistor, decNoTransistor]; decLeftPrech _ PW.AbutX[design, decPTrans, decPNoTransFlip]; decRightPrech _ PW.AbutX[design, decPNoTrans, decPTransFlip]; decWireCt _ PW.Get[design, "decWireCt"]; decWireNoCt _ PW.Get[design, "decWireNoCt"]; decWireZeroCt _ PW.AbutX[design, decWireCt, decWireNoCt]; decWireOneCt _ PW.AbutX[design, decWireNoCt, decWireCt]; decWireX _ PW.AbutX[design, decWireNoCt, decWireNoCt]; decWireNPSep _ PW.Get[design, "decWireNPSep"]; decWirePCt _ PW.Get[design, "decWirePCt"]; decWirePNoCt _ PW.Get[design, "decWirePNoCt"]; decWireDriver _ PW.Get[design, "decWireDriver"]; decBiasVoltage _ PW.Get[design, "decBiasVoltage"]; decWireGround _ PW.Get[design, "decWireGround"]; decWirePrechNoCt _ PW.AbutX[design, decWirePNoCt, PW.FlipX[design, decWirePNoCt]]; decWirePrechLeftCt _ PW.AbutX[design, decWirePCt, PW.FlipX[design, decWirePNoCt]]; decWirePrechRightCt _ PW.AbutX[design, decWirePNoCt, PW.FlipX[design, decWirePCt]]; decInvGround _ PW.Get[design, "decInvGround"]; decNoInv _ PW.Get[design, "decNoInv"]; decNoInv2 _ PW.AbutX[design, decNoInv, decNoInv]; decInv _ PW.Get[design, "decInv"]; devInvNPSep _ PW.Get[design, "devInvNPSep"]; decInvP _ PW.Get[design, "decInvP"]; decInvPFlip _ PW.FlipX[design, decInvP]; decInvDriver _ PW.Get[design, "decInvDriver"]; decGapGround _ PW.Get[design, "decGapGround"]; decGapPass _ PW.Get[design, "decGapPass"]; decGapNoPass _ PW.Get[design, "decGapNoPass"]; decPassX _ PW.AbutX[design, decGapNoPass, decGapNoPass]; decPass2 _ PW.AbutX[design, decGapPass, decGapPass]; decGapNPSep _ PW.Get[design, "decGapNPSep"]; decGapPPass _ PW.Get[design, "decGapPPass"]; decGapPNoPass _ PW.Get[design, "decGapPNoPass"]; decGapDriver _ PW.Get[design, "decGapDriver"]; cellCache _ SymTab.Create[mod: 67]; END; END. EuControlImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reversed. Created by Louis Monier, May 10, 1985 10:46:58 pm PDT Last Edited by: Monier, July 8, 1985 4:29:40 pm PDT --User-level routines for describing control in this style of design: nand precharged decoder -- Integers and bools are represented by pairs of wires, bits (not bools) on a single wire -- A generic proc that turns a descriptor into some part of the control -- Assemble pieces into a NAND decoder -- A wire or set of wires routing a particular item to the datapath (right side) -- Bias voltage generator -- A set of inverters computing the complementary of signals specified by the descriptor -- A separations between two control parts having different descriptors of the same size; the semantic is the same as the routing, but specifies whether a wire is interrupted or not; if metal2 is used to double poly, this is the place to contact both layers -- A set of NAND decoders, grouped as pull-downs of a precharged NOR; each branch has a different pull-down descriptor, but there is only one pull-up descriptor -- Internal routines for generating control -- Descriptor to pull-down chain -- Descriptor to pull-up chain: different from DescrToPD because not only the cells, but also the assembly process is different (flip) -- Descriptor to wire routing to a particular item in the descriptor: only one bit is wired. -- so far, we find only bits in a pull-up -- Descriptor to pull-down chain -- Descriptor to pull-up chain: different from DescrToPD because not only the cells, but also the assembly process is different (flip) -- Descriptor to gap. All the wires of an item are passed together -- so far, we find only bits in a pull-up -- A speed-up hack -- Pull-down of the Nand/Nor of Nand decoder -- Pull-up of the Nand/Nor of Nand decoder -- Pull-down part of a wire -- Pull-up part of a wire, and a special case for the bias voltage generator -- Pull-down part of an inverter -- Pull-up part of an inverter -- Pull-down part of a gap -- Pull-up part of a gap Κ^˜– "Cedar" stylešœ™Jšœ Οmœ1™˜OJšœ˜Jšžœ˜—Jšœ žœ˜*Jšžœžœ žœ˜0Jšžœ(˜*Jšžœ˜—J™šŸ œžœ žœ6žœžœžœ žœ ˜{Jšœcžœžœžœ#˜©——J™™+J™ š Ÿ œžœ žœ$žœžœ žœ˜bJšž˜Jšœžœ žœ˜šŸœžœžœžœ ˜@šœžœžœž˜Jšœ žœ˜"Jšœ žœ˜#Jšœ žœ˜$JšžœžœΟc"˜5——šŸœžœžœžœ ˜=Jšž˜Jšœžœ˜ Jšœ˜Jš ˜JšŸœžœ žœžœ˜;Jšœ žœ)˜6Jšœžœ4˜=Jšœ,˜,šžœžœ˜Jšœžœ/˜7Jšœ(˜(—Jšžœžœ˜Jšžœ˜—šŸ œ˜&šœžœ ˜šžœžœž˜!Jšœžœ žœžœ˜PJšœ.˜.Jšœ*˜*Jšžœžœ˜——Jšœ žœ˜—Jšœ+˜+Jšœžœžœ˜/Jšžœ˜—Jš †™†š Ÿ œžœ žœ$žœžœ žœ˜bJšž˜Jšœžœ žœ˜šŸ œ˜&šœžœ ˜šžœžœž˜!šœ˜Jš žœ žœžœžœžœ ˜Jšž˜JšŸ œžœ žœžœ˜>Jšœžœ1˜9Jšžœ˜—šŸœ˜.Jšž˜šœžœ žœžœž˜1Jšœžœ žœ žœ˜DJšœ)˜)Jšœ%˜%Jšžœžœ˜—Jšœ žœ˜Jšžœ˜—Jšœ3˜3Jšœžœžœ˜/Jšžœ˜—J™)š Ÿ œžœ žœ$žœžœ žœ˜aJšž˜Jšœžœ žœ˜šŸœ˜.Jšž˜šœžœ žœžœž˜1Jšœžœ žœ žœ˜FJšžœžœ˜—Jšžœžœ žœžœ˜9Jšžœ žœ˜ Jšœ ˜ Jšžœ˜—Jšœžœžœ˜Jšœ3˜3Jšœžœžœ˜/Jšžœ˜—J™J™J™Jšœ˜J™J™,JšœBžœ˜KJ™*JšœŒžœ˜•J™JšœNžœ˜WJ™LJšœ‚žœ˜‹J™ Jšœ8žœ˜AJ™Jšœ$žœ˜-J™Jšœ<žœ˜EJ™Jšœ7žœ˜@J™J˜šŸ œžœžœ žœ ˜1Jšž˜Jšœžœ!˜?J˜Jšœžœ˜0Jšœžœ ˜4Jšœ žœ˜(Jšœžœ˜2Jšœžœ!˜6Jšœžœ˜,Jšœžœ˜0Jšœ žœ˜(Jšœžœ˜,J˜Jšœ žœ˜&Jšœ žœ˜(Jšœ žœ1 ˜MJšœ žœ/˜:Jšœžœ2˜;Jšœžœ+˜