<> <> <> DIRECTORY CD, CDBasics, CDGenerate, CDPinObjects, Core, CoreClasses, CoreProperties, CoreRecord, Rope, Route, RTBasic, SC, SCCoreUtil, SCInstUtil, SCNetUtil, SCPrivate, SCUtil, TerminalIO; SCGetStructureImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDGenerate, CDPinObjects, CoreClasses, CoreProperties, Rope, RTBasic, SC, SCCoreUtil, SCInstUtil, SCNetUtil, SCUtil, TerminalIO EXPORTS SCPrivate SHARES SC = BEGIN debug: BOOLEAN _ FALSE; GetStructure: PUBLIC PROCEDURE [handle: SC.Handle, cellType: Core.CellType] RETURNS [done: BOOLEAN] = { InternalWireProc: SCCoreUtil.EachWireProc = { net: SCPrivate.Net _ SCUtil.FindNet[handle, wire.name]; IF net # NIL THEN SC.Signal[callingError, Rope.Cat["Duplicate net name: ", wire.name]] ELSE net _ SCNetUtil.DefineNet[handle, wire.name]}; ExternalWireProc: SCCoreUtil.EachWireProc = { instance: SCPrivate.Instance _ SCUtil.FindInstance[handle, wire.name]; net: SCPrivate.Net _ SCUtil.FindNet[handle, wire.name]; IF net = NIL THEN SC.Signal[callingError, Rope.Cat["Missing net name: ", wire.name]]; IF instance # NIL THEN SC.Signal[callingError, Rope.Cat["Duplicate port name: ", wire.name, ", object: ", parms.portObject.name]]; IF instance = NIL AND net # NIL THEN {instance _ SCInstUtil.DefineInstance[handle, wire.name, parms.portObject, NIL, wire.name]; SCNetUtil.AddConnection[handle, net, instance, parms.portObject.pins.p[0], 0]; GetIOHints[handle, instance, wire.properties]}}; InstanceProc: SCCoreUtil.EachInstanceProc = { object: SCPrivate.Object _ SCUtil.FindObject[handle, cellInstance.type.name]; IF object = NIL THEN object _ DefineObject[handle, cellInstance.type.name, logic, cellInstance.type]; IF object = NIL THEN SC.Signal[callingError, Rope.Cat["Object is not defined: ", cellInstance.type.name, "\n"]] ELSE {GetCellName: PROC [cellInstance: CoreClasses.CellInstance] RETURNS [name: Rope.ROPE _ ""] = { <> name _ NARROW[CoreProperties.GetCellInstanceProp[cellInstance, CoreClasses.instanceNameProp]]}; EachInstancePin: SCCoreUtil.EachInstancePinProc = { IF ~SCUtil.IsPowerName[handle, actualWire.name] THEN {net: SCPrivate.Net _ SCUtil.FindNet[handle, actualWire.name]; pin: SCPrivate.ObjectPin _ SCUtil.FindPin[object, publicWire.name]; -- get the pin IF net = NIL THEN {SC.Signal[callingError, Rope.Cat[Rope.Cat["Net not defined: ", actualWire.name, " on component: ", instance.name], Rope.Cat[", type: ", object.name]]]}; IF pin = NIL THEN {SC.Signal[callingError, Rope.Cat[Rope.Cat["not enough pins on component: ", instance.name], Rope.Cat[", type: ", object.name]]]}; IF pin # NIL AND net # NIL THEN { <> FOR pinIndex: NAT IN [0 .. object.numPins) DO objPin: SCPrivate.ObjectPin _ objectPins.p[pinIndex]; IF objPin # NIL THEN IF Rope.Equal[objPin.name, pin.name] THEN SCNetUtil.AddConnection[handle, net, instance, objPin, pinIndex]; ENDLOOP}}}; instance: SCPrivate.Instance _ SCInstUtil.DefineInstance[handle, GetCellName[cellInstance], object, cellInstance, NIL]; objectPins: SCPrivate.ObjectPins _ object.pins; IF objectPins = NIL THEN SC.Signal[callingError, Rope.Cat[Rope.Cat["Pins not defined on instance: ", instance.name], Rope.Cat[", object: ", object.name, "\n"]]] ELSE { [] _ SCCoreUtil.EnumFlatInstancePins[cellInstance, EachInstancePin]; GetLogicHints[handle, instance, cellInstance.properties]}}}; <> recCell: CoreClasses.RecordCellType _ NARROW[cellType.data]; parms: SCPrivate.Parms _ NARROW[handle.parms]; portName:Rope.ROPE _ "IOPort"; -- need to get from Core ftName:Rope.ROPE _ "Feedthru"; -- need to get from Core structureData: SCPrivate.StructureData _ NARROW[NEW[SCPrivate.StructureDataRec], SCPrivate.StructureData]; structureData.objects _ NEW[SCPrivate.ObjectsRec]; structureData.instances _ NEW[SCPrivate.InstancesRec]; structureData.nets _ NEW[SCPrivate.NetsRec]; handle.structureData _ structureData; parms.portObject _ DefineIOType[handle, portName]; parms.ftObject _ DefineAuxType[handle, ftName, ft]; <> TerminalIO.WriteRope["Getting structure description . . .\n"]; done _ ~SCCoreUtil.EnumerateFlatWires[recCell.internal, InternalWireProc]; done _ done AND ~SCCoreUtil.EnumerateFlatWires[cellType.public, ExternalWireProc]; done _ done AND ~SCCoreUtil.EnumerateInstances[cellType, InstanceProc]; <<>> <> DoBuses[handle, left]; DoBuses[handle, right]; IF debug THEN SCUtil.WriteStructure[handle]}; DoBuses: PROCEDURE [handle: SC.Handle, lRSide: RTBasic.LRSide] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; powerBuses: SCPrivate.PowerBuses _ layoutData.powerBuses; acBuses: SCPrivate.AcBuses _ layoutData.acBuses; rules: Route.DesignRules _ handle.rules.sideRules; pWidth: SC.Number _ 0; numClocks: NAT _ 0; net: SCPrivate.Net _ SCUtil.FindNet[handle, powerBuses[lRSide].name]; IF net # NIL THEN pWidth _ net.trunkWidth + rules.trunkSpacing; -- fill in width !!! powerBuses[lRSide].width _ pWidth; FOR clockIndex: NAT IN [0 .. acBuses[lRSide].count) DO IF acBuses[lRSide].sigs.c[clockIndex].onSide = lRSide THEN {numClocks _ numClocks + 1; acBuses[lRSide].sigs.c[clockIndex].depth _ pWidth + (numClocks-1)*rules.trunkToTrunk + rules.trunkWidth/2}; ENDLOOP; acBuses[lRSide].width _ numClocks* rules.trunkToTrunk}; DefineObject: PROCEDURE [handle: SC.Handle, objectName: Rope.ROPE, class: SCPrivate.CompClass, cellType: Core.CellType _ NIL] RETURNS [object: SCPrivate.Object _ NIL] = { <> <<>> <> CountPins: CDPinObjects.InstanceEnumerator = { name: Rope.ROPE _ CDPinObjects.GetName[inst]; IF ~SCUtil.IsPowerName[handle, name] THEN object.numPins _ object.numPins + 1}; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; objects: SCPrivate.Objects _ structureData.objects; parms: SCPrivate.Parms _ NARROW[handle.parms]; ob: CD.Object _ CDGenerate.FetchNCall[parms.cdTable, parms.cdDesign, objectName]; numPins: NAT _ 0; obRect: CD.Rect; size, orgin: RTBasic.PQPos; IF ob = NIL THEN { SC.Signal[callingError, Rope.Cat["Core object: ", objectName, " not in CND library"]]; RETURN}; obRect _ CD.InterestRect[ob].r; size _ RTBasic.XYToPQ[horizontal, CDBasics.SizeOfRect[obRect]]; orgin _ RTBasic.XYToPQ[horizontal, CDBasics.BaseOfAnyRect[obRect]]; objects.count _ objects.count + 1; object _ NEW[SCPrivate.ObjectRec _ [objectName, objects.count, size, orgin, 0, NIL, class, 0, ob]]; objects.ob[objects.count] _ object; <<>> <> [] _ CDPinObjects.EnumeratePins[ob, CountPins]; object.pins _ NEW[SCPrivate.ObjectPinsRec[object.numPins]]; IF object.numPins > 0 THEN { PinEnum: CDPinObjects.InstanceEnumerator = { name: Rope.ROPE _ CDPinObjects.GetName[inst]; IF ~SCUtil.IsPowerName[handle, name] THEN {pinPos: SCPrivate.PinPos; rect: SC.Rect; objectPin: SCPrivate.ObjectPin; name: Rope.ROPE _ CDPinObjects.GetName[inst]; layer: SC.Layer _ CDPinObjects.GetLayer[inst]; [pinPos, rect] _ GetPinPos[inst.location, inst.ob.size, object, obRect]; objectPin _ NEW[SCPrivate.ObjectPinRec _ [name, pinPos, inst, rect, layer, name]]; object.pins.p[numPins] _ objectPin; numPins _ numPins + 1}}; [] _ CDPinObjects.EnumeratePins[ob, PinEnum]}; <> IF cellType # NIL THEN { WireEnum: SCCoreUtil.EachWireProc = { IF ~SCUtil.IsPowerName[handle, wire.name] THEN {IF SCUtil.FindPin[object, wire.name] = NIL THEN SC.Signal[callingError, Rope.Cat["Physical pins and logical pins on object: ", object.name, " do not correspond"]]}}; [] _ SCCoreUtil.EnumerateFlatWires[cellType.public, WireEnum]}}; DefineAuxType: PROCEDURE [handle: SC.Handle, name: Rope.ROPE, class: SCPrivate.CompClass] RETURNS [object: SCPrivate.Object _ NIL] = { object _ SCUtil.FindObject[handle, name]; IF object # NIL THEN { SC.Signal[callingError, Rope.Cat["Duplicate auxillary object: ", name, "\n"]]; RETURN}; object _ DefineObject[handle, name, class]; IF object = NIL THEN SC.Signal[callingError, Rope.Cat["Auxillary object is not defined: ", name, "\n"]]}; DefineIOType: PROCEDURE [handle: SC.Handle, name: Rope.ROPE] RETURNS [object: SCPrivate.Object _ NIL] = { object _ SCUtil.FindObject[handle, name]; IF object # NIL THEN { SC.Signal[callingError, Rope.Cat["Duplicate IO object: ", name, "\n"]]; RETURN}; object _ DefineObject[handle, name, io]; IF object = NIL THEN SC.Signal[callingError, Rope.Cat["IO object is not defined: ", name, "\n"]]}; GetPinPos: PROCEDURE [loc, size: SC.Pos, object: SCPrivate.Object, obRect: CD.Rect] RETURNS [pinPos: SCPrivate.PinPos, rect: SC.Rect] = { <> px, py: SC.Number; rect.x1 _ loc.x - obRect.x1; rect.y1 _ loc.y - obRect.y1; rect.x2 _ loc.x + size.x - obRect.x1; rect.y2 _ loc.y + size.y - obRect.y1; py _ (rect.y1 + rect.y2)/2; px _ (rect.x1 + rect.x2)/2; IF py > object.size.q/2 THEN RETURN [[top, object.size.p - px, object.size.q - py], rect] ELSE RETURN [[bottom, px, py], rect]}; GetLogicHints: PROCEDURE [handle: SC.Handle, instance: SCPrivate.Instance, properties: Core.Properties] = { }; GetIOHints: PROCEDURE [handle: SC.Handle, instance: SCPrivate.Instance, properties: Core.Properties] = { }; END.