<> <> <> <> <> 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>> 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) ]]]; <<-- All the wires used as inputs (numbers)>> 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]; <<-- Expressions (booleans)>> 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; <<-- Input inverters to the Alps blocks>> 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 <<-- Enable Write on the KBus (IFU side); by luck, same timing as ram>> outputDrivers _ AppendOutput["enWrtIFUPhA", EqualInt[cAdr, EUUtils.IFUAdr], NIL, outputDrivers]; <<-- enWrtIFUPhA _ cAdr=IFUAdr>> outputDrivers _ AppendOutput["enWrtIFUPhB", false, NIL, outputDrivers]; <<-- enWrtIFUPhB _ false (if no // debug, never used, so could be removed)>> <<>> <<-- Precharge of the ram>> outputDrivers _ AppendOutput["nPrech", true, "nPhB", outputDrivers]; <<-- nPrech _ nPhB>> <<>> <<-- Output drivers, all of the same type: they follow PhA>> FOR i: INT IN [0..EUUtils.nRows) DO AppendRamDriver[Index["selA", i], EqualInt[aHi, i]]; <<-- selHi[i][a] _ aAdrH=i>> AppendRamDriver[Index["selB", i], EqualInt[bHi, i]]; <<-- selHi[i][b] _ bAdrH=i>> expr _ IF i=EUUtils.marAdr/4 THEN Or[reject, EqualInt[cHi, i]] ELSE And[nReject, EqualInt[cHi, i]]; AppendRamDriver[Index["selC", i], expr]; <<-- selHi[i][c] _ (cAdrH=i).~reject for i#marAdr/4>> <<-- selHi[marAdr/4][c] _ (cAdrH=i)+reject>> ENDLOOP; FOR i: INT IN [0..EUUtils.sizeSelLow) DO AppendRamDriver[Index["selALow", i], EqualInt[aLow, i]]; <<-- selLow[i][a] _ aAdrL=i>> AppendRamDriver[Index["selBLow", i], EqualInt[bLow, i]]; <<-- selLow[i][b] _ bAdrL=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]; <<-- selLow[i][c] _ (cAdrL=i).~reject for i#marAdr MOD 4>> <<-- selHi[marAdr MOD 4][c] _ (cAdrL=i)+reject>> ENDLOOP; <<>> <<-- Control for Field register; located here because it requires cAdr; also same timing as ram>> outputDrivers _ AppendOutput["selFieldSrc[0]", And[nReject, nHold, EqualInt[cAdr, EUUtils.fieldAdr]], "phA", outputDrivers]; <<-- selFieldSrc[0] _ (cAdr=fieldAdr).~reject.~hold.PhA>> outputDrivers _ AppendOutput["selFieldSrc[1]", And[write, EqualInt[dStateAd, EUUtils.field]], NIL, outputDrivers]; <<-- selFieldSrc[1] _ (dStateAd=field).write>> outputDrivers _ AppendOutput["selFieldSrc[2]", And[read, EqualInt[dStateAd, EUUtils.field]], NIL, outputDrivers]; <<-- selFieldSrc[2] _ (dStateAd=field).read>> <<>> <<-- reading the ram while debugging>> outputDrivers _ AppendOutput["dRamRead", And[read, EqualInt[dStateAd, EUUtils.ramA]], NIL, outputDrivers]; <<-- selFieldSrc[2] _ (dStateAd=ramA).read>> <<>> 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 ]; }; <<-- Creates the control for the bottom of the Datapath>> 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]]]; <<-- All the wires used as inputs (numbers)>> 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"]; <<-- Expressions (booleans)>> 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"]; <<>> <<-- PhA latches>> LeftExpr: ExprProc = {RETURN[And[nReject, nHold, EqualInt[leftSrc, i]]]}; <> RightExpr: ExprProc = {RETURN[And[nReject, nHold, EqualInt[rightSrc, i]]]}; <<-- selRightSrc[i] _ PhA . (rightSrc=i) . ~reject . ~hold>> St2AExpr: ExprProc = {RETURN[And[nReject, nHold, EqualInt[st2ASrc, i]]]}; <<-- selSt2ASrc[i] _ PhA . (st2ASrc=i) . ~reject . ~hold>> R3AExpr: ExprProc = {RETURN[And[nReject, nHold]]}; <<-- selRes3ABSrc _ PhA . ~reject . ~hold>> St3AExpr: ExprProc = {RETURN[ SELECT i FROM 0 => And[nReject, nHold, Not[st3AisC]], 1 => And[nReject, nHold, st3AisC], ENDCASE => ERROR]}; <<-- selSt3ABSrc[st2B] _ PhA . ~st3AisC . ~reject . ~hold>> <<-- selSt3ABSrc[cBus] _ PhA . st3AisC . ~reject . ~hold>> <<-- PhB latches>> KRegExpr: ExprProc = {RETURN[nHold]}; <<-- selKRegAdr _ PhB . ~hold>> 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]}; <<-- selRes2BASrc[aluOut] _ PhB . ~hold . (aluOp=FOP)>> <<-- selRes2BASrc[fuOut] _ PhB . ~hold . (aluOp#FOP)>> <<-- selRes2BASrc[left] _ PhB . ~hold . (aluOp=BndChk)>> St2BExpr: ExprProc = {RETURN[nHold]}; <<-- selSt2BASrc _ PhB . ~hold>> R3BExpr: ExprProc = {RETURN[nHold]}; <<-- selRes3BASrc[tBus] _ PhB . ~hold>> DataInExpr: ExprProc = {RETURN[nHold]}; <<-- selDataInSrc _ PhB . ~hold>> <<-- Special guys>> 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]}; <<-- selCBusSrc[r3B] _ (reject + ~fetch + ~store)>> <<-- selCBusSrc[dataIn] _ ~reject . ~hold . fetch>> <<-- selCBusSrc[enW] _ (dStAd=cBus) + ~read>> <<>> <<-- Field Unit>> ShExpr: ExprProc = {RETURN[EqualInt[shift, i]]}; <<-- sh[i] _ (shift=i)>> <<>> <<-- ALU>> 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] ]}; <<-- carryAB _ IF ~reject AND ~condition THEN carryBA ELSE carryAB>> 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]]}; <<-- enWrtPBusPhA _ ~reject AND ~hold>> WrPBusPhBExpr: ExprProc = {RETURN[And[store, nHold]]}; <<-- enWrtPBusPhB _ store AND ~hold>> <<>> <<-- Input to control in order>> <<-- Input Drivers for the (few) signals coming straight from the pads>> 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 <<-- Input Drivers for the signals coming from the Data Path>> 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 <<-- Outputs to Data path in order: bottom ones first>> <<-- To pad frame>> outputDrivers _ AppendOutput["enWrtPBusPhA", WrPBusPhAExpr[], , outputDrivers]; outputDrivers _ AppendOutput["enWrtPBusPhB", WrPBusPhBExpr[], , outputDrivers]; <<-- Bottom Registers>> 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"]; <<-- Field unit control>> FOR i: NAT DECREASING IN [0..EUUtils.wordSize+1) DO outputDrivers _ AppendOutput[Index["sh", i], ShExpr[i], NIL, outputDrivers]; ENDLOOP; <<-- res2BA Register>> MakeSelExpr[EUUtils.r2B, R2BExpr, "phB"]; <<-- ALU control>> FOR i: NAT IN [0..5) DO outputDrivers _ AppendOutput[Index["op", i], OpExpr[i], NIL, outputDrivers]; ENDLOOP; outputDrivers _ AppendOutput["carryIn", CarryInExpr[], NIL, outputDrivers]; <<-- Top Registers>> MakeSelExpr[EUUtils.st2A, St2AExpr, "phA"]; MakeSelExpr[EUUtils.left, LeftExpr, "phA"]; MakeSelExpr[EUUtils.right, RightExpr, "phA"]; MakeSelExpr[EUUtils.kReg, KRegExpr, "phB"]; <<-- Carry feedback >> outputDrivers _ AppendState["carryBA", CarryBAExpr[], "phB", outputDrivers]; outputDrivers _ AppendState["carryAB", CarryABExpr[], "phA", outputDrivers]; <<-- Sub-expressions to compute Condition>> outputDrivers _ AppendOutput["il", ILExpr[], NIL, outputDrivers]; outputDrivers _ AppendOutput["lz", LZExpr[], NIL, outputDrivers]; outputDrivers _ AppendOutput["kernal", KernalExpr[], NIL, outputDrivers]; <<>> <<-- Generate the block Alps>> 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] ~ { <<-- To build the public>> 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] ]; <<-- goes throuh>> condition: Wire _ FindWire[public, "condition"]; Vdd: Wire _ FindWire[public, "Vdd"]; Gnd: Wire _ FindWire[public, "Gnd"]; <<-- out to the left>> reject: Wire _ FindWire[public, "reject"]; <<-- out to the right>> 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 ]] ]};