<> <> <> <> <> <<>> DIRECTORY Basics, CD, Core, CoreBeau, CoreClasses, CoreCompose, CoreOps, IO, PWCore, Rope, Sinix; CrossRAMTop: CEDAR PROGRAM IMPORTS Basics, CoreBeau, CoreCompose, CoreOps, PWCore, Sinix = BEGIN OPEN CoreCompose; <> CrossRAMTop: ROPE = RegisterStructureProc[name: "CrossRAMTop", proc: CreateCrossRAMTop]; CreateCrossRAMTop: StructureProc = { addressBits: INT _ GetInt[context, $addressBits]; addressDecoderBits: INT _ GetInt[context, $addressDecoderBits]; columnOcts: INT _ GetInt[context, $columnOcts]; select: INT _ GetInt[context, $select]; log2Select: INT _ GetInt[context, $log2Select]; driverPairCount: INT _ (addressBits-log2Select)/2; PushInt[context, $driverPairCount, driverPairCount]; cellType _ CreateRecordCell[ name: CrossRAMTop, context: context, public: CreateWires[context, "VddLeft, VddRight, Gnd, WriteB, nWriteB, ReadB, nReadB, AddressB[seq: addressBits], DataB[seq: columnOcts], AdrBit[seq: addressDecoderBits], nAdrBit[seq: addressDecoderBits], Bit[seq: select*columnOcts], nBit[seq: select*columnOcts]"], onlyInternal: CreateWires[context, "VddHigh, GndHigh, Select[seq: select]"], instances: LIST [ [type: DecoderDriverLeft[context: context, log2Select: log2Select], actual: "Vdd: VddLeft, AddressB: AddressB[start: 0, len: log2Select]"], [type: DecoderDriverSequence[context: context, log2Select: log2Select, driverPairCount: driverPairCount], actual: "Vdd: VddLeft, VddTop: VddLeft, VddHigh: VddLeft, GndHigh: Gnd, LowAddressB: AddressB[start: 0, len: log2Select], HighAddressB: AddressB[start: log2Select, len: addressBits-log2Select]"], [type: DecoderLogicDriver[context: context, select: select, log2Select: log2Select], actual: "Vdd: VddLeft, AddressB: AddressB[start: 0, len: log2Select], AdrBit: AdrBit[addressDecoderBits-1], nAdrBit: nAdrBit[addressDecoderBits-1]"], [type: CreateStructure[name: "DataBuffer", context: context], actual: "Vdd: VddRight"], [type: DataBufferRight[context: context], actual: "Vdd: VddRight"] ] ]; IF GetBool[context, $PWCore] THEN PWCore.SetAbutX[cellType: cellType]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; <> DecoderDriverLeft: PROC [context: CoreCompose.Context, log2Select: INT] RETURNS [cellType: CellType] = { cellType _ CoreBeau.Cell[ name: "DecoderDriverLeft", public: CoreBeau.Wires["Vdd", "Gnd", CoreBeau.Seq["AddressB", log2Select]], instances: NIL ]; IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; DecoderDriverSequence: PROC [context: CoreCompose.Context, log2Select, driverPairCount: INT] RETURNS [cellType: CellType] = { driverCount: INT _ 2*driverPairCount; MakeStackPA: PROC [base: ROPE] RETURNS [pa: CoreBeau.PA] = { pa _ [public: base, actual: CoreBeau.Indexes[wr: base, length: driverCount-2]]; }; MakePairPA: PROC [base: ROPE] RETURNS [pa: CoreBeau.PA] = { pa _ [public: base, actual: CoreBeau.Indexes[wr: base, start: driverCount-2, length: 2]]; }; cellType _ CoreBeau.Cell[ name: "DecoderDriverSequence", public: CoreBeau.Wires["Vdd", "Gnd", "VddTop", "VddHigh", "GndHigh", CoreBeau.Seq["LowAddressB", log2Select], CoreBeau.Seq["HighAddressB", driverCount], CoreBeau.Seq["AdrBit", driverCount], CoreBeau.Seq["nAdrBit", driverCount]], instances: LIST [ CoreBeau.Instance[ DecoderDriverStackBitSeq[context: context, log2Select: log2Select, driverPairCount: driverPairCount], MakeStackPA["HighAddressB"], MakeStackPA["AdrBit"], MakeStackPA["nAdrBit"] ], CoreBeau.Instance[ DecoderDriverTreeBit[context: context, log2Select: log2Select], MakePairPA["HighAddressB"], MakePairPA["AdrBit"], MakePairPA["nAdrBit"] ] ] ]; IF GetBool[context, $PWCore] THEN PWCore.SetAbutX[cellType: cellType]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; DecoderDriverStackBitSeq: PROC [context: CoreCompose.Context, log2Select, driverPairCount: INT] RETURNS [cellType: CellType] = { cellType _ CoreBeau.SequenceCell[ name: "DecoderDriverStackBitSeq", baseCell: DecoderDriverStackBit[context: context, log2Select: log2Select], count: driverPairCount-1, sequencePorts: CoreBeau.Wires["HighAddressB", "AdrBit", "nAdrBit"]]; IF GetBool[context, $PWCore] THEN PWCore.SetArrayX[cellType: cellType]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; DecoderDriverStackBit: PROC [context: CoreCompose.Context, log2Select: INT] RETURNS [cellType: CellType] = { decoderDriver: Core.CellType _ DecoderDriver[context: context, log2Select: log2Select]; cellType _ CoreBeau.Cell[ name: "DecoderDriverStackBit", public: CoreOps.CopyWire[decoderDriver.public], instances: LIST [CoreBeau.Instance[decoderDriver]]]; IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; DecoderDriverTreeBit: PROC [context: CoreCompose.Context, log2Select: INT] RETURNS [cellType: CellType] = { decoderDriver: Core.CellType _ DecoderDriver[context: context, log2Select: log2Select]; cellType _ CoreBeau.Cell[ name: "DecoderDriverTreeBit", public: CoreOps.CopyWire[decoderDriver.public], instances: LIST [CoreBeau.Instance[decoderDriver]]]; IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; <> DecoderDriverCellType: Core.CellType; DecoderDriver: PROC [context: CoreCompose.Context, log2Select: INT] RETURNS [cellType: CellType] = { IF DecoderDriverCellType#NIL THEN RETURN[DecoderDriverCellType]; DecoderDriverCellType _ cellType _ CoreBeau.SequenceCell[ name: "DecoderDriver", baseCell: DecoderDriverHalf[context: context, log2Select: log2Select], count: 2, sequencePorts: CoreBeau.Wires["HighAddressB", "AdrBit", "nAdrBit"]]; }; DecoderDriverHalf: PROC [context: CoreCompose.Context, log2Select: INT] RETURNS [cellType: CellType] = { inverter4, inverter16: Core.CellType; PushReal[context: context, prop: $SSIRatio, val: 2.5]; PushInt[context: context, prop: $SSIWidth, val: 4]; inverter4 _ CreateStructure[name: "Inverter", context: context]; PushInt[context: context, prop: $SSIWidth, val: 16]; inverter16 _ CreateStructure[name: "Inverter", context: context]; cellType _ CoreBeau.Cell[ name: "DecoderDriverHalf", public: CoreBeau.Wires["Vdd", "Gnd", "VddTop", "VddHigh", "GndHigh", "HighAddressB", "AdrBit", "nAdrBit", CoreBeau.Seq["LowAddressB", log2Select]], onlyInternal: CoreBeau.Wires["nAddress"], instances: LIST [ CoreBeau.Instance[inverter4, ["Vdd", "VddHigh"], ["Gnd", "GndHigh"], ["Input", "HighAddressB"], ["Output", "nAddress"]], CoreBeau.Instance[inverter16, ["Input", "nAddress"], ["Output", "AdrBit"]], CoreBeau.Instance[inverter16, ["Input", "HighAddressB"], ["Output", "nAdrBit"]] ]]; }; DecoderLogicDriver: PROC [context: CoreCompose.Context, select, log2Select: INT] RETURNS [cellType: CellType] = { invert8: Core.CellType; and: Core.CellType; -- inputCount: log2Select, width: 16 instances: LIST OF CoreClasses.CellInstance _ NIL; -- fill in! PushReal[context: context, prop: $SSIRatio, val: 2.5]; PushInt[context: context, prop: $SSIWidth, val: 8]; invert8 _ CreateStructure[name: "Inverter", context: context]; PushInt[context: context, prop: $SSIWidth, val: 16]; PushInt[context: context, prop: $SSIInputCount, val: log2Select]; and _ CreateStructure[name: "And", context: context]; <<-- Drop three inverters>> FOR adrBit: INT IN [0 .. log2Select) DO instances _ CONS [ CoreBeau.Instance[ invert8, ["Input", CoreBeau.Index["AddressB", adrBit]], ["Output", CoreBeau.Index["nHighAddressB", adrBit]] ], instances]; ENDLOOP; <<-- Drop eight nand gates>> FOR sel: INT IN [0 .. select) DO bind: LIST OF CoreBeau.WR _ NIL; FOR adrBit: INT DECREASING IN [0 .. log2Select) DO bind _ CONS [ CoreBeau.Index[ IF Basics.BITAND[Basics.BITSHIFT[sel, adrBit-log2Select+1], 1]#0 THEN "AddressB" ELSE "nHighAddressB", adrBit], bind]; ENDLOOP; instances _ CONS [ CoreBeau.Instance[ and, ["Input", CoreBeau.WireList[bind]], ["Output", CoreBeau.Index["Select", sel]] ], instances]; ENDLOOP; cellType _ CoreBeau.Cell[ name: "DecoderLogicDriver", public: CoreBeau.Wires["Vdd", "Gnd", "AdrBit", "nAdrBit", CoreBeau.Seq["AddressB", log2Select], CoreBeau.Seq["Select", select]], onlyInternal: CoreBeau.Wires[CoreBeau.Seq["nHighAddressB", log2Select]], instances: instances ]; IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; <<>> DataBufferRight: PROC [context: CoreCompose.Context] RETURNS [cellType: CellType] = { cellType _ CoreBeau.Cell[ name: "DataBufferRight", public: CoreBeau.Wires["Vdd", "WriteB", "nWriteB", "ReadB", "nReadB"], instances: NIL ]; IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; RegisterIntProperty[prop: $driverPairCount]; END.