SSIImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Barth, January 23, 1986 5:30:16 pm PST
Louis Monier October 21, 1985 5:26:34 pm PDT
Bertrand Serlet January 27, 1986 4:16:01 pm PST
DIRECTORY Core, CoreCreate, IO, RealOps, Rosemary, SSI, Ports;
SSIImpl: CEDAR PROGRAM
IMPORTS CoreCreate, IO, RealOps, Rosemary, Ports
EXPORTS SSI
= BEGIN OPEN SSI, CoreCreate;
WidthRatioNameProc: PROC [prefix: ROPE, width: NAT ← 4, ratio: REAL ← 2.5] RETURNS [name: ROPE] = {
name ← IO.PutFR["%g%g*%g", IO.rope[prefix], IO.int[width], IO.real[ratio]];
};
CountWidthRatioNameProc: PROC [prefix: ROPE, inputCount: NAT, width: NAT ← 4, ratio: REAL ← 2.5] RETURNS [name: ROPE] = {
name ← IO.PutFR["%g%g*%g*%g", IO.rope[prefix], IO.int[inputCount], IO.int[width], IO.real[ratio]];
};
MakeTransistor: PROC [stackHeight: NAT ← 1, stackType: TransistorType ← nE, width: NAT ← 4, ratio: REAL ← 2.5] RETURNS [t: Core.CellType] = {
tWidth: NAT ← stackHeight * width;
IF stackType = pE THEN tWidth ← RealOps.RoundLI[RealOps.Float[tWidth] * ratio, [round: rn]];
t ← Transistor[type: stackType, width: tWidth];
};
InverterName: ROPE = Rosemary.Register[roseClassName: "Inverter", evalSimple: InverterSimple];
InverterVdd: NAT = 0;
InverterGnd: NAT = 1;
InverterInput: NAT = 2;
InverternOutput: NAT = 3;
Inverter: PUBLIC PROC [w: NAT ← 4, r: REAL ← 2.5] RETURNS [ct: CellType] = {
ct ← Cell[
name: WidthRatioNameProc[prefix: InverterName, width: w, ratio: r],
public: Wires["Vdd", "Gnd", "Input", "nOutput"],
instances: LIST [
Instance[MakeTransistor[width: w, ratio: r, stackType: pE],
["gate", "Input"], ["ch1", "Vdd"], ["ch2", "nOutput"]],
Instance[MakeTransistor[width: w, ratio: r, stackType: nE],
["gate", "Input"], ["ch1", "nOutput"], ["ch2", "Gnd"]]]];
[] ← Rosemary.BindCellType[cellType: ct, roseClassName: InverterName];
[] ← Rosemary.AddCutSets[cellType: ct, cs1: "JustAboveTransistors"];
[] ← Ports.InitPort[wire: ct.public[InverterVdd], initType: l];
[] ← Ports.InitPort[wire: ct.public[InverterGnd], initType: l];
[] ← Ports.InitPort[wire: ct.public[InverterInput], initType: l];
[] ← Ports.InitPort[wire: ct.public[InverternOutput], initType: l, initDrive: drive];
};
InverterSimple: Rosemary.EvalProc = {
p[InverternOutput].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;
};
TristateBufferName: ROPE = Rosemary.Register[roseClassName: "TristateBuffer", evalSimple: TristateSimple];
TristateVdd: NAT = 0;
TristateGnd: NAT = 1;
TristateInput: NAT = 2;
TristateDrive: NAT = 3;
TristatenDrive: NAT = 4;
TristatenOutput: NAT = 5;
TristateBuffer: PUBLIC PROC [w: NAT ← 4, r: REAL ← 2.5] RETURNS [ct: CellType] = {
pType: Core.CellType ← MakeTransistor[stackHeight: 2, stackType: pE, width: w, ratio: r];
nType: Core.CellType ← MakeTransistor[stackHeight: 2, stackType: nE, width: w, ratio: r];
ct ← Cell[
name: WidthRatioNameProc[prefix: TristateBufferName, width: w, ratio: r],
public: Wires["Vdd", "Gnd", "Input", "Drive", "nDrive", "nOutput"],
onlyInternal: Wires["pstack", "nstack"],
instances: LIST [
Instance[pType, ["gate", "Input"], ["ch1", "Vdd"], ["ch2", "pstack"]],
Instance[pType, ["gate", "nDrive"], ["ch1", "pstack"], ["ch2", "nOutput"]],
Instance[nType, ["gate", "Drive"], ["ch1", "nOutput"], ["ch2", "nstack"]],
Instance[nType, ["gate", "Input"], ["ch1", "nstack"], ["ch2", "Gnd"]]]];
[] ← Rosemary.BindCellType[cellType: ct, roseClassName: TristateBufferName];
[] ← Rosemary.AddCutSets[cellType: ct, cs1: "JustAboveTransistors"];
};
TristateSimple: Rosemary.EvalProc = {
IF NOT p[TristateVdd].b OR p[TristateGnd].b OR (p[TristateDrive].b AND NOT p[TristatenDrive].b) THEN SIGNAL Rosemary.Stop[];
p[TristatenOutput].d ← IF p[TristateDrive].b OR NOT p[TristatenDrive].b THEN drive ELSE none;
p[TristatenOutput].b ← NOT p[TristateInput].b;
};
NAndName: ROPE = Rosemary.Register[roseClassName: "NAnd", evalSimple: NAndSimple];
NAndVdd: NAT = 0;
NAndGnd: NAT = 1;
NAndInput: NAT = 2;
NAndnOutput: NAT = 3;
NAnd: PUBLIC PROC [i: NAT, w: NAT ← 4, r: REAL ← 2.5] RETURNS [ct: CellType] = {
instances: LIST OF CellInstance ← NIL;
pType: Core.CellType ← MakeTransistor[stackType: pE, width: w, ratio: r];
nType: Core.CellType ← MakeTransistor[stackHeight: i, stackType: nE, width: w, ratio: r];
FOR input: NAT IN [0..i) DO
instances ← CONS[Instance[pType,
["gate", Index["Input", input]], ["ch1", "Vdd"], ["ch2", "nOutput"]],
instances];
instances ← CONS[Instance[nType,
["gate", Index["Input", input]],
["ch1", IF input=0 THEN "nOutput" ELSE Index["stack", input-1]],
["ch2", IF input=i-1 THEN "Gnd" ELSE Index["stack", input]]],
instances];
ENDLOOP;
ct ← Cell[
name: CountWidthRatioNameProc[NAndName, i, w, r],
public: Wires["Vdd", "Gnd", Seq["Input", i], "nOutput"],
onlyInternal: Wires[Seq["stack", i-1]],
instances: instances];
[] ← Rosemary.BindCellType[cellType: ct, roseClassName: NAndName];
[] ← Rosemary.AddCutSets[cellType: ct, cs1: "JustAboveTransistors"];
[] ← Ports.InitPort[wire: ct.public[NAndnOutput], initType: b, initDrive: drive];
};
NAndSimple: Rosemary.EvalProc = {
IF NOT p[NAndVdd].b OR p[NAndGnd].b THEN SIGNAL Rosemary.Stop[];
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;
};
AndName: ROPE = Rosemary.Register[roseClassName: "And", evalSimple: AndSimple];
AndVdd: NAT = 0;
AndGnd: NAT = 1;
AndInput: NAT = 2;
AndOutput: NAT = 3;
And: PUBLIC PROC [i: NAT, w: NAT ← 4, r: REAL ← 2.5] RETURNS [ct: CellType] = {
ct ← Cell[
name: CountWidthRatioNameProc[AndName, i, w, r],
public: Wires["Vdd", "Gnd", Seq["Input", i], "Output"],
onlyInternal: Wires["nOutput"],
instances: LIST [
Instance[NAnd[i, w, r]], -- fix this to scale nand to inverter gate cap.
Instance[Inverter[w, r], ["Input", "nOutput"]]]];
[] ← Rosemary.BindCellType[cellType: ct, roseClassName: AndName];
[] ← Rosemary.AddCutSets[cellType: ct, cs1: "JustAboveTransistors"];
[] ← Ports.InitPort[wire: ct.public[AndOutput], initType: b, initDrive: drive];
};
AndSimple: Rosemary.EvalProc = {
IF NOT p[AndVdd].b OR p[AndGnd].b THEN SIGNAL Rosemary.Stop[];
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;
};
NOrName: ROPE = Rosemary.Register[roseClassName: "NOr", evalSimple: NOrSimple];
NOrVdd: NAT = 0;
NOrGnd: NAT = 1;
NOrInput: NAT = 2;
NOrnOutput: NAT = 3;
NOr: PUBLIC PROC [i: NAT, w: NAT ← 4, r: REAL ← 2.5] RETURNS [ct: CellType] = {
instances: LIST OF CellInstance ← NIL;
pType: Core.CellType ← MakeTransistor[stackType: pE, stackHeight: i, width: w, ratio: r];
nType: Core.CellType ← MakeTransistor[stackType: nE, width: w, ratio: r];
FOR input: NAT IN [0..i) DO
instances ← CONS[Instance[pType,
["gate", Index["Input", input]],
["ch1", IF input=0 THEN "Vdd" ELSE Index["stack", input-1]],
["ch2", IF input=i-1 THEN "nOutput" ELSE Index["stack", input]]],
instances];
instances ← CONS[Instance[nType,
["gate", Index["Input", input]], ["ch1", "nOutput"], ["ch2", "Gnd"]],
instances];
ENDLOOP;
ct ← Cell[
name: CountWidthRatioNameProc[NOrName, i, w, r],
public: Wires["Vdd", "Gnd", Seq["Input", i], "nOutput"],
onlyInternal: Wires[Seq["stack", i-1]],
instances: instances];
[] ← Rosemary.BindCellType[cellType: ct, roseClassName: NOrName];
[] ← Rosemary.AddCutSets[cellType: ct, cs1: "JustAboveTransistors"];
[] ← Ports.InitPort[wire: ct.public[NOrnOutput], initType: b, initDrive: drive];
};
NOrSimple: Rosemary.EvalProc = {
IF NOT p[NOrVdd].b OR p[NOrGnd].b THEN SIGNAL Rosemary.Stop[];
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;
};
OrName: ROPE = Rosemary.Register[roseClassName: "Or", evalSimple: OrSimple];
OrVdd: NAT = 0;
OrGnd: NAT = 1;
OrInput: NAT = 2;
OrOutput: NAT = 3;
Or: PUBLIC PROC [i: NAT, w: NAT ← 4, r: REAL ← 2.5] RETURNS [ct: CellType] = {
ct ← Cell[
name: CountWidthRatioNameProc[OrName, i, w, r],
public: Wires["Vdd", "Gnd", Seq["Input", i], "Output"],
onlyInternal: Wires[Seq["nInput", i]],
instances: LIST [
Instance[InverterSeq[i, w, r], ["Input", "Input"], ["nOutput", "nInput"]],
Instance[NAnd[i, w, r], ["Input", "nInput"], ["nOutput", "Output"]]]];
[] ← Rosemary.BindCellType[cellType: ct, roseClassName: OrName];
[] ← Rosemary.AddCutSets[cellType: ct, cs1: "JustAboveTransistors"];
[] ← Ports.InitPort[wire: ct.public[OrOutput], initType: b, initDrive: drive];
};
OrSimple: Rosemary.EvalProc = {
IF NOT p[OrVdd].b OR p[OrGnd].b THEN SIGNAL Rosemary.Stop[];
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;
};
InverterSeqName: ROPE = "InverterSeq";
InverterSeq: PROC [inputCount: NAT, width: NAT ← 4, ratio: REAL ← 2.5] RETURNS [ct: CellType] = {
baseCell: CellType ← Inverter[width, ratio];
ct ← SequenceCell[
name: CountWidthRatioNameProc[InverterSeqName, inputCount, width, ratio],
baseCell: baseCell,
count: inputCount,
sequencePorts: Wires[baseCell.public[InverterInput], baseCell.public[InverternOutput]]];
};
END.