<> <> <> <> <> <<>> <> DIRECTORY CD, CDCells, CDDirectory, CDGenerate, CDOps, CDSequencer, Core, CoreProperties, CoreGeometry, IO, PWCore, PWCoreLichen, Rope, RopeList, Sinix, --SoS,-- Sisyph, TerminalIO; LayoutSchematics: CEDAR PROGRAM IMPORTS CDCells, CDDirectory, CDGenerate, CDOps, CDSequencer, CoreProperties, IO, PWCore, PWCoreLichen, Rope, RopeList, Sinix, --SoS,-- Sisyph, TerminalIO = BEGIN ROPE: TYPE = Core.ROPE; CellType: TYPE = Core.CellType; Wire: TYPE = Core.Wire; LayoutSelectedSchematics: CDGenerate.GeneratorProc = { cx: Sisyph.Context _ Sisyph.Create[design]; selected: CD.Instance; multiple: BOOL; [selected, multiple] _ CDOps.SelectedInstance[design]; IF selected=NIL THEN {TerminalIO.PutF["\n** No current selection --can't do it.\n"]; RETURN}; IF multiple THEN {TerminalIO.PutF["\n** Multiple instances selected --can't do it.\n"]; RETURN}; IF NOT CDCells.IsCell[selected.ob] THEN {TerminalIO.PutF["\n** Not a cell --can't do it.\n"]; RETURN}; IF NOT Rope.Match["*.sch", CDDirectory.Name[selected.ob]] THEN {TerminalIO.PutF["\n** Not a schematics --can't do it.\n"]; RETURN}; TerminalIO.PutF["\nGenerating layout for %g.\n", IO.rope[CDDirectory.Name[selected.ob]]]; ob _ CheckSch[design, cx, selected.ob].layout; }; WriteBold: PROC [before, bold, after: ROPE _ NIL] = { TerminalIO.PutF["%g%l%g%l%g", IO.rope[before], IO.rope["b"], IO.rope[bold], IO.rope["B"], IO.rope[after]]; }; CheckMask: PROC [design: CD.Design, layout: CD.Object] RETURNS [ok: BOOL _ TRUE] = { name: ROPE _ CDDirectory.Name[layout]; cellType: CellType _ NARROW [Sinix.Extract[layout, PWCore.extractMode! ANY => {WriteBold["Sinix extraction fails for ", name, " .\n"]; GOTO Fails}].result]; TerminalIO.PutRope["**SOS not yet available\n"]; <> <> EXITS Fails => RETURN [FALSE]; }; CheckSch: PROC [design: CD.Design, cx: Sisyph.Context, sch: CD.Object] RETURNS [ok: BOOL _ TRUE, layout: CD.Object _ NIL] = { name: ROPE _ CDDirectory.Name[sch]; cellType: CellType _ Sisyph.ES[name, cx ! ANY => {WriteBold["Sisyph extraction fails for ", name, ".\n"]; GOTO Fails}]; IF CoreProperties.GetCellTypeProp[cellType, PWCore.layoutAtomProp]=NIL THEN { name _ Rope.Cat[Rope.Substr[name, 0, Rope.Length[name]-4], PWCore.maskSuffix]; layout _ CDDirectory.Fetch[design, name].object; IF layout=NIL THEN RETURN; PWCore.DecorateValue[cellType, layout ! ANY => {WriteBold["Decoration fails for ", name, " .\n"]; GOTO Fails}]; } ELSE layout _ PWCore.Layout[cellType ! ANY => {WriteBold["Layout generation fails for ", name, " .\n"]; GOTO Fails}]; PWCoreLichen.Compare[cellType ! ANY => {WriteBold["Comparaison with schematics fails for ", name, " .\n"]; GOTO Fails}]; ok _ CheckMask[design, layout]; 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; }; Cons: PROC [rope: ROPE, list: LIST OF ROPE] RETURNS [LIST OF ROPE] = { RETURN [IF RopeList.Memb[list, rope] THEN list ELSE CONS [rope, list]]; }; CheckSchematics: PROC [command: CDSequencer.Command] = { cx: Sisyph.Context _ Sisyph.Create[command.design]; checked, notSch, notOk: LIST OF ROPE; sel, notCells: INT _ 0; TerminalIO.PutF["Check schematics\n"]; 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}; SELECT TRUE FROM Rope.Match[Rope.Cat["*", PWCore.maskSuffix], name] => { 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] AND ~ RopeList.Memb[checked, schName] THEN { checked _ Cons[name, Cons[schName, checked]]; IF NOT CheckSch[command.design, cx, sch].ok THEN notOk _ Cons[name, Cons[schName, notOk]]; } ELSE { checked _ Cons[name, checked]; IF NOT CheckMask[command.design, obj].ok THEN notOk _ Cons[name, notOk]; }; }; Rope.Match["*.sch", name] => { IF RopeList.Memb[checked, name] THEN LOOP; checked _ Cons[name, checked]; IF NOT CheckSch[command.design, cx, obj].ok THEN notOk _ Cons[name, notOk]; }; ENDCASE => { notSch _ Cons[name, notSch]; LOOP; }; ENDLOOP; TerminalIO.PutF["%g instances selected.", IO.int[sel]]; IF notCells#0 THEN TerminalIO.PutF[" %g instances not cells.", IO.int[notCells]]; IF notSch#NIL THEN TerminalIO.PutF["\n%gcells not schematics.\n", IO.rope[Cat[notSch]]]; TerminalIO.PutF[" %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"]; }; [] _ CDGenerate.Register[context: CDGenerate.AssertContext["PatchWork"], key: "Layout selected schematics", generator: LayoutSelectedSchematics, cache: FALSE]; [] _ CDGenerate.Register[context: CDGenerate.AssertContext["USER"], key: "Layout selected schematics", generator: LayoutSelectedSchematics, cache: FALSE]; <> CDSequencer.ImplementCommand[key: $DAUserCheckSchematics, proc: CheckSchematics, queue: doQueue]; END. <<>>