LichenFlatGroup1.Mesa
Last tweaked by Mike Spreitzer on May 12, 1989 10:41:12 am PDT
DIRECTORY AbSets, BiRelBasics, BiRels, IntStuff, LichenArrayPrivate, LichenDataOps, LichenDataStructure, LichenFlatPrivate, LichenIntBasics, Rope, SetBasics;
LichenFlatGroup1: CEDAR PROGRAM
IMPORTS AbSets, BiRelBasics, BiRels, IntStuff, LichenArrayPrivate, LichenDataOps, LichenDataStructure, LichenIntBasics, SetBasics
EXPORTS LichenDataOps, LichenFlatPrivate
=
BEGIN OPEN IS:IntStuff, LIB:LichenIntBasics, LIB, LichenDataStructure, LichenDataOps, LichenFlatPrivate, Sets:AbSets;
status: PUBLIC REF Status ~ NEW [Status ← []];
ExpandInstance: PUBLIC PROC [d: Design, ci: CellInstance] RETURNS [ciWas, wireWas: OneToOne] ~ {
ict: CellType ~ d.CiT[ci];
cct: CellType ~ d.CiCct[ci];
privates: Set ~ ict.CTParts[w] .Difference[d.ancest.Image[ict.asu.publics]] .CreateHashCopy[];
oldCis: Set ~ ict.CTParts[i];
status.inst ← Describe[d, ci, d];
status.type ← Describe[d, ict, d];
wireWas ← CopyPWStructure[ict, cct, w, privates, cct.INames[ci]];
{newWires: Set ~ wireWas.SetOn[left];
wireAttached: BiRel ~ ci.conns.Invert.Compose[ict.asu.exports];
ageWire: BiRel ~ wireWas.Union[b: wireAttached, disjoint: TRUE];
ciWas ← CopyInstStructure[ict, cct, oldCis, cct.INames[ci], ageWire, IF d.physd THEN VXfm[d.ciXfm.ApplyA[ci].Val] ELSE [], ci.offset];
{newCis: Set ~ ciWas.SetOn[left];
DeleteInsts[d, Sets.CreateSingleA[ci, d.eSpace], TRUE, FALSE];
IF ict.Unused[] THEN DeleteCellType[ict, FALSE, NIL];
status.expansions ← status.expansions+1;
RETURN}}};
GroupInstancesToNewCT: PUBLIC PROC [d: Design, cis: Set, iName: ROPE, tNames: Set] 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, tNames];
[] ← d.crossedCellTypes.AddA[newCT];
{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, FALSE];
DeleteWires[cct, pvtWires, FALSE, FALSE];
RETURN}};
CopyPWStructure: PUBLIC PROC [fromCT, toCT: CellType, class: PWClass, olds, cins: Set] RETURNS [was: OneToOne--wire in toCT é wire in fromCT--] ~ {
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: PUBLIC PROC [fromCT, toCT: CellType, oldCis, cins: Set, ageWire: InvFn--wire in toCT ← wire in fromCT--, xf: Transform, ofst: Int2] RETURNS [ciWas: OneToOne--ci in toCT é ci in fromCT--] ~ {
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.physd THEN {
t1: Transform ~ VXfm[d.ciXfm.ApplyA[oci].Val];
xfm ← t1.Compose[xf];
offset ← Add[ofst, xf.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--don't have to worry about crossing because only used in ShortenArrayInstance, to create a type that's later deleted--};
CopyCellType: PUBLIC 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, d.CTNames[oct]];
nct.bbox ← oct.bbox;
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 d.physd THEN oa.fXfm.Copy ELSE nilBiRel, IF d.physd THEN CopyOffsets[oa.offsets] ELSE NIL];
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;
IF oa.statrep.edges.Scan[MoveEdge].found 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};
RETURN--don't have to worry about crossing because only used in Differentiate--};
CopyOffsets: PROC [old: OffsetSeq] RETURNS [new: OffsetSeq] ~ {
new ← NEW [OffsetSequence[old.length]];
FOR i: NAT IN [0 .. old.length) DO new[i] ← old[i] ENDLOOP;
new ← new};
END.