-- 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 }; }.