CrossRAMSSIImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last Edited by: Barth, September 4, 1985 2:16:04 pm PDT
DIRECTORY CoreCreate, CoreTransistor, CrossRAMSSI, IO, RealOps, Rope;
CrossRAMSSIImpl: CEDAR PROGRAM
IMPORTS CoreCreate, CoreTransistor, IO, RealOps, Rope
EXPORTS CrossRAMSSI =
BEGIN OPEN CoreCreate, CrossRAMSSI;
fileRoot: ROPE ← "SSI";
CreateInverter: PUBLIC PROC [design: Design, width: NAT ← 4, ratio: REAL ← 2.5] RETURNS [cell: CellType] = {
name: ROPE ← WidthRatioNameProc["Inverter", width, ratio];
IF (cell ← FetchCell[design, name])=NIL THEN {
p: CellType ← TransistorType[design: design, stackType: pE, width: width, ratio: ratio];
n: CellType ← TransistorType[design: design, width: width, ratio: ratio];
cell ← CreateRecordCell[design: design, name: name];
[] ← CreatePublicWire[design: design, on: cell, name: "Vdd"];
[] ← CreatePublicWire[design: design, on: cell, name: "Gnd"];
[] ← CreatePublicWire[design: design, on: cell, name: "Input"];
[] ← CreatePublicWire[design: design, on: cell, name: "Output", attributes: LIST[[$StcOut, NIL]]];
[] ← CreateCellInstance[design: design, in: cell, type: p, bind: "gate: Input, ch1: Vdd, ch2: Output"];
[] ← CreateCellInstance[design: design, in: cell, type: n, bind: "gate: Input, ch1: Output, ch2: Gnd"];
};
};
CreateTristateBuffer: PUBLIC PROC [design: Design, width: NAT ← 4, ratio: REAL ← 2.5] RETURNS [cell: CellType] = {
class: ROPE ← "TristateBuffer";
name: ROPE ← WidthRatioNameProc[class, width, ratio];
IF (cell ← FetchCell[design, name])=NIL THEN {
p: CellType ← TransistorType[design: design, stackHeight: 2, stackType: pE, width: width, ratio: ratio];
n: CellType ← TransistorType[design: design, stackHeight: 2, width: width, ratio: ratio];
cell ← CreateRecordCell[design: design, name: name, attributes: LIST[[$Behave, class], [$BhvFileRoot, fileRoot]]];
[] ← CreatePublicWire[design: design, on: cell, name: "Vdd"];
[] ← CreatePublicWire[design: design, on: cell, name: "Gnd"];
[] ← CreatePublicWire[design: design, on: cell, name: "nInput"];
[] ← CreatePublicWire[design: design, on: cell, name: "Drive"];
[] ← CreatePublicWire[design: design, on: cell, name: "nDrive"];
[] ← CreatePublicWire[design: design, on: cell, name: "Output", attributes: LIST[[$StcTristate, NIL]]];
[] ← CreateWire[design: design, in: cell, name: "pstack"];
[] ← CreateWire[design: design, in: cell, name: "nstack"];
[] ← CreateCellInstance[design: design, in: cell, type: p, bind: "gate: nInput, ch1: Vdd, ch2: pstack"];
[] ← CreateCellInstance[design: design, in: cell, type: p, bind: "gate: nDrive, ch1: pstack, ch2: Output"];
[] ← CreateCellInstance[design: design, in: cell, type: n, bind: "gate: Drive, ch1: Output, ch2: nstack"];
[] ← CreateCellInstance[design: design, in: cell, type: n, bind: "gate: nInput, ch1: nstack, ch2: Gnd"];
};
};
WidthRatioNameProc: PROC [prefix: ROPE, width: NAT, ratio: REAL] RETURNS [name: ROPE] = {
name ← IO.PutFR["%g%g*%g", IO.rope[prefix], IO.int[width], IO.real[ratio]];
};
CreateNAnd: PUBLIC PROC [design: Design, inputCount: NAT ← 2, width: NAT ← 4, ratio: REAL ← 2.5] RETURNS [cell: CellType] = {
class: ROPE ← "NAnd";
name: ROPE ← CountWidthRatioNameProc[class, inputCount, width, ratio];
IF (cell ← FetchCell[design, name])=NIL THEN {
p: CellType ← TransistorType[design: design, stackType: pE, width: width, ratio: ratio];
n: CellType ← TransistorType[design: design, stackHeight: inputCount, width: width, ratio: ratio];
cell ← CreateRecordCell[design: design, name: name, attributes: LIST[[$Behave, class], [$BhvFileRoot, fileRoot], [$BhvArgs, NEW[NAndArgsRec ← [inputCount: inputCount]]]]];
NPortStackProc[design: design, cell: cell, inputCount: inputCount];
FOR input: NAT IN [0..inputCount) DO
[] ← CreateCellInstance[design: design, in: cell, type: p, bind: IO.PutFR["gate: Input[%g], ch1: Vdd, ch2: nOutput", IO.int[input]]];
[] ← CreateCellInstance[design: design, in: cell, type: n, bind: 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]]]]];
ENDLOOP;
};
};
CreateAnd: PUBLIC PROC [design: Design, inputCount: NAT ← 2, width: NAT ← 4, ratio: REAL ← 2.5] RETURNS [cell: CellType] = {
name: ROPE ← CountWidthRatioNameProc["And", inputCount, width, ratio];
IF (cell ← FetchCell[design, name])=NIL THEN {
inputSeq: Wire ← CreateWireSequenceType[design: design, count: inputCount];
nand: CellType ← CreateNAnd[design: design, inputCount: inputCount, width: width, ratio: ratio]; -- fix this to scale nand to inverter gate cap.
invert: CellType ← CreateInverter[design: design, width: width, ratio: ratio];
cell ← CreateRecordCell[design: design, name: name];
[] ← CreatePublicWire[design: design, on: cell, name: "Vdd"];
[] ← CreatePublicWire[design: design, on: cell, name: "Gnd"];
[] ← CreatePublicWire[design: design, on: cell, name: "Input", type: inputSeq];
[] ← CreatePublicWire[design: design, on: cell, name: "Output", attributes: LIST[[$StcOut, NIL]]];
[] ← CreateWire[design: design, in: cell, name: "nOutput"];
[] ← CreateCellInstance[design: design, in: cell, type: nand];
[] ← CreateCellInstance[design: design, in: cell, type: invert, bind: "Input: nOutput"];
};
};
CreateNOr: PUBLIC PROC [design: Design, inputCount: NAT ← 2, width: NAT ← 4, ratio: REAL ← 2.5] RETURNS [cell: CellType] = {
name: ROPE ← CountWidthRatioNameProc["NOr", inputCount, width, ratio];
IF (cell ← FetchCell[design, name])=NIL THEN {
p: CellType ← TransistorType[design: design, stackHeight: inputCount, stackType: pE, width: width, ratio: ratio];
n: CellType ← TransistorType[design: design, width: width, ratio: ratio];
cell ← CreateRecordCell[design: design, name: name];
NPortStackProc[design: design, cell: cell, inputCount: inputCount];
FOR input: NAT IN [0..inputCount) DO
[] ← CreateCellInstance[design: design, in: cell, type: p, bind: 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]]]]];
[] ← CreateCellInstance[design: design, in: cell, type: n, bind: IO.PutFR["gate: Input[%g], ch1: nOutput, ch2: Gnd", IO.int[input]]];
ENDLOOP;
};
};
CreateOr: PUBLIC PROC [design: Design, inputCount: NAT ← 2, width: NAT ← 4, ratio: REAL ← 2.5] RETURNS [cell: CellType] = {
name: ROPE ← CountWidthRatioNameProc["Or", inputCount, width, ratio];
IF (cell ← FetchCell[design, name])=NIL THEN {
inputSeq: Wire ← CreateWireSequenceType[design: design, count: inputCount];
invertSeq: CellType ← CreateSequenceCell[design: design, name: Rope.Cat[name, "InverterSeq"], baseCell: CreateInverter[design: design, width: 4, ratio: ratio], count: inputCount, sequencePorts: LIST["Input", "Output"]];
nand: CellType ← CreateNAnd[design: design, inputCount: inputCount, width: width, ratio: ratio];
cell ← CreateRecordCell[design: design, name: name];
[] ← CreatePublicWire[design: design, on: cell, name: "Vdd"];
[] ← CreatePublicWire[design: design, on: cell, name: "Gnd"];
[] ← CreatePublicWire[design: design, on: cell, name: "Input", type: inputSeq];
[] ← CreatePublicWire[design: design, on: cell, name: "Output", attributes: LIST[[$StcOut, NIL]]];
[] ← CreateWire[design: design, in: cell, name: "nInput", type: inputSeq];
[] ← CreateCellInstance[design: design, in: cell, type: invertSeq, bind: "Input: Input, Output: nInput"];
[] ← CreateCellInstance[design: design, in: cell, type: nand, bind: "Input: nInput, nOutput: Output"];
};
};
NPortStackProc: PROC [design: Design, cell: CellType, inputCount: NAT] = {
inputSeq: Wire ← CreateWireSequenceType[design: design, count: inputCount];
[] ← CreatePublicWire[design: design, on: cell, name: "Vdd"];
[] ← CreatePublicWire[design: design, on: cell, name: "Gnd"];
[] ← CreatePublicWire[design: design, on: cell, name: "Input", type: inputSeq];
FOR input: NAT IN [0..inputCount-1) DO
[] ← CreateWire[design: design, in: cell, name: IO.PutFR["stack%g", IO.int[input]]];
ENDLOOP;
[] ← CreatePublicWire[design: design, on: cell, name: "nOutput", attributes: LIST[[$StcOut, NIL]]];
};
CountWidthRatioNameProc: PROC [prefix: ROPE, inputCount: NAT, width: NAT, ratio: REAL] RETURNS [name: ROPE] = {
name ← IO.PutFR["%g%g*%g*%g", IO.rope[prefix], IO.int[inputCount], IO.int[width], IO.real[ratio]];
};
TransistorType: PROC [design: Design, stackHeight: NAT ← 1, stackType: CoreTransistor.TransistorType ← nE, width: NAT, ratio: REAL] RETURNS [t: CellType] = {
tWidth: NAT ← stackHeight * width;
IF stackType = pE THEN tWidth ← RealOps.RoundLI[RealOps.Float[tWidth] * ratio, [round: rn]];
t ← CoreTransistor.Create[args: NEW[CoreTransistor.TransistorRec ← [type: stackType, width: tWidth]]];
};
END.