<> <> <> <> <> <<>> DIRECTORY CD, CDSymbolicObjects, Convert, CoreClasses, CoreCompose, CoreFlatten, CoreProperties, IO, PW, PWCore, PWPins, Rope, Rosemary, Sinix; CrossRAMDataBuffer: CEDAR PROGRAM IMPORTS CDSymbolicObjects, Convert, CoreCompose, CoreFlatten, CoreProperties, IO, PW, PWCore, PWPins, Rope, Rosemary, Sinix = BEGIN OPEN CoreCompose; <> DataBuffer: ROPE = RegisterStructureProc[name: "DataBuffer", proc: CreateDataBuffer]; CreateDataBuffer: StructureProc = { columnOcts: INT _ GetInt[context, $columnOcts]; cellType _ CreateSequenceCell[ name: DataBuffer, baseCell: CreateStructure[name: "DataBufferBit", context: context], count: columnOcts, sequencePorts: "Bit, nBit, DataB"]; IF GetBool[context, $PWCore] THEN PWCore.SetArrayX[cellType: cellType]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; DataBufferBit: ROPE = RegisterStructureProc[name: "DataBufferBit", proc: CreateDataBufferBit]; CreateDataBufferBit: StructureProc = { cellType _ CreateRecordCell[ name: DataBufferBit, context: context, public: CreateWires[context, "Vdd, Gnd, WriteB, nWriteB, ReadB, nReadB, DataB, Select[SEQ:select], Bit[SEQ:select], nBit[SEQ:select]"], instances: LIST [ [type: CreateStructure[name: "DataBufferOct", context: context], actual: "GndLow: Gnd"], [type: CreateStructure[name: "DecoderStitch", context: context]] ]]; IF GetBool[context, $PWCore] THEN PWCore.SetAbutX[cellType: cellType]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; IF GetBool[context, $Rosemary] THEN Rosemary.Bind[cellType: cellType, roseClassName: DataBufferBitRoseClass]; CoreProperties.PutCellTypeProp[on: cellType, prop: CoreFlatten.CoreFlattenCutSets, value: LIST["JustAboveTransistors"]]; }; DataBufferBitRoseClass: ROPE = Rosemary.Register[roseClassName: DataBufferBit, init: DataBufferBitInit, evalSimple: DataBufferBitSimple]; Vdd: NAT = 0; Gnd: NAT = 1; WriteB: NAT = 2; nWriteB: NAT = 3; ReadB: NAT = 4; nReadB: NAT = 5; DataB: NAT = 6; Select: NAT = 7; Bit: NAT = 8; nBit: NAT = 9; DataBufferBitInit: Rosemary.InitProc = { p[Vdd].type _ b; p[Gnd].type _ b; p[WriteB].type _ b; p[nWriteB].type _ b; p[ReadB].type _ b; p[nReadB].type _ b; p[DataB].type _ b; FOR port: NAT IN [0..p[Select].size) DO p[Select][port].type _ b; ENDLOOP; FOR port: NAT IN [0..p[Bit].size) DO p[Bit][port].type _ b; ENDLOOP; FOR port: NAT IN [0..p[nBit].size) DO p[nBit][port].type _ b; ENDLOOP; }; DataBufferBitSimple: Rosemary.EvalProc = { someSelect: BOOL _ FALSE; whichSelect: NAT; write: BOOL _ p[WriteB].b OR NOT p[nWriteB].b; read: BOOL _ p[ReadB].b OR NOT p[nReadB].b; FOR port: NAT IN [0..p[Select].size) DO p[Bit][port].d _ none; p[nBit][port].d _ none; IF p[Select][port].b THEN { IF (read OR write) AND someSelect THEN SIGNAL Rosemary.Stop[]; someSelect _ TRUE; whichSelect _ port; }; ENDLOOP; IF NOT p[Vdd].b OR p[Gnd].b OR (write AND read) THEN SIGNAL Rosemary.Stop[]; IF write AND someSelect THEN { p[Bit][whichSelect].d _ IF (p[DataB].b AND NOT p[nWriteB].b) OR (NOT p[DataB].b AND p[WriteB].b) THEN drive ELSE none; p[nBit][whichSelect].d _ IF (p[DataB].b AND p[WriteB].b) OR (NOT p[DataB].b AND NOT p[nWriteB].b) THEN drive ELSE none; p[Bit][whichSelect].b _ p[DataB].b; p[nBit][whichSelect].b _ NOT p[DataB].b; }; p[DataB].d _ none; IF read THEN { IF someSelect THEN { p[DataB].d _ IF (p[nBit][whichSelect].b AND p[ReadB].b) OR (NOT p[nBit][whichSelect].b AND NOT p[nReadB].b) THEN drive ELSE none; p[DataB].b _ NOT p[nBit][whichSelect].b; } ELSE { p[DataB].b _ FALSE; p[DataB].d _ drive; }; }; }; DataBufferOct: ROPE = RegisterStructureProc[name: "DataBufferOct", proc: CreateDataBufferOct]; CreateDataBufferOct: StructureProc = { onlyInternal: Wire _ CreateWires[context, "Buffer, nBuffer"]; cellType _ CreateRecordCell[ name: DataBufferOct, context: context, public: CreateWires[context, "Vdd, Gnd, GndLow, WriteB, nWriteB, ReadB, nReadB, DataB, Select[SEQ: select], Bit[SEQ: select], nBit[SEQ: select]"], onlyInternal: onlyInternal, instances: LIST [ [type: CreateStructure[name: "BitLineConnectSeq", context: context], actual: "Gnd: GndLow"], [type: CreateStructure[name: "DataBufferMux", context: context]], [type: CreateStructure[name: "DataBufferMuxBit", context: context]], [type: CreateStructure[name: "BitDrive", context: context]] ]]; <> IF GetBool[context, $PWCore] THEN PWCore.SetLayout[cellType, PWCore.HidePins[onlyInternal, PW.AbutListY[NIL, PWCore.GateWays[cellType]]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; <> BitLineConnectSeq: ROPE = RegisterStructureProc[name: "BitLineConnectSeq", proc: CreateBitLineConnectSeq]; CreateBitLineConnectSeq: StructureProc = { select: INT _ GetInt[context, $select]; cellType _ CreateSequenceCell[ name: BitLineConnectSeq, baseCell: CreateStructure[name: "BitLineConnect", context: context], count: select, sequencePorts: "Bit, nBit"]; IF GetBool[context, $PWCore] THEN PWCore.SetArrayX[cellType: cellType]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; BitLineConnect: ROPE = RegisterStructureProc[name: "BitLineConnect", proc: CreateBitLineConnect]; CreateBitLineConnect: StructureProc = { cellType _ CreateRecordCell[ name: BitLineConnect, context: context, public: CreateWires[context, "Gnd, Bit, nBit"]]; IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; DataBufferMux : ROPE = RegisterStructureProc[name: "DataBufferMux", proc: CreateDataBufferMux]; CreateDataBufferMux: StructureProc = { select: INT _ GetInt[context, $select]; DataBufferMuxLayout: PROC[] RETURNS [obj: PW.Object] = { Rename: PWPins.ChangePinProc = { oldRope: ROPE _ CDSymbolicObjects.GetName[oldPin]; newPin _ PWPins.CopyInstance[oldPin]; IF Rope.Match["VSelect[*]", oldRope] AND PWPins.GetSide[obj, oldPin]=top THEN CDSymbolicObjects.SetName[newPin, IO.PutFR["Select[%g]", IO.int[Convert.IntFromRope[Rope.Substr[oldRope, 8, Rope.Length[oldRope]-9]]]]]; IF Rope.Match["Select[*]", oldRope] AND PWPins.GetSide[obj, oldPin]=top THEN CDSymbolicObjects.SetName[newPin, IO.PutFR["Select[%g]", IO.int[select-1]]]; }; DataBufferMuxSelect: PW.XYFunction ={ resultingOb _ SELECT TRUE FROM y BitSelNoPoly, y=x => BitSelContact, y>x => BitSelPoly, ENDCASE => ERROR; }; design: CD.Design _ NARROW[GetRef[context, $sourceCDDesign]]; BitSelNoPoly: PW.Object _ PW.Get[design, "BitSelNoPoly"]; BitSelContact: PW.Object _ PW.Get[design, "BitSelContact"]; BitSelPoly: PW.Object _ PW.Get[design, "BitSelPoly"]; obj _ PW.MapFunctionIndexPins[NIL, DataBufferMuxSelect, 0, select, 0, select, [bottom: LIST["Bit", "nBit"], top: LIST["VSelect", "Select", "Bit", "nBit"], left: LIST["Select"], right: LIST["Select"]]]; obj _ PWPins.ChangePins[NIL, obj, Rename]; }; cellType _ CreateRecordCell[ name: DataBufferMux, context: context, public: CreateWires[context, "Select[seq: select], Bit[seq: select], nBit[seq: select]"] ]; IF GetBool[context, $PWCore] THEN PWCore.SetLayout[cellType, PWCore.LabelPins[cellType.public, DataBufferMuxLayout[]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; DataBufferMuxBit: ROPE = RegisterStructureProc[name: "DataBufferMuxBit", proc: CreateDataBufferMuxBit]; CreateDataBufferMuxBit: StructureProc = { select: INT _ GetInt[context, $select]; cellType _ CreateRecordCell[ name: DataBufferMuxBit, context: context, public: CreateWires[context, "Buffer, nBuffer, Select[seq: select], Bit[seq: select], nBit[seq: select]"], instances: LIST [ [type: CreateStructure[name: BitMuxEnd, context: context], actual: "Select: Select[0], Bit: Bit[0], nBit: nBit[0]"], [type: CreateStructure[name: BitMuxSeq, context: context], actual: "Select: Select[start: 1, len: select-1], Bit: Bit[start: 1, len: select-1], nBit: nBit[start: 1, len: select-1]"]]]; IF GetBool[context, $PWCore] THEN PWCore.SetAbutX[cellType: cellType]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; <> BitMuxEnd: ROPE = RegisterStructureProc[name: "BitMuxEnd", proc: CreateBitMuxEnd]; CreateBitMuxEnd: StructureProc = { cellType _ CreateRecordCell[ name: BitMuxEnd, context: context, public: CreateWires[context, "Select, Bit, nBit, Buffer, nBuffer"], instances: LIST [ [type: CreateTransistor[name: "Transistor", type: nE], actual: "gate: Select, ch1: Bit, ch2: Buffer"], [type: CreateTransistor[name: "Transistor", type: nE], actual: "gate: Select, ch1: nBit, ch2: nBuffer"]] ]; IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; BitMuxSeq: ROPE = RegisterStructureProc[name: "BitMuxSeq", proc: CreateBitMuxSeq]; CreateBitMuxSeq: StructureProc = { select: INT _ GetInt[context, $select]; cellType _ CreateSequenceCell[ name: BitMuxSeq, baseCell: CreateStructure[name: BitMux, context: context], count: select-1, sequencePorts: "Select, Bit, nBit"]; IF GetBool[context, $PWCore] THEN PWCore.SetArrayX[cellType: cellType]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; <> BitMux: ROPE = RegisterStructureProc[name: "BitMux", proc: CreateBitMuxBit]; CreateBitMuxBit: StructureProc = { cellType _ CreateRecordCell[ name: BitMux, context: context, public: CreateWires[context, "Select, Bit, nBit, Buffer, nBuffer"], instances: LIST [ [type: CreateTransistor[name: "Transistor", type: nE], actual: "gate: Select, ch1: Bit, ch2: Buffer"], [type: CreateTransistor[name: "Transistor", type: nE], actual: "gate: Select, ch1: nBit, ch2: nBuffer"]] ]; IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; BitDrive: ROPE = RegisterStructureProc[name: "BitDrive", proc: CreateBitDrive]; CreateBitDrive: StructureProc = { PushInt[context: context, prop: $SSIWidth, val: 4]; PushReal[context: context, prop: $SSIRatio, val: 2.5]; cellType _ CreateRecordCell[ name: BitDrive, context: context, public: CreateWires[context, "Vdd, Gnd, WriteB, nWriteB, ReadB, nReadB, DataB, Buffer, nBuffer"], onlyInternal: CreateWires[context, "ndatab"], instances: LIST [ [type: CreateStructure[name: "Inverter", context: context], actual: "Input: DataB, Output: ndatab"], [type: CreateStructure[name: "TristateBuffer", context: context], actual: "nInput: nBuffer, Drive: ReadB, nDrive: nReadB, Output: DataB"], [type: CreateStructure[name: "TristateBuffer", context: context], actual: "nInput: DataB, Drive: WriteB, nDrive: nWriteB, Output: nBuffer"], [type: CreateStructure[name: "TristateBuffer", context: context], actual: "nInput: ndatab, Drive: WriteB, nDrive: nWriteB, Output: Buffer"]]]; IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; DecoderStitch: ROPE = RegisterStructureProc[name: "DecoderStitch", proc: CreateDecoderStitch]; CreateDecoderStitch: StructureProc = { select: INT _ GetInt[context, $select]; cellType _ CreateRecordCell[ name: DecoderStitch, context: context, public: CreateWires[context, "Vdd, Gnd, WriteB, nWriteB, ReadB, nReadB, Select[seq: select]"]]; IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]]; IF GetBool[context, $Sinix] THEN [] _ Sinix.Extract[PWCore.GetLayout[cellType]]; }; END.