LichenArrayExtract.Mesa
Last tweaked by Mike Spreitzer on August 27, 1988 3:30:58 pm PDT
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: BOOLTRUE] ~ {
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];
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}
ELSE {
};
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}}};
END.