-- JaMMOSSIMFnsImplB.mesa
-- created by Haeberli from JamMOSSIM.mesa: 7-Jan-82 13:17:11
DIRECTORY
InlineDefs,
JaMFnsDefs,
JaMMOSSIMFns,
Mopcodes,
MOSSIMFns,
StreamDefs,
StringDefs;
JaMMOSSIMFnsImplB: PROGRAM
IMPORTS InlineDefs, JaMFnsDefs, JaMMOSSIMFns, MOSSIMFns
EXPORTS JaMMOSSIMFns =
{
OPEN InlineDefs, JaMFnsDefs, JaMMOSSIMFns, MOSSIMFns, StreamDefs;
--vector of channel commands for the tester A channels
--In OutA and Enable, bit 0 means send this group of 8 bits at the next step
OutA: ARRAY [0..15] OF WORD;
--vector of channel commands for the tester Enable channels. Initialized
--to Disabled (0).
Enable: ARRAY [0..15] OF WORD;
--array of bits, one per channel, containing the channels to be inspected
--after the next step.
Look: ARRAY [0..7] OF WORD;
--array of bits containing the expected values for the channels in Look.
--The tester does: "if (Result xor Expected) and Look # 0 then error"
Expected: ARRAY [0..7] OF WORD;
s: StreamDefs.StreamHandle; --output stream for vectors
CheckFirstBlock, CheckSecondBlock: BOOLEAN; --indicates that
--some value in the block was examined, so tester
--must do a read/compare before doing the next step.
DoStep: BOOLEAN ← FALSE; --have changed some edge pin input, so do a step
--modified at least one edge pin (as opposed to internal nodes).
StepControl: TYPE = CARDINAL [0..15];
Steps: LONG DESCRIPTOR FOR PACKED ARRAY OF StepControl;
Data: LONG DESCRIPTOR FOR ARRAY OF WORD;
StepCount: CARDINAL;
DataCount: CARDINAL;
--Read the file into core. Takes a stream from JaM, returns number
--of steps loaded
LoadTest: PUBLIC PROC = {
item: WORD;
BlockCount: CARDINAL ← 0; --count of words sent in the current block
NopInst: CARDINAL = 0;
k: CARDINAL;
Steps ← DESCRIPTOR[1000000B, 2000B]; --first 1k of bank 4
Data ← DESCRIPTOR[1002000B, 176000B]; --rest of bank 4
s ← PopStream[];
StepCount ← 0;
DataCount ← 8; --skip temp buffer
UNTIL s.endof[s] DO
item ← s.get[s];
IF BITAND[item, 100000B] # 0 THEN --block done
{
--fill out block to 4 or 8 words (with nops)
UNTIL ((BlockCount > 0) AND ((BlockCount MOD 4) = 0)) DO
Data[DataCount] ← NopInst;
DataCount ← DataCount + 1;
BlockCount ← BlockCount + 1;
ENDLOOP;
--set the GO bit in the last word
Data[DataCount - 1] ← BITOR[Data[DataCount - 1], 100000B];
--In bad cases, we can have as many as 12 4-word blocks. Since the tester
--can only do 1 to 4 blocks per step, we may have to do multiple steps.
UNTIL BlockCount <= 16 DO
Steps[StepCount] ← 14B; --tells the tester to send 4 blocks, no read
StepCount ← StepCount + 1;
BlockCount ← BlockCount - 16;
ENDLOOP;
--Check for read after step
IF BITAND[item, 1] # 0 THEN --want to read/check the first block
{
FOR k IN [0..7] DO
Data[DataCount] ← s.get[s]; DataCount ← DataCount + 1; ENDLOOP;
BlockCount ← BlockCount + 1;
};
IF BITAND[item, 2] # 0 THEN --want to read/check the second block
{
FOR k IN [0..7] DO
Data[DataCount] ← s.get[s]; DataCount ← DataCount + 1; ENDLOOP;
BlockCount ← BlockCount + 2;
};
BlockCount ← BlockCount - 4; --since it is biased
Steps[StepCount] ← LOOPHOLE[BlockCount, StepControl];
StepCount ← StepCount + 1;
BlockCount ← 0;
}
ELSE {
Data[DataCount] ← item;
DataCount ← DataCount + 1;
BlockCount ← BlockCount + 1;
};
ENDLOOP;
PushInteger[LOOPHOLE[StepCount, INTEGER]]; --return the number of steps
};
DoTest: PROC [c: INTEGER, control, data: LONG POINTER] RETURNS [cc: INTEGER] =
MACHINE CODE {Mopcodes.zMISC, 14B};
DoOutput: PROC [data, addr: WORD] = MACHINE CODE {Mopcodes.zMISC, 6B};
DoInput: PROC [addr: INTEGER] RETURNS [data: INTEGER] = MACHINE CODE {
Mopcodes.zMISC, 5B};
--Do Output from JaM
Out: PUBLIC PROC = {
addr, data: INTEGER;
addr ← PopInteger[];
data ← PopInteger[];
DoOutput[data, addr];
};
--Do Input from Jam
In: PUBLIC PROC = {
addr, data: INTEGER;
addr ← PopInteger[];
data ← DoInput[addr];
PushInteger[data];
};
--Set up fixed tester registers
SetUpTester: PUBLIC PROC = {
e: ARRAY [0..14] OF INTEGER ← [
20377B, 20777B, 21377B, 21777B, 22377B, 22777B, 23377B, 23777B, 24377B,
24777B, 25377B, 25777B, 26377B, 26777B, 27377B];
a: ARRAY [0..14] OF INTEGER ← [
40000B, 40400B, 41000B, 41400B, 42000B, 42400B, 43000B, 43400B, 44000B,
44400B, 45000B, 45400B, 46000B, 46400B, 47000B];
b: ARRAY [0..14] OF INTEGER ← [
60377B, 60777B, 61377B, 61777B, 62377B, 62777B, 63377B, 63777B, 64377B,
64777B, 65377B, 65777B, 66377B, 66777B, 67377B];
i: CARDINAL;
DoOutput[1, 0]; --release reset
DoOutput[2000B, 1]; --input group select buffer ← 0
DoOutput[4020B, 1]; --clock parameter 1
DoOutput[10777B, 1]; --clock parameter 2
FOR i IN [0..14] DO
DoOutput[a[i], 1]; --A channels ← 0
DoOutput[b[i], 1]; --B channels ← 1
DoOutput[e[i], 1]; --Enable channels ← 1 (open)
ENDLOOP;
DoOutput[100000B, 1]; --Do one step
};
--Run a test. Takes a step count and returns final step count
RunTest: PUBLIC PROC = {
InCount, OutCount: INTEGER;
StepAddr: LONG POINTER = LOOPHOLE[1000000B, LONG POINTER];
DataAddr: LONG POINTER = LOOPHOLE[1002000B, LONG POINTER];
i: CARDINAL;
InCount ← PopInteger[];
OutCount ← DoTest[InCount, StepAddr, DataAddr];
PushInteger[OutCount]; --return final step
FOR i IN [0..7] DO
PushInteger[LOOPHOLE[(LOOPHOLE[1002000B + i, LONG POINTER])↑, INTEGER]];
ENDLOOP;
};
CheckTest: PUBLIC PROC = {
s: StreamDefs.StreamHandle;
i: CARDINAL;
sc: StepControl;
wc: CARDINAL;
dc: CARDINAL ← 8; --data blocks begin at word 8
s ← PopStream[];
FOR i IN [0..StepCount - 1] DO
sc ← Steps[i];
--form word count
wc ← 4 + BITAND[sc, 14B] + ((BITAND[sc, 1]) + (BITAND[sc, 2]/2))*8;
s.put[s, sc];
UNTIL wc = 0 DO s.put[s, Data[dc]]; dc ← dc + 1; wc ← wc - 1; ENDLOOP;
ENDLOOP;
};
--Tinit takes the output stream from Jam, and initializes the tester tables.
Tinit: PUBLIC PROC = {
i: CARDINAL;
s ← PopStream[];
OutA ← [
40000B, 40400B, 41000B, 41400B, 42000B, 42400B, 43000B, 43400B, 44000B,
44400B, 45000B, 45400B, 46000B, 46400B, 47000B, 47400B];
Enable ← [
20000B, 20400B, 21000B, 21400B, 22000B, 22400B, 23000B, 23400B, 24000B,
24400B, 25000B, 25400B, 26000B, 26400B, 27000B, 27400B];
FOR i IN [0..7] DO Look[i] ← 0; Expected[i] ← 0; ENDLOOP;
CheckFirstBlock ← FALSE;
CheckSecondBlock ← FALSE;
DoStep ← FALSE;
};
--use THi instead of hi when sending data to the tester. Takes a channel
--number and a name. Sends to the simulator and tester.
THi: PUBLIC PROC = {
ch, m, i: INTEGER;
ch ← PopInteger[];
i ← ch/8;
m ← BITSHIFT[200B, -BITAND[ch, 7]];
IF BITAND[Enable[i], m] = 0 THEN --if not enabled
{
Enable[i] ← BITOR[Enable[i], BITOR[100000B, m]]; --set the enable
OutA[i] ← BITOR[OutA[i], BITOR[100000B, m]]; --set the bit
}
ELSE --if not equal to current value
IF BITAND[OutA[i], m] # m THEN OutA[i] ← BITOR[OutA[i], BITOR[100000B, m]];
SetInputHigh[];
};
--use TLo instead of lo when sending data to the tester. Takes a channel
--number and a name. Sends to the simulator and tester.
TLo: PUBLIC PROC = {
ch, m, i: INTEGER;
ch ← PopInteger[];
i ← ch/8;
m ← BITSHIFT[200B, -BITAND[ch, 7]];
IF BITAND[Enable[i], m] = 0 THEN --if not enabled
{
Enable[i] ← BITOR[Enable[i], BITOR[100000B, m]]; --set the enable
OutA[i] ← BITOR[BITAND[BITNOT[m], OutA[i]], 100000B]; --clear the bit
}
ELSE --if not equal to current value
IF BITAND[OutA[i], m] # 0 THEN
OutA[i] ← BITOR[BITAND[BITNOT[m], OutA[i]], 100000B]; --clear the bit
SetInputLow[];
};
--use Tx instead of x when sending data to the tester. Takes a channel
--number and a name. Sends to the simulator and tester.
Tx: PUBLIC PROC = {
ch, m, i: INTEGER;
ch ← PopInteger[];
i ← ch/8;
m ← BITSHIFT[200B, -BITAND[ch, 7]];
IF BITAND[Enable[i], m] # 0 THEN --if enabled
Enable[i] ← BITOR[BITAND[BITNOT[m], Enable[i]], 100000B]; --clear the enable
SetInputX[];
};
--Gnv1 takes a channel number and puts the channel into the read vectors.
--The comparison is done with the data provided by the simulator.
Gnv1: PUBLIC PROC = {
value: INTEGER;
ch: INTEGER ← PopInteger[];
i: INTEGER ← ch/16;
m: INTEGER ← BITSHIFT[100000B, -BITAND[ch, 17B]];
IF i < 4 THEN CheckFirstBlock ← TRUE ELSE CheckSecondBlock ← TRUE;
targv[1].length ← 0;
PopString[targv[1]];
targc ← 2;
value ← getNodeValue[];
Look[i] ← BITOR[Look[i], m];
Expected[i] ←
(IF value = 0 THEN (BITAND[Expected[i], BITNOT[m]])
ELSE (BITOR[Expected[i], m]));
PushInteger[value];
};
--Tstep does one step and outputs commands for changed channels to the
--tester. It is called by the Jam program after all values generated by
--the previous step (if any) have been examined,
--and after all input values for this
--step have been set up. We output the step command for the previous tester
--cycle at this time, with the Read bit ON if any values were examined.
--Then we output Look and Expected if any values were read, then we output the
--Input vectors for the next step, and STEP the simulator.
Tstep: PUBLIC PROC = {
nout: CARDINAL ← 0;
i: INTEGER;
control: WORD ← 100000B;
--put out the step command for previous data (if some input connected to a pin has been changed
IF DoStep THEN {
IF CheckFirstBlock THEN control ← control + 1;
IF CheckSecondBlock THEN control ← control + 2;
s.put[s, control];
IF CheckFirstBlock THEN {
FOR i IN [0..3] DO s.put[s, Expected[i]]; ENDLOOP;
FOR i IN [0..3] DO s.put[s, Look[i]]; Look[i] ← 0; ENDLOOP;
CheckFirstBlock ← FALSE;
};
IF CheckSecondBlock THEN {
FOR i IN [4..7] DO s.put[s, Expected[i]]; ENDLOOP;
FOR i IN [4..7] DO s.put[s, Look[i]]; Look[i] ← 0; ENDLOOP;
CheckSecondBlock ← FALSE;
};
};
--send any inputs that will change in preparation for the next step
FOR i IN [0..15] DO
IF BITAND[OutA[i], 100000B] # 0 THEN {
OutA[i] ← BITAND[OutA[i], 77777B]; s.put[s, OutA[i]]; nout ← nout + 1; };
IF BITAND[Enable[i], 100000B] # 0 THEN {
Enable[i] ← BITAND[Enable[i], 77777B];
s.put[s, BITXOR[Enable[i], 377B]]; --enables are inverted at the tester
nout ← nout + 1;
};
ENDLOOP;
DoStep ← TRUE;
Step[]; --step the simulator
};
-- New procedures to allow immediate manipulation of tester, if present.
--Set up tester without changing state
SetUpIntact: PUBLIC PROC = {
DoOutput[2000B, 1]; --input group select buffer ← 0
DoOutput[4020B, 1]; --clock parameter 1
DoOutput[10777B, 1]; --clock parameter 2
DoOutput[100000B, 1]; --Do one step
};
--Read the state of the tester quickly, without a test vector
ReadState: PUBLIC PROC = {
i: CARDINAL;
DoOutput[2000B, 1]; --input group select buffer ← 0
DoOutput[4020B, 1]; --clock parameter 1
DoOutput[10777B, 1]; --clock parameter 2
DoOutput[100000B, 1]; --Do one step
PushInteger[0]; --return final step
FOR i IN [0..7] DO PushInteger[DoInput[1]]; ENDLOOP;
};
--Read the state of a single tester channel
ReadChan: PUBLIC PROC = {
chan, binaryState: INTEGER;
w, b, i: CARDINAL;
state: ARRAY [0..7] OF WORD;
chan ← PopInteger[];
w ← chan/16;
b ← (chan MOD 16) - 15;
DoOutput[2000B, 1]; --input group select buffer ← 0
DoOutput[4020B, 1]; --clock parameter 1
DoOutput[10777B, 1]; --clock parameter 2
DoOutput[100000B, 1]; --Do one step
FOR i IN [0..7] DO state[i] ← DoInput[1]; ENDLOOP;
binaryState ← BITAND[BITSHIFT[state[w], b], 1];
PushInteger[binaryState];
};
--Set the state of a single tester channel
SetChan: PUBLIC PROC = {
chan, newState: INTEGER;
grp, w, b, i: CARDINAL;
data: WORD;
state: ARRAY [0..7] OF WORD;
chan ← PopInteger[];
newState ← BITAND[PopInteger[], 1];
w ← chan/16;
grp ← chan/8;
b ← 7 - (chan MOD 8);
DoOutput[2000B, 1]; --input group select buffer ← 0
DoOutput[4020B, 1]; --clock parameter 1
DoOutput[10777B, 1]; --clock parameter 2
DoOutput[100000B, 1]; --Do one step
FOR i IN [0..7] DO state[i] ← DoInput[1]; ENDLOOP;
data ← state[w];
IF BITAND[grp, 1] = 0 THEN data ← BITSHIFT[data, -8]
ELSE data ← BITAND[data, 377B];
data ← BITOR[BITAND[data, BITNOT[BITSHIFT[1, b]]], BITSHIFT[newState, b]];
DoOutput[40000B + BITSHIFT[grp, 8] + data, 1]; --set output
DoOutput[100000B, 1]; --Do one step
};
}.