DIRECTORY Core, CoreCompose, IO, RealOps, Rosemary; CrossRAMSSI: CEDAR PROGRAM IMPORTS CoreCompose, IO, RealOps, Rosemary = BEGIN OPEN CoreCompose; WidthRatioNameProc: PROC [context: Context, prefix: ROPE] RETURNS [name: ROPE] = { name _ IO.PutFR["%g%g*%g", IO.rope[prefix], IO.int[GetInt[context, $SSIWidth]], IO.real[GetReal[context, $SSIRatio]]]; }; CountWidthRatioNameProc: PROC [context: Context, prefix: ROPE] RETURNS [name: ROPE] = { inputCount: NAT _ GetInt[context: context, prop: $SSIInputCount]; width: NAT _ GetInt[context: context, prop: $SSIWidth]; ratio: REAL _ GetReal[context: context, prop: $SSIRatio]; name _ IO.PutFR["%g%g*%g*%g", IO.rope[prefix], IO.int[inputCount], IO.int[width], IO.real[ratio]]; }; MakeTransistor: PROC [context: Context, stackHeight: NAT _ 1, stackType: TransistorType _ nE] RETURNS [t: Core.CellType] = { width: NAT _ GetInt[context: context, prop: $SSIWidth]; ratio: REAL _ GetReal[context: context, prop: $SSIRatio]; tWidth: NAT _ stackHeight * width; IF stackType = pE THEN tWidth _ RealOps.RoundLI[RealOps.Float[tWidth] * ratio, [round: rn]]; t _ CreateTransistor[type: stackType, width: tWidth]; }; Inverter: ROPE = RegisterStructureProc[name: "Inverter", proc: CreateInverter]; InverterVdd: NAT = 0; InverterGnd: NAT = 1; InverterInput: NAT = 2; InverterOutput: NAT = 3; CreateInverter: StructureProc = { cellType _ CreateRecordCell[ context: context, name: WidthRatioNameProc[context: context, prefix: Inverter], public: CreateWires[context, "Vdd, Gnd, Input, Output"], instances: LIST [ [actual: "gate: Input, ch1: Vdd, ch2: Output", type: MakeTransistor[context: context, stackType: pE]], [actual: "gate: Input, ch1: Output, ch2: Gnd", type: MakeTransistor[context: context, stackType: nE]]]]; Rosemary.Register[cellType: cellType, init: InverterInit, evalSimple: InverterSimple]; }; InverterInit: Rosemary.InitProc = { p[InverterOutput].d _ drive; }; InverterSimple: Rosemary.EvalProc = { p[InverterOutput].l _ SELECT TRUE FROM p[InverterInput].l=X OR p[InverterVdd].l#H OR p[InverterGnd].l#L => X, p[InverterInput].l=L => H, p[InverterInput].l=H => L, ENDCASE => ERROR; }; TristateBuffer: ROPE = RegisterStructureProc[name: "TristateBuffer", proc: CreateTristateBuffer]; TristateVdd: NAT = 0; TristateGnd: NAT = 1; TristatenInput: NAT = 2; TristateDrive: NAT = 3; TristatenDrive: NAT = 4; TristateOutput: NAT = 5; CreateTristateBuffer: StructureProc = { pType: Core.CellType _ MakeTransistor[context: context, stackHeight: 2, stackType: pE]; nType: Core.CellType _ MakeTransistor[context: context, stackHeight: 2, stackType: nE]; cellType _ CreateRecordCell[ context: context, name: WidthRatioNameProc[context: context, prefix: TristateBuffer], public: CreateWires[context, "Vdd, Gnd, nInput, Drive, nDrive, Output"], onlyInternal: CreateWires[context, "pstack, nstack"], instances: LIST [ [actual: "gate: nInput, ch1: Vdd, ch2: pstack", type: pType], [actual: "gate: nDrive, ch1: pstack, ch2: Output", type: pType], [actual: "gate: Drive, ch1: Output, ch2: nstack", type: nType], [actual: "gate: nInput, ch1: nstack, ch2: Gnd", type: nType]]]; Rosemary.Register[cellType: cellType, init: TristateInit, evalSimple: TristateSimple]; }; TristateInit: Rosemary.InitProc = { FOR port: NAT IN [0..p.size) DO p[port].type _ b; ENDLOOP; }; TristateSimple: Rosemary.EvalProc = { IF NOT p[TristateVdd].b OR p[TristateGnd].b OR (p[TristateDrive].b AND NOT p[TristatenDrive].b) THEN ERROR; p[TristateOutput].d _ IF p[TristateDrive].b OR NOT p[TristatenDrive].b THEN drive ELSE none; p[TristateOutput].b _ NOT p[TristatenInput].b; }; NAnd: ROPE = RegisterStructureProc[name: "NAnd", proc: CreateNAnd]; NAndVdd: NAT = 0; NAndGnd: NAT = 1; NAndInput: NAT = 2; NAndnOutput: NAT = 3; CreateNAnd: StructureProc = { inputCount: NAT _ GetInt[context: context, prop: $SSIInputCount]; pType: Core.CellType _ MakeTransistor[context: context, stackType: pE]; nType: Core.CellType _ MakeTransistor[context: context, stackHeight: inputCount, stackType: nE]; instances: InstanceList _ NIL; FOR input: NAT IN [0..inputCount) DO instances _ CONS[[ actual: IO.PutFR["gate: Input[%g], ch1: Vdd, ch2: nOutput", IO.int[input]], type: pType], instances]; instances _ CONS[[ actual: IO.PutFR["gate: Input[%g], ch1: %g, ch2: %g", IO.int[input], IF input=0 THEN IO.rope["nOutput"] ELSE IO.rope[IO.PutFR["stack[%g]", IO.int[input-1]]], IF input=inputCount-1 THEN IO.rope["Gnd"] ELSE IO.rope[IO.PutFR["stack[%g]", IO.int[input]]]], type: nType], instances]; ENDLOOP; cellType _ CreateRecordCell[ context: context, name: CountWidthRatioNameProc[context: context, prefix: NAnd], public: CreateWires[context, "Vdd, Gnd, Input[SEQ: SSIInputCount], nOutput"], onlyInternal: CreateWires[context, "stack[SEQ: SSIInputCount-1]"], instances: instances]; Rosemary.Register[cellType: cellType, init: NAndInit, evalSimple: NAndSimple]; }; NAndInit: Rosemary.InitProc = { p[NAndVdd].type _ b; p[NAndGnd].type _ b; FOR input: NAT IN [0..p[NAndInput].size) DO p[NAndInput][input].type _ b; ENDLOOP; p[NAndnOutput].type _ b; p[NAndnOutput].d _ drive; }; NAndSimple: Rosemary.EvalProc = { IF NOT p[NAndVdd].b OR p[NAndGnd].b THEN ERROR; FOR input: NAT IN [0..p[NAndInput].size) DO IF NOT p[NAndInput][input].b THEN { p[NAndnOutput].b _ TRUE; EXIT; }; REPEAT FINISHED => p[NAndnOutput].b _ FALSE; ENDLOOP; }; And: ROPE = RegisterStructureProc[name: "And", proc: CreateAnd]; AndVdd: NAT = 0; AndGnd: NAT = 1; AndInput: NAT = 2; AndOutput: NAT = 3; CreateAnd: StructureProc = { cellType _ CreateRecordCell[ context: context, name: CountWidthRatioNameProc[context: context, prefix: And], public: CreateWires[context, "Vdd, Gnd, Input[SEQ: SSIInputCount], Output"], onlyInternal: CreateWires[context, "nOutput"], instances: LIST [ [type: CreateStructure[name: "NAnd", context: context]], -- fix this to scale nand to inverter gate cap. [type: CreateStructure[name: "Inverter", context: context], actual: "Input: nOutput"]]]; Rosemary.Register[cellType: cellType, init: AndInit, evalSimple: AndSimple]; }; AndInit: Rosemary.InitProc = { p[AndVdd].type _ b; p[AndGnd].type _ b; FOR input: NAT IN [0..p[AndInput].size) DO p[AndInput][input].type _ b; ENDLOOP; p[AndOutput].type _ b; p[AndOutput].d _ drive; }; AndSimple: Rosemary.EvalProc = { IF NOT p[AndVdd].b OR p[AndGnd].b THEN ERROR; FOR input: NAT IN [0..p[AndInput].size) DO IF NOT p[AndInput][input].b THEN { p[AndOutput].b _ FALSE; EXIT; }; REPEAT FINISHED => p[AndOutput].b _ TRUE; ENDLOOP; }; NOr: ROPE = RegisterStructureProc[name: "NOr", proc: CreateNOr]; NOrVdd: NAT = 0; NOrGnd: NAT = 1; NOrInput: NAT = 2; NOrnOutput: NAT = 3; CreateNOr: StructureProc = { inputCount: NAT _ GetInt[context: context, prop: $SSIInputCount]; pType: Core.CellType _ MakeTransistor[context: context, stackType: pE, stackHeight: inputCount]; nType: Core.CellType _ MakeTransistor[context: context, stackType: nE]; instances: InstanceList _ NIL; FOR input: NAT IN [0..inputCount) DO instances _ CONS[[ actual: IO.PutFR["gate: Input[%g], ch1: %g, ch2: %g", IO.int[input], IF input=0 THEN IO.rope["Vdd"] ELSE IO.rope[IO.PutFR["stack[%g]", IO.int[input-1]]], IF input=inputCount-1 THEN IO.rope["nOutput"] ELSE IO.rope[IO.PutFR["stack[%g]", IO.int[input]]]], type: pType], instances]; instances _ CONS[[ actual: IO.PutFR["gate: Input[%g], ch1: nOutput, ch2: Gnd", IO.int[input]], type: nType], instances]; ENDLOOP; cellType _ CreateRecordCell[ context: context, name: CountWidthRatioNameProc[context: context, prefix: NOr], public: CreateWires[context, "Vdd, Gnd, Input[SEQ: SSIInputCount], nOutput"], onlyInternal: CreateWires[context, "stack[SEQ: SSIInputCount-1]"], instances: instances]; Rosemary.Register[cellType: cellType, init: NOrInit, evalSimple: NOrSimple]; }; NOrInit: Rosemary.InitProc = { p[NOrVdd].type _ b; p[NOrGnd].type _ b; FOR input: NAT IN [0..p[NOrInput].size) DO p[NOrInput][input].type _ b; ENDLOOP; p[NOrnOutput].type _ b; p[NOrnOutput].d _ drive; }; NOrSimple: Rosemary.EvalProc = { IF NOT p[NOrVdd].b OR p[NOrGnd].b THEN ERROR; FOR input: NAT IN [0..p[NOrInput].size) DO IF p[NOrInput][input].b THEN { p[NOrnOutput].b _ FALSE; EXIT; }; REPEAT FINISHED => p[NOrnOutput].b _ TRUE; ENDLOOP; }; Or: ROPE = RegisterStructureProc[name: "Or", proc: CreateOr]; OrVdd: NAT = 0; OrGnd: NAT = 1; OrInput: NAT = 2; OrOutput: NAT = 3; CreateOr: StructureProc = { inputCount: NAT _ GetInt[context: context, prop: $SSIInputCount]; cellType _ CreateRecordCell[ context: context, name: CountWidthRatioNameProc[context: context, prefix: Or], public: CreateWires[context, "Vdd, Gnd, Input[SEQ: SSIInputCount], Output"], onlyInternal: CreateWires[context, "nInput[SEQ: SSIInputCount]"], instances: LIST [ [type: CreateStructure[name: "InverterSeq", context: context], actual: "Input: Input, Output: nInput"], [type: CreateStructure[name: "NAnd", context: context], actual: "Input: nInput, nOutput: Output"]]]; Rosemary.Register[cellType: cellType, init: OrInit, evalSimple: OrSimple]; }; OrInit: Rosemary.InitProc = { p[OrVdd].type _ b; p[OrGnd].type _ b; FOR input: NAT IN [0..p[OrInput].size) DO p[OrInput][input].type _ b; ENDLOOP; p[OrOutput].type _ b; p[OrOutput].d _ drive; }; OrSimple: Rosemary.EvalProc = { IF NOT p[OrVdd].b OR p[OrGnd].b THEN ERROR; FOR input: NAT IN [0..p[OrInput].size) DO IF p[OrInput][input].b THEN { p[OrOutput].b _ TRUE; EXIT; }; REPEAT FINISHED => p[OrOutput].b _ FALSE; ENDLOOP; }; InverterSeq: ROPE = RegisterStructureProc[name: "InverterSeq", proc: CreateInverterSeq]; CreateInverterSeq: StructureProc = { cellType _ CoreCompose.CreateSequenceCell[ name: CountWidthRatioNameProc[context: context, prefix: InverterSeq], baseCell: CreateStructure[name: "Inverter", context: context], count: GetInt[context: context, prop: $SSIInputCount]]; }; END. ͺCrossRAMSSI.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Barth, October 27, 1985 4:40:48 pm PST Louis Monier October 21, 1985 5:26:34 pm PDT Κ V– "cedar" style˜codešœ™Kšœ Οmœ1™˜>KšœM˜MKšœB˜BKšœ˜—KšœN˜NKšœ˜—šœ˜Kšœ˜Kšœ˜šžœžœžœž˜+Kšœ˜Kšžœ˜—Kšœ˜Kšœ˜Kšœ˜—šœ!˜!Kš žœžœžœžœžœ˜/šžœžœžœž˜+šžœžœžœ˜#Kšœžœ˜Kšžœ˜K˜—Kšž˜Kšžœžœ˜%Kšžœ˜—Kšœ˜K˜——šŸœžœ7˜@Kšœžœ˜Kšœžœ˜Kšœ žœ˜Kšœ žœ˜šœ˜˜Kšœ˜Kšœ=˜=KšœL˜LKšœ.˜.šœ žœ˜Kšœ:Οc/˜iKšœX˜X——KšœL˜LKšœ˜—šœ˜Kšœ˜Kšœ˜šžœžœžœž˜*Kšœ˜Kšžœ˜—Kšœ˜Kšœ˜Kšœ˜—šœ ˜ Kš žœžœ žœ žœžœ˜-šžœžœžœž˜*šžœžœžœ˜"Kšœžœ˜Kšžœ˜K˜—Kšž˜Kšžœžœ˜"Kšžœ˜—Kšœ˜K˜——šŸœžœ7˜@Kšœžœ˜Kšœžœ˜Kšœ žœ˜Kšœ žœ˜šœ˜Kšœ žœ2˜AKšœ`˜`KšœG˜GKšœžœ˜šžœžœžœž˜$šœ žœ˜šœžœ+˜5Kšžœ ˜šžœ žœžœ ˜Kšžœžœžœžœ˜5—šžœžœžœ˜-Kšžœžœžœžœ˜4——Kšœ ˜ Kšœ ˜ —šœ žœ˜Kšœžœ2žœ ˜KKšœ ˜ Kšœ ˜ —Kšžœ˜—˜Kšœ˜Kšœ=˜=KšœM˜MKšœB˜BKšœ˜—KšœL˜LKšœ˜—šœ˜Kšœ˜Kšœ˜šžœžœžœž˜*Kšœ˜Kšžœ˜—Kšœ˜Kšœ˜Kšœ˜—šœ ˜ Kš žœžœ žœ žœžœ˜-šžœžœžœž˜*šžœžœ˜Kšœžœ˜Kšžœ˜K˜—Kšž˜Kšžœžœ˜#Kšžœ˜—Kšœ˜K˜——šŸœžœ5˜=Kšœžœ˜Kšœžœ˜Kšœ žœ˜Kšœ žœ˜šœ˜Kšœ žœ2˜A˜Kšœ˜Kšœ<˜˜>Kšœ(˜(—šœ7˜7Kšœ,˜,———KšœJ˜JKšœ˜—šœ˜Kšœ˜Kšœ˜šžœžœžœž˜)Kšœ˜Kšžœ˜—Kšœ˜Kšœ˜Kšœ˜—šœ˜Kš žœžœ žœ žœžœ˜+šžœžœžœž˜)šžœžœ˜Kšœžœ˜Kšžœ˜K˜—Kšž˜Kšžœžœ˜"Kšžœ˜—Kšœ˜K˜——šŸ œžœG˜Xšœ$˜$šœ*˜*KšœE˜EKšœ>˜>Kšœ7˜7—Kšœ˜—K˜—Kšžœ˜K˜—…—&2