CreateRealUCodeRom:
PUBLIC
PROC [tamarinCx: Sisyph.Context]
RETURNS [cellType: Core.CellType] = {
Create the UCode Rom.
-- Types
RomCellType: TYPE = {A, B0, B1, C, D0000, D0001, D0010, D0011, D0100, D0101, D0110, D0111, D1000, D1001, D1010, D1011, D1100, D1101, D1110, D1111, E, F, G0, G1, H};
RowCells: TYPE = ARRAY RomCellType OF Core.CellType;
-- Vars
nMI: NAT;
wMI: NAT;
-- Cells
romTA: Core.CellType ← Sisyph.ES["RomTA.sch", tamarinCx];
romTB: Core.CellType ← Sisyph.ES["RomTB.sch", tamarinCx];
romTBl: Core.CellType ← Sisyph.ES["RomTB1.sch", tamarinCx];
romTC: Core.CellType ← Sisyph.ES["RomTC.sch", tamarinCx];
romTD: Core.CellType ← Sisyph.ES["RomTD.sch", tamarinCx];
romTE: Core.CellType ← Sisyph.ES["RomTE.sch", tamarinCx];
romTF: Core.CellType ← Sisyph.ES["RomTF.sch", tamarinCx];
romTG: Core.CellType ← Sisyph.ES["RomTG.sch", tamarinCx];
romTH: Core.CellType ← Sisyph.ES["RomTH.sch", tamarinCx];
romHA: Core.CellType ← Sisyph.ES["RomHA.sch", tamarinCx];
romHB: Core.CellType ← Sisyph.ES["RomHB.sch", tamarinCx];
romHC: Core.CellType ← Sisyph.ES["RomHC.sch", tamarinCx];
romHD: Core.CellType ← Sisyph.ES["RomHD.sch", tamarinCx];
romHE: Core.CellType ← Sisyph.ES["RomHE.sch", tamarinCx];
romHF: Core.CellType ← Sisyph.ES["RomHF.sch", tamarinCx];
romHG: Core.CellType ← Sisyph.ES["RomHG.sch", tamarinCx];
romHH: Core.CellType ← Sisyph.ES["RomHH.sch", tamarinCx];
romUA: Core.CellType ← Sisyph.ES["RomUA.sch", tamarinCx];
romUB0: Core.CellType ← Sisyph.ES["RomUB0.sch", tamarinCx];
romUB1: Core.CellType ← Sisyph.ES["RomUB1.sch", tamarinCx];
romUC: Core.CellType ← Sisyph.ES["RomUC.sch", tamarinCx];
romUD0000: Core.CellType ← Sisyph.ES["RomU0000.sch", tamarinCx];
romUD0001: Core.CellType ← Sisyph.ES["RomU0001.sch", tamarinCx];
romUD0010: Core.CellType ← Sisyph.ES["RomU0010.sch", tamarinCx];
romUD0011: Core.CellType ← Sisyph.ES["RomU0011.sch", tamarinCx];
romUD0100: Core.CellType ← Sisyph.ES["RomU0100.sch", tamarinCx];
romUD0101: Core.CellType ← Sisyph.ES["RomU0101.sch", tamarinCx];
romUD0110: Core.CellType ← Sisyph.ES["RomU0110.sch", tamarinCx];
romUD0111: Core.CellType ← Sisyph.ES["RomU0111.sch", tamarinCx];
romUD1000: Core.CellType ← Sisyph.ES["RomU1000.sch", tamarinCx];
romUD1001: Core.CellType ← Sisyph.ES["RomU1001.sch", tamarinCx];
romUD1010: Core.CellType ← Sisyph.ES["RomU1010.sch", tamarinCx];
romUD1011: Core.CellType ← Sisyph.ES["RomU1011.sch", tamarinCx];
romUD1100: Core.CellType ← Sisyph.ES["RomU1100.sch", tamarinCx];
romUD1101: Core.CellType ← Sisyph.ES["RomU1101.sch", tamarinCx];
romUD1110: Core.CellType ← Sisyph.ES["RomU1110.sch", tamarinCx];
romUD1111: Core.CellType ← Sisyph.ES["RomU1111.sch", tamarinCx];
romUE: Core.CellType ← Sisyph.ES["RomUE.sch", tamarinCx];
romUF: Core.CellType ← Sisyph.ES["RomUF.sch", tamarinCx];
romUG0: Core.CellType ← Sisyph.ES["RomUG0.sch", tamarinCx];
romUG1: Core.CellType ← Sisyph.ES["RomUG1.sch", tamarinCx];
romUH: Core.CellType ← Sisyph.ES["RomUH.sch", tamarinCx];
romDA: Core.CellType ← Sisyph.ES["RomDA.sch", tamarinCx];
romDB0: Core.CellType ← Sisyph.ES["RomDB0.sch", tamarinCx];
romDB1: Core.CellType ← Sisyph.ES["RomDB1.sch", tamarinCx];
romDC: Core.CellType ← Sisyph.ES["RomDC.sch", tamarinCx];
romDD0000: Core.CellType ← Sisyph.ES["RomD0000.sch", tamarinCx];
romDD0001: Core.CellType ← Sisyph.ES["RomD0001.sch", tamarinCx];
romDD0010: Core.CellType ← Sisyph.ES["RomD0010.sch", tamarinCx];
romDD0011: Core.CellType ← Sisyph.ES["RomD0011.sch", tamarinCx];
romDD0100: Core.CellType ← Sisyph.ES["RomD0100.sch", tamarinCx];
romDD0101: Core.CellType ← Sisyph.ES["RomD0101.sch", tamarinCx];
romDD0110: Core.CellType ← Sisyph.ES["RomD0110.sch", tamarinCx];
romDD0111: Core.CellType ← Sisyph.ES["RomD0111.sch", tamarinCx];
romDD1000: Core.CellType ← Sisyph.ES["RomD1000.sch", tamarinCx];
romDD1001: Core.CellType ← Sisyph.ES["RomD1001.sch", tamarinCx];
romDD1010: Core.CellType ← Sisyph.ES["RomD1010.sch", tamarinCx];
romDD1011: Core.CellType ← Sisyph.ES["RomD1011.sch", tamarinCx];
romDD1100: Core.CellType ← Sisyph.ES["RomD1100.sch", tamarinCx];
romDD1101: Core.CellType ← Sisyph.ES["RomD1101.sch", tamarinCx];
romDD1110: Core.CellType ← Sisyph.ES["RomD1110.sch", tamarinCx];
romDD1111: Core.CellType ← Sisyph.ES["RomD1111.sch", tamarinCx];
romDE: Core.CellType ← Sisyph.ES["RomDE.sch", tamarinCx];
romDF: Core.CellType ← Sisyph.ES["RomDF.sch", tamarinCx];
romDG0: Core.CellType ← Sisyph.ES["RomDG0.sch", tamarinCx];
romDG1: Core.CellType ← Sisyph.ES["RomDG1.sch", tamarinCx];
romDH: Core.CellType ← Sisyph.ES["RomDH.sch", tamarinCx];
romBA: Core.CellType ← Sisyph.ES["RomBA.sch", tamarinCx];
romBB: Core.CellType ← Sisyph.ES["RomBB.sch", tamarinCx];
romBC: Core.CellType ← Sisyph.ES["RomBC.sch", tamarinCx];
romBD: Core.CellType ← Sisyph.ES["RomBD.sch", tamarinCx];
romBE: Core.CellType ← Sisyph.ES["RomBE.sch", tamarinCx];
romBF: Core.CellType ← Sisyph.ES["RomBF.sch", tamarinCx];
romBG: Core.CellType ← Sisyph.ES["RomBG.sch", tamarinCx];
romBH: Core.CellType ← Sisyph.ES["RomBH.sch", tamarinCx];
tRowCells: RowCells ← [romTA, romTB, romTBl, romTC, romTD, romTD, romTD, romTD, romTD, romTD, romTD, romTD, romTD, romTD, romTD, romTD, romTD, romTD, romTD, romTD, romTE, romTF, romTG, romTG, romTH];
hRowCells: RowCells ← [romHA, romHB, romHB, romHC, romHD, romHD, romHD, romHD, romHD, romHD, romHD, romHD, romHD, romHD, romHD, romHD, romHD, romHD, romHD, romHD, romHE, romHF, romHG, romHG, romHH];
uRowCells: RowCells ← [romUA, romUB0, romUB1, romUC, romUD0000, romUD0001, romUD0010, romUD0011, romUD0100, romUD0101, romUD0110, romUD0111, romUD1000, romUD1001, romUD1010, romUD1011, romUD1100, romUD1101, romUD1110, romUD1111, romUE, romUF, romUG0, romUG1, romUH];
dRowCells: RowCells ← [romDA, romDB0, romDB1, romDC, romDD0000, romDD0001, romDD0010, romDD0011, romDD0100, romDD0101, romDD0110, romDD0111, romDD1000, romDD1001, romDD1010, romDD1011, romDD1100, romDD1101, romDD1110, romDD1111, romDE, romDF, romDG0, romDG1, romDH];
bRowCells: RowCells ← [romBA, romBB, romBB, romBC, romBD, romBD, romBD, romBD, romBD, romBD, romBD, romBD, romBD, romBD, romBD, romBD, romBD, romBD, romBD, romBD,romBE, romBF, romBG, romBG, romBH];
romCellSelect: ARRAY [0..15] OF RomCellType ← [D0000, D0001, D0010, D0011, D0100, D0101, D0110, D0111, D1000, D1001, D1010, D1011, D1100, D1101, D1110, D1111];
-- Vars
tileArray: TilingClass.TileArray;
-- Wire Sequences
aAddrWire: CoreCreate.Wire ← CoreCreate.Seq["aAddr", uCodeAddrSize];
bAddrWire: CoreCreate.Wire ← CoreCreate.Seq["bAddr", uCodeAddrSize];
miWire: CoreCreate.Wire ← CoreCreate.Seq["MI", sMI];
milWire: CoreCreate.Wire ← CoreCreate.Seq["MIL", sMI];
opcodeWire: CoreCreate.Wire ← CoreCreate.Seq["newOpcode", uCodeAddrSize];
precondWire: CoreCreate.Wire ← CoreCreate.Seq["Precond", 3];
nUCodeMuxSel: CoreCreate.Wire ← CoreCreate.Seq["nUCodeMuxSel", 4];
MakeUCodeRow:
PROC [type:
NAT, row:
NAT, aAddr, bAddr:
NAT, deMI, doMI, ueMI, uoMI: Rope.
ROPE, order:
LORA]
RETURNS [] = {
BoolToInt:
PROC [val:
BOOLEAN, index:
NAT]
RETURNS [i:
NAT] = {
i ← (IF val THEN index ELSE 0);
};
cells: RowCells ← (
SELECT type
FROM
0 => tRowCells,
1 => hRowCells,
2 => uRowCells,
3 => dRowCells,
4 => bRowCells,
ENDCASE => ERROR);
tileArray[row] ← NEW[TilingClass.TileRowRec[wMI+uCodeAddrSize+uCodeAddrSize+2]];
tileArray[row][0] ←
NEW[TilingClass.TileRec ← [
type: cells[A],
renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]]
]];
IF type=0
THEN
FOR i:
NAT
IN [0..uCodeAddrSize-1)
DO
tileArray[row][1+i] ←
NEW[TilingClass.TileRec ← [
type: (IF i<5 THEN cells[B0] ELSE cells[B1]),
flatten: FALSE,
renaming: (
IF i<5
THEN
LIST[["AAddr", aAddrWire[i]], ["Opcode", opcodeWire[i]], ["Vdd", "Vdd"], ["Gnd", "Gnd"]]
ELSE LIST[["AAddr", aAddrWire[i]], ["Opcode", opcodeWire[i]], ["PreCondAddr", precondWire[i-5]], ["Vdd", "Vdd"], ["Gnd", "Gnd"]])
]];
ENDLOOP
ELSE
FOR i:
NAT
IN [0..uCodeAddrSize-1)
DO
tileArray[row][1+i] ←
NEW[TilingClass.TileRec ← [
type: (IF TamarinUtil.BitOnP[aAddr, uCodeAddrSize-i-1] THEN cells[B0] ELSE cells[B1]),
renaming: (
SELECT type
FROM
1 => NIL,
2,3 => LIST[["Gnd", "Gnd"]],
4 => LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]],
ENDCASE => ERROR)
]];
ENDLOOP;
tileArray[row][uCodeAddrSize] ←
NEW[TilingClass.TileRec ← [
type: cells[C],
renaming: (
SELECT type
FROM
0 => LIST[["AAddr", aAddrWire[uCodeAddrSize-1]], ["Opcode", opcodeWire[uCodeAddrSize-1]], ["PreCondAddr", precondWire[2]], ["nClock", "nClock"], ["nUCodeMuxSel", nUCodeMuxSel], ["Vdd", "Vdd"], ["Gnd", "Gnd"]],
1,2,3,4 => LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]],
ENDCASE => ERROR)
]];
FOR i:
INT
IN [0..wMI)
DO
bitPos: BitPos ← NARROW[List.NthElement[order, i+1]];
ue: BOOLEAN ← TamarinUtil.RopeBitOnP[ueMI, bitPos.bitPos];
uo: BOOLEAN ← TamarinUtil.RopeBitOnP[uoMI, bitPos.bitPos];
de: BOOLEAN ← TamarinUtil.RopeBitOnP[deMI, bitPos.bitPos];
do: BOOLEAN ← TamarinUtil.RopeBitOnP[doMI, bitPos.bitPos];
IF bitPos.bitType=spacer
THEN
tileArray[row][1+uCodeAddrSize+i] ←
NEW[TilingClass.TileRec ← [
type: cells[E],
flatten: FALSE,
renaming: (
SELECT type
FROM
1,2,3 => LIST[["Gnd", "Gnd"]],
0,4=> LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]],
ENDCASE => ERROR) ]]
ELSE
tileArray[row][1+uCodeAddrSize+i] ←
NEW[TilingClass.TileRec ← [
type:
cells[romCellSelect[
BoolToInt[~ue, 8] + BoolToInt[~de, 4] + BoolToInt[~uo, 2] + BoolToInt[~do, 1]
]],
renaming: (
SELECT type
FROM
0 =>
(IF bitPos.bitType=latch
THEN
LIST[["MIL", miWire[bitPos.bitPos]], ["Vdd", "Vdd"], ["Gnd", "Gnd"]]
ELSE LIST[["MI", miWire[bitPos.bitPos]], ["Vdd", "Vdd"], ["Gnd", "Gnd"]]),
1,2,3 => LIST[["Gnd", "Gnd"]],
4 => LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]],
ENDCASE => ERROR) ]];
ENDLOOP;
tileArray[row][1+uCodeAddrSize+wMI] ←
NEW[TilingClass.TileRec ← [
type: cells[F],
renaming: (
SELECT type
FROM
0=> LIST[["AddrIn", bAddrWire[uCodeAddrSize-1]], ["UCodeSel", "UCodeSel"], ["nStall", "nStall"], ["Vdd", "Vdd"], ["Gnd", "Gnd"]],
1,2,3,4 => LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]],
ENDCASE => ERROR)
]];
FOR i:
NAT
IN [0..uCodeAddrSize-1)
DO
tileArray[row][i+2+uCodeAddrSize+wMI] ←
NEW[TilingClass.TileRec ← [
type: (IF TamarinUtil.BitOnP[bAddr, uCodeAddrSize-i-1] THEN cells[G0] ELSE cells[G1]),
renaming: (
SELECT type
FROM
0=> LIST[["AddrIn", bAddrWire[i]], ["Vdd", "Vdd"], ["Gnd", "Gnd"]],
1 => NIL,
2,3 => LIST[["Gnd", "Gnd"]],
4 => LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]],
ENDCASE => ERROR)
]];
ENDLOOP;
tileArray[row][1+uCodeAddrSize+wMI+uCodeAddrSize] ←
NEW[TilingClass.TileRec ← [
type: cells[H],
renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]]
]];
};
uCodeContents: LORA ← TamarinUtil.GetUCodeContents[];
line: NAT ← 0;
tapFreq: NAT ← 4;
dUC: Rope.ROPE ← NARROW[List.NthElement[uCodeContents, 1], TamarinUtil.UCodeWord].beMI;
nMI ← List.Length[uCodeContents];
wMI ← List.Length[uCodeOrder];
tileArray ← NEW[TilingClass.TileArrayRec[nMI+2+nMI/2/tapFreq]];
MakeUCodeRow[4, line, 0, 0, dUC, dUC, dUC, dUC, uCodeOrder];
line← 1;
FOR row:
NAT
IN [0..nMI/2)
DO
up: TamarinUtil.UCodeWord ← NARROW[List.NthElement[uCodeContents, row*2+2]];
dn: TamarinUtil.UCodeWord ← NARROW[List.NthElement[uCodeContents, row*2+1]];
IF row
MOD tapFreq = tapFreq/2
THEN {
MakeUCodeRow[1, line, 0, 0, dUC, dUC, dUC, dUC, uCodeOrder];
line ← line + 1 };
MakeUCodeRow[3, line, dn.aAddr, dn.bAddr, dn.beMI, dn.boMI, up.beMI, up.boMI, uCodeOrder];
MakeUCodeRow[2, line+1, up.aAddr, up.bAddr, dn.aeMI, dn.aoMI, up.aeMI, up.aoMI, uCodeOrder];
line ← line + 2;
ENDLOOP;
MakeUCodeRow[0, line, 0, 0, dUC, dUC, dUC, dUC, uCodeOrder];
TerminalIO.PutF["Creating UCodeRom: %g x %g", IO.int[nMI], IO.int[wMI]];
cellType ← TilingClass.CreateTiling[
name: "UCodeRom",
public: CoreCreate.WireList[LIST["Vdd", "Gnd", "nClock", "UCodeSel", "nStall", aAddrWire, bAddrWire, miWire, opcodeWire, precondWire, nUCodeMuxSel]],
public: CoreCreate.WireList[LIST["Vdd", "Gnd"]],
tileArray: tileArray,
neighborX: TilingClass.SchematicsNeighborX,
neighborY: TilingClass.SchematicsNeighborY
];
uCode ← tileArray;
uCell ← cellType;
};