LichenDataImpl2B.Mesa
Last tweaked by Mike Spreitzer on August 22, 1988 3:59:03 pm PDT
DIRECTORY AbSets, BiRels, IntStuff, LichenDataOps, LichenDataStructure, LichenIntBasics, SetBasics;
LichenDataImpl2B: CEDAR PROGRAM
IMPORTS AbSets, BiRels, IntStuff, LichenDataOps, LichenDataStructure, SetBasics
EXPORTS LichenDataOps, LichenDataStructure
=
BEGIN OPEN IS:IntStuff, IB:LichenIntBasics, IB, LichenDataStructure, LichenDataOps, Sets:AbSets;
KnowPartName: PUBLIC PROC [ct: CellType, class: PartClass, part: Part, fullName: SteppyName, onlyIfGood: BOOL]
~ {KnowPartNames[ct, class, part, Sets.CreateSingleton[SnV[fullName], steppyNameSpace], onlyIfGood]};
KnowPartNames: PUBLIC PROC [ct: CellType, class: PartClass, part: Part, fullNames: Set--of SteppyName--, onlyIfGood: BOOL] ~ {
IF onlyIfGood AND ct.d.inheritNames THEN {
bestNewM: Sets.MaybeValue ~ fullNames.AnElt[Sets.fwd];
IF NOT bestNewM.found THEN RETURN;
{bestNew: SteppyName ~ VSn[bestNewM.it];
bestOldM: Sets.MaybeValue ~ ct.fullName[class].Lookup[goal: AV[part], side: left];
IF bestOldM.found THEN {
bestOld: SteppyName ~ VSn[bestOldM.it];
IF GrossSteppyNameGradeCompare[bestOld.grade, bestNew.grade] < equal THEN RETURN};
}};
[] ← ct.fullName[class].AddSet[BiRels.CreateProduct[[Sets.CreateSingleA[part, ct.d.eSpace], fullNames]]];
RETURN};
ForgetPartNames: PUBLIC PROC [ct: CellType, class: PartClass, part: Part, fullNames: Set] ~ {
[] ← ct.fullName[class].RemSet[BiRels.CreateProduct[[Sets.CreateSingleA[part, ct.d.eSpace], fullNames]]];
RETURN};
ForgetPartName: PUBLIC PROC [ct: CellType, class: PartClass, part: Part, fullName: SteppyName] ~ {
[] ← ct.fullName[class].RemPair[[AV[part], SnV[fullName]]];
RETURN};
GrossSteppyNameGradeCompare: PUBLIC PROC [g1, g2: SteppyNameGrade] RETURNS [SetBasics.TotalComparison] ~ {
SELECT TRUE FROM
g1.global<g2.global => RETURN [greater];
g1.global>g2.global => RETURN [less];
g1.gend<g2.gend => RETURN [less];
g1.gend>g2.gend => RETURN [greater];
g1.power<g2.power => RETURN [greater];
g1.power>g2.power => RETURN [less];
g1.global OR g1.gend => RETURN [equal];
g1.nonsubs > 1 AND g2.nonsubs > 1 => RETURN [equal];
g1.nonsubs < g2.nonsubs => RETURN [less];
g1.nonsubs > g2.nonsubs => RETURN [greater];
g1.subs < g2.subs => RETURN [less];
g1.subs > g2.subs => RETURN [greater];
ENDCASE => RETURN [equal]};
PortForWire: PUBLIC PROC [ct: CellType, internal: Wire, mayAdd: BOOL] RETURNS [port: Port] ~ {
mv: Sets.MaybeValue ← ct.asu.exports.Lookup[goal: AV[internal], order: Sets.alleq];
IF NOT mv.found THEN {
[] ← FullySfwdlyExportWires[ct, NonPublicDescendants[ct, internal]];
mv ← ct.asu.exports.Lookup[goal: AV[internal], order: Sets.alleq]};
IF NOT mv.found THEN ERROR;
RETURN [NARROW[mv.MA]]};
FullySfwdlyExportWires: PUBLIC PROC [ct: CellType, wires: Set] RETURNS [Set--of Port--] ~ {
d: Design ~ ct.d;
childWires: Set ~ d.parent.Image[wires, rightToLeft];
badKids: Set ~ childWires.Difference[wires.Union[ct.asu.publics]];
newPorts: Seq--of Port-- ~ CreateSeq[dense: TRUE, oneToOne: TRUE];
DoWire: PROC [w: Wire] RETURNS [p: Port] ~ {
p ← AConndPort[ct, w];
IF p#NIL THEN RETURN;
{kidWires: Seq--of Wire-- ~ BiRels.DeRef[d.sub.ApplyA[w].MDA];
kidPorts: Seq--of Port-- ← nilBiRel;
IF kidWires#nilBiRel THEN {
kidPorts ← BiRels.CreateVector[rightSpace: d.eSpace];
FOR i: LNAT IN [0 .. kidWires.Size.EN) DO
kidWire: Wire ~ NARROW[kidWires.ApplyI[i].MA];
kidPort: Port ~ DoWire[kidWire];
kidPorts.AddNewIA[i, kidPort];
w ← w; ENDLOOP;
w ← w};
p ← CreatePort[ct, IF d.inheritNames THEN WNames[ct, w] ELSE emptySteppySet, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, kidPorts];
Connect[d, w, p, ct];
newPorts.AppendA[p];
RETURN}};
StartExport: PROC [val: Sets.Value] RETURNS [BOOL] ~ {
[] ← DoWire[NARROW[val.VA]];
RETURN [FALSE]};
FixUse: PROC [use: CellUse] ~ {WITH use SELECT FROM
ci: CellInstance => {
cct: CellType ~ d.CiCct[ci];
FOR i: LNAT IN [0 .. newPorts.Size.EN) DO{
p: Port ~ NARROW[newPorts.ApplyI[i].MA];
kidPorts: Seq--of Port-- ~ BiRels.DeRef[d.sub.ApplyA[p].MDA];
kidWires: Seq--of Wire-- ← nilBiRel;
w: Wire;
{IF kidPorts#nilBiRel THEN {
kidWires ← kidPorts.Compose[ci.conns];
IF kidWires.Size # kidPorts.Size THEN GOTO DontDoit;
{ssi: SubsIndex ~ d.SubseqIndex[kidWires];
IF ssi.multiparents THEN GOTO DontDoit;
IF ssi.full THEN {w ← NARROW[ssi.parent]; GOTO GotIt};
IF ssi.parent#NIL THEN GOTO DontDoit;
IF NOT cct.ExportableKids[kidWires] THEN GOTO DontDoit;
}};
w ← CreateWire[cct, IF d.inheritNames THEN ActualNames[d.labelCellTypes.HasMemA[ct], cct.INames[ci], ct.PNames[p]] ELSE emptySteppySet, FALSE, TRUE, TRUE, kidWires];
w ← w;
EXITS GotIt => use ← use};
Connect[d, w, p, ci];
w ← w;
EXITS DontDoit => ct ← ct
}ENDLOOP;
RETURN};
act: CellType => {
FOR i: LNAT IN [0 .. newPorts.Size.EN) DO
p: Port ~ NARROW[newPorts.ApplyI[i].MA];
NoteNewEltPort[act, p];
ct ← ct; ENDLOOP;
RETURN};
ENDCASE => ERROR};
IF NOT badKids.Empty THEN ERROR;
IF NOT wires.Intersection[ct.asu.publics].Empty THEN ERROR;
IF wires.Scan[StartExport].found THEN ERROR;
ct.EnumerateUses[FixUse];
RETURN [newPorts.SetOn[right]]};
Connect: PUBLIC PROC [d: Design, wire: Wire, port: Port, site: Cell] ~ {
cct: CellType ~ d.WCct[wire];
conns: Fn--Port b Wire--;
WITH site SELECT FROM
ci: CellInstance => conns ← ci.conns;
ct: CellType => {conns ← ct.asu.exports; IF ct#cct THEN ERROR};
ENDCASE => ERROR;
[] ← conns.AddAA[port, wire];
[] ← wire.conns.AddAA[port, site];
RETURN};
ConnectPWs: PUBLIC PROC [d: Design, pws: Fn, site: Cell] ~ {
PerPW: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ {
port: Port ~ NARROW[pair[left].VA];
wire: Wire ~ NARROW[pair[right].VA];
Connect[d, wire, port, site];
RETURN [FALSE]};
IF pws.Scan[PerPW].found THEN ERROR;
RETURN};
ConnectPCs: PUBLIC PROC [d: Design, wire: Wire, pcs: BiRel] ~ {
PerPC: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ {
port: Port ~ NARROW[pair[left].VA];
site: Cell ~ NARROW[pair[right].VA];
Connect[d, wire, port, site];
RETURN [FALSE]};
IF pcs.Scan[PerPC].found THEN ERROR;
RETURN};
END.