DIRECTORY CD, CDBasics, CDSymbolicObjects, Core, CoreClasses, CoreOps, CoreProperties, PW, PWPins, Rope, Route, RTBasic, SC, SCCoreUtil, SCInstUtil, SCObjUtil, SCNetUtil, SCPrivate, SCUtil, TerminalIO; SCGetStructureImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDSymbolicObjects, CoreOps, CoreProperties, PW, PWPins, Rope, RTBasic, SC, SCCoreUtil, SCInstUtil, SCObjUtil, 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, NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]]; IF net # NIL THEN SC.Signal[callingError, Rope.Cat["Duplicate net name: ", NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]]] ELSE net _ SCNetUtil.DefineNet[handle, wire]}; ExternalWireProc: SCCoreUtil.EachWireProc = { instance: SCPrivate.Instance _ SCUtil.FindInstance[handle, NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]]; net: SCPrivate.Net _ SCUtil.FindNet[handle, NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]]; IF net = NIL THEN SC.Signal[callingError, Rope.Cat["Missing net name: ", NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]]]; IF instance # NIL THEN SC.Signal[callingError, Rope.Cat["Duplicate port name: ", NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]], ", object: ", parms.portObject.name]]; IF instance = NIL AND net # NIL THEN {instance _ SCInstUtil.DefineInstance[handle, NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]], parms.portObject, NIL, NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]]; SCNetUtil.AddConnection[handle, net, instance, parms.portObject.pins.p[0], 0]; net.externNet _ externalNet; GetIOProperties[handle, instance, net, wire]}}; InstanceProc: SCCoreUtil.EachInstanceProc = { object: SCPrivate.Object _ SCUtil.FindObject[handle, NARROW[CoreProperties.GetCellTypeProp[cellInstance.type, CoreOps.nameProp]]]; IF object = NIL THEN object _ DefineObject[handle, NARROW[CoreProperties.GetCellTypeProp[cellInstance.type, CoreOps.nameProp]], logic, cellInstance.type]; IF object = NIL THEN SC.Signal[callingError, Rope.Cat["Object is not defined: ", NARROW[CoreProperties.GetCellTypeProp[cellInstance.type, CoreOps.nameProp]], "\n"]] ELSE {GetCellName: PROC [cellInstance: CoreClasses.CellInstance] RETURNS [name: Rope.ROPE _ ""] = { name _ NARROW[CoreProperties.GetCellInstanceProp[cellInstance, CoreOps.nameProp]]}; EachInstancePin: SCCoreUtil.EachInstancePinProc = { IF ~SCUtil.IsPowerName[handle, NARROW[CoreProperties.GetWireProp[publicWire, CoreOps.nameProp]]] THEN {net: SCPrivate.Net _ SCUtil.FindNet[handle, NARROW[CoreProperties.GetWireProp[actualWire, CoreOps.nameProp]]]; unconnected: REF ANY _ CoreProperties.GetProp[actualWire.properties, SC.unconnectedProp]; IF unconnected = NIL THEN { pin: SCPrivate.ObjectPin _ SCUtil.FindPin[object, NARROW[CoreProperties.GetWireProp[publicWire, CoreOps.nameProp]]]; -- get the pin IF net = NIL THEN {SC.Signal[callingError, Rope.Cat[Rope.Cat["Net not defined: ", NARROW[CoreProperties.GetWireProp[actualWire, CoreOps.nameProp]], " 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]; GetLogicProperties[handle, instance, cellInstance]}}}; 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.instances.inst _ NEW[SCPrivate.InstsOb]; structureData.nets _ NEW[SCPrivate.NetsRec]; structureData.nets.nets _ NEW[SCPrivate.NetArray]; 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; numClocks: NAT _ 0; minWidth: INT _ rules.CDLambda*24 + rules.trunkSpacing; net: SCPrivate.Net _ SCUtil.FindNet[handle, powerBuses[lRSide].name]; pWidth: SC.Number _ IF net # NIL THEN MAX[minWidth, net.trunkWidth + rules.trunkSpacing] ELSE minWidth; powerBuses[lRSide].width _ pWidth; powerBuses[lRSide].net _ net; 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: PWPins.InstanceEnumerator = { name: Rope.ROPE _ CDSymbolicObjects.GetName[inst]; IF ~SCUtil.IsPowerName[handle, name] AND CDSymbolicObjects.IsSymbolicOb[inst.ob] 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 _ PW.Get[parms.libDesign, 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; [] _ PWPins.EnumerateDeepPins[ob, CountPins]; object.pins _ NEW[SCPrivate.ObjectPinsRec[object.numPins]]; IF object.numPins > 0 THEN { PinEnum: PWPins.InstanceEnumerator = { name: Rope.ROPE _ CDSymbolicObjects.GetName[inst]; IF ~SCUtil.IsPowerName[handle, name] AND CDSymbolicObjects.IsSymbolicOb[inst.ob] THEN {pinPos: SCPrivate.PinPos; rect: SC.Rect; objectPin: SCPrivate.ObjectPin; name: Rope.ROPE _ CDSymbolicObjects.GetName[inst]; layer: SC.Layer _ CDSymbolicObjects.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}}; [] _ PWPins.EnumerateDeepPins[ob, PinEnum]}; IF cellType # NIL THEN { WireEnum: SCCoreUtil.EachWireProc = { IF ~SCUtil.IsPowerName[handle, NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]] THEN {IF SCUtil.FindPin[object, NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]] = 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.q - py, object.size.p - px], rect] ELSE RETURN [[bottom, py, px], rect]}; GetLogicProperties: PROCEDURE [handle: SC.Handle, instance: SCPrivate.Instance, cellInstance: CoreClasses.CellInstance] = { ProcProps: PROC [prop: ATOM, val: REF ANY] ~ { SELECT TRUE FROM prop = $Row => instance.fnlRow _ NARROW[val, REF INT]^; prop = $PosOnRow => instance.fnlPos _ NARROW[val, REF INT]^; ENDCASE; }; CoreProperties.Enumerate[cellInstance.properties, ProcProps]}; GetIOProperties: PROCEDURE [handle: SC.Handle, instance: SCPrivate.Instance, net: SCPrivate.Net, wire: Core.Wire] = { ProcProps: PROC [prop: ATOM, val: REF ANY] ~ { SELECT TRUE FROM prop = $Side => instance.fnlSide _ NARROW[val, REF SC.SideOrNone]^; prop = $PosOnSide => instance.fnlPos _ NARROW[val, REF INT]^; prop = $LeftPower => { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; layoutData.powerBuses[left].name _ NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]; layoutData.powerBuses[left].net _ net}; prop = $RightPower => { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; layoutData.powerBuses[right].name _ NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]; layoutData.powerBuses[right].net _ net}; prop = $LeftClock => {}; prop = $RightClock => {}; ENDCASE; }; CoreProperties.Enumerate[wire.properties, ProcProps]}; ProcClock: PROCEDURE [descName: ATOM, lRSide: SCPrivate.LRSide] RETURNS [acSide: SCPrivate.AcBusSides] = BEGIN clockSignalNames: LIST OF Rope.ROPE _ NIL; -- GetRopeListProp[descName]; acSide _ NEW[SCPrivate.AcBusSidesRec]; FOR nameList: LIST OF Rope.ROPE _ clockSignalNames, nameList.rest WHILE nameList # NIL DO acSide.count _ acSide.count + 1 ENDLOOP; IF acSide.count > 0 THEN { index: NAT _ 0; acSide.sigs _ NEW[SCPrivate.AcBusSigsRec[acSide.count]]; FOR nameList: LIST OF Rope.ROPE _ clockSignalNames, nameList.rest WHILE nameList # NIL DO acSide.sigs[index].name _ nameList.first; acSide.sigs[index].onSide _ lRSide; index _ index + 1; ENDLOOP}; END; DestroyStructure: PUBLIC PROC [handle: SC.Handle] ~ { EachObj: SCObjUtil.EachObjectProc ~ { EachPin: SCObjUtil.EachPinProc ~ { objectPin.cdPin _ NIL}; [] _ SCObjUtil.EnumeratePinsOnObject[object, EachPin]; object.pins _ NIL; object.cdOb _ NIL; objects.ob[object.objectNum] _ NIL}; EachInst: SCInstUtil.EachInstanceProc ~ { EachPin: SCInstUtil.EachPinProc ~ { netPin.pin _ NIL; netPin.net _ NIL}; [] _ SCInstUtil.EnumeratePinsOnInst[instance, EachPin]; instance.pinNets _ NIL; instance.ftNet _ NIL; instances.inst[instance.instanceNum] _ NIL}; EachNet: SCNetUtil.EachNetProc ~ { EachPin: SCNetUtil.EachPinProc ~ { netPin.pin _ NIL; netPin.instance _ NIL}; [] _ SCNetUtil.EnumeratePinsOnNet[net, EachPin]; net.pins _ NIL; net.acBus _ NIL; net.netDat _ NIL; nets.nets[net.netNum] _ NIL}; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; objects: SCPrivate.Objects _ structureData.objects; instances: SCPrivate.Instances _ structureData.instances; nets: SCPrivate.Nets _ structureData.nets; [] _ SCObjUtil.EnumerateAllObjects[handle, EachObj]; [] _ SCInstUtil.EnumerateAllInstances[handle, EachInst]; [] _ SCNetUtil.EnumerateNets[handle, EachNet]; structureData.objects _ NIL; structureData.instances _ NIL; structureData.nets _ NIL; handle.structureData _ NIL}; END. ///stdcell/SCGetStructureImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Last Edited by: Preas, September 9, 1985 10:06:38 am PDT Frank Bowers February 3, 1986 5:41:01 pm PST Preas, April 4, 1986 6:33:08 pm PST get design data by reading Core connectivity and ChipnDale cells this is a lot to go through to get an instance name this is a HACK!! Core does not permit unconnected pins add connection for comp, pin set up the private data get auxalliary components fix up the bus widths based on connectivity get physical description and define the type enter a new object into standard cell data structure define the pins on the object check physical pins against the logical pins analyze cell for relevant parameters get signals to route without feedthrus Κ ϋ˜šœ"™"Icodešœ Οmœ1™<—™8K™,K™#—J˜J™@J˜šΟk ˜ Jšžœ˜J˜ J˜J˜Jšœ ˜ J˜J˜Jšžœ˜J˜Jšœ˜J˜J˜Jšžœ˜Jšœ ˜ Jšœ ˜ J˜ Jšœ ˜ Jšœ ˜ J˜Jšœ ˜ —J˜šΟnœžœž˜!Kšžœžœ8žœžœC˜’Kšžœ ˜Kšžœžœ˜ K˜Kšž˜K˜Kšœžœžœ˜K˜šŸ œžœž œ žœ!˜KKšžœžœ˜K˜šŸœ˜-Jšœ,žœ6˜hJš žœžœžœžœ7žœ6˜‡šž˜Jšœ)˜)J˜——šŸœ˜-Jšœ;žœ6˜wJšœ,žœ6˜hJš žœžœžœžœ5žœ7˜†Jš žœ žœžœžœ8žœ\˜³š žœ žœžœžœž˜$Jšœ.žœHžœžœ6˜½JšœN˜NJ˜Jšœ/˜/—J˜—šŸ œ!˜-Jšœ5žœG˜‚šžœ žœžœ˜Kšœžœa˜…—šžœ žœžœ˜Kšžœ:žœM˜—šž˜š œŸ œžœ*žœ žœ ˜^Jšœ3™3J˜JšœžœF˜SJ˜—šŸœ$˜3šžœžœ<ž˜eJšœ-žœ<˜oKšœ žœžœ1žœ˜YK™Kšœ6™6šžœžœžœ˜Kšœ2žœ=Οc˜ƒK˜šžœžœž˜Kšœžœ>žœ…˜Μ—šžœžœž˜Kšœžœ€˜ƒ—š žœžœžœžœžœ˜!Kšœ™šžœ žœžœž˜-Kšœ5˜5šžœ žœžœ˜šžœ#žœ˜*JšœA˜A——Kšžœ˜ ———K˜——Jšœržœ˜wK˜/šžœžœžœ˜Kšžœ‡˜‰—šžœ˜KšœD˜DJšœ6˜6—J˜——J˜Jšœ™Kšœ&žœ˜JšœJ˜JJšœ žœC˜RJšœ žœ8˜GK™Kšœ+™+Jšœ˜Jšœ˜Jšžœžœ ˜-K˜—šŸœž œ žœ$˜BK˜Kšœ#žœ˜=Kšœ9˜9Kšœ0˜0Kšœ2˜2Kšœ žœ˜Kšœ7˜7KšœE˜Ešœžœ žœžœž˜%Kšœ2˜2Kšœ˜—Jšœ"˜"šœ˜K˜—šžœ žœžœž˜6šžœ4ž˜:Jšœ˜Jšœk˜k—Jšžœ˜—Jšœ7˜7—K˜š Ÿ œž œ žœžœ8žœ˜}Kšžœžœ˜,Kšœ,™,K™Kšœ4™4šŸ œ˜(Jšœ žœ#˜2Jšžœ#žœ)ž˜UJšœ&˜&J˜—Kšœ)žœ˜FKšœ3˜3Kšœžœ˜.Kšœžœ žœ"˜4Jšœ žœ˜Kšœžœ˜Kšœ˜K˜šžœžœžœ˜KšžœT˜VKšžœ˜K˜—Kšœ žœ˜Kšœ?˜?KšœC˜CK˜Kšœ"˜"Kšœ žœCžœ˜cKšœ#˜#K™Jšœ™Jšœ-˜-Jšœžœ*˜;šžœžœ˜šŸœ˜&Jšœ žœ$˜3šžœ#žœ)ž˜UJšœ˜Jšœžœ˜Jšœ˜Jšœ žœ#˜2JšœžœΟrœ!˜3JšœH˜HJšœ žœ<‘œ˜RJšœ#˜#Jšœ˜K˜—Jšœ,˜,——J˜Jšœ,™,šžœ žœžœ˜šŸœ˜%šžœžœ6ž˜_šœžœžœ8žœž˜aJšžœs˜u——J˜—Jšœ@˜@—K˜—š Ÿ œž œ žœžœžœžœ˜†K˜Kšœ)˜)šžœ žœžœ˜KšžœL˜NKšžœ˜K˜—Kšœ+˜+šžœ žœžœ˜KšžœR˜T——K˜š Ÿ œž œ žœžœžœžœ˜iK˜Kšœ)˜)šžœ žœžœ˜KšžœE˜GKšžœ˜K˜—Kšœ(˜(šžœ žœžœ˜KšžœK˜M——K˜šŸ œž œ žœ(žœ˜SKšžœ"žœ ˜5Kšœ$™$J˜Kšœžœ˜Kšœ˜Kšœ˜Kšœ%˜%Kšœ%˜%Kšœ˜Kšœ˜Kšžœžœžœ6˜YKšžœžœ˜&K˜—šŸœž œ žœR˜{š Ÿ œžœžœžœžœ˜.šžœžœž˜Kšœ!žœžœžœ˜7Kšœ&žœžœžœ˜˜>K˜—šŸœž œ žœO˜uš Ÿ œžœžœžœžœ˜.šžœžœž˜Kšœ#žœžœžœ˜CKšœ'žœžœžœ˜=šœ˜Kšœ#žœ˜=Kšœ#žœ5˜^Kšœ'˜'—šœ˜Kšœ#žœ˜=Kšœ$žœ5˜_Kšœ(˜(—Kšœ˜Kšœ˜Kšžœ˜—Kšœ˜—Kšœ6˜6—K˜Jšœ&™&šŸ œž œ žœ˜?Jšžœ!˜(J˜Jšž˜Jšœžœžœžœ%˜HJšœ žœ˜&š žœ žœžœžœ#žœ žœž˜YJ˜Jšžœ˜J˜—šžœžœ˜Jšœžœ˜Jšœžœ'˜8š žœ žœžœžœ#žœ žœž˜YJšœ)˜)Jšœ#˜#J˜Jšžœ˜ ——Jšžœ˜J˜—šŸœžœžœ žœ ˜5K˜šŸœ˜%šŸœ˜"Kšœžœ˜K˜—Kšœ6˜6Kšœžœ˜Kšœžœ˜Kšœžœ˜$K˜—šŸœ!˜)šŸœ˜#Kšœ žœ˜Kšœ žœ˜K˜—Kšœ7˜7Kšœžœ˜Kšœžœ˜Kšœ'žœ˜,K˜—šŸœ˜"šŸœ˜"Kšœ žœ˜Kšœžœ˜K˜—Kšœ0˜0Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœžœ˜K˜—Kšœ)žœ˜FKšœ3˜3Kšœ9˜9Kšœ*˜*Kšœ4˜4Kšœ8˜8Kšœ.˜.K˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜—K˜Kšžœ˜——…—3C'