ROPE = RegisterStructureProc[name: "BidirectionalPad", proc: CreateBidirectionalPad];
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"]];
};
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;
};
};