DIRECTORY Buttons USING [Create, ReLabel, ButtonProc, Button, SetDisplayStyle], Containers USING [Container, Create], CD USING [ Design, Instance, Object], CDCommandOps USING [RegisterWithMenu], CDOps USING [SelectedInstance], CDProperties USING [PutDesignProp], CDSequencer USING [Command], Core USING [CellType, Wire], CoreFlat USING [FlatWire, FlatWireRec, rootCellType, PathError], CoreOps USING [GetCellTypeName, VisitRootAtomics], HashTable USING [Fetch, Table], Icons USING [NewIconFromFile], ImagerFont USING [Font, Find], IO USING [PutF, real], Menus USING [MenuProc, CreateEntry, AppendMenuEntry, CreateMenu, Menu], Mint, PWCore USING [Layout, CorrespondingCellType, LayoutCellTypeInfo], Rope USING [ROPE, Cat, Replace], Sisyph USING [mode], Sinix USING [Mode], SinixOps, TerminalIO USING [PutRope, PutF], ViewerOps USING [DestroyViewer, OpenIcon], WriteCapa; CDMint: CEDAR MONITOR IMPORTS Buttons, Containers, CoreFlat, CDCommandOps, CDOps, CDProperties, CoreOps, Icons, IO, HashTable, ImagerFont, Menus, Mint, PWCore, Rope, Sisyph, SinixOps, TerminalIO, ViewerOps, WriteCapa ~ BEGIN Key: TYPE = REF KeyRec; KeyRec: TYPE = RECORD [ locked: BOOL _ TRUE, unlocked: CONDITION ]; debugCircuit: Mint.Circuit; verbose: BOOLEAN _ FALSE; maxNumber: NAT _ 10; nOfPaths: CARD _ 16; buttonFont: ImagerFont.Font _ ImagerFont.Find["Xerox/TiogaFonts/Gacha10"]; defaultCapa: REAL _ 0.5; vdd: REAL _ 5.0; vTn: REAL _ 0.78; vbb: REAL _ 1200.0; --mV SetButtonToL: PROC [button: Buttons.Button] ~ { Buttons.SetDisplayStyle[button, $WhiteOnBlack, FALSE]; Buttons.ReLabel[button, Rope.Replace[button.name, 0, 1, "L"]]; }; SetButtonToX: PROC [button: Buttons.Button] ~ { Buttons.SetDisplayStyle[button, $BlackOnWhite, FALSE]; Buttons.ReLabel[button, Rope.Replace[button.name, 0, 1, "X"]]; }; SetButtonToH: PROC [button: Buttons.Button] ~ { Buttons.SetDisplayStyle[button, $WhiteOnBlack, FALSE]; Buttons.ReLabel[button, Rope.Replace[button.name, 0, 1, "H"]]; }; SetNewVal: Buttons.ButtonProc ~ { button: Buttons.Button _ NARROW[parent]; node: Mint.Node _ NARROW[clientData]; SELECT mouseButton FROM red => { Mint.SetNode[node: node, val: FALSE]; SetButtonToL[button]; }; yellow => { node.history _ NIL; SetButtonToX[button]; }; blue => { Mint.SetNode[node: node, val: TRUE]; SetButtonToH[button]; }; ENDCASE => ERROR; }; MakeMintPanelViewer: PROC [circuit: Mint.Circuit] RETURNS [modifList: Mint.NodeList] ~ { EachWireButton: PROC [wire: Core.Wire] ~ { flatWire: CoreFlat.FlatWire _ NEW[CoreFlat.FlatWireRec _ [ flatCell: CoreFlat.rootCellType, wireRoot: public, wire: wire ]]; node: Mint.Node _ NARROW[HashTable.Fetch[circuit.nodeTable, flatWire].value]; button: Buttons.Button _ Buttons.Create[ info: [ name: Rope.Cat["X : ", Mint.RopeFromNode[node, circuit]], parent: container, wx: entryVSpace, wy: height + 2, border: TRUE ], proc: SetNewVal, clientData: node, fork: FALSE, font: buttonFont, paint: FALSE]; IF node.history#NIL THEN IF Mint.GetNode[node] THEN SetButtonToH[button] ELSE SetButtonToL[button]; height _ height + button.wh + entryVSpace; }; EachWireCheck: PROC [wire: Core.Wire] ~ { flatWire: CoreFlat.FlatWire _ NEW[CoreFlat.FlatWireRec _ [ flatCell: CoreFlat.rootCellType, wireRoot: public, wire: wire ]]; node: Mint.Node _ NARROW[HashTable.Fetch[circuit.nodeTable, flatWire].value]; IF node.history#NIL THEN modifList _ CONS[node, modifList]; }; entryHeight: CARDINAL = 12; entryVSpace: CARDINAL = 6; height: CARDINAL _ 0; name: Rope.ROPE _ CoreOps.GetCellTypeName[circuit.rootCell]; key: Key _ NEW[KeyRec]; menu: Menus.Menu _ MakePanelMenu[key]; container: Containers.Container _ Containers.Create[ info: [ name: IF name=NIL THEN "MintPanel" ELSE name, menu: menu, iconic: TRUE, icon: Icons.NewIconFromFile["/DATools/DATools6.1/Mint/Mint.icons", 1], column: left, scrollable: TRUE, inhibitDestroy: TRUE ], paint: FALSE ]; height _ entryVSpace; CoreOps.VisitRootAtomics[root: circuit.rootCell.public, eachWire: EachWireButton]; ViewerOps.OpenIcon[container]; WaitForOk[key]; CoreOps.VisitRootAtomics[root: circuit.rootCell.public, eachWire: EachWireCheck]; ViewerOps.DestroyViewer[container]; }; -- MakeMintPanelViewer MakePanelMenu: PROC [key: Key] RETURNS [menu: Menus.Menu] ~ { menu _ Menus.CreateMenu[]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[ name: "OK", proc: OK, clientData: key, guarded: FALSE, documentation: "Fake"] ]; }; WaitForOk: ENTRY PROC [key: Key] ~ { ENABLE UNWIND => NULL; WHILE key.locked DO WAIT key.unlocked ENDLOOP; }; OK: ENTRY Menus.MenuProc ~ { ENABLE UNWIND => NULL; key: Key _ NARROW[clientData]; key.locked _ FALSE; BROADCAST key.unlocked; }; GetLayoutExtracted: PUBLIC PROC [schCT: Core.CellType] RETURNS [maskCT: Core.CellType, extractedToSource: HashTable.Table] ~ { indirectObj: CD.Object = PWCore.Layout[schCT]; layoutCellType: Core.CellType = PWCore.CorrespondingCellType[indirectObj]; source: Core.CellType; [sourceCellType: source, extractedCellType: maskCT, extractedToSource: extractedToSource] _ PWCore.LayoutCellTypeInfo[layoutCellType]; }; CorrectROn: PROC [fet: Mint.Fet, vBias: REAL, biasedList: LIST OF Mint.FetType] ~ { alpha: REAL; fType: Mint.FetType; FOR fTList: LIST OF Mint.FetType _ biasedList, fTList.rest UNTIL fTList=NIL DO IF fTList.first.l#fet.type.l THEN LOOP; IF fTList.first.w#fet.type.w THEN LOOP; IF fTList.first.type#fet.type.type THEN LOOP; fet.type _ fTList.first; RETURN; ENDLOOP; fType _ NEW[Mint.FetTypeRec _ fet.type^]; alpha _ SELECT fType.type FROM pE => ERROR, nE => (vBias-vTn)/(vdd-vTn), ENDCASE => ERROR; fType.rOnInv _ IF alpha>0.0 THEN fet.type.rOnInv*alpha ELSE 0.0; fet.type _ fType; }; BiasFets: PROC [node: Mint.Node] RETURNS [numberOfModifications: CARD _ 0] ~ { bList: LIST OF Mint.FetType _ NIL; vBias: REAL _ Mint.SettledValuesOfNode[node].v; FOR i: NAT IN [0..node.fetSeq.nUsed) DO fet: Mint.Fet = node.fetSeq[i]; IF fet.gate=node THEN { CorrectROn[fet, vBias, bList]; numberOfModifications _ numberOfModifications+1 } ENDLOOP; }; ExtractAndPrepare: PROC [mode: Sinix.Mode, comm: CDSequencer.Command] RETURNS[circuit: Mint.Circuit, instance: CD.Instance] ~ { coreCell: Core.CellType; isLayout: BOOLEAN _ mode#Sisyph.mode; gndNode, vddNode, vbbNode: Mint.Node; fixedV: Mint.NodeList; multiple: BOOL; isVbb: BOOL _ TRUE; [instance, multiple] _ CDOps.SelectedInstance[comm.design]; IF instance=NIL THEN {TerminalIO.PutRope["*** No current selection--can't do it.\n"]; RETURN}; IF multiple THEN TerminalIO.PutRope["*** Multiple instances selected--Using first.\n"]; IF mode=NIL THEN {TerminalIO.PutRope ["technology unknown.\n"]; RETURN}; coreCell _ NARROW[SinixOps.ExtractCDInstance [instance, comm.design, mode].result]; IF isLayout THEN WriteCapa.WriteWireCapa[coreCell, comm.design.technology.key]; circuit _ Mint.CreateCircuit[coreCell]; vddNode _ Mint.NodeFromRope["public.Vdd", circuit]; Mint.SetNode[vddNode, TRUE]; gndNode _ Mint.NodeFromRope["public.Gnd", circuit]; Mint.SetNode[gndNode, FALSE]; vbbNode _ Mint.NodeFromRope["public.Vbb", circuit ! CoreFlat.PathError => {isVbb _ FALSE; CONTINUE}]; IF isVbb THEN { TerminalIO.PutF["Vbb found and set to %4.1f\n", IO.real[vbb]]; Mint.EditNodeHistory[vbbNode, 0.0, vbb]; [] _ BiasFets[vbbNode]; fixedV _ LIST[gndNode, vddNode, vbbNode]; } ELSE { fixedV _ LIST[gndNode, vddNode]; }; Mint.InputData[circuit, fixedV, isLayout, defaultCapa]; }; ShowCamino: PROC [decoration: SinixOps.Decoration, design: CD.Design, instance: CD.Instance, root: Core.CellType, camino: Mint.Camino] ~ { flatWires: LIST OF SinixOps.FlatWireRec _ NIL; FOR iCaminoData: LIST OF Mint.CaminoCell _ camino.data, iCaminoData.rest UNTIL iCaminoData.rest=NIL DO flatWires _ CONS[iCaminoData.first.node.flatWire^, flatWires]; ENDLOOP; SinixOps.HighlightNets[decoration, design, instance, root, flatWires]; }; ExtractAndTiming: PROC [mode: Sinix.Mode, comm: CDSequencer.Command] ~ { worst: Mint.ps; caminos: Mint.Caminos; circuit: Mint.Circuit; clkList: Mint.NodeList; instance: CD.Instance; warningMsg: Rope.ROPE _ NIL; [circuit, instance] _ ExtractAndPrepare[mode, comm]; IF circuit=NIL THEN RETURN; clkList _ LIST[ Mint.NodeFromRope[clkName, circuit ! CoreFlat.PathError => {warningMsg _ Rope.Cat["warning: no ", clkName, " wire"]; CONTINUE}]]; IF warningMsg#NIL THEN clkList _ MakeMintPanelViewer[circuit]; [worst, caminos] _ Mint.MaxFreqEvaluate[circuit, clkList, nOfPaths, 0.0]; IO.PutF[Mint.StdOut, "longest time: %4.1fns\n", IO.real[worst/1000.0]]; Mint.PrintCamino[caminos.first, circuit]; ShowCamino[mode.decoration, comm.design, instance, circuit.rootCell, caminos.first]; Mint.KillCircuit[circuit]; }; ExtractAndCheck: PROC [mode: Sinix.Mode, comm: CDSequencer.Command] ~ { circuit: Mint.Circuit _ ExtractAndPrepare[mode, comm].circuit; IF circuit=NIL THEN RETURN; Mint.CheckLibrary[circuit]; debugCircuit _ circuit; }; ExtractAndMint: PROC [mode: Sinix.Mode, comm: CDSequencer.Command] ~ { circuit: Mint.Circuit _ ExtractAndPrepare[mode, comm].circuit; IF circuit=NIL THEN RETURN; IF verbose THEN Mint.OutputResults[circuit]; [] _ Mint.InteractiveSimulate[circuit]; debugCircuit _ circuit; }; TimingFromLayout: PROC [comm: CDSequencer.Command] ~ { abort: REF BOOL _ NEW [BOOL_FALSE]; mode: Sinix.Mode _ SinixOps.GetExtractMode[comm.design.technology]; TerminalIO.PutRope ["TimingLayout\n"]; CDProperties.PutDesignProp [comm.design, $MintCmdDir]; ExtractAndTiming[mode, comm]; TerminalIO.PutRope ["Timing finished.\n"]; }; TimingFromSchematics: PROC [comm: CDSequencer.Command] ~ { abort: REF BOOL _ NEW [BOOL_FALSE]; TerminalIO.PutRope ["TimingSchematics\n"]; CDProperties.PutDesignProp [comm.design, $MintCmdDir]; ExtractAndTiming[Sisyph.mode, comm]; TerminalIO.PutRope ["Timing finished.\n"]; }; CheckFromLayout: PROC [comm: CDSequencer.Command] ~ { abort: REF BOOL _ NEW [BOOL_FALSE]; mode: Sinix.Mode _ SinixOps.GetExtractMode[comm.design.technology]; TerminalIO.PutRope ["CheckLayout\n"]; CDProperties.PutDesignProp [comm.design, $MintCmdDir]; ExtractAndCheck[mode, comm]; TerminalIO.PutRope ["Check finished.\n"]; }; CheckFromSchematics: PROC [comm: CDSequencer.Command] ~ { abort: REF BOOL _ NEW [BOOL_FALSE]; TerminalIO.PutRope ["CheckSchematics\n"]; CDProperties.PutDesignProp [comm.design, $MintCmdDir]; ExtractAndCheck[Sisyph.mode, comm]; TerminalIO.PutRope ["Check finished.\n"]; }; MintFromLayout: PROC [comm: CDSequencer.Command] ~ { abort: REF BOOL _ NEW [BOOL_FALSE]; mode: Sinix.Mode _ SinixOps.GetExtractMode[comm.design.technology]; TerminalIO.PutRope ["MintLayout\n"]; CDProperties.PutDesignProp [comm.design, $MintCmdDir]; ExtractAndMint[mode, comm]; TerminalIO.PutRope ["Mint finished.\n"]; }; MintFromSchematics: PROC [comm: CDSequencer.Command] ~ { abort: REF BOOL _ NEW [BOOL_FALSE]; TerminalIO.PutRope ["MintSchematics\n"]; CDProperties.PutDesignProp [comm.design, $MintCmdDir]; ExtractAndMint[Sisyph.mode, comm]; TerminalIO.PutRope ["Mint finished.\n"]; }; clkName: Rope.ROPE _ "public.CK"; CDCommandOps.RegisterWithMenu [menu: $ProgramMenu, entry: "Layout->Mint", doc: "Fast Timing Simulation", key: $MintLayoutSel, proc: MintFromLayout]; CDCommandOps.RegisterWithMenu [menu: $ProgramMenu, entry: "Schema->Mint", doc: "Fast Timing Simulation", key: $MintSchemSel, proc: MintFromSchematics]; CDCommandOps.RegisterWithMenu [menu: $ProgramMenu, entry: "Layout->Check", doc: "Electrical Static Check", key: $CheckLayoutSel, proc: CheckFromLayout]; CDCommandOps.RegisterWithMenu [menu: $ProgramMenu, entry: "Schema->Check", doc: "Electrical Static Check", key: $CheckSchemSel, proc: CheckFromSchematics]; CDCommandOps.RegisterWithMenu [menu: $ProgramMenu, entry: "Layout->Timing", doc: "Critical time path evaluation", key: $TimingLayoutSel, proc: TimingFromLayout]; CDCommandOps.RegisterWithMenu [menu: $ProgramMenu, entry: "Schema->Timing", doc: "Critical time path evaluation", key: $TimingSchemSel, proc: TimingFromSchematics]; TerminalIO.PutRope ["CDMint package loaded.\n"]; END. τCDMint.mesa Copyright (C) 1985 by Xerox Corporation. All rights reserved. Christian LeCocq April 21, 1987 2:57:26 pm PDT Mike Spreitzer November 18, 1986 6:21:02 pm PST Bridge beetween ChipNDale, Core and Mint. PROC [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: MouseButton _ red, shift, control: BOOL _ FALSE]; PROC [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: MouseButton _ red, shift, control: BOOL _ FALSE] Called by ChipNDale upon activation of the command. Called by ChipNDale upon activation of the command. Called by ChipNDale upon activation of the command. Called by ChipNDale upon activation of the command. Called by ChipNDale upon activation of the command. Called by ChipNDale upon activation of the command. Κ :˜codešœ ™ K™>Kšœ.™.Kšœ,Οk™/—K™K™)K˜š ˜ Kšœœ8˜EKšœ œ˜%Kšœœ˜%Kšœ œ˜&Kšœœ˜Kšœ œ˜#Kšœ œ ˜Kšœœ˜Kšœ œ2˜@Kšœœ%˜2Kšœ œ˜Kšœœ˜Kšœ œ˜Kšœœ˜Kšœœ<˜GK˜Kšœœ5˜AKšœœœœ ˜ Kšœœ˜Kšœœ˜Kšœ ˜ Kšœ œ˜!Kšœ œ˜*Kšœ ˜ —KšΠbnœœ˜šœ˜KšœPœd˜Ί—šœ˜šœœœ˜šœœœ˜Kšœœœ˜Jšœ  ˜J˜——K˜Kšœ œœ˜Kšœ œ˜Kšœ œ˜KšœJ˜JKšœ œ˜Kšœœ˜Kšœœ˜Kšœœ Οc˜K˜šΟn œœ˜/Kšœ/œ˜6Kšœ>˜>K˜K˜—š  œœ˜/Kšœ/œ˜6Kšœ>˜>K˜—K˜š  œœ˜/Kšœ/œ˜6Kšœ>˜>K˜K˜—š  œ˜!Kšœ œœœœœ2œœ™pKšœœ ˜(Kšœœ ˜%šœ ˜˜Kšœœ˜%K˜K˜—šœ ˜ Kšœœ˜K˜Kšœ˜—šœ ˜ Kšœœ˜$K˜Kšœ˜—Kšœœ˜—K˜K˜—š œœœ˜Xš œœ˜*šœœ˜:Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜—Kšœœ5˜Mšœ(˜(šœ˜Kšœ9˜9Kšœ˜Kšœ˜Kšœ˜Kšœœ˜—Kšœ˜Kšœ˜Kšœœ˜ Kšœ˜Kšœœ˜—šœ  ˜Kšœœœ˜J—Kšœ*˜*K˜—š  œœ˜)šœœ˜:Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜—Kšœœ5˜MKšœœœ œ˜;K˜—Kšœ œ˜Kšœ œ˜Kšœœ˜Kšœ œ-˜˜>Kšœ(˜(Kšœ˜Kšœ œ˜)K˜—šœ˜Kšœ œ˜ K˜—Kšœ7˜7Kšœ˜K˜—š  œœ+œœ8˜ŠKšœ œœœ˜.š œœœ1œœ˜fKšœ œ.˜>Kšœ˜—KšœF˜FK˜K˜—š œœ2˜HKšœ˜Kšœ˜Kšœ˜K˜Kšœ œ ˜Kšœœœ˜Kšœ4˜4Kšœ œœœ˜Kšœ œwœ˜‘Kšœ œœ(˜>KšœI˜IKšœ.œ˜GKšœ)˜)KšœT˜TK˜Kšœ˜K˜—š œœ2˜GKšœ>˜>Kšœ œœœ˜Kšœ˜Kšœ˜Kšœ˜K˜—š œœ2˜FKšœ>˜>Kšœ œœœ˜Kšœ œ˜,Kšœ'˜'Kšœ˜Kšœ˜—K˜šžœœ ˜6K™3Kš œœœœœœ˜#KšœC˜CKšœ&˜&Kšœ6˜6Kšœ˜Kšœ*˜*Kšœ˜K˜—šžœœ ˜:K™3Kš œœœœœœ˜#Kšœ*˜*Kšœ6˜6Kšœ$˜$Kšœ*˜*Kšœ˜K˜—šžœœ ˜5K™3Kš œœœœœœ˜#KšœC˜CKšœ%˜%Kšœ6˜6Kšœ˜Kšœ)˜)Kšœ˜K˜—šžœœ ˜9K™3Kš œœœœœœ˜#Kšœ)˜)Kšœ6˜6Kšœ#˜#Kšœ)˜)Kšœ˜K˜—šžœœ ˜4K™3Kš œœœœœœ˜#KšœC˜CKšœ$˜$Kšœ6˜6Kšœ˜Kšœ(˜(Kšœ˜K˜—šžœœ ˜8K™3Kš œœœœœœ˜#Kšœ(˜(Kšœ6˜6Kšœ"˜"Kšœ(˜(Kšœ˜—K˜Kšœœ˜!KšœPΟtœ.˜”KšœP’œ1˜—KšœQ’œ0˜˜KšœQ’œ3˜›KšœR’œ2˜‘KšœR’œ5˜€Kšœ0˜0—Kšœ˜—…—.l>š