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. ΒCrossRAMDataBuffer.mesa Copyright c 1985 by Xerox Corporation. All rights reservedSinix.Extract Barth, November 7, 1985 4:41:32 pm PST Louis Monier October 28, 1985 8:34:19 am PST Bertrand Serlet December 6, 1985 5:04:44 pm PST Ports: Vdd, Gnd, WriteB, nWriteB, ReadB, nReadB, DataB[SEQ: columnOcts], Select[SEQ: select], Bit[SEQ: columnOcts*select], nBit[SEQ: columnOcts*select] BS: We need the following to avoid nBuffer and Buffer pins that inadvertantly cross the boundary of the cell to mismatch in PWCore, since they are not part of the public Ports: Gnd, Bit[SEQ: select], nBit[SEQ: select] Following is copy if BitMuxBit, need to fix this Ports: Gnd, Select, Bit, nBit, Buffer, nBuffer Κ – "cedar" style˜codešœ™Kšœ Οmœ=™HK™&K™,K™/K™—KšΟk œžœUžœžœ(˜K˜•StartOfExpansion[]šΟbœžœž˜!KšžœGžœ*˜~Kšžœžœ ˜—K˜Jš œ7žœžœžœžœ™—šŸ œžœE˜Ušœ#˜#Kšœ žœ ˜/šœ˜Kšœ˜KšœC˜CKšœ˜Kšœ#˜#—Kšžœžœ&˜GKšžœžœ0˜PKšœ˜K˜——šŸ œžœK˜^šœ&˜&šœ˜Kšœ˜K˜šœ˜Kšœ2˜2Kšœžœžœžœ ˜8—šœ žœ˜KšœX˜XKšœ@˜@Kšœ˜——Kšžœžœ%˜FKšžœžœ0˜PKšžœžœJ˜mKšœZžœ˜xKšœ˜—Kšœžœm˜‰Kšœžœ˜ Kšœžœ˜ Kšœžœ˜Kšœ žœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜ Kšœžœ˜šœ(˜(Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜šžœžœžœž˜'Kšœ˜Kšžœ˜—šžœžœžœž˜$Kšœ˜Kšžœ˜—šžœžœžœž˜%Kšœ˜Kšžœ˜—Kšœ˜—šœ*˜*Kšœ žœžœ˜Kšœ žœ˜Kšœžœžœžœ˜.Kšœžœžœžœ ˜+šžœžœžœž˜'Kšœ˜Kšœ˜šžœžœ˜Kš žœžœžœ žœžœ˜>Kšœ žœ˜Kšœ˜Kšœ˜—Kšžœ˜—Kšžœžœ žœ žœžœžœžœ˜Lšžœžœ žœ˜Kšœžœ žœžœžœžœ žœžœžœ˜vKšœžœ žœžœžœ žœžœžœžœ˜wKšœ#˜#Kšœžœ ˜(K˜—Kšœ˜šžœžœ˜šžœ žœ˜Kšœ žœžœ žœžœžœžœžœžœ˜Kšœ žœ˜(K˜—šžœ˜Kšœ žœ˜Kšœ˜K˜—K˜—Kšœ˜K˜K˜——šŸ œžœK˜^šœ&˜&Kšœ=˜=šœ˜Kšœ˜K˜šœ˜Kšœ:˜:Kšœžœžœžœ ˜;—Kšœ˜šœ žœ˜Kšœ\˜\KšœA˜AKšœD˜DKšœ;˜;Kšœ˜——Kšœͺ™ͺKšžœžœ:žœ žœ˜ŠKšžœžœ0˜PKšœ˜K˜——Jšœžœžœ ™0šœžœS˜jšœ*˜*Kšœžœ˜'šœ˜Kšœ˜KšœD˜DKšœ˜Kšœ˜—Kšžœžœ&˜GKšžœžœ0˜PKšœ˜K˜——šœžœM˜ašœ'˜'šœ˜Kšœ˜K˜Kšœ0˜0—Kšžœžœ+žœ$˜vKšžœžœ0˜PKšœ˜K˜——šŸœžœK˜_šœ&˜&Kšœžœ˜'šΟnœžœžœžœ ˜8šŸœ˜ Kšœ žœ%˜2Jšœ%˜%šžœ#žœ ˜HJšžœ#žœžœM˜—šžœ"žœ ˜GJšžœ#žœžœ˜Q—K˜—šŸœžœ˜%šœžœžœž˜Kšœ˜Kšœ˜Kšœ˜Kšžœžœ˜—Kšœ˜—Kšœžœ žœ#˜=Kšœžœ žœ˜9Kšœžœ žœ˜;Kšœ žœ žœ˜5Kš œžœžœ6žœžœ-žœžœ ˜ΚKšœžœ˜*Kšœ˜—šœ˜Kšœ˜K˜KšœX˜XKšœ˜—KšžœžœV˜wKšžœžœ0˜PKšœ˜K˜——šŸœžœQ˜gšœ)˜)Kšœžœ˜'šœ˜Kšœ˜K˜Kšœj˜jšœ žœ˜šœ:˜:Kšœ9˜9—šœ:˜:Kšœ}˜}———Kšžœžœ%˜FKšžœžœ0˜PKšœ˜——K˜K™0šŸ œžœC˜Ršœ"˜"šœ˜Kšœ˜K˜KšœC˜Cšœ žœ˜šœ6˜6Kšœ/˜/—šœ6˜6Kšœ1˜1—Kšœ˜——Kšžœžœ+žœ$˜vKšžœžœ0˜PKšœ˜K˜——šŸ œžœC˜Ršœ"˜"Kšœžœ˜'šœ˜Kšœ˜Kšœ:˜:Kšœ˜Kšœ$˜$—Kšžœžœ&˜GKšžœžœ0˜PKšœ˜K˜——Jšœ/™/šŸœžœ@˜Lšœ"˜"šœ˜Kšœ ˜ K˜KšœC˜Cšœ žœ˜šœ6˜6Kšœ/˜/—šœ6˜6Kšœ1˜1—Kšœ˜——Kšžœžœ+žœ$˜vKšžœžœ0˜PKšœ˜K˜——šœ žœA˜Ošœ!˜!Kšœ3˜3Kšœ6˜6šœ˜Kšœ˜K˜Kšœa˜aKšœ-˜-šœ žœ˜šœ;˜;Kšœ)˜)—šœA˜AKšœI˜I—šœA˜AKšœK˜K—šœA˜AKšœL˜L———Kšžœžœ+žœ$˜vKšžœžœ0˜PKšœ˜K˜——šœžœK˜^šœ&˜&Kšœžœ˜'šœ˜Kšœ˜K˜Kšœ_˜_—Kšžœžœ+žœ$˜vKšžœžœ0˜PKšœ˜K˜——Kšžœ˜K˜—…—-`;+