<> <> DIRECTORY AbSets, BiRelBasics, BiRels, IntStuff, IO, LichenDataOps, LichenDataStructure, LichenIntBasics, Rope, SetBasics; LichenFusing: CEDAR PROGRAM IMPORTS AbSets, BiRels, IntStuff, IO, LichenDataOps, LichenDataStructure, SetBasics = BEGIN OPEN IS:IntStuff, LIB:LichenIntBasics, LIB, LichenDataStructure, LichenDataOps, Sets:AbSets; FuseCIs: PROC [ct: CellType, ps1, ps2: Set--of Port--, inhibit: Port, log: IO.STREAM _ NIL] ~ { d: Design ~ ct.d; allps: Set ~ ct.CTParts[p]; allInsts: Set ~ ct.CtInsts[]; FuseInst: PROC [civ: Sets.Value] RETURNS [BOOL] ~ { ci: CellInstance ~ NARROW[civ.VA]; ws1: Set ~ ci.conns.Image[ps1]; IF ws1.Size.EN # 1 THEN RETURN [FALSE]; {ws2: Set ~ ci.conns.Image[ps2]; IF ws2.Size.EN # 1 THEN RETURN [FALSE]; IF inhibit#NIL THEN { w: Wire ~ ConndWire[ci, inhibit]; IF w.conns.Size.EN # 1 THEN RETURN [FALSE]; }; {cct: CellType ~ d.CiCct[ci]; exp: Set ~ cct.asu.exports.Image[ws1, rightToLeft] .Union[ cct.asu.exports.Image[ws2, rightToLeft] ]; w1: Wire ~ NARROW[ws1.TheElt.VA]; w2: Wire ~ NARROW[ws2.TheElt.VA]; IF exp.Size.EN > 1 THEN ERROR; IF w1#w2 THEN { IF log#NIL THEN log.PutF["Fusing %g and %g, and deleting %g\n", [rope[Describe[d, w1, cct]]], [rope[Describe[d, w2, cct]]], [rope[Describe[d, ci, d]]]]; [] _ MergeNets[d, w1, w2, TRUE]; log _ log} ELSE { IF log#NIL THEN log.PutF["Deleting %g\n", [rope[Describe[d, ci, d]]]]; inhibit _ inhibit}; DeleteInsts[d, Sets.CreateSingleton[civ, d.eSpace], TRUE]; RETURN [FALSE]}}}; IF NOT (ps1.Subset[allps] AND ps2.Subset[allps]) THEN ERROR; IF allInsts.Scan[FuseInst].found THEN ERROR; RETURN}; END.