OpenCores
URL https://opencores.org/ocsvn/ao68000/ao68000/trunk

Subversion Repositories ao68000

[/] [ao68000/] [trunk/] [sw/] [ao68000_tool/] [Tester.java] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 alfik
/*
2
 * Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without modification, are
5
 * permitted provided that the following conditions are met:
6
 *
7
 *  1. Redistributions of source code must retain the above copyright notice, this list of
8
 *     conditions and the following disclaimer.
9
 *
10
 *  2. Redistributions in binary form must reproduce the above copyright notice, this list
11
 *     of conditions and the following disclaimer in the documentation and/or other materials
12
 *     provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
15
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
 */
24
 
25
package ao68000_tool;
26
 
27
import java.io.File;
28
import java.util.HashMap;
29
import java.util.Random;
30
import java.util.Vector;
31
 
32
/*
33
 * 0000 0000 ss ddd DDD : ORI
34
 *
35
 * 0000 rrr1 00 ddd DDD : BTST
36
 * 0000 ddd1 ss 001 sss : MOVEP from memory
37
 *
38
 * 0000 rrr1 01 ddd DDD : BCHG
39
 * 0000 rrr1 10 ddd DDD : BCLR
40
 * 0000 rrr1 11 ddd DDD : BSET
41
 *
42
 * 0000 0010 ss ddd DDD : ANDI
43
 *
44
 * 0000 0100 ss ddd DDD : SUBI
45
 *
46
 * 0000 0110 ss ddd DDD : ADDI
47
 *
48
 * 0000 1000 00 ddd DDD : BTST imm
49
 * 0000 1000 01 ddd DDD : BCHG imm
50
 * 0000 1000 10 ddd DDD : BCLR imm
51
 * 0000 1000 11 ddd DDD : BSET imm
52
 *
53
 * 0000 1010 ss ddd DDD : EORI
54
 * 0000 1100 ss ddd DDD : CMPI
55
 *
56
 * 0000 1110 xx xxx xxx : illegal instruction
57
 *
58
 * 00ss DDDd dd sss SSS : MOVE
59
 * 00ss DDD0 01 sss SSS : MOVEA
60
 *
61
 * 0100 0000 ss ddd DDD : NEGX
62
 * 0100 0000 11 ddd DDD : MOVE FROM SR
63
 *
64
 * 0100 0001 00 xxx xxx : illegal instruction
65
 *
66
 * 0100 rrrs s0 ddd DDD : CHK
67
 * 0100 rrr1 11 ddd DDD : LEA
68
 *
69
 * 0100 0010 ss ddd DDD : CLR
70
 *
71
 * 0100 0100 ss ddd DDD : NEG
72
 * 0100 0100 11 sss SSS : MOVE TO CCR
73
 * 0100 0110 ss ddd DDD : NOT
74
 * 0100 0110 11 sss SSS : MOVE TO SR
75
 *
76
 * 0100 1000 00 ddd DDD : NBCD
77
 * 0100 1000 01 000 rrr : SWAP
78
 *
79
 * 0100 1000 01 001 xxx : illegal instruction
80
 * 0100 1000 01 ddd DDD : PEA
81
 *
82
 * 0100 1000 ss ddd DDD : EXT
83
 * 0100 1000 ss 001 rrr : MOVEM register to memory
84
 *
85
 * 0100 1010 ss ddd DDD : TST
86
 * 0100 1010 11 ddd DDD : TAS
87
 *
88
 * 0100 1010 11 111 100 : ILLEGAL
89
 *
90
 * 0100 1100 ss ddd DDD : MOVEM memory to register
91
 *
92
 * 0100 1110 01 00i iii : TRAP
93
 *
94
 * 0100 1110 01 010 rrr : LNK
95
 * 0100 1110 01 011 rrr : ULNK
96
 *
97
 * 0100 1110 01 10d rrr : MOVE USP
98
 *
99
 * 0100 1110 01 110 000 : RESET
100
 * 0100 1110 01 110 001 : NOP
101
 * 0100 1110 01 110 010 : STOP
102
 * 0100 1110 01 110 011 : RTE
103
 * 0100 1110 01 110 100 : illegal instruction
104
 * 0100 1110 01 110 101 : RTS
105
 * 0100 1110 01 110 110 : TRAPV
106
 * 0100 1110 01 110 111 : RTR
107
 *
108
 * 0100 1110 01 111 xxx : illegal instruction
109
 * 0100 1110 10 sss SSS : JSR
110
 * 0100 1110 11 sss SSS : JMP
111
 *
112
 * 0101 cccc 11 001 rrr : DBcc
113
 * 0101 cccc 11 ddd DDD : Scc
114
 * 0101 qqq1 ss ddd DDD : SUBQ
115
 * 0101 qqq0 ss ddd DDD : ADDQ
116
 *
117
 * 0110 0001 dd ddd ddd : BSR
118
 * 0110 0000 dd ddd ddd : BRA
119
 * 0110 cccc dd ddd ddd : Bcc
120
 *
121
 * 0111 rrr0 dd ddd ddd : MOVEQ
122
 *
123
 * 1011 rrro oo sss SSS : CMP
124
 * 1011 rrro oo sss SSS : CMPA
125
 * 1011 ddd1 ss 001 sss : CMPM
126
 * 1011 ssso oo ddd DDD : EOR
127
 *
128
 * 1101 rrro oo eee EEE : ADD
129
 * 1100 rrro oo eee EEE : AND
130
 * 1000 rrro oo eee EEE : OR
131
 * 1001 rrro oo eee EEE : SUB
132
 *
133
 * 1001 rrro oo sss SSS : SUBA
134
 * 1101 rrro oo sss SSS : ADDA
135
 *
136
 * 1101 ddd1 oo 00m sss : ADDX
137
 * 1001 ddd1 oo 00m sss : SUBX
138
 *
139
 * 1100 ddd1 00 00m sss : ABCD
140
 * 1000 ddd1 00 00m sss : SBCD
141
 *
142
 * 1100 ddd1 oo ooo aaa : EXG
143
 *
144
 * 1100 ddd0 11 sss SSS : MULU
145
 * 1100 ddd1 11 sss SSS : MULS
146
 * 1000 ddd0 11 sss SSS : DIVU
147
 * 1000 ddd1 11 sss SSS : DIVS
148
 *
149
 * 1110 000d 11 sss SSS : ASL,ASR memory
150
 * 1110 cccd ss i00 rrr : ASL,ASR register/immediate
151
 * 1110 001d 11 sss SSS : LSL,LSR memory
152
 * 1110 cccd ss i01 rrr : LSL,LSR register/immediate
153
 * 1110 011d 11 sss SSS : ROL,ROR memory
154
 * 1110 cccd ss i11 rrr : ROL,ROR register/immediate
155
 * 1110 010d 11 sss SSS : ROXL,ROXR memory
156
 * 1110 cccd ss i10 rrr : ROXL,ROXR register/immediate
157
 */
158
 
159
public class Tester {
160
    static int get_random(Random random, boolean must_be_even) {
161
        if(global_zero) return 0;
162
        while(true) {
163
            int rand = random.nextInt();
164
            if(must_be_even == false) return rand;
165
            else if(must_be_even == true && (rand % 2) == 0) return rand;
166
        }
167
    }
168
    static int get_random_bit(Random random) {
169
        if(global_zero) return 0;
170
        return (random.nextInt() % 2 == 0) ? 0 : 1;
171
    }
172
    static int get_random_ipm(Random random) {
173
        if(global_zero) return 0;
174
        int rand = random.nextInt();
175
        rand = rand % 8;
176
        return (rand < 0) ? -rand : rand;
177
    }
178
    static String get_8_char_hex_string(int val) throws Exception {
179
        String s = Integer.toHexString(val>>>2);
180
        while(s.length() < 8) s = "0" + s;
181
        return s.substring(s.length()-8);
182
    }
183
    static String get_4_char_hex_string(int val) throws Exception {
184
        String s = Integer.toHexString(val);
185
        while(s.length() < 4) s = "0" + s;
186
        return s.substring(s.length()-4);
187
    }
188
 
189
    static void start_test(File exe1, File exe2, int start, int end) throws Exception {
190
        random = new Random();
191
        for(int i=start; i<end; i++) {
192
            String ir = Integer.toBinaryString(i);
193
            while(ir.length() < 16) ir = "0" + ir;
194
            instruction = "ir=" + ir + ", " + i + "/" + end;
195
            System.out.println(instruction);
196
 
197
            for(int j=0; j<6; j++) {
198
                if(j==0) global_zero = true;
199
                else global_zero = false;
200
 
201
                System.out.println("j=" + j);
202
                start_test_hex(i,exe1,exe2);
203
            }
204
        }
205
    }
206
    static void start_test_hex(int i, File exe1, File exe2) throws Exception {
207
 
208
        Vector<String> common = new Vector<String>();
209
 
210
        try {
211
            common.add("+A0=" + Integer.toHexString(get_random(random, false)));
212
            common.add("+A1=" + Integer.toHexString(get_random(random, false)));
213
            common.add("+A2=" + Integer.toHexString(get_random(random, false)));
214
            common.add("+A3=" + Integer.toHexString(get_random(random, false)));
215
            common.add("+A4=" + Integer.toHexString(get_random(random, false)));
216
            common.add("+A5=" + Integer.toHexString(get_random(random, false)));
217
            common.add("+A6=" + Integer.toHexString(get_random(random, false)));
218
            common.add("+SSP=" + Integer.toHexString(get_random(random, false)));
219
            common.add("+USP=" + Integer.toHexString(get_random(random, false)));
220
 
221
            common.add("+D0=" + Integer.toHexString(get_random(random, false)));
222
            common.add("+D1=" + Integer.toHexString(get_random(random, false)));
223
            common.add("+D2=" + Integer.toHexString(get_random(random, false)));
224
            common.add("+D3=" + Integer.toHexString(get_random(random, false)));
225
            common.add("+D4=" + Integer.toHexString(get_random(random, false)));
226
            common.add("+D5=" + Integer.toHexString(get_random(random, false)));
227
            common.add("+D6=" + Integer.toHexString(get_random(random, false)));
228
            common.add("+D7=" + Integer.toHexString(get_random(random, false)));
229
 
230
            common.add("+C=" + get_random_bit(random));
231
            common.add("+V=" + get_random_bit(random));
232
            common.add("+Z=" + get_random_bit(random));
233
            common.add("+N=" + get_random_bit(random));
234
            common.add("+X=" + get_random_bit(random));
235
            common.add("+IPM=" + get_random_ipm(random));
236
            common.add("+S=" + get_random_bit(random));
237
            common.add("+T=" + "0"); //get_random_bit(random));
238
 
239
            int pc = get_random(random, true);
240
            common.add("+PC=" + Integer.toHexString(pc));
241
 
242
            if((pc % 4) == 0) {
243
                common.add("+MEM" + get_8_char_hex_string(pc) + "=" +
244
                        get_4_char_hex_string(i) +
245
                        get_4_char_hex_string(get_random(random, false)));
246
            }
247
            else {
248
                common.add("+MEM" + get_8_char_hex_string(pc) + "=" +
249
                        get_4_char_hex_string(get_random(random, false)) +
250
                        get_4_char_hex_string(i));
251
            }
252
            program_output = "Running exe1: " + exe1.getName() + "\n";
253
            common.add(0,  exe1.getCanonicalPath());
254
            HashMap<String, String> map_exe1 = start_test_process(common, exe1);
255
            if(map_exe1 == null) throw new Exception("Exe1 odd address read/write.");
256
 
257
 
258
            program_output += "\nRunning exe2: " + exe2.getName() + "\n";
259
            common.remove(0);
260
            common.add(0, exe2.getCanonicalPath());
261
            HashMap<String, String> map_exe2 = start_test_process(common, exe2);
262
            if(map_exe2 == null) throw new Exception("Exe2 odd address read/write.");
263
 
264
            boolean failed = false;
265
            boolean is_blocked = (map_exe1.containsKey("processor blocked") && map_exe2.containsKey("processor blocked")) ? true : false;
266
            for(String key : map_exe1.keySet()) {
267
                String value_emu = map_exe1.get(key);
268
                String value_verilog = map_exe2.get(key);
269
                map_exe2.remove(key);
270
 
271
                // if processor blocked, do not compare PC and SSP registers
272
                if(is_blocked && key.equals("PC")) continue;
273
                if(is_blocked && key.equals("SSP")) continue;
274
 
275
                if(value_emu.equals(value_verilog) == false) {
276
                    if(failed == false) System.out.println("");
277
                    System.out.println("Key mismatch: " + key + ": Exe1=" + value_emu + " / Exe2=" + value_verilog);
278
                    failed = true;
279
                }
280
            }
281
            for(String key : map_exe2.keySet()) {
282
                if(failed == false) System.out.println("");
283
                System.out.println("Key mismatch: " + key + ": EXE1=" + null + " / EXE2=" + map_exe2.get(key));
284
                failed = true;
285
            }
286
 
287
            if(failed) {
288
                System.out.println("");
289
                throw new Exception("Mismatch detected. Program output:\n" + program_output);
290
            }
291
        }
292
        catch(Exception e) {
293
            String result = "";
294
            for(String s : common) {
295
                result += s + "\n";
296
            }
297
            throw new Exception(e.getMessage() + "\nCommon dump:\n" + result + "\nInstruction:\n" + instruction);
298
        }
299
    }
300
    static HashMap<String, String> start_test_process(Vector<String> common, File file) throws Exception {
301
 
302
        Runtime runtime = Runtime.getRuntime();
303
        String result = "";
304
        String addresses = "\n";
305
        int count=0;
306
        while(true) {
307
            result = "";
308
            if(file.isDirectory() == false) file = new File(file.getParent());
309
            Process p = runtime.exec(common.toArray(new String[0]), null, file);
310
 
311
            int read = p.getInputStream().read();
312
            while(read != -1) {
313
                result += (char)read;
314
                read = p.getInputStream().read();
315
            }
316
            p.waitFor();
317
            p.getErrorStream().close();
318
            p.getInputStream().close();
319
            p.getOutputStream().close();
320
 
321
            if(p.exitValue() == 0) break;
322
            else {
323
                int index = result.indexOf("Missing argument: MEM");
324
                int index2 = result.indexOf("on odd address");
325
                if(index != -1) {
326
                    index += new String("Missing argument: MEM").length();
327
                    result = result.substring(index, index+8);
328
                    addresses += result + "\n";
329
 
330
                    String to_add = "+MEM" + result + "=" + Integer.toHexString(get_random(random, false));
331
                    if(to_add.length() > 4+8+1+8) throw new Exception("Illegal memory value length: " + to_add);
332
                    common.add(to_add);
333
                }
334
                else if(index2 != -1) {
335
                    throw new Exception("Odd address:" + result);
336
                }
337
                else throw new Exception("Error running process:\n" + result);
338
            }
339
 
340
            count++;
341
            if(count == 100) throw new Exception("Number of memory reads exceeded: " + common.firstElement() + " " + addresses);
342
        }
343
 
344
        program_output += result;
345
 
346
        result = result.substring(result.indexOf("START TEST") + new String("START TEST").length());
347
        String split[] = result.split("\n");
348
 
349
        HashMap<String, String> map = new HashMap<String, String>();
350
        for(int i=0; i<split.length; i++) {
351
            if(split[i].trim().length() == 0) continue;
352
            if(split[i].startsWith("memory read")) continue;
353
 
354
            String split2[] = split[i].split(":");
355
            if(split2.length == 1) throw new Exception("Line not split: " + split2[0]);
356
 
357
            map.put(split2[0].trim(), split2[1].trim());
358
        }
359
        return map;
360
    }
361
    static String program_output;
362
    static Random random;
363
    static boolean global_zero;
364
    static String instruction;
365
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.