<> <> DIRECTORY Asserting, CompareDataStructure, CompareOps, CompareTransforms, Convert, IO, OrderedSymbolTableRef, Rope, RoseTypes, RoseCreate, SwitchTypes, Transistors; RoseFromStructure: CEDAR PROGRAM IMPORTS Asserting, SO: CompareOps, CT: CompareTransforms, Convert, IO, OrderedSymbolTableRef, Rope, RoseCreate, RoseTypes, SwitchTypes, Transistors = {OPEN S: CompareDataStructure, R: RoseTypes; ROPE: TYPE = Rope.ROPE; GenericIO: TYPE = REF GenericIORep; GenericIORep: TYPE = RECORD [ ports: SEQUENCE COMPUTED CARDINAL OF SwitchTypes.SwitchValHolder]; Thresholds: TYPE = REF ThresholdsRep; ThresholdsRep: TYPE = RECORD [ weakRatio, strongRatio: REAL]; thresholdsFn: REF ANY _ NEW [ROPE _ "thresholdsFn"]; MergeFromStructure: PROC [design: S.Design, weakRatio: REAL _ 3.0, strongRatio: REAL _ 0.3] = { thresholds: Thresholds _ NEW [ThresholdsRep _ [weakRatio, strongRatio]]; FOR sct: S.CellType _ CT.FirstCellType[design], CT.NextCellType[sct] WHILE sct # NIL DO cellTypeName: ROPE _ SO.PickAName[sct.names]; oldCellType: R.CellType _ RoseCreate.GetCellType[cellTypeName]; IF oldCellType = NIL THEN ReallyDefineCellType[sct, cellTypeName, thresholds]; ENDLOOP; weakRatio _ weakRatio; }; DefineCellType: PROC [design: S.Design, cellTypeName: ROPE, weakRatio: REAL _ 3.0, strongRatio: REAL _ 0.3] = { thresholds: Thresholds _ NEW [ThresholdsRep _ [weakRatio, strongRatio]]; sct: S.CellType _ SO.ToType[design, cellTypeName]; ReallyDefineCellType[sct, cellTypeName, thresholds]; }; ReallyDefineCellType: PROC [sct: S.CellType, cellTypeName: ROPE, thresholds: Thresholds] = { SO.EnsureParts[sct]; SO.EnsurePorts[sct]; IF SO.ExpansionKnown[sct] THEN { rosePorts: R.Ports _ RosePortsFromStructure[sct]; rct: R.CellType; rct _ RoseCreate.RegisterCellType[ name: cellTypeName, expandProc: ExpandFromStructure, ioCreator: CreateIOForStructure, evals: [], ports: rosePorts, typeData: sct]; sct.otherPrivate _ Asserting.AssertFn1[fn: thresholdsFn, val: thresholds, inAdditionTo: sct.otherPrivate]; }; }; RosePortsFromStructure: PROC [sct: S.CellType] RETURNS [rosePorts: R.Ports] = { strPorts: S.PortS _ sct.ports; rosePorts _ NEW [R.PortsRep[strPorts.length]]; FOR pi: NAT IN [0 .. strPorts.length) DO portName: ROPE _ SO.PickAName[strPorts[pi].names]; isIn: BOOL _ Asserting.Test[$IN, NIL, strPorts[pi].other]; isOut: BOOL _ Asserting.Test[$OUT, NIL, strPorts[pi].other]; isBi: BOOL _ Asserting.Test[$BIDIR, NIL, strPorts[pi].other]; isDird: BOOL _ isIn OR isOut OR isBi; confused: BOOL _ (isIn AND isOut) OR (isOut AND isBi) OR (isBi AND isIn); IF confused THEN SO.Warn[[], "Confused port %g", IO.rope[SO.GlobalPortName[sct, pi]]]; FOR nnl: S.RopeList _ strPorts[pi].netNames, nnl.rest WHILE nnl # NIL DO net: S.Vertex _ NARROW[SO.Lookup[sct.parts, nnl.first]]; IF NOT SO.PickAName[net.names].Equal[portName] THEN ERROR; ENDLOOP; rosePorts[pi] _ [ firstWord: pi, wordCount: SwitchTypes.wordsPerSwitchValPort, name: portName, type: SwitchTypes.bitType, input: isIn OR isBi OR NOT isDird, output: isOut OR isBi OR NOT isDird, XPhobic: FALSE]; ENDLOOP; }; CreateIOForStructure: PROC [ct: R.CellType] RETURNS [ioAsAny: REF ANY] = { sct: S.CellType _ NARROW[ct.typeData]; ioAsAny _ NEW [GenericIORep[sct.ports.length]]; }; ExpandFromStructure: PROC [thisCell: R.Cell, to: R.ExpansionReceiver] = { PerNode: PROC [ra: REF ANY] RETURNS [stop: BOOL] = { v: S.Vertex _ NARROW[SO.AntiAlias[ra]]; name: ROPE _ SO.PickAName[v.names]; already: R.Node _ RoseCreate.LookupCellNode[thisCell, name]; stop _ FALSE; IF already # NIL THEN RETURN; SELECT v.class FROM net => { [] _ to.class.NodeInstance[ erInstance: to.instance, name: name, type: SwitchTypes.bitType]; }; cell => NULL; ENDCASE => ERROR}; PerCell: PROC [ra: REF ANY] RETURNS [stop: BOOL] = { v: S.Vertex _ NARROW[SO.AntiAlias[ra]]; name: ROPE _ SO.PickAName[v.names]; already: R.Cell _ NARROW[thisCell.components.Lookup[name]]; stop _ FALSE; IF already # NIL THEN RETURN; SELECT v.class FROM net => NULL; cell => { typeName: ROPE; connections: ROPE _ EncodeConnections[v]; isTrans: BOOL; nType: BOOL; mode: Transistors.Mode; ratio: REAL; [isTrans, nType, mode, ratio] _ TransistorStuff[v.type]; IF isTrans THEN typeName _ Transistors.Transistor[[ strength: SELECT ratio FROM >thresholds.weakRatio => driveWeak, driveStrong, ENDCASE => drive, positive: nType, mode: mode ]].name ELSE typeName _ SO.PickAName[v.type.names]; [] _ to.class.CellInstance[ erInstance: to.instance, instanceName: name, typeName: typeName, interfaceNodes: connections]; }; ENDCASE => ERROR}; sct: S.CellType _ NARROW[thisCell.type.typeData]; thresholds: Thresholds _ NARROW[Asserting.FnVal[fn: thresholdsFn, from: sct.otherPrivate]]; sct.parts.EnumerateIncreasing[PerNode]; sct.parts.EnumerateIncreasing[PerCell]; }; EncodeConnections: PROC [cell: S.Vertex] RETURNS [connections: ROPE] = { connections _ NIL; FOR e: S.Edge _ cell.firstEdge, e.sides[cell].next WHILE e # NIL DO IF e.sides[cell].v # cell THEN ERROR; IF connections # NIL THEN connections _ connections.Cat[", "]; connections _ connections.Cat[ Convert.RopeFromRope[SO.PickAName[cell.type.ports[e.portIndex].names]], ": ", Convert.RopeFromRope[SO.PickAName[e.sides[net].v.names]] ]; ENDLOOP; }; TransistorStuff: PROC [sct: S.CellType] RETURNS [isTrans, nType: BOOL, mode: Transistors.Mode, ratio: REAL] = { lora, lenwid: Asserting.Terms; len: REAL _ 2; wid: REAL _ 2; isTrans _ FALSE; nType _ TRUE; mode _ Enhancement; ratio _ 1.0; lenwid _ Asserting.FnVals[fn: $MOSFETShape, from: sct.otherPublic]; IF lenwid = NIL OR lenwid.rest = NIL OR lenwid.rest.rest # NIL THEN RETURN; WITH lenwid.first SELECT FROM rr: REF REAL => len _ rr^; ri: REF INT => len _ ri^; ENDCASE => SIGNAL R.Warning[IO.PutFR["Ill-formatted assertion ($MOSFETShape %g ..) on %g", IO.refAny[lenwid.first], IO.rope[SO.GlobalCellTypeName[sct]]]]; WITH lenwid.rest.first SELECT FROM rr: REF REAL => wid _ rr^; ri: REF INT => wid _ ri^; ENDCASE => SIGNAL R.Warning[IO.PutFR["Ill-formatted assertion ($MOSFETShape .. %g) on %g", IO.refAny[lenwid.rest.first], IO.rope[SO.GlobalCellTypeName[sct]]]]; ratio _ len/wid; lora _ Asserting.FnVals[fn: $MOSFETFlavor, from: sct.otherPublic]; IF lora = NIL THEN RETURN; IF lora.rest = NIL OR lora.rest.rest # NIL THEN SIGNAL R.Warning[IO.PutFR[ "Ill-formatted assertion %g on %g", IO.refAny[CONS[$MOSFETFlavor, lora]], IO.rope[SO.GlobalCellTypeName[sct]] ]] ELSE { SELECT lora.first FROM $n => nType _ TRUE; $p => nType _ FALSE; ENDCASE => SIGNAL R.Warning[IO.PutFR["Illegal $MOSFETFlavor type %g on %g", IO.refAny[lora.first], IO.rope[SO.GlobalCellTypeName[sct]]]]; SELECT lora.rest.first FROM $E => mode _ Enhancement; $D => mode _ Depletion; ENDCASE => SIGNAL R.Warning[IO.PutFR["Illegal $MOSFETFlavor mode %g on %g", IO.refAny[lora.rest.first], IO.rope[SO.GlobalCellTypeName[sct]]]]; }; isTrans _ TRUE; }; }.