LichenFusing.Mesa
Last tweaked by Mike Spreitzer on April 13, 1989 5:07:24 pm PDT
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.STREAMNIL] ~ {
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, FALSE];
RETURN [FALSE]}}};
IF NOT (ps1.Subset[allps] AND ps2.Subset[allps]) THEN ERROR;
IF allInsts.Scan[FuseInst].found THEN ERROR;
RETURN};
END.