TamarinCellsImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last Edited by: Ross May 15, 1987 12:24:48 pm PDT
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] = {
Create the Internal RegFile Array. Build the Reg Array such that there are 34 MemQuad cells across (which makes 4 words per row). Divide these cells into segments and place taps between them based on segments. regLength is the number of words per register bank, and banks is the # of register banks to create.
-- 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: NATNUMBITS - 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]];
I want the control over the actual placement of the cells
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;
Extract all of the cells once
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: NATNUMBITS-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] = {
Constant Declarations:
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];
Extract all of the cells once
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]];
Put on the two ends
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"]]
]];
Now do the guts
bitVals ← i;
FOR j: NAT DECREASING IN [0..numBits) DO
bit: BOOLLOOPHOLE[(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.