RadioLock.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Barth, January 30, 1990 4:50:21 pm PST
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;
RadioLock
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];
};
LegalCheck
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];
};
AssDis
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];
};
Synthesis
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];
};
Encode8to10
Encode8to10Ports: TYPE = REF Encode8to10PortsRec;
Encode8to10PortsRec: TYPE = RECORD[
i, o: Port ← NIL];
Encode8to10TestProc: RosemaryUser.TestProc = {
OPEN BitOps;
Encode: PROC [input: BitDWord] RETURNS [output: BitDWord𡤋itDWordZero] = {
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.ROPENIL;
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 ANYNARROW[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] ~ {
Read a boolean property from a CT with the specified default
rb: REF BOOLNARROW [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.