<> <> <> <> <> <<>> DIRECTORY Basics, CD, Core, CoreClasses, CoreCompose, CoreOps, IO, PWCore, Rope, Sinix; CrossRAMTop: CEDAR PROGRAM IMPORTS Basics, CoreCompose, CoreOps, IO, PWCore, Rope, 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]; PushInt[context, $driverPairCount, (addressBits-log2Select)/2]; 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: CreateStructure[name: DecoderDriverLeft, context: context], actual: "Vdd: VddLeft, AddressB: AddressB[start: 0, len: log2Select]"], [type: CreateStructure[name: DecoderDriverSequence, context: context], actual: "Vdd: VddLeft, VddTop: VddLeft, VddHigh: VddLeft, GndHigh: Gnd, LowAddressB: AddressB[start: 0, len: log2Select], HighAddressB: AddressB[start: log2Select, len: addressBits-log2Select]"], [type: CreateStructure[name: DecoderLogicDriver, context: context], 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: CreateStructure[name: DataBufferRight, context: context], actual: "Vdd: VddRight"] ] ]; IF GetBool[context, $PWCore] THEN PWCore.SetAbutX[cellType: cellType]; IF GetBool[context, $Sinix] THEN [] _ Sinix.ExtractObj[PWCore.GetLayout[cellType]]; }; <> DecoderDriverLeft: ROPE = RegisterStructureProc[name: "DecoderDriverLeft", proc: CreateDecoderDriverLeft]; CreateDecoderDriverLeft: StructureProc = { cellType _ CreateRecordCell[ name: DecoderDriverLeft, context: context, public: CreateWires[context, "Vdd, Gnd, AddressB[seq: log2Select]"]]; IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.ExtractObj[PWCore.GetLayout[cellType]]; }; DecoderDriverSequence: ROPE = RegisterStructureProc[name: "DecoderDriverSequence", proc: CreateDecoderDriverSequence]; CreateDecoderDriverSequence: StructureProc = { driverCount: INT _ 2*GetInt[context, $driverPairCount]; MakeStackRope: PROC [base: ROPE] RETURNS [ROPE] = { RETURN[IO.PutFR["%g: %g[start:0, len:%g]", IO.rope[base], IO.rope[base], IO.int[driverCount-2]]];}; MakePairRope: PROC [base: ROPE] RETURNS [ROPE] = { RETURN[IO.PutFR["%g: %g[start:%g, len:2]", IO.rope[base], IO.rope[base], IO.int[driverCount-2]]];}; cellType _ CreateRecordCell[ name: DecoderDriverSequence, context: context, public: CreateWires[context, "Vdd, Gnd, VddTop, VddHigh, GndHigh, LowAddressB[seq: log2Select], HighAddressB[seq: 2*driverPairCount], AdrBit[seq: 2*driverPairCount], nAdrBit[seq: 2*driverPairCount]"], instances: LIST [ [type: CreateStructure[name: DecoderDriverStackBitSeq, context: context], actual: Rope.Cat[MakeStackRope["HighAddressB"], ", ", MakeStackRope["AdrBit"], ", ", MakeStackRope["nAdrBit"]]], [type: CreateStructure[name: DecoderDriverTreeBit, context: context], actual: Rope.Cat[MakePairRope["HighAddressB"], ", ", MakePairRope["AdrBit"], ", ", MakePairRope["nAdrBit"]]] ] ]; IF GetBool[context, $PWCore] THEN PWCore.SetAbutX[cellType: cellType]; IF GetBool[context, $Sinix] THEN [] _ Sinix.ExtractObj[PWCore.GetLayout[cellType]]; }; DecoderDriverStackBitSeq: ROPE = RegisterStructureProc[name: "DecoderDriverStackBitSeq", proc: CreateDecoderDriverStackBitSeq]; CreateDecoderDriverStackBitSeq: StructureProc = { cellType _ CreateSequenceCell[ name: DecoderDriverStackBitSeq, baseCell: CreateStructure[name: DecoderDriverStackBit, context: context], count: GetInt[context: context, prop: $driverPairCount]-1, sequencePorts: "HighAddressB, AdrBit, nAdrBit"]; IF GetBool[context, $PWCore] THEN PWCore.SetArrayX[cellType: cellType]; IF GetBool[context, $Sinix] THEN [] _ Sinix.ExtractObj[PWCore.GetLayout[cellType]]; }; DecoderDriverStackBit: ROPE = RegisterStructureProc[name: "DecoderDriverStackBit", proc: CreateDecoderDriverStackBit]; CreateDecoderDriverStackBit: StructureProc = { decoderDriver: Core.CellType _ CreateStructure[name: DecoderDriver, context: context]; cellType _ CreateRecordCell[ name: DecoderDriverStackBit, context: context, public: CoreOps.CopyWire[decoderDriver.public], instances: LIST [[type: decoderDriver]]]; IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.ExtractObj[PWCore.GetLayout[cellType]]; }; DecoderDriverTreeBit: ROPE = RegisterStructureProc[name: "DecoderDriverTreeBit", proc: CreateDecoderDriverTreeBit]; CreateDecoderDriverTreeBit: StructureProc = { decoderDriver: Core.CellType _ CreateStructure[name: DecoderDriver, context: context]; cellType _ CreateRecordCell[ name: DecoderDriverTreeBit, context: context, public: CoreOps.CopyWire[decoderDriver.public], instances: LIST [[type: decoderDriver]]]; IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.ExtractObj[PWCore.GetLayout[cellType]]; }; <> DecoderDriver: ROPE = RegisterStructureProc[name: "DecoderDriver", proc: CreateDecoderDriver]; DecoderDriverCellType: Core.CellType; CreateDecoderDriver: StructureProc = { IF DecoderDriverCellType#NIL THEN RETURN[DecoderDriverCellType]; DecoderDriverCellType _ cellType _ CreateSequenceCell[ name: DecoderDriver, baseCell: CreateStructure[name: DecoderDriverHalf, context: context], count: 2, sequencePorts: "HighAddressB, AdrBit, nAdrBit"]; }; DecoderDriverHalf: ROPE = RegisterStructureProc[name: "DecoderDriverHalf", proc: CreateDecoderDriverHalf]; CreateDecoderDriverHalf: StructureProc = { 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 _ CreateRecordCell[ name: DecoderDriverHalf, context: context, public: CreateWires[context, "Vdd, Gnd, VddTop, VddHigh, GndHigh, HighAddressB, AdrBit, nAdrBit, LowAddressB[seq: log2Select]"], onlyInternal: CreateWires[context, "nAddress"], instances: LIST [ [actual: "Vdd: VddHigh, Gnd: GndHigh, Input: HighAddressB, Output: nAddress", type: inverter4], [actual: "Input: nAddress, Output: AdrBit", type: inverter16], [actual: "Input: HighAddressB, Output: nAdrBit", type: inverter16]]]; }; DecoderLogicDriver: ROPE = RegisterStructureProc[name: "DecoderLogicDriver", proc: CreateDecoderLogicDriver]; CreateDecoderLogicDriver: StructureProc = { select: INT _ GetInt[context, $select]; log2Select: INT _ GetInt[context, $log2Select]; invert8: Core.CellType; and: Core.CellType; -- inputCount: log2Select, width: 16 instances: InstanceList _ 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[[type: invert8, actual: IO.PutFR["Input: AddressB[%g], Output: nHighAddressB[%g]", IO.int[adrBit], IO.int[adrBit]]], instances]; ENDLOOP; <<-- Drop eight nand gates>> FOR sel: INT IN [0..select) DO bind: ROPE _ NIL; FOR adrBit: INT IN [0..log2Select) DO bind _ Rope.Cat[bind, IF Basics.BITAND[Basics.BITSHIFT[sel, adrBit-log2Select+1], 1]#0 THEN IO.PutFR["AddressB[%g]", IO.int[adrBit]] ELSE IO.PutFR["nHighAddressB[%g]", IO.int[adrBit]]]; IF adrBit < log2Select-1 THEN bind _ Rope.Cat[bind, ", "]; ENDLOOP; instances _ CONS[[type: and, actual: IO.PutFR["Input: [%g], Output: Select[%g]", IO.rope[bind], IO.int[sel]]], instances]; ENDLOOP; cellType _ CreateRecordCell[ name: DecoderLogicDriver, context: context, public: CreateWires[context, "Vdd, Gnd, AdrBit, nAdrBit, AddressB[seq: log2Select], Select[seq: select]"], onlyInternal: CreateWires[context, "nHighAddressB[seq: log2Select]"], instances: instances]; IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.ExtractObj[PWCore.GetLayout[cellType]]; }; <<>> DataBufferRight: ROPE = RegisterStructureProc[name: "DataBufferRight", proc: CreateDataBufferRight]; CreateDataBufferRight: StructureProc = { cellType _ CreateRecordCell[ name: DataBufferRight, context: context, public: CreateWires[context, "Vdd, WriteB, nWriteB, ReadB, nReadB"]]; IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.ExtractObj[PWCore.GetLayout[cellType]]; }; RegisterIntProperty[prop: $driverPairCount]; END.