SCNetUtilImpl.mesa
Copyright Ó 1986, 1987 by Xerox Corporation. All rights reserved.
Frank Bowers January 27, 1986 4:15:38 pm PST
Preas September 29, 1987 3:59:15 pm PDT
Cong, August 20, 1987 5:47:10 pm PDT
Jean-Marc Frailong October 14, 1987 12:54:23 pm PDT
chan utility routines
DIRECTORY
Core, CoreFlat, CoreRoute, RefTab, Rope, Route, RTSets, SC, SCInstUtil, SCNetUtil, SCPrivate, SCRowUtil;
SCNetUtilImpl: CEDAR PROGRAM
IMPORTS CoreRoute, RefTab, Rope, SC, SCInstUtil, SCNetUtil, SCRowUtil
EXPORTS SCNetUtil
SHARES SC =
BEGIN
Global data structure maintenance
DefineNet: PUBLIC PROC [handle: SC.Handle, flatWire: CoreFlat.FlatWire] RETURNS [net: SCPrivate.Net] = {
Create a net corresponding to a canonical flat wire & scream if already defined
structureData: SCPrivate.StructureData = NARROW[handle.structureData];
rules: Route.DesignRules = handle.rules.rowRules;
name: Rope.ROPE = CoreRoute.LabelFlatWire[handle.coreCellType, flatWire^];
IF RefTab.Fetch[structureData.nets, flatWire].found THEN SC.Error[callingError, Rope.Cat["Redefinition of net ", name]];
net ← NEW[SCPrivate.NetRec ← [name: name, publicWire: NIL, trunkWidth: rules.trunkWidth, branchWidth: rules.branchWidth, routeTopology: ALL[[none, none]], pins: NIL]];
net.num ← nets.count;
net.ftsOnRow ← RTSets.RTLgSetEmpty;
net.chanExits[left] ← net.chanExits[right] ← RTSets.RTLgSetEmpty;
IF NOT RefTab.Insert[structureData.nets, flatWire, net] THEN ERROR; -- tested just before...
};
FindNet: PUBLIC PROC [handle: SC.Handle, flatWire: CoreFlat.FlatWire] RETURNS [net: SCPrivate.Net] ~ {
Locate a net by coresponding canonical flat wire, scream if not found
structureData: SCPrivate.StructureData = NARROW[handle.structureData];
net ← NARROW [RefTab.Fetch[structureData.nets, flatWire].val];
IF net=NIL THEN SC.Error[callingError, Rope.Cat["Net not found : ", CoreRoute.LabelFlatWire[handle.coreCellType, flatWire^]]];
};
FindPublicNet: PUBLIC PROC [handle: SC.Handle, wire: Core.Wire] RETURNS [net: SCPrivate.Net] ~ {
Locate a net by the corresponding public wire, scream if not found
flatWire: CoreFlat.FlatWire = NEW [CoreFlat.FlatWireRec ← [flatCell: CoreFlat.rootCellType, wireRoot: public, wire: wire]];
net ← FindNet[handle, flatWire];
};
EnumerateNets: PUBLIC PROC [handle: SC.Handle, eachNet: SCNetUtil.EachNetProc] RETURNS [quit: BOOL] ~ {
Enumerate all nets that have pins on them
EachNet: RefTab.EachPairAction ~ {
net: SCPrivate.Net = NARROW [val];
IF net.pins#NIL THEN quit ← eachNet[net];
};
structureData: SCPrivate.StructureData ← NARROW[handle.structureData];
quit ← RefTab.Pairs[structureData.nets, EachNet];
};
Nets and instances
NetsOnInst: PUBLIC PROC[insts: SCPrivate.InstanceList] RETURNS [nets: SCPrivate.NetList ← NIL] ~ {
Return the list of all nets that are connected to the list of instances. The returned list has no duplicates
WHILE insts#NIL DO -- enumerate required instances
inst: SCPrivate.Instance = insts.first;
insts ← insts.rest;
FOR i: NAT IN [0..inst.pinNets.size) DO -- enumerate PinNets on instance
net: SCPrivate.Net = inst.pinNets[i].net;
IF net=NIL THEN LOOP; -- ignore NIL nets
FOR netList: SCPrivate.NetList ← nets, netList.rest WHILE netList#NIL DO
IF netList.first=net THEN EXIT; -- net is already in the result list
REPEAT FINISHED => nets ← CONS [net, nets]; -- new net connected
ENDLOOP; -- adding net to list
ENDLOOP; -- enumerating pins on instance
ENDLOOP; -- enumerating list of instances
};
InstsOnNets: PUBLIC PROC[nets: SCPrivate.NetList] RETURNS [insts: SCPrivate.InstanceList ← NIL] ~ {
InstProc: SCNetUtil.EachInstProc ~ {IF instance # NIL THEN insts ← CONS[instance, insts]};
[] ← SCNetUtil.EnumerateInstsOnNets[nets, InstProc];
};
EnumerateInstsOnNets: PUBLIC PROC[nets: SCPrivate.NetList, eachInst: SCNetUtil.EachInstProc] RETURNS [quit: BOOLFALSE] ~ {
PinProc: SCNetUtil.EachPinProc = {
instance: SCPrivate.Instance ← netPin.instance;
IF instance # NIL THEN {
found: BOOLEANFALSE;
FOR instanceList: SCPrivate.InstanceList ← insts, instanceList.rest WHILE instanceList # NIL AND ~found DO
IF instanceList.first = instance THEN found ← TRUE;
ENDLOOP;
IF ~found THEN {insts ← CONS[instance, insts]; quit ← eachInst[instance]};
};
};
insts: SCPrivate.InstanceList ← NIL;
FOR netList: SCPrivate.NetList ← nets, netList.rest WHILE netList # NIL AND ~quit DO
[] ← SCNetUtil.EnumeratePinsOnNet[netList.first, PinProc];
ENDLOOP;
};
Nets and pins
EnumeratePinsOnNet: PUBLIC PROC [net: SCPrivate.Net, eachPin: SCNetUtil.EachPinProc] RETURNS [quit: BOOLFALSE] ~ {
FOR netPin: SCPrivate.NetPin ← net.pins, netPin.link UNTIL (netPin=NIL OR quit) DO
quit ← eachPin[netPin];
ENDLOOP;
};
Connections
AddConnection: PUBLIC PROC [handle: SC.Handle, net: SCPrivate.Net, instance: SCPrivate.Instance, pin: SCPrivate.ObjectPin, pinIndex: NAT, pinClass: SCPrivate.PinType] ~ {
net.pins ← NEW [SCPrivate.NetPinRec ← [pinClass: pinClass, instance: instance, pin: pin, link: net.pins]]; -- add pin ahead of list
instance.pinNets.n[pinIndex] ← NEW[SCPrivate.PinNetRec ← [pin: pin, pinInChan: NIL, net: net]];
};
RemoveConnections: PUBLIC PROC [handle: SC.Handle, instance: SCPrivate.Instance] ~ {
pinNets: SCPrivate.PinNets ← instance.pinNets;
FOR index: NAT IN [0 .. pinNets.size-1] DO pinNets.n[index] ← NIL ENDLOOP;
};
Utilities
RemoveFtsOnNet: PUBLIC PROC [handle: SC.Handle, net: SCPrivate.Net] ~ {
Remove all feedthroughs from the net list
result: SCPrivate.NetPin ← NIL; -- the new result
source: SCPrivate.NetPin ← net.pins; -- the initial pins
WHILE source#NIL DO
nextPin: SCPrivate.NetPin = source.link; -- link may be overwritten
IF source.pinClass#ftPin THEN {source.link ← result; result ← source}; -- add to result
source ← nextPin;
ENDLOOP;
net.pins ← result;
};
ExitOnSide: PUBLIC PROC [handle: SC.Handle, net: SCPrivate.Net, side: SC.Side] RETURNS [onThisSide: BOOLEAN] ~ {
EachInstance: SCRowUtil.EachInstProc ~ {
CheckPin: SCInstUtil.EachPinProc = {
[instance: SCPrivate.Instance, pin: NAT, netPin: SCPrivate.PinNet]
IF netPin.net = net THEN quit ← TRUE;
};
quit ← SCInstUtil.EnumeratePinsOnInst[instance, CheckPin];
};
onThisSide ← SCRowUtil.EnumerateAllInstsOnSide[handle, side, EachInstance];
};
END.