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];
D: Int2 ~ ConsInt2[sDim, nl, 0];
eltType: CellType ~ act.EltType;
ctNames: Set--of ROPE-- ~ d.CTNames[act];
insts: Set ~ act.CtInsts[];
lhConn: BiRel--port of actl port of acth-- ~ BiRels.CreateHashReln[ALL[d.eSpace]];
hlConn: BiRel--port of acth port of actl-- ~ lhConn.Invert;
lRep: OneToOne--port of actl é port of act-- ~ BiRels.CreateHashOTO[ALL[d.eSpace]];
hRep: OneToOne--port of acth é port of act-- ~ BiRels.CreateHashOTO[ALL[d.eSpace]];
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]<nl THEN lowCais ELSE highCais, cai] THEN ERROR;
ENDLOOP ENDLOOP;
{al: Array ~ actl.asArray;
ah: Array ~ acth.asArray;
CopyEdge:
PROC [sev: Sets.Value]
RETURNS [
BOOL] ~ {
se: StatEdge ~ NARROW[sev.VA];
sep: StatEdgeSpec ~ SeSp[se, a.statrep];
[] ← AddStatEdge[d, al.statrep, sep];
[] ← AddStatEdge[d, ah.statrep, sep];
RETURN [FALSE]};
base: Set ~ a.dumrep.apToWire.SetOn[left];
<<spans: Set ~ d.parent.Image[base].Difference[base].CreateHashCopy[];>>
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], D];
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.
d[sDim]
FROM
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];
<<spand: Set ~ Sets.CreateHashSet[d.eSpace];
PerSpan:
PROC [pv: Sets.Value]
RETURNS [
BOOL] ~ {
p: Port ~ NARROW[pv.VA];
pKidSeq: Seq ~ d.SubSeq[p];
paiSeq: Seq ~ pKidSeq.Compose[a.statrep.apToPAI];
xSeq: Seq ~ paiSeq.Compose[a.statrep.paiToX, [TRUE, FALSE]].CreateHashCopy[];
ySeq: Seq ~ paiSeq.Compose[a.statrep.paiToY, [TRUE, FALSE]].CreateHashCopy[];
spansXY:
ARRAY Dim2
OF
BOOL ~ [
X: xSeq.Equal[xId] AND ySeq.SetOn[right].Equal[setOf0],
Y: xSeq.SetOn[right].Equal[setOf0] AND ySeq.Equal[yId]];
IF spansXY[X] = spansXY[Y] THEN RETURN [FALSE];
IF spansXY[sDim]
THEN {
plKidSeq: Seq ~ pKidSeq.ShiftAndClip[clip: [0, nl-1]].Compose[lRepInv].CreateHashCopy[];
phKidSeq: Seq ~ pKidSeq.ShiftAndClip[shift: IS.ISub[0, nl], clip: [nl, nlh]].Compose[hRepInv].CreateHashCopy[];
pNames: Set ~ act.PNames[p];
pl: Port ~ CreatePort[actl, pNames, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, plKidSeq];
ph: Port ~ CreatePort[acth, pNames, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, phKidSeq];
IF NOT spand.AddA[pl] THEN ERROR;
IF NOT spand.AddA[ph] THEN ERROR}
RETURN [FALSE]};>>
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 spans.Scan[PerSpan].found THEN ERROR;>>
IF insts.Scan[PerInst].found THEN ERROR;
DeleteCellType[act, NIL];
RETURN}}};