RadioTest.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Barth, February 23, 1990 5:24:55 pm PST
DIRECTORY BitOps, Core, IO, Ports, Rosemary, RosemaryUser, TerminalIO;
RadioTest: CEDAR PROGRAM
IMPORTS BitOps, IO, Ports, Rosemary, RosemaryUser, TerminalIO =
BEGIN OPEN Ports;
SSCtl
SSCtlPorts: TYPE = REF SSCtlPortsRec;
SSCtlPortsRec: TYPE = RECORD[
nBR, nBG, nReset, nSel, nAS, SClk, nLErr, nAck0, nAck1, nAck2, Siz, Read, PA, Data, TxClock, TxCode, TxData, TxEnb, RxClock, RxCode, RxData, Lock, SamClk, SamData, Illegal, T0, SRegOut, Ser0, SlipEnb: Port ← NIL];
Warning: SIGNAL = CODE;
SSCtlTestProc: RosemaryUser.TestProc = {
ports: SSCtlPorts ← SSCtlInitialize[p, cellType.public, Eval ! Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME ELSE REJECT];
{OPEN ports;
txData: NAT = 0;
txCtl: NAT = 1;
rxData: NAT = 2;
rxCtl: NAT = 3;
serialCtl: NAT = 4;
serialIntegrate: NAT = 0;
serialDecay: NAT = 1;
serialLockThreshold: NAT = 2;
serialUnlockThreshold: NAT = 3;
SBusStore: PROC [adr: NAT, value: NAT] = {
PB[nSel, FALSE, force];
PB[nAS, FALSE, force];
PB[nLErr, TRUE, expect];
PB[nAck0, TRUE, expect];
PD[nAck1, inspect];
PB[nAck2, TRUE, expect];
PDW[Siz, 1, force];
PB[Read, FALSE, force];
PDW[PA, adr, force];
PDW[Data, BitOps.DShift[value, 24, 32], force];
THROUGH [1..255] DO
SSCtlCycleClock[ports, Eval];
IF NOT GB[nAck1] THEN EXIT;
REPEAT FINISHED => SIGNAL Warning;
ENDLOOP;
PB[nAS, TRUE, force];
SSCtlCycleClock[ports, Eval];
PB[nSel, TRUE, force];
SSCtlCycleClock[ports, Eval];
};
SBusFetch: PROC [adr: NAT] RETURNS [value: NAT] = {
PB[nSel, FALSE, force];
PB[nAS, FALSE, force];
PB[nLErr, TRUE, expect];
PB[nAck0, TRUE, expect];
PD[nAck1, inspect];
PB[nAck2, TRUE, expect];
PDW[Siz, 1, force];
PB[Read, TRUE, force];
PDW[PA, adr, force];
PD[Data, inspect];
THROUGH [1..255] DO
SSCtlCycleClock[ports, Eval];
IF NOT GB[nAck1] THEN EXIT;
REPEAT FINISHED => SIGNAL Warning;
ENDLOOP;
value ← BitOps.ELFD[GDW[Data], 0, 8, 32];
PB[nAS, TRUE, force];
SSCtlCycleClock[ports, Eval];
PB[nSel, TRUE, force];
SSCtlCycleClock[ports, Eval];
};
serialBitCount: NAT = 12;
SerialStore: PROC [value: NAT, reg: NAT] = {
OPEN BitOps;
serialCtlRegLen: NAT = 8;
serialDoIt: NAT = 0;
serialBitOfData: NAT = 1;
serialRegAdr: NAT = 2;
serialRegAdrLen: NAT = 2;
serialBitAdr: NAT = 4;
serialBitAdrLen: NAT = 4;
d: BitWord ← BitWordZero;
d ← ICIW[reg, d, serialRegAdr, serialRegAdrLen, serialCtlRegLen];
FOR bitIndex:NAT IN [0..serialBitCount) DO
d ← IBIW[FALSE, d, serialDoIt, serialCtlRegLen];
d ← ICIW[bitIndex, d, serialBitAdr, serialBitAdrLen, serialCtlRegLen];
d ← IBIW[EBFW[value, serialBitCount-bitIndex-1, serialBitCount], d, serialBitOfData, serialCtlRegLen];
SBusStore[serialCtl, d];
d ← IBID[TRUE, d, serialDoIt, serialCtlRegLen];
SBusStore[serialCtl, d];
SSCtlCycleClock[ports, Eval, 2*serialBitCount];
ENDLOOP;
};
PD[TxEnb, inspect];
SBusStore[txCtl, 40H];
IF NOT GB[TxEnb] THEN SIGNAL Warning;
PD[Ser0, inspect];
SerialStore[00AH, serialIntegrate];
IF GDW[Ser0]#00AH THEN SIGNAL Warning;
SBusStore[rxCtl, 32H];
SerialStore[004H, serialLockThreshold];
SerialStore[006H, serialUnlockThreshold];
SerialStore[001H, serialDecay];
SSCtlCycleClock[ports, Eval, 10*serialBitCount];
PB[Lock, TRUE, expect];
SSCtlCycleClock[ports, Eval];
PD[Lock, none];
THROUGH [1..10] DO
PB[TxData, FALSE, none];
SSCtlCycleClock[ports, Eval, 16];
PB[TxData, TRUE, none];
SSCtlCycleClock[ports, Eval, 16];
PB[TxData, FALSE, none];
SSCtlCycleClock[ports, Eval, 16];
PB[TxData, TRUE, none];
SSCtlCycleClock[ports, Eval, 16];
ENDLOOP;
PB[Lock, FALSE, expect];
SSCtlCycleClock[ports, Eval];
PD[Lock, none];
PD[TxData, inspect];
SSCtlCycleClock[ports, Eval, 510]; -- initialize receiver
IF BitOps.EBFD[SBusFetch[txCtl], 0, 8] THEN SIGNAL Warning; -- tx already busy?
SBusStore[txData, 55H];
IF NOT BitOps.EBFD[SBusFetch[txCtl], 0, 8] THEN SIGNAL Warning; -- tx failed to go busy?
THROUGH [1..100] DO
IF BitOps.EBFD[SBusFetch[rxCtl], 0, 8] THEN EXIT;
REPEAT FINISHED => SIGNAL Warning; -- rx failed to go ready?
ENDLOOP;
IF SBusFetch[rxData]#55H THEN SIGNAL Warning; -- incorrect data?
}};
SSCtlInitialize: PROC [p: Ports.Port, public: Core.Wire, eval: RosemaryUser.TestEvalProc] RETURNS [ports: SSCtlPorts]= {
ports ← NEW[SSCtlPortsRec];
{OPEN ports;
[nBR, nBG, nReset, nSel, nAS, SClk, nLErr, nAck0, nAck1, nAck2] ← Ports.BindPorts[public, p, "nBR", "nBG", "nReset", "nSel", "nAS", "SClk", "nLErr", "nAck0", "nAck1", "nAck2"];
[Siz, Read, PA, Data, TxClock, TxCode, TxData, TxEnb, RxClock, RxCode, RxData] ← Ports.BindPorts[public, p, "Siz", "Read", "PA", "Data", "TxClock", "TxCode", "TxData", "TxEnb", "RxClock", "RxCode", "RxData"];
[Lock, SamClk, SamData, Illegal, T0, SRegOut, Ser0, SlipEnb] ← Ports.BindPorts[public, p, "Lock", "SamClk", "SamData", "Illegal", "T0", "SRegOut", "Ser0", "SlipEnb"];
PB[nBR, TRUE, force];
PB[nBG, TRUE, force];
PB[nReset, TRUE, force];
PB[nSel, TRUE, force];
PB[nAS, TRUE, force];
PB[nLErr, TRUE, force];
PB[nAck0, TRUE, force];
PB[nAck1, TRUE, force];
PB[nAck2, TRUE, force];
PDW[Siz, 0, force];
PB[Read, TRUE, force];
PDW[PA, 0, force];
PDW[Data, 0, force];
PD[TxCode, none];
PD[TxData, none];
PD[TxEnb, none];
PD[RxCode, none];
PB[RxData, TRUE, force];
PD[Lock, none];
PD[SamClk, none];
PD[SamData, none];
PD[Illegal, none];
PD[T0, none];
PD[SRegOut, none];
PD[Ser0, none];
PB[SlipEnb, TRUE, force];
PB[TxClock, TRUE, force];
SSCtlCycleClock[ports, eval];
}};
SSCtlCycleClock: PROC [ports: SSCtlPorts, eval: RosemaryUser.TestEvalProc, count: NAT ← 1] = {
OPEN ports;
THROUGH [1..count] DO
PB[RxData, NOT GB[TxData], force];
PB[SClk, FALSE, force];
PB[TxClock, NOT GB[TxClock], force];
PB[RxClock, FALSE, force];
eval[clockEval: TRUE];
eval[clockEval: FALSE];
PB[RxData, NOT GB[TxData], force];
PB[SClk, TRUE, force];
PB[RxClock, TRUE, force];
eval[clockEval: TRUE];
eval[clockEval: FALSE];
ENDLOOP;
};
Recover
RecoverPorts: TYPE = REF RecoverPortsRec;
RecoverPortsRec: TYPE = RECORD[
Signal, CK, Sample, Data: Port ← NIL];
RecoverTestProc: RosemaryUser.TestProc = {
ports: RecoverPorts ← RecoverInitialize[p, cellType.public, Eval ! Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME ELSE REJECT];
{OPEN ports;
RecoverCycleClock[ports, Eval, 21];
THROUGH [1..25] DO
PB[Signal, FALSE, force];
RecoverCycleClock[ports, Eval, 25];
PB[Signal, TRUE, force];
RecoverCycleClock[ports, Eval, 25];
ENDLOOP;
}};
RecoverInitialize: PROC [p: Ports.Port, public: Core.Wire, eval: RosemaryUser.TestEvalProc] RETURNS [ports: RecoverPorts]= {
ports ← NEW[RecoverPortsRec];
{OPEN ports;
[Signal, CK, Sample, Data] ← Ports.BindPorts[public, p, "Signal", "CK", "Sample", "Data"];
PB[Signal, FALSE, force];
PD[Sample, none];
PD[Data, none];
RecoverCycleClock[ports, eval];
}};
RecoverCycleClock: PROC [ports: RecoverPorts, eval: RosemaryUser.TestEvalProc, count: NAT ← 1] = {
OPEN ports;
THROUGH [1..count] DO
PB[CK, FALSE, force];
eval[clockEval: TRUE];
eval[clockEval: FALSE];
PB[CK, TRUE, force];
eval[clockEval: TRUE];
eval[clockEval: FALSE];
ENDLOOP;
};
Lock
LockPorts: TYPE = REF LockPortsRec;
LockPortsRec: TYPE = RECORD[
Signal, CK, T0, Data, Sum: Port ← NIL];
LockTestProc: RosemaryUser.TestProc = {
ports: LockPorts ← LockInitialize[p, cellType.public, Eval ! Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME ELSE REJECT];
{OPEN ports;
DO
LockCycleClock[ports, Eval, 13];
PB[Signal, NOT GB[Signal], force];
ENDLOOP;
}};
LockInitialize: PROC [p: Ports.Port, public: Core.Wire, eval: RosemaryUser.TestEvalProc] RETURNS [ports: LockPorts]= {
ports ← NEW[LockPortsRec];
{OPEN ports;
[Signal, CK, T0, Data, Sum] ← Ports.BindPorts[public, p, "Signal", "CK", "T0", "Data", "Sum"];
PB[Signal, FALSE, force];
PD[T0, none];
PD[Data, none];
PD[Sum, none];
LockCycleClock[ports, eval];
}};
LockCycleClock: PROC [ports: LockPorts, eval: RosemaryUser.TestEvalProc, count: NAT ← 1] = {
OPEN ports;
THROUGH [1..count] DO
PB[CK, FALSE, force];
eval[clockEval: TRUE];
eval[clockEval: FALSE];
PB[CK, TRUE, force];
eval[clockEval: TRUE];
eval[clockEval: FALSE];
ENDLOOP;
};
Encode8to10
Encode8to10Ports: TYPE = REF Encode8to10PortsRec;
Encode8to10PortsRec: TYPE = RECORD[
i, o, Idle: Port ← NIL];
Encode8to10TestProc: RosemaryUser.TestProc = {
ports: Encode8to10Ports ← Encode8to10Initialize[p, cellType.public, Eval ! Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME ELSE REJECT];
{OPEN ports;
PB[Idle, FALSE, expect];
FOR input: BitOps.BitDWord IN [0..256) DO
output: BitOps.BitDWord ← Encode[input];
PDW[i, input, force];
PDW[o, output, expect];
TerminalIO.PutF["\ni: %x, o: %x", IO.int[input], IO.int[output]];
Eval[];
IF output IN [336..352) AND input#6AH THEN ERROR;
FOR check: BitOps.BitDWord IN [0..input) DO
IF Encode[check]=output THEN ERROR;
ENDLOOP;
ENDLOOP;
PD[o, none];
PB[Idle, TRUE, expect];
PDW[i, 155H, force];
Eval[];
PDW[i, 2AAH, force];
Eval[];
}};
Encode8to10Initialize: PROC [p: Ports.Port, public: Core.Wire, eval: RosemaryUser.TestEvalProc] RETURNS [ports: Encode8to10Ports]= {
ports ← NEW[Encode8to10PortsRec];
{OPEN ports;
[i, o, Idle] ← Ports.BindPorts[public, p, "i", "o", "Idle"];
PDW[i, 0, force];
PD[o, none];
PD[Idle, none];
eval[];
}};
Decode10to8
Decode10to8Ports: TYPE = REF Decode10to8PortsRec;
Decode10to8PortsRec: TYPE = RECORD[
i, o: Port ← NIL];
Decode10to8TestProc: RosemaryUser.TestProc = {
ports: Decode10to8Ports ← Decode10to8Initialize[p, cellType.public, Eval ! Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME ELSE REJECT];
{OPEN ports;
FOR output: BitOps.BitDWord IN [0..256) DO
input: BitOps.BitDWord ← Encode[output];
PDW[i, input, force];
PDW[o, output, expect];
TerminalIO.PutF["\ni: %x, o: %x", IO.int[input], IO.int[output]];
Eval[];
ENDLOOP;
}};
Decode10to8Initialize: PROC [p: Ports.Port, public: Core.Wire, eval: RosemaryUser.TestEvalProc] RETURNS [ports: Decode10to8Ports]= {
ports ← NEW[Decode10to8PortsRec];
{OPEN ports;
[i, o] ← Ports.BindPorts[public, p, "i", "o"];
PDW[i, 0, force];
PDW[o, 0, none];
eval[];
}};
Encode: PROC [input: BitOps.BitDWord] RETURNS [output: BitOps.BitDWord𡤋itOps.BitDWordZero] = {
OPEN BitOps;
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 => IF ECFD[input, 2, 6, 8]=02AH THEN output ← 154H ELSE {
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;
};
RosemaryUser.RegisterTestProc["SSCtl", SSCtlTestProc];
RosemaryUser.RegisterTestProc["Recover", RecoverTestProc];
RosemaryUser.RegisterTestProc["Lock", LockTestProc];
RosemaryUser.RegisterTestProc["Encode8to10", Encode8to10TestProc];
RosemaryUser.RegisterTestProc["Decode10to8", Decode10to8TestProc];
END.