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; regscdpd: PWDescr.Descriptor; regscdpu: PWDescr.Descriptor; 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[]; 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"]; fnBlcksDP _ PW.ArrayX[design, PW.AbutX[design, PW.AbutY[design, aluFnBlock, wiresLeftAluFnBlock], PW.AbutY[design, aluFnBlock, wiresRightAluFnBlock]], EuGen.nbSlices/2]; regscdpd _ EmptyDescrRegsPD[]; regscdpu _ EmptyDescrRegsPU[]; PWDescr.SetBit[regscdpu, "nPhA", TRUE]; PWDescr.SetBit[regscdpu, "Vbias", TRUE]; PWDescr.SetBit[regscdpd, "PhB", TRUE]; PWDescr.SetInt[regscdpd, "EUAluOp2AB", 2, 2]; listOb _ CONS[EuControl.Nand[design, regscdpd, regscdpu], listOb]; PWDescr.SetInt[regscdpd, "EUAluOp2AB", 1, 1]; listOb _ CONS[EuControl.Nand[design, regscdpd, regscdpu, TRUE], listOb]; 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; 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"]; 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[]; 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; 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. REuGenImplC.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Last Edited by: Monier, July 8, 1985 3:59:12 pm PDT -- Control descriptors -- Here starts the layout of the ALU -- ALU writes on sBus if not FOP or FOPK -- The function block: a pair -> one carry prop cell -- Control -- op2 -- op1 -- op3 -- 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 -- The numeration starts at 1, and this is important -- Connect the 5 wires of EUAluOp2AB to the pads -- Assemble all these wires Κ6˜– "Cedar" stylešœ™Jšœ Οmœ1™Jšœ žœ˜*J™4šœ žœ˜šžœ˜Jšžœ0˜2Jšžœ2˜4—Jšœ˜—J™ Jšœ˜Jšœ˜Jšœ!žœ˜'Jšœ"žœ˜(Jšœ žœ˜&J™J™Jšœ-˜-Jšœ žœ5˜BJ™Jšœ-˜-Jšœ žœ,žœ ˜HJ™Jšœ-˜-Jšœ žœ5˜BJšœžœ˜$Jšœ4˜4Jšžœ˜—šŸ œžœžœ žœ ˜3Jšž˜šŸœžœžœžœ ˜7Jšž˜Jšœ&žœ˜/Jšœžœ žœ˜J™WJ™3š Ÿœžœ žœžœ žœžœ˜