SplitArray:
PROC [fromArrayCT: CellType] ~ {
fa: Array ~ fromArrayCT.asArray;
faName: ROPE ~ NARROW[Asserting.FnVal[nameReln, fromArrayCT.otherPublic]];
taName: ROPE ~ faName.Cat[subTail];
toArrayCT: CellType ~ CreateArray[design, taName, NIL, toAncestorCT, fa.size2, fa.basePeriod, NIL, NIL];
ta: Array ~ toArrayCT.asArray;
arrayConnectionsV: VarOneToOne--port of toArrayCT é port of fromArrayCT-- ~ PairColls.CreateHashOTO[];
arrayTPToWireV: VarFunction--port of ta b wire-- ~ PairColls.CreateHashFn[];
doomedArrayPortsV: VarSet--of port of fa-- ~ Colls.CreateHashSet[];
portRep: VarFunction--port of fa b non-doomed PortAtIndex-- ~ PairColls.CreateHashFn[invable: FALSE];
NotDoomed:
PROC [sv: StatVertex]
RETURNS [
BOOL]
~ {RETURN [NOT doomedFromPorts.HasMember[sv.port]]};
HasNew:
PROC [sv: StatVertex]
RETURNS [
BOOL]
~ {RETURN [eltConnections.Apply[sv.port, rightToLeft].found]};
toNewComp: SubComponenting ~ CreateSubComponents[fa, HasNew];
inSameNewComp: Relation--between svs of fa-- ~ PairColls.Compose[[toNewComp[TRUE], toNewComp[TRUE].Invert]];
nonDoomedSVs: Set--of sv of fa-- ~ FilterSVs[fa, NotDoomed];
inNonDoomedNewComp: Set--of sv of fa-- ~ inSameNewComp.Image[nonDoomedSVs];
crossings: LIST OF RECORD [hasNew, hasnt: StatVertex, d: Int2] ← NIL;
NoteCrossing:
PROC [in, out: StatVertex,
d: Int2] ~ {
IF inNonDoomedNewComp.HasMember[in]
THEN crossings ← CONS[[in, out, d], crossings]};
tNewStat: StatRep ~ CopySubGraph[fa, HasNew, eltConnections.Invert.AsConst, NoteCrossing];
sizeRange: Range2 ~ SizeRange[fa.size2];
FindRep:
PROC [pair: PairColls.Pair] ~ {
fap: Port ~ NARROW[pair[left]];
dw: DumbWire ~ NARROW[pair[right]];
NotDoomed:
PROC [fep: Port]
RETURNS [
BOOL] ~ {
IF NOT doomedFromPorts.HasMember[fep] THEN RETURN [TRUE];
RETURN [FALSE]};
fep: Port ~ ScanPortsInDumbWire[fa, dw, NotDoomed].ep;
IF fep#
NIL
THEN {
ai: ArrayIndex ~ GetInstForPortInDumbWire[fa, dw, fep];
IF ai=ALL[-1] THEN ERROR;
portRep.AddNewPair[[fap, NEW [PortAtIndexPrivate ← [fep, ai]]]]}
ELSE IF NOT doomedArrayPortsV.AddElt[fap] THEN ERROR;
RETURN};
SetStatRep[toArrayCT, tNewStat, FALSE];
FOR crossings ← crossings, crossings.rest
WHILE crossings #
NIL
DO
rA: Range2 ~ Range2Intersection[sizeRange, Range2Off[sizeRange, Int2Neg[crossings.first.d]]];
irA: Range2 ~ Range2Div[rA, fa.basePeriod, crossings.first.hasNew.phase];
FOR i
f:
NATURAL
IN [
NATURAL[irA[Foo].min] ..
NATURAL[irA[Foo].maxPlusOne])
DO
FOR i
b:
NATURAL
IN [
NATURAL[irA[Bar].min] ..
NATURAL[irA[Bar].maxPlusOne])
DO
aiA: ArrayIndex ~ Int2Mul[[if, ib], fa.basePeriod, crossings.first.hasNew.phase];
aiB: ArrayIndex ~ Int2Add[aiA, crossings.first.d];
tep: Port ~ NARROW[eltConnections.Apply[crossings.first.hasNew.port, rightToLeft].val];
tepw: Wire ~ NARROW[eltTPToWire.Apply[tep].val];
fap: Port--of fromArrayCT-- ~ GetArrayPortForPort[fromArrayCT, aiB, crossings.first.hasnt.port, TRUE];
tap: Port--of toArrayCT-- ~ GetArrayPortForPort[toArrayCT, aiA, tep, TRUE];
np: PairColls.NewsPair ~ arrayConnectionsV.AddPair[[tap, fap]];
IF np#ALL[new] AND np#ALL[same] THEN ERROR;
[] ← arrayTPToWireV.AddPair[[tap, tepw]];
design ← design;
ENDLOOP ENDLOOP;
ENDLOOP;
fa.dumrep.apToWire.Enumerate[FindRep];
{fNewStat: StatRep ~ CopySubGraph[fa, NotDoomed, PairColls.id, NIL];
MakeNewPort:
PROC [pair: PairColls.Pair] ~ {
fap: Port ~ NARROW[pair[left]];
pai: PortAtIndex ~ NARROW[pair[right]];
dw: DumbWire ~ GetDumbWire[fa, pai.port, pai.ai];
IF dw=NIL THEN ERROR--exporting a composite wire that doesn't really exist--;
fa.dumrep.apToWire.AddNewPair[[fap, dw]];
RETURN};
SetStatRep[fromArrayCT, fNewStat, TRUE];
[] ← fa.dumrep.apToWire.RemColl[fa.dumrep.apToWire];
IF NOT fa.dumrep.apToWire.Empty[] THEN ERROR;
portRep.Enumerate[MakeNewPort];
{arrayConnections: ConstFunction ~ arrayConnectionsV.Freeze;
doomedArrayPorts: ConstSet ~ doomedArrayPortsV.Freeze;
arrayTPToWire: ConstFunction ~ arrayTPToWireV.Freeze;
KillDoomedArrayPort:
PROC [ra:
REF
ANY] ~ {
p: Port--of fromArrayCT-- ~ NARROW[ra];
RemovePort[p];
};
FixArrays[design, fromArrayCT, toArrayCT, arrayConnections, doomedArrayPorts, arrayTPToWire, subTail, pairs];
FixInstances[fromArrayCT, toArrayCT, arrayConnections, doomedArrayPorts, arrayTPToWire, pairs];
doomedArrayPorts.Enumerate[KillDoomedArrayPort];
RETURN}}};