<> <> <> <> <> <> <<>> DIRECTORY Build, Core, CoreClasses, CoreFlat, CoreOps, CoreProperties, Flow, Globals, HashTable, IO, Model, Real, Rope, WriteCapa; BuildImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreFlat, CoreOps, CoreProperties, Flow, Globals, HashTable, IO, Model, Real, Rope, WriteCapa EXPORTS Build = BEGIN OPEN Build; CoreAttributes: TYPE = LIST OF CoreAttributeRec; CoreAttributeRec: TYPE = RECORD [ port: CoreClasses.TransistorPort, attribute: Rope.ROPE]; FlatCellProc: TYPE = PROC [cell: Core.CellType, target: CoreFlat.FlatCellTypeRec _ CoreFlat.allFlatCells, flatCell: CoreFlat.FlatCellTypeRec _ [], instance: CoreClasses.CellInstance _ NIL, parent: Core.CellType _ NIL, flatParent: CoreFlat.FlatCellTypeRec _ [], data: REF ANY _ NIL, wireName: HashTable.Table]; Units: PUBLIC REAL _ 2.0; <> totalNodes: INT _ 0; totalFets: ARRAY[0..Model.maxFetTypes) OF INT _ ALL[0]; debug: PUBLIC BOOL _ FALSE; EOF: ERROR = CODE; <> Terminal: TYPE = {gate, source, drain}; BuildNode: PUBLIC PROC[flatWire: CoreFlat.FlatWire, globalVars: Globals.GlobalVars] RETURNS [Globals.Node] = { <> new: Globals.Node; val: HashTable.Value; found: BOOLEAN; <> <> <> [found: found, value: val] _ HashTable.Fetch[globalVars.nodeTable, flatWire]; IF found THEN RETURN[NARROW[val]]; new _ NEW[Globals.NodeRec]; <> new.flatWire _ flatWire; new.cap _ WriteCapa.GetRootCap[flatWire.wire]; new.res _ 0; new.hiTime _ -1.0; new.loTime _ -1.0; new.firstPointer _ NIL; new.always0 _ FALSE; new.always1 _ FALSE; new.input _ FALSE; new.precharged _ FALSE; new.dynamic _ FALSE; new.ratioError _ FALSE; new.watched _ FALSE; <> [] _ HashTable.Store[table: globalVars.nodeTable, key: flatWire, value: new]; totalNodes _ totalNodes + 1; RETURN [new]; }; BuildPointer: PROC[node: Globals.Node, fet: Globals.Fet] = { <> p: Globals.Pointer _ NEW[Globals.PointerRec _ [fet, node.firstPointer]]; node.firstPointer _ p; }; BuildFet: PROC[gate, source, drain: CoreFlat.FlatWire, fetData: REF ANY, l, w: REAL, globalVars: Globals.GlobalVars] RETURNS [fet: Globals.Fet] = { <> <<>> <> f2: Globals.Fet; ptr: Globals.Pointer; type: REF INTEGER _ NARROW[fetData]; fet _ NEW[Globals.FetRec]; fet.type _ type^; fet.gate _ BuildNode[gate, globalVars]; fet.source _ BuildNode[source, globalVars]; fet.drain _ BuildNode[drain, globalVars]; fet.area _ l*w; fet.aspect _ l/w; <> <> <> IF fet.type = Model.fetNDep THEN { IF fet.source = globalVars.VddNode THEN { IF fet.drain = fet.gate THEN fet.type _ Model.fetNLoad ELSE fet.type _ Model.fetNSuper; } ELSE IF fet.drain = globalVars.VddNode THEN { IF fet.source = fet.gate THEN fet.type _ Model.fetNLoad ELSE fet.type _ Model.fetNSuper; }; }; <> <> <> <> <> <> <> <<};>> <> <> <> <<};>> <> IF (fet.source # globalVars.VddNode) AND (fet.source # globalVars.GroundNode) THEN ptr _ fet.source.firstPointer ELSE IF (fet.drain # globalVars.VddNode) AND (fet.drain # globalVars.GroundNode) THEN ptr _ fet.drain.firstPointer ELSE IF (fet.gate # globalVars.VddNode) AND (fet.gate # globalVars.GroundNode) THEN ptr _ fet.gate.firstPointer ELSE ptr _ NIL; WHILE ptr # NIL DO f2 _ ptr.fet; IF (f2.gate = fet.gate) AND (f2.drain = fet.drain) AND (f2.source = fet.source) AND (f2.type = fet.type) THEN { f2.area _ f2.area + fet.area; f2.aspect _ 1.0/(1.0/f2.aspect + 1.0/fet.aspect); fet _ f2; EXIT; }; ptr _ ptr.next; ENDLOOP; IF ptr = NIL THEN { BuildPointer[fet.gate, fet]; IF fet.drain # fet.gate THEN BuildPointer[fet.drain, fet]; IF (fet.source # fet.gate) AND (fet.source # fet.drain) THEN BuildPointer[fet.source, fet]; fet.on0 _ Model.TypeTable[fet.type].on0; fet.on1 _ Model.TypeTable[fet.type].on1; fet.onAlways _ Model.TypeTable[fet.type].onAlways; }; totalFets[fet.type] _ totalFets[fet.type] + 1; RETURN; }; BuildAtt: PROC[fet: Globals.Fet, terminal: Terminal, string: Rope.ROPE] RETURNS [Rope.ROPE] = { <> <<>> pos, index: INT; pos _ Rope.Run[string, 0, "Crystal:", 0, FALSE]; IF pos < 7 THEN { pos _ Rope.Run[string, 0, "Cr:", 0, FALSE]; IF pos < 2 THEN RETURN[NIL]; }; string _ Rope.Replace[base: string, start: 0, len: pos, with: NIL]; <> IF terminal = gate THEN { index _ Model.NameToIndex[string]; IF index < 0 THEN RETURN [IO.PutFR["unknown transistor type %s", IO.rope[string]]]; fet.type _ index; RETURN [NIL]; }; <> IF Rope.Equal[string, "In", FALSE] OR Rope.Equal[string, "IN", FALSE] THEN { IF terminal = source THEN fet.noDrainInfo _ TRUE ELSE fet.noSourceInfo _ TRUE; } ELSE IF Rope.Equal[string, "Out", FALSE] OR Rope.Equal[string, "OUT", FALSE] THEN { IF terminal = source THEN fet.noSourceInfo _ TRUE ELSE fet.noDrainInfo _ TRUE; } ELSE Flow.Build[fet: fet, name: string, source: terminal=source]; RETURN [NIL]; }; Stats: PUBLIC PROC[] = { total: INT _ 0; IO.PutF[Globals.StdOut, "Total number of nodes: %d.\n", IO.int[totalNodes]]; FOR i:INT IN [0..Model.maxFetTypes) DO IF totalFets[i] = 0 THEN LOOP; IO.PutF[Globals.StdOut, "Number of %s transistors: %d.\n", IO.rope[Model.TypeTable[i].name], IO.int[totalFets[i]]]; total _ total + totalFets[i]; ENDLOOP; IO.PutF[Globals.StdOut, "Total number of transistors: %d.\n", IO.int[total]]; }; <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<};>> <> <> <> <> <> <<};>> <<};>> <<};>> <<>> <> <> <> <<>> <<};>> <> <<>> <> <> <> <> <> <> <> <> <> <> < gate, ch1 => source, ch2 => drain, ENDCASE => ERROR), Rope.Cat["Cry: ", att.first.attribute]];>> <> <> <> <<}>> <> <<>> <> <<[] _ HashTable.Store[table: publics, key: wire, value: $Public];>> <<};>> <<>> <> <> <> <> <<};>> <<};>> <<>> <> <> <> <> <<[] _ HashTable.Store[table: wireName, key: publicWire, value: name];>> <<};>> <<};>> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <<};>> <<};>> <<>> <> <> <> <> <> <<};>> <<};>> <<>> <> <> <> <<[] _ HashTable.Store[table: wireName, key: wire, value: name];>> <> <> <<};>> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> <> <> <> <> <> <<>> <> <> <> <