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

Subversion Repositories ao68000

[/] [ao68000/] [trunk/] [sw/] [ao68000_tool/] [Tester.java] - Rev 12

Compare with Previous | Blame | View Log

/*
 * Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are
 * permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice, this list of
 *     conditions and the following disclaimer.
 *
 *  2. Redistributions in binary form must reproduce the above copyright notice, this list
 *     of conditions and the following disclaimer in the documentation and/or other materials
 *     provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
package ao68000_tool;
 
import java.io.File;
import java.util.HashMap;
import java.util.Random;
import java.util.Vector;
 
/* 
 * 0000 0000 ss ddd DDD : ORI
 *
 * 0000 rrr1 00 ddd DDD : BTST
 * 0000 ddd1 ss 001 sss : MOVEP from memory
 *
 * 0000 rrr1 01 ddd DDD : BCHG
 * 0000 rrr1 10 ddd DDD : BCLR
 * 0000 rrr1 11 ddd DDD : BSET
 *
 * 0000 0010 ss ddd DDD : ANDI
 *
 * 0000 0100 ss ddd DDD : SUBI
 *
 * 0000 0110 ss ddd DDD : ADDI
 *
 * 0000 1000 00 ddd DDD : BTST imm
 * 0000 1000 01 ddd DDD : BCHG imm
 * 0000 1000 10 ddd DDD : BCLR imm
 * 0000 1000 11 ddd DDD : BSET imm
 *
 * 0000 1010 ss ddd DDD : EORI
 * 0000 1100 ss ddd DDD : CMPI
 *
 * 0000 1110 xx xxx xxx : illegal instruction
 *
 * 00ss DDDd dd sss SSS : MOVE
 * 00ss DDD0 01 sss SSS : MOVEA
 *
 * 0100 0000 ss ddd DDD : NEGX
 * 0100 0000 11 ddd DDD : MOVE FROM SR
 *
 * 0100 0001 00 xxx xxx : illegal instruction
 *
 * 0100 rrrs s0 ddd DDD : CHK
 * 0100 rrr1 11 ddd DDD : LEA
 *
 * 0100 0010 ss ddd DDD : CLR
 *
 * 0100 0100 ss ddd DDD : NEG
 * 0100 0100 11 sss SSS : MOVE TO CCR
 * 0100 0110 ss ddd DDD : NOT
 * 0100 0110 11 sss SSS : MOVE TO SR
 *
 * 0100 1000 00 ddd DDD : NBCD
 * 0100 1000 01 000 rrr : SWAP
 *
 * 0100 1000 01 001 xxx : illegal instruction
 * 0100 1000 01 ddd DDD : PEA
 *
 * 0100 1000 ss ddd DDD : EXT
 * 0100 1000 ss 001 rrr : MOVEM register to memory
 *
 * 0100 1010 ss ddd DDD : TST
 * 0100 1010 11 ddd DDD : TAS
 * 
 * 0100 1010 11 111 100 : ILLEGAL
 * 
 * 0100 1100 ss ddd DDD : MOVEM memory to register
 * 
 * 0100 1110 01 00i iii : TRAP
 * 
 * 0100 1110 01 010 rrr : LNK
 * 0100 1110 01 011 rrr : ULNK
 * 
 * 0100 1110 01 10d rrr : MOVE USP
 * 
 * 0100 1110 01 110 000 : RESET
 * 0100 1110 01 110 001 : NOP
 * 0100 1110 01 110 010 : STOP
 * 0100 1110 01 110 011 : RTE
 * 0100 1110 01 110 100 : illegal instruction
 * 0100 1110 01 110 101 : RTS
 * 0100 1110 01 110 110 : TRAPV
 * 0100 1110 01 110 111 : RTR
 *
 * 0100 1110 01 111 xxx : illegal instruction
 * 0100 1110 10 sss SSS : JSR
 * 0100 1110 11 sss SSS : JMP
 * 
 * 0101 cccc 11 001 rrr : DBcc
 * 0101 cccc 11 ddd DDD : Scc
 * 0101 qqq1 ss ddd DDD : SUBQ
 * 0101 qqq0 ss ddd DDD : ADDQ
 *
 * 0110 0001 dd ddd ddd : BSR
 * 0110 0000 dd ddd ddd : BRA
 * 0110 cccc dd ddd ddd : Bcc
 * 
 * 0111 rrr0 dd ddd ddd : MOVEQ
 *
 * 1011 rrro oo sss SSS : CMP
 * 1011 rrro oo sss SSS : CMPA
 * 1011 ddd1 ss 001 sss : CMPM
 * 1011 ssso oo ddd DDD : EOR
 *
 * 1101 rrro oo eee EEE : ADD
 * 1100 rrro oo eee EEE : AND
 * 1000 rrro oo eee EEE : OR
 * 1001 rrro oo eee EEE : SUB
 *
 * 1001 rrro oo sss SSS : SUBA
 * 1101 rrro oo sss SSS : ADDA
 *
 * 1101 ddd1 oo 00m sss : ADDX
 * 1001 ddd1 oo 00m sss : SUBX
 *
 * 1100 ddd1 00 00m sss : ABCD
 * 1000 ddd1 00 00m sss : SBCD
 *
 * 1100 ddd1 oo ooo aaa : EXG
 *
 * 1100 ddd0 11 sss SSS : MULU
 * 1100 ddd1 11 sss SSS : MULS
 * 1000 ddd0 11 sss SSS : DIVU
 * 1000 ddd1 11 sss SSS : DIVS
 * 
 * 1110 000d 11 sss SSS : ASL,ASR memory
 * 1110 cccd ss i00 rrr : ASL,ASR register/immediate
 * 1110 001d 11 sss SSS : LSL,LSR memory
 * 1110 cccd ss i01 rrr : LSL,LSR register/immediate
 * 1110 011d 11 sss SSS : ROL,ROR memory
 * 1110 cccd ss i11 rrr : ROL,ROR register/immediate
 * 1110 010d 11 sss SSS : ROXL,ROXR memory
 * 1110 cccd ss i10 rrr : ROXL,ROXR register/immediate
 */
 
public class Tester {
    static int get_random(Random random, boolean must_be_even) {
        if(global_zero) return 0;
        while(true) {
            int rand = random.nextInt();
            if(must_be_even == false) return rand;
            else if(must_be_even == true && (rand % 2) == 0) return rand;
        }
    }
    static int get_random_bit(Random random) {
        if(global_zero) return 0;
        return (random.nextInt() % 2 == 0) ? 0 : 1;
    }
    static int get_random_ipm(Random random) {
        if(global_zero) return 0;
        int rand = random.nextInt();
        rand = rand % 8;
        return (rand < 0) ? -rand : rand;
    }
    static String get_8_char_hex_string(int val) throws Exception {
        String s = Integer.toHexString(val>>>2);
        while(s.length() < 8) s = "0" + s;
        return s.substring(s.length()-8);
    }
    static String get_4_char_hex_string(int val) throws Exception {
        String s = Integer.toHexString(val);
        while(s.length() < 4) s = "0" + s;
        return s.substring(s.length()-4);
    }
 
    static void start_test(File exe1, File exe2, int start, int end) throws Exception {
        random = new Random();
        for(int i=start; i<end; i++) {
            String ir = Integer.toBinaryString(i);
            while(ir.length() < 16) ir = "0" + ir;
            instruction = "ir=" + ir + ", " + i + "/" + end;
            System.out.println(instruction);
 
            for(int j=0; j<6; j++) {
                if(j==0) global_zero = true;
                else global_zero = false;
 
                System.out.println("j=" + j);
                start_test_hex(i,exe1,exe2);
            }
        }
    }
    static void start_test_hex(int i, File exe1, File exe2) throws Exception {
 
        Vector<String> common = new Vector<String>();
 
        try {
            common.add("+A0=" + Integer.toHexString(get_random(random, false)));
            common.add("+A1=" + Integer.toHexString(get_random(random, false)));
            common.add("+A2=" + Integer.toHexString(get_random(random, false)));
            common.add("+A3=" + Integer.toHexString(get_random(random, false)));
            common.add("+A4=" + Integer.toHexString(get_random(random, false)));
            common.add("+A5=" + Integer.toHexString(get_random(random, false)));
            common.add("+A6=" + Integer.toHexString(get_random(random, false)));
            common.add("+SSP=" + Integer.toHexString(get_random(random, false)));
            common.add("+USP=" + Integer.toHexString(get_random(random, false)));
 
            common.add("+D0=" + Integer.toHexString(get_random(random, false)));
            common.add("+D1=" + Integer.toHexString(get_random(random, false)));
            common.add("+D2=" + Integer.toHexString(get_random(random, false)));
            common.add("+D3=" + Integer.toHexString(get_random(random, false)));
            common.add("+D4=" + Integer.toHexString(get_random(random, false)));
            common.add("+D5=" + Integer.toHexString(get_random(random, false)));
            common.add("+D6=" + Integer.toHexString(get_random(random, false)));
            common.add("+D7=" + Integer.toHexString(get_random(random, false)));
 
            common.add("+C=" + get_random_bit(random));
            common.add("+V=" + get_random_bit(random));
            common.add("+Z=" + get_random_bit(random));
            common.add("+N=" + get_random_bit(random));
            common.add("+X=" + get_random_bit(random));
            common.add("+IPM=" + get_random_ipm(random));
            common.add("+S=" + get_random_bit(random));
            common.add("+T=" + "0"); //get_random_bit(random));
 
            int pc = get_random(random, true);
            common.add("+PC=" + Integer.toHexString(pc));
 
            if((pc % 4) == 0) {
                common.add("+MEM" + get_8_char_hex_string(pc) + "=" +
                        get_4_char_hex_string(i) +
                        get_4_char_hex_string(get_random(random, false)));
            }
            else {
                common.add("+MEM" + get_8_char_hex_string(pc) + "=" +
                        get_4_char_hex_string(get_random(random, false)) +
                        get_4_char_hex_string(i));
            }
            program_output = "Running exe1: " + exe1.getName() + "\n";
            common.add(0,  exe1.getCanonicalPath());
            HashMap<String, String> map_exe1 = start_test_process(common, exe1);
            if(map_exe1 == null) throw new Exception("Exe1 odd address read/write.");
 
 
            program_output += "\nRunning exe2: " + exe2.getName() + "\n";
            common.remove(0);
            common.add(0, exe2.getCanonicalPath());
            HashMap<String, String> map_exe2 = start_test_process(common, exe2);
            if(map_exe2 == null) throw new Exception("Exe2 odd address read/write.");
 
            boolean failed = false;
            boolean is_blocked = (map_exe1.containsKey("processor blocked") && map_exe2.containsKey("processor blocked")) ? true : false;
            for(String key : map_exe1.keySet()) {
                String value_emu = map_exe1.get(key);
                String value_verilog = map_exe2.get(key);
                map_exe2.remove(key);
 
                // if processor blocked, do not compare PC and SSP registers
                if(is_blocked && key.equals("PC")) continue;
                if(is_blocked && key.equals("SSP")) continue;
 
                if(value_emu.equals(value_verilog) == false) {
                    if(failed == false) System.out.println("");
                    System.out.println("Key mismatch: " + key + ": Exe1=" + value_emu + " / Exe2=" + value_verilog);
                    failed = true;
                }
            }
            for(String key : map_exe2.keySet()) {
                if(failed == false) System.out.println("");
                System.out.println("Key mismatch: " + key + ": EXE1=" + null + " / EXE2=" + map_exe2.get(key));
                failed = true;
            }
 
            if(failed) {
                System.out.println("");
                throw new Exception("Mismatch detected. Program output:\n" + program_output);
            }
        }
        catch(Exception e) {
            String result = "";
            for(String s : common) {
                result += s + "\n";
            }
            throw new Exception(e.getMessage() + "\nCommon dump:\n" + result + "\nInstruction:\n" + instruction);
        }
    }
    static HashMap<String, String> start_test_process(Vector<String> common, File file) throws Exception {
 
        Runtime runtime = Runtime.getRuntime();
        String result = "";
        String addresses = "\n";
        int count=0;
        while(true) {
            result = "";
            if(file.isDirectory() == false) file = new File(file.getParent());
            Process p = runtime.exec(common.toArray(new String[0]), null, file);
 
            int read = p.getInputStream().read();
            while(read != -1) {
                result += (char)read;
                read = p.getInputStream().read();
            }
            p.waitFor();
            p.getErrorStream().close();
            p.getInputStream().close();
            p.getOutputStream().close();
 
            if(p.exitValue() == 0) break;
            else {
                int index = result.indexOf("Missing argument: MEM");
                int index2 = result.indexOf("on odd address");
                if(index != -1) {
                    index += new String("Missing argument: MEM").length();
                    result = result.substring(index, index+8);
                    addresses += result + "\n";
 
                    String to_add = "+MEM" + result + "=" + Integer.toHexString(get_random(random, false));
                    if(to_add.length() > 4+8+1+8) throw new Exception("Illegal memory value length: " + to_add);
                    common.add(to_add);
                }
                else if(index2 != -1) {
                    throw new Exception("Odd address:" + result);
                }
                else throw new Exception("Error running process:\n" + result);
            }
 
            count++;
            if(count == 100) throw new Exception("Number of memory reads exceeded: " + common.firstElement() + " " + addresses);
        }
 
        program_output += result;
 
        result = result.substring(result.indexOf("START TEST") + new String("START TEST").length());
        String split[] = result.split("\n");
 
        HashMap<String, String> map = new HashMap<String, String>();
        for(int i=0; i<split.length; i++) {
            if(split[i].trim().length() == 0) continue;
            if(split[i].startsWith("memory read")) continue;
 
            String split2[] = split[i].split(":");
            if(split2.length == 1) throw new Exception("Line not split: " + split2[0]);
 
            map.put(split2[0].trim(), split2[1].trim());
        }
        return map;
    }
    static String program_output;
    static Random random;
    static boolean global_zero;
    static String instruction;
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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