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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [ao486_tool/] [src/] [ao486/] [test/] [TestUnit.java] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright (c) 2014, Aleksander Osman
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * * Redistributions of source code must retain the above copyright notice, this
9
 *   list of conditions and the following disclaimer.
10
 *
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 *   this list of conditions and the following disclaimer in the documentation
13
 *   and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
 
27
package ao486.test;
28
 
29
import ao486.test.layers.Layer;
30
import java.io.File;
31
import java.io.FileInputStream;
32
import java.io.FileOutputStream;
33
import java.io.ObjectInputStream;
34
import java.io.ObjectOutputStream;
35
import java.io.Serializable;
36
import java.lang.reflect.Method;
37
import java.util.HashMap;
38
import java.util.LinkedList;
39
import java.util.Properties;
40
import java.util.Random;
41
 
42
public abstract class TestUnit {
43
 
44
    //--------------------------------------------------------------------------
45
 
46
    public long getInput(String name) throws Exception {
47
//System.out.println("getInput for " + name);
48
        return (Long)executeMethod(name, false);
49
    }
50
    long check_interrupt(long time) throws Exception {
51
        Long ret = (Long)executeMethod("check_interrupt", false, check_interrupt_index++);
52
        return (ret == null)? 0x100 : ret;
53
    }
54
    long getTestType() throws Exception {
55
        return (Long)executeMethod("get_test_type", false);
56
    }
57
 
58
    long read_io(Runner.CMD_start_io_read params) throws Exception {
59
        return read(params.byteena, params.address, local_io, null, "get_io");
60
    }
61
    long read(Runner.CMD_start_read params) throws Exception {
62
        return read(params.byteena, params.address, local_memory, local_memory_read_only, "get_memory");
63
    }
64
    long read_code(Runner.CMD_start_read_code params) throws Exception {
65
        return read(params.byteena, params.address, local_memory, local_memory_read_only, "get_memory");
66
    }
67
    void write_io(Runner.CMD_start_io_write params) throws Exception {
68
        // do nothing; params saved in Runner
69
    }
70
    void write(Runner.CMD_start_write params) throws Exception {
71
        long byteenable = params.byteena;
72
        long data       = params.data;
73
 
74
        for(int i=0; i<4; i++) {
75
            if((byteenable & 1) == 1) local_memory.put(params.address + i, (byte)(data & 0xFF));
76
 
77
            byteenable >>= 1;
78
            data >>= 8;
79
        }
80
    }
81
 
82
    //--------------------------------------------------------------------------
83
 
84
    LinkedList<Object>          run_log                 = new LinkedList<>();
85
    HashMap<Long, Byte>         local_memory            = new HashMap<>();
86
    HashMap<Long, Byte>         local_memory_read_only  = new HashMap<>();
87
    HashMap<Long, Byte>         local_io                = new HashMap<>();
88
    long                        check_interrupt_index   = 0;
89
 
90
    public Random               random;
91
    public int                  index;
92
    public LinkedList<Layer>    layers = new LinkedList<>();
93
 
94
    //--------------------------------------------------------------------------
95
 
96
    private Object executeMethod(String name, boolean null_is_skip, Object ...args) throws Exception {
97
        for(Layer layer : layers) {
98
            for(Method m : layer.getClass().getDeclaredMethods()) {
99
                if(m.getName().equals(name)) {
100
                    m.setAccessible(true);
101
                    Object ret = m.invoke(layer, args);
102
                    if(ret != null || null_is_skip == false) {
103
                        return ret;
104
                    }
105
                }
106
            }
107
        }
108
        return null;
109
    }
110
 
111
    private long read(long byteenable, long address, HashMap<Long, Byte> map, HashMap<Long, Byte> map_ro, String method_name) throws Exception {
112
        long data = 0;
113
 
114
        for(int i=0; i<4; i++) {
115
            data <<= 8;
116
 
117
            if((byteenable & 1) == 1) {
118
 
119
                if(map.containsKey(address + i)) {
120
                    data |= map.get(address + i) & 0xFFL;
121
//System.out.printf("in map: %08x = %x\n", (address+i), data & 0xFFL);
122
                }
123
                else {
124
                    Object obj = executeMethod(method_name, true, (address + i));
125
//System.out.printf("executed: %08x = %x, in class: %s, method_name: %s\n", (address+i), (obj != null)? (Byte)obj : 0, executed_in_class, method_name);
126
                    if(obj == null) data |= random.nextInt() & 0xFFL;
127
                    else            data |= ((Byte)obj) & 0xFFL;
128
 
129
                    map.put(address + i, (byte)(data & 0xFFL));
130
                    if(map_ro != null) map_ro.put(address + i, (byte)(data & 0xFFL));
131
                }
132
            }
133
            byteenable >>= 1;
134
        }
135
        return ((data >> 24) & 0xFFL) | ((data >> 8) & 0xFF00L) | ((data << 8) & 0xFF0000L) | ((data << 24) & 0xFF000000L);
136
    }
137
 
138
    //--------------------------------------------------------------------------
139
 
140
    public boolean is_memory_not_random(long address) throws Exception {
141
        Boolean ret = (Boolean)executeMethod("is_memory_not_random", false, address);
142
        return (ret == null)? false : ret;
143
    }
144
 
145
    public String bytesToHex(byte bytes[]) {
146
        String s = "";
147
        for(byte b : bytes) s += String.format("%02x", b);
148
        return s;
149
    }
150
 
151
    static public byte[] hexToBytes(String hex) throws Exception {
152
        if((hex.length() %2) != 0) throw new Exception("Not full hex string: " + hex);
153
 
154
        byte bytes[] = new byte[hex.length()/2];
155
        for(int i=0; i<bytes.length; i++) bytes[i] = (byte)Integer.valueOf(hex.substring(i*2, i*2+2), 16).intValue();
156
 
157
        return bytes;
158
    }
159
 
160
    public boolean isAccepted(int val, boolean... conds) {
161
        for(boolean b : conds) {
162
            if((val & 1) == 1 && b == false) return false;
163
            if((val & 1) == 0 && b == true) return false;
164
            val >>= 1;
165
        }
166
        return true;
167
    }
168
 
169
    public int unsigned(byte b) {
170
        int result = b;
171
        if(result < 0) result += 256;
172
        return result;
173
    }
174
 
175
    public int modregrm_len(boolean a16, int modregrm, int sib) {
176
        int mod      = (modregrm >> 6) & 3;
177
        int rm       = modregrm & 7;
178
        int base     = sib & 7;
179
 
180
        // d_CRx_DRx_condition ignored
181
 
182
        if(a16 && mod == 0 && rm == 6) return 3;
183
        if(a16 && mod == 1) return 2;
184
        if(a16 && mod == 2) return 3;
185
        if(a16) return 1;
186
 
187
        if(mod == 0 && rm == 5) return 5;
188
        if(mod == 0 && rm == 4 && base == 5) return 6;
189
        if(mod == 0 && rm == 4) return 2;
190
        if(mod == 1 && rm == 4) return 3;
191
        if(mod == 1) return 2;
192
        if(mod == 2 && rm == 4) return 6;
193
        if(mod == 2) return 5;
194
 
195
        return 1;
196
    }
197
 
198
    public static class Descriptor implements Serializable {
199
        public Descriptor(int base, int limit, int type, boolean segment, boolean present, int dpl, boolean d_b, boolean g, boolean l, boolean avl) {
200
            this.base       = base;
201
            this.limit      = limit;
202
            this.type       = type;
203
            this.segment    = segment;
204
            this.present    = present;
205
            this.dpl        = dpl;
206
            this.d_b        = d_b;
207
            this.g          = g;
208
            this.l          = l;
209
            this.avl        = avl;
210
        }
211
        public int     base,limit,type,dpl;
212
        public boolean segment, present, d_b, g;
213
        public boolean l, avl;
214
 
215
        public byte get_byte(int index) {
216
            switch(index) {
217
                case 0:     return (byte)((limit >> 0) & 0xFF);
218
                case 1:     return (byte)((limit >> 8) & 0xFF);
219
                case 2:     return (byte)((base >> 0) & 0xFF);
220
                case 3:     return (byte)((base >> 8) & 0xFF);
221
                case 4:     return (byte)((base >> 16) & 0xFF);
222
                case 5:     return (byte)( (present? 1 << 7 : 0) | ((dpl & 3) << 5) | (segment? 1 << 4 : 0) | (type & 15) );
223
                case 6:     return (byte)( (g? 1 << 7 : 0) | (d_b? 1 << 6 : 0) | (l? 1 << 5 : 0) | (avl? 1 << 4 : 0) | ((limit >> 16) & 15) );
224
                default:    return (byte)((base >> 24) & 0xFF);
225
            }
226
        }
227
        public void set_dest_offset(long offset) {
228
            limit = (int)(offset & 0xFFFFF);
229
            avl   = ((offset >> 20)&1) == 1;
230
            l     = ((offset >> 21)&1) == 1;
231
            d_b   = ((offset >> 22)&1) == 1;
232
            g     = ((offset >> 23)&1) == 1;
233
 
234
            base  = (int)((offset & 0xFF000000) | (base & 0x00FFFFFF));
235
        }
236
    }
237
 
238
    //--------------------------------------------------------------------------
239
 
240
    public abstract int get_test_count() throws Exception;
241
 
242
    public abstract void init() throws Exception;
243
 
244
    //--------------------------------------------------------------------------
245
 
246
    //--------------------------------------------------------------------------
247
 
248
    public static void run_test(Class test_class) throws Exception {
249
 
250
        int index = 0;
251
 
252
        FileInputStream run_prop_files = new FileInputStream("run.properties");
253
        Properties run_prop = new Properties();
254
        run_prop.load(run_prop_files);
255
        run_prop_files.close();
256
 
257
        if(run_prop.getProperty("deserialize").toLowerCase().equals("yes")) {
258
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test.obj"));
259
            index = ois.readInt();
260
            ois.close();
261
        }
262
 
263
        File output_directory = new File(".");
264
        File directory;
265
        LinkedList<String> command_line = new LinkedList<>();
266
 
267
        Runner runner = new Runner();
268
 
269
        boolean test_failed = false;
270
 
271
        TestUnit test_for_size = (TestUnit)test_class.newInstance();
272
 
273
        for(; index<test_for_size.get_test_count(); index++) {
274
            System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Running test " +
275
                    (index+1) + "/" + test_for_size.get_test_count());
276
 
277
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test.obj"));
278
            oos.writeInt(index);
279
            oos.close();
280
 
281
            //run bochs486
282
            TestUnit test_bochs = (TestUnit)test_class.newInstance();
283
            test_bochs.index = index;
284
 
285
            test_bochs.init();
286
 
287
            directory = new File("./../bochs486/");
288
            command_line.clear();
289
            command_line.add("./bochs486");
290
 
291
            runner.execute(command_line, directory, test_bochs);
292
 
293
            //run verilog
294
            TestUnit test_verilog = (TestUnit)test_class.newInstance();
295
            test_verilog.index        = index;
296
            test_verilog.local_io     = test_bochs.local_io;
297
            test_verilog.local_memory = test_bochs.local_memory_read_only;
298
 
299
            test_verilog.init();
300
 
301
            directory = new File("./../sim/ao486");
302
            command_line.clear();
303
            command_line.add("/opt/iverilog/bin/vvp");
304
            command_line.add("tb_ao486.vvp");
305
            //command_line.add("-lxt");
306
 
307
            runner.execute(command_line, directory, test_verilog);
308
 
309
            test_failed = RunRaport.compare(test_bochs.run_log, test_verilog.run_log, output_directory);
310
            if(test_failed) break;
311
        }
312
 
313
        if(test_failed) System.out.println("TEST: FAILED.");
314
        else            System.out.println("TEST: OK.");
315
    }
316
}

powered by: WebSVN 2.1.0

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