<> <> DIRECTORY AbSets, BiRelBasics, BiRels, IntStuff, LichenArrayPrivate, LichenDataOps, LichenDataStructure, LichenFlatPrivate, LichenIntBasics, Rope, SetBasics; LichenFlatGroup2: CEDAR PROGRAM IMPORTS AbSets, BiRels, LichenDataOps, LichenDataStructure, LichenFlatPrivate, LichenIntBasics, Rope, SetBasics EXPORTS LichenDataOps, LichenFlatPrivate = BEGIN OPEN IS:IntStuff, LIB:LichenIntBasics, LIB, LichenDataStructure, LichenDataOps, LichenFlatPrivate, Sets:AbSets; ExpandType: PUBLIC PROC [d: Design, ct: CellType] RETURNS [newCis: Set] ~ { ExpInst: PROC [civ: Sets.Value] RETURNS [BOOL] ~ { ci: CellInstance ~ NARROW[civ.VA]; ciWas, wireWas: OneToOne; [ciWas, wireWas] _ ExpandInstance[d, ci]; [] _ newCis.AddSet[ciWas.SetOn[left]]; RETURN [FALSE]}; IF d.arrayElt.HasMapA[ct, rightToLeft] THEN ERROR; newCis _ Sets.CreateHashSet[d.eSpace]; IF ct.asArray#NIL AND ct.asu=NIL THEN UnorganizeArray[ct]; IF d.ciType.ScanMapping[AV[ct], ExpInst, rightToLeft].found THEN ERROR; RETURN}; ExpandDesign: PUBLIC PROC [d: Design, cts: Set--of CellType-- _ nilSet, except: CellType _ NIL] ~ { DisorgCT: PROC [ctv: Sets.Value] RETURNS [BOOL] ~ { ct: CellType ~ NARROW[ctv.VA]; IF ct#except AND ct.asArray#NIL AND ct.asu=NIL THEN UnorganizeArray[ct]; RETURN [FALSE]}; PerCT: PROC [ctv: Sets.Value] RETURNS [BOOL] ~ { ct: CellType ~ NARROW[ctv.VA]; IF ct=d.root OR ct=except THEN RETURN [FALSE]; IF ct.asu#NIL OR ct.asArray#NIL THEN [] _ ExpandType[d, ct]; IF d.cellTypes.HasMember[ctv] AND ct.Unused[] THEN DeleteCellType[ct, FALSE, NIL]; RETURN [FALSE]}; IF cts=nilSet THEN cts _ d.cellTypes; IF d.arrayElt.ScanImage[cts, DisorgCT, rightToLeft].found THEN ERROR; status^ _ []; IF cts.Scan[PerCT].found THEN ERROR; RETURN}; RaiseGCs: PUBLIC PROC [d: Design, gcs: Set--of CellInstance--] RETURNS [newCis: Set--of CellInstance--] ~ { from, to: CellType; [from, to] _ SplitUnorganized[d, gcs]; RETURN ExpandType[d, to]}; LowerKidsOnce: PUBLIC PROC [d: Design, kids: Set--of CellInstance--, sib: CellInstance] RETURNS [loweredCis: Set--of CellInstance--] ~ { intoT: CellType ~ d.CiT[sib]; tempT: CellType; tempI: CellInstance; [tempT, tempI] _ GroupInstancesToNewCT[d, kids, "temp", emptyRopeSet]; {ciWas: OneToOne--kept loweredCis _ ciWas.SetOn[left]; RETURN}}; SplitUnorganized: PUBLIC PROC [d: Design, take: Set--of CellInstance--] RETURNS [from, to: CellType] ~ { from _ NARROW[d.cct[i].Image[take].TheElt.VA]; IF NOT d.arrayElt.MappingEmpty[AV[from], rightToLeft] THEN ERROR nyet; {takename: SteppyName ~ VSn[from.fullName[i].Image[take].First[].Val]; fix: OneToOne ~ BiRels.CreateRopeCat[Rope.Cat["-", takename.UnparseSteppyName], suffix]; to _ CreateCellType[d, unorganized, fix.Image[d.CTNames[from]]]; [] _ d.crossedCellTypes.AddA[from]; [] _ d.crossedCellTypes.AddA[to]; {allcis: Set ~ from.Subcells[]; keep: Set ~ allcis.Difference[take].CreateHashCopy[]; tw: Set ~ d.iwConns.Image[take]; kw: Set ~ d.iwConns.Image[keep]; twRoots: Set ~ d.toRoot.Image[tw].CreateHashCopy[]; kwRoots: Set ~ d.toRoot.Image[kw].CreateHashCopy[]; twForest: Set ~ d.toRoot.Image[twRoots, rightToLeft].CreateHashCopy[]; kwForest: Set ~ d.toRoot.Image[kwRoots, rightToLeft].CreateHashCopy[]; dwForest: Set ~ from.CTParts[w].Difference[kwForest].CreateHashCopy[]; bw: Set ~ tw.Intersection[kw]; bwRoots: Set ~ d.toRoot.Image[bw].CreateHashCopy[]; bwForest: Set ~ d.toRoot.Image[bwRoots, rightToLeft].CreateHashCopy[]; npbwForest: Set ~ bwForest .Difference[from.asu.publics] .CreateHashCopy[]; [] _ FullySfwdlyExportWires[from, npbwForest]; IF NOT npbwForest.Subset[from.asu.publics] THEN ERROR; {tp: Set ~ from.asu.exports.Image[twForest, rightToLeft]; kp: Set ~ from.asu.exports.Image[kwForest, rightToLeft]; tpRoots: Set ~ d.toRoot.Image[tp].CreateHashCopy[]; kpRoots: Set ~ d.toRoot.Image[kp].CreateHashCopy[]; tpForest: Set ~ d.toRoot.Image[tpRoots, rightToLeft].CreateHashCopy[]; kpForest: Set ~ d.toRoot.Image[kpRoots, rightToLeft].CreateHashCopy[]; dpForest: Set ~ from.CTParts[p].Difference[kpForest].CreateHashCopy[]; portWas: OneToOne ~ CopyPWStructure[from, to, p, tpForest, nilSet]; wireWas: OneToOne ~ CopyPWStructure[from, to, w, twForest, nilSet]; ciWas: OneToOne ~ CopyInstStructure[from, to, take, nilSet, wireWas, [], ALL[0]]; FixInst: PROC [ociv: Sets.Value] RETURNS [BOOL] ~ { oci: CellInstance ~ NARROW[ociv.VA]; cct: CellType ~ d.CiCct[oci]; nci: CellInstance ~ Instantiate[to, cct, FALSE, IF d.physd THEN VXfm[d.ciXfm.ApplyA[oci].Val] ELSE [], oci.offset, cct.INames[oci]]; ConnectPWs[d, portWas.Compose[oci.conns], nci]; RETURN [FALSE]}; ConnectPWs[d, portWas.Compose[from.asu.exports.Compose[wireWas.Invert]], to]; IF d.ciType.ScanMapping[AV[from], FixInst, rightToLeft].found THEN ERROR; DeletePorts[from, dpForest, TRUE, FALSE, FALSE]; DeleteWires[from, dwForest, TRUE, FALSE]; DeleteInsts[d, take, TRUE, FALSE]; RETURN}}}}; MergeUnorganized: PUBLIC PROC [a, b: CellType, iAssoc: OneToOne--instance of a ciWas: OneToOne--kept d: Design ~ a.d; IF a=b OR a.d#b.d OR a.asu=NIL OR b.asu=NIL OR a.asArray#NIL OR b.asArray#NIL OR d.arrayElt.HasMapA[a, rightToLeft] OR d.arrayElt.HasMapA[b, rightToLeft] OR NOT (iAssoc.SetOn[left].Equal[a.CtInsts] AND iAssoc.SetOn[right].Equal[b.CtInsts]) THEN ERROR; kept _ a; lost _ b; {wpk: BiRel--Wire _ Port-- ~ kept.asu.exports.Invert; wpl: BiRel--Wire _ Port-- ~ lost.asu.exports.Invert; wireReallyIs: InvFn--kept wire _ lost wire-- ~ BiRels.CreateHashReln[ALL[d.eSpace], [FALSE, TRUE]]; wireIs: BiRel--kept wire xfm: Transform _ []; offset: Int2 _ [0, 0]; StartAssoc: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ { ik: CellInstance ~ NARROW[pair[left].VA]; il: CellInstance ~ NARROW[pair[right].VA]; wk: BiRel ~ wpk.Compose[ik.conns]; wl: BiRel ~ il.conns.Invert.Compose[lost.asu.exports]; wkl: BiRel ~ wk.Compose[wl].CreateHashCopy[mappable: ALL[TRUE]]; IF d.physd THEN { tk: Transform ~ VXfm[d.ciXfm.ApplyA[ik].Val]; tl: Transform ~ VXfm[d.ciXfm.ApplyA[il].Val]; tki: Transform ~ tk.Invert[]; xf: Transform ~ tl.Compose[tki]; of: Int2 ~ tki.TransformVector[LIB.Sub[il.offset, ik.offset]]; IF wireIs=nilBiRel THEN {xfm _ xf; offset _ of} ELSE IF xfm#xf OR offset#of THEN ERROR; }; IF wireIs=nilBiRel THEN wireIs _ wkl ELSE wireIs _ wireIs.Intersection[wkl].CreateHashCopy[]; IF wireIs=nilBiRel THEN ERROR; RETURN [FALSE]}; IF iAssoc.Empty THEN ERROR; IF iAssoc.Scan[StartAssoc].found THEN ERROR; IF wireIs=nilBiRel THEN ERROR; [] _ wireReallyIs.AddSet[wireIs]; {lostWires: Set ~ lost.CTParts[w]; alreadyWires: Set ~ wireReallyIs.SetOn[right]; alreadyAncestors: Set ~ d.ancest.Image[alreadyWires].CreateHashCopy[]; neededWires: Set ~ lostWires.Difference[alreadyAncestors].CreateHashCopy[]; wireWas: OneToOne--kept neededPorts: Set ~ lost.asu.exports.Image[neededWires, rightToLeft]; portWas: OneToOne--kept ageWire: InvFn--kept wire _ lost wire-- ~ wireReallyIs.Union[b: wireWas, disjoint: TRUE, functional: [FALSE, TRUE]]; lostCis: Set ~ lost.Subcells[]; FixPair: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ { ik: CellInstance ~ NARROW[pair[left].VA]; il: CellInstance ~ NARROW[pair[right].VA]; ConnectPWs[d, portWas.Compose[il.conns], ik]; RETURN [FALSE]}; ciWas _ CopyInstStructure[lost, kept, lostCis, nilSet, ageWire, xfm, offset]; ConnectPWs[d, portWas.Compose[lost.asu.exports].Compose[wireWas.Invert], kept]; IF iAssoc.Scan[FixPair].found THEN ERROR; [] _ d.crossedCellTypes.AddA[kept]; d.ctName.SubstituteA[lost, kept, left]; DeleteCellType[lost, FALSE, NIL]; RETURN}}}; END.