<> <> <> <> <<>> 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.