LichenFlatGroup.Mesa
Last tweaked by Mike Spreitzer on August 25, 1988 3:14:56 pm PDT
DIRECTORY AbSets, BiRelBasics, BiRels, IntStuff, LichenArrayPrivate, LichenDataOps, LichenDataStructure, LichenIntBasics, Rope, SetBasics;
LichenFlatGroup: CEDAR PROGRAM
IMPORTS AbSets, BiRelBasics, BiRels, IntStuff, LichenArrayPrivate, LichenDataOps, LichenDataStructure, LichenIntBasics, Rope, SetBasics
EXPORTS LichenDataOps
=
BEGIN OPEN IS:IntStuff, LIB:LichenIntBasics, LIB, LichenDataStructure, LichenDataOps, Sets:AbSets;
ExpandType: PUBLIC PROC [d: Design, ct: CellType] ~ {
ExpInst: PROC [civ: Sets.Value] RETURNS [BOOL] ~ {
ci: CellInstance ~ NARROW[civ.VA];
ExpandInstance[d, ci];
RETURN [FALSE]};
IF ct.asArray#NIL AND ct.asu=NIL THEN UnorganizeArray[ct];
IF d.ciType.ScanMapping[AV[ct], ExpInst, rightToLeft].found THEN ERROR;
RETURN};
ExpandInstance: PUBLIC PROC [d: Design, ci: CellInstance] ~ {
ict: CellType ~ d.CiT[ci];
cct: CellType ~ d.CiCct[ci];
privates: Set ~ ict.CTParts[w] .Difference[d.ancest.Image[ict.asu.publics]] .CreateHashCopy[];
wireWas: OneToOne ~ CopyPWStructure[ict, cct, w, privates, cct.INames[ci]];
newWires: Set ~ wireWas.SetOn[left];
oldCis: Set ~ ict.CTParts[i];
wireAttached: BiRel ~ ci.conns.Invert.Compose[ict.asu.exports];
ageWire: BiRel ~ wireWas.Union[b: wireAttached, disjoint: TRUE];
ciWas: OneToOne ~ CopyInstStructure[ict, cct, oldCis, cct.INames[ci], ageWire, IF d.ciXfm#nilBiRel THEN VXfm[d.ciXfm.ApplyA[ci].Val] ELSE [], ci.offset];
newCis: Set ~ ciWas.SetOn[left];
DeleteInsts[d, Sets.CreateSingleA[ci, d.eSpace], TRUE];
IF ict.Unused[] THEN DeleteCellType[ict, NIL];
RETURN};
GroupInstancesToNewCT: PROC [d: Design, cis: Set, iName, tName: ROPE] RETURNS [newCT: CellType, newCI: CellInstance] ~ {
cct: CellType ~ NARROW[d.cct[i].Image[cis].TheElt.VA];
conndWires: Set ~ d.iwConns.Image[cis].CreateHashCopy[];
conndRoots: Set ~ d.toRoot.Image[conndWires].CreateHashCopy[];
relatedWires: Set ~ d.ancest.Image[conndRoots, rightToLeft].CreateHashCopy[];
otherCis: Set ~ cct.CTParts[i].Difference[cis];
otherConndWires: Set ~ d.iwConns.Image[otherCis] .Union[cct.asu.exports.SetOn[right]] .CreateHashCopy[];
otherRoots: Set ~ d.toRoot.Image[otherConndWires].CreateHashCopy[];
splitRoots: Set ~ conndRoots.Intersection[otherRoots].CreateHashCopy[];
pvtRoots: Set ~ conndRoots.Difference[otherRoots].CreateHashCopy[];
splitWires: Set ~ d.ancest.Image[splitRoots, rightToLeft].CreateHashCopy[];
pvtWires: Set ~ d.ancest.Image[pvtRoots, rightToLeft].CreateHashCopy[];
newCT ← CreateCellType[d, unorganized, fullRange2, OneRope[tName]];
{wireWas: OneToOne ~ CopyPWStructure[cct, newCT, w, relatedWires, nilSet];
ciWas: OneToOne ~ CopyInstStructure[cct, newCT, cis, nilSet, wireWas, [], ALL[0]];
Exportit: PROC [owv: Sets.Value] RETURNS [BOOL] ~ {
nw: Wire ~ NARROW[wireWas.InvApply[owv].MA];
p: Port ~ PortForWire[newCT, nw, TRUE];
IF p=NIL THEN ERROR;
RETURN [FALSE]};
Connectit: PROC [owv: Sets.Value] RETURNS [BOOL] ~ {
ow: Wire ~ NARROW[owv.VA];
nw: Wire ~ NARROW[wireWas.InvApply[owv].MA];
p: Port ~ PortForWire[newCT, nw, FALSE];
IF p=NIL THEN ERROR;
Connect[d, ow, p, newCI];
RETURN [FALSE]};
IF splitWires.Scan[Exportit].found THEN ERROR;
newCI ← Instantiate[newCT, cct, FALSE, [], ALL[0], OneOSn[iName]];
IF splitWires.Scan[Connectit].found THEN ERROR;
DeleteInsts[d, cis, TRUE];
DeleteWires[cct, pvtWires, FALSE];
RETURN}};
SplitUnorganized: 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, emptyRange2, fix.Image[d.CTNames[from]]];
{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, [], 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}}}};
CopyPWStructure: PROC [fromCT, toCT: CellType, class: PWClass, olds, cins: Set] RETURNS [was: OneToOne] ~ {
d: Design ~ fromCT.d;
lab: BOOL ~ d.labelCellTypes.HasMemA[fromCT];
simpleNames: BOOL ~ cins=nilSet;
MoveWire: PROC [opwv: Sets.Value] RETURNS [BOOL] ~ {
IF was.HasMapping[opwv, rightToLeft] THEN RETURN [FALSE];
{opw: PW ~ NARROW[opwv.VA];
atomic: BOOL ~ d.Atomic[opw];
oNames: Set ~ fromCT.PartNames[class, opw];
fullNames: Set ~ IF simpleNames THEN oNames ELSE IF d.inheritNames THEN ActualNames[lab, cins, oNames] ELSE emptySteppySet;
nkids: Seq ← nilBiRel;
npw: PWNIL;
IF NOT atomic THEN {
okids: Seq ~ d.SubSeq[opw];
n: NAT ~ okids.Size.EN;
nkids ← CreateSeq[len: n, oneToOne: TRUE, dense: TRUE, rightSpace: d.eSpace];
FOR i: NAT IN [0 .. n) DO
okid: PW ~ NARROW[okids.ApplyI[i].MA];
IF MoveWire[[okid]] THEN ERROR;
nkids.AddNewIA[i, was.InvApplyA[okid].MA];
ENDLOOP;
nkids ← nkids};
SELECT class FROM
p => npw ← CreatePort[toCT, fullNames, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, nkids];
w => npw ← CreateWire[toCT, fullNames, FALSE, FALSE, FALSE, nkids];
ENDCASE => ERROR;
was.AddNewAA[npw, opw];
RETURN [FALSE]}};
was ← BiRels.CreateHashOTO[ALL[d.eSpace]];
IF olds.Scan[MoveWire].found THEN ERROR;
RETURN};
CopyInstStructure: PROC [fromCT, toCT: CellType, oldCis, cins: Set, ageWire: BiRel, xf: Transform, ofst: Int2] RETURNS [ciWas: OneToOne] ~ {
d: Design ~ fromCT.d;
simpleNames: BOOL ~ cins=nilSet;
MoveInst: PROC [ociv: Sets.Value] RETURNS [BOOL] ~ {
oci: CellInstance ~ NARROW[ociv.VA];
oct: CellType ~ d.CiT[oci];
oNames: Set ~ fromCT.INames[oci];
fullNames: Set ~ IF simpleNames THEN oNames ELSE IF d.inheritNames THEN ActualNames[FALSE, cins, oNames] ELSE emptySteppySet;
xfm: Transform ← [];
offset: Int2 ← dullInt2;
IF d.ciXfm#nilBiRel THEN {
t1: Transform ~ VXfm[d.ciXfm.ApplyA[oci].Val];
xfm ← t1.Compose[xf];
offset ← Add[ofst, t1.TransformVector[oci.offset]]};
{nci: CellInstance ~ Instantiate[oct, toCT, FALSE, xfm, offset, fullNames];
MoveConnection: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ {
p: Port ~ NARROW[pair[left].VA];
wmv: Sets.MaybeValue ~ ageWire.InvApply[pair[right]];
IF wmv.found THEN Connect[d, NARROW[wmv.it.VA], p, nci] ELSE IF d.Atomic[p] THEN ERROR;
RETURN [FALSE]};
ciWas.AddNewAA[nci, oci];
IF oci.conns.Scan[MoveConnection].found THEN ERROR;
RETURN [FALSE]}};
ciWas ← BiRels.CreateHashOTO[ALL[d.eSpace]];
IF oldCis.Scan[MoveInst].found THEN ERROR;
RETURN};
Differentiate: PUBLIC PROC [d: Design, cis: Set] RETURNS [new: CellType] ~ {
old: CellType ~ NARROW[d.ciType.Image[cis].TheElt.VA];
portAssoc: OneToOne--old Port é new Port--;
portInv: OneToOne--new Port é old Port--;
FixInst: PROC [civ: Sets.Value] RETURNS [BOOL] ~ {
ci: CellInstance ~ NARROW[civ.VA];
FixWire: PROC [wv: Sets.Value] RETURNS [BOOL] ~ {
w: Wire ~ NARROW[wv.VA];
oPorts: Set ~ w.conns.Mapping[civ, rightToLeft];
nPorts: Set ~ portAssoc.Image[oPorts].CreateHashCopy[];
IF NOT w.conns.Delete[civ, right] THEN ERROR;
[] ← w.conns.AddSet[BiRels.CreateProduct[[nPorts, Sets.CreateSingleton[civ, d.eSpace]]]];
RETURN [FALSE]};
[] ← d.ciType.AddAA[ci, new];
{newConns: Fn ~ portInv.Compose[ci.conns, [FALSE,TRUE]].CreateHashCopy[];
IF ci.conns.SetOn[right].Scan[FixWire].found THEN ERROR;
[] ← ci.conns.Erase[];
[] ← ci.conns.AddSet[newConns];
RETURN [FALSE]}};
[new, portInv] ← CopyCellType[old];
portAssoc ← portInv.Invert;
IF cis.Scan[FixInst].found THEN ERROR;
RETURN};
CopyCellType: PROC [oct: CellType] RETURNS [nct: CellType, portInv: OneToOne] ~ {
d: Design ~ oct.d;
flavor: CellFlavor ~ SELECT TRUE FROM
oct.asTrans # NIL => leaf,
oct.asArray # NIL => array,
oct.asu # NIL => unorganized,
ENDCASE => ERROR;
nct ← CreateCellType[d, flavor, oct.bbox, d.CTNames[oct]];
portInv ← CopyPWStructure[oct, nct, p, oct.CTParts[p], nilSet];
IF flavor=unorganized THEN {
wireWas: OneToOne ~ CopyPWStructure[oct, nct, p, oct.CTParts[w], nilSet];
ciWas: OneToOne ~ CopyInstStructure[oct, nct, oct.CTParts[w], nilSet, wireWas, [], ALL[0]];
ConnectPWs[d, portInv.Compose[oct.asu.exports.Compose[wireWas.Invert]], nct];
nct ← nct}
ELSE IF flavor=array THEN {
oa: Array ~ oct.asArray;
ect: CellType ~ oct.EltType;
na: Array ~ CreateArrayPart[nct, ect, oa.size2, oa.basePeriod, IF oa.fXfm#nilBiRel THEN oa.fXfm.Copy ELSE nilBiRel, CopyOffsets[oa.offsets]];
MoveEdge: PROC [sev: Sets.Value] RETURNS [BOOL] ~ {
se: StatEdge ~ NARROW[sev.VA];
sep: StatEdgeSpec ~ se.SeSp[oa.statrep];
[] ← LichenArrayPrivate.AddStatEdge[d, na.statrep, sep];
RETURN [FALSE]};
IF oa.buildPhase # statrepFixed THEN ERROR;
[] ← na.statrep.apToPAI.AddSet[portInv.Compose[oa.statrep.apToPAI, [FALSE, TRUE]]];
SetArrayPart[nct, ect, na];
FinishedMakingArrayConnections[nct];
nct ← nct}
ELSE {
nct.asTrans ← NEW [TransistorPrivate ← oct.asTrans^];
nct ← nct};
oct ← oct};
CopyOffsets: PROC [old: OffsetSeq] RETURNS [new: OffsetSeq] ~ {
IF old=NIL THEN RETURN [NIL];
new ← NEW [OffsetSequence[old.length]];
FOR i: NAT IN [0 .. old.length) DO new[i] ← old[i] ENDLOOP;
new ← new};
END.