<> <> <> <> <> <> <> DIRECTORY CD USING [CreateDrawRef, DrawOb, DrawRectProc, DrawRef, Instance, Layer, undefLayer], CDBasics USING [Intersection, NonEmpty], CDInstances USING [InstRectO], CDOps USING [LayerRope], CDSymbolicObjects USING [EnumerateSymbolicObs, GetLayer, GetName, GetOwner, InstEnumerator], IO USING [Close, EndOf, Error, RIS, SkipWhitespace, STREAM], Properties USING [GetProp, PutProp], Rope USING [Cat, Equal, ROPE], SX USING [AddRect, AdjustNode, Circuit, CircuitNode, IllegalLayer, LogicalCell, SignalName, SpinifexLayerIndex], SXAccess, SXAccessInternal, SXAtoms USING [SignalName, spinifexCircuitDescription], SXUserExtract, SymTab USING [Create, Fetch, Ref, Store]; SXUserExtractImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDInstances, CDOps, CDSymbolicObjects, IO, Properties, Rope, SX, SXAccess, SXAccessInternal, SXAtoms, SymTab EXPORTS SXUserExtract = BEGIN ConnectionPin: PROCEDURE [app: CD.Instance] RETURNS [BOOLEAN] ~ { RETURN [CDSymbolicObjects.GetOwner[app] = NIL AND CDSymbolicObjects.GetLayer[app] # CD.undefLayer] }; DataForRects: TYPE ~ RECORD [ pinLayer: CD.Layer, pinName: Rope.ROPE, cir: REF SX.Circuit, ports: SymTab.Ref ]; TranslateCell: PUBLIC PROCEDURE [cell: REF SX.LogicalCell, CircuitDescription: Rope.ROPE] ~ { AddPinRects: CDSymbolicObjects.InstEnumerator ~ { -- PROC [inst: CD.Instance] RETURNS [quit: BOOL_FALSE] IF ConnectionPin[inst] THEN { dataRef: REF DataForRects _ NEW[DataForRects]; dr: CD.DrawRef ~ CD.CreateDrawRef [[]]; dr.drawRect _ CaptureGeomInPin; dr.devicePrivate _ dataRef; dr.stopFlag _ SXAccess.stopFlag; dr.interestClip _ CDInstances.InstRectO[inst]; dataRef.pinLayer _ CDSymbolicObjects.GetLayer[inst]; dataRef.pinName _ CDSymbolicObjects.GetName[inst]; dataRef.cir _ cell.circuit; dataRef.ports _ ports; CD.DrawOb[dr, cell.cellObj ! SX.IllegalLayer => { SXAccessInternal.PutError[ob: cell.cellObj, r: dr.interestClip, message: Rope.Cat["Material on level ", CDOps.LayerRope[dataRef.pinLayer], " may not appear as an isolated rectangle.\n"]]; GOTO BadRect } ]; EXITS BadRect => NULL }; quit _ FALSE }; -- end AddPinRects ports: SymTab.Ref ~ SymTab.Create[521]; <<-- Flag this cell for special output handling.>> cell.circuit.properties _ Properties.PutProp [cell.circuit.properties, SXAtoms.spinifexCircuitDescription, SXAtoms.spinifexCircuitDescription]; IF ~ Rope.Equal [CircuitDescription, "()"] THEN { [] _ CDSymbolicObjects.EnumerateSymbolicObs[cell.cellObj, AddPinRects]; ReadPortOrder[ cell, IO.RIS[CircuitDescription], ports]; <> }; <> <> <> <> }; CaptureGeomInPin: CD.DrawRectProc -- [r: DesignRect, l: Layer, pr: DrawRef] -- ~ { data: REF DataForRects ~ NARROW[pr.devicePrivate]; IF l = data.pinLayer THEN { r _ CDBasics.Intersection[r, pr.interestClip]; IF CDBasics.NonEmpty[r] THEN { <<-- value parameter may be NIL node has not been added yet>> node: REF SX.CircuitNode ~ SX.AddRect[ cir~ data.cir, lev~ l, dim~ r, value~ NARROW[data.ports.Fetch[data.pinName].val]]; IF node # NIL THEN { Layers: TYPE ~ SX.SpinifexLayerIndex; [] _ data.ports.Store[data.pinName, node]; FOR layer: Layers IN [Layers.FIRST .. SXAccess.sxTech.numSpinifexLayers) DO SX.AdjustNode[node, layer, 0, 0, absolute]; ENDLOOP; IF Properties.GetProp [node.properties, SXAtoms.SignalName] = NIL THEN node.properties _ Properties.PutProp [node.properties, SXAtoms.SignalName, NEW[ SX.SignalName _ [name~ data.pinName]]] }; } } }; ReadPortOrder: PROC [cell: REF SX.LogicalCell, from: IO.STREAM, ports: SymTab.Ref] ~ { <<-- Process SpinifexCircuitDescription property (a ROPE) to determine order of Thyme ports for cell.>> ENABLE IO.Error => { }; DO [] _ from.SkipWhitespace[]; IF from.EndOf[] THEN EXIT; EXIT; ENDLOOP; from.Close[]; }; END. <> <>