-- File: DJExtOutput.mesa -- output structures created by the disjoint circuit extractor -- Written by Martin Newell/Dan Fitzpatrick July 1981 -- Last edited: 12-Aug-81 13:51:44 DIRECTORY DisjointAllocDefs: FROM "DisjointAllocDefs" USING [EnumerateSymbols], DisjointPropDefs: FROM "DisjointPropDefs" USING [GetLongProp,PutProp, GetProp, AllocPropID], DisjointTypes: FROM "DisjointTypes" USING [Symbol, Instance, PropID], DJExtDefs: FROM "DJExtDefs", DJExtractDefs: FROM "DJExtractDefs" USING [GetNodeLocID, GetNodesID, GetParamID, GetNParamID, GetIntTransID, GetExtTransID, GetSegmentID, GetIntCapID, GetExtCapID], DJExtTypes: FROM "DJExtTypes" USING [ActualParameter, NodeLocation, Node, Diffusion, Segment], DJExtUtilsDefs: FROM "DJExtUtilsDefs" USING [Create, Close, WriteCIFUnits, WriteLongDecimal,WriteFloat], IODefs: FROM "IODefs" USING [WriteString, WriteLine, WriteDecimal, GetOutputStream, SetOutputStream], Inline: FROM "Inline" USING [LowHalf], Runtime: FROM "Runtime" USING [CallDebugger], StreamDefs: FROM "StreamDefs" USING [StreamHandle]; DJExtOutput: PROGRAM IMPORTS DisjointAllocDefs, DisjointPropDefs, DJExtractDefs, DJExtUtilsDefs, IODefs, Inline, Runtime EXPORTS DJExtDefs = BEGIN OPEN DisjointAllocDefs, DisjointPropDefs, DisjointTypes, DJExtractDefs, DJExtTypes, DJExtUtilsDefs, IODefs, Inline, Runtime, StreamDefs; ExtOutput: PUBLIC PROCEDURE [symbol: Symbol] = BEGIN fileName:STRING _ "file.ext"; default: StreamHandle _ GetOutputStream[]; cifFile: StreamHandle _ Create[fileName]; SetOutputStream[cifFile]; count _ 0; etrans _ dtrans _ utrans _ btrans _ ctrans _ 0; WriteString["| Scale set at "]; WriteFloat[scale]; WriteLine[""]; [] _ EnumerateSymbols[Mark]; [] _ Out[symbol]; SetOutputStream[default]; Close[cifFile]; WriteLongDecimal[etrans]; WriteString[": enhancement, "]; WriteLongDecimal[dtrans]; WriteString[": depletion"]; IF utrans # 0 THEN { WriteString[", "]; WriteLongDecimal[utrans]; WriteString[": unusual implants "]; }; IF ctrans # 0 THEN { WriteString[", "]; WriteLongDecimal[ctrans]; WriteString[": poly/diff capacitors "]; }; IF btrans # 0 THEN { WriteString[", "]; WriteLongDecimal[btrans]; WriteString[": malformed transistors "]; }; WriteLine[""]; END; Mark: PROCEDURE[s: Symbol] RETURNS[BOOLEAN] = BEGIN -- mark = 1 means symbol has not yet been output -- count#0 means symbol can still be called count _ count + 1; PutProp[@s.prop,markID,1]; PutProp[@s.prop,countID,count]; RETURN[FALSE]; END; Out: PROCEDURE[s: Symbol] RETURNS[BOOLEAN] = BEGIN param: ActualParameter; cnt,n: LONG CARDINAL; PutProp[@s.prop,markID,0]; FOR in: Instance _ s.insts,in.next UNTIL in = NIL DO IF GetProp[in.symbol.prop,markID] = 1 THEN [] _ Out[in.symbol]; ENDLOOP; WriteLine[""]; WriteString["SH "]; WriteSymbolNumber[s]; WriteString[" "]; WriteLongDecimal[GetLongProp[s.prop,nparamID]]; WriteString[" "]; WriteLongDecimal[GetLongProp[s.prop,nodeID]]; WriteLine[";"]; -- write geometry FOR loc:NodeLocation _ GetLongProp[s.prop,locID],loc.next UNTIL loc = NIL DO WriteLocation[loc]; ENDLOOP; FOR trans:Node _ GetLongProp[s.prop,intID],trans.next UNTIL trans = NIL DO WriteTransistor[trans]; ENDLOOP; FOR cap:Node _ GetLongProp[s.prop,intCapID],cap.next UNTIL cap = NIL DO WriteCap[cap]; ENDLOOP; param _ GetLongProp[s.prop,paramID]; cnt _ 0; FOR in: Instance _ s.insts,in.next UNTIL in = NIL DO WriteString["C "]; WriteSymbolNumber[in.symbol]; WriteString[" ["]; n _ GetLongProp[in.symbol.prop,nparamID]; FOR i: LONG CARDINAL IN [0..n) DO WriteString[" "]; WriteLongDecimal[param.node[LowHalf[cnt]]]; cnt _ cnt + 1; IF cnt = param.count THEN { param _ param.next; cnt _ 0; }; ENDLOOP; WriteString[" ] T "]; WriteCIFUnits[in.xOffset]; WriteString[" "]; WriteCIFUnits[in.yOffset]; WriteLine[""]; ENDLOOP; WriteLine["SE;"]; RETURN[FALSE]; END; WriteCap: PROCEDURE [cap: Node] = BEGIN WriteString["N "]; WriteLongDecimal[cap.node]; WriteString[" "]; WriteFloat[cap.carea[Diff]/scale2]; WriteString[" "]; WriteFloat[cap.cperim[Diff]/scale]; WriteString[" "]; WriteFloat[cap.carea[Poly]/scale2]; WriteString[" "]; WriteFloat[cap.cperim[Poly]/scale]; WriteString[" "]; WriteFloat[cap.carea[Metal]/scale2]; WriteString[" "]; WriteFloat[cap.cperim[Metal]/scale]; WriteLine[";"]; END; WriteLocation: PROCEDURE [loc: NodeLocation] = BEGIN WriteString["PL "]; WriteLongDecimal[loc.node]; WriteString[" "]; WriteCIFUnits[loc.x]; WriteString[" "]; WriteCIFUnits[loc.y]; WriteLine[";"]; END; WriteSegment: PROCEDURE [seg: Segment] = BEGIN WriteString["Seg "]; WriteLongDecimal[seg.node]; WriteString[" "]; WriteDecimal[seg.layer]; WriteString[" "]; WriteCIFUnits[seg.bx]; WriteString[" "]; WriteCIFUnits[seg.by]; WriteString[" "]; WriteCIFUnits[seg.tx]; WriteString[" "]; WriteCIFUnits[seg.ty]; WriteLine[";"]; END; WriteTransistor: PROCEDURE [trans: Node] = BEGIN cnt: CARDINAL _ 0; diffLen: REAL _ 0; FOR d:Diffusion _ trans.diff,d.next UNTIL d = NIL DO cnt _ cnt+1; diffLen _ diffLen + d.length; ENDLOOP; SELECT cnt FROM 1 => { -- transistor with only one diffusion -- See if it's a butting contact IF trans.poly # trans.diff.node THEN { WriteString["Cap "]; WriteLongDecimal[trans.node]; WriteString[" "]; WriteLongDecimal[trans.poly]; WriteString[" "]; WriteLongDecimal[trans.diff.node]; WriteString[" loc="]; WriteTransLoc[trans]; WriteLine[";"]; ctrans _ ctrans + 1; }; }; 2 => { -- normal transistor IF NOT trans.ion AND trans.nion THEN { WriteString["e "]; etrans _ etrans + 1; } ELSE IF trans.ion AND NOT trans.nion THEN { WriteString["d "]; dtrans _ dtrans + 1; } ELSE IF trans.ion AND trans.nion THEN { WriteString["u "]; utrans _ utrans + 1; } ELSE CallDebugger["bug in transistor type checker"]; WriteLongDecimal[trans.poly]; WriteString["/"]; WriteFloat[(trans.perim-diffLen)/scale]; WriteString[" "]; WriteDiffusion[trans.diff]; WriteString[" "]; WriteDiffusion[trans.diff.next]; WriteString[" a="]; WriteFloat[trans.area/scale2]; WriteString[" loc="]; WriteTransLoc[trans]; WriteLine[";"]; }; ENDCASE => { -- bad transistor WriteString["f "]; WriteLongDecimal[trans.node]; WriteString[" "]; WriteLongDecimal[trans.poly]; WriteString["/"]; WriteFloat[(trans.perim-diffLen)/scale]; FOR d:Diffusion _ trans.diff,d.next UNTIL d = NIL DO WriteString[" "]; WriteDiffusion[d]; ENDLOOP; WriteString[" loc="]; WriteTransLoc[trans]; WriteLine[";"]; btrans _ btrans + 1; }; END; WriteTransLoc: PROCEDURE[trans:Node] = BEGIN WriteFloat[trans.x/scale]; WriteString[" "]; WriteFloat[trans.y/scale]; END; WriteDiffusion: PROCEDURE[d:Diffusion] = BEGIN WriteLongDecimal[d.node]; WriteString["/"]; WriteFloat[d.length/scale]; END; WriteSymbolNumber: PROCEDURE[s: Symbol] = BEGIN WriteDecimal[GetProp[s.prop,countID]]; END; locID: PropID _ GetNodeLocID[]; nodeID: PropID _ GetNodesID[]; nparamID: PropID _ GetNParamID[]; paramID: PropID _ GetParamID[]; intID: PropID _ GetIntTransID[]; extID: PropID _ GetExtTransID[]; intCapID: PropID _ GetIntCapID[]; extCapID: PropID _ GetExtCapID[]; segID: PropID _ GetSegmentID[]; countID: PropID _ AllocPropID[]; markID: PropID _ AllocPropID[]; count:CARDINAL; etrans,dtrans,utrans,btrans,ctrans:LONG CARDINAL; scale: REAL _ 250; scale2: REAL _ scale*scale; END. (672)\182b10B880b11B283b10B886b4B247b3B1382b9B436b14B194b13B320b16B216i34I8i29I338i17I719i14I393b13B114b14B115b17B