LichenFlatGroup2.Mesa
Last tweaked by Mike Spreitzer on April 6, 1989 5:43:23 pm 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] ~ {
DisorgCT: PROC [ctv: Sets.Value] RETURNS [BOOL] ~ {
ct: CellType ~ NARROW[ctv.VA];
IF 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 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, 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]};
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];
RETURN}}}};
END.