DIRECTORY CD, CDCells, CDPinObjects, CMos, Convert, EuControl, EuGen, EUtils, PW, PWCmos, PWDescr, PWPins, Rope; EuGenImplA: CEDAR PROGRAM IMPORTS CDCells, CMos, Convert, EuControl, EuGen, EUtils, PW, PWCmos, PWDescr, PWPins, Rope EXPORTS EuGen = BEGIN OPEN EuGen; ramcdpd: PWDescr.Descriptor; ramcdpu: PWDescr.Descriptor; regscdpd: PWDescr.Descriptor; regscdpu: PWDescr.Descriptor; RAMGen: PUBLIC PROC [design: CD.Design] RETURNS [ram: PW.ObPtr] = BEGIN RamDecFn: PW.XYFunction = {dec: PW.ObPtr _ RamRow3Dec[y]; RETURN[IF PW.EVEN[y] THEN PW.AbutX[design, dec, ramRow] ELSE PW.AbutX[design, PW.FlipY[design, dec], ramRowFlipped]]}; RamRow3Dec: PROC [n: INT] RETURNS [row3Dec: PW.ObPtr] = BEGIN aDec, bDec, cDec: PW.ObPtr; PW.Output["Row number ", Convert.RopeFromInt[n], "\n"]; PWDescr.SetInt[ramcdpd, "aAdrHi", n]; aDec _ EuControl.Nand[design, ramcdpd, ramcdpu]; PWDescr.SetInt[ramcdpd, "aAdrHi", 0, 0]; PWDescr.SetInt[ramcdpd, "bAdrHi", n]; bDec _ EuControl.Nand[design, ramcdpd, ramcdpu]; PWDescr.SetInt[ramcdpd, "bAdrHi", 0, 0]; PWDescr.SetInt[ramcdpd, "cAdrHi", n]; cDec _ EuControl.Nand[design, ramcdpd, ramcdpu, TRUE]; PWDescr.SetInt[ramcdpd, "cAdrHi", 0, 0]; row3Dec _ PW.AbutX[design, PW.AbutY[design, bDec, cDec, aDec, fillerDec], -- same order as select lines routingDecToRam]; END; PrechargeGen: PROC RETURNS [ramPrecharge: PW.ObPtr] = BEGIN PrechargeCtrlGen: PROC RETURNS [prechCtrl: PW.ObPtr] = BEGIN VddProc: PW.SelectNamesProc = {keepIt _ Rope.Equal[name, "vdd"]}; RenameNPhA: PWPins.RenameProc = {SELECT TRUE FROM Rope.Equal[oldRope, "wireLeft"] => newRope _ "nPhA"; Rope.Equal[oldRope, "wireRight"] => newRope _ NIL; ENDCASE => newRope _ oldRope}; RenameNPhB: PWPins.RenameProc = {SELECT TRUE FROM Rope.Equal[oldRope, "wireLeft"] => newRope _ "nPhB"; Rope.Equal[oldRope, "wireRight"] => newRope _ "nPhB"; ENDCASE => newRope _ oldRope}; RenamePhA: PWPins.RenameProc = {SELECT TRUE FROM Rope.Equal[oldRope, "wireLeft"] => newRope _ "PhA"; Rope.Equal[oldRope, "wireRight"] => newRope _ NIL; ENDCASE => newRope _ oldRope}; RenamePhB: PWPins.RenameProc = {SELECT TRUE FROM Rope.Equal[oldRope, "wireLeft"] => newRope _ "PhB"; Rope.Equal[oldRope, "wireRight"] => newRope _ NIL; ENDCASE => newRope _ oldRope}; wire, vddConnect, ctrl, vddRect:PW.ObPtr; listOb: PW.ListOb _ NIL; size: CD.Position; ramcdpu _ EmptyDescrRamPU[]; ramcdpd _ EmptyDescrRamPD[]; PWDescr.SetBit[ramcdpd, "PhA", TRUE]; wire _ EuControl.RouteTo[design, ramcdpd, ramcdpu]; PWDescr.SetBit[ramcdpd, "PhA", FALSE]; listOb _ CONS[PWPins.RenamePins[design, wire, RenamePhA], listOb]; PWDescr.SetBit[ramcdpu, "nPhA", TRUE]; wire _ EuControl.RouteTo[design, ramcdpd, ramcdpu]; PWDescr.SetBit[ramcdpu, "nPhA", FALSE]; listOb _ CONS[PWPins.RenamePins[design, wire, RenameNPhA], listOb]; PWDescr.SetBit[ramcdpd, "PhB", TRUE]; wire _ EuControl.RouteTo[design, ramcdpd, ramcdpu]; PWDescr.SetBit[ramcdpd, "PhB", FALSE]; listOb _ CONS[PWPins.RenamePins[design, wire, RenamePhB], listOb]; PWDescr.SetBit[ramcdpu, "nPhB", TRUE]; wire _ EuControl.RouteTo[design, ramcdpd, ramcdpu]; PWDescr.SetBit[ramcdpu, "nPhB", FALSE]; listOb _ CONS[PWPins.RenamePins[design, wire, RenameNPhB], listOb]; PWDescr.SetBit[ramcdpu, "Vbias", TRUE]; listOb _ CONS[EuControl.BiasVoltage[design, ramcdpd, ramcdpu], listOb]; PWDescr.SetBit[ramcdpu, "Vbias", FALSE]; ctrl _ PW.AbutListY[design, listOb]; vddConnect _ EUtils.CtrlFiller[design, ctrl, contactPrechargeBitLines, VddProc]; size _ PW.Size[vddConnect]; vddRect _ PWCmos.Rect[CMos.met2, [size.x, size.y-12*l]]; PW.IncludeInCell[design, vddConnect, vddRect, [0, 12*l]]; -- hack!!! [] _ CDCells.RepositionCell[vddConnect, design]; prechCtrl _ PW.AbutY[design, ctrl, vddConnect]; END; listOb: PW.ListOb _ NIL; block, prechargeBitLines, contactPrechargeBitLines, ctrl: PW.ObPtr; PW.Output["The precharge of the RAM", "\n"]; prechargeBitLines _ PW.Get[design, "prechargeBitLines"]; contactPrechargeBitLines _ PW.Get[design, "contactPrechargeBitLines"]; block _ PW.AbutX[design, contactPrechargeBitLines, PW.ArrayX[design, prechargeBitLines, nbBitsperSliceInRam]]; block _ PWPins.RenamePins[design, block]; listOb _ NIL; -- re-used FOR i: INT IN [0..nbSlices) DO RenameK: PWPins.RenameProc = {IF Rope.Equal[oldRope, "kBus"] THEN newRope _ PWPins.Index[oldRope, nbSlices-1-i]; IF Rope.Equal[oldRope, "vdd"] OR Rope.Equal[oldRope, "gnd"] THEN newRope _ oldRope}; listOb _ CONS[PWPins.RenamePins[design, block, RenameK], listOb]; ENDLOOP; ctrl _ PrechargeCtrlGen[]; ramPrecharge _ PW.AbutX[design, ctrl, EUtils.QadCR[design, ctrl, contactPrechargeBitLines, glueWidth, FALSE], PW.AbutListX[design, listOb]]; END; decConnectionPrecharge, genericDec, genericCtrl, fillerDec, routingDecToRam, contactSelectLinesAndKBus, ramRow, ramRowFlipped, ramArrayandDec: PW.ObPtr; PW.Output["Generating the RAM", "\n"]; decConnectionPrecharge _ PW.CreateEmptyCell[]; ramcdpu _ InitDescrRamPU[]; ramcdpd _ InitDescrRamPD[]; contactSelectLinesAndKBus _ PW.Get[design, "contactSelectLinesAndKBus"]; genericDec _ EuControl.Nand[design, ramcdpd, ramcdpu]; genericCtrl _ PW.AbutY[design, genericDec, PW.FlipY[design, genericDec], genericDec]; fillerDec _ EUtils.CtrlFiller[design, genericCtrl, contactSelectLinesAndKBus]; genericCtrl _ PW.AbutY[design, genericCtrl, fillerDec]; routingDecToRam _ EUtils.QadCR[design, genericCtrl, contactSelectLinesAndKBus, glueWidth]; ramRow _ PW.ArrayX[design, PW.AbutX[design, contactSelectLinesAndKBus, PW.ArrayX[design, PW.Get[design, "threePortedRamCell"], nbBitsperSliceInRam]], nbSlices]; ramRow _ PWPins.RenamePins[design, ramRow]; ramRowFlipped _ PW.FlipY[design, ramRow]; ramArrayandDec _ PW.MapFunctionY[design, RamDecFn, 0, nbRowsInRam]; ram _ PW.AbutY[design, ramArrayandDec, PrechargeGen[]]; ram _ PWPins.RenamePins[design, ram]; PW.RenameObject[design, ram, "ram"]; END; BitLinesMuxesGen: PUBLIC PROC [design: CD.Design] RETURNS [mux: PW.ObPtr] = BEGIN MuxCtrlGen: PROC [] RETURNS [muxCtrl: PW.ObPtr] = BEGIN a0, a1, a2, a3, b0, b1, b2, b3, c0, c1, c2, c3: PW.ObPtr; ramcd1: PWDescr.Descriptor; ramcd1 _ InitDescrRamPD[]; ramcdpd _ InitDescrRamPD[]; ramcdpu _ InitDescrRamPU[]; PWDescr.SetBit[ramcdpd, "nhold2BA", TRUE]; PWDescr.SetBit[ramcdpd, "nrejectBA", TRUE]; PWDescr.SetInt[ramcdpd, "aAdrLow", 0]; a0 _ EuControl.Nand[design, ramcdpd, ramcdpu]; PWDescr.SetInt[ramcdpd, "aAdrLow", 1]; a1 _ EuControl.Nand[design, ramcdpd, ramcdpu, TRUE]; PWDescr.SetInt[ramcdpd, "aAdrLow", 2]; a2 _ EuControl.Nand[design, ramcdpd, ramcdpu]; PWDescr.SetInt[ramcdpd, "aAdrLow", 3]; a3 _ EuControl.Nand[design, ramcdpd, ramcdpu, TRUE]; PWDescr.SetInt[ramcdpd, "aAdrLow", 0, 0]; PWDescr.SetInt[ramcdpd, "bAdrLow", 0]; b0 _ EuControl.Nand[design, ramcdpd, ramcdpu]; PWDescr.SetInt[ramcdpd, "bAdrLow", 1]; b1 _ EuControl.Nand[design, ramcdpd, ramcdpu, TRUE]; PWDescr.SetInt[ramcdpd, "bAdrLow", 2]; b2 _ EuControl.Nand[design, ramcdpd, ramcdpu]; PWDescr.SetInt[ramcdpd, "bAdrLow", 3]; b3 _ EuControl.Nand[design, ramcdpd, ramcdpu, TRUE]; PWDescr.SetInt[ramcdpd, "bAdrLow", 0, 0]; PWDescr.SetInt[ramcdpd, "cAdrLow", 0]; c0 _ EuControl.Nand[design, ramcdpd, ramcdpu]; PWDescr.SetInt[ramcdpd, "cAdrLow", 1]; c1 _ EuControl.Nand[design, ramcdpd, ramcdpu, TRUE]; PWDescr.SetInt[ramcdpd, "cAdrLow", 2]; c2 _ EuControl.Nand[design, ramcdpd, ramcdpu]; PWDescr.SetInt[ramcdpd, "cAdrLow", 3]; c3 _ EuControl.Nand[design, ramcdpd, ramcdpu, TRUE]; PWDescr.SetInt[ramcdpd, "cAdrLow", 0, 0]; muxCtrl _ PW.AbutListY[design, LIST[a0, a1, a2, a3, b0, b1, b2, b3, c0, c1, c2, c3]]; END; MuxDataGen: PROC [] RETURNS [muxDataPathSlice: PW.ObPtr] = BEGIN ABLFn: PW.XYFunction = {RETURN[IF x=y THEN aBLMuxTrans ELSE bitLineMuxNoTrans]}; BBLFn: PW.XYFunction = {RETURN[IF x=y THEN bBLMuxTrans ELSE bitLineMuxNoTrans]}; CBLFn: PW.XYFunction = {RETURN[IF x=y THEN cBLMuxTrans ELSE bitLineMuxNoTrans]}; muxA, muxB, muxC, fourToOne, contacts: PW.ObPtr; bitLineMuxNoTrans: PW.ObPtr _ PW.Get[design, "bitLineMuxNoTrans"]; aBLMuxTrans: PW.ObPtr _ PW.Get[design, "aBLMuxTrans"]; bBLMuxTrans: PW.ObPtr _ PW.Get[design, "bBLMuxTrans"]; cBLMuxTrans: PW.ObPtr _ PW.Get[design, "cBLMuxTrans"]; PW.Output["Bit lines multiplexers", "\n"]; muxA _ PW.MapFunction[design, ABLFn, 0, nbBitsperSliceInRam, 0, nbBitsperSliceInRam]; muxB _ PW.MapFunction[design, BBLFn, 0, nbBitsperSliceInRam, 0, nbBitsperSliceInRam]; muxC _ PW.MapFunction[design, CBLFn, 0, nbBitsperSliceInRam, 0, nbBitsperSliceInRam]; contacts _ PW.AbutY[design, PW.Get[design, "contactFourToOne"], PW.ArrayY[design, PW.Get[design, "contactBLMux"], 3*nbBitsperSliceInRam]]; fourToOne _ PW.AbutY[design, PW.ArrayX[design, PW.Get[design, "fourToOneBLMuxes"], nbBitsperSliceInRam], muxC, muxB, muxA]; muxDataPathSlice _ PW.AbutX[design, contacts, fourToOne]; END; fillerSlice, muxDataPathSlice, ctrl, dp: PW.ObPtr; ramcdpd _ InitDescrRamPD[]; ctrl _ MuxCtrlGen[]; muxDataPathSlice _ MuxDataGen[]; fillerSlice _ EUtils.CtrlFiller[design, muxDataPathSlice, ctrl]; dp _ PW.ArrayX[design, PW.AbutY[design, muxDataPathSlice, fillerSlice], nbSlices]; mux _ PW.AbutX[design, ctrl, EUtils.QadCR[design, ctrl, dp, glueWidth], dp]; PW.RenameObject[design, mux, "mux"]; END; BitLinesReadWriteGen: PUBLIC PROC [design: CD.Design] RETURNS [readWrite: PW.ObPtr] = BEGIN ReadWriteCtrlGen: PROC [] RETURNS [readWriteCtrl: PW.ObPtr] = BEGIN nPhBWire, phAWire, inverters: PW.ObPtr; ramcdpd _ EmptyDescrRamPD[]; ramcdpu _ EmptyDescrRamPU[]; PWDescr.SetBit[ramcdpu, "nPhB", TRUE]; nPhBWire _ EuControl.RouteTo[design, ramcdpd, ramcdpu]; PWDescr.SetBit[ramcdpu, "nPhB", FALSE]; PWDescr.SetBit[ramcdpd, "PhA", TRUE]; phAWire _ EuControl.RouteTo[design, ramcdpd, ramcdpu]; PWDescr.SetBit[ramcdpd, "PhA", FALSE]; ramcdpd _ EmptyDescrRamPD[]; ramcdpu _ EmptyDescrRamPU[]; PWDescr.SetInt[ramcdpd, "aAdrHi", PWDescr.allOnes]; PWDescr.SetInt[ramcdpd, "aAdrLow", PWDescr.allOnes]; PWDescr.SetInt[ramcdpd, "bAdrHi", PWDescr.allOnes]; PWDescr.SetInt[ramcdpd, "bAdrLow", PWDescr.allOnes]; PWDescr.SetInt[ramcdpd, "cAdrHi", PWDescr.allOnes]; PWDescr.SetInt[ramcdpd, "cAdrLow", PWDescr.allOnes]; inverters _ EuControl.Inverters[design, ramcdpd, ramcdpu, TRUE]; readWriteCtrl _ PW.AbutY[design, phAWire, nPhBWire, inverters]; END; ReadWriteDataGen: PROC [] RETURNS [readWriteDataPath: PW.ObPtr] = BEGIN bitLinesRead, bitLinesWrite, readWrite: PW.ObPtr; bitLinesRead _ PW.Get[design, "bitLinesRead"]; bitLinesWrite _ PW.Get[design, "bitLinesWrite"]; readWrite _ PW.AbutY[design, bitLinesWrite, bitLinesRead]; readWriteDataPath _ PW.ArrayX[design, readWrite, nbSlices]; END; PW.Output["Read and write ports of the RAM", "\n"]; readWrite _ EUtils.Assemble[design, ReadWriteCtrlGen[], ReadWriteDataGen[]]; PW.RenameObject[design, readWrite, "readWrite"]; END; DrivekBusGen: PUBLIC PROC [design: CD.Design] RETURNS [cell: PW.ObPtr] = BEGIN cAdrGreaterThan239: PW.ObPtr; PW.Output["kBus driver", "\n"]; ramcdpd _ InitDescrRamPD[]; ramcdpu _ InitDescrRamPU[]; PWDescr.SetInt[ramcdpd, "cAdrHi", 60, 60]; -- cAdr>239, i.e. cAdr=1111xxxx PWDescr.SetBit[ramcdpd, "nhold2BA", TRUE]; cAdrGreaterThan239 _ EuControl.Nand[design, ramcdpd, ramcdpu]; cell _ EUtils.MakeTstDriver[design: design, in: "c", out: "kOut", ctrlListOb: LIST[cAdrGreaterThan239]]; PW.RenameObject[design, cell, "kBusDriver"]; END; AdrRegGen: PUBLIC PROC [design: CD.Design] RETURNS [regs: PW.ObPtr] = BEGIN ctrl: PW.ObPtr; regD: EUtils.RegDescr; PW.Output["Address registers", "\n"]; ramcdpd _ EmptyDescrRamPD[]; ramcdpu _ EmptyDescrRamPU[]; PWDescr.SetBit[ramcdpd, "PhB", TRUE]; ctrl _ EuControl.RouteTo[design, ramcdpd, ramcdpu]; regD _ NEW[EUtils.RegDescrRec _ [ inListOb: LIST["k"], out: "down", ctrlListOb: LIST[ctrl]]]; regs _ PW.AbutY[design, RoutingAdrRegGen[design], EUtils.MakeReg[design, regD]]; PW.RenameObject[design, regs, "addressRegisters"]; END; RoutingAdrRegGen: PROC [design: CD.Design] RETURNS [routing: PW.ObPtr] = BEGIN RoutingCtrlGen: PROC RETURNS [ctAdr: PW.ObPtr] = BEGIN listOb: PW.ListOb _ NIL; IntToWires: PROC [name: ROPE, nbBits: INT] = BEGIN ramcdpd _ EmptyDescrRamPD[]; PWDescr.SetInt[ramcdpd, name, PWDescr.allOnes]; FOR i: INT DECREASING IN [0..nbBits) DO PWDescr.SetInt[ramcdpd, name, PW.TwoToThe[i], PW.TwoToThe[i]]; listOb _ CONS[EuControl.RouteTo[design, ramcdpd, ramcdpu], listOb]; ENDLOOP; PWDescr.SetInt[ramcdpd, name, 0, 0]; END; ramcdpd _ EmptyDescrRamPD[]; ramcdpu _ EmptyDescrRamPU[]; IntToWires["aAdrHi", 6]; IntToWires["aAdrLow", 2]; IntToWires["bAdrHi", 6]; IntToWires["bAdrLow", 2]; IntToWires["cAdrHi", 6]; IntToWires["cAdrLow", 2]; regscdpd _ EmptyDescrRegsPD[]; PWDescr.SetBit[regscdpd, "PhA", TRUE]; PWDescr.SetBit[regscdpd, "PhB", TRUE]; PWDescr.SetBit[regscdpd, "nhold2BA", TRUE]; PWDescr.SetBit[regscdpd, "nrejectBA", TRUE]; PWDescr.SetBit[regscdpd, "DExecute", TRUE]; PWDescr.SetInt[regscdpd, "DStateAddress", PWDescr.allOnes]; regscdpu _ InitDescrRamPU[]; PWDescr.SetBit[regscdpu, "nPhA", TRUE]; listOb _ CONS[EuControl.Gap[design, regscdpd, regscdpu], listOb]; regscdpd _ EmptyDescrRegsPD[]; regscdpu _ EmptyDescrRamPU[]; PWDescr.SetInt[regscdpd, "EUAluLeftSrc1BA", 2, 2]; listOb _ CONS[EuControl.RouteTo[design, regscdpd, regscdpu], listOb]; PWDescr.SetInt[regscdpd, "EUAluLeftSrc1BA", 1, 1]; listOb _ CONS[EuControl.RouteTo[design, regscdpd, regscdpu], listOb]; PWDescr.SetInt[regscdpd, "EUAluLeftSrc1BA", 0, 0]; PWDescr.SetInt[regscdpd, "EUAluRightSrc1BA", 2, 2]; listOb _ CONS[EuControl.RouteTo[design, regscdpd, regscdpu], listOb]; PWDescr.SetInt[regscdpd, "EUAluRightSrc1BA", 1, 1]; listOb _ CONS[EuControl.RouteTo[design, regscdpd, regscdpu], listOb]; PWDescr.SetInt[regscdpd, "EUAluRightSrc1BA", 0, 0]; PWDescr.SetInt[regscdpd, "EUStore2ASrc1BA", 2, 2]; listOb _ CONS[EuControl.RouteTo[design, regscdpd, regscdpu], listOb]; PWDescr.SetInt[regscdpd, "EUStore2ASrc1BA", 1, 1]; listOb _ CONS[EuControl.RouteTo[design, regscdpd, regscdpu], listOb]; PWDescr.SetInt[regscdpd, "EUStore2ASrc1BA", 0, 0]; PWDescr.SetBool[regscdpd, "EUSt3AisCBus2BA", TRUE]; listOb _ CONS[EuControl.RouteTo[design, regscdpd, regscdpu], listOb]; PWDescr.SetBool[regscdpd, "EUSt3AisCBus2BA", FALSE, FALSE]; PWDescr.SetBool[regscdpd, "EURes3AisCBus2BA", TRUE]; listOb _ CONS[EuControl.RouteTo[design, regscdpd, regscdpu], listOb]; PWDescr.SetBool[regscdpd, "EURes3AisCBus2BA", FALSE, FALSE]; ctAdr _ PW.AbutListY[design, listOb]; END; WiringFn24: PW.XYFunction = {RETURN[SELECT TRUE FROM x=23-y => wiresCt, x<23-y => wiresNothing, -- below ENDCASE => wiresNoCt]}; -- above WiringFn8: PW.XYFunction = {RETURN[SELECT TRUE FROM x=31-y => wiresCt, x<31-y => wiresNothing, -- below ENDCASE => wiresNoCt]}; -- above routingAdrRegToCtrlPass, routingAdrRegToCtrlNoPass, wires, gapWires, glue, ctrl: PW.ObPtr; wiresCt: PW.ObPtr _ PW.Get[design, "routingAdrRegToCtrl"]; wiresNoCt: PW.ObPtr _ PW.Inst[design, wiresCt, LIST["Contact"]]; wiresNothing: PW.ObPtr _ PW.Inst[design, wiresCt, LIST["Contact", "wire"]]; routingAdrRegToCtrlPass _ PW.Get[design, "routingAdrRegToCtrlPass"]; routingAdrRegToCtrlNoPass _ PW.Inst[design, routingAdrRegToCtrlPass, LIST["vertical"]]; PW.Output["A lot of routing for the addresses", "\n"]; gapWires _ PW.AbutX[design, PW.ArrayX[design, routingAdrRegToCtrlNoPass, 24], PW.ArrayX[design, routingAdrRegToCtrlPass, 8]]; wires _ PW.AbutY[design, PW.MapFunction[design, WiringFn8, 0, nbSlices, 0, 8], gapWires, PW.MapFunction[design, WiringFn24, 0, nbSlices, 0, 24]]; ctrl _ RoutingCtrlGen[]; glue _ EUtils.QadCR[design, ctrl, wires, glueWidth]; routing _ PW.AbutX[design, ctrl, glue, wires]; PW.RenameObject[design, routing, "addressRegisters"]; END; FDRegsGen: PUBLIC PROC [design: CD.Design] RETURNS [fdRegs: PW.ObPtr] = BEGIN Regs: PROC RETURNS [regs: PW.ObPtr] = BEGIN regD: EUtils.RegDescr; listOb: PW.ListOb _ NIL; genericCtrl, ctrl, kBusAB, field, fd, dp: PW.ObPtr; regscdpd _ EmptyDescrRegsPD[]; regscdpu _ EmptyDescrRegsPU[]; PWDescr.SetInt[regscdpd, "DStateAddress", PWDescr.allOnes]; PWDescr.SetInt[regscdpd, "EUAluLeftSrc1BA", PWDescr.allOnes]; PWDescr.SetInt[regscdpd, "EUAluRightSrc1BA", PWDescr.allOnes]; PWDescr.SetInt[regscdpd, "EUStore2ASrc1BA", PWDescr.allOnes]; PWDescr.SetBool[regscdpd, "EUSt3AisCBus2BA", TRUE]; PWDescr.SetBool[regscdpd, "EURes3AisCBus2BA", TRUE]; PWDescr.SetBool[regscdpd, "FDInsert", TRUE]; PWDescr.SetInt[regscdpd, "FDMask", PWDescr.allOnes]; PWDescr.SetInt[regscdpd, "FDShift", PWDescr.allOnes]; PWDescr.SetInt[regscdpd, "EUAluOp2AB", PWDescr.allOnes]; PWDescr.SetBool[regscdpd, "EUWriteToPBus3AB", TRUE]; PWDescr.SetBool[regscdpd, "EURes3BisPBus3AB", TRUE]; listOb _ CONS[EuControl.Inverters[design, regscdpd, regscdpu, TRUE], listOb]; regscdpd _ EmptyDescrRegsPD[]; regscdpu _ EmptyDescrRamPU[]; PWDescr.SetBit[regscdpu, "nPhB", TRUE]; PWDescr.SetBit[regscdpu, "Vbias", TRUE]; PWDescr.SetBit[regscdpd, "PhA", TRUE]; PWDescr.SetInt[regscdpd, "EUAluOp2AB", fop]; -- EUAluOp2AB=FOP listOb _ CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb]; PWDescr.SetInt[regscdpd, "EUAluOp2AB", fopk]; -- EUAluOp2AB=FOPK listOb _ CONS[EuControl.Nand[design, regscdpd, regscdpu, TRUE], listOb]; PWDescr.SetInt[regscdpd, "EUAluOp2AB", 0, 0]; -- clean-up PWDescr.SetBit[regscdpd, "nrejectBA", TRUE]; PWDescr.SetBit[regscdpd, "nhold2BA", TRUE]; listOb _ CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb]; PWDescr.SetBit[regscdpd, "EULoadField3BA", TRUE]; -- for field genericCtrl _ EuControl.Nand[design, regscdpd, regscdpu, TRUE]; listOb _ CONS[genericCtrl, listOb]; PWDescr.SetBit[regscdpd, "nrejectBA", FALSE]; PWDescr.SetBit[regscdpd, "nhold2BA", FALSE]; ctrl _ PW.AbutListY[design, listOb]; regD _ NEW[EUtils.RegDescrRec _ [inListOb: LIST["k"], out: "opL"]]; kBusAB _ EUtils.MakeRegDP[design, regD]; regD _ NEW[EUtils.RegDescrRec _ [inListOb: LIST["c"], out: "opR", interruptBuses: LIST["opLBus", "opRBus", "downBus"]]]; field _ EUtils.MakeRegDP[design, regD]; regD _ NEW[EUtils.RegDescrRec _ [inListOb: LIST["opL", "opR"], out: "down"]]; fd _ EUtils.MakeRegDP[design, regD]; dp _ PW.AbutY[design, field, kBusAB, fd]; regs _ EUtils.Assemble[design, ctrl, dp]; END; Routing: PROC RETURNS [routing: PW.ObPtr] = BEGIN WiringFn13: PW.XYFunction = {RETURN[SELECT TRUE FROM x<3 => wiresNothing, x=15-y => wiresCt, x>15-y => wiresNothing, ENDCASE => wiresNoCt]}; Ctrl: PROC RETURNS [ctrl: PW.ObPtr] = BEGIN IntToWires: PROC [name: ROPE, nbBits: INT] = BEGIN regscdpd _ EmptyDescrRegsPD[]; PWDescr.SetInt[regscdpd, name, PWDescr.allOnes]; FOR i: INT DECREASING IN [0..nbBits) DO PWDescr.SetInt[regscdpd, name, PW.TwoToThe[i], PW.TwoToThe[i]]; listOb _ CONS[EuControl.RouteTo[design, regscdpd, regscdpu], listOb]; ENDLOOP; PWDescr.SetInt[regscdpd, name, 0, 0]; END; listOb: PW.ListOb _ NIL; regscdpd _ EmptyDescrRegsPD[]; regscdpu _ EmptyDescrRegsPU[]; PWDescr.SetBool[regscdpd, "FDInsert", TRUE]; listOb _ CONS[EuControl.RouteTo[design, regscdpd, regscdpu], listOb]; IntToWires["FDMask", 6]; IntToWires["FDShift", 6]; ctrl _ PW.AbutListY[design, listOb]; END; wires: PW.ObPtr _ PW.MapFunction[design, WiringFn13, 0, nbSlices, 0, 13]; routing _ EUtils.Assemble[design, Ctrl[], wires]; END; wiresCt: PW.ObPtr _ PW.Get[design, "routingfdRegsToCtrl"]; wiresNoCt: PW.ObPtr _ PW.Inst[design, wiresCt, LIST["Contact"]]; wiresNothing: PW.ObPtr _ PW.Inst[design, wiresCt, LIST["Contact", "wire"]]; PW.Output["Registers associated with the Field Unit", "\n"]; regscdpd _ EmptyDescrRegsPD[]; regscdpu _ EmptyDescrRegsPU[]; PWDescr.SetBit[regscdpu, "nPhB", TRUE]; PWDescr.SetBit[regscdpu, "Vbias", TRUE]; PWDescr.SetBit[regscdpd, "PhA", TRUE]; PWDescr.SetBit[regscdpd, "nhold2BA", TRUE]; PWDescr.SetBit[regscdpd, "nrejectBA", TRUE]; fdRegs _ PW.AbutY[design, Regs[], Routing[]]; PW.RenameObject[design, fdRegs, "fdRegisters"]; END; FieldUnitGen: PUBLIC PROC [design: CD.Design] RETURNS [fieldUnit: PW.ObPtr] = BEGIN MaskGen: PROC[maskNb: INT] RETURNS [mask: PW.ObPtr] = BEGIN MaskCtrlGen: PROC [maskNb: INT] RETURNS [maskCtrl: PW.ObPtr] = BEGIN ctrl: PW.ObPtr; listOb: PW.ListOb _ NIL; name: ROPE = IF maskNb=1 THEN "FDShift" ELSE "FDMask"; regscdpd _ EmptyDescrRegsPD[]; regscdpu _ EmptyDescrRamPU[]; PWDescr.SetBit[regscdpu, "nPhA", TRUE]; PWDescr.SetBit[regscdpu, "Vbias", TRUE]; PWDescr.SetBit[regscdpd, "PhB", TRUE]; PWDescr.SetInt[regscdpd, name, 0, 1]; listOb _ CONS[EuControl.Nand[design, regscdpd, regscdpu, TRUE], listOb]; PWDescr.SetInt[regscdpd, name, 0, 2]; listOb _ CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb]; PWDescr.SetInt[regscdpd, name, 4, 4]; listOb _ CONS[EuControl.Nand[design, regscdpd, regscdpu, TRUE], listOb]; PWDescr.SetInt[regscdpd, name, 0, 8]; listOb _ CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb]; PWDescr.SetInt[regscdpd, name, 16, 16]; listOb _ CONS[EuControl.Nand[design, regscdpd, regscdpu, TRUE], listOb]; PWDescr.SetInt[regscdpd, name, 0, 32]; ctrl _ EuControl.Nand[design, regscdpd, regscdpu]; listOb _ CONS[ctrl, listOb]; maskCtrl _ PW.AbutListY[design, listOb]; END; MaskGate: PROC [i, b: INT] RETURNS [PW.ObPtr] = BEGIN useNand: BOOL _ ~PW.XthBitOfN[b, i]; IF PW.ODD[b] THEN useNand _ ~useNand; IF useNand THEN RETURN[maskNandArray[b]] ELSE RETURN[maskNorArray[b]]; END; MaskFn: PW.XYFunction = {RETURN[ PW.AbutListX[design, LIST[IF PW.EVEN[x] THEN maskBusesSel ELSE maskBusesOne, MaskGate[x, 1], MaskGate[x, 2], MaskGate[x, 3], MaskGate[x, 4], MaskGate[x, 5], IF maskNb=1 THEN maskRight1 ELSE maskRight2]]]}; maskNor, maskNand, maskBuses, maskBusesOne, maskBusesSel, maskRight, maskRight1, maskRight2: PW.ObPtr; maskNorArray, maskNandArray: ARRAY [1..5] OF PW.ObPtr; maskNor _ PW.Get[design, "maskNor"]; maskNand _ PW.Get[design, "maskNand"]; maskBuses _ PW.Get[design, "maskBuses"]; maskRight _ PW.Get[design, "maskRight"]; maskNorArray[1] _ PW.Inst[design, maskNor, LIST["Ct1"], FALSE]; maskNorArray[2] _ PW.Inst[design, maskNor, LIST["Ct2"], FALSE]; maskNorArray[3] _ PW.Inst[design, maskNor, LIST["Ct3"], FALSE]; maskNorArray[4] _ PW.Inst[design, maskNor, LIST["Ct4"], FALSE]; maskNorArray[5] _ PW.Inst[design, maskNor, LIST["Ct5"], FALSE]; maskNandArray[1] _ PW.Inst[design, maskNand, LIST["Ct1"], FALSE]; maskNandArray[2] _ PW.Inst[design, maskNand, LIST["Ct2"], FALSE]; maskNandArray[3] _ PW.Inst[design, maskNand, LIST["Ct3"], FALSE]; maskNandArray[4] _ PW.Inst[design, maskNand, LIST["Ct4"], FALSE]; maskNandArray[5] _ PW.Inst[design, maskNand, LIST["Ct5"], FALSE]; maskBusesOne _ PW.Inst[design, maskBuses, LIST["One"], FALSE]; maskBusesSel _ PW.Inst[design, maskBuses, LIST["Sel"], FALSE]; maskRight1 _ PW.Inst[design, maskRight, LIST["mask1"], FALSE]; maskRight2 _ PW.Inst[design, maskRight, LIST["mask2"], FALSE]; mask _ EUtils.Assemble[design, MaskCtrlGen[maskNb], PW.MapFunctionX[design, MaskFn, 0, nbSlices]]; END; ShifterGen: PROC RETURNS [shifter: PW.ObPtr] = BEGIN CtrlGen: PROC RETURNS [ctrl: PW.ObPtr] = BEGIN listOb: PW.ListOb _ NIL; regscdpd _ EmptyDescrRegsPD[]; regscdpu _ EmptyDescrRamPU[]; PWDescr.SetBit[regscdpu, "nPhA", TRUE]; PWDescr.SetBit[regscdpu, "Vbias", TRUE]; PWDescr.SetBit[regscdpd, "PhB", TRUE]; FOR i: INT IN [0..nbSlices+1) DO PWDescr.SetInt[regscdpd, "FDShift", i]; -- shift=i listOb _ CONS[EuControl.Nand[design, regscdpd, regscdpu, PW.ODD[i]], listOb]; ENDLOOP; ctrl _ PW.AbutListY[design, listOb]; END; shifter0Cell, shifterCell, shifter32Cell, ctrl, sh: PW.ObPtr; shifter0Cell _ PW.Get[design, "shifter0Cell"]; shifterCell _ PW.Get[design, "shifterCell"]; shifter32Cell _ PW.Get[design, "shifter32Cell"]; sh _ PW.AbutY[design, PW.ArrayX[design, shifter32Cell, nbSlices], PW.Array[design, shifterCell, nbSlices, nbSlices-1], PW.ArrayX[design, shifter0Cell, nbSlices]]; ctrl _ CtrlGen[]; shifter _ EUtils.Assemble[design, ctrl, sh]; END; MergeGen: PROC RETURNS [merge: PW.ObPtr] = BEGIN CtrlGen: PROC RETURNS [ctrl: PW.ObPtr] = BEGIN generic: PW.ObPtr; regscdpd2: PWDescr.Descriptor; listOb: PW.ListOb _ NIL; regscdpd _ EmptyDescrRegsPD[]; regscdpd2 _ EmptyDescrRegsPD[]; regscdpu _ EmptyDescrRamPU[]; PWDescr.SetBit[regscdpu, "nPhA", TRUE]; PWDescr.SetBit[regscdpu, "Vbias", TRUE]; PWDescr.SetBit[regscdpd, "PhB", TRUE]; PWDescr.SetBit[regscdpd2, "PhB", TRUE]; generic _ EuControl.Nand[design, regscdpd, regscdpu]; PWDescr.SetInt[regscdpd, "EUAluOp2AB", fop]; -- EUAluOp2AB=FOP PWDescr.SetInt[regscdpd2, "EUAluOp2AB", fopk]; -- EUAluOp2AB=FOPK listOb _ CONS[EuControl.NorOfNands[design, LIST[regscdpd, regscdpd2], regscdpu], listOb]; regscdpd _ EmptyDescrRegsPD[]; regscdpu _ EmptyDescrRamPU[]; PWDescr.SetBit[regscdpu, "nPhA", TRUE]; PWDescr.SetBit[regscdpu, "Vbias", TRUE]; PWDescr.SetBit[regscdpd, "PhB", TRUE]; PWDescr.SetBool[regscdpd, "FDInsert", TRUE]; -- insert listOb _ CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb]; PWDescr.SetBool[regscdpd, "FDInsert", FALSE]; -- ~insert listOb _ CONS[EuControl.Nand[design, regscdpd, regscdpu, TRUE], listOb]; ctrl _ PW.AbutListY[design, listOb]; END; ctrl, mergeDp: PW.ObPtr; mergeDp _ PW.ArrayX[design, PW.Get[design, "fuMerge"], nbSlices]; ctrl _ CtrlGen[]; merge _ EUtils.Assemble[design, ctrl, mergeDp]; END; PW.Output["The Field Unit", "\n"]; fieldUnit _ PW.AbutY[design, MaskGen[1], PW.FlipY[design, MaskGen[2]], MergeGen[], ShifterGen[] ]; PW.RenameObject[design, fieldUnit, "fieldUnit"]; END; END. ξEuGenImplA.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Last Edited by: Monier, July 9, 1985 4:05:06 pm PDT -- Control descriptors -- Here starts the layout of the RAM -- This generates every row of the ram, with the appropriate decoder -- Generating the three decoders for each row of the RAM -- PhA -- nPhA -- PhB -- nPhB -- Bias voltage generator -- Make one block (=1 bitslice = 4 RAM bits) -- Rename the kBus pins -- Now add the control -- Cells which will be re-used a lot -- One row of ram cells -- The whole ram with the decoder, generated row by row, flipping alternate rows -- Add precharge on top of the array -- The three sets of muxes -- Put together (from top to bottom, a, b and c), and add the contacts on the left -- nPhB wire nPhBWire _ PWPins.RenamePins[design, nPhBWire, RenameNPhB]; -- PhA wire: no hold, since the muxes take care of it phAWire _ PWPins.RenamePins[design, phAWire, RenamePhA]; -- The 3*8 inverters computing the complement of the RAM address -- Bringing PhB to the address register ctrl _ PWPins.RenamePins[design, ctrl, RenamePhB]; -- The address register is a regular register -- Connecting the address wires -- Now the gap between the RAM control part and the rest (mask=> pass) (except bit) -- Notice the change in descriptor -- And the connection of the 8 remaining wires to the bottom (add the inverters somewhere!!!) -- The registers providing the field descriptor -- The 4 inverters for DStateAddress, 8 inverters for EUAluLeftSrc1BA, EUAluRightSrc1BA, EUStore2ASrc1BA, EUSt3AisCBus2BA and EURes3AisCBus2BA, then 13 inverters for the fd, 5 for EUAluOp2AB, 1 for EUWriteToPBus3AB, and 1 for EURes3BisPBus3AB -- The 2 nand decoders for fd -- The 2 nand decoders for field and kBusAB (reject???) -- just PhA.nrejectBA for kBusAB -- Generate the three registers -- insert -- mask -- shift -- Let's shift to the layout of the Field Unit -- I want to isolate the ith bit of FDShift -- EUAluOp2AB=FOP OR EUAluOp2AB=FOPK (could be checked on one bit) ΚG˜– "Cedar" stylešœ™Jšœ Οmœ1™˜>J™JšœNžœ˜hJšžœ*˜,Jšžœ˜—J˜š Ÿ œžœžœ žœ žœžœ ˜EJšž˜Jšœžœ˜Jšœ˜Jšžœ#˜%J™'Jšœ˜Jšœ˜Jšœžœ˜%Jšœ3˜3Jšœ2™2J™J™-šœžœ˜!Jšœ žœ˜Jšœ ˜ Jšœ žœ ˜—šœ˜Jšœ˜Jšœ˜—Jšžœ0˜2Jšžœ˜—š Ÿœžœ žœ žœ žœ ˜HJšž˜šŸœžœžœ žœ ˜1Jšž˜Jšœžœ žœ˜šŸ œžœžœ žœ˜-Jšž˜Jšœ˜Jšœ/˜/š žœžœž œžœ ž˜'Jšœžœžœ˜>Jšœ žœ6˜CJšžœ˜—Jšœ$˜$Jšžœ˜—Jšœ˜Jšœ˜J™Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜J™SJ™"Jšœ˜Jšœ žœ˜&Jšœ žœ˜&Jšœ%žœ˜+Jšœ&žœ˜,Jšœ%žœ˜+Jšœ;˜;Jšœ˜Jšœ!žœ˜'Jšœ žœ4˜AJ™]Jšœ˜Jšœ˜Jšœ2˜2Jšœ žœ8˜EJšœ2˜2Jšœ žœ8˜EJšœ2˜2Jšœ3˜3Jšœ žœ8˜EJšœ3˜3Jšœ žœ8˜EJšœ3˜3Jšœ2˜2Jšœ žœ8˜EJšœ3˜3Jšœ žœ8˜EJšœ2˜2Jšœ-žœ˜3Jšœ žœ8˜EJšœ-žœžœ˜;Jšœ.žœ˜4Jšœ žœ8˜EJšœ.žœžœ˜˜>Jšœ=˜=Jšœ-žœ˜3Jšœ.žœ˜4Jšœ&žœ˜,Jšœ4˜4Jšœ5˜5Jšœ8˜8Jšœ.žœ˜4Jšœ.žœ˜4Jšœ žœ1žœ ˜MJ™Jšœ˜Jšœ˜Jšœ!žœ˜'Jšœ"žœ˜(Jšœ žœ˜&Jšœ- ˜>Jšœ žœ5˜BJšœ. ˜@Jšœ žœ,žœ ˜HJšœ.  ˜9J˜J™7Jš  œ   ™ Jšœ&žœ˜,Jšœ%žœ˜+Jšœ žœ5˜BJšœ+žœ  ˜>Jšœ9žœ˜?Jšœ žœ˜#Jšœ&žœ˜-Jšœ%žœ˜,Jšœžœ˜$J™Jšœžœ!žœ˜CJšœ(˜(Jšœžœ!žœ#žœ"˜xJšœ'˜'Jšœžœ!žœ˜MJšœ$˜$Jšœžœ"˜)J˜Jšœ)˜)Jšžœ˜—šŸœžœžœ žœ ˜,Jšž˜šŸ œžœ˜šœžœžœžœž˜Jšœ˜Jšœ˜Jšœ˜Jšžœ˜——šŸœžœžœžœ ˜&Jšž˜šŸ œžœžœ žœ˜-Jšž˜Jšœ˜Jšœ0˜0š žœžœž œžœ ž˜'Jšœžœžœ˜?Jšœ žœ8˜EJšžœ˜—Jšœ%˜%Jšžœ˜—Jšœžœ žœ˜Jšœ˜Jšœ˜J™ Jšœ&žœ˜,Jšœ žœ8˜EJ™Jšœ˜J™Jšœ˜Jšœžœ˜$Jšžœ˜—Jšœžœ5˜Išœ"˜"Jšœ˜Jšœ˜—Jšžœ˜—Jšœ žœ žœ$˜:Jšœ žœ žœžœ ˜@Jšœžœ žœžœ˜KJšžœ:˜Jšœžœžœ žœ˜>Jšœ žœžœ žœ˜>Jšœ žœžœ žœ˜>J˜šœ˜Jšœ˜Jšžœ,˜.—Jšžœ˜—šŸ œžœžœ žœ ˜/Jšž˜šŸœžœžœžœ ˜)Jšž˜Jšœžœ žœ˜Jšœ˜Jšœ˜Jšœ!žœ˜'Jšœ"žœ˜(Jšœ žœ˜&šžœžœžœž˜ Jšœ'  ˜2Jšœ žœ,žœžœ˜MJšž˜—Jšœžœ˜$Jšžœ˜—Jšœ4žœ˜=Jšœ žœ˜.Jšœ žœ˜,Jšœ žœ˜0šœžœ˜Jšžœ*˜,Jšžœ3˜5Jšžœ)˜+—Jšœ˜Jšœ,˜,Jšžœ˜—šŸœžœžœ žœ ˜+Jšž˜šŸœžœžœžœ ˜)Jšž˜Jšœ žœ˜Jšœ˜Jšœžœ žœ˜Jšœ˜Jšœ˜Jšœ˜J˜Jšœ!žœ˜'Jšœ"žœ˜(Jšœ žœ˜&Jšœ!žœ˜'Jšœ5˜5Jš B™BJšœ- ˜>Jšœ/ ˜AJšœ žœžœ*˜YJ˜Jšœ˜Jšœ˜Jšœ!žœ˜'Jšœ"žœ˜(Jšœ žœ˜&Jšœ&žœ  ˜6Jšœ žœ5˜BJšœ&žœ  ˜8Jšœ žœ,žœ ˜HJ˜Jšœžœ˜$Jšžœ˜—Jšœžœ˜Jšœ žœžœ#˜AJšœ˜Jšœ/˜/Jšžœ˜—J˜Jšžœ ˜"šœ žœ˜Jšœ ˜ Jšœ˜Jšœ ˜ Jšœ ˜ Jšœ˜—Jšžœ.˜0Jšžœ˜—J™—J™Jšžœ˜—J™—…—b…M