CrossRAMSSIImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last Edited by: Barth, October 23, 1985 7:04:16 pm PDT
Louis Monier October 21, 1985 5:26:34 pm PDT
DIRECTORY Core, CoreCompose, IO, RealOps;
CrossRAMSSIImpl: CEDAR PROGRAM
IMPORTS CoreCompose, IO, RealOps
EXPORTS = BEGIN OPEN CoreCompose;
moduleName: ROPE ← "SSI";
inverterName: ROPE ← "Inverter";
InverterBC: RoseBind.BehaviorClass ← RoseBind.EnsureBehaviorClass[
name: inverterName,
publicWirePrototype: CreateInverterPublic[NIL],
moduleNameRoot: moduleName];
CreateInverterPublic: PROC [context: Context] RETURNS [public: Core.Wire] = {
public ← CreateWires[context, "Vdd, Gnd, Input, Output"];
};
Inverter: ROPE = RegisterStructureProc[name: "Inverter", proc: CreateInverter];
CreateInverter: PUBLIC StructureProc = {
cellType ← CreateRecordCell[
context: context,
name: WidthRatioNameProc[context: context, prefix: Inverter],
public: CreateInverterPublic[context],
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]]]];
};
TristateBuffer: ROPE = RegisterStructureProc[name: "TristateBuffer", proc: CreateTristateBuffer];
CreateTristateBuffer: PUBLIC 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]]];
};
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]]];
};
NAnd: ROPE = RegisterStructureProc[name: "NAnd", proc: CreateNAnd];
CreateNAnd: PUBLIC 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: inputCount], nOutput"],
onlyInternal: CreateWires[context, "stack[SEQ: inputCount-1]"],
instances: instances];
};
And: ROPE = RegisterStructureProc[name: "And", proc: CreateAnd];
CreateAnd: PUBLIC StructureProc = {
cellType ← CreateRecordCell[
context: context,
name: CountWidthRatioNameProc[context: context, prefix: And],
public: CreateWires[context, "Vdd, Gnd, Input[SEQ: inputCount], 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"]]];
};
NOr: ROPE = RegisterStructureProc[name: "NOr", proc: CreateNOr];
CreateNOr: PUBLIC 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: inputCount], nOutput"],
onlyInternal: CreateWires[context, "stack[SEQ: inputCount-1]"],
instances: instances];
};
Or: ROPE = RegisterStructureProc[name: "Or", proc: CreateOr];
CreateOr: PUBLIC 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: inputCount], Output"],
onlyInternal: CreateWires[context, "nInput[SEQ: inputCount]"],
instances: LIST [
[type: CreateStructure[name: InverterSeq, context: context],
actual: "Input: Input, Output: nInput"],
[type: CreateStructure[name: NAnd, context: context],
actual: "Input: nInput, nOutput: Output"]]];
};
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]];
};
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];
};
END.