<> <> 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]; RETURN}}; CopyPWStructure: PUBLIC PROC [fromCT, toCT: CellType, class: PWClass, olds, cins: Set] RETURNS [was: OneToOne--wire in toCT 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: PW _ NIL; 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 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 portInv: OneToOne--new 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. 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.