EuGenImplA:
CEDAR
PROGRAM
IMPORTS CMos, CDCells, EuControl, EUtils, PW, PWCmos, PWDescr, PWPins, Rope
EXPORTS EuGen =
BEGIN
OPEN EuGen;
-- Control descriptors
regscdpd: PWDescr.Descriptor;
regscdpu: PWDescr.Descriptor;
regsInitialised: BOOL ← FALSE;
EmptyDescrRamPD:
PUBLIC PROC
RETURNS [descr: PWDescr.Descriptor] =
BEGIN
descr ← PWDescr.RopesToDescr[LIST["PhA", "PhB", "nhold2BA", "nrejectBA", "DExecute", "DStateAddress", "aAdrHi", "aAdrLow", "bAdrHi", "bAdrLow", "cAdrHi", "cAdrLow", "spare4w", "spare1b"]];
PWDescr.SetTypeBit[descr, "PhA"];
PWDescr.SetTypeBit[descr, "PhB"];
PWDescr.SetTypeBit[descr, "nhold2BA"];
PWDescr.SetTypeBit[descr, "nrejectBA"];
PWDescr.SetTypeBit[descr, "DExecute"];
PWDescr.SetTypeInt[descr, "DStateAddress", 4];
PWDescr.SetTypeInt[descr, "aAdrHi", nbBitInRowDecoder];
PWDescr.SetTypeInt[descr, "aAdrLow", nbBitInColumnDecoder];
PWDescr.SetTypeInt[descr, "bAdrHi", nbBitInRowDecoder];
PWDescr.SetTypeInt[descr, "bAdrLow", nbBitInColumnDecoder];
PWDescr.SetTypeInt[descr, "cAdrHi", nbBitInRowDecoder];
PWDescr.SetTypeInt[descr, "cAdrLow", nbBitInColumnDecoder];
PWDescr.SetTypeInt[descr, "spare4w", 4];
PWDescr.SetTypeBit[descr, "spare1b"];
END;
InitDescrRamPD:
PUBLIC PROC
RETURNS [descr: PWDescr.Descriptor] =
BEGIN
descr ← EmptyDescrRamPD[];
PWDescr.SetBit[descr, "PhA", TRUE];
END;
EmptyDescrRamPU:
PUBLIC PROC
RETURNS [descr: PWDescr.Descriptor] =
BEGIN
descr ← PWDescr.RopesToDescr[LIST["nPhA", "nPhB", "Vbias"]];
PWDescr.SetTypeBit[descr, "nPhA"];
PWDescr.SetTypeBit[descr, "nPhB"];
PWDescr.SetTypeBit[descr, "Vbias"];
END;
InitDescrRamPU:
PUBLIC PROC
RETURNS [descr: PWDescr.Descriptor] =
BEGIN
descr ← EmptyDescrRamPU[];
PWDescr.SetTypeBit[descr, "nPhA", FALSE];
PWDescr.SetTypeBit[descr, "nPhB", TRUE];
PWDescr.SetTypeBit[descr, "Vbias", TRUE];
END;
EmptyDescrRegsPD:
PUBLIC
PROC
RETURNS [descr: PWDescr.Descriptor] =
BEGIN
descr ← PWDescr.RopesToDescr[LIST["PhA", "PhB", "nhold2BA", "nrejectBA", "DExecute", "DStateAddress", "EUAluLeftSrc1BA", "EUAluRightSrc1BA", "EUStore2ASrc1BA", "EUSt3AisCBus2BA", "EURes3AisCBus2BA", "FDInsert", "FDMask", "FDShift", "EUAluOp2AB", "EULoadField3BA", "EUWriteToPBus3AB", "EURes3BisPBus3AB"]];
PWDescr.SetTypeBit[descr, "PhA"];
PWDescr.SetTypeBit[descr, "PhB"];
PWDescr.SetTypeBit[descr, "nhold2BA"];
PWDescr.SetTypeBit[descr, "nrejectBA"];
PWDescr.SetTypeBit[descr, "DExecute"];
PWDescr.SetTypeInt[descr, "DStateAddress", 4];
PWDescr.SetTypeInt[descr, "EUAluLeftSrc1BA", 2];
PWDescr.SetTypeInt[descr, "EUAluRightSrc1BA", 2];
PWDescr.SetTypeInt[descr, "EUStore2ASrc1BA", 2];
PWDescr.SetTypeBool[descr, "EUSt3AisCBus2BA"];
PWDescr.SetTypeBool[descr, "EURes3AisCBus2BA"];
PWDescr.SetTypeBool[descr, "FDInsert"];
PWDescr.SetTypeInt[descr, "FDMask", 6];
PWDescr.SetTypeInt[descr, "FDShift", 6];
PWDescr.SetTypeInt[descr, "EUAluOp2AB", 5];
PWDescr.SetTypeBit[descr, "EULoadField3BA"];
PWDescr.SetTypeBool[descr, "EUWriteToPBus3AB"];
PWDescr.SetTypeBool[descr, "EURes3BisPBus3AB"];
END;
EmptyDescrRegsPU:
PUBLIC
PROC
RETURNS [descr: PWDescr.Descriptor] =
BEGIN
descr ← PWDescr.RopesToDescr[LIST["nPhA", "nPhB", "Vbias"]];
PWDescr.SetTypeBit[descr, "nPhA"];
PWDescr.SetTypeBit[descr, "nPhB"];
PWDescr.SetTypeBit[descr, "Vbias"];
END;
-- And now the pipeline registers
PipeLineRegsGen:
PUBLIC
PROC [design:
CD.Design]
RETURNS [pipe:
PW.ObPtr] =
BEGIN
leftOp2AB, rightOp2AB, store2AB, store2BA, store3AB: PW.ObPtr;
LeftOp2ABGen:
PROC
RETURNS [leftOp2AB:
PW.ObPtr] =
BEGIN
regD: EUtils.RegDescr;
listOb: PW.ListOb ← NIL; -- remember that AbutY builds UP
PWDescr.SetInt[regscdpd, "EUAluLeftSrc1BA", 0]; -- aBus
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu, TRUE], listOb];
PWDescr.SetInt[regscdpd, "EUAluLeftSrc1BA", 1]; -- rBus
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb];
PWDescr.SetInt[regscdpd, "EUAluLeftSrc1BA", 2]; -- cBus
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu, TRUE], listOb];
PWDescr.SetInt[regscdpd, "EUAluLeftSrc1BA", 0, 0]; -- clean-up
regD ← NEW[EUtils.RegDescrRec ← [inListOb: LIST["ap", "r", "c"], out: "opL", ctrlListOb: listOb]];
leftOp2AB ← EUtils.MakeRegWithDBus[design, regD, lOp2AB];
END;
RightOp2ABGen:
PROC
RETURNS [rightOp2AB:
PW.ObPtr] =
BEGIN
regD: EUtils.RegDescr;
listOb: PW.ListOb ← NIL;
PWDescr.SetInt[regscdpd, "EUAluRightSrc1BA", 0]; -- bBus
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb];
PWDescr.SetInt[regscdpd, "EUAluRightSrc1BA", 1]; -- rBus
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu, TRUE], listOb];
PWDescr.SetInt[regscdpd, "EUAluRightSrc1BA", 2]; -- cBus
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb];
PWDescr.SetInt[regscdpd, "EUAluRightSrc1BA", 3]; -- kBus
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu, TRUE], listOb];
PWDescr.SetInt[regscdpd, "EUAluRightSrc1BA", 0, 0]; -- clean-up
regD ← NEW[EUtils.RegDescrRec ← [inListOb: LIST["bs", "r", "c", "k"], out: "opR", ctrlListOb: listOb]];
rightOp2AB ← EUtils.MakeRegWithDBus[design, regD, rOp2AB];
END;
Store2ABGen:
PROC
RETURNS [store2AB:
PW.ObPtr] =
BEGIN
regD: EUtils.RegDescr;
listOb: PW.ListOb ← NIL;
PWDescr.SetInt[regscdpd, "EUStore2ASrc1BA", 0]; -- bBus
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu, TRUE], listOb];
PWDescr.SetInt[regscdpd, "EUStore2ASrc1BA", 1]; -- rBus
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb];
PWDescr.SetInt[regscdpd, "EUStore2ASrc1BA", 2]; -- cBus
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu, TRUE], listOb];
PWDescr.SetInt[regscdpd, "EUStore2ASrc1BA", 0, 0]; -- clean-up
regD ←
NEW[EUtils.RegDescrRec ← [
inListOb: LIST["bs", "r", "c"],
out: "down",
ctrlListOb: listOb,
interruptBuses: LIST["apBus", "bsBus"]]];
store2AB ← EUtils.MakeRegWithDBus[design, regD, st2AB];
store2AB ← EUtils.MakeReg[design, regD];
END;
Store2BAGen:
PROC
RETURNS [store2BA:
PW.ObPtr] =
BEGIN
regD: EUtils.RegDescr;
listOb: PW.ListOb ← NIL;
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb]; -- no control
regD ← NEW[EUtils.RegDescrRec ← [inListOb: LIST["top"], out: "down", ctrlListOb: listOb, cutTopBot: TRUE]];
store2BA ← EUtils.MakeReg[design, regD ];
END;
Store3ABGen:
PROC
RETURNS [store3AB:
PW.ObPtr] =
BEGIN
regD: EUtils.RegDescr;
listOb: PW.ListOb ← NIL;
PWDescr.SetBool[regscdpd, "EUSt3AisCBus2BA", TRUE]; -- cBus
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb];
PWDescr.SetBool[regscdpd, "EUSt3AisCBus2BA", FALSE]; -- store2BA
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu, TRUE], listOb];
PWDescr.SetBool[regscdpd, "EUSt3AisCBus2BA", FALSE, FALSE]; -- clean-up
regD ←
NEW[EUtils.RegDescrRec ← [
inListOb: LIST["top", "c"],
out: "ap",
ctrlListOb: listOb,
interruptBuses: LIST["downBus"]]];
store3AB ← EUtils.MakeRegWithDBus[design, regD, st3AB];
END;
PW.Output["The top pipeline registers", "\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];
-- PhA latches
leftOp2AB ← LeftOp2ABGen[];
rightOp2AB ← RightOp2ABGen[];
store2AB ← Store2ABGen[];
store3AB ← Store3ABGen[];
-- PhB latches
regscdpd ← EmptyDescrRegsPD[];
regscdpu ← EmptyDescrRegsPU[];
PWDescr.SetBit[regscdpu, "nPhA", TRUE];
PWDescr.SetBit[regscdpu, "Vbias", TRUE];
PWDescr.SetBit[regscdpd, "PhB", TRUE];
PWDescr.SetBit[regscdpd, "nhold2BA", TRUE]; -- really???
store2BA ← Store2BAGen[];
pipe ←
PW.AbutY[design,
store3AB,
store2BA,
store2AB,
rightOp2AB,
leftOp2AB];
PW.RenameObject[design, pipe, "pipelineRegisters"];
END;
ResultRegsGen:
PUBLIC PROC [design:
CD.Design]
RETURNS [resultRegs:
PW.ObPtr] =
BEGIN
result2BA, result3AB, result3BA, dataDriver, addrDriver: PW.ObPtr;
Result2BAGen:
PROC
RETURNS [result2BA:
PW.ObPtr] =
BEGIN
regD: EUtils.RegDescr;
listOb: PW.ListOb ← NIL;
-- no special control
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb];
regD ←
NEW[EUtils.RegDescrRec ← [
inListOb: LIST["bs"],
out: "r",
ctrlListOb: listOb,
interruptBuses: LIST["opLBus", "opRBus", "downBus"]]];
result2BA ← EUtils.MakeRegWithDBus[design, regD, r2BA];
END;
Result3ABGen:
PROC
RETURNS [result3AB:
PW.ObPtr] =
BEGIN
regD: EUtils.RegDescr;
listOb: PW.ListOb ← NIL;
PWDescr.SetBool[regscdpd, "EURes3AisCBus2BA", FALSE]; -- rBus
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu, TRUE], listOb];
PWDescr.SetBool[regscdpd, "EURes3AisCBus2BA", TRUE]; -- cBus
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb];
PWDescr.SetBool[regscdpd, "EURes3AisCBus2BA", FALSE, FALSE]; -- clean-up
regD ←
NEW[EUtils.RegDescrRec ← [
inListOb: LIST["r", "c"],
out: "opL",
ctrlListOb: listOb]];
result3AB ← EUtils.MakeRegWithDBus[design, regD, r3AB];
END;
Result3BAGen:
PROC
RETURNS [result3BA:
PW.ObPtr] =
BEGIN
regD: EUtils.RegDescr;
listOb: PW.ListOb ← NIL;
PWDescr.SetBool[regscdpd, "EURes3BisPBus3AB", FALSE]; -- from result3AB (opL)
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu, TRUE], listOb];
PWDescr.SetBool[regscdpd, "EURes3BisPBus3AB", TRUE]; -- pPort (opR)
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb];
PWDescr.SetBool[regscdpd, "EURes3BisPBus3AB", FALSE, FALSE]; -- clean-up
regD ←
NEW[EUtils.RegDescrRec ← [
inListOb: LIST["opL", "top"],
out: "c",
ctrlListOb: listOb]];
result3BA ← EUtils.MakeRegWithDBus[design, regD, r3BA];
END;
BottomGen:
PROC
RETURNS [bottom:
PW.ObPtr] =
BEGIN
BottomCtrlGen:
PROC
RETURNS [bottomCtrl:
PW.ObPtr] =
BEGIN
index: INT ← 1;
GndProc: PW.SelectNamesProc = {keepIt ← Rope.Equal[name, "gnd"]};
RenameEULoadField3BA: PWPins.RenameProc =
{
SELECT
TRUE
FROM
Rope.Equal[oldRope, "wireLeft"] => newRope ← "EULoadField3BA";
Rope.Equal[oldRope, "wireRight"] => newRope ← NIL;
ENDCASE => newRope ← oldRope};
RenameNRejectBA: PWPins.RenameProc =
{
SELECT
TRUE
FROM
Rope.Equal[oldRope, "wireLeft"] => newRope ← "nrejectBA";
Rope.Equal[oldRope, "wireRight"] => newRope ← NIL;
ENDCASE => newRope ← oldRope};
RenameNHold2BA: PWPins.RenameProc =
{
SELECT
TRUE
FROM
Rope.Equal[oldRope, "wireLeft"] => newRope ← "nhold2BA";
Rope.Equal[oldRope, "wireRight"] => newRope ← NIL;
ENDCASE => newRope ← oldRope};
RenameEURes3BisPBus3AB: PWPins.RenameProc =
{
SELECT
TRUE
FROM
Rope.Equal[oldRope, "wireLeft"] => newRope ← "EURes3BisPBus3AB";
Rope.Equal[oldRope, "wireRight"] => newRope ← NIL;
ENDCASE => newRope ← oldRope};
RenameEUWriteToPBus3AB: PWPins.RenameProc =
{
SELECT
TRUE
FROM
Rope.Equal[oldRope, "wireLeft"] => newRope ← "EUWriteToPBus3AB";
Rope.Equal[oldRope, "wireRight"] => newRope ← NIL;
ENDCASE => newRope ← oldRope};
RenameDExecute: PWPins.RenameProc =
{
SELECT
TRUE
FROM
Rope.Equal[oldRope, "wireLeft"] => newRope ← "DExecute";
Rope.Equal[oldRope, "wireRight"] => newRope ← NIL;
ENDCASE => newRope ← oldRope};
listOb: PW.ListOb ← NIL;
gndConnect, gndRect, wires, wire: PW.ObPtr;
size: CD.Position;
-- wires: connect all leftover wires
regscdpd ← EmptyDescrRegsPD[];
regscdpu ← EmptyDescrRegsPU[];
-- EULoadField3BA
PWDescr.SetBit[regscdpd, "EULoadField3BA", TRUE];
wire ← EuControl.RouteTo[design, regscdpd, regscdpu];
listOb ← CONS[PWPins.RenamePins[design, wire, RenameEULoadField3BA], listOb];
PWDescr.SetBit[regscdpd, "EULoadField3BA", FALSE];
-- nrejectBA
PWDescr.SetBit[regscdpd, "nrejectBA", TRUE];
wire ← EuControl.RouteTo[design, regscdpd, regscdpu];
PWDescr.SetBit[regscdpd, "nrejectBA", FALSE];
listOb ← CONS[PWPins.RenamePins[design, wire, RenameNRejectBA], listOb];
-- nhold2BA
PWDescr.SetBit[regscdpd, "nhold2BA", TRUE];
wire ← EuControl.RouteTo[design, regscdpd, regscdpu];
PWDescr.SetBit[regscdpd, "nhold2BA", FALSE];
listOb ← CONS[PWPins.RenamePins[design, wire, RenameNHold2BA], listOb];
-- EURes3BisPBus3AB
PWDescr.SetBool[regscdpd, "EURes3BisPBus3AB", TRUE];
wire ← EuControl.RouteTo[design, regscdpd, regscdpu];
PWDescr.SetBool[regscdpd, "EURes3BisPBus3AB", FALSE, FALSE];
listOb ← CONS[PWPins.RenamePins[design, wire, RenameEURes3BisPBus3AB], listOb];
-- EUWriteToPBus3AB
PWDescr.SetBool[regscdpd, "EUWriteToPBus3AB", TRUE];
wire ← EuControl.RouteTo[design, regscdpd, regscdpu];
PWDescr.SetBool[regscdpd, "EUWriteToPBus3AB", FALSE, FALSE]; -- clean-up
listOb ← CONS[PWPins.RenamePins[design, wire, RenameEUWriteToPBus3AB], listOb];
-- DExecute
PWDescr.SetBit[regscdpd, "DExecute", TRUE];
wire ← EuControl.RouteTo[design, regscdpd, regscdpu];
PWDescr.SetBit[regscdpd, "DExecute", FALSE];
listOb ← CONS[PWPins.RenamePins[design, wire, RenameDExecute], listOb];
-- DStateAddress
FOR i:
INT
IN [0..4)
DO
RenameDStateAddress: PWPins.RenameProc =
{
SELECT
TRUE
FROM
Rope.Equal[oldRope, "wireLeft"] => newRope ← PWPins.Index["DStateAddress", i];
Rope.Equal[oldRope, "wireRight"] => newRope ← NIL;
ENDCASE => newRope ← oldRope};
PWDescr.SetInt[regscdpd, "DStateAddress", index, index];
wire ← EuControl.RouteTo[design, regscdpd, regscdpu];
listOb ← CONS[PWPins.RenamePins[design, wire, RenameDStateAddress], listOb];
index ← 2*index;
ENDLOOP;
PWDescr.SetInt[regscdpd, "DStateAddress", 0, 0];
-- Assemble all these wires
wires ← PW.AbutListY[design, listOb];
-- Now the m2 comb
gndConnect ← EUtils.CtrlFiller[design, wires, bottomDataPath, GndProc];
size ← PW.Size[gndConnect];
gndRect ← PWCmos.Rect[CMos.met2, [size.x, size.y-10*l]]; -- hack!!!
PW.IncludeInCell[design, gndConnect, gndRect, [0, 0]];
[] ← CDCells.RepositionCell[gndConnect, design];
bottomCtrl ← PW.AbutY[design, gndConnect, wires];
END;
bottomDataPath, botDP: PW.ObPtr;
listOb: PW.ListOb ← NIL;
bottomDataPath ← PW.Get[design, "bottomDataPath"];
FOR i:
INT
IN [0..nbSlices)
DO
RenameEPData: PWPins.RenameProc =
{
SELECT
TRUE FROM
Rope.Equal[oldRope, "EPData"] => newRope ← PWPins.Index[oldRope, nbSlices-i-1];
ENDCASE => newRope ← oldRope;};
listOb ← CONS[PWPins.RenamePins[design, bottomDataPath, RenameEPData], listOb];
ENDLOOP;
botDP ← PW.AbutListX[design, listOb];
bottom ← EUtils.Assemble[design, BottomCtrlGen[], botDP,, Bottom];
END;
AddrDriverGen:
PROC
RETURNS [addrDriver:
PW.ObPtr] =
BEGIN
listOb: PW.ListOb ← NIL;
-- Cache access: address, always on PhA
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb];
addrDriver ← EUtils.MakeTstDriver[design: design, in: "r", out: "downOut", ctrlListOb: listOb];
END;
DataDriverGen:
PROC
RETURNS [dataDriver:
PW.ObPtr] =
BEGIN
listOb: PW.ListOb ← NIL;
-- Cache access: data
PWDescr.SetBool[regscdpd, "EUWriteToPBus3AB", TRUE];
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu, TRUE], listOb];
PWDescr.SetBool[regscdpd, "EUWriteToPBus3AB", FALSE, FALSE]; -- clean-up
dataDriver ← EUtils.MakeTstDriver[design: design, in: "ap", out: "downOut", ctrlListOb: listOb];
END;
PW.Output["The bottom pipeline registers", "\n"];
regscdpd ← EmptyDescrRegsPD[];
regscdpu ← EmptyDescrRegsPU[];
-- PhA latch
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];
result3AB ← Result3ABGen[];
addrDriver ← AddrDriverGen[];
-- PhB latches
regscdpd ← EmptyDescrRegsPD[];
regscdpu ← EmptyDescrRegsPU[];
PWDescr.SetBit[regscdpu, "nPhA", TRUE];
PWDescr.SetBit[regscdpu, "Vbias", TRUE];
PWDescr.SetBit[regscdpd, "PhB", TRUE];
PWDescr.SetBit[regscdpd, "nhold2BA", TRUE]; -- really???
result2BA ← Result2BAGen[];
result3BA ← Result3BAGen[];
dataDriver ← DataDriverGen[];
resultRegs ←
PW.AbutY[design,
BottomGen[],
dataDriver,
addrDriver,
result3BA,
result3AB,
result2BA];
PW.RenameObject[design, resultRegs, "resultRegisters"];
END;
END.