<> <> <> <> <<>> DIRECTORY CedarProcess USING [SetPriority, GetPriority, Priority], CifToCD USING [ReadFile], CD USING [Design, Instance], CDCells USING [IsPushedIn], CDDirectory USING [Name], CDImports USING [HasUnloadedImports], CDOps USING [TheInstance, RedrawInstance], CDSequencer USING [Command], CDSequencerExtras USING [RegisterCommand], CDToCif USING [WriteCIF], EcadOps USING [ExecuteRemoteECAD, WaitForOk, noError], FS USING [StreamOpen, Error], IO USING [STREAM], Rope USING [ROPE, Cat], TerminalIO USING [PutRope, PutRopes] ; EcadCDCmds: CEDAR PROGRAM IMPORTS CedarProcess, CifToCD, CDCells, CDDirectory, CDImports, CDOps, CDSequencerExtras, CDToCif, EcadOps, FS, Rope, TerminalIO EXPORTS EcadOps ~ BEGIN cifExt: Rope.ROPE _ ".cif"; errExt: Rope.ROPE _ ".errors.cif"; defaultRulesName: Rope.ROPE _ "VTI"; cifPerLambda: INT _ 100; flattenAtomics: BOOLEAN _ TRUE; ecadKey: ATOM _ $EcadErrorsCif; --to identify the set of cif conventions EcadDRCCmd: PROC [comm: CDSequencer.Command] ~ { <> msg: Rope.ROPE; mainInst: CD.Instance; IF CDCells.IsPushedIn[comm.design] THEN { TerminalIO.PutRope["**Design is pushed in\n"]; GOTO Exit }; IF CDImports.HasUnloadedImports[comm.design].yes THEN { TerminalIO.PutRope["**Design has non bound imports\n"]; GOTO Exit }; mainInst _ CDOps.TheInstance[comm.design, "cif generation\n"]; IF mainInst=NIL THEN { TerminalIO.PutRope["**CIF generation needs single selected object\n"]; GOTO Exit }; msg _ DRCInstance[mainInst, comm.design, defaultRulesName]; TerminalIO.PutRope[" Dracula cmd finished\n"]; EXITS Exit => {}; }; DRCInstance: PROC [instance: CD.Instance, design: CD.Design, rules: Rope.ROPE] RETURNS [msg: Rope.ROPE _ NIL] ~ { priority: CedarProcess.Priority _ CedarProcess.GetPriority[]; CedarProcess.SetPriority[background]; { topCellName, fileName: Rope.ROPE; cifFile: IO.STREAM; topCellName _ CDDirectory.Name[instance.ob, design]; IF topCellName=NIL THEN RETURN["Impossible to DRC non named objects"]; fileName _ Rope.Cat[topCellName, cifExt]; cifFile _ FS.StreamOpen[fileName, create ! FS.Error => IF error.group#bug THEN { msg _ error.explanation; CONTINUE; }]; IF msg#NIL THEN GOTO Failed; TerminalIO.PutRopes["Dracula DRC. CIF file: ", fileName, "\n"]; msg _ CDToCif.WriteCIF[design, instance, cifFile, cifPerLambda, flattenAtomics]; IF msg#NIL THEN GOTO Failed; msg _ EcadOps.ExecuteRemoteECAD[topCellName, rules]; IF msg#NIL THEN GOTO Failed; msg _ EcadOps.WaitForOk[topCellName]; IF msg#NIL THEN GOTO Failed; fileName _ Rope.Cat[topCellName, errExt]; cifFile _ FS.StreamOpen[fileName, read ! FS.Error => IF error.group#bug THEN { msg _ error.explanation; CONTINUE; }]; IF msg#NIL THEN GOTO Failed; msg _ CifToCD.ReadFile[cifFile, design, ecadKey, instance.trans]; IF msg#NIL THEN GOTO Failed; CedarProcess.SetPriority[priority]; CDOps.RedrawInstance[design, instance]; EXITS Failed => { TerminalIO.PutRope[msg]; CedarProcess.SetPriority[priority]; }; }; }; CheckDRC: PUBLIC PROC [instance: CD.Instance, design: CD.Design, rules: Rope.ROPE] RETURNS [noErrors: BOOLEAN] ~ { msg: Rope.ROPE _ DRCInstance[instance, design, rules]; RETURN[msg=EcadOps.noError]; }; CDSequencerExtras.RegisterCommand[key: $DraculaSel, proc: EcadDRCCmd, queue: doQueue]; END.