DIRECTORY Boole, BooleCore, CDSimpleRules, CoreCreate, CoreOps, CoreProperties, Dragon, EUControlAlps, EULeafUtils, EUUtils, LayoutCheckpoint, PWCore, PWCoreRoute, PWRoute, Rope, RopeList; EUControlAlpsImpl: CEDAR PROGRAM IMPORTS Boole, BooleCore, CDSimpleRules, CoreCreate, CoreOps, CoreProperties, EULeafUtils, EUUtils, LayoutCheckpoint, PWCore, Rope, RopeList EXPORTS EUControlAlps = BEGIN OPEN Boole, BooleCore, CoreCreate, EUControlAlps--, EUUtils--; ExprProc: TYPE ~ PROC [i: NAT _ 0] RETURNS [Expression]; AppendInput: PROC [public: Wire, wr: WR, inputD: Inputs] RETURNS [ins: Inputs]~ { AppendOneInput: PROC [wire: Wire] ~ {ins _ CONS[[input: wire, driver: inv], ins]}; inv: CellType _ EULeafUtils.AlpsExtract["InputDriver.sch"]; ins _ inputD; CoreOps.VisitAtomicWires[FindWire[public, wr], AppendOneInput]; }; AppendOutput: PROC [wire: WR, expr: Expression, clock: ROPE _ NIL, outputDrivers: Outputs] RETURNS [Outputs] ~ { out: CellType _ EULeafUtils.AlpsExtract[IF clock=NIL THEN "OutputDriver.sch" ELSE "ClockedOutputDriver.sch"]; RETURN [CONS[ [driver: out, pas: IF clock=NIL THEN LIST[["VRef", "VRef"]] ELSE LIST[["Clock", clock], ["VRef", "VRef"]], output: wire, expr: expr], outputDrivers]]; }; AppendState: PROC [wire: WR, expr: Expression, clock: ROPE, outputDrivers: Outputs] RETURNS [Outputs] ~ { out: CellType _ EULeafUtils.AlpsExtract["StateOutputDriver.sch"]; IF clock=NIL THEN ERROR; -- need a clock to latch the state RETURN [CONS[ [driver: out, pas: LIST[["Latch", clock], ["VRef", "VRef"]], output: wire, expr: expr], outputDrivers]]; }; -- To be generated by Alps (Ave, Serlet, programatori te salutant!) CreateRamControl: PUBLIC PROC RETURNS [cellType: CellType] = { IF EUUtils.useRamControlCheckpoint THEN RETURN [LayoutCheckpoint.Retrieve["RamControl"]]; BEGIN inputDrivers: Inputs _ NIL; outputDrivers: Outputs _ NIL; expr: Expression _ NIL; public: Wire _ Union[ EUUtils.GenPGnEWires[], -- Vdd and Gnd EUUtils.GenWiresCtrlToRam[], -- all Select lines, nPrech, dRamRead EUUtils.GenWiresRamToCtrl[], -- ramAdr WireList[LIST["reject", "hold", "read", "write", Seq["dStateAd", 4], "enWrtIFUPhA", "enWrtIFUPhB", "phA", "nPhB", "VRef", EUUtils.GenRegSelWire[EUUtils.field], -- selFieldSrc[0..2) ]]]; dStateAd: Wire _ FindWire[public, "dStateAd"]; ramAdr: Wire _ FindWire[public, "ramAdr"]; aHi: Wire _ ramAdr[0][0]; bHi: Wire _ ramAdr[1][0]; cHi: Wire _ ramAdr[2][0]; aLow: Wire _ ramAdr[0][1]; bLow: Wire _ ramAdr[1][1]; cLow: Wire _ ramAdr[2][1]; cAdr: Wire _ ramAdr[2]; read: Variable _ FindWire[public, "read"]; write: Variable _ FindWire[public, "write"]; reject: Variable _ FindWire[public, "reject"]; nReject: Expression _ Not[reject]; hold: Variable _ FindWire[public, "hold"]; nHold: Expression _ Not[hold]; AppendRamDriver: PROC [output: WR, expr: Expression] ~ { outputDrivers _ AppendOutput[output , expr, "phA", outputDrivers]; }; IF aLow.size#2 OR bLow.size#2 OR cLow.size#2 THEN ERROR; IF aHi.size#6 OR bHi.size#6 OR cHi.size#6 THEN ERROR; inputDrivers _ AppendInput[public, "reject", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "hold", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "read", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "write", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "dStateAd", inputDrivers]; -- 4 inputDrivers _ AppendInput[public, ramAdr, inputDrivers]; -- 24 outputDrivers _ AppendOutput["enWrtIFUPhA", EqualInt[cAdr, EUUtils.IFUAdr], NIL, outputDrivers]; outputDrivers _ AppendOutput["enWrtIFUPhB", false, NIL, outputDrivers]; outputDrivers _ AppendOutput["nPrech", true, "nPhB", outputDrivers]; FOR i: INT IN [0..EUUtils.nRows) DO AppendRamDriver[Index["selA", i], EqualInt[aHi, i]]; AppendRamDriver[Index["selB", i], EqualInt[bHi, i]]; expr _ IF i=EUUtils.marAdr/4 THEN Or[reject, EqualInt[cHi, i]] ELSE And[nReject, EqualInt[cHi, i]]; AppendRamDriver[Index["selC", i], expr]; ENDLOOP; FOR i: INT IN [0..EUUtils.sizeSelLow) DO AppendRamDriver[Index["selALow", i], EqualInt[aLow, i]]; AppendRamDriver[Index["selBLow", i], EqualInt[bLow, i]]; expr _ IF i=EUUtils.marAdr MOD 4 THEN Or[reject, EqualInt[cLow, i]] ELSE And[nReject, EqualInt[cLow, i]]; AppendRamDriver[Index["selCLow", i], expr]; ENDLOOP; outputDrivers _ AppendOutput["selFieldSrc[0]", And[nReject, nHold, EqualInt[cAdr, EUUtils.fieldAdr]], "phA", outputDrivers]; outputDrivers _ AppendOutput["selFieldSrc[1]", And[write, EqualInt[dStateAd, EUUtils.field]], NIL, outputDrivers]; outputDrivers _ AppendOutput["selFieldSrc[2]", And[read, EqualInt[dStateAd, EUUtils.field]], NIL, outputDrivers]; outputDrivers _ AppendOutput["dRamRead", And[read, EqualInt[dStateAd, EUUtils.ramA]], NIL, outputDrivers]; cellType _ AlpsCell[ name: "RamControl", public: public, inputs: inputDrivers, outputs: outputDrivers, props: CoreProperties.Props[[$ContactPolyMetal2, NEW[INT _ 20]]] ]; END; }; GndAndVdd10Met2MinWidth: PUBLIC PWRoute.WireWidthProc = { wireWidth _ CDSimpleRules.MinWidth[CDSimpleRules.GetLayer[$cmosB, "metal2"]] *(IF Rope.Equal[netName, "Vdd"] OR Rope.Equal[netName, "Gnd"] THEN 10 ELSE 1); }; CreateBothAlps: PUBLIC PROC RETURNS [cellType: CellType] ~ { ctrlTop: CellType _ CreateCondControl[]; ctrlBot: CellType _ CreateDPControl[]; public: Wire _ Union[ CopyAndDeleteNames[ctrlTop.public, LIST["Vdd", "Gnd", "VRef", "phB", "res0", "carryOut", "lz", "kernal", "il"]], CopyAndDeleteNames[ctrlBot.public] ]; Vdd: Wire _ FindWire[public, "Vdd"]; Gnd: Wire _ FindWire[public, "Gnd"]; condSel: Wire _ FindWire[public, "condSel"]; reject: Wire _ FindWire[public, "reject"]; hold: Wire _ FindWire[public, "hold"]; read: Wire _ FindWire[public, "read"]; write: Wire _ FindWire[public, "write"]; res3BisP: Wire _ FindWire[public, "res3BisP"]; writePBus: Wire _ FindWire[public, "writePBus"]; aluOp: Wire _ FindWire[public, "aluOp"]; dStateAd: Wire _ FindWire[public, "dStateAd"]; il: Wire _ FindWire[public, "il"]; lz: Wire _ FindWire[public, "lz"]; kernal: Wire _ FindWire[public, "kernal"]; zero: Wire _ FindWire[public, "zero"]; ctrl8: Wire _ FindWire[public, "ctrl8"]; opL: Wire _ FindWire[public, "opL"]; opR: Wire _ FindWire[public, "opR"]; res: Wire _ FindWire[public, "res"]; carryOut: Wire _ FindWire[public, "carryOut"]; shift: Wire _ FindWire[public, "shift"]; carryABIn: Wire _ FindWire[public, "carryABIn"]; carryBAIn: Wire _ FindWire[public, "carryBAIn"]; conditionIn: Wire _ FindWire[public, "conditionIn"]; channelData: PWCoreRoute.ChannelData _ NEW[PWCoreRoute.ChannelDataRec _ [ inX: FALSE, bottomOrLeftWires: LIST[Vdd, Gnd, condSel, reject, res3BisP, writePBus, aluOp], topOrRightWires: LIST[hold, read, write, dStateAd, il, lz, kernal, zero, ctrl8, opL, opR, res, carryOut, shift, carryABIn, carryBAIn, conditionIn], trunkLayer: "metal", branchLayer: "metal2", extendTopOrRight: FALSE, extend: TRUE, wireWidthProc: GndAndVdd10Met2MinWidth ]]; cellType _ Cell[ name: "BothAlps", public: public, instances: LIST [ Instance[name: "BottomAlps", type: PWCore.RotateCellType[ctrlBot, $FlipY]], Instance[name: "TopAlps", type: ctrlTop, pa1: ["res0", "res[0]"]] ] ]; PWCore.SetLayout[cellType, $Channel, $ChannelData, channelData]; }; CreateCondControl: PUBLIC PROC RETURNS [cellType: CellType] ~ { CondIs: PROC [cond: Dragon.CondSelects] RETURNS [expr: Expression] ~ { expr _ EqualInt[condSel, Dragon.CondSelects[cond].ORD]; }; public: Wire _ Wires["Vdd", "Gnd", "phB", "condition", "VRef", Seq["condSel", EUUtils.sizeCondSelects], -- from pads "zero", "carryOut", "res0", -- from data path "kernal", "lz", "il"]; -- output of DPControl alps block condSel: Wire _ FindWire[public, "condSel"]; zero: Variable _ FindWire[public, "zero"]; lz: Variable _ FindWire[public, "lz"]; le: Expression _ Or[lz, zero]; kernal: Variable _ FindWire[public, "kernal"]; res0: Variable _ FindWire[public, "res0"]; overflow: Expression _ Xor[lz, res0]; carryOut: Variable _ FindWire[public, "carryOut"]; il: Variable _ FindWire[public, "il"]; cond: Expression _ OrList[LIST[ And[CondIs[EZ], zero], And[CondIs[LZ], lz], And[CondIs[LE], le], And[CondIs[NE], Not[zero]], And[CondIs[GE], Not[lz]], And[CondIs[GZ], Not[le]], And[CondIs[OvFl], overflow], And[CondIs[BC], Not[carryOut]], And[CondIs[IL], il], And[CondIs[NotBC], carryOut], And[CondIs[NotIL], Not[il]], And[CondIs[ModeFault], true] ]]; inputDrivers: Inputs _ NIL; outputDrivers: Outputs _ NIL; inputDrivers _ AppendInput[public, "condSel", inputDrivers]; -- 4 inputDrivers _ AppendInput[public, "zero", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "carryOut", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "res0", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "kernal", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "lz", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "il", inputDrivers]; -- 1 outputDrivers _ AppendState["condition", cond, "phB", outputDrivers]; cellType _ AlpsCell[ name: "CondControl", public: public, inputs: inputDrivers, outputs: outputDrivers ]; }; CreateDPControl: PUBLIC PROC RETURNS [cellType: CellType] = { IF EUUtils.useDPControlCheckpoint THEN RETURN [LayoutCheckpoint.Retrieve["DPControl"]]; BEGIN MakeSelExpr: PROC [reg: EUUtils.PipeRange, exprProc: ExprProc, clock: ROPE _ NIL] ~ { size: NAT _ EUUtils.sources[reg].sizeSel; FOR i: INT IN [0..size) DO outputDrivers _ AppendOutput[ wire: Index[EUUtils.sources[reg].nameSel, i], expr: exprProc[i], clock: clock, outputDrivers: outputDrivers]; ENDLOOP; outputDrivers _ AppendOutput[ wire: Index[EUUtils.sources[reg].nameSel, size], expr: And[write, EqualInt[dStateAd, reg]], clock: NIL, outputDrivers: outputDrivers]; outputDrivers _ AppendOutput[ wire: Index[EUUtils.sources[reg].nameSel, size+1], expr: And[read, EqualInt[dStateAd, reg]], clock: NIL, outputDrivers: outputDrivers]; }; inputDrivers: Inputs _ NIL; outputDrivers: Outputs _ NIL; public: Wire _ Union[ WireList[LIST["Vdd", "Gnd", "phA", "phB", "carryBA", "carryBAIn", "carryAB", "carryABIn", "kernal", "il", "lz", "enWrtPBusPhA", "enWrtPBusPhB", "conditionIn", Seq["ctrl8", 8], "writePBus", "res3BisP", "reject", Seq["aluOp", EUUtils.sizeALUOps], "hold", "read", "write", Seq["dStateAd", 4], "VRef" ]], Wires[EUUtils.GenRegSelWire[EUUtils.left], EUUtils.GenRegSelWire[EUUtils.right], EUUtils.GenRegSelWire[EUUtils.st2A], EUUtils.GenRegSelWire[EUUtils.st2B], EUUtils.GenRegSelWire[EUUtils.st3A], EUUtils.GenRegSelWire[EUUtils.kReg], EUUtils.GenRegSelWire[EUUtils.r2B], EUUtils.GenRegSelWire[EUUtils.r3A], EUUtils.GenRegSelWire[EUUtils.r3B], EUUtils.GenRegSelWire[EUUtils.dataIn], Seq["selcBusSrc", 3]], EUUtils.GenWiresCtrlToALU[], Wires["carryOut", Seq["res", 8], Seq["opL", 3], Seq["opR", 3], Seq["shift", 6], Seq["sh", EUUtils.wordSize+1]]]; ctrl8: Wire _ FindWire[public, "ctrl8"]; leftSrc: Wire _ Range[ctrl8, 1, 2]; rightSrc: Wire _ Range[ctrl8, 3, 3]; st2ASrc: Wire _ Range[ctrl8, 6, 2]; res: Wire _ FindWire[public, "res"]; opL: Wire _ FindWire[public, "opL"]; opR: Wire _ FindWire[public, "opR"]; shift: Wire _ FindWire[public, "shift"]; aluOp: Wire _ FindWire[public, "aluOp"]; dStateAd: Wire _ FindWire[public, "dStateAd"]; reject: Variable _ FindWire[public, "reject"]; -- latched on PhB in the pad nReject: Expression _ Not[reject]; read: Variable _ FindWire[public, "read"]; write: Variable _ FindWire[public, "write"]; hold: Variable _ FindWire[public, "hold"]; nHold: Expression _ Not[hold]; fetch: Variable _ FindWire[public, "res3BisP"]; store: Variable _ FindWire[public, "writePBus"]; st3AisC: Variable _ FindWire[public, ctrl8[0]]; opL0: Variable _ FindWire[public, opL[0]]; opR0: Variable _ FindWire[public, opR[0]]; carryOut: Variable _ FindWire[public, "carryOut"]; carryBAIn: Variable _ FindWire[public, "carryBAIn"]; carryABIn: Variable _ FindWire[public, "carryABIn"]; conditionIn: Variable _ FindWire[public, "conditionIn"]; LeftExpr: ExprProc = {RETURN[And[nReject, nHold, EqualInt[leftSrc, i]]]}; RightExpr: ExprProc = {RETURN[And[nReject, nHold, EqualInt[rightSrc, i]]]}; St2AExpr: ExprProc = {RETURN[And[nReject, nHold, EqualInt[st2ASrc, i]]]}; R3AExpr: ExprProc = {RETURN[And[nReject, nHold]]}; St3AExpr: ExprProc = {RETURN[ SELECT i FROM 0 => And[nReject, nHold, Not[st3AisC]], 1 => And[nReject, nHold, st3AisC], ENDCASE => ERROR]}; KRegExpr: ExprProc = {RETURN[nHold]}; R2BExpr: ExprProc = {RETURN[ SELECT i FROM 0 => And[nHold, Nor[ -- aluOut OpIs[FOP], -- neither FOP OpIs[BndChk]]], -- nor BndChk 1 => And[nHold, OpIs[FOP]], -- fuOut 2 => And[nHold, OpIs[BndChk]], -- left ENDCASE => ERROR]}; St2BExpr: ExprProc = {RETURN[nHold]}; R3BExpr: ExprProc = {RETURN[nHold]}; DataInExpr: ExprProc = {RETURN[nHold]}; CBusExpr: ExprProc = {RETURN[ -- use the non-latched reject and a simple driver, no clock!!! SELECT i FROM 0 => Nand[nReject, store, fetch], -- r3B 1 => And[nReject, nHold, fetch], -- dataIn 2 => Or[EqualInt[dStateAd, EUUtils.cBus], Not[read]], ENDCASE => ERROR]}; ShExpr: ExprProc = {RETURN[EqualInt[shift, i]]}; CarryInExpr: ExprProc = {RETURN[ OrList[LIST[ -- Or, And, LAdd, Xor, FOP, VAdd and VAdd2 -> false And[OpIs[VSub], true], -- I hope Alps does some simplification!!! And[OpIs[LSub], true], And[OpIs[BndChk], true], And[OpIs[SAdd], carryABIn], -- prev And[OpIs[SSub], Not[carryABIn]], -- nprev And[OpIs[UAdd], carryABIn], And[OpIs[USub], Not[carryABIn]] ]] ]}; CarryBAExpr: ExprProc = {RETURN[ If[OrList[LIST[OpIs[SAdd], OpIs[SSub], OpIs[LAdd], OpIs[LSub]]], false, -- reset carry If[OpIs[UAdd], carryOut, -- get carryOut If[OpIs[USub], Not[carryOut], -- get ~carryOut carryABIn]]] -- recycle the carry ]}; CarryABExpr: ExprProc = {RETURN[ If[And[nReject, Not[conditionIn]], carryBAIn, carryABIn] ]}; OpExpr: ExprProc = { RETURN[SELECT i FROM -- add sub xor or and 0 => Not[InSet[sub]], -- 1 0 1 1 1 1 => InSet[sub, and], -- 0 1 0 0 1 2 => InSet[add, xor], -- 1 0 1 0 0 3 => Not[InSet[add]], -- 0 1 1 1 1 4 => Not[InSet[sub]], -- 1 0 1 1 1 ENDCASE => ERROR]; }; OpType: TYPE = {add, sub, xor, or, and, none}; OpIs: PROC [op: Dragon.ALUOps] RETURNS [expr: Expression] ~ { expr _ EqualInt[aluOp, Dragon.ALUOps[op].ORD]; }; InSet: PROC [t1, t2: OpType _ none] RETURNS [expr: Expression] ~ { AddMatchType: PROC [op: OpType] RETURNS [expr: Expression]~ { expr _ SELECT op FROM add => Or[OpIs[VAdd2], OpIs[SAdd], OpIs[LAdd], OpIs[VAdd], OpIs[UAdd]], sub => Or[OpIs[BndChk], OpIs[SSub], OpIs[LSub], OpIs[VSub], OpIs[USub]], xor => OpIs[Xor], or => Or[OpIs[Or], OpIs[FOP]], and => OpIs[And], ENDCASE => ERROR; }; expr _ AddMatchType[t1]; IF t2#none THEN expr _ Or[expr, AddMatchType[t2]]; }; IsLispInt: PROC [threeBit: Wire] RETURNS [Expression] ~ { RETURN[Or[EqualInt[threeBit, 0], EqualInt[threeBit, 7]]]; }; KernalExpr: ExprProc = {RETURN[EqualInt[res, 0]]}; ILExpr: ExprProc = {RETURN[Nand[IsLispInt[Range[res, 0, 3]], IsLispInt[opL], IsLispInt[opR]]]}; LZExpr: ExprProc = {RETURN[Xor[Xor[carryOut, opL0], opR0]]}; WrPBusPhAExpr: ExprProc = {RETURN[And[nReject, nHold]]}; WrPBusPhBExpr: ExprProc = {RETURN[And[store, nHold]]}; inputDrivers _ AppendInput[public, "reject", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "hold", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "write", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "read", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "res3BisP", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "writePBus", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "aluOp", inputDrivers]; -- 4 inputDrivers _ AppendInput[public, "dStateAd", inputDrivers]; -- 4 inputDrivers _ AppendInput[public, "conditionIn", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "carryBAIn", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "carryABIn", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "ctrl8", inputDrivers]; -- 8 inputDrivers _ AppendInput[public, "shift", inputDrivers]; -- 6 inputDrivers _ AppendInput[public, "carryOut", inputDrivers]; -- 1 inputDrivers _ AppendInput[public, "res", inputDrivers]; -- 8 inputDrivers _ AppendInput[public, "opL", inputDrivers]; -- 3 inputDrivers _ AppendInput[public, "opR", inputDrivers]; -- 3 outputDrivers _ AppendOutput["enWrtPBusPhA", WrPBusPhAExpr[], , outputDrivers]; outputDrivers _ AppendOutput["enWrtPBusPhB", WrPBusPhBExpr[], , outputDrivers]; MakeSelExpr[EUUtils.dataIn, DataInExpr, "phB"]; outputDrivers _ AppendOutput[Index["selcBusSrc", 0], CBusExpr[0], , outputDrivers]; outputDrivers _ AppendOutput[Index["selcBusSrc", 1], CBusExpr[1], , outputDrivers]; outputDrivers _ AppendOutput[Index["selcBusSrc", 2], CBusExpr[2], , outputDrivers]; MakeSelExpr[EUUtils.r3B, R3BExpr, "phB"]; MakeSelExpr[EUUtils.r3A, R3AExpr, "phA"]; MakeSelExpr[EUUtils.st3A, St3AExpr, "phA"]; MakeSelExpr[EUUtils.st2B, St2BExpr, "phB"]; FOR i: NAT DECREASING IN [0..EUUtils.wordSize+1) DO outputDrivers _ AppendOutput[Index["sh", i], ShExpr[i], NIL, outputDrivers]; ENDLOOP; MakeSelExpr[EUUtils.r2B, R2BExpr, "phB"]; FOR i: NAT IN [0..5) DO outputDrivers _ AppendOutput[Index["op", i], OpExpr[i], NIL, outputDrivers]; ENDLOOP; outputDrivers _ AppendOutput["carryIn", CarryInExpr[], NIL, outputDrivers]; MakeSelExpr[EUUtils.st2A, St2AExpr, "phA"]; MakeSelExpr[EUUtils.left, LeftExpr, "phA"]; MakeSelExpr[EUUtils.right, RightExpr, "phA"]; MakeSelExpr[EUUtils.kReg, KRegExpr, "phB"]; outputDrivers _ AppendState["carryBA", CarryBAExpr[], "phB", outputDrivers]; outputDrivers _ AppendState["carryAB", CarryABExpr[], "phA", outputDrivers]; outputDrivers _ AppendOutput["il", ILExpr[], NIL, outputDrivers]; outputDrivers _ AppendOutput["lz", LZExpr[], NIL, outputDrivers]; outputDrivers _ AppendOutput["kernal", KernalExpr[], NIL, outputDrivers]; cellType _ AlpsCell[ name: "DPControl", public: public, inputs: inputDrivers, outputs: outputDrivers, props: CoreProperties.Props[[$ContactPolyMetal2, NEW[INT _ 20]]] ]; END; }; CopyAndDeleteNames: PROC [public: Wire, names: LIST OF ROPE _ NIL] RETURNS [copiedAndDeleted: Wire] ~ { listWires: LIST OF Wire _ NIL; FOR i: NAT IN [0 .. public.size) DO name: ROPE _ CoreOps.GetShortWireName[public[i]]; IF ~RopeList.Memb[names, name] THEN listWires _ CONS[CoreOps.CopyWire[public[i]], listWires]; ENDLOOP; copiedAndDeleted _ CoreOps.CreateWire[listWires]; }; CreateControl: PUBLIC PROC RETURNS [cellType: CellType] ~ { IF EUUtils.useControlCheckpoint THEN RETURN [LayoutCheckpoint.Retrieve["Control"]]; BEGIN ctrlTop: CellType _ CreateRamControl[]; ctrlBot: CellType _ CreateBothAlps[]; public: Wire _ Union[ CopyAndDeleteNames[ctrlTop.public, LIST["Vdd", "Gnd", "VRef", "reject", "hold", "read", "write", "dStateAd", "phA"]], CopyAndDeleteNames[ctrlBot.public] ]; condition: Wire _ FindWire[public, "condition"]; Vdd: Wire _ FindWire[public, "Vdd"]; Gnd: Wire _ FindWire[public, "Gnd"]; reject: Wire _ FindWire[public, "reject"]; hold: Wire _ FindWire[public, "hold"]; read: Wire _ FindWire[public, "read"]; write: Wire _ FindWire[public, "write"]; dStateAd: Wire _ FindWire[public, "dStateAd"]; ramAdr: Wire _ FindWire[public, "ramAdr"]; channelData: PWCoreRoute.ChannelData _ NEW[PWCoreRoute.ChannelDataRec _ [ inX: FALSE, bottomOrLeftWires: LIST[Vdd, Gnd, reject, condition], topOrRightWires: LIST[ramAdr, hold, read, write, dStateAd, condition], trunkLayer: "metal", branchLayer: "metal2", extendTopOrRight: FALSE, extend: TRUE, wireWidthProc: GndAndVdd10Met2MinWidth ]]; cellType _ Cell[ name: "Control", public: public, instances: LIST [ Instance[name: "BottomAlps", type: ctrlBot], Instance[name: "TopAlps", type: ctrlTop] ] ]; PWCore.SetLayout[cellType, $Channel, $ChannelData, channelData]; END; }; END. CarryInExpr: ExprProc = {RETURN[ OrList[LIST[ -- Or, And, LAdd, Xor, FOP, VAdd and VAdd2 -> false And[OpIs[VSub], true], -- I hope Alps does some simplification!!! And[OpIs[LSub], true], And[OpIs[BndChk], true], And[OpIs[SAdd], carryABIn], -- prev And[OpIs[SSub], Not[carryABIn]], -- nprev And[OpIs[UAdd], carryABIn], And[OpIs[USub], Not[carryABIn]] ]] ]}; CarryBAExpr: ExprProc = {RETURN[ OrList[LIST[ -- SAdd, SSub, LAdd and LSub -> false And[OpIs[VAdd], carryABIn], And[OpIs[VAdd2], carryABIn], And[OpIs[VSub], carryABIn], And[OpIs[BndChk], carryABIn], And[OpIs[Or], carryABIn], And[OpIs[And], carryABIn], And[OpIs[Xor], carryABIn], And[OpIs[FOP], carryABIn], -- prev And[OpIs[UAdd], carryOut], -- comp And[OpIs[USub], Not[carryOut]] -- ncomp ]] ]}; 0EUControlAlpsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Louis Monier June 19, 1986 4:21:32 pm PDT Bertrand Serlet August 26, 1986 1:38:02 am PDT Last Edited by: Louis Monier September 15, 1986 4:03:05 pm PDT -- public -- All the wires used as inputs (numbers) -- Expressions (booleans) -- Input inverters to the Alps blocks -- Enable Write on the KBus (IFU side); by luck, same timing as ram -- enWrtIFUPhA _ cAdr=IFUAdr -- enWrtIFUPhB _ false (if no // debug, never used, so could be removed) -- Precharge of the ram -- nPrech _ nPhB -- Output drivers, all of the same type: they follow PhA -- selHi[i][a] _ aAdrH=i -- selHi[i][b] _ bAdrH=i -- selHi[i][c] _ (cAdrH=i).~reject for i#marAdr/4 -- selHi[marAdr/4][c] _ (cAdrH=i)+reject -- selLow[i][a] _ aAdrL=i -- selLow[i][b] _ bAdrL=i -- selLow[i][c] _ (cAdrL=i).~reject for i#marAdr MOD 4 -- selHi[marAdr MOD 4][c] _ (cAdrL=i)+reject -- Control for Field register; located here because it requires cAdr; also same timing as ram -- selFieldSrc[0] _ (cAdr=fieldAdr).~reject.~hold.PhA -- selFieldSrc[1] _ (dStateAd=field).write -- selFieldSrc[2] _ (dStateAd=field).read -- reading the ram while debugging -- selFieldSrc[2] _ (dStateAd=ramA).read And[CondIs[False], false], And[CondIs[AddressCheckFault], kernal], -- Creates the control for the bottom of the Datapath -- All the wires used as inputs (numbers) -- Expressions (booleans) -- PhA latches selLeftSrc[i] _ PhA . (leftSrc=i) . ~reject . ~hold -- selRightSrc[i] _ PhA . (rightSrc=i) . ~reject . ~hold -- selSt2ASrc[i] _ PhA . (st2ASrc=i) . ~reject . ~hold -- selRes3ABSrc _ PhA . ~reject . ~hold -- selSt3ABSrc[st2B] _ PhA . ~st3AisC . ~reject . ~hold -- selSt3ABSrc[cBus] _ PhA . st3AisC . ~reject . ~hold -- PhB latches -- selKRegAdr _ PhB . ~hold -- selRes2BASrc[aluOut] _ PhB . ~hold . (aluOp=FOP) -- selRes2BASrc[fuOut] _ PhB . ~hold . (aluOp#FOP) -- selRes2BASrc[left] _ PhB . ~hold . (aluOp=BndChk) -- selSt2BASrc _ PhB . ~hold -- selRes3BASrc[tBus] _ PhB . ~hold -- selDataInSrc _ PhB . ~hold -- Special guys -- selCBusSrc[r3B] _ (reject + ~fetch + ~store) -- selCBusSrc[dataIn] _ ~reject . ~hold . fetch -- selCBusSrc[enW] _ (dStAd=cBus) + ~read -- Field Unit -- sh[i] _ (shift=i) -- ALU -- carryAB _ IF ~reject AND ~condition THEN carryBA ELSE carryAB -- enWrtPBusPhA _ ~reject AND ~hold -- enWrtPBusPhB _ store AND ~hold -- Input to control in order -- Input Drivers for the (few) signals coming straight from the pads -- Input Drivers for the signals coming from the Data Path -- Outputs to Data path in order: bottom ones first -- To pad frame -- Bottom Registers -- Field unit control -- res2BA Register -- ALU control -- Top Registers -- Carry feedback -- Sub-expressions to compute Condition -- Generate the block Alps -- To build the public -- goes throuh -- out to the left -- out to the right Κ – "cedar" style˜codešœ™Kšœ Οmœ1™—K˜KšΟk œ³˜ΌK˜•StartOfExpansion[]šΟbœžœž˜ Kšžœ…˜ŒKšžœ˜Kšžœžœ:˜D—K˜Kš Οnœžœžœžœžœ˜8K˜š  œžœžœžœ˜QKš œžœžœžœ#˜RKšœ;˜;Kšœ ˜ Kšœ?˜?K˜—K˜š   œžœžœžœžœžœ˜pKš œ(žœžœžœžœ˜mšžœžœ˜ šœ˜š œžœžœžœžœ˜.Kšžœžœ&˜/—Kšœ˜—Kšœ˜—K˜—š   œžœžœžœžœ˜iKšœA˜AKš žœžœžœžœΟc"˜;šžœžœ˜ šœ˜Kšœžœ&˜/Kšœ˜—Kšœ˜—K˜—K˜Kš‘C˜Cš œž œžœ˜>Kšžœ!žœžœ+˜YKšž˜Kšœžœ˜Kšœžœ˜Kšœžœ˜K™ šœ˜Kšœ‘˜(Kšœ‘%˜DKšœ‘ ˜(šœ žœm˜zKšœ'‘˜;Kšœ˜——K™)Kšœ.˜.šœ*˜*Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—K™Kšœ*˜*Kšœ,˜,Kšœ.˜.Kšœ"˜"Kšœ*˜*Kšœ˜K˜š œžœ žœ˜8KšœB˜BK˜—K™Kš žœ žœ žœ žœžœ˜8Kš žœ žœ žœ žœžœ˜5™%Kšœ<‘˜@Kšœ:‘˜>Kšœ:‘˜>Kšœ;‘˜?Kšœ>‘˜BKšœ:‘˜?—K˜™CšœLžœ˜`Kšœ™—šœ3žœ˜GKšœH™H——K™šœ™KšœD˜Dšœ™K™——šœ8™8šžœžœžœž˜#šœ4˜4Kšœ™—šœ4˜4Kšœ™—šœžœžœ˜?Kšžœ ˜$—šœ(˜(Kšœ1™1Kšœ(™(—Kšžœ˜—šžœžœžœž˜(šœ8˜8Kšœ™—šœ8˜8Kšœ™—šœžœžœžœ˜DKšžœ!˜%—šœ+˜+Kšœ1žœ™6Kšœžœ™,—Kšžœ˜——K™šœ]™]šœ/˜/KšœM˜MKšœ5™5—šœ/˜/Kšœ/žœ˜CKšœ*™*—šœ/˜/Kšœ.žœ˜BKšœ)™)K™——šœ"™"šœ)˜)Kšœ-žœ˜AKšœ(™(——K™šœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ1žœžœ˜@K˜—Kšžœ˜Kšœ˜—K˜š œžœ˜9šœL˜LKš œžœžœžœžœ˜N—Kšœ˜J˜—K˜š œž œžœ˜Kšœ>‘˜BKšœ:‘˜>Kšœ<‘˜@Kšœ8‘˜˜\šžœž˜ Kšœ#‘˜)Kšœ"‘ ˜+Kšœ5˜5Kšžœžœ˜—Kšœ/™/Kš‘œ$‘œ™/Kš‘œ&™)—K™Kš’ ™ š œžœ˜0Kš‘œ™K™—Kš’™š  œžœ˜ šœžœ‘3˜@Kšœ‘*˜BKšœ˜Kšœ˜Kšœ‘˜$Kšœ"‘˜*Kšœ˜Kšœ˜Kšœ˜—Kšœ˜—š  œžœ˜ šœ žœ3˜AKšœ‘˜šœ˜Kšœ ‘˜šœ˜Kšœ‘ ˜ Kšœ ‘˜!———Kšœ˜—š  œžœ˜ Kšœ<˜Kšœ:‘˜>Kšœ:‘˜>K˜—š’3™3™KšœO˜OKšœO˜O—™Kšœ/˜/KšœS˜SKšœS˜SKšœS˜SKšœ)˜)Kšœ)˜)Kšœ+˜+Kšœ+˜+—™š žœžœž œžœž˜3Kšœ8žœ˜LKšžœ˜——™Kšœ)˜)—™šžœžœžœž˜Kšœ8žœ˜LKšžœ˜—Kšœ7žœ˜K—™Kšœ+˜+Kšœ+˜+Kšœ-˜-Kšœ+˜+—šœ™KšœL˜LKšœL˜L—šœ'™'Kšœ-žœ˜AKšœ-žœ˜AKšœ5žœ˜I—K˜—K™Kš’™šœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ1žœžœ˜@K˜—Kšžœ˜Kšœ˜K˜—š  œžœžœžœž œžœ˜gKšœ žœžœžœ˜šžœžœžœž˜#Kšœžœ'˜1Kšžœžœ žœ)˜]Kšžœ˜—Kšœ1˜1K˜K˜—š  œžœžœžœ˜;K™Kšžœžœžœ(˜SKšž˜Jšœ'˜'Jšœ%˜%šœ˜Kšœ#žœO˜vKšœ"˜"Kšœ˜—K™Kšœ0˜0Kšœ$˜$Kšœ$˜$K™Kšœ*˜*K™Kšœ&˜&Kšœ&˜&Kšœ(˜(Kšœ.˜.Kšœ*˜*K˜šœ'žœ˜IKšœžœ˜ Jšœžœ˜5Jšœžœ1˜FJšœ˜Jšœ˜Jšœžœ˜Jšœž˜ Jšœ&˜&J˜—šœ˜Kšœ˜Kšœ˜šœ žœ˜Kšœ,˜,Kšœ(˜(Kšœ˜—K˜—Kšœ@˜@Kšžœ˜Kšœ˜K˜—Kšžœ˜˜š  œžœ˜ šœžœ‘3˜@Kšœ‘*˜BKšœ˜Kšœ˜Kšœ‘˜$Kšœ"‘˜*Kšœ˜Kšœ˜Kšœ˜—Kšœ˜—š  œžœ˜ šœžœ‘%˜2Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ žœ‘˜#Kšœ‘˜#Kšœ‘˜'Kšœ˜—Kšœ˜—K˜——…—Obož