<> <> <> <> <> <> <> <<>> 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 <> DefineNet: PUBLIC PROC [handle: SC.Handle, flatWire: CoreFlat.FlatWire] RETURNS [net: SCPrivate.Net] = { <> 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.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] ~ { <> 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] ~ { <> 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] ~ { <> 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]; }; <> NetsOnInst: PUBLIC PROC[insts: SCPrivate.InstanceList] RETURNS [nets: SCPrivate.NetList _ NIL] ~ { <> 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: BOOL _ FALSE] ~ { PinProc: SCNetUtil.EachPinProc = { instance: SCPrivate.Instance _ netPin.instance; IF instance # NIL THEN { found: BOOLEAN _ FALSE; 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; }; <> EnumeratePinsOnNet: PUBLIC PROC [net: SCPrivate.Net, eachPin: SCNetUtil.EachPinProc] RETURNS [quit: BOOL _ FALSE] ~ { FOR netPin: SCPrivate.NetPin _ net.pins, netPin.link UNTIL (netPin=NIL OR quit) DO quit _ eachPin[netPin]; ENDLOOP; }; <> 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; }; <> RemoveFtsOnNet: PUBLIC PROC [handle: SC.Handle, net: SCPrivate.Net] ~ { <> 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.