CrossRAMPads.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last Edited by: Barth, November 5, 1985 2:44:49 pm PST
Bertrand Serlet November 9, 1985 2:41:06 pm PST
DIRECTORY Core, CoreCompose, CoreFlatten, CoreProperties, Rosemary;
CrossRAMPads: CEDAR PROGRAM
IMPORTS CoreCompose, CoreFlatten, CoreProperties, Rosemary =
BEGIN OPEN CoreCompose;
BasicInputPad: ROPE = RegisterStructureProc[name: "BasicInputPad", proc: CreateBasicInputPad];
BasicInputPadCellType: Core.CellType ← NIL;
CreateBasicInputPad: StructureProc = {
inverter: Core.CellType;
IF BasicInputPadCellType#NIL THEN RETURN[BasicInputPadCellType];
PushInt[context: context, prop: $SSIWidth, val: 64];
PushReal[context: context, prop: $SSIRatio, val: 0.125];
inverter ← CreateStructure[name: "Inverter", context: context];
BasicInputPadCellType ← cellType ← CreateRecordCell[
name: BasicInputPad,
context: context,
public: CreateWires[context, "Vdd, Gnd, Pad, nOutput"],
instances: LIST [[actual: "Input: Pad, Output: nOutput", type: inverter]]];
IF GetBool[context, $Rosemary] THEN Rosemary.Bind[cellType: cellType, roseClassName: BasicInputPadRoseClass];
CoreProperties.PutCellTypeProp[on: cellType, prop: CoreFlatten.CoreFlattenCutSets, value: LIST["JustAboveTransistors"]];
};
BPVdd: NAT = 0;
BPGnd: NAT = 1;
BPPad: NAT = 2;
BPnOutput: NAT = 3;
BasicInputPadRoseClass: ROPE = Rosemary.Register[roseClassName: BasicInputPad, init: BasicInputPadInit, evalSimple: BasicInputPadSimple];
BasicInputPadInit: Rosemary.InitProc = {
FOR port: NAT IN [0..p.size) DO
p[port].type ← b;
ENDLOOP;
p[BPnOutput].d ← drive;
};
BasicInputPadSimple: Rosemary.EvalProc = {
IF NOT p[BPVdd].b OR p[BPGnd].b THEN SIGNAL Rosemary.Stop[];
p[BPnOutput].b ← NOT p[BPPad].b;
};
InputPad: ROPE = RegisterStructureProc[name: "InputPad", proc: CreateInputPad];
InputPadCellType: Core.CellType ← NIL;
CreateInputPad: StructureProc = {
inverter: Core.CellType;
IF InputPadCellType#NIL THEN RETURN[InputPadCellType];
PushInt[context: context, prop: $SSIWidth, val: 8];
PushReal[context: context, prop: $SSIRatio, val: 2.5];
inverter ← CreateStructure[name: "Inverter", context: context];
InputPadCellType ← cellType ← CreateRecordCell[
name: InputPad,
context: context,
public: CreateWires[context, "Vdd, Gnd, Pad, Output"],
onlyInternal: CreateWires[context, "nOutput"],
instances: LIST [
[type: CreateStructure[name: BasicInputPad, context: context]],
[type: inverter, actual: "Input: nOutput, Output: Output"]]];
};
DifferentialInputPad: ROPE = RegisterStructureProc[name: "DifferentialInputPad", proc: CreateDifferentialInputPad];
DifferentialInputPadCellType: Core.CellType ← NIL;
CreateDifferentialInputPad: StructureProc = {
inverter8, inverter4: Core.CellType;
IF DifferentialInputPadCellType#NIL THEN RETURN[DifferentialInputPadCellType];
PushInt[context: context, prop: $SSIWidth, val: 8];
PushReal[context: context, prop: $SSIRatio, val: 2.5];
inverter8 ← CreateStructure[name: "Inverter", context: context];
PushInt[context: context, prop: $SSIWidth, val: 4];
inverter4 ← CreateStructure[name: "Inverter", context: context];
DifferentialInputPadCellType ← cellType ← CreateRecordCell[
name: DifferentialInputPad,
context: context,
public: CreateWires[context, "Vdd, Gnd, Pad, Output, nOutput"],
onlyInternal: CreateWires[context, "nbpOut, bpOut"],
instances: LIST [
[type: CreateStructure[name: BasicInputPad, context: context], actual: "nOutput: nbpOut"],
[type: inverter8, actual: "Input: nbpOut, Output: Output"],
[type: inverter4, actual: "Input: nbpOut, Output: bpOut"],
[type: inverter8, actual: "Input: bpOut, Output: nOutput"]]];
};
BidirectionalPad: ROPE = RegisterStructureProc[name: "BidirectionalPad", proc: CreateBidirectionalPad];
BidirectionalPadCellType: Core.CellType ← NIL;
CreateBidirectionalPad: StructureProc = {
tristate, nand2, nor2: Core.CellType;
IF BidirectionalPadCellType#NIL THEN RETURN[BidirectionalPadCellType];
PushReal[context: context, prop: $SSIRatio, val: 2.5];
PushInt[context: context, prop: $SSIWidth, val: 32];
tristate ← CreateStructure[name: "TristateBuffer", context: context];
PushInt[context: context, prop: $SSIWidth, val: 8];
PushInt[context: context, prop: $SSIInputCount, val: 2];
nand2 ← CreateStructure[name: "NAnd", context: context];
nor2 ← CreateStructure[name: "NOr", context: context];
BidirectionalPadCellType ← cellType ← CreateRecordCell[
name: BidirectionalPad,
context: context,
public: CreateWires[context, "Vdd, Gnd, Read, nRead, Write, nWrite, Pad, Data"],
onlyInternal: CreateWires[context, "nandOut, norOut, nbpOut"],
instances: LIST [
[type: CreateStructure[name: BasicInputPad, context: context], actual: "nOutput: nbpOut"],
[type: tristate, actual: "nInput: nbpOut, Drive: Write, nDrive: nWrite, Output: Data"],
[type: nand2, actual: "Input: [Read, Data], nOutput: nandOut"],
[type: nor2, actual: "Input: [nRead, Data], nOutput: norOut"],
[type: CreateTransistor[type: nE, width: 300], actual: "gate: norOut, ch1: Pad, ch2: Gnd"],
[type: CreateTransistor[type: pE, width: 600], actual: "gate: nandOut, ch1: Vdd, ch2: Pad"]]];
IF GetBool[context, $Rosemary] THEN Rosemary.Bind[cellType: cellType, roseClassName: BidirectionalPadRoseClass];
CoreProperties.PutCellTypeProp[on: cellType, prop: CoreFlatten.CoreFlattenCutSets, value: LIST["JustAboveTransistors"]];
};
BiVdd: NAT = 0;
BiGnd: NAT = 1;
BiRead: NAT = 2;
BinRead: NAT = 3;
BiWrite: NAT = 4;
BinWrite: NAT = 5;
BiPad: NAT = 6;
BiData: NAT = 7;
BidirectionalPadRoseClass: ROPE = Rosemary.Register[roseClassName: BidirectionalPad, init: BidirectionalPadInit, evalSimple: BidirectionalPadSimple];
BidirectionalPadInit: Rosemary.InitProc = {
FOR port: NAT IN [0..p.size) DO
p[port].type ← b;
ENDLOOP;
};
BidirectionalPadSimple: Rosemary.EvalProc = {
write: BOOL ← p[BiWrite].b OR NOT p[BinWrite].b;
read: BOOL ← p[BiRead].b OR NOT p[BinRead].b;
IF NOT p[BiVdd].b OR p[BiGnd].b OR (write AND read) THEN SIGNAL Rosemary.Stop[];
p[BiPad].d ← none;
p[BiData].d ← none;
IF write THEN {
p[BiData].b ← p[BiPad].b;
p[BiData].d ← IF (p[BiPad].b AND NOT p[BinWrite].b) OR (NOT p[BiPad].b AND p[BiWrite].b) THEN drive ELSE none;
};
IF read THEN {
p[BiPad].b ← p[BiData].b;
p[BiPad].d ← IF (p[BiData].b AND NOT p[BinRead].b) OR (NOT p[BiData].b AND p[BiRead].b) THEN drive ELSE none;
};
};
END.