DIRECTORY CD, CDSequencer, CDSequencerExtras, CDViewer, Core, CoreCDUser, CoreFlat, CoreGeometry, CoreOps, CoreProperties, DAUser, ExtractOps, IO, MessageWindow, Ports, PW, PWCore, RefTab, Rope, Rosemary, RosemaryUser, Sisyph, Static, TerminalIO; DAUserCmdsImpl: CEDAR PROGRAM IMPORTS CD, CDSequencerExtras, CDViewer, CoreCDUser, CoreFlat, CoreGeometry, CoreOps, CoreProperties, ExtractOps, IO, MessageWindow, Ports, PW, PWCore, RefTab, Rope, Rosemary, RosemaryUser, Sisyph, Static, TerminalIO EXPORTS DAUser = BEGIN layoutDecoration: CoreGeometry.Decoration = PWCore.extractMode.decoration; schematicDecoration: CoreGeometry.Decoration = Sisyph.mode.decoration; GenerateLayout: PROC [comm: CDSequencer.Command] = { LayoutOne: CoreCDUser.EachRootCellTypeProc ~ { layout: CD.Object = PWCore.Layout[root]; design: CD.Design; TerminalIO.PutF["Generating layout for %g.\n", IO.rope[CoreOps.GetCellTypeName[root]]]; design _ PW.Draw[layout]; design.name _ CD.Describe[layout]; }; [] _ CoreCDUser.EnumerateSelectedCellTypes[comm.design, LayoutOne]; }; shellWithTexts: BOOL _ TRUE; -- this may be modified using the interpreter to have raw shells ShowShell: PROC [comm: CDSequencer.Command] = { OneShell: CoreCDUser.EachRootCellTypeProc ~ { HasLayoutPins: CoreOps.EachWireProc ~ { quit _ CoreGeometry.HasPins[layoutDecoration, wire]; }; rootName: Rope.ROPE = CoreOps.GetCellTypeName[root]; IF CoreCDUser.GetRootCellTypeDecoration[root]=schematicDecoration THEN [] _ PWCore.Layout[root]; IF CoreOps.VisitWire[root.public, HasLayoutPins] THEN { [] _ PW.Draw[CoreGeometry.CreateShell[layoutDecoration, root, shellWithTexts]]; TerminalIO.PutF["Created layout shell for %g.\n", IO.rope[rootName]]; } ELSE TerminalIO.PutF["%g has no layout pins...\n", IO.rope[rootName]]; }; [] _ CoreCDUser.EnumerateSelectedCellTypes[comm.design, OneShell]; }; ForgetLayout: PROC [comm: CDSequencer.Command] = { ForgetOne: CoreCDUser.EachRootCellTypeProc ~ { RemoveLayoutPins: CoreOps.EachWireProc ~ { CoreGeometry.PutGeometry[layoutDecoration, wire, NIL]; }; IF NOT CoreGeometry.HasObject[layoutDecoration, root] THEN RETURN; TerminalIO.PutF["Removing layout for %g.\n", IO.rope[CoreOps.GetCellTypeName[root]]]; CoreGeometry.PutObject[layoutDecoration, root, NIL]; -- ct -> layout [] _ CoreOps.VisitWireSeq[root.public, RemoveLayoutPins]; CoreProperties.PutCellTypeProp[root, $PWCoreLichenCompareResults, NIL]; CoreProperties.PutCellTypeProp[root, $PWCoreLichenImplDone, NIL]; }; [] _ CoreCDUser.EnumerateSelectedCellTypes[comm.design, ForgetOne]; }; RootedErrorWires: TYPE = LIST OF RootedErrorWire; RootedErrorWire: TYPE = RECORD[root: Core.CellType, flatWire: CoreFlat.FlatWireRec, count: INT]; DoStaticCheck: PROC [command: CDSequencer.Command] = { CheckOne: CoreCDUser.EachRootCellTypeProc = { CheckCount: Static.ConnectionCheckProc = { IF (NOT unconnectedOK) AND ((flatWire.wireRoot=public AND count<1) OR (NOT flatWire.wireRoot=public AND count<2)) THEN { errors _ CONS[[root, flatWire, count], errors]; TerminalIO.PutF["DAUser: %g has %g connection.\n", IO.rope[CoreFlat.WirePathRope[root, flatWire]], IO.rope[IF count=0 THEN "no" ELSE "only one"]]; }; }; name: IO.ROPE = CoreOps.GetCellTypeName[root]; cutSet: CoreFlat.CutSet _ IF CoreProperties.GetCellTypeProp[root, Static.staticCutSetProp]=NIL THEN CoreFlat.CreateCutSet[labels: LIST ["Logic", "LogicMacro"]] ELSE NIL; errors: RootedErrorWires _ NIL; TerminalIO.PutF["DAUser: %g static checking %g.\n", IO.rope[IF flat THEN "Flat" ELSE "Hierarchical"], IO.rope[name]]; quit _ (IF flat THEN Static.CountFlatConnections ELSE Static.CountHierarchicalConnections)[root, CheckCount, cutSet]; FOR errs: RootedErrorWires _ errors, errs.rest UNTIL errs=NIL DO root: Core.CellType _ errs.first.root; flatWire: CoreFlat.FlatWireRec _ errs.first.flatWire; { CoreCDUser.HighlightFlatWire[root, flatWire, command.design ! CoreCDUser.CoreCDUserError => {TerminalIO.PutF["%g\n", IO.rope[msg]]; GOTO oops}]; IF NOT flat THEN CoreCDUser.SelectFlatWire[root, flatWire, command.design ! CoreCDUser.CoreCDUserError => {TerminalIO.PutF["%g\n", IO.rope[msg]]; GOTO oops}]; EXITS oops => NULL; }; TerminalIO.PutF["DAUser: %g has %g connection.\n", IO.rope[CoreFlat.WirePathRope[root, flatWire]], IO.rope[IF errs.first.count=0 THEN "no" ELSE "only one"]]; quit _ MessageWindow.Confirm["Static: Error highlighted, quit?"]; ENDLOOP; TerminalIO.PutF["DAUser: Finished static checking %g.\n", IO.rope[name]]; }; flat: BOOL _ command.key=$StaticFlatCheck; [] _ CoreCDUser.EnumerateSelectedCellTypes[command.design, CheckOne]; }; GetBool: PROC [ct: Core.CellType, prop: ATOM, default: BOOL] RETURNS [BOOL] ~ { rb: REF BOOL _ NARROW [CoreProperties.GetCellTypeProp[ct, prop]]; RETURN [IF rb=NIL THEN default ELSE rb^]; }; RunRosemary: PUBLIC PROC [cellType: Core.CellType, design: CD.Design] RETURNS [tester: RosemaryUser.Tester _ NIL] = { IF cellType#NIL THEN { -- something to do public: Core.Wire _ cellType.public; Vdd: Core.Wire _ CoreOps.FindWire[public, "Vdd"]; Gnd: Core.Wire _ CoreOps.FindWire[public, "Gnd"]; testButtons: LIST OF Rope.ROPE _ NIL; IF Vdd=NIL THEN TerminalIO.PutRope["DAUser: Couldn't find Vdd\n"] ELSE [] _ Rosemary.SetFixedWire[Vdd, H]; IF Gnd=NIL THEN TerminalIO.PutRope["DAUser: Couldn't find Gnd\n"] ELSE [] _ Rosemary.SetFixedWire[Gnd, L]; FOR tbl: LIST OF REF ANY _ NARROW[CoreProperties.GetCellTypeProp[cellType, $Tests]], tbl.rest UNTIL tbl=NIL DO testButtons _ CONS[CoreOps.FixStupidRef[tbl.first], testButtons]; ENDLOOP; IF testButtons=NIL THEN testButtons _ LIST["Logic Test"]; CoreCDUser.SetDesignRootCellType[design, cellType]; CoreCDUser.SetRootCellTypeDecoration[cellType, Sisyph.mode.decoration]; tester _ RosemaryUser.TestProcedureViewer[ cellType: cellType, testButtons: testButtons, name: Rope.Cat[CoreOps.GetCellTypeName[cellType], " Test"], displayWires: RosemaryUser.DisplayPortLeafWires[cellType], recordDeltas: GetBool[cellType, $RecordDeltas, TRUE], cutSet: NARROW[CoreProperties.GetCellTypeProp[cellType, $CutSet]]]; tester.display.recordSteps _ tester.display.recordDeltas AND GetBool[cellType, $RecordSteps, TRUE]; }; }; RosemaryCreate: PROC [command: CDSequencer.Command] = { ct: Core.CellType _ NIL; SeeOne: CoreCDUser.EachRootCellTypeProc ~ { IF ct=NIL THEN ct _ root ELSE {quit _ TRUE; ct _ NIL}; }; IF CoreCDUser.EnumerateSelectedCellTypes[command.design, SeeOne] THEN TerminalIO.PutF["\n*** Only a single cell may be simulated at a time ***\n"] ELSE IF ct=NIL THEN TerminalIO.PutF["\n*** No cell selected for simulation ***\n"] ELSE [] _ RunRosemary[ct, command.design]; }; RosemaryPrintSelectedWires: PROC [command: CDSequencer.Command] = { PrintAValue: CoreCDUser.SelectedFlatWireActionProc = { TerminalIO.PutF[ "Value[%g] = %g\n", IO.rope[CoreFlat.WirePathRope[cellType, selectedFlatWire^]], IO.rope[Ports.LSToRope[ Rosemary.WireValue[display.simulation, selectedFlatWire]]]]; }; cellType: Core.CellType _ NIL; display: RosemaryUser.RoseDisplay _ NIL; [cellType, display] _ GetRoseDisplay[command]; IF display#NIL THEN CoreCDUser.DoForSelectedFlatWires[cellType, PrintAValue, display.cutSet, command.design]; }; RosemaryPlotSelectedWires: PROC [command: CDSequencer.Command] = { AddAWire: CoreCDUser.SelectedFlatWireActionProc = { errorMsg: Rope.ROPE _ RosemaryUser.AddWireToPlot[display, selectedFlatWire]; IF errorMsg#NIL THEN ERROR CoreCDUser.CoreCDUserError[errorMsg]; }; cellType: Core.CellType _ NIL; display: RosemaryUser.RoseDisplay _ NIL; [cellType, display] _ GetRoseDisplay[command]; IF display#NIL THEN CoreCDUser.DoForSelectedFlatWires[cellType, AddAWire, display.cutSet, command.design]; }; RosemaryPlotSelectedCellTypes: PROC [command: CDSequencer.Command] = { AddACellType: CoreCDUser.SelectedFlatCellActionProc = { errorMsg: Rope.ROPE _ RosemaryUser.AddStateToPlot[display, selectedFlatCell]; IF errorMsg#NIL THEN ERROR CoreCDUser.CoreCDUserError[errorMsg]; }; cellType: Core.CellType _ NIL; display: RosemaryUser.RoseDisplay _ NIL; [cellType, display] _ GetRoseDisplay[command]; IF display#NIL THEN CoreCDUser.DoForSelectedFlatCells[cellType, AddACellType, display.cutSet, command.design]; }; GetRoseDisplay: PROC [command: CDSequencer.Command] RETURNS [cellType: Core.CellType _ NIL, display: RosemaryUser.RoseDisplay _ NIL] = { cellType _ CoreCDUser.GetDesignRootCellType[command.design]; IF cellType=NIL THEN TerminalIO.PutRope["DAUser: No root cell type"] ELSE { display _ RosemaryUser.RoseDisplayFor[cellType]; IF display=NIL THEN TerminalIO.PutRope["DAUser: No Rosemary simulation"] }; }; RosemaryCheckCoverage: PROC [command: CDSequencer.Command] ~ { cellType: Core.CellType _ NIL; display: RosemaryUser.RoseDisplay _ NIL; [cellType, display] _ GetRoseDisplay[command]; SELECT TRUE FROM display=NIL => NULL; -- error message already printed RosemaryUser.CheckCoverage[display] => TerminalIO.PutF["The test forces all wires at least once to the H and L states.\n"]; ENDCASE => TerminalIO.PutF["Some wires do not reach the H or L states. Check details in the Rosemary typescript.\n"]; }; HighlightCorrespondingLayout: PROC [command: CDSequencer.Command] = { decoration: CoreGeometry.Decoration = PWCore.extractMode.decoration; geom: CoreGeometry.Instances _ NIL; ConsGeom: CoreGeometry.EachInstanceProc = {geom _ CONS [instance, geom]}; EachWire: CoreCDUser.SelectedFlatWireActionProc = { flatWire: CoreFlat.FlatWireRec _ CoreFlat.CanonizeWire[root, selectedFlatWire^]; EachPair: RefTab.EachPairAction = { ew: Core.Wire = NARROW [key]; sw: Core.Wire = NARROW [val]; IF NOT CoreOps.RecursiveMember[flatWire.wire, sw] THEN RETURN; [] _ CoreGeometry.EnumerateAllGeometry[layoutDecoration, layoutCT, ew, ConsGeom]; }; layoutRoot2: CoreGeometry.Object; layoutCT: Core.CellType; extractedToSource: RefTab.Ref; [layoutRoot2, layoutCT, extractedToSource] _ PWCore.LayoutInfo[root]; IF layoutRoot2#layoutRoot THEN ERROR; [] _ RefTab.Pairs[extractedToSource, EachPair]; }; root: Core.CellType _ CoreCDUser.GetDesignRootCellType[command.design]; layoutRoot: CoreGeometry.Object; layoutDesign: CD.Design; IF root=NIL THEN {TerminalIO.PutF["*** No registered cellType for HighlightCorrespondingLayout!\n"]; RETURN}; layoutRoot _ CoreGeometry.GetObject[layoutDecoration, root]; IF layoutRoot=NIL THEN {TerminalIO.PutF["*** No layout for cellType!\n"]; RETURN}; layoutDesign _ CDViewer.FindDesign[CD.Describe[layoutRoot]]; IF layoutDesign=NIL THEN {TerminalIO.PutF["*** No layout design for cellType!\n"]; RETURN}; ExtractOps.HighlightDesign[command.design]; CoreCDUser.DoForSelectedFlatWires[root, EachWire, NIL, command.design]; geom _ CoreGeometry.TransformList[layoutDesign.actual.first.specific.contents.first.trans, geom]; ExtractOps.HighlightDesignList[layoutDesign, ExtractOps.HighlightInstanceList[geom]]; }; CDSequencerExtras.RegisterCommand[key: $StaticFlatCheck, proc: DoStaticCheck, queue: doQueue]; CDSequencerExtras.RegisterCommand[key: $StaticHierCheck, proc: DoStaticCheck, queue: doQueue]; CDSequencerExtras.RegisterCommand[key: $RosemaryCreate, proc: RosemaryCreate, queue: doQueue]; CDSequencerExtras.RegisterCommand[key: $RosemaryPrintSelectedWires, proc: RosemaryPrintSelectedWires, queue: doQueue]; CDSequencerExtras.RegisterCommand[key: $RosemaryPlotSelectedWires, proc: RosemaryPlotSelectedWires, queue: doQueue]; CDSequencerExtras.RegisterCommand[key: $RosemaryPlotSelectedCellTypes, proc: RosemaryPlotSelectedCellTypes, queue: doQueue]; CDSequencerExtras.RegisterCommand[key: $RosemaryCheckCoverage, proc: RosemaryCheckCoverage, queue: doQueue]; CDSequencerExtras.RegisterCommand[key: $LayoutGenerate, proc: GenerateLayout, queue: doQueue]; CDSequencerExtras.RegisterCommand[key: $LayoutUndo, proc: ForgetLayout, queue: doQueue]; CDSequencerExtras.RegisterCommand[key: $LayoutShell, proc: ShowShell, queue: doQueue]; CDSequencerExtras.RegisterCommand[key: $HighlightCorrespondingLayout, proc: HighlightCorrespondingLayout, queue: doQueue]; END. ^DAUserCmdsImpl.mesa Copyright Σ 1986, 1987 by Xerox Corporation. All rights reserved. Last Edited by: Louis Monier April 28, 1988 6:02:27 pm PDT Last Edited by: Christian Jacobi, January 7, 1987 11:41:28 am PST Jean-Marc Frailong May 1, 1988 4:36:06 pm PDT Barth, October 15, 1987 11:35:03 am PDT Bertrand Serlet April 17, 1988 5:25:49 pm PDT Decorations Layout Force enumeration to return TRUE iff some public has layout geometry Warning: This command is extremely unsafe: - it does not reach for parent celltypes that might be using the same layout - it removes layout only one level deep - it will break StdCellsCMosB if applied to a standard cell - it uses PWCoreLichen properties by name in order to reduce loading dependencies... Static Rosemary Read a boolean property from a CT with the specified default Highlight Layout <-> Sch Initialization Κ ‰– "cedar" style˜codešœ™KšœB™BKšœ:™:Kšœ>Οk™AK™-Kšœ'™'Kšœ-™-K™—š ˜ Kšœ,˜.KšœC˜CK˜Kšœ ˜ Kšœ˜Kšœ˜KšœK˜MK˜—•StartOfExpansion[]šΟnœœ˜KšœœhœœJ˜ΨKšœ˜Kšœœ˜—head™ KšœJ˜JKšœF˜F—™šžœœ ˜4šž œ%˜.Jšœœ˜(Jšœœ˜Jšœ/œ&˜WKšœ œ˜Kšœœ˜"K˜—KšœC˜CJ˜J˜—JšœœœΟc@˜]šž œœ ˜/šžœ%˜-šž œ˜'Kšœœ$™DKšœ4˜4K˜—Kšœœ!˜4Kšœ@œ˜`šœ/œ˜7KšœœH˜OJšœ2œ˜EKšœ˜—Kšœ/œ˜FK˜—KšœB˜BJ˜J˜—šž œœ ˜2šžœΟb œ™*JšœL™LJšœ'™'J™;J™T—šž œ%˜.šžœ˜*Kšœ1œ˜6K˜—Kšœœ0œœ˜BKšœ-œ&˜UKšœ/œŸ˜DKšœ9˜9KšœBœ˜GKšœ<œ˜AK˜—KšœC˜CJ˜——™Jšœœœœ˜1šœœœ=œ˜`J˜—šž œœ#˜6šžœ%˜-šž œ ˜*šœœœœ œœœ œ˜xJšœ œ"˜/šœ2˜2Kšœ-˜/Kšœœ œœ˜/—K˜—K˜—Jšœœœ!˜.šœœ?˜^Jšœœ˜@Jšœœ˜ —Jšœœ˜Kš œ4œœœœœ ˜uJšœœœœ@˜ušœ,œœ˜@Jšœ&˜&Jšœ5˜5šœ˜Kšœuœ œ˜Kš œœœsœ œ˜žKšœ œ˜K˜—šœ2˜2Kšœ-˜/Kšœœœœ˜:—KšœA˜AJšœ˜—Jšœ:œ˜JJšœ˜—Jšœœ ˜*JšœE˜EJšœ˜——™š žœœœ œœœ˜OKšœœ™Kšœœ˜Kšœ$œ˜(Kšœ.˜.šœœ˜KšœœœŸ ˜5Kšœ{˜{Kšœn˜u—Jšœ˜J˜——™šžœœ#˜EKšœD˜DKšœœ˜#Kšžœ*œ˜Išžœ+˜3KšœP˜Pšžœ˜#Kšœœ˜Kšœœ˜Kšœœ,œœ˜>KšœQ˜QK˜—KšœY˜YKšœE˜EKšœœœ˜%Kšœ/˜/K˜—KšœG˜GKšœ ˜ Kšœœ˜KšœœœUœ˜mKšœ<˜