DIRECTORY BitOps, CD, CDOps, Core, CoreOps, CoreProperties, IO, Ports, Rope, Rosemary, RosemaryUser, Sisyph, TerminalIO; RadioLock: CEDAR PROGRAM IMPORTS BitOps, CDOps, CoreOps, CoreProperties, IO, Ports, Rope, Rosemary, RosemaryUser, Sisyph, TerminalIO = BEGIN OPEN Ports; RadioLockPorts: TYPE = REF RadioLockPortsRec; RadioLockPortsRec: TYPE = RECORD[ CK, LegalCount, Legal, Illegal, Slip, SlipCount, Lock: Port _ NIL]; RadioLockTestProc: RosemaryUser.TestProc = { ports: RadioLockPorts _ Initialize[p, cellType.public, Eval ! Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME ELSE REJECT]; {OPEN ports; FOR slipCount: INT IN [0..4) DO PDW[SlipCount, slipCount, force]; PB[Legal, TRUE, force]; CycleClock[ports, Eval]; THROUGH [1..2] DO CycleClock[ports, Eval]; ENDLOOP; PB[Legal, FALSE, force]; PB[Illegal, TRUE, force]; CycleClock[ports, Eval]; PB[Illegal, FALSE, force]; THROUGH [1..10] DO CycleClock[ports, Eval]; ENDLOOP; ENDLOOP; }}; Initialize: PROC [p: Ports.Port, public: Core.Wire, eval: RosemaryUser.TestEvalProc] RETURNS [ports: RadioLockPorts]= { ports _ NEW[RadioLockPortsRec]; {OPEN ports; [CK, LegalCount, Legal, Illegal, Slip, SlipCount, Lock] _ Ports.BindPorts[public, p, "CK", "LegalCount", "Legal", "Illegal", "Slip", "SlipCount", "Lock"]; PDW[LegalCount, 1, force]; PB[Legal, FALSE, force]; PB[Illegal, FALSE, force]; PB[Slip, FALSE, none]; PDW[SlipCount, 0, force]; PB[Lock, FALSE, none]; CycleClock[ports, eval]; }}; CycleClock: PROC [ports: RadioLockPorts, eval: RosemaryUser.TestEvalProc] = { OPEN ports; PB[CK, FALSE, force]; eval[clockEval: TRUE]; eval[clockEval: FALSE]; PB[CK, TRUE, force]; eval[clockEval: TRUE]; eval[clockEval: FALSE]; }; LegalCheckPorts: TYPE = REF LegalCheckPortsRec; LegalCheckPortsRec: TYPE = RECORD[ Edge, CK, MinDelay, Legal, Illegal: Port _ NIL]; LegalCheckTestProc: RosemaryUser.TestProc = { ports: LegalCheckPorts _ LegalCheckInitialize[p, cellType.public, Eval ! Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME ELSE REJECT]; {OPEN ports; PDW[MinDelay, 7, force]; THROUGH [1..2] DO PB[Edge, TRUE, force]; LegalCheckCycleClock[ports, Eval]; PB[Edge, FALSE, force]; THROUGH [1..100] DO LegalCheckCycleClock[ports, Eval]; ENDLOOP; ENDLOOP; }}; LegalCheckInitialize: PROC [p: Ports.Port, public: Core.Wire, eval: RosemaryUser.TestEvalProc] RETURNS [ports: LegalCheckPorts]= { ports _ NEW[LegalCheckPortsRec]; {OPEN ports; [Edge, CK, MinDelay, Legal, Illegal] _ Ports.BindPorts[public, p, "Edge", "CK", "MinDelay", "Legal", "Illegal"]; PB[Edge, FALSE, force]; PDW[MinDelay, 0, force]; PB[Legal, FALSE, none]; PB[Illegal, FALSE, none]; LegalCheckCycleClock[ports, eval]; }}; LegalCheckCycleClock: PROC [ports: LegalCheckPorts, eval: RosemaryUser.TestEvalProc] = { OPEN ports; PB[CK, FALSE, force]; eval[clockEval: TRUE]; eval[clockEval: FALSE]; PB[CK, TRUE, force]; eval[clockEval: TRUE]; eval[clockEval: FALSE]; }; AssDisPorts: TYPE = REF AssDisPortsRec; AssDisPortsRec: TYPE = RECORD[ ToReg, FromReg, ReadEnable, WriteEnable, IOCK, Address, TxData, RxData, Lock, CK: Port _ NIL]; AssDisTestProc: RosemaryUser.TestProc = { ports: AssDisPorts _ AssDisInitialize[p, cellType.public, Eval ! Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME ELSE REJECT]; {OPEN ports; PDW[Address, 3, force]; PDW[ToReg, 85, force]; AssDisCycleClock[ports, Eval]; AssDisCycleClock[ports, Eval]; AssDisCycleClock[ports, Eval]; AssDisCycleClock[ports, Eval]; PB[WriteEnable, TRUE, force]; AssDisCycleClock[ports, Eval]; PB[WriteEnable, FALSE, force]; THROUGH [1..600] DO PB[RxData, GB[TxData], force]; AssDisCycleClock[ports, Eval]; ENDLOOP; }}; AssDisInitialize: PROC [p: Ports.Port, public: Core.Wire, eval: RosemaryUser.TestEvalProc] RETURNS [ports: AssDisPorts]= { ports _ NEW[AssDisPortsRec]; {OPEN ports; [ToReg, FromReg, ReadEnable, WriteEnable, IOCK, Address, TxData, RxData, Lock, CK] _ Ports.BindPorts[public, p, "ToReg", "FromReg", "ReadEnable", "WriteEnable", "IOCK", "Address", "TxData", "RxData", "Lock", "CK"]; PDW[ToReg, 0, force]; PDW[FromReg, 0, none]; PB[ReadEnable, FALSE, force]; PB[WriteEnable, FALSE, force]; PDW[Address, 0, force]; PB[TxData, FALSE, inspect]; PB[RxData, FALSE, force]; PB[Lock, TRUE, force]; AssDisCycleClock[ports, eval]; }}; AssDisCycleClock: PROC [ports: AssDisPorts, eval: RosemaryUser.TestEvalProc] = { OPEN ports; PB[CK, FALSE, force]; PB[IOCK, FALSE, force]; eval[clockEval: TRUE]; eval[clockEval: FALSE]; PB[CK, TRUE, force]; PB[IOCK, TRUE, force]; eval[clockEval: TRUE]; eval[clockEval: FALSE]; }; SynthesisPorts: TYPE = REF SynthesisPortsRec; SynthesisPortsRec: TYPE = RECORD[ Lock, LockFall, Control, CK, RegAddress, LockDelay, OverFlow, Sum, Addend, T0, Decrement, DelayEqual: Port _ NIL]; SynthesisTestProc: RosemaryUser.TestProc = { ports: SynthesisPorts _ SynthesisInitialize[p, cellType.public, Eval ! Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME ELSE REJECT]; {OPEN ports, BitOps; freqBitCount: NAT = 16; freqDoIt: NAT = 0; freqDisIncDec: NAT = 1; freqDisableSum: NAT = 2; freqBitOfData: NAT = 3; lockDelayReg: NAT = 3; FreqStore: PROC [value: NAT, reg: NAT] = { PDW[RegAddress, reg, force]; SynthesisCycleClock[ports, Eval]; FOR bitIndex:NAT IN [0..freqBitCount) DO b: BitDWord _ bitIndex; IF EBFD[value, freqBitCount-bitIndex-1, freqBitCount] THEN b _ IBID[TRUE, b, freqBitOfData, 8]; PDW[Control, b, force]; SynthesisCycleClock[ports, Eval]; b _ IBID[TRUE, b, freqDoIt, 8]; PDW[Control, b, force]; THROUGH [1..32] DO SynthesisCycleClock[ports, Eval]; ENDLOOP; ENDLOOP; }; CycleLock: PROC [cycles: NAT] = { PB[Lock, TRUE, force]; THROUGH [1..cycles] DO SynthesisCycleClock[ports, Eval]; ENDLOOP; PB[Lock, FALSE, force]; SynthesisCycleClock[ports, Eval]; PB[LockFall, TRUE, force]; SynthesisCycleClock[ports, Eval]; PB[LockFall, FALSE, force]; THROUGH [1..cycles-2] DO SynthesisCycleClock[ports, Eval]; ENDLOOP; }; FreqStore[6, lockDelayReg]; THROUGH [1..4] DO CycleLock[128]; CycleLock[64]; ENDLOOP; }}; SynthesisInitialize: PROC [p: Ports.Port, public: Core.Wire, eval: RosemaryUser.TestEvalProc] RETURNS [ports: SynthesisPorts]= { ports _ NEW[SynthesisPortsRec]; {OPEN ports; [Lock, LockFall, Control, CK, RegAddress, LockDelay, OverFlow, Sum, Addend, T0, Decrement, DelayEqual] _ Ports.BindPorts[public, p, "Lock", "LockFall", "Control", "CK", "RegAddress", "LockDelay", "OverFlow", "Sum", "Addend", "T0", "Decrement", "DelayEqual"]; PB[Lock, FALSE, force]; PB[LockFall, FALSE, force]; PDW[Control, 0, force]; PDW[RegAddress, 0, force]; PB[LockDelay, FALSE, none]; PB[OverFlow, FALSE, none]; PB[Sum, FALSE, none]; PB[Addend, FALSE, none]; PB[T0, FALSE, none]; PB[Decrement, FALSE, none]; PB[DelayEqual, FALSE, none]; SynthesisCycleClock[ports, eval]; }}; SynthesisCycleClock: PROC [ports: SynthesisPorts, eval: RosemaryUser.TestEvalProc] = { OPEN ports; PB[CK, FALSE, force]; eval[clockEval: TRUE]; eval[clockEval: FALSE]; PB[CK, TRUE, force]; eval[clockEval: TRUE]; eval[clockEval: FALSE]; }; Encode8to10Ports: TYPE = REF Encode8to10PortsRec; Encode8to10PortsRec: TYPE = RECORD[ i, o: Port _ NIL]; Encode8to10TestProc: RosemaryUser.TestProc = { OPEN BitOps; Encode: PROC [input: BitDWord] RETURNS [output: BitDWord_BitDWordZero] = { SELECT ECFD[input, 0, 2, 8] FROM 0 => IF ECFD[input, 2, 2, 8]=1 THEN { output _ IBID[TRUE, output, 0, 10]; output _ IBID[EBFD[input, 5, 8], output, 1, 10]; output _ IBID[EBFD[input, 4, 8], output, 2, 10]; output _ IBID[EBFD[input, 6, 8], output, 3, 10]; output _ ICID[5, output, 4, 5, 10]; output _ IBID[EBFD[input, 7, 8], output, 9, 10]; } ELSE { output _ ICID[5, output, 0, 4, 10]; output _ ICID[ECFD[input, 2, 6, 8], output, 4, 6, 10]; }; 1 => { output _ IBID[EBFD[input, 2, 8], output, 0, 10]; output _ ICID[5, output, 1, 4, 10]; output _ ICID[ECFD[input, 3, 5, 8], output, 5, 5, 10]; }; 2 => IF ECFD[input, 2, 2, 8]=1 THEN { output _ ICID[ECFD[input, 4, 2, 8], output, 0, 2, 10]; output _ ICID[0, output, 2, 2, 10]; output _ ICID[ECFD[input, 6, 2, 8], output, 4, 2, 10]; output _ ICID[5, output, 6, 4, 10]; } ELSE { output _ ICID[ECFD[input, 2, 2, 8], output, 0, 2, 10]; output _ ICID[5, output, 2, 4, 10]; output _ ICID[ECFD[input, 4, 4, 8], output, 6, 4, 10]; }; 3 => IF ECFD[input, 3, 2, 8]=1 THEN { output _ IBID[EBFD[input, 2, 8], output, 0, 10]; output _ IBID[EBFD[input, 5, 8], output, 1, 10]; output _ ICID[3, output, 2, 2, 10]; output _ ICID[ECFD[input, 6, 2, 8], output, 4, 2, 10]; output _ ICID[5, output, 6, 4, 10]; } ELSE { output _ ICID[ECFD[input, 2, 3, 8], output, 0, 3, 10]; output _ ICID[5, output, 3, 4, 10]; output _ ICID[ECFD[input, 5, 3, 8], output, 7, 3, 10]; }; ENDCASE => ERROR; }; ports: Encode8to10Ports _ Encode8to10Initialize[p, cellType.public, Eval ! Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME ELSE REJECT]; {OPEN ports; FOR input: BitDWord IN [0..256) DO output: BitDWord _ Encode[input]; PDW[i, input, force]; PDW[o, output, expect]; TerminalIO.PutF["i: %x, o: %x", IO.int[input], IO.int[output]]; Eval[]; IF output IN [336..352) THEN ERROR; FOR check: BitDWord IN [0..input) DO IF Encode[check]=output THEN ERROR; ENDLOOP; ENDLOOP; }}; Encode8to10Initialize: PROC [p: Ports.Port, public: Core.Wire, eval: RosemaryUser.TestEvalProc] RETURNS [ports: Encode8to10Ports]= { ports _ NEW[Encode8to10PortsRec]; {OPEN ports; [i, o] _ Ports.BindPorts[public, p, "i", "o"]; PDW[i, 0, force]; PDW[o, 0, none]; eval[]; }}; RunRosemary: PROC [cellName: Rope.ROPE, design: CD.Design] = { cellType: Core.CellType _ Sisyph.ES[cellName, Sisyph.Create[design]]; CDOps.SetMutability[design, readonly]; IF cellType#NIL THEN { -- something to do tester: RosemaryUser.Tester _ NIL; public: Core.Wire _ cellType.public; Vdd: Core.Wire _ CoreOps.FindWire[public, "Vdd"]; Gnd: Core.Wire _ CoreOps.FindWire[public, "Gnd"]; testButtons: LIST OF Rope.ROPE _ NIL; IF Vdd=NIL THEN TerminalIO.PutRope["DAUser: Couldn't find Vdd\n"] ELSE [] _ Rosemary.SetFixedWire[Vdd, H]; IF Gnd=NIL THEN TerminalIO.PutRope["DAUser: Couldn't find Gnd\n"] ELSE [] _ Rosemary.SetFixedWire[Gnd, L]; FOR tbl: LIST OF REF ANY _ NARROW[CoreProperties.GetCellTypeProp[cellType, $Tests]], tbl.rest UNTIL tbl=NIL DO testButtons _ CONS[CoreOps.FixStupidRef[tbl.first], testButtons]; ENDLOOP; tester _ RosemaryUser.TestProcedureViewer[ cellType: cellType, testButtons: testButtons, name: Rope.Cat[CoreOps.GetCellTypeName[cellType], " Test"], displayWires: RosemaryUser.DisplayPortLeafWires[cellType], recordDeltas: GetBool[cellType, $RecordDeltas, TRUE], cutSet: NARROW[CoreProperties.GetCellTypeProp[cellType, $CutSet]]]; tester.display.recordSteps _ tester.display.recordDeltas AND GetBool[cellType, $RecordSteps, TRUE]; }; }; GetBool: PROC [ct: Core.CellType, prop: ATOM, default: BOOL] RETURNS [BOOL] ~ { rb: REF BOOL _ NARROW [CoreProperties.GetCellTypeProp[ct, prop]]; RETURN [IF rb=NIL THEN default ELSE rb^]; }; RosemaryUser.RegisterTestProc["RadioLock", RadioLockTestProc]; RosemaryUser.RegisterTestProc["LegalCheck", LegalCheckTestProc]; RosemaryUser.RegisterTestProc["AssDis", AssDisTestProc]; RosemaryUser.RegisterTestProc["Synthesis", SynthesisTestProc]; RosemaryUser.RegisterTestProc["Encode8to10", Encode8to10TestProc]; END. κRadioLock.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Barth, January 30, 1990 4:50:21 pm PST RadioLock LegalCheck AssDis Synthesis Encode8to10 Read a boolean property from a CT with the specified default ΚP– "cedar" style˜codešœ™K™œ˜CK˜—šžœ˜,Kš œOœœœœœ˜‚Kšœœ˜ šœ œœ˜Kšœ˜!Kšœœ ˜Kšœ˜Kšœœœ˜3Kšœœ ˜Kšœ œ ˜Kšœ˜Kšœ œ ˜Kšœ œœ˜4Kšœ˜—šœ˜K˜——šž œœEœ˜wKšœœ˜Kšœœ˜ Kšœš˜šKšœ˜Kšœœ ˜Kšœ œ ˜Kšœœ˜Kšœ˜Kšœœ˜Kšœ˜K˜K˜—šž œœ=˜MKšœ˜ Kšœœ ˜Kšœœ˜Kšœœ˜Kšœœ ˜Kšœœ˜Kšœœ˜Kšœ˜K˜——šœ ™ Kšœœœ˜/šœœœ˜"Kšœ+œ˜0K˜—šžœ˜-Kš œZœœœœœ˜Kšœœ˜ Kšœ˜šœ˜Kšœœ ˜Kšœ"˜"Kšœœ ˜Kšœ œ$œ˜?Kšœ˜—šœ˜K˜——šžœœEœ˜‚Kšœœ˜ Kšœœ˜ Kšœp˜pKšœœ ˜Kšœ˜Kšœœ˜Kšœ œ˜Kšœ"˜"K˜K˜—šžœœ>˜XKšœ˜ Kšœœ ˜Kšœœ˜Kšœœ˜Kšœœ ˜Kšœœ˜Kšœœ˜Kšœ˜K˜——™Kšœ œœ˜'šœœœ˜KšœYœ˜^K˜—šžœ˜)Kš œRœœœœœ˜…Kšœœ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœœ ˜Kšœ˜Kšœœ ˜šœ ˜Kšœ œ˜Kšœ˜Kšœ˜—šœ˜K˜——šžœœEœ˜zKšœœ˜Kšœœ˜ KšœΦ˜ΦKšœ˜Kšœ˜Kšœ œ ˜Kšœœ ˜Kšœ˜Kšœ œ ˜Kšœ œ ˜Kšœœ ˜Kšœ˜K˜K˜—šžœœ:˜PKšœ˜ Kšœœ ˜Kšœœ ˜Kšœœ˜Kšœœ˜Kšœœ ˜Kšœœ ˜Kšœœ˜Kšœœ˜Kšœ˜K˜——šœ ™ Kšœœœ˜-šœœœ˜!Kšœmœ˜rK˜—šžœ˜,Kš œXœœœœœ˜‹Kšœœ˜Kšœœ˜Kšœ œ˜Kšœœ˜Kšœœ˜Kšœœ˜Kšœœ˜šž œœ œœ˜*Kšœ˜Kšœ!˜!šœ œœ˜(Kšœ˜Kš œœ/œœœ˜_Kšœ˜Kšœ!˜!Kšœœœ˜Kšœ˜Kšœ œ#œ˜=Kšœ˜—K˜—šž œœ œ˜!Kšœœ ˜Kšœ œ#œ˜AKšœœ ˜Kšœ!˜!Kšœ œ ˜Kšœ!˜!Kšœ œ ˜Kšœœ#œ˜CK˜—Kšœ˜šœ˜K˜K˜Kšœ˜—šœ˜K˜——šžœœEœ˜€Kšœœ˜Kšœœ˜ Kšœ‚˜‚Kšœœ ˜Kšœ œ ˜Kšœ˜Kšœ˜Kšœ œ˜Kšœ œ˜Kšœœ˜Kšœ œ˜Kšœœ˜Kšœ œ˜Kšœ œ˜Kšœ!˜!K˜K˜—šžœœ=˜VKšœ˜ Kšœœ ˜Kšœœ˜Kšœœ˜Kšœœ ˜Kšœœ˜Kšœœ˜Kšœ˜K˜——™ Kšœœœ˜1šœœœ˜#Kšœ œ˜K˜—šžœ˜.Kšœ˜ šžœœœ$˜Jšœœ˜ šœœœœ˜%Kšœ œœ˜#Kšœ œœ˜0Kšœ œœ˜0Kšœ œœ˜0Kšœ œ˜#Kšœ œœ˜0Kšœœ˜Kšœ œ˜#Kšœ œœ$˜6K˜—šœ˜Kšœ œœ˜0Kšœ œ˜#Kšœ œœ$˜6K˜—šœœœœ˜%Kšœ œœ$˜6Kšœ œ˜#Kšœ œœ$˜6Kšœ œ˜#Kšœœ˜Kšœ œœ$˜6Kšœ œ˜#Kšœ œœ$˜6K˜—šœœœœ˜%Kšœ œœ˜0Kšœ œœ˜0Kšœ œ˜#Kšœ œœ$˜6Kšœ œ˜#Kšœœ˜Kšœ œœ$˜6Kšœ œ˜#Kšœ œœ$˜6K˜—Kšœœ˜—K˜—Kš œ\œœœœœ˜Kšœœ˜ šœœ ˜"K˜!Kšœ˜Kšœ˜K˜?Kšœ˜Kšœœ œœ˜#šœœ ˜$Kšœœœ˜#Kšœ˜—Kšœ˜—šœ˜K˜——šžœœEœ˜„Kšœœ˜!Kšœœ˜ Kšœ.˜.Kšœ˜Kšœ ˜Kšœ˜K˜K˜——šž œœœ œ ˜>Kšœ!œ"˜EKšœ&˜&šœ œœΟc˜)Kšœœ˜"Kšœ$˜$Kšœ1˜1Kšœ1˜1Kš œ œœœœ˜%Kšœœœ2˜AKšœ$˜(Kšœœœ2˜AKšœ$˜(šœœœœœœ=œœ˜nKšœœ/˜AKšœ˜—šœ*˜*Kšœ˜Kšœ˜Kšœ<˜˜>Kšœ@˜@Kšœ8˜8Kšœ>˜>KšœB˜BK˜Kšœ˜K˜K˜K˜K˜—…—+r:¬