<> <> <> DIRECTORY CD, CDIO, CDCommandOps, CDSequencer, Core USING [CellType], CoreCreate, CoreProperties, PW, PWCore, Rope, Sisyph USING [Context, ES], TerminalIO, TilingClass USING [CreateTiling, SchematicsNeighborX, SchematicsNeighborY, TileArray, TileArrayRec, TileRec, TileRowRec]; TamarinCellsImpl: CEDAR PROGRAM IMPORTS CoreCreate, CDIO, CDCommandOps, CoreProperties, PW, PWCore, Sisyph, TerminalIO, TilingClass, Rope = BEGIN OPEN CoreCreate; mask: CD.Design _ NIL; OpenLayout: PROC [] RETURNS [] = { maskFileName: Rope.ROPE _ "TamarinLayout"; mask _ CDIO.ReadDesign[maskFileName, NIL, NIL, NIL]; }; SetMask: PROC [command: CDSequencer.Command] = { mask _ command.design }; TamGetAttribute: PWCore.AttributesProc = { fileName: Rope.ROPE; IF mask = NIL THEN { fileName _ TerminalIO.RequestRope["Name of Layout File (include full path) > "]; mask _ PW.OpenDesign[fileName]; }; CoreProperties.PutCellTypeProp[cellType, $PWCoreSourceDesign, mask]; }; CreateRegArray: PROC [tamarinCx: Sisyph.Context, banks, regLength, segments: NAT] RETURNS [cellType: CellType] = { <> <<-- Constants>> <<>> busSize: NAT = 34; wordsPerRow: NAT = 4; <<>> <<-- Cells>> tapcell: Core.CellType _ Sisyph.ES["TapCell.sch", tamarinCx]; memQuad: Core.CellType _ Sisyph.ES["MemQuad.sch", tamarinCx]; rBotQuad: Core.CellType _ Sisyph.ES["RBotQuad.sch", tamarinCx]; dMapperQuad: Core.CellType _ Sisyph.ES["DMapperQuad.sch", tamarinCx]; ramDrivers: Core.CellType _ Sisyph.ES["RamDrivers.sch", tamarinCx]; ramDecoders: Core.CellType _ Sisyph.ES["RamDecoders.sch", tamarinCx]; senseControl: Core.CellType _ Sisyph.ES["SenseControl.sch", tamarinCx]; dMapperCorner: Core.CellType _ Sisyph.ES["DMapperCorner.sch", tamarinCx]; decoderControl: Core.CellType _ Sisyph.ES["DecoderControl.sch", tamarinCx]; <<-- Vars>> pubwires: LIST OF WR; rows: NAT _ banks * (regLength / wordsPerRow) + 2; tileArray: TilingClass.TileArray _ NEW[TilingClass.TileArrayRec[rows]]; <<-- Wire Sequences>> wlro: Wire _ Seq["wlroBus", rows]; wlre: Wire _ Seq["wlreBus", rows]; wlw: Wire _ Seq["wlwBus", rows]; blo: Wire _ Seq["bloBus", busSize]; nblo: Wire _ Seq["nbloBus", busSize]; rlo: Wire _ Seq["rloBus", busSize]; rbus: Wire _ Seq["R",busSize]; d1: Wire _ Seq["D1",busSize]; d2: Wire _ Seq["D2",busSize]; nMemOut: Wire _ Seq["nMemOut" , busSize]; MakeRow: PROC [row: NAT] RETURNS [] = { MakeTap: PROC = { <<-- Make a Tap Row>> tileArray[row][index] _ NEW[TilingClass.TileRec _ [ type: tapcell, flatten: FALSE, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; index _ index + 1; }; index: NAT _ 0; tileArray[row] _ NEW[TilingClass.TileRowRec[busSize+3 + segments]]; <<-- Make 1st Tap at Begining of row>> MakeTap[]; <<-- Loop through the Row Entries, Making taps on the way.>> FOR i: NAT IN [0..busSize) DO SELECT row FROM << -- DMapper Row>> 0 => tileArray[row][index] _ NEW[TilingClass.TileRec _ [ type: dMapperQuad, flatten: FALSE, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"], ["R", rbus[i]], ["nMemOut", nMemOut[row]], ["ROtoD1", "ROtoD1"], ["REtoD1", "REtoD1"], ["END2", "END2"], ["nEND2", "nEND2"], ["END1","END1"], ["nEND1","nEND1"], ["D1",d1[i]], ["D2",d2[i]] ] ]]; << -- Sense & Drive Row>> 1 => tileArray[row][index] _ NEW[TilingClass.TileRec _ [ type: memQuad, flatten: FALSE, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"], ["wlro", wlro[row]], ["wlre", wlre[row]], ["wlw", wlw[row]], ["blo", blo[i]], ["nblo", nblo[i]], ["rlo", rlo[i]], ["wlro","wlro"], ["wlre","wlre"], ["wlw","wlw"] ] ]]; << -- Ram Row>> ENDCASE => tileArray[row][index] _ NEW[TilingClass.TileRec _ [ type: rBotQuad, flatten: FALSE, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"], ["wlro", wlro[row]], ["wlre", wlre[row]], ["wlw", wlw[row]], ["blo", blo[i]], ["nblo", nblo[i]], ["rlo", rlo[i]], ["RamPrecharge","RamPrecharge"], ["RamVref","RamVref"], ["nWriteE","nWriteE"], ["nWriteO","nWriteO"], ["nMemOut",nMemOut[i]], ["R",rbus[i]] ] ]]; index _ index + 1; IF ((i+1) MOD (busSize/segments)) = 0 THEN MakeTap[]; ENDLOOP; <<-- Add Drivers & Decoders>> SELECT row FROM << -- DMapper Row>> 0 => tileArray[row][index] _ NEW[TilingClass.TileRec _ [ type: dMapperCorner, flatten: FALSE, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"], ["WriteOk", "WriteOk"], ["WriteOctal", "WriteOctal"], ["DSwap", "DSwap"], ["MemtoD1", "MemtoD1"], ["MemtoD2", "MemtoD2"], ["NextState", "NextState"] ] ]]; << -- Sense & Drive Row>> 1 => { tileArray[row][index] _ NEW[TilingClass.TileRec _ [ type: senseControl, flatten: FALSE, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"] ] ]]; tileArray[row][index] _ NEW[TilingClass.TileRec _ [ type: decoderControl, flatten: FALSE, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"],["NextRAddr", "NextRAddr"] ] ]]; }; << -- Memory Row>> ENDCASE => { tileArray[row][index] _ NEW[TilingClass.TileRec _ [ type: ramDrivers, flatten: FALSE, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"], ["wlro", wlro[row]], ["wlre", wlre[row]], ["wlw", wlw[row]] ] ]]; tileArray[row][index+1] _ NEW[TilingClass.TileRec _ [ type: ramDecoders, flatten: FALSE, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"], ["wlro", wlro[row]], ["wlre", wlre[row]], ["wlw", wlw[row]] ] ]]; }; RETURN; }; <<>> <<-- Error Checking>> IF (34 MOD segments) # 0 THEN ERROR; IF (regLength MOD 4) # 0 THEN ERROR; <<-- Build each bank of the Reg Array>> <<>> FOR bank: NAT IN [0..banks) DO FOR counter: NAT IN [0..bank / wordsPerRow) DO rows _ rows - 1; MakeRow[rows]; ENDLOOP; ENDLOOP; pubwires _ LIST["Vdd", "Gnd", "D1", "D2", "R", "WriteOctal", "NextRAddr", "WriteOk", "NextState", "MemtoD2", "DSwap", "MemtoD1"]; cellType _ TilingClass.CreateTiling[ name: "RegFile", public: WireList[pubwires], tileArray: tileArray, neighborX: TilingClass.SchematicsNeighborX, neighborY: TilingClass.SchematicsNeighborY ]; }; CreateTagCC: PROC [tamarinCx: Sisyph.Context] RETURNS [cellType: CellType] = { ccRows: NAT = 2; ccWordLength: NAT = 34; TagCcOut: Wire _ Seq["ccOut", ccRows]; D1Bus: Wire _ Seq["D1", 34]; D2Bus: Wire _ Seq["D2", 34]; RBus: Wire _ Seq["R", 34]; ccD1Bus: Wire _ Seq["ccD1", 34]; ccD2Bus: Wire _ Seq["ccD2", 34]; ccnD1Bus: Wire _ Seq["ccnD1", 34]; ccnD2Bus: Wire _ Seq["ccnD2", 34]; ccD1xorD2Bus: Wire _ Seq["ccD1xorD2", 34]; pubwires: LIST OF WR; tags: ARRAY [0..ccRows) OF Rope.ROPE _ [ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" ]; ct: Core.CellType; ccBasect: Core.CellType _ Sisyph.ES["ccBase.sch", tamarinCx]; ccD10D2Xct: Core.CellType _ Sisyph.ES["ccD10D2X.sch", tamarinCx]; ccD11D2Xct: Core.CellType _ Sisyph.ES["ccD11D2X.sch", tamarinCx]; ccD1XD20ct: Core.CellType _ Sisyph.ES["ccD1XD20.sch", tamarinCx]; ccD10D20ct: Core.CellType _ Sisyph.ES["ccD10D20.sch", tamarinCx]; ccD11D20ct: Core.CellType _ Sisyph.ES["ccD10D20.sch", tamarinCx]; ccD1XD21ct: Core.CellType _ Sisyph.ES["ccD10D21.sch", tamarinCx]; ccD10D21ct: Core.CellType _ Sisyph.ES["ccD10D21.sch", tamarinCx]; ccD11D21ct: Core.CellType _ Sisyph.ES["ccD11D21.sch", tamarinCx]; ccD1eqD2ct: Core.CellType _ Sisyph.ES["ccD1eqD2.sch", tamarinCx]; tileArray: TilingClass.TileArray _ NEW[TilingClass.TileArrayRec[ccRows]]; FOR row: NAT IN [0..ccRows) DO tagRope: Rope.ROPE _ tags[row]; tileArray[row] _ NEW[TilingClass.TileRowRec[34]]; FOR bit: NAT IN [0..ccWordLength) DO ch: CHAR _ Rope.Fetch[tagRope, bit]; SELECT ch FROM 'A => {ct _ ccBasect}; 'B => {ct _ ccD10D2Xct}; 'C => {ct _ ccD11D2Xct}; 'D => {ct _ ccD1XD20ct}; 'E => {ct _ ccD10D20ct}; 'F => {ct _ ccD11D20ct}; 'G => {ct _ ccD1XD21ct}; 'H => {ct _ ccD10D21ct}; 'I => {ct _ ccD11D21ct}; 'J => {ct _ ccD1eqD2ct}; ENDCASE => {ct _ ccBasect}; tileArray[row][bit] _ NEW[TilingClass.TileRec _ [type: ct, flatten: FALSE, renaming: LIST[ ["D1", D1Bus[bit]], ["D2", D2Bus[bit]], ["R", RBus[bit]], ["ccD1", ccD1Bus[bit]], ["ccD2", ccD2Bus[bit]], ["ccnD1", ccnD1Bus[bit]], ["ccnD2", ccnD2Bus[bit]], ["ccD1xorD2", ccD1xorD2Bus[bit]], ["ccOut", TagCcOut[row]], ["Gnd", "Gnd"]]]]; ENDLOOP; ENDLOOP; pubwires _ LIST[TagCcOut, D1Bus, D2Bus, RBus, ccD1Bus, ccD2Bus, ccnD1Bus, ccnD2Bus, ccD1xorD2Bus, "Gnd"]; cellType _ TilingClass.CreateTiling[ name: "TagCc", public: WireList[pubwires], tileArray: tileArray, neighborX: TilingClass.SchematicsNeighborX, neighborY: TilingClass.SchematicsNeighborY]; }; CreateAdder: PROC [tamarinCx: Sisyph.Context] RETURNS [cellType: CellType] = { NUMBITS: NAT = 32; BlAndRip: PROC [numRipples, index: NAT] RETURNS [] = { tileArray[0][index] _ NEW[TilingClass.TileRec _ [ type: block, flatten: FALSE, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"], ["D1", D1[index]], ["D2", D2[index]], ["R", R[index]], ["SelAdder", SelAdder], ["DOADD", DoAdd[1]], ["DOSUB", DoAdd[0]]] ]]; FOR i: NAT IN [1..numRipples] DO tileArray[0][index-i] _ NEW[TilingClass.TileRec _ [ type: ripple, flatten: FALSE, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"], ["D1", D1[index-i]], ["D2", D2[index-i]], ["R", R[index-i]], ["SelAdder", SelAdder], ["DOADD", DoAdd[1]], ["DOSUB", DoAdd[0]]] ]]; ENDLOOP; RETURN; }; D1: Wire _ Seq["D1", NUMBITS]; D2: Wire _ Seq["D2", NUMBITS]; R: Wire _ Seq["R", NUMBITS]; SelAdder: Wire _ Seq["SelAdder", 2]; CarryIn: Wire _ Seq["CarryIn", 2]; GKout: Wire _ Seq["GKout", 2]; Pout: Wire _ Seq["Pout", 2]; DoAdd: Wire _ Seq["DoAdd", 2]; Bcin: Wire _ Seq["Bcin", 2]; pubwires: LIST OF WR; tileArray: TilingClass.TileArray _ NEW[TilingClass.TileArrayRec[1]]; block: Core.CellType _ Sisyph.ES["BlockAdder.sch", tamarinCx]; ripple: Core.CellType _ Sisyph.ES["RippleAdder.sch", tamarinCx]; i: NAT _ NUMBITS - 2; j: NAT _ 1; <<-- Start building at the middle stuff, then put on the least sig. side followed by the ms side >> tileArray[0] _ NEW[TilingClass.TileRowRec[NUMBITS]]; <> BlAndRip[1, 30]; BlAndRip[2, 28]; BlAndRip[3, 25]; BlAndRip[4, 21]; BlAndRip[5, 16]; BlAndRip[5, 10]; BlAndRip[3, 4]; tileArray[0][NUMBITS-1] _ NEW[TilingClass.TileRec _ [ type: block, flatten: FALSE, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"], ["D1", D1[NUMBITS-1]], ["D2", D2[NUMBITS-1]], ["R", R[NUMBITS-1]], ["SelAdder", SelAdder], ["DOADD", DoAdd[1]], ["DOSUB", DoAdd[0]], ["NGKIN", "Gnd"], ["GKIN", "Vdd"], ["PIN", "Vdd"], ["NPIN", "Gnd"], ["CIN", CarryIn[1]], ["NCIN", CarryIn[0]]] ]]; tileArray[0][0] _ NEW[TilingClass.TileRec _ [ type: ripple, flatten: FALSE, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"], ["D1", D1[0]], ["D2", D2[0]], ["R", R[0]], ["SelAdder", SelAdder], ["NGKOUT", GKout[0]], ["GKOUT", GKout[1]], ["POUT", Pout[1]], ["NPOUT", Pout[0]], ["NCIN2", Bcin [0]], ["CIN2", Bcin[1]], ["DOADD", DoAdd[1]], ["DOSUB", DoAdd[0]], ["SUM", "sum0"]] ]]; pubwires _ LIST[D1, D2, R, "Vdd", "Gnd", DoAdd, CarryIn, SelAdder, GKout, Pout, Bcin, "sum0"]; cellType _ TilingClass.CreateTiling[ name: "Adder", public: WireList[pubwires], tileArray: tileArray, neighborX: TilingClass.SchematicsNeighborX, neighborY: TilingClass.SchematicsNeighborY ]; }; CreateShifter: PROC [tamarinCx: Sisyph.Context] RETURNS [cellType: CellType] = { Select: Wire _ Seq["Select", 16]; shResult: Wire _ Seq["shResult", 32]; D1Bus: Wire _ Seq["D1Bus", 32]; D2Bus: Wire _ Seq["D2Bus", 32]; shTopOut: Wire _ Seq["shTopOut", 32]; RBus: Wire _ Seq["RBus", 32]; spass: Wire _ Seq["spass", 16]; ShiftBotCtl: Wire _ Seq["ShiftBotCtl", 3]; SelShifter: Wire _ Seq["SelShifter", 2]; tileArray: TilingClass.TileArray _ NEW[TilingClass.TileArrayRec[18]]; <<-- 17 is the top and I'll start building there>> tileArray[17] _ NEW[TilingClass.TileRowRec[33]]; FOR i: NAT IN [0..32) DO tileArray[17][i] _ NEW[TilingClass.TileRec _ [ type: Sisyph.ES["ShiftTop.sch", tamarinCx], flatten: FALSE, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"], ["D1", D1Bus[i]], ["D2", D2Bus[i]], ["R", RBus[i]]] ]]; ENDLOOP; <<-- build the right edge>> tileArray[17][32] _ NEW[TilingClass.TileRec _ [ type: Sisyph.ES["ShiftTopR.sch", tamarinCx], flatten: FALSE, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; <<-- line n of shifter is tileArray[16-n]>> FOR row: NAT DECREASING IN [1..16] DO tileArray[row] _ NEW[TilingClass.TileRowRec[33]]; FOR i: NAT IN [0..31] DO tileArray[row][i] _ NEW[TilingClass.TileRec _ [ type: Sisyph.ES["ShiftBase.sch", tamarinCx], flatten: FALSE, renaming: LIST[ ["Select", Select[16-row]] ] ]]; ENDLOOP; <<-- build the right edge>> tileArray[row][32] _ NEW[TilingClass.TileRec _ [ type: Sisyph.ES["ShiftBaseR.sch", tamarinCx], flatten: FALSE, renaming: LIST[ ["Select", Select[16-row]] ] ]]; ENDLOOP; <<-- 0 is the bottom>> tileArray[0] _ NEW[TilingClass.TileRowRec[33]]; FOR i: NAT IN [0..31] DO tileArray[0][i] _ NEW[TilingClass.TileRec _ [ type: Sisyph.ES["ShiftBottom.sch", tamarinCx], flatten: FALSE, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"], ["D1", D1Bus[i]], ["D2", D2Bus[i]], ["R", RBus[i]], ["ShiftBotCtl", ShiftBotCtl], ["SelShifter", SelShifter] ] ]]; ENDLOOP; tileArray[0][32] _ NEW[TilingClass.TileRec _ [ type: Sisyph.ES["ShiftBottomR.sch", tamarinCx], flatten: FALSE, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"], ["SelShifter", SelShifter], ["ShiftBotCtl", ShiftBotCtl] ] ]]; cellType _ TilingClass.CreateTiling[ name: "BarrelShifter", public: Wires[D1Bus, D2Bus, RBus, "Vdd", "Gnd", Select, ShiftBotCtl, SelShifter], tileArray: tileArray, neighborX: TilingClass.SchematicsNeighborX, neighborY: TilingClass.SchematicsNeighborY ]; }; CreateIShifter: PROC [tamarinCx: Sisyph.Context] RETURNS [cellType: CellType] = { R: Wire _ Seq["R", 32]; Sel: Wire _ Seq["Sel", 4]; IBSres: Wire _ Seq["IBSres", 32]; OpCode: Wire _ Seq["OpCode", 8]; NextIWd: Wire _ Seq["NextIWd", 32]; CurIWd: Wire _ Seq["CurIWd", 32]; pubwires: LIST OF WR; <> IShiftTopCT: Core.CellType _ Sisyph.ES["IShiftTop.sch", tamarinCx]; IShiftTopNCCT: Core.CellType _ Sisyph.ES["IShiftTopNC.sch", tamarinCx]; IShiftBaseCT: Core.CellType _ Sisyph.ES["IShiftBase.sch", tamarinCx]; IShiftBotCT: Core.CellType _ Sisyph.ES["IShiftBot.sch", tamarinCx]; tileArray: TilingClass.TileArray _ NEW[TilingClass.TileArrayRec[6]]; tileArray[0] _ NEW[TilingClass.TileRowRec[40]]; FOR i: NAT IN [0..31] DO tileArray[0][i] _ NEW[TilingClass.TileRec _ [ type: IShiftBotCT, flatten: FALSE, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"], ["R", R[i]], ["IBSres", IBSres[i]], ["NextIWd", NextIWd[i]], ["CurIWd", CurIWd[i]] ] ]]; ENDLOOP; FOR i: NAT IN [32..39] DO tileArray[0][i] _ NEW[TilingClass.TileRec _ [ type: IShiftBotCT, flatten: FALSE, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"], ["R", "Gnd"], ["IBSres", OpCode[i-32]] ] ]]; ENDLOOP; FOR row: NAT IN [1..4] DO tileArray[row] _ NEW[TilingClass.TileRowRec[40]]; FOR i: NAT IN [0..39] DO tileArray[row][i] _ NEW[TilingClass.TileRec _ [ type: IShiftBaseCT, flatten: FALSE, renaming: LIST[ ["Select", Sel[row-1]] ] ]]; ENDLOOP; ENDLOOP; tileArray[5] _ NEW[TilingClass.TileRowRec[40]]; FOR i: NAT IN [0..31] DO tileArray[5][i] _ NEW[TilingClass.TileRec _ [ type: IShiftTopCT, flatten: FALSE, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"] ] ]]; ENDLOOP; FOR i: NAT IN [32..39] DO tileArray[5][i] _ NEW[TilingClass.TileRec _ [ type: IShiftTopNCCT, flatten: FALSE, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"] ] ]]; ENDLOOP; pubwires _ LIST[IBSres, R, Sel, OpCode, NextIWd, CurIWd, "Vdd", "Gnd"]; cellType _ TilingClass.CreateTiling[ name: "InstShifter", public: WireList[pubwires], tileArray: tileArray, neighborX: TilingClass.SchematicsNeighborX, neighborY: TilingClass.SchematicsNeighborY ]; }; Adder36: PROC [tamarinCx: Sisyph.Context] RETURNS [cellType: CellType] = { NUMBITS: NAT = 36; BlAndRip: PROC [numRipples, index: NAT] RETURNS [] = { tileArray[0][index] _ NEW[TilingClass.TileRec _ [ type: block, flatten: FALSE, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"], ["D1", in1[index]], ["D2", in0[index]], ["R", res[index]], ["SelAdder", SelAdder], ["DOADD", "Vdd"], ["DOSUB", "Gnd"]] ]]; FOR i: NAT IN [1..numRipples] DO tileArray[0][index-i] _ NEW[TilingClass.TileRec _ [ type: ripple, flatten: FALSE, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"], ["D1", in1[index-i]], ["D2", in0[index-i]], ["R", res[index-i]], ["SelAdder", SelAdder], ["DOADD", "Vdd"], ["DOSUB", "Gnd"]] ]]; ENDLOOP; RETURN; }; in0: Wire _ Seq["in0", NUMBITS]; in1: Wire _ Seq["in1", NUMBITS]; res: Wire _ Seq["res", NUMBITS]; SelAdder: Wire _ Seq["SelAdder", 2]; tileArray: TilingClass.TileArray _ NEW[TilingClass.TileArrayRec[1]]; block: Core.CellType _ Sisyph.ES["BlockAdder.sch", tamarinCx]; ripple: Core.CellType _ Sisyph.ES["RippleAdder.sch", tamarinCx]; i: NAT _ NUMBITS-2; j: NAT _ 1; <<-- Start building at the middle stuff, then put on the least sig. side followed by the ms side >> tileArray[0] _ NEW[TilingClass.TileRowRec[NUMBITS]]; WHILE (i >(j+1)) DO BlAndRip[j, i]; j _ j + 1; i _ i - j; ENDLOOP; BlAndRip[i, i]; tileArray[0][NUMBITS-1] _ NEW[TilingClass.TileRec _ [ type: block, flatten: FALSE, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"], ["D1", in1[NUMBITS-1]], ["D2", in0[NUMBITS-1]], ["R", res[NUMBITS-1]], ["SelAdder", SelAdder], ["DOADD", "Vdd"], ["DOSUB", "Gnd"], ["NGKIN", "Vdd"], ["GKIN", "Gnd"], ["PIN", "Vdd"], ["NPIN", "Gnd"], ["CIN", "Gnd"], ["NCIN", "Vdd"]] ]]; cellType _ TilingClass.CreateTiling[ name: "Adder", public: Wires[in0, in1, res, "Vdd", "Gnd", SelAdder], tileArray: tileArray, neighborX: TilingClass.SchematicsNeighborX, neighborY: TilingClass.SchematicsNeighborY ]; }; CreateRam: PROC [tamarinCx: Sisyph.Context] RETURNS [cellType: CellType] = { <> NUMFRAMES: NAT = 5; NUMWORDSPERFRAME: NAT = 40; NUMBITSPERWORD: NAT = 34; NUMDECODEBITS: NAT = 6; NUMFRAMEBITS: NAT = 3; NUMROWS: NAT = (NUMFRAMES * NUMWORDSPERFRAME) / 4; TAPFREQX: NAT = 34; -- divides it up into 4 segments NUMTAPS: NAT = 4; <<>> blo: Wire _ Seq["blo", NUMBITSPERWORD]; nblo: Wire _ Seq["nblo", NUMBITSPERWORD]; rlo: Wire _ Seq["rlo", NUMBITSPERWORD]; ble: Wire _ Seq["ble", NUMBITSPERWORD]; nble: Wire _ Seq["nble", NUMBITSPERWORD]; rle: Wire _ Seq["rle", NUMBITSPERWORD]; wlro: Wire _ Seq["wlro", NUMROWS]; wlre: Wire _ Seq["wlre", NUMROWS]; wlw: Wire _ Seq["wlw", NUMROWS]; tileArray: TilingClass.TileArray _ NEW[TilingClass.TileArrayRec[NUMROWS + 1]]; FOR i: NAT IN [1..NUMROWS) DO tileArray[i] _ NEW[TilingClass.TileRowRec[NUMBITSPERWORD*NUMTAPS + NUMTAPS + 1]]; ENDLOOP; }; ShiftDecode: PROC [numBits: NAT, tamarinCx: Sisyph.Context] RETURNS [cellType: CellType] = { twoToTheN: ARRAY [0..8] OF NAT = [1, 2, 4, 8, 16, 32, 64, 128, 256]; numCols: NAT _ (2 * numBits) + 2; numRows: NAT _ twoToTheN[numBits]; bit: Wire _ Seq["bit", numBits]; out: Wire _ Seq["out", numRows]; Sel: Wire _ Seq["Sel", numBits]; nSel: Wire _ Seq["nSel", numBits]; <> DTransCT: Core.CellType _ Sisyph.ES["DecTrans.sch", tamarinCx]; DBlankCT: Core.CellType _ Sisyph.ES["DecBlank.sch", tamarinCx]; DEndCT: Core.CellType _ Sisyph.ES["DecEnd.sch", tamarinCx]; DInvCT: Core.CellType _ Sisyph.ES["DecInv.sch", tamarinCx]; bitVals: NAT; tileArray: TilingClass.TileArray _ NEW[TilingClass.TileArrayRec[numRows]]; FOR i: NAT IN [0..numRows) DO tileArray[i] _ NEW[TilingClass.TileRowRec[numCols]]; <> tileArray[i][0] _ NEW[TilingClass.TileRec _ [ type: DInvCT, flatten: FALSE, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"], ["out", out[i]]] ]]; tileArray[i][numCols-1] _ NEW[TilingClass.TileRec _ [ type: DEndCT, flatten: FALSE, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; <> bitVals _ i; FOR j: NAT DECREASING IN [0..numBits) DO bit: BOOL _ LOOPHOLE[(bitVals MOD 2), BOOL]; IF bit THEN { tileArray[i][2*j + 1] _ NEW[TilingClass.TileRec _ [ type: DBlankCT, flatten: FALSE, renaming: LIST[["Gnd", "Gnd"], ["sel", Sel[j]]] ]]; tileArray[i][2*j + 2] _ NEW[TilingClass.TileRec _ [ type: DTransCT, flatten: FALSE, renaming: LIST[["Gnd", "Gnd"], ["sel", nSel[j]]] ]]; } ELSE { tileArray[i][2*j + 1] _ NEW[TilingClass.TileRec _ [ type: DTransCT, flatten: FALSE, renaming: LIST[["Gnd", "Gnd"], ["sel", Sel[j]]] ]]; tileArray[i][2*j + 2] _ NEW[TilingClass.TileRec _ [ type: DBlankCT, flatten: FALSE, renaming: LIST[["Gnd", "Gnd"], ["sel", nSel[j]]] ]]; }; bitVals _ bitVals/2; ENDLOOP; ENDLOOP; cellType _ TilingClass.CreateTiling[ name: "ShiftDecode", public: Wires[out, Sel, nSel, "Vdd", "Gnd"], tileArray: tileArray, neighborX: TilingClass.SchematicsNeighborX, neighborY: TilingClass.SchematicsNeighborY ]; }; CDCommandOps.RegisterWithMenu[ menu: $ProgramMenu, entry: "Set Layout", doc: "Sets .mask file for schematic generated layout", proc: SetMask, queue: dontQueue ]; [] _ PWCore.RegisterLayoutAtom[ layoutAtom: $TamGet, layoutProc: PWCore.GetLayoutAtomRegistration[$Get].layoutProc, decorateProc: PWCore.GetLayoutAtomRegistration[$Get].decorateProc, attributesProc: TamGetAttribute ]; [] _ PWCore.RegisterLayoutAtom[ layoutAtom: $TamGetAndFlatten, layoutProc: PWCore.GetLayoutAtomRegistration[$GetAndFlatten].layoutProc, decorateProc: PWCore.GetLayoutAtomRegistration[$GetAndFlatten].decorateProc, attributesProc: TamGetAttribute ]; END.