Driver:
PROC
RETURNS [driver:
PW.ObPtr] =
BEGIN
listOb: PW.ListOb ← NIL;
regscdpd ← EmptyDescrRegsPD[];
regscdpu ← EmptyDescrRegsPU[];
-- ALU writes on sBus if not FOP or FOPK
PWDescr.SetBit[regscdpu, "nPhA", TRUE];
PWDescr.SetBit[regscdpu, "Vbias", TRUE];
PWDescr.SetBit[regscdpd, "PhB", TRUE];
PWDescr.SetInt[regscdpd, "EUAluOp2AB", 0, 8]; -- EUAluOp2AB#FOP or FOPK
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb];
driver ← EUtils.MakeTstDriver[design: design, in: "down", out: "bsOut", ctrlListOb: listOb];
END;
FnBlocksGen:
PROC
RETURNS [fnBlocks:
PW.ObPtr] =
BEGIN
wiresLeftAluFnBlock, wiresRightAluFnBlock, aluFnBlock, fnBlcksDP, ctrl: PW.ObPtr;
listOb: PW.ListOb ← NIL;
wiresLeftAluFnBlock ← PW.Get[design, "wiresLeftAluFnBlock"];
wiresRightAluFnBlock ← PW.Get[design, "wiresRightAluFnBlock"];
aluFnBlock ← PW.Get[design, "aluFnBlock"];
-- The function block: a pair -> one carry prop cell
fnBlcksDP ←
PW.ArrayX[design,
PW.AbutX[design,
PW.AbutY[design, aluFnBlock, wiresLeftAluFnBlock],
PW.AbutY[design, aluFnBlock, wiresRightAluFnBlock]],
EuGen.nbSlices/2];
-- Control
regscdpd ← EmptyDescrRegsPD[];
regscdpu ← EmptyDescrRegsPU[];
PWDescr.SetBit[regscdpu, "nPhA", TRUE];
PWDescr.SetBit[regscdpu, "Vbias", TRUE];
PWDescr.SetBit[regscdpd, "PhB", TRUE];
-- op2
PWDescr.SetInt[regscdpd, "EUAluOp2AB", 2, 2];
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb];
-- op1
PWDescr.SetInt[regscdpd, "EUAluOp2AB", 1, 1];
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu, TRUE], listOb];
-- op3
PWDescr.SetInt[regscdpd, "EUAluOp2AB", 4, 4];
listOb ← CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb];
ctrl ← PW.AbutListY[design, listOb];
fnBlocks ← EUtils.Assemble[design, ctrl, fnBlcksDP];
END;
CarryPropGen:
PROC
RETURNS [carryProp:
PW.ObPtr] =
BEGIN
CarryPropDPGen:
PROC
RETURNS [carryPropDP:
PW.ObPtr] =
BEGIN
carryZero, cpCtonC, cpnCtoC, routing: PW.ObPtr;
listOb: PW.ListOb ← NIL;
-- first is the position of the rightmost one in the binary representation of the index
-- next is the bit on the left of the rightmost one
Level:
PROC [index:
INT]
RETURNS [first:
INT, next:
BOOL] =
BEGIN
IF index<=0 THEN ERROR;
FOR i:
INT
IN [0..31)
DO
IF PW.XthBitOfN[i, index] THEN {first ← i; next ← PW.XthBitOfN[i+1, index]; EXIT};
ENDLOOP;
END;
carryZero ← PW.Get[design, "carryZero"];
cpCtonC ← PW.Get[design, "cpCtonC"];
cpnCtoC ← PW.Get[design, "cpnCtoC"];
-- The numeration starts at 1, and this is important
FOR index:
INT
IN [1..EuGen.nbSlices]
DO
RenamePins : PWPins.RenameProc =
{
SELECT
TRUE
FROM
Rope.Equal[oldRope, "g1"] OR Rope.Equal[oldRope, "p1"] OR Rope.Equal[oldRope, "c1"]
OR Rope.Equal[oldRope, "g0"]
OR Rope.Equal[oldRope, "p0"]
OR Rope.Equal[oldRope, "c0"] =>
newRope ← PWPins.Index[oldRope, index]; -- don't modify input pins
Rope.Equal[oldRope, "g"] =>
newRope ← PWPins.Index[IF next THEN "g1" ELSE "g0", fatherIndex];
Rope.Equal[oldRope, "p"] =>
newRope ← PWPins.Index[IF next THEN "p1" ELSE "p0", fatherIndex];
Rope.Equal[oldRope, "c"] =>
newRope ← PWPins.Index[IF next THEN "c1" ELSE "c0", fatherIndex];
ENDCASE => newRope ← oldRope;
};
first, fatherIndex: INT;
next: BOOL;
[first, next] ← Level[index];
fatherIndex ← IF next THEN index-PW.TwoToThe[first] ELSE index+PW.TwoToThe[first];
listOb ←
CONS[
PWPins.RenamePins[
design,
(SELECT
TRUE
FROM
index=EuGen.nbSlices => carryZero,
PW.ODD[index] => cpnCtoC,
ENDCASE => cpCtonC),
RenamePins],
listOb];
ENDLOOP;
carryPropDP ← PW.AbutListX[design, listOb];
routing ← EUtils.TreeRouter[design, carryPropDP, 270 ];
carryPropDP ← PW.AbutY[design, carryPropDP, routing];
END;
CarryPropCtrlGen:
PROC
RETURNS [ctrl:
PW.ObPtr] =
BEGIN
index: INT ← 1;
listOb: PW.ListOb ← NIL;
wire: PW.ObPtr;
regscdpd ← EmptyDescrRegsPD[];
regscdpu ← EmptyDescrRegsPU[];
-- Connect the 5 wires of EUAluOp2AB to the pads
FOR i:
INT
IN [0..5)
DO
RenameEUAluOp2AB: PWPins.RenameProc =
{
SELECT
TRUE
FROM
Rope.Equal[oldRope, "wireLeft"] => newRope ← PWPins.Index["EUAluOp2AB", i];
Rope.Equal[oldRope, "wireRight"] => newRope ← NIL;
ENDCASE => newRope ← oldRope};
PWDescr.SetInt[regscdpd, "EUAluOp2AB", index, index];
wire ← EuControl.RouteTo[design, regscdpd, regscdpu];
listOb ← CONS[PWPins.RenamePins[design, wire, RenameEUAluOp2AB], listOb];
index ← 2*index;
ENDLOOP;
-- Assemble all these wires
ctrl ← PW.AbutListY[design, listOb];
END;
carryProp ← EUtils.Assemble[design, CarryPropCtrlGen[], CarryPropDPGen[]];
END;