DIRECTORY CD, CDAtomicObjects, CDBasics, CDCells, CDDesignRules, CDInstances, CDOrient, CDSymbolicObjects, CDRects, CoreClasses, CoreOps, CoreProperties, PW, RefTab, Rope, Sinix, Stix, TerminalIO; StixImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDDesignRules, CDInstances, CDOrient, CDSymbolicObjects, CoreOps, CoreProperties, PW, RefTab, Rope, Sinix EXPORTS Stix = BEGIN OPEN Stix; extractedCoreProp: PUBLIC ATOM _ Sinix.extractedCoreProp; errorsProp: PUBLIC ATOM _ Sinix.errorsProp; layoutProp: PUBLIC ATOM _ CoreProperties.RegisterProperty[$StixSymbolicObject, CoreProperties.Props[[CoreProperties.propCopy, CoreProperties.PropDoCopy]]]; pinsProp: PUBLIC ATOM _ CoreProperties.RegisterProperty[$StixPins, CoreProperties.Props[[CoreProperties.propCopy, CoreProperties.PropDoCopy]]]; wireGeometryProp: PUBLIC ATOM _ CoreProperties.RegisterProperty[$StixWireGeometry, CoreProperties.Props[[CoreProperties.propCopy, CoreProperties.PropDoCopy]]]; instanceProp: PUBLIC ATOM _ CoreProperties.RegisterProperty[$StixInstance, CoreProperties.Props[[CoreProperties.propCopy, CoreProperties.PropDoCopy]]]; wireNodesProp: PUBLIC ATOM _ CoreProperties.RegisterProperty[$StixWireNodes, CoreProperties.Props[[CoreProperties.propCopy, CoreProperties.PropDoCopy]]]; nTrColor: PUBLIC Color _ $ndif; pTrColor: PUBLIC Color _ $wpdif; trGateColor: PUBLIC Color _ $pol; contactClass: PUBLIC Class _ NEW[ClassRec _ [ LayoutMe: LayoutContact, ExplodeMe: ExplodeContact, MyOriginNode: ContactOrigin, AllMyNodes: ContactNodes, objectType: $contact]]; wireClass: PUBLIC Class _ NEW[ClassRec _ [ LayoutMe: LayoutWire, ExplodeMe: ExplodeWire, MyOriginNode: WireOrigin, AllMyNodes: WireNodes, objectType: $wire]]; transistorClass: PUBLIC Class _ NEW[ClassRec _ [ LayoutMe: LayoutTransistor, ExplodeMe: ExplodeTransistor, MyOriginNode: TransistorOrigin, AllMyNodes: TransistorNodes, objectType: $transistor]]; stickCellClass: PUBLIC Class _ NEW[ClassRec _ [ LayoutMe: LayoutStickCell, ExplodeMe: ExplodeStickCell, MyOriginNode: StickCellOrigin, AllMyNodes: StickCellNodes, objectType: $stickCell]]; AllNodes: PUBLIC EnumerateNodesProc ~ {RETURN[stickPtr.class.AllMyNodes[stickPtr]]}; ContactNodes: EnumerateNodesProc = {RETURN[LIST[Origin[stickPtr]]]}; WireNodes: EnumerateNodesProc = { wireRef: WireRef _ NARROW[stickPtr.data, WireRef]; RETURN[LIST[wireRef.origin,wireRef.other]]}; TransistorNodes: EnumerateNodesProc = { transistorRef: TransistorRef _ NARROW[stickPtr.data, TransistorRef]; RETURN[LIST[transistorRef.gate, transistorRef.ch1, transistorRef.ch2]]}; StickCellNodes: EnumerateNodesProc = {RETURN[NARROW[stickPtr.data, StickCell].allNodes]}; Origin: PUBLIC OriginProc ~ {RETURN[stickPtr.class.MyOriginNode[stickPtr]]}; ContactOrigin: OriginProc = {RETURN[NARROW[stickPtr.data, ContactRef].node]}; WireOrigin: OriginProc = { n1: Node _ NARROW[stickPtr.data, WireRef].origin; n2: Node _ NARROW[stickPtr.data, WireRef].other; SELECT TRUE FROM n1.pos.x=n2.pos.x => RETURN [IF n1.pos.y<=n2.pos.y THEN n1 ELSE n2]; n1.pos.y=n2.pos.y => RETURN [IF n1.pos.x<=n2.pos.x THEN n1 ELSE n2]; ENDCASE => ERROR; }; TransistorOrigin: OriginProc = {RETURN[NARROW[stickPtr.data, TransistorRef].gate]}; StickCellOrigin: OriginProc = {RETURN[NARROW[stickPtr.data, StickCell].origin]}; CreateNode: PUBLIC PROC [pos: Position, wire: Wire, cellType: CellType, private: BOOL _ FALSE] RETURNS [node: Node] = { stCell: StickCell _ NARROW[GetStickPtr[cellType].data, StickCell]; IF ~private THEN -- try to share an exisiting public node FOR l: Nodes _ stCell.allNodes, l.rest WHILE l#NIL DO IF l.first.pos=pos AND ~l.first.private THEN RETURN [l.first]; ENDLOOP; node _ NEW[NodeRec _ [pos: pos, private: private]]; IF stCell.origin=NIL THEN stCell.origin _ node; stCell.allNodes _ CONS[node, stCell.allNodes]; AppendWireNode[wire, node]; }; CreateContact: PUBLIC PROC [node: Node] RETURNS [stickPtr: StickPtr] = { contactRef: ContactRef _ NEW [ContactRec _ [node: node]]; stickPtr _ NEW[StickRec _ [class: contactClass, data: contactRef]]; }; CreateWire: PUBLIC PROC [n1, n2: Node, color: Color, width: NAT _ 0] RETURNS [stickPtr: StickPtr] = { wireRef: WireRef _ NEW [WireRec _ [origin: n1, other: n2, color: color, width: width]]; stickPtr _ NEW[StickRec _ [class: wireClass, data: wireRef]]; }; CreateTransistor: PUBLIC PROC [gate, ch1, ch2: Node, color: Color, width, length: NAT] RETURNS [stickPtr: StickPtr] = { transistorRef: TransistorRef _ NEW [TransistorRec _ [ gate: gate, ch1: ch1, ch2: ch2, color: color, width: width, length: length]]; stickPtr _ NEW[StickRec _ [class: transistorClass, data: transistorRef]]; }; CreateStickCell: PUBLIC PROC [name: ROPE] RETURNS [stickPtr: StickPtr] = { stickCellRef: StickCell _ NEW [StickCellRec _ [name: name]]; stickPtr _ NEW[StickRec _ [class: stickCellClass, data: stickCellRef]]; }; FinishCell: PUBLIC PROC [cellType: CellType] = { FinishStickPtr: EachStickPtrProc = { SELECT stickPtr.class FROM contactClass => { -- colors contactRef: ContactRef _ NARROW[stickPtr.data]; colors: Colors _ FindColorsUnder[Origin[stickPtr], wire]; IF colors=NIL THEN ERROR; contactRef.color1 _ colors.first; IF colors.rest=NIL THEN ERROR; contactRef.color2 _ colors.rest.first; }; ENDCASE => NULL; }; cell: StickPtr _ GetStickPtr[cellType]; [] _ EnumerateInsts[cellType, FinishStickPtr]; BuildConnectTable[cell]; }; OrientStickPtr: PROC [stickPtr: StickPtr] RETURNS [Orient] ~ { RETURN [SELECT stickPtr.class FROM wireClass => FindOrient[Origin[stickPtr], OtherEnd[stickPtr]], transistorClass => FindOrient[CH1[stickPtr], CH2[stickPtr]], ENDCASE => CDOrient.original ]; }; FindOrient: PROC [n1, n2: Node] RETURNS [Orient] ~ { IF n1.pos.x=n2.pos.x THEN { -- vertical IF n1.pos.y<=n2.pos.y THEN RETURN [CDOrient.original] ELSE RETURN [CDOrient.rotate180]} ELSE { -- horizontal IF n1.pos.x<=n2.pos.x THEN RETURN [CDOrient.rotate90] ELSE RETURN [CDOrient.rotate270]}; }; FindColorsUnder: PROC [node: Node, wire: Wire] RETURNS [colors: Colors _ NIL] = { FOR l: StickPtrs _ GetWireGeom[wire], l.rest WHILE l#NIL DO color: Color; stickPtr: StickPtr _ l.first; SELECT stickPtr.class FROM wireClass => IF InBetween[Origin[stickPtr], OtherEnd[stickPtr], node] THEN color _ NARROW[stickPtr.data, WireRef].color; transistorClass => { IF Gate[stickPtr]=node THEN color _ trGateColor; IF CH1[stickPtr]=node OR CH2[stickPtr]=node THEN color _ NARROW[stickPtr.data, TransistorRef].color; }; ENDCASE => LOOP; colors _ InsertColor[color, colors]; ENDLOOP; }; InsertColor: PROC [color: Color, colors: Colors] RETURNS [Colors] = { IF color=NIL THEN RETURN [colors]; FOR l: Colors _ colors, l.rest WHILE l#NIL DO IF l.first=color THEN RETURN[colors]; ENDLOOP; RETURN[CONS[color, colors]]; }; InBetween: PROC [n1, n2, n: Node] RETURNS [BOOL] ~ { IF n1.pos.x=n2.pos.x THEN { -- vertical segment RETURN [n.pos.x=n1.pos.x AND n.pos.y >= MIN[n1.pos.y, n2.pos.y] AND n.pos.y <= MAX[n1.pos.y, n2.pos.y]]} ELSE { -- horizontal segment RETURN [n.pos.y=n1.pos.y AND n.pos.x >= MIN[n1.pos.x, n2.pos.x] AND n.pos.x <= MAX[n1.pos.x, n2.pos.x]]}; }; ConvertToDR: PUBLIC PROC [cellType: CellType, dr: DRules] = { blowUp: INT = 10; LambdarizeStickPtr: EachStickPtrProc = { SELECT stickPtr.class FROM contactClass => { contactRef: ContactRef _ NARROW[stickPtr.data]; contactRef.dx _ contactRef.dx*dr.lambda; contactRef.dy _ contactRef.dy*dr.lambda; }; wireClass => { wireRef: WireRef _ NARROW[stickPtr.data]; wireRef.width _ wireRef.width*dr.lambda; }; transistorClass => { transistorRef: TransistorRef _ NARROW[stickPtr.data]; transistorRef.ch1.pos _ MultModule[transistorRef.gate.pos, transistorRef.ch1.pos, dr.gateSDNodeSp]; transistorRef.ch2.pos _ MultModule[transistorRef.gate.pos, transistorRef.ch2.pos, dr.gateSDNodeSp]; transistorRef.width _ transistorRef.width*dr.lambda; transistorRef.length _ transistorRef.length*dr.lambda; }; ENDCASE => ERROR; }; cell: StickPtr _ GetStickPtr[cellType]; FOR l: Nodes _ AllNodes[cell], l.rest WHILE l#NIL DO l.first.pos _ Mult[l.first.pos, dr.lambda*blowUp]; ENDLOOP; [] _ EnumerateInsts[cellType, LambdarizeStickPtr]; }; MultModule: PROC [center, pos: Position, val: INT] RETURNS [vec: Position] ~ { mod: INT; vec _ CDBasics.SubPoints[pos, center]; mod _ MAX [ABS[vec.x], ABS[vec.y]]; IF vec.x#0 AND vec.y#0 THEN ERROR; -- non-manhattan vector IF mod=0 THEN ERROR; -- null vector vec _ [vec.x/mod, vec.y/mod]; vec _ CDBasics.AddPoints[center, Mult[vec, val]]; }; BuildConnectTable: PROC [cell: StickPtr] ~ { EnterWires: CoreOps.EachWireProc ~ { FOR l: StickPtrs _ GetWireGeom[wire], l.rest WHILE l#NIL DO SELECT l.first.class FROM contactClass => Connect[Origin[l.first], wire, stCell.tab]; wireClass => { Connect[Origin[l.first], wire, stCell.tab]; Connect[OtherEnd[l.first], wire, stCell.tab]; }; ENDCASE => ERROR; ENDLOOP; }; cellType: CellType _ GetCellType[cell]; recCell: CoreClasses.RecordCellType _ NARROW[cellType.data]; stCell: StickCell _ NARROW[cell.data, StickCell]; stCell.tab _ RefTab.Create[]; [] _ CoreOps.VisitWire[recCell.internal, EnterWires]; }; PlatesAreConnected: PUBLIC PROC [p1, p2: Plate, table: Tab] RETURNS [BOOL _ FALSE] = { RETURN[NodesAreConnected[p1.node, p2.node, table]]; }; NodesAreConnected: PUBLIC PROC [n1, n2: Node, table: Tab] RETURNS [BOOL _ FALSE] = { IF n1=NIL OR n2=NIL THEN RETURN; RETURN[HisWire[n1, table]=HisWire[n2, table]]; }; Connect: PROC [n: Node, w: Wire, table: Tab] ~ { IF n=NIL OR w=NIL THEN RETURN; [] _ RefTab.Store[table, n, w]; }; HisWire: PROC [node: Node, table: Tab] RETURNS [Wire] = { ref: REF _ RefTab.Fetch[table, node].val; RETURN[IF ref=NIL THEN NIL ELSE NARROW[ref, Wire]]; }; Layout: PUBLIC Stix.LayoutProc ~ {inst _ stickPtr.class.LayoutMe[stickPtr, cell, dr]}; LayoutContact: LayoutProc = { mosOb: Object; contactRef: ContactRef _ NARROW[stickPtr.data]; deltaP: Position; mosOb _ CDDesignRules.Contact[dr: dr, l1: CDDesignRules.GetLayer[dr.techno, contactRef.color1], l2: CDDesignRules.GetLayer[dr.techno, contactRef.color2], size: [contactRef.dx, contactRef.dy]]; deltaP _ CHS[Half[CD.InterestSize[mosOb]]]; inst _ MakeNewInst[cell, mosOb, stickPtr, deltaP, dr]; }; LayoutWire: LayoutProc = { wireRef: WireRef _ NARROW[stickPtr.data]; layer: Layer _ CDDesignRules.GetLayer[dr.techno, wireRef.color]; width: INT _ MAX[ wireRef.width, CDDesignRules.MinWidth[dr, layer]]; length: INT _ Length[wireRef]; deltaP: Position _ CHS[Half[[width, width]]]; mosOb: Object _ CDDesignRules.Rect[ size: [x: width, y: length+width], layer: layer]; inst _ MakeNewInst[cell, mosOb, stickPtr, deltaP, dr]; }; LayoutTransistor: LayoutProc = { transistorRef: TransistorRef _ NARROW[stickPtr.data]; deltaP: Position; mosOb: Object; ratio: Position _ [transistorRef.width, transistorRef.length]; mosOb _ CDDesignRules.Transistor[dr: dr, difL: CDDesignRules.GetLayer[dr.techno, transistorRef.color], w: ratio.x, l: ratio.y]; deltaP _ CHS[Half[CD.InterestSize[mosOb]]]; inst _ MakeNewInst[cell, mosOb, stickPtr, deltaP, dr]; }; LayoutStickCell: LayoutProc = { LayoutEachStickPtr: EachStickPtrProc = {[] _ Layout[stickPtr, newCell, dr]}; newCell: Object _ PW.CreateEmptyCell[]; [] _ EnumerateInsts[GetCellType[stickPtr], LayoutEachStickPtr]; inst _ MakeNewInst[cell, newCell, stickPtr, [0, 0], dr]; }; MakeNewInst: PROC [cell, ob: Object, stickPtr: StickPtr, deltaP: Position, dr: DRules] RETURNS [inst: Instance] = { inst _ CDCells.IncludeOb[design: NIL, cell: cell, ob: ob, position: LayoutPos[stickPtr, deltaP, dr], orientation: OrientStickPtr[stickPtr], cellCSystem: interrestCoords, obCSystem: interrestCoords, mode: dontPropagate].newInst; }; Explode: PUBLIC ExplodeProc ~ {stickPtr.class.ExplodeMe[stickPtr, dr]}; ExplodeContact: ExplodeProc = { ToPlatesProc: CDSymbolicObjects.InstEnumerator ~ { stickPtr.plates _ CONS[PinToPlate[inst, node, OrientStickPtr[stickPtr]], stickPtr.plates]; }; inst: Instance _ Layout[stickPtr, NIL, dr]; -- coordinate system? dummy: Object _ CDDesignRules.Explode[dr, inst.ob]; node: Node _ Origin[stickPtr]; stickPtr.plates _ NIL; [] _ CDSymbolicObjects.EnumerateSymbolicObs[dummy, ToPlatesProc]; }; ExplodeWire: ExplodeProc = ExplodeContact; ExplodeTransistor: ExplodeProc = { -- use channel? ToPlatesProc: CDSymbolicObjects.InstEnumerator ~ { name: ROPE _ CDSymbolicObjects.GetName[inst]; plate: Plate _ SELECT TRUE FROM Rope.Equal[name, "gate"] => PinToPlate[inst, transistorRef.gate, OrientStickPtr[stickPtr]], Rope.Equal[name, "ch1"] => PinToPlate[inst, transistorRef.ch1, OrientStickPtr[stickPtr]], Rope.Equal[name, "ch2"] => PinToPlate[inst, transistorRef.ch2, OrientStickPtr[stickPtr]], ENDCASE => ERROR; stickPtr.plates _ CONS[plate, stickPtr.plates]; }; transistorRef: TransistorRef _ NARROW[stickPtr.data]; inst: Instance _ Layout[stickPtr, NIL, dr]; -- coordinate system? dummy: Object _ CDDesignRules.Explode[dr, inst.ob]; stickPtr.plates _ NIL; [] _ CDSymbolicObjects.EnumerateSymbolicObs[dummy, ToPlatesProc]; }; PinToPlate: PROC [pin: Instance, node: Node, orient: Orient] RETURNS [plate: Plate] ~ { rect: CD.Rect _ CenterOnNode[CDInstances.InstRectI[pin], node, orient]; -- use also dP ? drect: DRect _ [r: rect, lev: CDSymbolicObjects.GetLayer[pin]]; plate _ NEW [PlateRec _ [dr: drect, node: node]]; }; ExplodeStickCell: ExplodeProc = { ExplodeEachStickPtr: EachStickPtrProc = {[] _ Explode[stickPtr, dr]}; [] _ EnumerateInsts[GetCellType[stickPtr], ExplodeEachStickPtr]; }; EnumerateInsts: PUBLIC PROC [cellType: CellType, proc: EachStickPtrProc] RETURNS [quit: BOOL] ~ { ProcessStickPtr: CoreOps.EachWireProc ~ { FOR l: StickPtrs _ GetWireGeom[wire], l.rest WHILE l#NIL DO IF quit _ proc[l.first, wire] THEN RETURN; -- pin, contact or wire ENDLOOP; }; recCell: RecordCell _ NARROW[cellType.data]; FOR i: NAT IN [0..recCell.size) DO -- instanceProp stickPtr: StickPtr _ NARROW[CoreProperties.GetCellInstanceProp[recCell[i], instanceProp]]; IF quit _ proc[stickPtr, NIL] THEN RETURN; ENDLOOP; [] _ CoreOps.VisitWire[recCell.internal, ProcessStickPtr]; -- wireGeometryProp }; GetCellType: PUBLIC PROC [stickPtr: StickPtr] RETURNS [CellType] ~ { ref: REF _ CoreProperties.GetProp[stickPtr.properties, extractedCoreProp]; RETURN[IF ref#NIL THEN NARROW[ref] ELSE NIL]; }; GetStickPtr: PUBLIC PROC [cellType: CellType] RETURNS [StickPtr] ~ { ref: REF _ CoreProperties.GetCellTypeProp[cellType, layoutProp]; RETURN[IF ref#NIL THEN NARROW[ref] ELSE NIL]; }; PutStickPtr: PUBLIC PROC [cellType: CellType, stickPtr: StickPtr] ~ { CoreProperties.PutCellTypeProp[cellType, layoutProp, stickPtr]; }; GetWireGeom: PUBLIC PROC [wire: Wire] RETURNS [StickPtrs] ~ { ref: REF _ CoreProperties.GetWireProp[wire, wireGeometryProp]; RETURN[IF ref#NIL THEN NARROW[ref] ELSE NIL]; }; PutWireGeom: PUBLIC PROC [wire: Wire, stickPtrs: StickPtrs] ~ { CoreProperties.PutWireProp[wire, wireGeometryProp, stickPtrs]; }; AppendWireGeom: PUBLIC PROC [wire: Wire, stickPtr: StickPtr] ~ { stickPtrs: StickPtrs _ GetWireGeom[wire]; stickPtrs _ CONS[stickPtr, stickPtrs]; PutWireGeom[wire, stickPtrs]; }; GetWireNodes: PUBLIC PROC [wire: Wire] RETURNS [Nodes] ~ { ref: REF _ CoreProperties.GetWireProp[wire, wireNodesProp]; RETURN[IF ref#NIL THEN NARROW[ref] ELSE NIL]; }; PutWireNodes: PUBLIC PROC [wire: Wire, nodes: Nodes] ~ { CoreProperties.PutWireProp[wire, wireNodesProp, nodes]; }; AppendWireNode: PUBLIC PROC [wire: Wire, node: Node] ~ { nodes: Nodes _ GetWireNodes[wire]; nodes _ CONS[node, nodes]; PutWireNodes[wire, nodes]; }; GetInstance: PUBLIC PROC [coreInst: CoreClasses.CellInstance] RETURNS [StickPtr] ~ { ref: REF _ CoreProperties.GetCellInstanceProp[coreInst, instanceProp]; RETURN[IF ref#NIL THEN NARROW[ref] ELSE NIL]; }; PutInstance: PUBLIC PROC [coreInst: CoreClasses.CellInstance, stickPtr: StickPtr] ~ { CoreProperties.PutCellInstanceProp[coreInst, instanceProp, stickPtr]; }; IsNodeOf: PROC [stickPtr: StickPtr, node: Node] RETURNS [BOOL _ FALSE] ~ { FOR l: Nodes _ AllNodes[stickPtr], l.rest WHILE l#NIL DO IF node=l.first THEN RETURN[TRUE]; ENDLOOP; }; OtherEnd: PUBLIC PROC [stickPtr: StickPtr] RETURNS [node: Node] = { WITH stickPtr.data SELECT FROM w: WireRef => { n1: Node _ w.origin; n2: Node _ w.other; SELECT TRUE FROM n1.pos.x=n2.pos.x => RETURN [IF n1.pos.y<=n2.pos.y THEN n2 ELSE n1]; n1.pos.y=n2.pos.y => RETURN [IF n1.pos.x<=n2.pos.x THEN n2 ELSE n1]; ENDCASE => ERROR; }; ENDCASE => RETURN [NIL]; }; Gate: PROC [stickPtr: StickPtr] RETURNS [node: Node] = { WITH stickPtr.data SELECT FROM tr: TransistorRef => RETURN[tr.gate]; ENDCASE => RETURN [NIL]; }; CH1: PROC [stickPtr: StickPtr] RETURNS [node: Node] = { WITH stickPtr.data SELECT FROM tr: TransistorRef => RETURN[tr.ch1]; ENDCASE => RETURN [NIL]; }; CH2: PROC [stickPtr: StickPtr] RETURNS [node: Node] = { WITH stickPtr.data SELECT FROM tr: TransistorRef => RETURN[tr.ch2]; ENDCASE => RETURN [NIL]; }; TheColor: PROC [stickPtr: StickPtr] RETURNS [color: Color] = { WITH stickPtr.data SELECT FROM w: WireRef => RETURN[w.color]; tr: TransistorRef => RETURN[tr.color]; ENDCASE => RETURN [NIL]; }; Length: PROC [wireRef: WireRef] RETURNS [length: INT] = { node1, node2: Node; node1 _ wireRef.origin; node2 _ wireRef.other; length _ ABS[node1.pos.x-node2.pos.x+node1.pos.y-node2.pos.y] }; LayoutPos: PROC [stickPtr: StickPtr, deltaP: Position, dr: DRules] RETURNS [Position] ~ { RETURN [CDBasics.AddPoints[ deltaP, CDBasics.AddPoints[Origin[stickPtr].pos, stickPtr.dP]]]; }; Mult: PROC [pos: Position, n: INT] RETURNS [Position] ~ { RETURN[[pos.x*n, pos.y*n]]; }; Half: PROC [pos: Position] RETURNS [Position] ~ { RETURN[[pos.x/2, pos.y/2]]; }; CHS: PROC [pos: Position] RETURNS [Position] ~ { RETURN[[-pos.x, -pos.y]]; }; CenterOnNode: PROC [rect: CD.Rect, node: Node, orient: Orient] RETURNS [newRect: CD.Rect] = { rect _ CDOrient.OrientedRect[rect, orient]; newRect _ CDBasics.MoveRect[rect, CDBasics.SubPoints[node.pos, CDBasics.Center[rect]]]; }; END. ΌStixImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Louis Monier December 6, 1985 2:29:32 pm PST Properties connecting Core to Stix Classes How to access all the nodes -- EnumerateNodesProc: TYPE = PROC [stickPtr: StickPtr] RETURNS [nodes: Nodes]; How to access the Origin Node -- OriginProc: TYPE = PROC [stickPtr: StickPtr] RETURNS [node: Node]; Creation procs: minimum information, no context -- Cached creation: only one node per pos during the creation -- Nodes might overlap later, during compaction, but we do not create any node at this time -- Private nodes are not shared -- Either private or not found -- Create an empty stick Cell Must be called as soon as all objects have been put into the cell -- Fill-up redundant fields in these StickPtrs (orient, ...) -- A speed-up hack for the compaction -- Find colors under a given Node (ct or pin): explore only those in the same Core.Wire -- Avoid duplication in the list Must be called before layout or compaction, as soon as DRules are known -- All distances and sizes are converted to the new lambda; notice that the cell stays inside the same equivalence class. -- I am not convinced that this is necessary! -- Change sizes and internal spacing -- Change positions Electrical Connectivity -- Use a RefTab: [node, wire] where wire is a Core.Wire. -- for every internal wire, take all StickPtr attached to it and build an entry [node, wire] for every node -- Two nodes are connected if they have same wire Layout: from StickPtr to CMOS instances -- A LayoutProc produces an instance of a CD object inside a cell; it takes all its parameters from the StickPtr; the position of the instance is derived from the position of its origin node, of a user-set dP (set by a compaction algorithm for example) and from a deltaP which depends on the type of the object: e.g. a contact is centered on the node. -- LayoutProc: TYPE = PROC [stickPtr: StickPtr, cell: Object, dr: DRules] RETURNS [inst: Instance]; -- Must return the instance so that we can add properties (e.g. pin) Explode procs: from symbolic object + technology to plates -- ExplodeProc: TYPE = PROC [stickPtr: StickPtr, dr: DRules]; General Utilities -- All transistors -- Geometry on internal wire -- CellType from StickPtr -- StickPtr on CellType -- StickPtrs on Wire -- Nodes on Wire -- StickPtr on CellInstance (devices or subcells) -- List.Member -- NIL if not a wire -- NIL if not a transistor -- NIL if not a single color (e.g. contact) Κ˜šœ ™ Icodešœ Οmœ1™Kšžœ˜——K™Kšœžœ)˜3Kšžœžœžœ˜/Kšœžœ˜.Kšœ˜K˜—š‘ œžœžœžœ˜HKšœžœ˜9Kšœ žœ5˜CK˜—š ‘ œžœžœ%žœžœ˜eKšœžœA˜WKšœ žœ/˜=K˜—š‘œž œ5žœžœ˜wšœžœ˜5Kšœ ˜ Kšœ-˜-—Kšœ žœ;˜IKšœ˜—K™š‘œž œžœžœ˜JKšœžœ˜šžœžœž˜"Kšœ>˜>Kšœ<˜˜>šœ)˜)Kšœ>˜>Kšœ˜—Jšœ žœžœ˜+Jšœ6˜6K˜—š‘œ˜Kš‘œ:˜LKšœžœ˜'Kšœ?˜?Jšœ8˜8K˜—K™Dš‘ œžœFžœ˜sšœ!žœ˜:JšœQ˜QJšœW˜W—K˜——šœ:™:Kš‘œžœ8˜GKš =™=K˜š‘œ˜š‘ œ&˜2KšœžœD˜ZK˜—Kšœ"žœ ˜BKšœ3˜3Kšœ˜Kšœžœ˜KšœA˜AK˜—Kš‘ œ˜*š‘œ ˜2š‘ œ&˜2Kšœžœ#˜-šœžœžœž˜Kšœ[˜[KšœY˜YKšœY˜YKšžœžœ˜—Kšœžœ˜/K˜—Kšœžœ˜5Kšœ"žœ ˜BKšœ3˜3Kšœžœ˜KšœA˜AKšœ˜—š‘ œžœ-žœ˜WKšœžœD  ˜YKšœ?˜?Kšœžœ&˜1K˜—š‘œ˜!Kš‘œ2˜EKšœ@˜@Kšœ˜——šœ™š ‘œžœžœ.žœžœ˜aš‘œ˜)šžœ*žœžœžœ˜Kšžœžœžœžœžœžœžœ˜-K˜—š‘ œž œ'˜?Kšœ>˜>K˜—š‘œž œ%˜@Kšœ)˜)Kšœ žœ˜&Kšœ˜K˜—Kšœ™š‘ œž œžœ ˜:Kšœžœ3˜;Kšžœžœžœžœžœžœžœ˜-K˜—š‘ œž œ˜8Kšœ7˜7K˜—š‘œž œ˜8Kšœ"˜"Kšœžœ˜Kšœ˜K˜—Kšœ1™1š‘ œž œ&žœ˜TKšœžœ>˜FKšžœžœžœžœžœžœžœ˜-K˜—š‘ œž œ=˜UKšœE˜EK˜—K™K™š ‘œžœ"žœžœžœ˜Jšžœ'žœžœž˜8Kšžœžœžœžœ˜"Kšžœ˜—K˜—K™š‘œž œžœ˜Cšžœžœž˜šœ˜Kšœ˜Kšœ˜šžœžœž˜Kš œžœžœžœžœ˜DKš œžœžœžœžœ˜DKšžœžœ˜—K˜—Kšžœžœžœ˜—K˜—K™š‘œžœžœ˜8šžœžœž˜Kšœžœ ˜%Kšžœžœžœ˜—K˜—š‘œžœžœ˜7šžœžœž˜Kšœžœ ˜$Kšžœžœžœ˜—K˜—š‘œžœžœ˜7šžœžœž˜Kšœžœ ˜$Kšžœžœžœ˜—K˜—K™+š‘œžœžœ˜>šžœžœž˜Kšœžœ ˜Kšœžœ ˜&Kšžœžœžœ˜—K˜—š‘œžœžœ žœ˜9Kšœ˜Kšœ˜Kšœ˜Kšœ žœ1˜=K˜—š‘ œžœ4žœ˜Yšžœ˜Kšœ˜Kšœ8˜8—K˜—š‘œžœžœžœ˜9Kšžœ˜K˜—š‘œžœžœ˜1Kšžœ˜K˜—š‘œžœžœ˜0Kšžœ˜K˜—š ‘ œžœžœ#žœ žœ ˜]Kšœ+˜+KšœW˜WK˜—K˜—J˜Kšžœ˜K˜—…—Enc8