DIRECTORY Basics USING [CompareCard, Comparison], BasicTime USING [GMT, Now, Period], CD USING [Object, Orientation, Transformation], CDBasics USING [DecomposeOrient], CDOps USING [ToRope], Checksum USING [ComputeChecksum], Core USING [Wire], DrcDebug USING [debug, dLog, PrintWire], IO, -- debugging only PrincOpsUtils USING [], RefTab USING [Create, Delete, EachPairAction, Erase, Fetch, GetSize, Insert, Key, Pairs, Store, Ref, Val], Rope USING [ROPE], TNT USING []; TNTImpl: CEDAR PROGRAM IMPORTS Basics, BasicTime, CDBasics, CDOps, Checksum, DrcDebug, RefTab, IO EXPORTS TNT ~ BEGIN TNT: PUBLIC TYPE ~ REF TNTRep; -- The Neighbourhood Ref TNTRep: PUBLIC TYPE ~ RECORD [table: RefTab.Ref, lastSweep: BasicTime.GMT]; TNTkey: TYPE ~ REF TNTkeyRep; TNTkeyRep: TYPE ~ RECORD [cell1, cell2: CD.Object, relPos: CD.Transformation]; TNTdata: TYPE ~ REF TNTdataRep; TNTdataRep: TYPE ~ RECORD [neverAccessed: BOOL _ TRUE, actual1, actual2: Core.Wire]; TNTrecord: TYPE ~ RECORD [k: TNTkey, d: TNTdata]; TNTsize: NAT ~ 31991; -- 10007, 21383, 22307 TNThighWaterMark: NAT = (TNTsize / 3) * 2; -- optimization sweepInterval: INT ~ 25200; -- in seconds Hash: PROC [k: RefTab.Key] RETURNS [CARDINAL] ~ BEGIN TRUSTED {RETURN [Checksum.ComputeChecksum [0, SIZE [TNTkeyRep], LOOPHOLE [k]]]} END; -- Hash Match: PROC [key1, key2: RefTab.Key] RETURNS [BOOL] ~ BEGIN k1: TNTkey ~ NARROW [key1, TNTkey]; k2: TNTkey = NARROW [key2, TNTkey]; RETURN [(k1^ = k2^)] END; -- Match InitTNT: PUBLIC PROC RETURNS [t: TNT] ~ BEGIN t _ NEW [TNTRep _ [table: RefTab.Create [TNTsize, Match, Hash], lastSweep: BasicTime.Now []]]; END; -- InitTNT BlowTNT: PUBLIC PROC [t: TNT] ~ BEGIN t.table.Erase; t _ NIL END; -- BlowTNT BuildTNTrecord: PROC [o1, o2: CD.Object, t1, t2: CD.Transformation, a1, a2: Core.Wire] RETURNS [rec: TNTrecord] ~ BEGIN order: Basics.Comparison; rec.k _ NEW [TNTkeyRep]; rec.d _ NEW [TNTdataRep]; TRUSTED {order _ Basics.CompareCard [LOOPHOLE[o1], LOOPHOLE[o2]]}; IF order = greater THEN BEGIN oZ: CD.Object = o1; tZ: CD.Transformation = t1; aZ: Core.Wire = a1; o1 _ o2; o2 _ oZ; t1 _ t2; t2 _ tZ; a1 _ a2; a2 _ aZ END; rec.k.cell1 _ o1; rec.k.cell2 _ o2; rec.k.relPos _ [[t2.off.x - t1.off.x, t2.off.y - t1.off.y], CDBasics.DecomposeOrient [t1.orient, t2.orient]]; rec.d.actual1 _ a1; rec.d.actual2 _ a2 END; -- BuildTNTrecord RememberTNT: PUBLIC PROC [t: TNT, o1, o2: CD.Object, t1, t2: CD.Transformation, a1, a2: Core.Wire] ~ BEGIN rec: TNTrecord ~ BuildTNTrecord [o1, o2, t1, t2, a1, a2]; [] _ t.table.Insert [rec.k, rec.d] END; -- Remember InTNT: PUBLIC PROC [t: TNT, o1, o2: CD.Object, t1, t2: CD.Transformation, a1, a2: Core.Wire] RETURNS [BOOL] ~ BEGIN rec: TNTrecord ~ BuildTNTrecord [o1, o2, t1, t2, a1, a2]; isThere: BOOL; rawData: RefTab.Val; data: TNTdata; SameSignals: PROC RETURNS [BOOL] ~ INLINE BEGIN IF (data.actual1.size # rec.d.actual1.size) OR (data.actual2.size # rec.d.actual2.size) THEN RETURN [FALSE]; FOR i: NAT IN [0 .. rec.d.actual1.size) DO IF (rec.d.actual1[i] # data.actual1[i]) THEN RETURN [FALSE] ENDLOOP; FOR i: NAT IN [0 .. rec.d.actual2.size) DO IF (rec.d.actual2[i] # data.actual2[i]) THEN RETURN [FALSE] ENDLOOP; RETURN [TRUE] END; -- SameSignals [found: isThere, val: rawData] _ t.table.Fetch [rec.k]; data _ NARROW [rawData, TNTdata]; IF DrcDebug.debug AND isThere AND NOT SameSignals [] THEN BEGIN DrcDebug.dLog.Put1 [IO.rope ["Same key, but different signals:\n"]]; [] _ PrintEltLong [rec.k, rec.d]; [] _ PrintEltLong [rec.k, data] END; isThere _ isThere AND SameSignals []; IF isThere THEN data.neverAccessed _ FALSE; RETURN [isThere] END; -- InTNT UpdateTNT: PUBLIC PROC [t: TNT, o1, o2: CD.Object, t1, t2: CD.Transformation, a1, a2: Core.Wire] RETURNS [wasThere: BOOL] ~ BEGIN rec: TNTrecord ~ BuildTNTrecord [o1, o2, t1, t2, a1, a2]; rawData: RefTab.Val; data: TNTdata; SameSignals: PROC RETURNS [BOOL] ~ INLINE BEGIN IF (data.actual1.size # rec.d.actual1.size) OR (data.actual2.size # rec.d.actual2.size) THEN RETURN [FALSE]; FOR i: NAT IN [0 .. rec.d.actual1.size) DO IF (rec.d.actual1[i] # data.actual1[i]) THEN RETURN [FALSE] ENDLOOP; FOR i: NAT IN [0 .. rec.d.actual2.size) DO IF (rec.d.actual2[i] # data.actual2[i]) THEN RETURN [FALSE] ENDLOOP; RETURN [TRUE] END; -- SameSignals [found: wasThere, val: rawData] _ t.table.Fetch [rec.k]; data _ NARROW [rawData, TNTdata]; wasThere _ wasThere AND SameSignals []; IF wasThere THEN data.neverAccessed _ FALSE ELSE [] _ t.table.Store [rec.k, rec.d] END; -- UpdateTNT SweepTNT: PUBLIC PROC [t: TNT] ~ BEGIN RemoveCadavers: RefTab.EachPairAction ~ BEGIN IF NARROW [val, TNTdata].neverAccessed THEN [] _ t.table.Delete [key] END; -- RemoveCadavers IF (BasicTime.Period[t.lastSweep,BasicTime.Now[]] > sweepInterval) AND (t.table.GetSize > TNThighWaterMark) THEN {[] _ t.table.Pairs [RemoveCadavers]; t.lastSweep _ BasicTime.Now []} END; -- SweepTNT rot: ARRAY CD.Orientation OF Rope.ROPE ~ [original: "0", mirrorX: "x", rotate90: "90", rotate90X: "90x", rotate180: "180", rotate180X: "180x", rotate270: "-90", rotate270X: "-90x"]; PrintEltShort: RefTab.EachPairAction ~ BEGIN k: TNTkey ~ NARROW [key, TNTkey]; data: TNTdata ~ NARROW [val, TNTdata]; DrcDebug.dLog.PutF ["Key: %g, %g; %g, (%g, %g).\n", IO.card[LOOPHOLE[k.cell1]], IO.card[LOOPHOLE[k.cell2]], IO.rope[rot[k.relPos.orient]], IO.int[k.relPos.off.x], IO.int[k.relPos.off.y]]; FOR i: NAT IN [0 .. data.actual1.size) DO DrcDebug.dLog.Put [IO.card[LOOPHOLE[data.actual1[i]]], IO.char[' ]] ENDLOOP; DrcDebug.dLog.Put1 [IO.char['\n]]; FOR i: NAT IN [0 .. data.actual2.size) DO DrcDebug.dLog.Put [IO.card[LOOPHOLE[data.actual2[i]]], IO.char[' ]] ENDLOOP; DrcDebug.dLog.Put1 [IO.char['\n]] END; -- PrintEltShort PrintEltLong: RefTab.EachPairAction ~ BEGIN k: TNTkey = NARROW [key, TNTkey]; data: TNTdata = NARROW [val, TNTdata]; DrcDebug.dLog.PutF ["Key: %g, %g; %g, (%g, %g) ", IO.card[LOOPHOLE[k.cell1]], IO.card[LOOPHOLE[k.cell2]], IO.rope[rot[k.relPos.orient]], IO.int[k.relPos.off.x], IO.int[k.relPos.off.y]]; DrcDebug.dLog.PutF ["[CD objects: <%g>, <%g>].\n", IO.rope[CDOps.ToRope[k.cell1]], IO.rope[CDOps.ToRope[k.cell2]]]; DrcDebug.PrintWire [data.actual1]; DrcDebug.PrintWire [data.actual2]; DrcDebug.dLog.Put1 [IO.char['\n]] END; -- PrintEltLong PrintTNTLong: PROC [t: TNT] ~ BEGIN DrcDebug.dLog.PutRope ["\nNeighbourhood Ref:\n"]; [] _ RefTab.Pairs [t.table, PrintEltLong] END; -- PrintTNT END. @TNTImpl.mesa Copyright Σ 1985, 1987 by Xerox Corporation. All rights reserved. Giordano Bruno Beretta, October 17, 1985 4:37:14 pm PDT gbb June 4, 1987 12:58:38 pm PDT Implements The Neighbourhood Ref for Genista. Gli uomini vollero piuttosto le tenebre che la luce (Giovanni, III, 19.) The neighbourhood table Different wires may point to the same sequence of elements. [Se dovesse essere che la medesima configurazione si ripetesse spesso con differenti segnali, occorrerebbe mettere due campi contenenti i fili xorati.] PROC [Key] RETURNS [CARDINAL] RefTab.EqualProc To be called for each design rule check. To be called after each design rule check. Save a look-up. Puts the two objects in the neighbourhood table. Asserts that a combination of two cells was already checked. Asserts that a combination of two cells was already checked. The new combination is remembered. If the neighbourhood table is almost full and sufficient time has elapsed, the entries never accessed are removed from the table. To be called periodically by the main Core traversal mechanism. This procedure must be fast as a bullet, so do not put in additional stuff. PROC [key: Key, val: Val] RETURNS [quit: BOOLEAN _ FALSE] Debugging [key: Key, val: Val] RETURNS [quit: BOOLEAN _ FALSE] [key: Key, val: Val] RETURNS [quit: BOOLEAN _ FALSE] For debugging. Κr˜codešœ ™ KšœB™BKšœ7™7K™ —Icode2šœ-™-IquotešΟsH™HšΟk ˜ Kšœžœ˜'Kšœ žœžœ˜#Kšžœžœ'˜/Kšœ žœ˜!Kšœžœ ˜Kšœ žœ˜!Kšœžœ˜Kšœ žœ˜(KšžœΟc˜Kšœžœ˜Kšœžœ^˜jKšœžœžœ˜Kšœžœ˜ —LšΠblœžœž˜LšžœAž˜JLšžœ˜ Lšœž˜head™Lš žœžœžœžœ Ÿ˜7Kš œžœžœžœ*žœ˜KKšœžœžœ ˜š œ žœžœžœžœ˜NK™Τ—Kšœ žœžœ ˜Kš œ žœžœžœžœ˜TKšœ žœžœ˜1Lšœ žœ Ÿ˜,KšœžœŸ˜:Kšœžœ Ÿ ˜)š Οnœžœžœžœž˜5Kšžœžœžœ™Kšžœžœžœžœ˜OKšžœŸ˜ —š ‘œžœžœžœž˜;Lšœ™Kšœ žœžœ˜GKšžœ˜KšžœŸ˜ —š ‘œžœžœžœžœž˜-K™(KšœžœW˜^KšžœŸ˜—š ‘œžœžœžœž˜%K™*Kšœž˜KšžœŸ˜—š ‘œžœ žœžœ$žœž˜wK™Kšœ˜Kšœžœžœ˜2Kšžœžœžœ˜Bšžœžœž˜Kšœžœžœ)˜CKšœ8˜8Kšžœ˜—Kšœ#˜#Kšœm˜mKšœ&˜&KšžœŸ˜—š ‘ œžœžœžœ žœžœ&ž˜jKšœ0™0Kšœ9˜9Kšœ"˜"KšžœŸ˜—š‘œžœžœžœ žœžœ$žœžœž˜sK™