EuGenImplC.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Last Edited by: Monier, July 8, 1985 3:59:12 pm PDT
DIRECTORY
CD, CDCells, CDPinObjects, CMos, Convert, EuControl, EuGen, EUtils, PW, PWCmos, PWDescr, PWPins, Rope;
EuGenImplC: CEDAR PROGRAM
IMPORTS EuControl, EuGen, EUtils, PW, PWDescr, PWPins, Rope
EXPORTS EuGen =
BEGIN
OPEN EuGen;
-- Control descriptors
regscdpd: PWDescr.Descriptor;
regscdpu: PWDescr.Descriptor;
-- Here starts the layout of the ALU
ALUGen: PUBLIC PROC [design: CD.Design] RETURNS [alu: PW.ObPtr] =
BEGIN
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;
PW.Output["The ALU and its carry propagator", "\n"];
alu ← PW.AbutY[design, Driver[], FnBlocksGen[], CarryPropGen[]];
END;
END.