<> <> DIRECTORY AbSets, BiRels, IntStuff, LichenArrayPrivate, LichenDataOps, LichenDataStructure, LichenIntBasics, SetBasics; LichenArrayExtract: CEDAR PROGRAM IMPORTS AbSets, BiRels, LichenArrayPrivate, LichenDataOps, LichenDataStructure, LichenIntBasics, SetBasics = BEGIN OPEN IS:IntStuff, Sets:AbSets, LIB:LichenIntBasics, LIB, LichenArrayPrivate, LichenDataStructure, LichenDataOps; appLow: OneToOne ~ BiRels.CreateRopeCat["-low", suffix]; appHigh: OneToOne ~ BiRels.CreateRopeCat["-high", suffix]; ArrayEnd: TYPE ~ {low, high}; ShortenArrayInstance: PROC [d: Design, ci: CellInstance, end: ArrayEnd, sDim: Dim3 _ Z, by: NAT _ 1] ~ { act: CellType ~ Differentiate[d, Sets.CreateSingleA[ci, d.eSpace]]; ShortenArrayType[act, end, sDim, by]; RETURN}; ShortenArrayType: PROC [act: CellType, end: ArrayEnd, sDim: Dim3 _ Z, by: NAT _ 1, hackTypeNames: BOOL _ TRUE] ~ { d: Design ~ act.d; a: Array ~ act.asArray; actl, acth: CellType; IF sDim=Z THEN sDim _ SELECT 1 FROM a.size2[Y] => X, a.size2[X] => Y, ENDCASE => ERROR; SELECT end FROM low => { [actl, acth] _ SplitArrayType[act, sDim, by, hackTypeNames, FALSE]; ExpandType[d, actl]; by _ by}; high => { [actl, acth] _ SplitArrayType[act, sDim, a.size2[sDim]-by, hackTypeNames, FALSE]; ExpandType[d, acth]; by _ by}; ENDCASE => ERROR; RETURN}; SplitArrayType: PROC [act: CellType, sDim: Dim2, nl: NAT, hackTypeNames, hackInstNames: BOOL] RETURNS [actl, acth: CellType] ~ { d: Design ~ act.d; a: Array ~ act.asArray; tDim: Dim2 ~ OtherDim2[sDim]; nlh: NAT ~ a.size2[sDim]; nh: NAT ~ nlh-nl; nt: NAT ~ a.size2[tDim]; eltType: CellType ~ act.EltType; ctNames: Set--of ROPE-- ~ d.CTNames[act]; insts: Set ~ act.CtInsts[]; lhConn: BiRel--port of actl hlConn: BiRel--port of acth lRep: OneToOne--port of actl hRep: OneToOne--port of acth lRepInv: OneToOne ~ lRep.Invert; hRepInv: OneToOne ~ hRep.Invert; lowCais: Set ~ Sets.CreateBitVector[bounds: [0, a.size-1], expandable: FALSE]; highCais: Set ~ Sets.CreateBitVector[bounds: [0, a.size-1], expandable: FALSE]; IF a.buildPhase # statrepFixed THEN ERROR; IF nl MOD a.basePeriod[sDim] # 0 THEN ERROR nyet; IF NOT d.arrayElt.MappingEmpty[AV[act], rightToLeft] THEN ERROR nyet; actl _ CreateArray[d, eltType, ConsInt2[sDim, nl, nt], a.basePeriod, nilBiRel, NIL, IF hackTypeNames THEN appLow.Image[ctNames] ELSE ctNames]; acth _ CreateArray[d, eltType, ConsInt2[sDim, nh, nt], a.basePeriod, nilBiRel, NIL, IF hackTypeNames THEN appHigh.Image[ctNames] ELSE ctNames]; FOR x: NAT IN [0 .. a.size2[X]) DO FOR y: NAT IN [0 .. a.size2[Y]) DO ai: Int2 ~ [x, y]; cai: CompositeArrayIndex ~ ComposeAI[a, ai]; IF NOT Sets.AddI[IF ai[sDim]> exeen: Set ~ lRep.SetOn[right].Union[hRep.SetOn[right]]; PerExport: PROC [apv: Sets.Value] RETURNS [BOOL] ~ { IF exeen.HasMember[apv] THEN RETURN [FALSE]; {ap: Port ~ NARROW[apv.VA]; apKids: Set ~ d.parent.Mapping[apv, rightToLeft]; dw: DumbWire ~ NARROW[a.dumrep.apToWire.Apply[apv].MA]; cais: Set ~ dw.eps.SetOn[right]; aLow: BiRels.MaybePair ~ dw.eps.SkipTo[goal: cais.Intersection[lowCais], order: Sets.alleq]; aHigh: BiRels.MaybePair ~ dw.eps.SkipTo[goal: cais.Intersection[highCais], order: Sets.alleq]; IF apKids.Scan[PerExport].found THEN ERROR; IF aLow.found THEN { aplKids: Set ~ lRep.Image[apKids, rightToLeft]; IF aplKids.Size = apKids.Size THEN { epl: Port ~ NARROW[aLow.it[left].VA]; cail: CompositeArrayIndex ~ aLow.it[right].VI; ail: Int2 ~ DecomposeAI[a, cail]; apl: Port ~ GetArrayPortForPort[actl, ail, epl, TRUE, FALSE, FALSE]; lRep.AddNewAA[apl, ap]} ELSE ERROR}; IF aHigh.found THEN { aphKids: Set ~ hRep.Image[apKids, rightToLeft]; IF aphKids.Size = apKids.Size THEN { eph: Port ~ NARROW[aHigh.it[left].VA]; caih: CompositeArrayIndex ~ aHigh.it[right].VI; aih: Int2 ~ LIB.Sub[DecomposeAI[a, caih], aph: Port ~ GetArrayPortForPort[acth, aih, eph, TRUE, FALSE, FALSE]; hRep.AddNewAA[aph, ap]} ELSE ERROR}; IF NOT exeen.HasMember[apv] THEN ERROR; RETURN [FALSE]}}; EdgeExport: PROC [sev: Sets.Value] RETURNS [BOOL] ~ { se: StatEdge ~ NARROW[sev.VA]; sep: StatEdgeSpec ~ SeSp[se, a.statrep]; Chexport: PROC [bl, bh: BOOL] ~ { FOR i: NAT IN [0 .. nt) DO ail: Int2 ~ ConsInt2[sDim, nl-1, i]; aih: Int2 ~ ConsInt2[sDim, 0, i]; pl: Port ~ GetArrayPortForPort[actl, ail, sep.vs[bl].port, FALSE, FALSE, FALSE]; ph: Port ~ GetArrayPortForPort[acth, aih, sep.vs[bh].port, FALSE, FALSE, FALSE]; IF pl=NIL OR ph=NIL THEN ERROR; [] _ lhConn.AddAA[pl, ph]; ENDLOOP; RETURN}; SELECT sep. 1 => IF sep.vs[TRUE].phase[sDim]=0 THEN Chexport[FALSE, TRUE]; 0 => NULL; -1 => IF sep.vs[FALSE].phase[sDim]=0 THEN Chexport[TRUE, FALSE]; ENDCASE => ERROR; RETURN [FALSE]}; xIndices: Set ~ Sets.IIAsSet[[0, a.size2[X]-1]]; yIndices: Set ~ Sets.IIAsSet[[0, a.size2[Y]-1]]; xId: OneToOne ~ BiRels.CreateIDSubset[xIndices]; yId: OneToOne ~ BiRels.CreateIDSubset[yIndices]; setOf0: Set ~ Sets.CreateSingleI[0, SetBasics.ints]; <> IF a.statrep.edges.Scan[CopyEdge].found THEN ERROR; FinishedMakingArrayConnections[actl]; FinishedMakingArrayConnections[acth]; IF a.dumrep.apToWire.SetOn[left].Scan[PerExport].found THEN ERROR; IF NOT base.Equal[exeen] THEN ERROR; IF a.statrep.edges.Scan[EdgeExport].found THEN ERROR; {spandl: Set ~ DeduceStructureForPorts[actl]; spandh: Set ~ DeduceStructureForPorts[acth]; PerInst: PROC [civ: Sets.Value] RETURNS [BOOL] ~ { ci: CellInstance ~ NARROW[civ.VA]; cct: CellType ~ d.CiCct[ci]; ciNames: Set ~ cct.INames[ci]; cil: CellInstance ~ Instantiate[actl, cct, FALSE, [], dullInt2, IF hackInstNames THEN appLow.Image[ciNames] ELSE ciNames]; cih: CellInstance ~ Instantiate[acth, cct, FALSE, [], dullInt2, IF hackInstNames THEN appHigh.Image[ciNames] ELSE ciNames]; ldun: Fn ~ BiRels.CreateHashTable[ALL[d.eSpace]]; hdun: Fn ~ BiRels.CreateHashTable[ALL[d.eSpace]]; nextl: Fn ~ lhConn.Compose[hdun]; nexth: Fn ~ hlConn.Compose[ldun]; lconns: Fn _ lRep.Compose[ci.conns].CreateHashCopy[]; hconns: Fn _ hRep.Compose[ci.conns].CreateHashCopy[]; UNTIL lconns.Empty AND hconns.Empty DO ldun.AddNewSet[lconns]; hdun.AddNewSet[hconns]; ConnectPWs[d, lconns, cil]; ConnectPWs[d, hconns, cih]; lconns _ nextl.Difference[ldun].CreateHashCopy[mappable: [TRUE, FALSE]]; hconns _ nexth.Difference[hdun].CreateHashCopy[mappable: [TRUE, FALSE]]; ENDLOOP; ClosePortsConnectivity[d, spandl, cil.conns, cil]; ClosePortsConnectivity[d, spandh, cih.conns, cih]; RETURN [FALSE]}; <> IF insts.Scan[PerInst].found THEN ERROR; DeleteCellType[act, NIL]; RETURN}}}; END.