TestDRam.mesa
Copyright Ó 1986 by Xerox Corporation. All rights reserved.
Last Change: February 13, 1987 11:53:29 am PST
Bob Krivacic, January 14, 1987 2:30:40 pm PST

Module to test Dynamic Rams, reading in
the test vectors off of a disk file.
DIRECTORY Core, CoreCreate, ICTest, Ports, Rope, TestCable, IO, FS, Convert;
TestDRam: CEDAR PROGRAM

IMPORTS CoreCreate, ICTest, Ports, TestCable, Rope, IO, FS, Convert
= BEGIN
-- Types
ROPE: TYPE = Rope.ROPE;
VectorEntries: TYPE = RECORD [entrymode: ATOM, entryvalue: LONG CARDINAL];
TestVector: TYPE = ARRAY [0..20] OF VectorEntries;
-- Vector Assignments
vectorStream,outstream: IO.STREAM;
endofvectors: BOOL;
vectors: TestVector;
debugging: BOOL;
-- Port Assignments
ras: NAT = 0;
cas: NAT = 1;
we: NAT = 2;
addr: NAT = 3;
datain: NAT = 4;
dataout: NAT = 5;
trigger: NAT = 6;
lastport: NAT = 6;
-- Program Controled Ports:
gnd: NAT = 7;
vdd: NAT = 8;
cycle: NAT = 9;
-- Other Globals:
Assignments: TYPE = ICTest.Assignments;
assignments: Assignments;
thisTest: Rope.ROPE = "DRam Tester";
groups: ICTest.Groups ← NIL;
PrintAssignments: PROC = {
stream: FS.STREAMFS.StreamOpen["Pinout.txt",$create];
j: ICTest.Assignment;
i: Assignments ← assignments;
WHILE i#NIL DO {
j ← i.first;
IO.PutF[stream,"%15g: ",IO.rope[j.name]];
IF j.group = 0 THEN
IO.PutF[stream," "]
ELSE
IO.PutF[stream,"%g %g.%g[%1g] ",
IO.rope[IF j.loadBoardSide = R THEN "Right" ELSE "Left "],
IO.rope[
SELECT j.podPair FROM
AB => "AB",
CD => "CD",
EF => "EF",
GH => "GH",
IJ => "IJ",
KL => "KL",
ENDCASE => "??"],
IO.char[SELECT j.pod FROM A => 'A, B => 'B, ENDCASE => '?],
IO.int[j.channel],
];
IO.PutF[stream," ← %3g \n",IO.int[j.probeCardPin]];
i ← i.rest;
};
ENDLOOP;
IO.Close[stream];
};
Init: PROC = {
R: PROC [a: ICTest.Assignment] = {assignments ← CONS[a, assignments]};
ct: Core.CellType ←
CoreCreate.Cell[name:"DRam",
public: CoreCreate.WireList[LIST[
"ras",
"cas",
"we",
CoreCreate.Seq["addr",10],
"datain",
"dataout",
"trigger",
"gnd","vdd","cycle"]],
onlyInternal: NIL,
instances: NIL
];
assignments ← NIL;
groups ← LIST [
[number: 1,
name: "CtlLines",
directionality: force,
format: DNRZ,
delay: 0],
[number: 2,
name: "DataIn",
directionality: force,
format: DNRZ,
delay: 0],
[number: 3,
name: "DataOut",
directionality: acquire,
format: DNRZ,
sample: 5],
[number: 4,
name: "ClockCycle",
directionality: force,
format: RZ,
delay: 0, width: 20]
];
assignments ← NIL;
L
o
a T
d e
s
B t D
o e U
a P r T
r o C D
d d h H H U
G B a e e T
r o S P B n a a
o a i a y n d d P
u r d i t e e e i
Signal Name p d e r e l r r n
R[["gnd", 0,0,R,AB, A,1,001,001,18]];
R[["vdd", 0,0,R,AB, A,0,001,001,9]];
R[["ras", 1,0,R,AB, B,0,001,001,3]];
R[["cas", 1,0,R,AB, B,1,001,001,16]];
R[["we", 1,0,R,AB, B,2,001,001,2]];
R[["trigger", 1,0,R,AB, B,3,001,001,100]];
R[["addr[9]", 1,2,R,EF, B,1,001,001,15]];
R[["addr[8]", 1,2,R,EF, B,0,001,001,14]];
R[["addr[7]", 1,1,R,CD, B,7,001,001,13]];
R[["addr[6]", 1,1,R,CD, B,6,001,001,12]];
R[["addr[5]", 1,1,R,CD, B,5,001,001,11]];
R[["addr[4]", 1,1,R,CD, B,4,001,001,10]];
R[["addr[3]", 1,1,R,CD, B,3,001,001,8]];
R[["addr[2]", 1,1,R,CD, B,2,001,001,7]];
R[["addr[1]", 1,1,R,CD, B,1,001,001,6]];
R[["addr[0]", 1,1,R,CD, B,0,001,001,5]];
R[["datain", 2,3,R,GH, B,0,001,001,1]];
R[["dataout", 3,4,R,IJ, B,0,001,001,17]];
R[["cycle", 4,0,R,AB, A,3,001,001,200]];
[] ← Ports.InitPort[ct.public[datain],c];
[] ← Ports.InitPort[ct.public[dataout],c];
[] ← Ports.InitPort[ct.public[addr],c];
[] ← Ports.InitPort[ct.public[ras],c];
[] ← Ports.InitPort[ct.public[cas],c];
[] ← Ports.InitPort[ct.public[we],c];
[] ← Ports.InitPort[ct.public[cycle],b];
[] ← Ports.InitPort[ct.public[trigger],c];
Ports.InitTesterDrive[ct.public[vdd],force];
Ports.InitTesterDrive[ct.public[gnd],force];
Ports.InitTesterDrive[ct.public[cycle],force];
Ports.InitTesterDrive[ct.public[addr],force];
Ports.InitTesterDrive[ct.public[ras],force];
Ports.InitTesterDrive[ct.public[cas],force];
Ports.InitTesterDrive[ct.public[we],force];
Ports.InitTesterDrive[ct.public[datain],force];
Ports.InitTesterDrive[ct.public[dataout],none];
Ports.InitTesterDrive[ct.public[trigger],force];
TestCable.Init[groups, assignments, "cycle"];
ICTest.MakeStandardViewer[
testName: thisTest,
cellType: ct,
clockAName: "cycle",
groups: groups,
assignments: assignments,
period: 250];
};
PeriodChange: ICTest.PeriodChangeProc ~ {
--PROC [period: Period] RETURNS [newGroups: Groups]--
FOR g: ICTest.Groups ← groups, g.rest WHILE g#NIL DO
g.first.delay ← (g.first.delay*period)/oldPeriod;
g.first.width ← (g.first.width*period)/oldPeriod;
g.first.sample ← (g.first.sample*period)/oldPeriod;
ENDLOOP;
RETURN[groups];
};
NextVector: PROC = {
-- Read in the next cycle's test vectors
i,j: INT;
needrparen: BOOL;
token: ROPE;
needrparen ← TRUE; j𡤀 i𡤀
IF ~ IO.EndOf[vectorStream] THEN {
WHILE needrparen AND ~ endofvectors AND ~ IO.EndOf[vectorStream] DO {
j ← j+1;
token ← IO.GetTokenRope[vectorStream].token;
SELECT Rope.Fetch[token,0] FROM
') =>
needrparen ← FALSE;
'( =>
i ← 0;
'S => {
vectors[i].entryvalue ← Convert.CardFromRope[Rope.Substr[token,1]];
vectors[i].entrymode ← $Set;
i ← i + 1; };
'x,'X => {
vectors[i].entryvalue ← 0;
vectors[i].entrymode ← $Ignore;
i ← i + 1; };
'E =>
endofvectors ← TRUE;
'0,'1,'2,'3,'4,'5,'6,'7,'8,'9 => {
vectors[i].entryvalue ← Convert.CardFromRope[token];
vectors[i].entrymode ← $Set;
i ← i + 1; };
ENDCASE;
};
ENDLOOP;
}
ELSE endofvectors ← TRUE;
};
OpenVectors: PROC = {
vectorStream ← FS.StreamOpen["///datools/DRam2.txt"];
IF debugging THEN outstream ← FS.StreamOpen["///datools/debug.txt", $create];
endofvectors ← FALSE;
NextVector[];
};
CloseVectors: PROC = {
IO.Close[vectorStream];
IF debugging THEN IO.Close[outstream];
};
DoTest: ICTest.TestProc = {
SetP: PROC [vectorindex, value: LONG CARDINAL, mode: Ports.Drive] = {
p[vectorindex].d ← mode;
p[vectorindex].c ← value;
};
ClearEntry: PROC [vectorindex: INT] = {
SetP[vectorindex, 0, none];
};
SetEntry: PROC [vectorindex: INT] = {
SELECT vectors[vectorindex].entrymode FROM
$Set => SetP[vectorindex, vectors[vectorindex].entryvalue, force];
$Check => SetP[vectorindex, vectors[vectorindex].entryvalue, expect];
$Ignore => SetP[vectorindex, 0, none];
ENDCASE;
};
DoEval: PROC = {
p[cycle].b ← TRUE;
IF debugging THEN
FOR i: INT ← 0, i+1 DO {
IF i > lastport THEN {IO.Put[outstream,IO.char[15C]]; EXIT;}
ELSE {
IO.PutF[outstream,
SELECT p[i].d FROM
expect => " C: ",
force => " S: ",
drive => " D: ",
none => " x ",
ENDCASE => " ?: "
];
IF p[i].d # none THEN IO.Put[outstream,IO.int[p[i].c]];
};
};
ENDLOOP
ELSE Eval[];
};
Cycle: PROC = {
FOR i: INT ← 0, i+1 DO
SetEntry[i];
IF i = lastport THEN EXIT;
ENDLOOP;
DoEval[];
};
InitState: PROC = {
FOR i: INT ← 0, i+1 DO
ClearEntry[i];
IF i = lastport THEN EXIT;
ENDLOOP;
p[gnd].c ← 0; p[gnd].d ← force;
p[vdd].c ← 1; p[vdd].d ← force;
p[cycle].b ← TRUE; p[cycle].d ← force;
};
InitState[];
OpenVectors[];
WHILE ~endofvectors DO
Cycle[];
NextVector[];
ENDLOOP;
CloseVectors[];
};
Runit: PROC = {
debugging ← FALSE;
Init[];
ICTest.RegisterTestProc[thisTest,"RamTest",DoTest];
ICTest.RegisterTestProc[thisTest,"TestCable",TestCable.TestCable];
ICTest.RegisterPeriodChangeProc[thisTest, PeriodChange];
};
Runit[];
END.