<> <> <> <> <> <> <> DIRECTORY AMBridge USING [TVForSignal], BasicTime USING [GMT, Now, Period], BrineIO, CD USING [CreateDrawRef, Design, DrawProc, DrawRef, Instance, InstanceList, Layer, Number, Object, Technology], CDBasics USING [Extend, MapRect], CDCommandOps USING [DoWithResource, RegisterWithMenu], CDDirectory USING [Fetch, Name], CDErrors USING [IncludeMessage, RemoveMessages], CDIO USING [ReadDesign], CDOps USING [InstList, LayerRope, ToRope], CDProperties USING [GetDesignProp, GetObjectProp, PutDesignProp, RegisterProperty], CDSequencer USING [Command, ImplementCommand, UseAbortFlag], CDValue USING [Fetch], CDViewer USING [CreateViewer, ViewerList, ViewersOf], Commander USING [CommandProc, Register], CommandTool USING [NextArgument], Core USING [Wire], CoreClasses USING [recordCellClass, RecordCellType], CoreGeometry USING [GetObject], CoreIO, CoreOps USING [CopyWire, GetCellTypeName, GetShortWireName, PrintCellType, SetShortWireName], CoreProperties USING [GetProp, propPrint, PropPrintProc, Props, PutProp, RegisterProperty, StoreProperties], CoreView USING [debugViewer, DestroyView, GeometryView, StartIncrementalView, Viewer], CStitching USING [DumpCache], DesignRules USING [DesignRuleError, GetRuleSet, FetchRulesID, Rules], Drc USING [CheckDesignRules, CoreCell, coreInconsistent, DRV, DRVkey, ErrorRect, Layout, Tech, Wire], DrcCmosb USING [cMosBcompleteKey, cMosBsimpleKey, FlushTechCache, NewTechnology], DrcDebug USING [debug, dLog], ExtractOps USING [IsSchematic], FS USING [ComponentPositions, Error, ExpandName], IO USING [atom, card, GetID, int, PutF, PutF1, PutFR, PutFR1, RIS, ROS, rope, RopeFromROS, STREAM, time], PrincOpsUtils USING [], PrintTV USING [Print], Process USING [priorityBackground, SetPriority], Rope USING [Cat, Equal, IsEmpty, ROPE, Substr], RuntimeError USING [UNCAUGHT], SimpleMailer USING [SendMessage], Sinix USING [Extract, Mode], SinixOps USING [GetExtractMode], SinixRawCMosB USING [mode], TerminalIO USING [PutRope, PutRopes, PutF, PutF1], UserCredentials USING [Get], UserProfile USING [Boolean, CallWhenProfileChanges, ProfileChangedProc], ViewerOps USING [SetNewVersion]; DrcCommandImpl: CEDAR PROGRAM IMPORTS AMBridge, BasicTime, BrineIO, CD, CDBasics, CDCommandOps, CDDirectory, CDErrors, CDIO, CDOps, CDProperties, CDSequencer, CDValue, CDViewer, Commander, CommandTool, CoreClasses, CoreGeometry, CoreIO, CoreOps, CoreProperties, CoreView, CStitching, DesignRules, Drc, DrcCmosb, DrcDebug, ExtractOps, FS, IO, PrintTV, Process, Rope, RuntimeError, SimpleMailer, Sinix, SinixOps, SinixRawCMosB, TerminalIO, UserCredentials, UserProfile, ViewerOps ~ BEGIN OPEN DrcCmosb; ROPE: TYPE ~ Rope.ROPE; tryRaw: BOOL _ FALSE; violationsInTopCell: BOOL _ FALSE; timing: BOOL _ UserProfile.Boolean ["Genista.Timing", FALSE]; religion: BOOL _ UserProfile.Boolean ["Genista.EmulateSoS", FALSE]; failureReason: ROPE; failureTorch: REF ANY; failureSignal: UNSAFE ERROR ANY RETURNS ANY; Misc: TYPE ~ REF Stuff; Stuff: TYPE ~ RECORD [design: CD.Design, geom: Drc.Layout, inst: CD.Instance _ NIL]; TimeStamp: TYPE ~ REF Titius; Titius: TYPE ~ RECORD [caius: BasicTime.GMT]; regressionDesign: ROPE _ "[DATools]Saguaro>DragonRules.dale"; layoutViewer: CoreView.Viewer; stateHandle: Misc _ NEW [Stuff _ [NIL, SinixOps.GetExtractMode[$cmosB].decoration, NIL]]; lastCore: Drc.CoreCell _ NIL; lastKey: ATOM; status: RECORD [errors: REF CARDINAL, start: BasicTime.GMT, currentCell: REF ROPE]; comesFromCdFile: ATOM ~ CoreProperties.RegisterProperty [$DrcComesFromCdFile]; ruleKey: ATOM ~ CoreProperties.RegisterProperty [$DrcRules]; sessionKey: ATOM ~ CoreProperties.RegisterProperty [$DrcEnumerationSession]; notMe: BOOL ~NOT UserCredentials.Get[].name.Equal ["Beretta.pa", FALSE]; neverEver: ERROR [signal: SIGNAL ANY RETURNS ANY] ~ CODE; -- a signal never ever raised Execute: PROC [comm: CDSequencer.Command] ~ BEGIN <> ENABLE BEGIN Drc.coreInconsistent => BEGIN failureReason _ reason; failureTorch _ torch; GOTO failure END; neverEver --RuntimeError.UNCAUGHT-- => BEGIN TRUSTED {failureSignal _ LOOPHOLE [signal, SIGNAL ANY RETURNS ANY]}; GOTO alienFailure END END; state: Misc ~ NEW [Stuff]; abort: REF BOOL _ NEW [BOOL _ FALSE]; ExtractAndCheck: PROC [comm: CDSequencer.Command] ~ BEGIN <> startTime1, startTime2, lapTime, stopTime: BasicTime.GMT; usedRuleKey: ATOM _ DesignRules.FetchRulesID [state.design]; -- saved in Core rules: DesignRules.Rules; techE: Sinix.Mode _ SinixOps.GetExtractMode [state.design.technology]; techD: Drc.Tech; violations: CARDINAL _ 0; cDFileName: ROPE ~ NARROW [CDValue.Fetch [state.design, $CDxLastFile]]; coreFileName: ROPE; state.design.name _ BuildId [state.design.name, cDFileName, "Design"]; coreFileName _ Rope.Cat ["[]<>Temp>DRC>PreGenista>", state.design.name]; IF (techE = NIL) THEN BEGIN TerminalIO.PutRope [Rope.Cat ["The technology ", state.design.technology.name, " is not implemented in Sinix or Drc.\n"]]; RETURN END; IF tryRaw THEN techE _ SinixRawCMosB.mode; state.geom _ stateHandle.geom _ techE.decoration; rules _ DesignRules.GetRuleSet [usedRuleKey ! DesignRules.DesignRuleError => CONTINUE]; IF (rules = NIL) THEN BEGIN TerminalIO.PutRope ["The design does not specify a set of design rules. Using VTI rule set.\n"]; usedRuleKey _ $vti; rules _ DesignRules.GetRuleSet [usedRuleKey ! DesignRules.DesignRuleError => CONTINUE]; usedRuleKey _ $Vti; IF (rules = NIL) THEN rules _ DesignRules.GetRuleSet [usedRuleKey ! DesignRules.DesignRuleError => CONTINUE]; usedRuleKey _ $VTI; IF (rules = NIL) THEN rules _ DesignRules.GetRuleSet [usedRuleKey] END; techD _ DrcCmosb.NewTechnology [IF religion THEN cMosBsimpleKey ELSE cMosBcompleteKey, rules]; IF (comm.key = $DrcSelMinimal) THEN techD.verifyCell _ NIL; FOR all: CD.InstanceList _ CDOps.InstList [state.design], all.rest WHILE all # NIL DO IF all.first.selected THEN BEGIN whatTheUserMeant: ROPE _ CDDirectory.Name [all.first.ob, state.design]; rickThinksItsSchematics: BOOL ~ ExtractOps.IsSchematic [state.design, all.first.ob]; pos: FS.ComponentPositions; IF NOT whatTheUserMeant.IsEmpty THEN BEGIN [whatTheUserMeant, pos] _ FS.ExpandName [whatTheUserMeant ! FS.Error => GOTO illegalName]; whatTheUserMeant _ whatTheUserMeant.Substr [start: pos.ext.start, len: pos.ext.length]; EXITS illegalName => BEGIN TerminalIO.PutF ["\nThe name %g is illegal or a non-allowed pattern. Suggested replacement: %g.mask\n", IO.rope [whatTheUserMeant], IO.rope [BuildId [whatTheUserMeant, "Cell", "Cell"]]]; whatTheUserMeant _ NIL END END; SELECT TRUE FROM whatTheUserMeant.Equal ["mask", FALSE] => NULL; -- c'est bon whatTheUserMeant.Equal ["sch", FALSE], whatTheUserMeant.Equal ["icon", FALSE] => BEGIN TerminalIO.PutRope ["\nCells with extension and are ignored unless Rick thinks it is not schematics.\n"]; IF rickThinksItsSchematics THEN LOOP END; ENDCASE => BEGIN start: ROPE ~ UserCredentials.Get[].name.Cat [" is a user out there, who has a design ", comm.design.name, " on file ", cDFileName]; extendedName: ROPE ~ CDOps.ToRope[all.first.ob].Cat[" (the user meant ", CDDirectory.Name [all.first.ob, state.design], ")"]; IF rickThinksItsSchematics THEN BEGIN TerminalIO.PutF1 ["\nIn theory, cells without an extension are not allowed.\nIn this case, however, Rick thinks that %g is a schematics cell, so it is ignored.\n", IO.rope [extendedName]]; LOOP END; TerminalIO.PutF1 ["\nIn theory, cells without extension are not allowed.\nIn this case, however, Rick thinks that %g is not a schematics cell, so it is checked anyway.\n", IO.rope [extendedName]] <<[] _ CDErrors.IncludeMessage [design: state.design, ob: all.first.ob, rect: CDBasics.MapRect [all.first.ob.bbox, all.first.trans], message: "Cells without extension are not allowed and not checked", owner: Drc.DRVkey];>> <> END; TRUSTED {Process.SetPriority [Process.priorityBackground]}; startTime1 _ BasicTime.Now []; WITH Sinix.Extract [obj: all.first.ob, mode: techE].result SELECT FROM coreCell: Drc.CoreCell => BEGIN v: REF CARDINAL _ NIL; fakeActual: Drc.Wire ~ CoreOps.CopyWire [coreCell.public]; stamp: TimeStamp _ NEW [Titius]; lapTime _ BasicTime.Now []; lastCore _ coreCell; lastKey _ techD.checkedBy; coreCell.properties _ CoreProperties.PutProp [coreCell.properties, comesFromCdFile, cDFileName]; coreCell.properties _ CoreProperties.PutProp [coreCell.properties, ruleKey, usedRuleKey]; IF (comm.key # $DrcSel) THEN BEGIN <> compositeName: ROPE ~ coreFileName.Cat ["-", BuildId [CDDirectory.Name [all.first.ob, state.design], CDOps.ToRope [all.first.ob], "Cell"], ".Core"]; [] _ CoreIO.ReportSaveCellType [cellType: coreCell, fileName: compositeName]; TerminalIO.PutF ["\nExtraction saved on %g\n", IO.rope [compositeName]] END; FOR i: NAT IN [0 .. fakeActual.size) DO givenName: ROPE ~ CoreOps.GetShortWireName [fakeActual[i]]; fakeActual[i] _ CoreOps.SetShortWireName [fakeActual[i], IF givenName.IsEmpty THEN IO.PutFR1 ["External", IO.int [i]] ELSE givenName] ENDLOOP; IF DrcDebug.debug THEN BEGIN IF (layoutViewer # NIL) THEN CoreView.DestroyView [layoutViewer]; IF (CoreView.debugViewer # NIL) THEN CoreView.DestroyView [CoreView.debugViewer]; layoutViewer _ CoreView.GeometryView [coreCell, techE.decoration, abort]; CoreView.debugViewer _ CoreView.StartIncrementalView [coreCell, techE.decoration, abort] END; CDProperties.PutDesignProp [state.design, $DrcCoreCircularity]; -- remove IF DrcDebug.debug THEN BEGIN CoreOps.PrintCellType [coreCell, DrcDebug.dLog]; DrcDebug.dLog.PutF ["\n"]; END; status.errors _ NEW [CARDINAL _ 0]; status.currentCell _ NEW [ROPE]; status.start _ startTime2 _ BasicTime.Now[]; violations _ Drc.CheckDesignRules [cell: coreCell, external: fakeActual, viaFlatness: (comm.key = $DrcSel), tech: techD, stopFlag: abort, lap: status.errors, currentCell: status.currentCell, layout: state.geom]; stopTime _ BasicTime.Now []; IF timing THEN TerminalIO.PutF [ format: "\nNumber of new design violations found: %l%g%l\n", v1: IO.rope ["b"], v2: IO.card [violations], v3: IO.rope ["B"]]; IF DrcDebug.debug THEN VerifyObjects [state.design, all.first.ob]; IF timing THEN BEGIN TerminalIO.PutF1 ["\nElapsed time for extraction: %g", IO.rope [TimeToRope [startTime1, lapTime]]]; TerminalIO.PutF1 ["\nElapsed time for DRC: %g", IO.rope [TimeToRope [startTime2, stopTime]]]; TerminalIO.PutF1 ["\nTotal elapsed time: %g\n", IO.rope [TimeToRope [startTime1, stopTime]]] END; IF (violations > 0) THEN v _ NEW [CARDINAL _ violations]; CDProperties.PutDesignProp [state.design, $DrcNr, v]; CDProperties.PutDesignProp [state.design, $DrcCoreCircularity, coreCell]; -- a circularity, but I do not have a better idea at the moment CStitching.DumpCache []; stamp.caius _ BasicTime.Now []; IF (violations > 0) THEN BEGIN <> FOR vl: CDViewer.ViewerList _ CDViewer.ViewersOf [state.design], vl.rest WHILE vl # NIL DO ViewerOps.SetNewVersion [vl.first] ENDLOOP END; state.inst _ all.first; IF violationsInTopCell THEN CDErrors.RemoveMessages [design: state.design, ob: state.inst.ob, owner: Drc.DRVkey]; EnumerateCore [coreCell, BackAnnotation, stamp, state, abort]; status.errors _ NIL; status.currentCell _ NIL END; w: Core.Wire => ERROR; ENDCASE => NULL -- e.g., cell contains text or schematics END -- if selected ENDLOOP END; -- ExtractAndCheck TerminalIO.PutF1 ["DRC (Genista). %g\n", IO.rope [SELECT comm.key FROM $DrcSel => "Verify all rules.", $DrcSelVia => "Do not verify via flatness rules.", $DrcSelMinimal => "Do not verify via flatness nor well rules.", ENDCASE => "There is an implementation error"]]; state.design _ comm.design; CDSequencer.UseAbortFlag [state.design, abort]; [] _ CDCommandOps.DoWithResource [ExtractAndCheck, comm, $Drc]; TerminalIO.PutRope ["Drc done.\n"]; EXITS failure => BEGIN TerminalIO.PutRopes [failureReason, ". Core structure inconsistent. DRC aborted.\n"] END; alienFailure => TRUSTED BEGIN msg: ROPE; ros: IO.STREAM ~ IO.ROS []; lastCore.properties _ CoreProperties.PutProp [lastCore.properties, lastKey, NIL]; PrintTV.Print [tv: AMBridge.TVForSignal [failureSignal], put: ros, verbose: TRUE]; msg _ ros.RopeFromROS []; TerminalIO.PutRopes [msg, "\n\t*** Session miscarried ***\n"]; IF notMe THEN [] _ SimpleMailer.SendMessage [from: "Genista", to: LIST ["Beretta.PA"], subject: "Crash", body: msg] ELSE ERROR END END; -- Execute EachCell: TYPE ~ PROC [cell: Drc.CoreCell, data: REF ANY _ NIL]; EnumerateCore: PROC [cell: Drc.CoreCell, action: EachCell, session: TimeStamp, data: REF ANY _ NIL, stopFlag: REF BOOL] ~ BEGIN <> IF (session # NIL) THEN BEGIN visited: TimeStamp ~ NARROW [CoreProperties.GetProp [cell.properties, sessionKey], TimeStamp]; IF (visited = NIL) OR (session.caius # visited.caius) THEN cell.properties _ CoreProperties.PutProp [cell.properties, sessionKey, session] ELSE RETURN END; SELECT cell.class FROM CoreClasses.recordCellClass => BEGIN cellData: CoreClasses.RecordCellType ~ NARROW [cell.data]; FOR sub: NAT IN [0 .. cellData.size) DO IF stopFlag^ THEN ERROR ABORTED; EnumerateCore [cellData.instances[sub].type, action, session, data, stopFlag] ENDLOOP; action [cell, data] END; ENDCASE => NULL END; -- EnumerateCore BackAnnotation: EachCell ~ BEGIN <<[cell: Drc.CoreCell, data: REF ANY _ NIL]>> <> state: Misc ~ NARROW [data]; cdCell: CD.Object ~ CoreGeometry.GetObject [state.geom, cell]; drv: Drc.DRV ~ NARROW [CoreProperties.GetProp [cell.properties, Drc.DRVkey]]; IF NOT violationsInTopCell THEN CDErrors.RemoveMessages [design: state.design, ob: cdCell, owner: Drc.DRVkey]; IF (drv # NIL) THEN FOR v: LIST OF Drc.ErrorRect _ drv.places, v.rest WHILE v # NIL DO IF violationsInTopCell THEN [] _ CDErrors.IncludeMessage [design: state.design, ob: state.inst.ob, rect: CDBasics.MapRect [CDBasics.Extend [v.first.r, 4], state.inst.trans], message: v.first.msg, owner: Drc.DRVkey] ELSE [] _ CDErrors.IncludeMessage [design: state.design, ob: cdCell, rect: CDBasics.Extend [v.first.r, 4], message: v.first.msg, owner: Drc.DRVkey] ENDLOOP END; -- BackAnnotation ProblemMessage: EachCell ~ BEGIN <<[cell: Drc.CoreCell, data: REF ANY _ NIL]>> <> state: Misc ~ NARROW [data]; cdCell: CD.Object ~ CoreGeometry.GetObject [state.geom, cell]; IF (CoreProperties.GetProp [cell.properties, Drc.DRVkey] # NIL) THEN BEGIN TerminalIO.PutRopes [CDDirectory.Name [cdCell, state.design], " is not verified correctly ("]; TerminalIO.PutRopes [NARROW [CDProperties.GetObjectProp [cdCell, $rule], ROPE], ")\n"] END END; -- ProblemMessage UncheckedMessage: EachCell ~ BEGIN <<[cell: Drc.CoreCell, data: REF ANY _ NIL]>> <> state: Misc ~ NARROW [data]; cdCell: CD.Object ~ CoreGeometry.GetObject [state.geom, cell]; drv: Drc.DRV ~ NARROW [CoreProperties.GetProp [cell.properties, Drc.DRVkey]]; IF (drv = NIL) OR (drv.count # 1) THEN BEGIN description: ROPE ~ NARROW [CDProperties.GetObjectProp [cdCell, $rule]]; flat: BOOL ~ (CDProperties.GetObjectProp [cdCell, $flat] # NIL); IF flat THEN TerminalIO.PutF ["%g is verified flat (%g)\n", IO.rope [CDDirectory.Name [cdCell, state.design]], IO.rope [description]] ELSE TerminalIO.PutF ["%g is not verified correctly (%g)\n", IO.rope [CDDirectory.Name [cdCell, state.design]], IO.rope [description]] END END; -- UncheckedMessage Repeal: EachCell ~ BEGIN <<[cell: Drc.CoreCell, data: REF ANY _ NIL]>> cell.properties _ CoreProperties.PutProp [cell.properties, lastKey]; cell.properties _ CoreProperties.PutProp [cell.properties, Drc.DRVkey] END; -- Repeal RemoveCdErrors: PROC [comm: CDSequencer.Command] ~ BEGIN <> TerminalIO.PutRope ["Removing Genista's error rectangles from selected cells.\n"]; FOR all: CD.InstanceList _ CDOps.InstList [comm.design], all.rest WHILE all # NIL DO IF all.first.selected THEN CDErrors.RemoveMessages [design: comm.design, ob: all.first.ob, owner: Drc.DRVkey] ENDLOOP END; -- RemoveCdErrors List: PROC [comm: CDSequencer.Command] ~ BEGIN <> violations: REF CARDINAL ~ NARROW [CDProperties.GetDesignProp [comm.design, $DrcNr]]; IF (violations = NIL) THEN TerminalIO.PutRope ["No new violations found last time.\n"] ELSE TerminalIO.PutF1 ["Number of design rule violations found last time: %g\n", IO.card[violations^]]; END; -- List PrintDRV: EachCell ~ BEGIN <<[cell: Drc.CoreCell, data: REF ANY _ NIL]>> drv: Drc.DRV ~ NARROW [CoreProperties.GetProp [cell.properties, Drc.DRVkey]]; IF (drv # NIL) THEN BEGIN cellName: ROPE ~ CoreOps.GetCellTypeName [cell]; l: CD.Number ~ NARROW [data, CD.Technology].lambda; TerminalIO.PutF ["\ncell %g, %g violations:\n", IO.rope [cellName], IO.int [drv.count]]; FOR e: LIST OF Drc.ErrorRect _ drv.places, e.rest WHILE e # NIL DO TerminalIO.PutF ["%g at [(%g, %g); (%g, %g)] \n", IO.rope [e.first.msg], IO.int [e.first.r.x1/l], IO.int [e.first.r.y1/l], IO.int [e.first.r.x2/l], IO.int [e.first.r.y2/l]] ENDLOOP END END; -- PrintDRV ListAll: PROC [comm: CDSequencer.Command] ~ BEGIN <> coreCell: Drc.CoreCell ~ NARROW [CDProperties.GetDesignProp [comm.design, $DrcCoreCircularity]]; abort: REF BOOL _ NEW [BOOL _ FALSE]; stamp: TimeStamp _ NEW [Titius]; ListDRV: PROC [comm: CDSequencer.Command] ~ BEGIN <> EnumerateCore [coreCell, PrintDRV, stamp, comm.design.technology, abort] END; -- ListDRV TerminalIO.PutRope ["Design rule violations stored in Core:\n"]; CDSequencer.UseAbortFlag [comm.design, abort]; stamp.caius _ BasicTime.Now []; IF (coreCell = NIL) THEN TerminalIO.PutRope ["None recorded.\n"] ELSE [] _ CDCommandOps.DoWithResource [ListDRV, comm, $Drc] END; -- ListAll RegressionTest: PROC ~ BEGIN <> state: Misc ~ NEW [Stuff]; dummy: REF BOOL ~ NEW [BOOL _ FALSE]; test: CD.Design ~ CDIO.ReadDesign [regressionDesign]; usedRuleKey: ATOM; rules: DesignRules.Rules; techE: Sinix.Mode; techD: Drc.Tech; ok, ko: CD.Object; IF (test = NIL) THEN GOTO maintenanceProblem; techE _ SinixOps.GetExtractMode [test.technology]; usedRuleKey _ DesignRules.FetchRulesID [test]; IF (usedRuleKey = NIL) THEN usedRuleKey _ $Dragon; rules _ DesignRules.GetRuleSet [usedRuleKey]; techD _ DrcCmosb.NewTechnology [IF religion THEN cMosBsimpleKey ELSE cMosBcompleteKey, rules]; IF (techD = NIL) THEN GOTO maintenanceProblem; state.geom _ techE.decoration; ok _ CDDirectory.Fetch [test, "ok.mask"].object; IF (ok = NIL) THEN GOTO maintenanceProblem; TerminalIO.PutRope ["\n"]; WITH Sinix.Extract [obj: ok, mode: techE].result SELECT FROM coreCell: Drc.CoreCell => BEGIN status.errors _ NEW [CARDINAL _ 0]; status.start _ BasicTime.Now []; status.currentCell _ NEW [ROPE]; IF (Drc.CheckDesignRules [cell: coreCell, tech: techD, viaFlatness: TRUE, external: coreCell.public, stopFlag: dummy, lap: status.errors, currentCell: status.currentCell, layout: state.geom] > 0) THEN EnumerateCore [coreCell, ProblemMessage, NIL, state, dummy] END; ENDCASE => ERROR; TerminalIO.PutRope ["\n"]; ko _ CDDirectory.Fetch [test, "ko.mask"].object; IF (ko = NIL) THEN GOTO maintenanceProblem; WITH Sinix.Extract [obj: ko, mode: techE].result SELECT FROM coreCell: Drc.CoreCell => BEGIN status.errors _ NEW [CARDINAL _ 0]; status.start _ BasicTime.Now []; status.currentCell _ NEW [ROPE]; [] _ Drc.CheckDesignRules [cell: coreCell, tech: techD, viaFlatness: TRUE, external: coreCell.public, stopFlag: dummy, lap: status.errors, currentCell: status.currentCell, layout: state.geom]; EnumerateCore [coreCell, UncheckedMessage, NIL, state, dummy] END; ENDCASE => ERROR; status.errors _ NIL; status.currentCell _ NIL; EXITS maintenanceProblem => BEGIN TerminalIO.PutRope ["Please inform DRC maintainers that the self verification is broken.\n"] END END; -- RegressionTest VerifyRect: CD.DrawProc ~ BEGIN << [pr: CD.DrawRef, ob: CD.Object, trans: CD.Transformation_[], readOnlyInstProps: CD.PropList_NIL]>> specialLayers: CD.Layer = 5; -- combined, highLightShade, highLightError, pinRepresentation lambda: CD.Number ~ pr.design.technology.lambda; IF (ob.class.objectType = $Rect) AND (ob.layer >= specialLayers) AND (CDProperties.GetObjectProp [ob, $DrcTrace] = NIL) THEN DrcDebug.dLog.PutF [format: "Failed to check rectangle at [%g, %g] %l %g%l\n", v1: IO.int [trans.off.x / lambda], v2: IO.int [trans.off.y / lambda], v3: IO.rope ["b"], v4: IO.rope [CDOps.LayerRope[ob.layer]], v5: IO.rope ["B"]] END; -- VerifyRect VerifyObjects: PROC [design: CD.Design, obj: CD.Object] ~ BEGIN <> drawRef: CD.DrawRef _ CD.CreateDrawRef [[design: design]]; drawRef.drawChild _ VerifyRect; obj.class.drawMe [drawRef, obj] END; -- VerifyObjects EmulateSoS: UserProfile.ProfileChangedProc ~ BEGIN religion _ UserProfile.Boolean ["Genista.EmulateSoS", FALSE] END; -- EmulateSoS Timing: UserProfile.ProfileChangedProc ~ BEGIN timing _ UserProfile.Boolean ["Genista.Timing", FALSE] END; -- Timing RedoDrc: Commander.CommandProc ~ BEGIN <<[cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL]>> fileName: ROPE ~ CommandTool.NextArgument [cmd]; usedRules: ATOM; IF fileName.IsEmpty THEN RETURN [$Failure, "Please specify a full path file name, such as []<>Temp>DRC>PreGenista>designName"]; lastCore _ CoreIO.RestoreCellType [fileName]; IF (lastCore = NIL) THEN RETURN [$Failure, "There is no Core data structure with this name (specify a full name, like []<>Temp>DRC>PreGenista>designName)"]; usedRules _ NARROW [CoreProperties.GetProp [lastCore.properties, ruleKey], ATOM]; IF (usedRules = NIL) THEN RETURN [$Failure, "The Core data structure does not specify a design rule set."]; BEGIN violations: CARDINAL _ 0; rules: DesignRules.Rules _ DesignRules.GetRuleSet [usedRules]; fakeActual: Drc.Wire ~ CoreOps.CopyWire [lastCore.public]; techD: Drc.Tech _ DrcCmosb.NewTechnology [cMosBcompleteKey, rules]; startTime: BasicTime.GMT; cDFileName: ROPE ~ NARROW [CoreProperties.GetProp [lastCore.properties, comesFromCdFile]]; IF NOT (CommandTool.NextArgument[cmd].Equal ["wells", FALSE]) THEN techD.verifyCell _ NIL; lastCore _ lastCore.class.recast [lastCore]; FOR i: NAT IN [0 .. fakeActual.size) DO givenName: ROPE ~ CoreOps.GetShortWireName [fakeActual[i]]; fakeActual[i] _ CoreOps.SetShortWireName [fakeActual[i], IF givenName.IsEmpty THEN IO.PutFR1 ["External", IO.int [i]] ELSE givenName] ENDLOOP; status.errors _ NEW [CARDINAL _ 0]; status.start _ startTime _ BasicTime.Now []; status.currentCell _ NEW [ROPE]; [] _ Drc.CheckDesignRules [cell: lastCore, external: fakeActual, tech: techD, layout: stateHandle.geom, stopFlag: NIL, lap: status.errors, currentCell: status.currentCell]; msg _ Rope.Cat ["Elapsed time for DRC: ", TimeToRope [startTime, BasicTime.Now []]]; CStitching.DumpCache []; IF NOT cDFileName.IsEmpty THEN BEGIN abort: REF BOOL _ NEW [BOOL _ FALSE]; stateHandle.design _ CDIO.ReadDesign [cDFileName]; IF (stateHandle.design # NIL) THEN BEGIN stamp: TimeStamp _ NEW [Titius]; stamp.caius _ BasicTime.Now []; EnumerateCore [lastCore, BackAnnotation, stamp, stateHandle, abort]; [] _ CDViewer.CreateViewer [design: stateHandle.design] END END; status.errors _ NIL; status.currentCell _ NIL; END END; -- RedoDrc Hack: PROC ~ BEGIN <> CDCommandOps.RegisterWithMenu [menu: $DRCMenu, entry: "Small input DRC (Genista)", key: $DrcSel, proc: Execute, queue: doQueue]; CDCommandOps.RegisterWithMenu [menu: $DRCMenu, entry: "Large input DRC (Genista)", key: $DrcSelVia, proc: Execute, queue: doQueue]; CDCommandOps.RegisterWithMenu [menu: $DRCMenu, entry: "Minimal DRC (Genista)", key: $DrcSelMinimal, proc: Execute, queue: doQueue]; CDCommandOps.RegisterWithMenu [menu: $DRCMenu, entry: "List violations (Genista)", key: $DrcAll, proc: ListAll, queue: doQueue]; CDCommandOps.RegisterWithMenu [menu: $DRCMenu, entry: "Violation count (Genista)", key: $DrcDir, proc: List, queue: doQueue]; CDCommandOps.RegisterWithMenu [menu: $DRCMenu, entry: "Remove error rects (Genista)", key: $DrcRemove, proc: RemoveCdErrors, queue: doQueue] <> <> <> <> END; -- Hack StatusReport: Commander.CommandProc ~ BEGIN <<[cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL]>> IF (status.errors = NIL) THEN msg _ "Drc is idle." ELSE BEGIN msg _ IO.PutFR ["Last drc started %g\nelapsed time: %g,\nworking on: %g\nproblems found so far: %g.", IO.time [status.start], IO.rope [TimeToRope [status.start, BasicTime.Now[]]], IO.rope [status.currentCell^], IO.card [status.errors^]] END END; -- StatusReport RepealDrcFlags: Commander.CommandProc ~ BEGIN <<[cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL]>> IF (lastCore = NIL) THEN msg _ "There is no Core data structure" ELSE BEGIN abort: REF BOOL ~ NEW [BOOL _ FALSE]; EnumerateCore [lastCore, Repeal, NIL, , abort]; msg _ "Design rule violations stored in Core repealed" END END; -- RepealDrcFlags BuildId: PROC [pretendent, alternative, ifAllFails: ROPE] RETURNS [id: ROPE] ~ BEGIN <> ifAllFails _ IO.GetID [IO.RIS [ifAllFails] ! RuntimeError.UNCAUGHT => {ifAllFails _ "Foo"; CONTINUE}]; alternative _ IO.GetID [IO.RIS [alternative] ! RuntimeError.UNCAUGHT => {alternative _ ifAllFails; CONTINUE}]; id _ IO.GetID [IO.RIS [pretendent] ! RuntimeError.UNCAUGHT => {id _ IO.GetID [IO.RIS [UserCredentials.Get[].name]].Cat ["-", alternative]; CONTINUE}] END; -- BuildId TimeToRope: PROC [from, to: BasicTime.GMT] RETURNS [time: ROPE] ~ BEGIN <> TwoPosInt: PROC [i: INT] RETURNS [ROPE] ~ BEGIN RETURN [SELECT i FROM = 0 => "00", < 10 => Rope.Cat ["0", IO.PutFR1 [value: IO.int [i]]], ENDCASE => IO.PutFR1 [value: IO.int [i]]] END; sec: INT _ BasicTime.Period [from, to]; min: INT _ sec / 60; h: INT ~ min / 60; min _ min MOD 60; sec _ sec MOD 60; RETURN [TwoPosInt[h].Cat [":", TwoPosInt[min], ":", TwoPosInt[sec]]] END; -- TimeToRope PrintCdFileName: CoreProperties.PropPrintProc ~ BEGIN to.PutF1 [format: "Cell extracted from %g. ", value: IO.rope [NARROW[val,ROPE]]] END; -- PrintCdFileName RopeReadWrapping: CoreIO.PropReadProc ~ BEGIN RETURN [BrineIO.ReadRope [stream]] END; -- RopeReadWrapping RopeWriteWrapping: CoreIO.PropWriteProc ~ BEGIN BrineIO.WriteRope [stream, NARROW [value, ROPE]] END; -- RopeWriteWrapping PrintRuleKey: CoreProperties.PropPrintProc ~ BEGIN to.PutF1 [format: "Design rules: %g. ", value: IO.atom [NARROW[val,ATOM]]] END; -- PrintRuleKey AtomReadWrapping: CoreIO.PropReadProc ~ BEGIN RETURN [BrineIO.ReadAtom [stream]] END; -- AtomReadWrapping AtomWriteWrapping: CoreIO.PropWriteProc ~ BEGIN BrineIO.WriteAtom [stream, NARROW [value, ATOM]] END; -- AtomWriteWrapping Registrations: PROC ~ BEGIN IF NOT CDProperties.RegisterProperty [$DrcNr, $gbb] THEN DrcCmosb.FlushTechCache; [] _ CDProperties.RegisterProperty [$DrcCoreCircularity, $gbb]; CoreProperties.StoreProperties [prop: comesFromCdFile, properties: CoreProperties.Props [[CoreProperties.propPrint, NEW [CoreProperties.PropPrintProc _ PrintCdFileName]]]]; [] _ CoreIO.RegisterProperty [prop: comesFromCdFile, write: RopeWriteWrapping, read: RopeReadWrapping]; CoreProperties.StoreProperties [prop: ruleKey, properties: CoreProperties.Props [[CoreProperties.propPrint, NEW [CoreProperties.PropPrintProc _ PrintRuleKey]]]]; [] _ CoreIO.RegisterProperty [prop: ruleKey, write: AtomWriteWrapping, read: AtomReadWrapping]; CDSequencer.ImplementCommand [key: $DrcSel, proc: Execute, queue: doQueue]; CDSequencer.ImplementCommand [key: $DrcSelVia, proc: Execute, queue: doQueue]; CDSequencer.ImplementCommand [key: $DrcSelMinimal, proc: Execute, queue: doQueue]; CDSequencer.ImplementCommand [key: $DrcAll, proc: ListAll, queue: doQueue]; CDSequencer.ImplementCommand [key: $DrcDir, proc: List, queue: doQueue]; CDSequencer.ImplementCommand [key: $DrcRemove, proc: RemoveCdErrors, queue: doQueue]; Commander.Register [key: "DrcRepeal", proc: RepealDrcFlags, doc: "undoes last DRC by Genista"]; Commander.Register [key: "DrcEmpty", proc: RepealDrcFlags, doc: "undoes last DRC by Genista"]; Commander.Register [key: "DrcRedo", proc: RedoDrc, doc: "runs Genista on a Core file. Typical file names are of the form []<>Temp>DRC>PreGenista>designName"]; Commander.Register [key: "DrcCdCmosB", proc: RedoDrc, doc: "runs Genista on a Core file. Typical file names are of the form []<>Temp>DRC>PreGenista>designName"]; Commander.Register [key: "DrcStatus", proc: StatusReport, doc: "reports the current status of the drc"]; UserProfile.CallWhenProfileChanges [EmulateSoS]; UserProfile.CallWhenProfileChanges [Timing] END; -- Registrations Registrations; IF DrcDebug.debug THEN Hack; TerminalIO.PutRope ["DRC package Genista installed.\n"]; IF UserProfile.Boolean ["Genista.RegressionTest", FALSE] THEN RegressionTest END. <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> From: Barth.pa Subject: Bad Guy To: Beretta Reply-To: Barth Extract.df has an interface, ExtractOps, which has a routine, IsSchematic which given an object decides if it is a schematic cell. The current heuristic is fairly stupid but please change Genista to use it so that these bad guy messages stop coming. We can improve the heuristic, e.g. by looking at the name, as people complain. You should probably emit a warning message on TerminalIO saying that the cell has not been checked. Rick <> <> <> <>