DIRECTORY BitOps, CoreClasses, CoreCreate, CoreIO, CoreFlat, CoreProperties, Ports, Rosemary; BICTopLevel: CEDAR PROGRAM IMPORTS BitOps, CoreClasses, CoreCreate, CoreIO, CoreFlat, Ports, Rosemary = BEGIN OPEN CoreCreate; BICName: ROPE = Rosemary.Register[roseClassName: "BIC", init: BICInit, evalSimple: BICSimple]; AssertionFailed: SIGNAL [message: ROPE] = CODE; Assert: PROC [condition: BOOL, message: ROPE _ NIL] = {IF NOT condition THEN SIGNAL AssertionFailed[message]}; BtoN: PROC [b: BOOL] RETURNS [NAT] ~ {RETURN[IF b THEN 1 ELSE 0]}; MoreThanOne: PROC [a, b, c, d: BOOL _ FALSE] RETURNS [BOOL _ FALSE] ~ { RETURN[BtoN[a]+BtoN[b]+BtoN[c]+BtoN[d]>1]; }; Or4: PROC [a: CARD] RETURNS [b: BOOL] ~ { b _ BitOps.EBFD[a, 31] OR BitOps.EBFD[a, 30] OR BitOps.EBFD[a, 29] OR BitOps.EBFD[a, 28]; }; ExplodeAddress: PROC [id: CARD] RETURNS [cid, cs, rs: CARDINAL] ~ { IF id NOT IN [0..256) THEN ERROR; cid _ BitOps.ECFD[id, 0, 3, 8]; -- 3 high-order bits: compare to Name cs _ BitOps.ECFD[id, 3, 2, 8]; -- next 2 bits: this BIC or a client circuit rs _ BitOps.ECFD[id, 5, 3, 8]; -- 3 low-order bits: scan path in BIC }; CreateBIC: PUBLIC PROC [fromFile: BOOL _ FALSE] RETURNS [ct: CellType ] = { IF fromFile THEN ct _ CoreIO.RestoreCellType["BIC", NIL] ELSE { public: Wire _ WireList[LIST[ "Vdd", "Gnd", "Gnd2V", "CKRecAdj", "RecAdj", "nEClock", "Clock", "ChipCKIn", "ExtCKIn", "ChipCKOut", "ExtCKOut", "LocCKOut", Seq["nDInB", 3], Seq["nBInB", 24], Seq["nRqOutB", 2], Seq["nDOutB", 3], Seq["nBOutB", 24], "nOrOutB", Seq["DInH", 3], Seq["BInH", 24], Seq["RqIn", 2], Seq["OrInH", 4], Seq["DOutH", 3], Seq["BOutH", 24], "nSStop", "DOEn", Seq["Name", 3], Seq["DBusIn", 7], Seq["Send", 4], "DBusOut", Seq["DCS", 3] ]]; ct _ CoreClasses.CreateUnspecified[public, BICName]; }; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: BICName]; [] _ CoreFlat.CellTypeCutLabels[ct, "BIC"]; Ports.InitPorts[ct, b, none, "Vdd", "Gnd", "Gnd2V", "CKRecAdj", "RecAdj"]; Ports.InitPorts[ct, b, none, "nEClock", "Clock", "ChipCKIn", "ExtCKIn"]; Ports.InitPorts[ct, b, drive, "ChipCKOut", "ExtCKOut", "LocCKOut"]; Ports.InitPorts[ct, lc, none, "nDInB", "nBInB"]; Ports.InitPorts[ct, lc, drive, "nRqOutB", "nDOutB", "nBOutB"]; Ports.InitPorts[ct, b, drive, "nOrOutB"]; Ports.InitPorts[ct, lc, none, "DInH", "BInH", "RqIn", "OrInH"]; Ports.InitPorts[ct, lc, drive, "DOutH", "BOutH"]; Ports.InitPorts[ct, b, none, "nSStop", "DOEn"]; Ports.InitPorts[ct, lc, none, "Name"]; Ports.InitPorts[ct, bs, none, "DBusIn", "Send"]; Ports.InitPorts[ct, b, drive, "DBusOut"]; Ports.InitPorts[ct, lc, drive, "DCS"]; }; BICState: TYPE = REF BICStateRec; BICStateRec: TYPE = RECORD[ Vdd, Gnd, Gnd2V, CKRecAdj, RecAdj, nEClock, Clock, ChipCKIn, ExtCKIn, ChipCKOut, ExtCKOut, LocCKOut, nDInB, nBInB, nRqOutB, nDOutB, nBOutB, nOrOutB, DInH, BInH, RqIn, OrInH, DOutH, BOutH, nSStop, DOEn, Name, DBusIn, Send, DBusOut, DCS: NAT _ LAST[NAT], -- ports indexes resetM, normalM, freezeM, shiftM, normal, freeze, shift, reset: BOOL _ FALSE, bMaster, bSlave: CARD _ 0, -- 24 orMaster, orSlave: BOOL _ FALSE, -- 1 rqMaster, rqSlave: CARD _ 0, -- 2 nBMaster, nBSlave: CARD _ 0, -- 24 nOrFMaster, nOrFSlave: BOOL _ FALSE, -- 1 nRqFMaster, nRqFSlave: CARD _ 0, -- 2 r1M, r2M, er1M, f1M, f2M, s1M, s2M, s3M, e1M, e2M: BOOL _ FALSE, r1S, r2S, er1S, f1S, f2S, s1S, s2S, s3S, e1S, e2S: BOOL _ FALSE, deviceIdM, deviceIdS: CARD _ 0, -- 8 bits chipIdM, chipIdS: CARD _ 0, -- 16 bits extCkM, extCkS: CARD _ 0, -- 4 bits intCkM, intCkS: CARD _ 0, -- 4 bits last: BOOL _ FALSE ]; BICInit: Rosemary.InitProc = { state: BICState _ NEW[BICStateRec]; {OPEN state; [Vdd, Gnd, Gnd2V, CKRecAdj, RecAdj] _ Ports.PortIndexes[cellType.public, "Vdd", "Gnd", "Gnd2V", "CKRecAdj", "RecAdj"]; [nEClock, Clock, ChipCKIn, ExtCKIn] _ Ports.PortIndexes[cellType.public, "nEClock", "Clock", "ChipCKIn", "ExtCKIn"]; [ChipCKOut, ExtCKOut, LocCKOut] _ Ports.PortIndexes[cellType.public, "ChipCKOut", "ExtCKOut", "LocCKOut"]; [nDInB, nBInB] _ Ports.PortIndexes[cellType.public, "nDInB", "nBInB"]; [nRqOutB, nDOutB, nBOutB, nOrOutB] _ Ports.PortIndexes[cellType.public, "nRqOutB", "nDOutB", "nBOutB", "nOrOutB"]; [DInH, BInH, RqIn, OrInH] _ Ports.PortIndexes[cellType.public, "DInH", "BInH", "RqIn", "OrInH"]; [DOutH, BOutH] _ Ports.PortIndexes[cellType.public, "DOutH", "BOutH"]; [nSStop, DOEn, Name, DBusIn, Send] _ Ports.PortIndexes[cellType.public, "nSStop", "DOEn", "Name", "DBusIn", "Send"]; [DBusOut, DCS] _ Ports.PortIndexes[cellType.public, "DBusOut", "DCS"]; }; stateAny _ state; }; ShiftOneLeft: PROC [from: CARD, size: NAT, lsb: BOOL] RETURNS [CARD] ~ { RETURN[BitOps.DShift[from, 1, size]+BtoN[lsb]]; }; Decoder: PROC [ad: CARD, en: BOOL, s: NAT] RETURNS [sel: CARD] ~ { sel _ IF ~en THEN 0 ELSE BitOps.TwoToThe[s-1-ad] }; BICSimple: Rosemary.EvalProc = { state: BICState _ NARROW[stateAny]; ck, grant, csOn: BOOL; cid, cs, rs, csOt, selScanPath: CARD _ 0; nDReset: NAT = 0; nDFreeze: NAT = 1; DExecute: NAT = 2; DShiftCK: NAT = 3; nDAddress: NAT = 4; DBusInIndex: NAT = 5; HybridSel: NAT = 6; ReadChipID: NAT = 128; AccessDP: NAT = 64; ReadExtCK: NAT = 32; ReadIntCK: NAT = 16; WriteExtCK: NAT = 8; WriteIntCK: NAT = 4; {OPEN state; [cid, cs, rs] _ ExplodeAddress[deviceIdS]; csOn _ (cid=p[Name].lc) AND p[DBusIn].bs[nDAddress] AND p[DBusIn].bs[HybridSel]; csOt _ Decoder[ad: cs, en: csOn, s: 4]; selScanPath _ Decoder[ad: rs, en: csOt=8, s: 8]; grant _ p[Send].bs[0] OR p[Send].bs[1] OR p[Send].bs[2] OR p[Send].bs[3]; p[LocCKOut].b _ p[ExtCKOut].b _ NOT p[nEClock].b; ck _ p[ChipCKOut].b _ p[ChipCKIn].b; SELECT p[DBusIn].bs[DShiftCK] FROM FALSE => { SELECT TRUE FROM NOT p[DBusIn].bs[nDAddress] => deviceIdM _ ShiftOneLeft[deviceIdS, 8, p[DBusIn].bs[DBusInIndex]]; -- shift chipID ENDCASE => NULL; }; TRUE => deviceIdS _ deviceIdM; ENDCASE => ERROR; SELECT p[DBusIn].bs[DShiftCK] FROM FALSE => { SELECT TRUE FROM NOT p[DBusIn].bs[nDAddress] => chipIdM _ 5081H; -- load chipID selScanPath=ReadChipID => chipIdM _ ShiftOneLeft[chipIdS, 16, p[DBusIn].bs[DBusInIndex]]; -- shift chipID ENDCASE => NULL; }; TRUE => chipIdS _ chipIdM; ENDCASE => ERROR; SELECT p[DBusIn].bs[DShiftCK] FROM FALSE => IF selScanPath=ReadExtCK OR selScanPath=WriteExtCK THEN extCkM _ ShiftOneLeft[extCkS, 4, p[DBusIn].bs[DBusInIndex]]; -- shift extCkM TRUE => extCkS _ extCkM; ENDCASE => ERROR; SELECT p[DBusIn].bs[DShiftCK] FROM FALSE => IF selScanPath=ReadIntCK OR selScanPath=WriteIntCK THEN intCkM _ ShiftOneLeft[intCkS, 4, p[DBusIn].bs[DBusInIndex]]; -- shift extCkM TRUE => intCkS _ intCkM; ENDCASE => ERROR; IF NOT ck THEN { -- clock is low: sample the input in all masters f4: BOOL; r1M _ p[DBusIn].bs[nDReset]; r2M _ r1S; er1M _ p[nSStop].b; f1M _ p[DBusIn].bs[nDFreeze]; f2M _ f1S; s1M _ NOT(p[DBusIn].bs[DShiftCK] AND BitOps.EBFD[selScanPath, 1, 8]); -- AccessDP s2M _ s1S; s3M _ s2S; e1M _ p[DBusIn].bs[DExecute]; e2M _ e1S; f4 _ ~(er1S AND f2S); resetM _ r2S; freezeM _ ~(r2S AND f4 AND ~(~s2S AND s3S)); shiftM _ ~(~s2S AND s3S AND ~e2S) ; normalM _ ~(resetM AND freezeM AND shiftM); -- leave as last expression! SELECT TRUE FROM normal => { bMaster _ IF grant THEN p[BInH].lc ELSE 0; orMaster _ Or4[p[OrInH].lc]; rqMaster _ p[RqIn].lc; nBMaster _ p[nBInB].lc; nOrFMaster _ TRUE; -- guess why! nRqFMaster _ 3; }; reset => { bMaster _ 0; orMaster _ FALSE; rqMaster _ 0; nBMaster _ 0FFFFFFFFH; nOrFMaster _ TRUE; nRqFMaster _ 3; }; shift => { -- p[DBusIn].bs[DBusIn] to Normal to Request to Or to DPShiftOut; lsb to msb chain: CARD _ 0; -- 27 bits bMaster _ nBSlave; rqMaster _ nRqFSlave; orMaster _ nOrFSlave; chain _ BitOps.ILID[bSlave, chain, 3, 24, 27]; chain _ BitOps.ICID[rqSlave, chain, 1, 2, 27]; chain _ BitOps.IBID[orSlave, chain, 0, 27]; chain _ ShiftOneLeft[chain, 27, NOT p[DBusIn].bs[DBusInIndex]]; nBMaster _ BitOps.ELFD[chain, 3, 24, 27]; nRqFMaster _ BitOps.ECFD[chain, 1, 2, 27]; nOrFMaster _ BitOps.EBFD[chain, 0, 27]; }; freeze => NULL; ENDCASE => NULL; } ELSE { -- clock is high: copy masters into slaves r1S _ r1M; r2S _ r2M; er1S _ er1M; f1S _ f1M; f2S _ f2M; s1S _ s1M; s2S _ s2M; s3S _ s3M; e1S _ e1M; e2S _ e2M; normal _ NOT normalM; freeze _ NOT freezeM; shift _ NOT shiftM; reset _ NOT resetM; bSlave _ bMaster; rqSlave _ rqMaster; orSlave _ orMaster; nBSlave _ nBMaster; nRqFSlave _ nRqFMaster; nOrFSlave _ nOrFMaster; }; p[nDOutB].lc _ BitOps.DNOT[IF p[DOEn].b THEN p[DInH].lc ELSE 0]; p[nBOutB].lc _ BitOps.DNOT[bSlave]; p[nOrOutB].b _ ~ orSlave; p[nRqOutB].lc _ BitOps.DNOT[rqSlave]; p[DOutH].lc _ BitOps.DNOT[p[nDInB].lc]; p[BOutH].lc _ BitOps.DNOT[nBSlave]; p[DCS].lc _ csOt MOD 8; -- low-order three bits p[DBusOut].b _ SELECT selScanPath FROM 0 => TRUE, -- should be tristate ReadChipID => BitOps.EBFD[chipIdS, 0, 16], -- ChipID AccessDP => NOT orSlave, -- DPShiftOut ReadExtCK => BitOps.EBFD[extCkS, 0, 4], -- ExtCkDelay ReadIntCK => BitOps.EBFD[intCkS, 0, 4], -- IntCkDelay WriteExtCK => BitOps.EBFD[extCkS, 0, 4], -- ExtDelayState WriteIntCK => BitOps.EBFD[intCkS, 0, 4], -- IntDelayState ENDCASE => ERROR; }}; END. BICTopLevel.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Louis Monier September 15, 1987 3:38:07 pm PDT -- address on 8 bits, id = cid[3] cs[2] rs[3] -- this public conforms to BICForSim.icon in BIC.dale -- power -- clocks -- board side -- hybrid side -- DBus et al. -- from hybrid to board -- from board to hybrid -- control -- structure of DBusIn -- structure of selScanPath -- Check that power supplies are well hooked up Assert[NOT p[Gnd].b AND NOT p[Gnd2V].b]; Assert[p[Vdd].b]; Assert[NOT MoreThanOne[normal, freeze, shift, reset]]; -- Unclocked stuff -- Clocks: we ignore Clock and ExtCKIn -- at the Rosemary level, the delay lines are invisible -- ck is the current clock distributed inside the chip -- Using DShiftCK as clock -- DBus address register -- (0) ChipID shift register -- (2 and 4) External clock shift register -- (3 and 5) Internal clock shift register -- System clock: Control of slices -- the order of evaluation is important -- chain is the chain of flops whose outputs, inverted, will become BOutH; the 3 ghost flops do not come out; nChain _ BitOps.IBID[nOrFSlave, nChain, 0, 27]; nChain _ BitOps.ICID[nRqFSlave, nChain, 1, 2, 27]; nChain _ BitOps.ILID[nBSlave, nChain, 3, 24, 27]; orMaster _ BitOps.EBFD[nChain, 0, 27]; rqMaster _ BitOps.ECFD[nChain, 1, 2, 27]; bMaster _ BitOps.ELFD[nChain, 3, 24, 27]; chain _ 2*chain+BtoN[NOT p[DBusIn].bs[DBusInIndex]]; -- Always copy slaves to outputs -- 2V outputs (remember to modify to express the wired or: value=0, drive changes) -- 5V outputs Κ q– "cedar" style˜codešœ™Kšœ<™˜>Kšœ)˜)K˜Kšœ?˜?Kšœ1˜1K˜Kšœ/˜/Kšœ&˜&Kšœ0˜0Kšœ)˜)Kšœ&˜&K˜Kšœ˜K˜—Kšœ œœ ˜!šœ œœ˜Kšœ#˜#Kšœ#˜#Kšœ˜Kšœ˜Kšœ"˜"Kšœ˜Kšœ˜Kšœ!˜!KšœœœœŸ˜/K˜Jšœ@œœ˜MJšŸ™Jšœœ Ÿ˜%JšœœœŸ˜(Jšœœ Ÿ˜&JšŸ™Jšœœ Ÿ˜&JšœœœŸ˜*Jšœœ Ÿ˜(JšŸ ™ Jšœ3œœ˜@Jšœ3œœ˜@JšœœŸ ˜)JšœœŸ ˜&JšœœŸ ˜#JšœœŸ ˜#J˜Jšœœ˜šœ˜K˜——šžœ˜Kšœœ˜#šœœ˜ šœ&˜&KšœP˜P—šœ&˜&KšœN˜N—šœ"˜"KšœH˜H—šœ˜Kšœ5˜5—šœ%˜%KšœM˜M—šœ˜KšœD˜D—šœ˜Kšœ5˜5—šœ%˜%KšœO˜O—šœ˜Kšœ5˜5—Kšœ˜—Kšœ˜Kšœ˜—šž œœœœœœœ˜HKšœ)˜/K˜—šžœœœœœœœ˜BKšœœœœ˜0K˜—šž œ˜ Kšœœ ˜#Kšœ˜Kšœ œ˜)™Kšœ œ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜—šœ™Kšœ œ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜—K˜Jšœœ˜ J˜J™/Jšœœ œœ ™(Jšœ™Kšœœ,™6J™J™Jšœ*˜*Kšœœœ˜PKšœ'˜'Kšœ0˜0Jšœœœœ˜IJ™Jšœ&™&šœ œ˜2Jšœ7™7—šœ%˜%J™6—J™Jšœ™J˜K™šœ˜"šœ˜ šœœ˜Kšœ_Ÿ˜qKšœœ˜—Kšœ˜—Kšœ˜Kšœœ˜—K™K™šœ˜"šœ˜ šœœ˜Kšœ-Ÿ˜>KšœZŸ˜iKšœœ˜—Kšœ˜—Kšœ˜Kšœœ˜—K™K™*šœ˜"šœœœœ˜AKšœ=Ÿ˜L—Kšœ˜Kšœœ˜—K™K™*šœ˜"šœœœœ˜AKšœ=Ÿ˜L—Kšœ˜Kšœœ˜—J˜J™"šœœœŸ0˜AKšœœ˜ Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ KšœœœœŸ ˜QKšœ ˜ Kšœ ˜ Kšœ˜Kšœ ˜ K™'Kšœ œ˜Kšœ ˜ Kšœœœœ˜,Kšœœœ˜#Kšœœ œ Ÿ˜HK˜šœœ˜šœ ˜ Kšœ œœ œ˜*Kšœ˜Kšœ˜Kšœ˜Kšœ œŸ ˜ Kšœ˜Kšœ˜—šœ ˜ Kšœ ˜ Kšœ œ˜Kšœ ˜ Kšœ˜Kšœ œ˜Kšœ˜Kšœ˜—šœ ŸL˜WK™mKšœœŸ ˜Kšœ˜Kšœ˜Kšœ˜K˜Kšœœ™/Kšœœ™2Kšœœ™1Kšœœ™&Kšœœ™)Kšœœ™)K˜Kšœœ˜.Kšœœ˜.Kšœœ˜+Kšœ œ˜?Kšœœ™4Kšœœ˜)Kšœœ˜*Kšœœ˜'Kšœ˜—Kšœ œ˜Kšœœ˜—Kšœ˜—šœŸ*˜2Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ œ ˜Kšœ œ ˜Kšœœ˜Kšœœ˜K˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—K˜K™ K™K™RJš œœœ œ œ˜@Kšœœ ˜#Kšœ˜Kšœœ ˜%K™ Jšœœ˜'Kšœœ ˜#Kšœœ œŸ˜/šœœ ˜&KšœœŸ˜#KšœœŸ ˜4Kšœ œ Ÿ ˜'KšœœŸ ˜5KšœœŸ ˜5KšœœŸ˜9KšœœŸ˜9Kšœœ˜—K˜Kšœ˜—K˜K˜Kšœ˜K˜—…—#Z5Ω