LichenFlatGroup2.Mesa
Last tweaked by Mike Spreitzer on April 17, 1989 11:30:17 am PDT
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 é lost-- ~ MergeUnorganized[intoT, tempT, BiRels.CreateSingleton[[AV[sib], AV[tempI]], ALL[d.eSpace]]].ciWas;
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];
DeleteWires[from, dwForest, TRUE];
DeleteInsts[d, take, TRUE, FALSE];
RETURN}}}};
MergeUnorganized: PUBLIC PROC [a, b: CellType, iAssoc: OneToOne--instance of a é instance of b--] RETURNS [kept, lost: CellType, ciWas: OneToOne--kept é lost--] ~ {
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 lost wire-- ← nilBiRel;
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 é lost-- ~ CopyPWStructure[lost, kept, w, neededWires, nilSet];
neededPorts: Set ~ lost.asu.exports.Image[neededWires, rightToLeft];
portWas: OneToOne--kept é lost-- ~ CopyPWStructure[lost, kept, p, neededPorts, nilSet];
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.