DIRECTORY AbSets, BasicTime, BiRels, IntStuff, IO, LichenDataOps, LichenDataStructure, LichenIntBasics, Rope, SetBasics; LichenArrayDeduction: CEDAR PROGRAM IMPORTS AbSets, BasicTime, BiRels, IntStuff, IO, LichenDataOps, LichenDataStructure, LichenIntBasics, SetBasics = BEGIN OPEN IS:IntStuff, Sets:AbSets, LIB:LichenIntBasics, LIB, LichenDataStructure, LichenDataOps; DeducePairness: PUBLIC PROC [cts: Set--of CellType--] RETURNS [successes, failures: Set _ nilSet] ~ { DPCt: PROC [val: Sets.Value] RETURNS [BOOL] ~ { ct: CellType ~ NARROW[val.VA]; success: BOOL ~ DeduceCTPairness[ct]; IF successes=nilSet THEN {successes _ Sets.CreateHashSet[ct.d.eSpace]; failures _ Sets.CreateHashSet[ct.d.eSpace]}; IF NOT Sets.AddElt[IF success THEN successes ELSE failures, val] THEN ERROR; RETURN [FALSE]}; IF cts.Scan[DPCt].found THEN ERROR; RETURN}; DeduceCTPairness: PROC [ct: CellType] RETURNS [success: BOOL] ~ { cis: Set--of CellInstance-- ~ ct.CTParts[i]; IF ct.asu=NIL THEN RETURN [FALSE]; IF cis.Size[].EC MOD 2 # 0 THEN RETURN [FALSE]; ERROR --not yet implemented--}; DeduceArrayness: PROC [d: Design, cts: Set--of CellType--, pacify: IO.STREAM] RETURNS [oks: Set--of CellType--, errs: Fn--CellType _ err msg--] ~ { PerCT: PROC [ctv: Sets.Value] RETURNS [BOOL] ~ { ct: CellType ~ NARROW[ctv.VA]; start: BasicTime.Pulses ~ BasicTime.GetClockPulses[]; IF pacify#NIL THEN pacify.PutRope[Describe[d, ct]]; {err: ROPE ~ DeduceCTArrayness[ct]; IF err=NIL THEN {IF NOT oks.AddA[ct] THEN ERROR ELSE NULL} ELSE errs.AddNewAA[ct, err]; IF pacify#NIL THEN { end: BasicTime.Pulses ~ BasicTime.GetClockPulses[]; pacify.PutF[" %g\n", [real[BasicTime.PulsesToSeconds[end-start]]]]}; RETURN [FALSE]}}; oks _ Sets.CreateHashSet[d.eSpace]; errs _ BiRels.CreateHashTable[[d.eSpace, SetBasics.ropes[TRUE]]]; IF cts.Scan[PerCT].found THEN ERROR; RETURN}; DeduceCTArrayness: PUBLIC PROC [ct: CellType] RETURNS [err: ROPE] ~ { cis: Set--of CellInstance-- ~ ct.CTParts[i]; icts: Set--of CellType-- ~ ct.d.ciType.Image[cis]; n: NATURAL ~ cis.Size[].EN; IF n=0 THEN RETURN ["array of size 0"]; IF ct.asu=NIL THEN RETURN ["not unorganized"]; IF icts.Size[IS.two] # IS.one THEN RETURN ["non-uniform instance types"]; {ict: CellType ~ NARROW[icts.AnElt.MA]; nXfms: NATURAL ~ ct.d.ciXfm.ImageSize[cis, leftToRight, IS.IE[n+1]].EN; period: NATURAL ~ SELECT nXfms FROM < 1 => ERROR, = 1 => 1, <=n => n, ENDCASE => ERROR; sorted: OneToOne--index f ci-- ~ BiRels.EnumSeqOfSet[cis, [CompareCenters, TRUE, FALSE, ict]]; idxr: OneToOne--index f ci-- ~ BiRels.GenCreate[ spaces: [SetBasics.ints, ct.d.eSpace], functional: ALL[TRUE], hints: [ leftToRight: [[$Vector]], rightToLeft: [[$Hash]] ]]; [] _ idxr.AddSet[sorted]; IF NOT idxr.SetOn[right].Equal[cis] THEN ERROR; {ci0: CellInstance ~ NARROW[idxr.ApplyI[0].MA]; cin: CellInstance ~ NARROW[idxr.ApplyI[n-1].MA]; ctr0: Int2 ~ CiCtr[ci0, ict]; ctrn: Int2 ~ CiCtr[cin, ict]; dctr: Int2 ~ LIB.Sub[ctrn, ctr0]; dim: Dim2 ~ SELECT TRUE FROM dctr[X] > dctr[Y] => X, dctr[Y] > dctr[X] => Y, ENDCASE => ERROR; RETURN ConvertToArray[ct, ict, cis, n, period, dim, idxr]}}}; ConvertToArray: PROC [ct, ict: CellType, cis: Set, n, period: NATURAL, dim: Dim2, idxr: OneToOne] RETURNS [err: ROPE] ~ { idxfm: Fn--index _ Xfm-- ~ idxr.Compose[ct.d.ciXfm, [TRUE, FALSE]]; fXfm: Fn--phase _ Transform-- ~ BiRels.CreateHashTable[[int2s, xfmSpace]]; offsets: OffsetSeq ~ NEW [OffsetSequence[period]]; FOR fz: NATURAL IN [0 .. period) DO f: Int2 ~ ConsInt2[dim, fz, 0]; fXfm.AddNewPair[[I2V[f], idxfm.ApplyI[fz].Val]]; IF period=n THEN { ci: CellInstance ~ NARROW[idxr.ApplyI[fz].MA]; offsets[fz] _ [o0: ci.offset, o1: [0, 0]]; }; ENDLOOP; IF period#n THEN { ci0: CellInstance ~ NARROW[idxr.ApplyI[0].MA]; offsets[0].o0 _ ci0.offset; IF n=1 THEN offsets[0].o1 _ [0, 0] ELSE {ci1: CellInstance ~ NARROW[idxr.ApplyI[1].MA]; offsets[0].o1 _ LIB.Sub[ci1.offset, ci0.offset]; FOR i: NATURAL IN [2 .. n) DO cii: CellInstance ~ NARROW[idxr.ApplyI[i].MA]; IF cii.offset # LIB.Mul[offsets[0].o1, [i, i], offsets[0].o0] THEN ERROR; ENDLOOP; }}; {ConvertWire: PROC [val: Sets.Value] RETURNS [BOOL] ~ { w: Wire ~ NARROW[val.VA]; note: BOOL _ TRUE; Outer: PROC [pairo: BiRels.Pair] RETURNS [BOOL] ~ { porto: Port ~ NARROW[pairo[left].VA]; WITH pairo[right].VA SELECT FROM cio: CellInstance => { io: LNAT ~ idxr.Apply[pairo[right], rightToLeft].MI; NoteExPort: PROC [apv: Sets.Value] RETURNS [BOOL] ~ { ap: Port ~ NARROW[apv.VA]; MakeArrayExport[ct.d, ct.asArray, ap, porto, ConsInt2[dim, io, 0]]; RETURN [FALSE]}; Inner: PROC [pairi: BiRels.Pair] RETURNS [BOOL] ~ { WITH pairi[right].VA SELECT FROM cii: CellInstance => { ii: LNAT ~ idxr.Apply[pairi[right], rightToLeft].MI; IF ii-io IN [0 .. 1] THEN { porti: Port ~ NARROW[pairi[left].VA]; MakeArrayNewConnection[ct.d, ct.asArray, ConsRange2[dim, [0, n+io-ii], [0, 1]], ConsInt2[dim, ii-io, 0], porto, porti]; ct _ ct}; }; cti: CellType => NULL; ENDCASE => ERROR; RETURN [FALSE]}; IF note THEN { IF ct.asu.exports.ScanMapping[AV[w], NoteExPort, rightToLeft].found THEN ERROR; note _ FALSE}; IF w.conns.Scan[Inner].found THEN ERROR; ct _ ct}; cto: CellType => NULL; ENDCASE => ERROR; RETURN [FALSE]}; IF w.conns.Scan[Outer].found THEN ERROR; IF note AND ct.asu.exports.HasMapA[w, rightToLeft] THEN ERROR; RETURN [FALSE]}; SetArrayPart[ct, ict, CreateArrayPart[ct, ict, ConsInt2[dim, n, 1], ConsInt2[dim, period, 1], fXfm, offsets]]; IF ct.CTParts[w].Scan[ConvertWire].found THEN ERROR; FinishedMakingArrayConnections[ct]; ForgetUnorganized[ct]; RETURN [NIL]}}; DeduceIdxs: PROC [ct: CellType, cis: Set] RETURNS [upCells, dnCells: Set] ~ { upPorts: Set--of ct port-- ~ Sets.CreateHashSet[ct.d.eSpace]; dnPorts: Set--of ct port-- ~ Sets.CreateHashSet[ct.d.eSpace]; StartParent: PROC [val: Sets.Value] RETURNS [BOOL] ~ { pct: CellType ~ NARROW[val.VA]; a: Array ~ pct.asArray; IF a = NIL THEN ERROR; IF NOT (a.size2[X]=1 OR a.size2[Y]=1) THEN RETURN [FALSE]; {lows: Set ~ a.statrep.portEdge[FALSE].SetOn[left]; highs: Set ~ a.statrep.portEdge[TRUE].SetOn[left]; ups: Set ~ lows.Difference[highs]; dns: Set ~ highs.Difference[lows]; samebad: INT ~ upPorts.Intersection[dns].Size.EN + dnPorts.Intersection[ups].Size.EN; revbad: INT ~ upPorts.Intersection[ups].Size.EN + dnPorts.Intersection[dns].Size.EN; IF samebad <= revbad THEN {[] _ upPorts.AddSet[ups]; [] _ dnPorts.AddSet[dns]} ELSE {[] _ upPorts.AddSet[dns]; [] _ dnPorts.AddSet[ups]}; RETURN [FALSE]}}; IF ct.CtArrays.Scan[StartParent].found THEN ERROR; upCells _ Sets.CreateHashSet[ct.d.eSpace]; dnCells _ Sets.CreateHashSet[ct.d.eSpace]; {classified: Set ~ upCells.Union[b: dnCells, disjoint: TRUE]; toClassify: Set ~ cis.Difference[classified]; upWires: Set _ ct.asu.exports.Image[upPorts].CreateHashCopy[]; dnWires: Set _ ct.asu.exports.Image[dnPorts].CreateHashCopy[]; cws: Set _ upWires.Union[dnWires].CreateHashCopy[]; [] _ upWires.RemSet[dnWires]; [] _ dnWires.RemSet[upWires]; IF upWires.Empty[] # dnWires.Empty[] THEN ERROR; IF upWires.Empty[] THEN { DivvyType: PROC [val: Sets.Value] RETURNS [BOOL] ~ { ict: CellType ~ NARROW[val.VA]; isn: Set ~ cis.Intersection[ict.CtInsts[]]; ninsts: LNAT ~ isn.Size[].EN; i: LNAT _ 0; DivvyInst: PROC [val: Sets.Value] RETURNS [BOOL] ~ { IF NOT Sets.AddElt[IF i MOD 2 = 0 THEN upCells ELSE dnCells, val] THEN ERROR; i _ i+1; RETURN [FALSE]}; IF ninsts MOD 2 # 0 THEN ERROR; IF isn.Scan[DivvyInst].found THEN ERROR; RETURN [FALSE]}; IF ct.d.ciType.ScanImage[cis, DivvyType].found THEN ERROR; ct _ ct} ELSE { DO newUC: Set ~ ct.d.iwConns.Image[upWires, rightToLeft].Difference[classified].CreateHashCopy[]; newDC: Set ~ ct.d.iwConns.Image[dnWires, rightToLeft].Difference[classified].CreateHashCopy[]; [] _ newUC.RemSet[newDC]; [] _ newDC.RemSet[newUC]; IF newUC.Empty AND newDC.Empty THEN ERROR; [] _ upCells.AddSet[newUC]; [] _ dnCells.AddSet[newDC]; IF toClassify.Empty[] THEN EXIT; { newUW: Set ~ ct.d.iwConns.Image[newUC].Difference[cws].CreateHashCopy[]; newDW: Set ~ ct.d.iwConns.Image[newDC].Difference[cws].CreateHashCopy[]; [] _ cws.AddSet[newUW]; [] _ cws.AddSet[newDW]; [] _ newUW.RemSet[newDW]; [] _ newDW.RemSet[newUW]; IF newUW.Empty AND newDW.Empty THEN ERROR; [] _ upWires.AddSet[newUW]; [] _ dnWires.AddSet[newDW]; }ENDLOOP; ct _ ct}; RETURN}}; CompareCenters: PROC [data: REF ANY, v1, v2: Sets.Value] RETURNS [SetBasics.PartialComparison] ~ { ict: CellType ~ NARROW[data]; ci1: CellInstance ~ NARROW[v1.VA]; ci2: CellInstance ~ NARROW[v2.VA]; ctr1: Int2 ~ CiCtr[ci1, ict]; ctr2: Int2 ~ CiCtr[ci2, ict]; RETURN SetBasics.CompareIntI[INT[ctr1[X]]+ctr1[Y], INT[ctr2[X]]+ctr2[Y]]}; END. `LichenArrayDeduction.Mesa Last tweaked by Mike Spreitzer on July 1, 1988 10:22:23 am PDT Κ χ– "cedar" style˜codešœ™Kšœ>™>—K˜KšΟk œ&œG˜xK˜šΟnœœ˜#Kšœ&œ@˜oK˜—K˜Kš œœœ žœ œœ%˜bK˜š žœœœ Οcœœ(˜ešžœœœœ˜/Kšœœœ˜Kšœ œ˜%Kšœœ[˜sKšœœ œ œ œœœ˜LKšœœ˜—Kšœœœ˜#Kšœ˜—K˜šžœœœ œ˜AKšœŸœ˜,Kš œœœœœ˜"Kš œ œœœœœ˜/KšœŸœ˜—K˜šžœœŸœ œœœ Ÿœ Ÿ ΠcmŸ œ˜“šžœœœœ˜0Kšœœœ˜Kšœ5˜5Kšœœœ!˜3Kšœœ˜#Kšœœœœœœœœœ˜:Kšœ˜šœœœ˜Kšœ3˜3K˜D—Kšœœ˜—K˜#Kšœ9œ˜AKšœœœ˜$Kšœ˜—K˜š žœœœœœ˜EKšœŸœ˜,Kšœ Ÿœ˜2Kšœœœ˜Kšœœœ˜'Kšœœœœ˜.Kš œ œœœœ ˜IKšœœ œ˜'Kš œœ*œœœ˜Gšœœœ˜#Kšœœ˜ K˜ K˜ Kšœœ˜—Kš œŸ Ÿœ-œœ˜^šœŸ Ÿœ˜0K˜&Kšœ œœ˜˜K˜K˜——K˜Kšœœœœ˜/Kšœœœ˜/Kšœœœ˜0K˜K˜KšΟgœ œ˜!šœ œœ˜Kš‘œ ‘œ ˜Kš‘œ ‘œ ˜Kšœœ˜—Kšœ7˜=—K˜š žœœ*œœœ˜yKš œ Ÿ Ÿœœœ˜CKš‘œŸ Ÿ œ-˜JKšœœ˜2š œ‘Οdœœœ˜#Kš‘œ‘’œ˜Kš ‘œœ‘œ‘’œ˜0šœ œ˜Kšœœ ‘’œœ˜.Kšœ‘’œ ˜*K˜—Kšœ˜—šœ œ˜Kšœœœ˜.K˜Kšœœ˜'Kšœœœ˜/Kšœœ˜0šœœœ ˜Kšœœœ˜.Kšœœ+œœ˜IKšœ˜—K˜—š œž œœœœ˜7Kšœ œœ˜Kšœœœ˜šžœœœœ˜3Kšœœ œ˜%šœœœ˜ ˜Kšœœ)œ˜4šž œœœœ˜5Kšœ œœ˜KšœC˜CKšœœ˜—šžœœœœ˜3šœœœ˜ ˜Kšœœ)œ˜4šœœ œ˜Kšœœ œ˜%Kšœw˜wK˜ —K˜—Kšœœ˜Kšœœ˜—Kšœœ˜—šœœ˜Kšœœ$œœ˜OKšœœ˜—Kšœœœ˜(K˜ —Kšœœ˜Kšœœ˜—Kšœœ˜—Kšœœœ˜(Kšœœ(œœ˜>Kšœœ˜—Kšœ^‘œ˜nKšœ'œœ˜4Kšœ#˜#K˜Kšœœ˜—K˜šž œœœ˜MKšœ Ÿœ#˜=Kšœ Ÿœ#˜=šž œœœœ˜6Kšœœœ˜K˜Kšœœœœ˜Kš œœœœœœ˜:Kšœ œ˜3Kšœ œ˜2K˜"K˜"Kšœ œ"œ"œ˜UKšœœ"œ"œ˜Tšœ˜Kšœ5˜9Kšœ6˜:—Kšœœ˜—Kšœ%œœ˜2K˜*Kšœ*˜*Kšœ7œ˜=K˜-Kšœ>˜>Kšœ>˜>K˜3K˜K˜Kšœ#œœ˜0šœœ˜šž œœœœ˜4Kšœœœ˜K˜+Kšœœœ˜Kšœœ˜ šž œœœœ˜4Kšœœ œœœ œœœ˜MKšœ œœ˜—Kšœœœœ˜Kšœœœ˜(Kšœœ˜—Kšœ-œœ˜:K˜—šœ˜š˜K˜^Kšœ^˜^Kšœ˜Kšœ˜Kšœ œ œœ˜*K˜Kšœ˜Kšœœœ˜ K˜K˜HKšœH˜HK˜Kšœ˜Kšœ˜Kšœ˜Kšœ œ œœ˜*K˜Kšœ˜Kšœœ˜ —K˜ —Kšœ˜ —K˜š žœœœœœ"˜bKšœœ˜Kšœœœ˜"Kšœœœ˜"Kšœ˜Kšœ˜Kšœœœ˜J—K˜Kšœ˜—…—!b,Ή