TestarossaTest.mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Last Edited by: Gasbarro June 17, 1988 4:48:21 pm PDT
DIRECTORY
Atom, Basics, BitOps, CD, CDCommandOps, CDIO, CDOps, CDProperties, CDSequencer, CDViewer, CommandTool, Core, CoreCDUser, CoreFlat, FS, IO, Ports, Rope, Rosemary, RosemaryUser, Sinix, Sisyph, TerminalIO;
TestarossaTest: CEDAR PROGRAM
IMPORTS Atom, Basics, BitOps, CDCommandOps, CDIO, CDOps, CDProperties, CDViewer, CommandTool, CoreCDUser, CoreFlat, FS, IO, Ports, Rope, Rosemary, RosemaryUser, Sisyph, TerminalIO
~ BEGIN
RefCK, nError, nCS, CAdrData, ExtReset, Start, Loop, CAdrStb, CWriteStb, CReadStb, CK, CycCK, CycDiv2, DUT, Vdd, Gnd: NAT;
ROPE: TYPE = Rope.ROPE;
Port: TYPE = Ports.Port;
Quad: TYPE = BitOps.BitQWord;
qZero: Quad = BitOps.BitQWordZero;
REProc: TYPE = RosemaryUser.TestEvalProc;
--PROC [memory: BOOL ← TRUE, clockEval: BOOL ← FALSE]--
TProc: TYPE = PROC [h: Handle, Eval: REProc];
BITSHIFT: PROC [value: WORD, count: INTEGER] RETURNS [WORD] = Basics.BITSHIFT;
BITAND: Basics.BitOp = Basics.BITAND;
BITOR: Basics.BitOp = Basics.BITOR;
BITNOT: PROC [WORD] RETURNS [WORD] = Basics.BITNOT;
Log2: PROC [n: INT] RETURNS [INT] = BitOps.Log2;
design: CD.Design ← NIL;
cutSet: LIST OF ROPELIST["Logic", "LogicMacro", "DPMacro", "FSM"];
maxCycle: CARDINAL = 512;
driveVector: ARRAY[0..maxCycle) OF CARDINAL;
Handle: TYPE = REF HandleRec;
HandleRec: TYPE = RECORD[
tester: RosemaryUser.Tester ← NIL,
rootCT: Core.CellType ← NIL,
testFlatCell: CoreFlat.FlatCellType ← NIL,
testPort: Ports.Port ← NIL,
port: Port ← NIL,
prevClkDiv2: BOOLFALSE,
cycle: CARDINAL ← 0
];
Timing: TYPE = {Sample, Width, Delay};
PEReg: TYPE = [0..16);
PEData: TYPE = [0..1024);
Ram: TYPE = {VRam, HRam, ERam, CRam};
Channel: TYPE = [0..16);
VRamAdd: TYPE = [0..1024);
VRamAdd: TYPE = [0..25);
CBus Addresses
pinElec: CARDINAL ~ 000h; -- up to 17Fh
Each DUT pin
Each TimingChannel (Sample, Width, Delay)
dsr0: CARDINAL ~ 000h;
dsr1: CARDINAL ~ 001h;
invCh0: CARDINAL ~ 002h;
invCh1: CARDINAL ~ 003h;
invCh2: CARDINAL ~ 004h;
risingEdge: CARDINAL ~ 005h;
fallingEdge: CARDINAL ~ 006h;
ioCtl: CARDINAL ~ 007h;
format: CARDINAL ~ 00fh;
writeLoopAdd: CARDINAL ~ 180h;
writeEndAdd: CARDINAL ~ 181h;
writeExtRamAdd: CARDINAL ~ 182h;
writeExtRamCtl: CARDINAL ~ 183h;
ramWD0 : CARDINAL ~ 184h;
ramWD1 : CARDINAL ~ 185h;
ramWD2 : CARDINAL ~ 186h;
ramWD3 : CARDINAL ~ 187h;
dramCtl: CARDINAL ~ 188h;
readDebug: CARDINAL ~ 180h;
readVRamAdd: CARDINAL ~ 181h;
readHRamAdd: CARDINAL ~ 182h;
readCmd: CARDINAL ~ 183h;
ramRD0 : CARDINAL ~ 184h;
ramRD1 : CARDINAL ~ 185h;
ramRD2 : CARDINAL ~ 186h;
ramRD3 : CARDINAL ~ 187h;
IOCtl Register
phaseCompEarly: CARDINAL ~ 001h;
sampleLate: CARDINAL ~ 002h;
analogSample: CARDINAL ~ 004h;
ttlMode: CARDINAL ~ 008h;
selLateData: CARDINAL ~ 010h;
Format Register
dnrz: CARDINAL ~ 001h;
rz: CARDINAL ~ 002h;
ro: CARDINAL ~ 004h;
rc: CARDINAL ~ 008h;
rt: CARDINAL ~ 010h;
ExtRamCtl Register
writeCRam: CARDINAL ~ 101h;
writeERam: CARDINAL ~ 102h;
writeHRam: CARDINAL ~ 104h;
writeVRam: CARDINAL ~ 108h;
readCRam: CARDINAL ~ 110h;
readERam: CARDINAL ~ 120h;
readHRam: CARDINAL ~ 140h;
readVRam: CARDINAL ~ 180h;
extRamAccess: CARDINAL ~ 100h;
vramBypass: CARDINAL ~ 200h;
readDebug0 Register
resetMinus1: CARDINAL ~ 001h;
wrHRamLow: CARDINAL ~ 002h;
wrHRamHigh: CARDINAL ~ 004h;
fetchCmd: CARDINAL ~ 008h;
prefetch: CARDINAL ~ 010h;
error: CARDINAL ~ 020h;
file: ROPE ← "AChip3.force";
TestAll: RosemaryUser.TestProc ~ {
ENABLE UNWIND => NULL;
DoSimpleTest: TProc ~ {
InitPortIndicies[cellType];
Reset[h, Eval];
FromFileTest[h, Eval, file];
BypassTest[h, Eval];
VRamTest[h, Eval];
SimpleVRamTest[h, Eval];
};
h: Handle ← NEW[HandleRec];
FindDesign[];
h.tester ← NARROW[CDProperties.GetDesignProp[design, $DAUserRoseTester]];
h.rootCT ← NARROW[CDProperties.GetDesignProp[design, $DAUserCellType]];
h.port ← p;
DoSimpleTest[h, Eval];
};
Reset: TProc ~ {
ENABLE Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME;
p: Port ← h.port;
TerminalIO.PutRope["***Reset***\n"];
p[nError].d ← none;
p[CAdrData].d ← none;
FOR i: NAT IN [0..p[DUT].ds.size) DO
p[DUT].ds[i] ← none;
ENDLOOP;
p[RefCK].b ← FALSE;
p[nCS].b ← FALSE;
p[CAdrData].c ← 0;
p[ExtReset].b ← FALSE;
p[Start].b ← FALSE;
p[Loop].b ← FALSE;
p[CAdrStb].b ← FALSE;
p[CWriteStb].b ← FALSE;
p[CReadStb].b ← FALSE;
p[CK].b ← FALSE;
p[CycCK].b ← FALSE;
p[CycDiv2].b ← FALSE;
CBusWrite[h, Eval, writeLoopAdd, 0];
CBusWrite[h, Eval, writeEndAdd, 0];
CBusWrite[h, Eval, writeExtRamCtl, 0];
p[ExtReset].b ← TRUE;
Cycle[h, Eval, 10, TRUE];
p[ExtReset].b ← FALSE;
Cycle[h, Eval, 1, TRUE];
};
HalfClocks: TYPE = [0..20);
DSR: PROC [halfClocks: HalfClocks] RETURNS [high, low: CARDINAL] ~ {
c: BitOps.BitDWord ← 0;
c ← BitOps.IBID[TRUE, c, halfClocks/2, 12];
c ← BitOps.IBID[TRUE, c, IF (halfClocks MOD 2)=0 THEN 10 ELSE 11, 12];
high ← BitOps.ECFD[c, 0, 8, 12];
low ← BITSHIFT[BitOps.ECFD[c, 8, 4, 12], 4]; --left justify result
};
InvStages: TYPE = [0..20);
IC: PROC [invStages: InvStages, forceH, forceL: BOOL] RETURNS [high, mid, low: CARDINAL] ~ {
c: BitOps.BitDWord ← 0;
c ← BitOps.IBID[TRUE, c, invStages, 22];
IF forceL THEN c ← BitOps.IBID[TRUE, c, 20, 22];
IF forceH THEN c ← BitOps.IBID[TRUE, c, 21, 22];
high ← BitOps.ECFD[c, 0, 8, 22];
mid ← BitOps.ECFD[c, 8, 8, 22];
low ← BITSHIFT[BitOps.ECFD[c, 16, 6, 22], 2]; --left justify result
};
EdgeC: TYPE = [0..4);
EdgeF: TYPE = [0..6);
stepMap: ARRAY EdgeF OF [0..16) = [4, 2, 12, 10, 1, 9];
Edge: PROC [edgeC: EdgeC, edgeF: EdgeF] RETURNS [CARDINAL] ~ {
RETURN[BITOR[BITSHIFT[80h, -edgeC], stepMap[edgeF]]];
};
InitTimingChan: PROC [h: Handle, Eval: REProc, chan: Channel, timing: Timing, halfClocks: HalfClocks, invStages: InvStages, upEdgeC: EdgeC, upEdgeF: EdgeF, dnEdgeC: EdgeC, dnEdgeF: EdgeF] ~ {
PEWrite[h, Eval, chan, dsr0, DSR[halfClocks].high, timing];
PEWrite[h, Eval, chan, dsr1, DSR[halfClocks].low, timing];
PEWrite[h, Eval, chan, invCh0, IC[invStages, FALSE, FALSE].high, timing];
PEWrite[h, Eval, chan, invCh1, IC[invStages, FALSE, FALSE].mid, timing];
PEWrite[h, Eval, chan, invCh2, IC[invStages, FALSE, FALSE].low, timing];
PEWrite[h, Eval, chan, risingEdge, Edge[upEdgeC, upEdgeF], timing];
PEWrite[h, Eval, chan, fallingEdge, Edge[dnEdgeC, dnEdgeF], timing];
};
BypassTest: TProc ~ {
Wait: PROC [oldAdd, newAdd: VRamAdd] ~ {
add: VRamAdd ← BITAND[CBusRead[h, Eval, readVRamAdd], 03FFh];
WHILE add=oldAdd DO
Cycle[h, Eval, 1];
add ← BITAND[CBusRead[h, Eval, readVRamAdd], 03FFh];
ENDLOOP;
IF add#newAdd THEN ERROR;
};
p: Port ← h.port;
TerminalIO.PutRope["***Bypass Test***\n"];
InitTimingChan[h, Eval, 0, Sample, 8, 0, 0, 0, 0, 0];
PEWrite[h, Eval, 0, ioCtl, 0];
PEWrite[h, Eval, 0, format, rz];
InitTimingChan[h, Eval, 15, Delay, 6, 0, 0, 0, 0, 0];
InitTimingChan[h, Eval, 15, Width, 10, 0, 0, 0, 0, 0];
InitTimingChan[h, Eval, 15, Sample, 8, 0, 0, 0, 0, 0];
PEWrite[h, Eval, 15, ioCtl, 0];
PEWrite[h, Eval, 15, format, rz];
InitTimingChan[h, Eval, 14, Delay, 6, 1, 1, 1, 1, 1];
InitTimingChan[h, Eval, 14, Width, 10, 2, 0, 0, 0, 0];
InitTimingChan[h, Eval, 14, Sample, 8, 3, 0, 0, 0, 0];
PEWrite[h, Eval, 14, ioCtl, 0];
PEWrite[h, Eval, 14, format, ro];
InitTimingChan[h, Eval, 13, Delay, 6, 4, 2, 2, 2, 4];
InitTimingChan[h, Eval, 13, Width, 10, 5, 0, 0, 0, 0];
InitTimingChan[h, Eval, 13, Sample, 8, 6, 0, 0, 0, 0];
PEWrite[h, Eval, 13, ioCtl, 0];
PEWrite[h, Eval, 13, format, rc];
InitTimingChan[h, Eval, 12, Delay, 6, 7, 3, 3, 3, 5];
InitTimingChan[h, Eval, 12, Width, 10, 8, 0, 0, 0, 0];
InitTimingChan[h, Eval, 12, Sample, 8, 9, 0, 0, 0, 0];
PEWrite[h, Eval, 12, ioCtl, 0];
PEWrite[h, Eval, 12, format, dnrz];
p[DUT].ds[0] ← drive;
p[DUT].ls[0] ← L;
FOR i: NAT IN [0..maxCycle) DO
driveVector[i] ← SELECT i FROM
IN [0..24) => 0,
IN [24..32) => IF i MOD 2 = 0 THEN 0 ELSE 8000h,
ENDCASE => 0;
ENDLOOP;
RamWrite[h, Eval, CRam, 0, 01Fh, 3FFh, 020h, 0h];--mask: 7FFF, inhibit: 8000
CBusWrite[h, Eval, writeEndAdd, 3];
CBusWrite[h, Eval, writeExtRamCtl, vramBypass];
LoadRamWD[h, Eval, 5h, 0h, 0h, 20h]; --Lit:5; 0 0; 80
Cycle[h, Eval, 4, TRUE]; --clear the DSRs
p[Start].b ← TRUE;
Cycle[h, Eval, 4];
Wait[0,1];
p[Start].b ← FALSE;
LoadRamWD[h, Eval, 1h, 0h, 2h, 20h];-- 1; 0 2; 80
Wait[1,2];
LoadRamWD[h, Eval, 3h, 0h, 4h, 140h];-- 3; 0 4; Cpy:5,0;
Wait[2,3];
LoadRamWD[h, Eval, 1h, 0h, 3FFh, 0h];--Lit:1; 0 FF;
Wait[3,4];
TerminalIO.PutRope["\nRef Clock:"];
FOR i: NAT IN [0..20) DO
TerminalIO.PutF[" %g", IO.bool[BITAND[PERead[h, Eval, 15, ioCtl], phaseCompEarly]=1]];
Cycle[h, Eval, 1];
ENDLOOP;
TerminalIO.PutRope["\n"];
[] ← RamRead[h, Eval, ERam, 0];
[] ← RamRead[h, Eval, ERam, 1];
[] ← RamRead[h, Eval, ERam, 2];
[] ← RamRead[h, Eval, ERam, 3];
[] ← RamRead[h, Eval, ERam, 4];
[] ← RamRead[h, Eval, ERam, 5];
[] ← RamRead[h, Eval, ERam, 6];
};
SimpleVRamTest: TProc ~ {
p: Port ← h.port;
TerminalIO.PutRope["***Simple VRam Test***\n"];
RamWrite[h, Eval, VRam, 1, 1h, 1h, 1h, 1h];
RamWrite[h, Eval, VRam, 2, 2h, 2h, 2h, 2h];
RamWrite[h, Eval, VRam, 3, 3h, 3h, 3h, 3h];
[] ← RamRead[h, Eval, VRam, 1];
[] ← RamRead[h, Eval, VRam, 2];
[] ← RamRead[h, Eval, VRam, 3];
};
VRamTest: TProc ~ {
p: Port ← h.port;
TerminalIO.PutRope["***VRam Test***\n"];
InitTimingChan[h, Eval, 0, Sample, 8, 0, 0, 0, 0, 0];
PEWrite[h, Eval, 0, ioCtl, 0];
PEWrite[h, Eval, 0, format, rz];
InitTimingChan[h, Eval, 15, Delay, 6, 0, 0, 0, 0, 0];
InitTimingChan[h, Eval, 15, Width, 10, 0, 0, 0, 0, 0];
InitTimingChan[h, Eval, 15, Sample, 8, 0, 0, 0, 0, 0];
PEWrite[h, Eval, 15, ioCtl, 0];
PEWrite[h, Eval, 15, format, rz];
p[DUT].ds[0] ← drive;
p[DUT].ls[0] ← L;
FOR i: NAT IN [0..maxCycle) DO
driveVector[i] ← SELECT i FROM
IN [0..64) => 0,
IN [64..112) => IF i MOD 2 = 0 THEN 0 ELSE 8000h,
ENDCASE => 0;
ENDLOOP;
RamWrite[h, Eval, CRam, 0, 01Fh, 3FFh, 020h, 0h];--mask: 7FFF, inhibit: 8000
RamWrite[h, Eval, VRam, 0, 5h, 0h, 0h, 20h];
RamWrite[h, Eval, VRam, 1, 1h, 0h, 2h, 20h];
RamWrite[h, Eval, VRam, 2, 3h, 0h, 4h, 140h];
RamWrite[h, Eval, VRam, 3, 1h, 0h, 3FFh, 140h];
[] ← RamRead[h, Eval, CRam, 0];
[] ← RamRead[h, Eval, VRam, 0];
[] ← RamRead[h, Eval, VRam, 1];
[] ← RamRead[h, Eval, VRam, 2];
[] ← RamRead[h, Eval, VRam, 3];
CBusWrite[h, Eval, writeEndAdd, 03h];
CBusWrite[h, Eval, writeLoopAdd, 0h];
Cycle[h, Eval, 4, TRUE];
p[Start].b ← TRUE;
p[Loop].b ← TRUE;
Cycle[h, Eval, 4];
p[Start].b ← FALSE;
TerminalIO.PutRope["\nRef Clock:"];
FOR i: NAT IN [0..50) DO
TerminalIO.PutF[" %g", IO.bool[BITAND[PERead[h, Eval, 15, ioCtl], phaseCompEarly]=1]];
Cycle[h, Eval, 1];
ENDLOOP;
TerminalIO.PutRope["\n"];
[] ← RamRead[h, Eval, ERam, 0];
[] ← RamRead[h, Eval, ERam, 1];
[] ← RamRead[h, Eval, ERam, 2];
[] ← RamRead[h, Eval, ERam, 3];
[] ← RamRead[h, Eval, ERam, 4];
[] ← RamRead[h, Eval, ERam, 5];
[] ← RamRead[h, Eval, ERam, 6];
};
FromFileTest: PROC [h: Handle, Eval: REProc, fileName: ROPE] ~ {
GetData: PROC RETURNS [lastAdd: VRamAdd] ~ {
FOR add: NAT IN VRamAdd DO
RamWrite[h, Eval, VRam, add,
LOOPHOLE[IO.GetHWord[compStream ! IO.EndOfStream => GOTO huh]],
LOOPHOLE[IO.GetHWord[compStream ! IO.EndOfStream => GOTO huh]],
LOOPHOLE[IO.GetHWord[compStream ! IO.EndOfStream => GOTO huh]],
LOOPHOLE[IO.GetHWord[compStream ! IO.EndOfStream => GOTO done]]
];
REPEAT
huh => {
TerminalIO.PutRope["\n ***Huh? Unexpected eof in compressed input stream, STREAM TRUCATED***"];
lastAdd ← add-1;
};
done => {lastAdd ← add};
FINISHED => {TerminalIO.PutRope["\n ***Compressed input stream too long, STREAM TRUCATED***"];
lastAdd ← add
};
ENDLOOP;
};
InitChan: PROC [ch: Channel] ~ {
InitTimingChan[h, Eval, ch, Delay, 6, 0, 0, 0, 0, 0];
InitTimingChan[h, Eval, ch, Width, 10, 0, 0, 0, 0, 0];
InitTimingChan[h, Eval, ch, Sample, 8, 0, 0, 0, 0, 0];
PEWrite[h, Eval, ch, ioCtl, 0];
PEWrite[h, Eval, ch, format, dnrz];
};
p: Port ← h.port;
sourceStream: IO.STREAMFS.StreamOpen[fileName: Rope.Concat[fileName, ".bin"], wDir: CommandTool.CurrentWorkingDirectory[], streamOptions: FS.binaryStreamOptions];
compStream: IO.STREAMFS.StreamOpen[fileName: Rope.Concat[fileName, ".bin.com"], wDir: CommandTool.CurrentWorkingDirectory[], streamOptions: FS.binaryStreamOptions];
cycCount: CARDINAL ← 0;
TerminalIO.PutRope[IO.PutFR["***Vectors from file: %g***\n", IO.rope[fileName]]];
FOR i: NAT IN Channel DO
InitChan[i];
ENDLOOP;
RamWrite[h, Eval, CRam, 0, 03Fh, 3FFh, 000h, 0h];--mask: FFFF, inhibit: 0000
CBusWrite[h, Eval, writeLoopAdd, 0h];
CBusWrite[h, Eval, writeEndAdd, GetData[]];
p[Start].b ← TRUE;
Cycle[h, Eval, 4, TRUE];
p[Start].b ← FALSE;
Cycle[h, Eval, 200];
IO.Close[sourceStream];
IO.Close[compStream];
};
PEWrite: PROC [h: Handle, Eval: REProc, chan: Channel, reg: PEReg, data: PEData, timing: Timing ← Sample] ~ {
To write the ioCtl and Format registers, use default: timing ← Sample since these regs are not asociated with any particular timing chain
CBusWrite[h, Eval, (chan*24)+(timing.ORD*8)+reg, data];
};
PERead: PROC [h: Handle, Eval: REProc, chan: Channel, reg: PEReg, timing: Timing ← Sample] RETURNS [data: PEData] ~ {
To read the ioCtl and Format registers, use default: timing ← Sample since these regs are not asociated with any particular timing chain
data ← CBusRead[h, Eval, (chan*24)+(timing.ORD*8)+reg];
};
RamWrite: PROC [h: Handle, Eval: REProc, which: Ram, add: [0..1023], d0, d1, d2, d3: [0..1023]] ~ {
TerminalIO.PutRope[IO.PutFLR["Write %g Add: %x, Data: %x, %x, %x, %x\n", LIST[IO.rope[
SELECT which FROM
VRam => "VRam",
HRam => "HRam",
ERam => "ERam",
CRam => "CRam",
ENDCASE => ERROR],
IO.card[add], IO.card[d0], IO.card[d1], IO.card[d2], IO.card[d3]]]];
CBusWrite[h, Eval, writeExtRamAdd, add];
LoadRamWD[h, Eval, d0, d1, d2, d3];
CBusWrite[h, Eval, writeExtRamCtl, extRamAccess];
CBusWrite[h, Eval, writeExtRamCtl, SELECT which FROM
VRam => writeVRam,
HRam => writeHRam,
ERam => writeERam,
CRam => writeCRam,
ENDCASE => ERROR];
IF which=VRam THEN Cycle[h, Eval, 6];
CBusWrite[h, Eval, writeExtRamCtl, extRamAccess];
CBusWrite[h, Eval, writeExtRamCtl, 0];
IF which=VRam THEN Cycle[h, Eval, 4];
};
RamRead: PROC [h: Handle, Eval: REProc, which: Ram, add: [0..1023]]
RETURNS [d0, d1, d2, d3: [0..1023]] ~ {
CBusWrite[h, Eval, writeExtRamAdd, add];
CBusWrite[h, Eval, writeExtRamCtl, extRamAccess];
CBusWrite[h, Eval, writeExtRamCtl, SELECT which FROM
VRam => readVRam,
HRam => readHRam,
ERam => readERam,
CRam => readCRam,
ENDCASE => ERROR];
IF which=VRam THEN Cycle[h, Eval, 6];
[d0, d1, d2, d3] ← FetchRamRD[h, Eval];
CBusWrite[h, Eval, writeExtRamCtl, 0];
IF which=VRam THEN Cycle[h, Eval, 4];
TerminalIO.PutRope[IO.PutFLR["Read %g Add: %x, Data: %x, %x, %x, %x\n", LIST[IO.rope[
SELECT which FROM
VRam => "VRam",
HRam => "HRam",
ERam => "ERam",
CRam => "CRam",
ENDCASE => ERROR],
IO.card[add], IO.card[d0], IO.card[d1], IO.card[d2], IO.card[d3]]]];
};
LoadRamWD: PROC [h: Handle, Eval: REProc, d0, d1, d2, d3: [0..1023]] ~ {
CBusWrite[h, Eval, ramWD0, d0];
CBusWrite[h, Eval, ramWD1, d1];
CBusWrite[h, Eval, ramWD2, d2];
CBusWrite[h, Eval, ramWD3, d3];
};
FetchRamRD: PROC [h: Handle, Eval: REProc] RETURNS [d0, d1, d2, d3: [0..1023]] ~ {
d0 ← CBusRead[h, Eval, ramRD0];
d1 ← CBusRead[h, Eval, ramRD1];
d2 ← CBusRead[h, Eval, ramRD2];
d3 ← CBusRead[h, Eval, ramRD3];
};
CBusRead: PROC [h: Handle, Eval: REProc, add: [0..1023]] RETURNS [data: [0..1023]] ~ {
Eval: TYPE = PROC [memory: BOOL ← TRUE, clockEval: BOOL ← FALSE, checkPorts: BOOL ← TRUE];
p: Port ← h.port;
p[CAdrData].d ← drive;
p[CAdrData].c ← add;
Eval[TRUE, FALSE, TRUE];
p[CAdrStb].b ← TRUE;
Eval[TRUE, FALSE, TRUE];
p[CAdrStb].b ← FALSE;
Eval[TRUE, FALSE, TRUE];
p[CAdrData].d ← none;
p[CAdrData].d ← inspect;
Eval[TRUE, FALSE, TRUE];
p[CReadStb].b ← TRUE;
Eval[TRUE, FALSE, TRUE];
data ← p[CAdrData].c;
Eval[TRUE, FALSE, TRUE];
p[CReadStb].b ← FALSE;
p[CAdrData].c ← 0;
p[CAdrData].d ← none;
Eval[TRUE, FALSE, TRUE];
};
CBusWrite: PROC [h: Handle, Eval: REProc, add: [0..1023], data: [0..1023]] ~ {
Eval: TYPE = PROC [memory: BOOL ← TRUE, clockEval: BOOL ← FALSE, checkPorts: BOOL ← TRUE];
p: Port ← h.port;
p[CAdrData].d ← drive;
p[CAdrData].c ← add;
Eval[TRUE, FALSE, TRUE];
p[CAdrStb].b ← TRUE;
Eval[TRUE, FALSE, TRUE];
p[CAdrStb].b ← FALSE;
Eval[TRUE, FALSE, TRUE];
p[CAdrData].d ← drive;
p[CAdrData].c ← data;
Eval[TRUE, FALSE, TRUE];
p[CWriteStb].b ← TRUE;
Eval[TRUE, FALSE, TRUE];
p[CWriteStb].b ← FALSE;
Eval[TRUE, FALSE, TRUE];
p[CAdrData].c ← 0;
p[CAdrData].d ← none;
};
Cycle: PROC [h: Handle, Eval: REProc, n: CARDINAL ← 1, holdCycDiv2: BOOLFALSE] ~ {
p: Port ← h.port;
THROUGH [0..n) DO
Ports.CToLS[driveVector[h.cycle], p[DUT].ls];
Eval[TRUE, FALSE, FALSE]; --ignore errors before clock rises
p[CycCK].b ← TRUE;
p[CK].b ← TRUE;
Eval[TRUE, TRUE, FALSE]; --ignore errors during clockEval
Eval[TRUE, FALSE, TRUE];
p[CK].b ← FALSE;
Eval[TRUE, FALSE, TRUE];
Eval[TRUE, FALSE, TRUE];
p[CK].b ← TRUE;
Eval[TRUE, FALSE, TRUE];
p[CK].b ← FALSE;
p[CycDiv2].b ← NOT h.prevClkDiv2 AND NOT holdCycDiv2;
h.prevClkDiv2p[CycDiv2].b;
Eval[TRUE, FALSE, TRUE];
Eval[TRUE, FALSE, TRUE];
p[CycCK].b ← FALSE;
p[CK].b ← TRUE;
Eval[TRUE, TRUE, TRUE];
p[CK].b ← FALSE;
p[RefCK].b ← TRUE;
Eval[TRUE, FALSE, TRUE];
Eval[TRUE, FALSE, TRUE];
p[CK].b ← TRUE;
p[RefCK].b ← FALSE;
Eval[TRUE, FALSE, TRUE];
p[CK].b ← FALSE;
Eval[TRUE, FALSE, TRUE];
Eval[TRUE, FALSE, TRUE];
h.cycle ← h.cycle+1;
ENDLOOP;
};
InitPortIndicies: PROC [ct: Core.CellType] ~ {
[RefCK, nError, nCS, CAdrData, ExtReset, Start, Loop, CAdrStb, CWriteStb] ← Ports.PortIndexes[ct.public, "RefCK", "nError", "nCS", "CAdrData", "ExtReset", "Start", "Loop", "CAdrStb", "CWriteStb"];
[CReadStb, CK, CycCK, CycDiv2, DUT] ← Ports.PortIndexes[ct.public, "CReadStb", "CK", "CycCK", "CycDiv2", "DUT"];
Vdd ← Ports.PortIndex[ct.public, "Vdd"];
Gnd ← Ports.PortIndex[ct.public, "Gnd"];
};
CDExtract: PROC [comm: CDSequencer.Command] = {
design ← comm.design;
[] ← DoExtract[];
};
Extract: PROC [fileName: ROPENIL, wDir: ROPE] RETURNS [ct: Core.CellType]~ {
FindDesign[fileName, wDir];
ct ← DoExtract[];
};
DoExtract: PROC RETURNS [ct: Core.CellType] ~ {
ct ← Sisyph.ExtractSchematicByName["TestarossaTest.sch", Sisyph.Create[design]];
CDProperties.PutDesignProp[design, $TestarossaCellType, ct];
};
FindDesign: PROC [fileName: ROPENIL, wDir: ROPENIL] ~ {
IF design=NIL THEN design ← NARROW[Atom.GetProp[$Testarossa, $Design]];
IF design=NIL THEN design ← CDViewer.FindDesign["Testarossa"];
IF design=NIL THEN {
design ← CDIO.ReadDesign[fileName, NIL, wDir];
CDOps.SetMutability[design];
Viewer[];
};
Atom.PutProp[$Testarossa, $Design, design];
};
Viewer: PROC ~ {
[] ← CDViewer.CreateViewer[design];
};
Simulate: PROC RETURNS [tester: RosemaryUser.Tester] ~ {
ct: Core.CellType ← NARROW[CDProperties.GetDesignProp[design, $TestarossaCellType]];
InitPortIndicies[ct];
[] ← Rosemary.SetFixedWire[ct.public[Vdd], H];
[] ← Rosemary.SetFixedWire[ct.public[Gnd], L];
tester ← RosemaryUser.TestProcedureViewer[
cellType: ct,
testButtons: LIST["TestAll"],
name: "Testarossa Tester",
displayWires: RosemaryUser.DisplayPortLeafWires[ct],
cutSet: CoreFlat.CreateCutSet[cellTypes: LIST["DRam"], labels: cutSet],
recordDeltas: TRUE];
CDProperties.PutDesignProp[design, $TestarossaTester, tester];
CoreCDUser.SetDesignRootCellType[design, ct];
CoreCDUser.SetRootCellTypeDecoration[ct, Sisyph.mode.decoration];
};
StartTest: PROC ~ {
RosemaryUser.StartTest[NARROW[CDProperties.GetDesignProp[design, $TestarossaTester], RosemaryUser.Tester]];
};
RosemaryUser.RegisterTestProc["TestAll", TestAll];
CDCommandOps.RegisterWithMenu[
menu: $ProgramMenu,
entry: "Extract TR",
doc: "",
proc: CDExtract
];
END.