<> <> 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 RETURN [greater]; g1.global>g2.global => RETURN [less]; g1.gend RETURN [less]; g1.gend>g2.gend => RETURN [greater]; g1.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 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.