DIRECTORY CD, CDCells, CDDirectory, CDMenus, CDOps, CDSequencer, Core, CoreProperties, IO, PW, PWCore, Rope, RopeList, Sinix, SoS, Sisyph, ViewerIO, ViewerTools; LayoutSchematics: CEDAR PROGRAM IMPORTS CDCells, CDDirectory, CDMenus, CDOps, CoreProperties, IO, PW, PWCore, Rope, RopeList, Sinix, SoS, Sisyph, ViewerIO, ViewerTools = BEGIN ROPE: TYPE = Core.ROPE; CellType: TYPE = Core.CellType; Wire: TYPE = Core.Wire; WriteBold: PROC [before, bold, after: ROPE _ NIL] = { stream: IO.STREAM _ ViewerIO.CreateViewerStreams ["Terminal", ViewerTools.FindExistingViewer ["Terminal"]].out; IO.PutF[stream, "%g%l%g%l%g", IO.rope[before], IO.rope["b"], IO.rope[bold], IO.rope["B"], IO.rope[after]]; }; LayoutSchematics: PW.UserProc = { testLichen: BOOL _ PWCore.testLichen; checkAbuts: BOOL _ PWCore.checkAbuts; cx: Sisyph.Context _ Sisyph.Create[design]; selected: CD.Instance; multiple: BOOL; [selected, multiple] _ CDOps.SelectedInstance[design]; IF selected=NIL THEN {PW.WriteF["\n** No current selection --can't do it.\n"]; RETURN}; IF multiple THEN {PW.WriteF["\n** Multiple instances selected --can't do it.\n"]; RETURN}; IF NOT CDCells.IsCell[selected.ob] THEN {PW.WriteF["\n** Not a cell --can't do it.\n"]; RETURN}; IF NOT Rope.Match["*.sch", CDDirectory.Name[selected.ob]] THEN {PW.WriteF["\n** Not a schematics --can't do it.\n"]; RETURN}; PWCore.testLichen _ TRUE; PWCore.checkAbuts _ TRUE; PW.WriteF["\nGenerating layout for %g.\n", IO.rope[CDDirectory.Name[selected.ob]]]; ob _ CheckObject[design, cx, selected.ob].layout; PWCore.testLichen _ testLichen; PWCore.checkAbuts _ checkAbuts; }; CheckObject: PROC [design: CD.Design, cx: Sisyph.Context, obj: CD.Object] RETURNS [ok: BOOL _ TRUE, layout: CD.Object _ NIL] = { name: ROPE _ CDDirectory.Name[obj]; cellType: CellType _ Sisyph.ES[name, cx ! ANY => {WriteBold["Sisyph extraction fails for ", name, ".\n"]; GOTO Fails}]; IF CoreProperties.GetCellTypeProp[cellType, PWCore.layoutAtomProp]=NIL THEN { extracted: CellType; name _ Rope.Cat[Rope.Substr[name, 0, Rope.Length[name]-4], PWCore.maskSuffix]; layout _ CDDirectory.Fetch[design, name].object; IF layout=NIL THEN RETURN; extracted _ NARROW [Sinix.Extract[layout, PWCore.extractMode! ANY => {WriteBold["Sinix extraction fails for ", name, " .\n"]; GOTO Fails}].result]; PWCore.DecorateGet[cellType, layout ! ANY => {WriteBold["Comparison with schematics fails for ", name, " .\n"]; GOTO Fails}]; } ELSE layout _ PWCore.Layout[cellType ! ANY => {WriteBold["Layout generation fails for ", name, " .\n"]; GOTO Fails}]; SoS.CheckDesignRules [cellType, design , NIL, NEW [BOOL _ FALSE], FALSE, NIL, PWCore.extractMode.instanceProp, PWCore.extractMode.wireGeometryProp ! ANY => {WriteBold["DRC fails for ", name, " .\n"]; GOTO Fails}]; IF CoreProperties.GetCellTypeProp[cellType, SoS.DRVkey]#NIL THEN {WriteBold["DRC errors in cell ", name, " .\n"]; GOTO Fails}; EXITS Fails => RETURN [FALSE, layout]; }; Cat: PROC [list: LIST OF ROPE] RETURNS [catted: ROPE _ NIL] = { WHILE list#NIL DO catted _ Rope.Cat[catted, " ", list.first]; list _ list.rest ENDLOOP; }; CheckSchematics: PROC [command: CDSequencer.Command] = { testLichen: BOOL _ PWCore.testLichen; checkAbuts: BOOL _ PWCore.checkAbuts; cx: Sisyph.Context _ Sisyph.Create[command.design]; checked, notSch, notOk: LIST OF ROPE; sel, notCells: INT _ 0; PW.WriteF["Check schematics\n"]; PWCore.testLichen _ TRUE; PWCore.checkAbuts _ TRUE; FOR instances: CD.InstanceList _ CDOps.InstList[command.design], instances.rest WHILE instances#NIL DO obj: CD.Object _ instances.first.ob; name: ROPE _ CDDirectory.Name[obj]; IF NOT instances.first.selected THEN LOOP; sel _ sel + 1; IF NOT CDCells.IsCell[obj] THEN {notCells _ notCells + 1; LOOP}; IF Rope.Match[Rope.Cat["*", PWCore.maskSuffix], name] THEN { schName: ROPE _ Rope.Cat[Rope.Substr[name, 0, Rope.Length[name]-5], ".sch"]; sch: CD.Object _ CDDirectory.Fetch[command.design, schName].object; IF sch#NIL AND CDCells.IsCell[sch] THEN {name _ schName; obj _ sch}; }; IF NOT Rope.Match["*.sch", name] THEN { IF NOT RopeList.Memb[notSch, name] THEN notSch _ CONS [name, notSch]; LOOP; }; IF RopeList.Memb[checked, name] THEN LOOP; checked _ CONS [name, checked]; IF NOT CheckObject[command.design, cx, obj].ok THEN notOk _ CONS [name, notOk]; ENDLOOP; PW.WriteF["%g instances selected.", IO.int[sel]]; IF notCells#0 THEN PW.WriteF[" %g instances not cells.", IO.int[notCells]]; IF notSch#NIL THEN PW.WriteF["\n%gcells not schematics.\n", IO.rope[Cat[notSch]]]; PW.WriteF[" %g schematics checked.\n", IO.int[RopeList.Length[checked]]]; IF notOk#NIL THEN WriteBold["", Cat[notOk], " not ok.\n"]; IF notOk=NIL AND notCells=0 THEN WriteBold["", "OK", ".\n"]; PWCore.testLichen _ testLichen; PWCore.checkAbuts _ checkAbuts; }; PW.Register[LayoutSchematics, "Layout selected schematics"]; CDMenus.ImplementEntryCommand[$ProgramMenu, "Check selected Schematics", CheckSchematics]; END. φLayoutSchematics.mesa Copyright c 1984 by Xerox Corporation. All rights reversed. Created by Bertrand Serlet June 8, 1986 10:16:41 pm PDT Bertrand Serlet June 9, 1986 7:30:24 pm PDT due to a bug in TerminalIO.WriteF that does a WriteRope ΚT˜– "Cedar" stylešœ™Jšœ Οmœ1™žœ˜ZJš žœžœžœžœ-žœ˜`Jš žœžœ4žœžœ3žœ˜}Kšœžœ˜Kšœžœ˜Jšžœ)žœ&˜SJšœ1˜1Kšœ˜Kšœ˜J˜K˜—š  œžœ žœ"žœ žœžœžœ žœ žœ˜€Jšœžœ˜#Jšœžœ žœ=žœ ˜wšžœAžœžœ˜MJ˜JšœN˜NJšœ0˜0Jšžœžœžœžœ˜Jšœ žœ,žœ=žœ˜“Jšœ&žœGžœ ˜}Jšœžœ#žœ>žœ ˜w—Kšœ)žœžœžœžœžœžœIžœ0žœ ˜ΥJšžœ6žœžœ2žœ˜~Jšžœ žœžœ ˜&J˜J˜—š œžœžœžœžœžœ žœžœ˜?Jšžœžœžœ>žœ˜WJ˜J˜—š œžœ#˜8Kšœ žœ˜%Kšœ žœ˜%Kšœ3˜3Jšœžœžœžœ˜%Jšœžœ˜Jšžœ˜!Kšœžœ˜Kšœžœ˜š žœ žœ?žœ žœž˜fJšœžœ˜$Jšœžœ˜#Jšžœžœžœžœ˜*J˜Jšžœžœžœžœ˜@šžœ4žœ˜