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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [ao486_tool/] [src/] [ao486/] [module/] [memory/] [test/] [TestReadCacheLRU.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.module.memory.test;
28
 
29
import ao486.module.memory.AvalonListener;
30
import ao486.module.memory.GlobalListener;
31
import ao486.module.memory.Input;
32
import ao486.module.memory.Listener;
33
import ao486.module.memory.Output;
34
import ao486.module.memory.ReadListener;
35
import ao486.module.memory.Test;
36
import java.util.LinkedList;
37
import java.util.Random;
38
 
39
class TestReadCacheLRUState {
40
 
41
    TestReadCacheLRUState(Random random) {
42
        this.random = random;
43
 
44
        address_middle_base = random.nextLong();
45
        address_middle_base &= 0x00000FF0L;
46
    }
47
 
48
    boolean select_0() {
49
        if(active_0 == false) return false;
50
 
51
        next_address_base = address_middle_base | address_0_base;
52
 
53
        plru_0 = true;
54
        plru_1 = true;
55
 
56
        return true;
57
    }
58
    boolean select_1() {
59
        if(active_1 == false || active_0 == false) return false;
60
 
61
        next_address_base = address_middle_base | address_1_base;
62
 
63
        plru_0 = true;
64
        plru_1 = false;
65
 
66
        return true;
67
    }
68
    boolean select_2() {
69
        if(active_2 == false || active_0 == false || active_1 == false) return false;
70
 
71
        next_address_base = address_middle_base | address_2_base;
72
 
73
        plru_0 = false;
74
        plru_2 = true;
75
 
76
        return true;
77
    }
78
    boolean select_3() {
79
        if(active_3 == false || active_0 == false || active_1 == false || active_2 == false) return false;
80
 
81
        next_address_base = address_middle_base | address_3_base;
82
 
83
        plru_0 = false;
84
        plru_2 = false;
85
 
86
        return true;
87
    }
88
    void select_new() {
89
        if(active_0 == false) {
90
            active_0 = true;
91
 
92
            plru_0 = true;
93
            plru_1 = true;
94
 
95
            do {
96
                address_0_base = random.nextLong();
97
                address_0_base &= 0xFFFFF000L;
98
            } while(Test.address_not_in_cache(address_0_base) || address_0_base == address_1_base || address_0_base == address_2_base || address_0_base == address_3_base);
99
 
100
            next_address_base = address_middle_base | address_0_base;
101
        }
102
        else if(active_1 == false) {
103
            active_1 = true;
104
 
105
            plru_0 = true;
106
            plru_1 = false;
107
 
108
            do {
109
                address_1_base = random.nextLong();
110
                address_1_base &= 0xFFFFF000L;
111
            } while(Test.address_not_in_cache(address_1_base) || address_1_base == address_0_base || address_1_base == address_2_base || address_1_base == address_3_base);
112
 
113
            next_address_base = address_middle_base | address_1_base;
114
        }
115
        else if(active_2 == false) {
116
            active_2 = true;
117
 
118
            plru_0 = false;
119
            plru_2 = true;
120
 
121
            do {
122
                address_2_base = random.nextLong();
123
                address_2_base &= 0xFFFFF000L;
124
            } while(Test.address_not_in_cache(address_2_base) || address_2_base == address_0_base || address_2_base == address_1_base || address_2_base == address_3_base);
125
 
126
            next_address_base = address_middle_base | address_2_base;
127
        }
128
        else if(active_3 == false) {
129
            active_3 = true;
130
 
131
            plru_0 = false;
132
            plru_2 = false;
133
 
134
            do {
135
                address_3_base = random.nextLong();
136
                address_3_base &= 0xFFFFF000L;
137
            } while(Test.address_not_in_cache(address_3_base) || address_3_base == address_0_base || address_3_base == address_1_base || address_3_base == address_2_base);
138
 
139
            next_address_base = address_middle_base | address_3_base;
140
        }
141
        else {
142
            if(plru_0 == false && plru_1 == false) { //0
143
                plru_0 = true;
144
                plru_1 = true;
145
 
146
                next_writeback = true;
147
                next_writeback_address = address_middle_base | address_0_base;
148
 
149
                do {
150
                    address_0_base = random.nextLong();
151
                    address_0_base &= 0xFFFFF000L;
152
                } while(Test.address_not_in_cache(address_0_base) || address_0_base == address_1_base || address_0_base == address_2_base || address_0_base == address_3_base);
153
 
154
                next_address_base = address_middle_base | address_0_base;
155
            }
156
            else if(plru_0 == false && plru_1 == true) { //1
157
                plru_0 = true;
158
                plru_1 = false;
159
 
160
                next_writeback = true;
161
                next_writeback_address = address_middle_base | address_1_base;
162
 
163
                do {
164
                    address_1_base = random.nextLong();
165
                    address_1_base &= 0xFFFFF000L;
166
                } while(Test.address_not_in_cache(address_1_base) || address_1_base == address_0_base || address_1_base == address_2_base || address_1_base == address_3_base);
167
 
168
                next_address_base = address_middle_base | address_1_base;
169
            }
170
            else if(plru_0 == true && plru_2 == false) { //2
171
                plru_0 = false;
172
                plru_2 = true;
173
 
174
                next_writeback = true;
175
                next_writeback_address = address_middle_base | address_2_base;
176
 
177
                do {
178
                    address_2_base = random.nextLong();
179
                    address_2_base &= 0xFFFFF000L;
180
                } while(Test.address_not_in_cache(address_2_base) || address_2_base == address_0_base || address_2_base == address_1_base || address_2_base == address_3_base);
181
 
182
                next_address_base = address_middle_base | address_2_base;
183
            }
184
            else if(plru_0 == true && plru_2 == true) { //3
185
                plru_0 = false;
186
                plru_2 = false;
187
 
188
                next_writeback = true;
189
                next_writeback_address = address_middle_base | address_3_base;
190
 
191
                do {
192
                    address_3_base = random.nextLong();
193
                    address_3_base &= 0xFFFFF000L;
194
                } while(Test.address_not_in_cache(address_3_base) || address_3_base == address_0_base || address_3_base == address_1_base || address_3_base == address_2_base);
195
 
196
                next_address_base = address_middle_base | address_3_base;
197
            }
198
        }
199
    }
200
 
201
    void select() {
202
 
203
        while(true) {
204
            int val = random.nextInt(5);
205
 
206
            if(val >= 0 && val <= 3)    next_read_from_cache = true;
207
            else                        next_read_from_cache = false;
208
 
209
            if(val == 0) {
210
                boolean accepted = select_0();
211
                if(accepted == false) continue;
212
                break;
213
            }
214
            else if(val == 1) {
215
                boolean accepted = select_1();
216
                if(accepted == false) continue;
217
                break;
218
            }
219
            else if(val == 2) {
220
                boolean accepted = select_2();
221
                if(accepted == false) continue;
222
                break;
223
            }
224
            else if(val == 3) {
225
                boolean accepted = select_3();
226
                if(accepted == false) continue;
227
                break;
228
            }
229
            else {
230
                select_new();
231
                break;
232
            }
233
        }
234
    }
235
 
236
    private Random random;
237
 
238
    private long address_middle_base;
239
 
240
    private long address_0_base;
241
    private long address_1_base;
242
    private long address_2_base;
243
    private long address_3_base;
244
 
245
    private boolean active_0;
246
    private boolean active_1;
247
    private boolean active_2;
248
    private boolean active_3;
249
 
250
    private boolean plru_0;
251
    private boolean plru_1;
252
    private boolean plru_2;
253
 
254
    long next_address_base;
255
 
256
    boolean next_writeback;
257
    long    next_writeback_address;
258
 
259
    boolean next_read_from_cache;
260
}
261
 
262
public class TestReadCacheLRU extends Test implements Listener, ReadListener.ReadInterface {
263
 
264
    void go(long seed) throws Exception {
265
        random = new Random(seed);
266
        state  = new TestReadCacheLRUState(random);
267
 
268
        avalon = new AvalonListener(random, this);
269
        read   = new ReadListener();
270
        global = new GlobalListener();
271
 
272
        global.set(false, false, false, false, true, false, 0xABCDE000, false, false, false, false);
273
 
274
        finish_cycle = 0;
275
        counter = 1;
276
 
277
        state.select();
278
 
279
        length  = 1 + random.nextInt(8);
280
        address = state.next_address_base + random.nextInt(16 - length + 1);
281
 
282
        read_cycle = 257;
283
        read.read(read_cycle, 0, address, length, false, false, this);
284
 
285
        //----------
286
 
287
        LinkedList<Listener> listeners = new LinkedList<>();
288
        listeners.add(avalon);
289
        listeners.add(read);
290
        listeners.add(global);
291
        listeners.add(this);
292
 
293
        run_simulation(listeners);
294
    }
295
    @Override
296
    public void read(int cycle, long data) throws Exception {
297
        //System.out.printf("Read value: %x\n", data);
298
 
299
        for(int i=0; i<length; i++) {
300
            long value = avalon.get_memory(address+i);
301
 
302
            if((value & 0xFF) != (data & 0xFF)) throw new Exception(String.format("Value mismatch: data: %x, value: %x, i: %d, address: %x", data, value, i, address));
303
 
304
            value >>= 8;
305
            data >>= 8;
306
        }
307
 
308
        // read only: no writeback
309
        //if(state.next_writeback) throw new Exception("No writeback detected.");
310
 
311
        if((cycle - read_cycle) >= 5 && state.next_read_from_cache)         throw new Exception("Expected cache read.");
312
        if((cycle - read_cycle) < 5 && state.next_read_from_cache == false) throw new Exception("Expected not cache read.");
313
 
314
        counter++;
315
 
316
        if(counter >= 1000) {
317
            finish_cycle = cycle+1;
318
            return;
319
        }
320
 
321
        state.select();
322
 
323
        length  = 1 + random.nextInt(8);
324
        address = state.next_address_base + random.nextInt(16 - length + 1);
325
 
326
        read_cycle = cycle+1;
327
        read.read(read_cycle, 0, address, length, false, false, this);
328
    }
329
 
330
    @Override
331
    public void read_page_fault(int cycle, long cr2, long error_code) throws Exception {
332
        throw new Exception("read_page_fault: cr2: " + cr2 + ", error_code: " + error_code);
333
    }
334
 
335
    @Override
336
    public void read_ac_fault(int cycle) throws Exception {
337
        throw new Exception("read_ac_fault.");
338
    }
339
 
340
    @Override
341
    public void avalon_write(int cycle, long write_address) throws Exception {
342
        throw new Exception("avalon_write not expected.");
343
    }
344
 
345
    @Override
346
    public void set_input(int cycle, Input input) throws Exception {
347
        if(cycle >= finish_cycle && finish_cycle > 0) input.finished = true;
348
    }
349
 
350
    @Override
351
    public void get_output(int cycle, Output output) throws Exception {
352
    }
353
 
354
    int  length;
355
    long address;
356
 
357
    TestReadCacheLRUState state;
358
 
359
    Random random;
360
 
361
    int counter;
362
    int read_cycle;
363
    int finish_cycle;
364
 
365
    AvalonListener avalon;
366
    ReadListener   read;
367
    GlobalListener global;
368
 
369
    //-------------
370
 
371
    public static void main(String args[]) throws Exception {
372
        TestReadCacheLRU test1 = new TestReadCacheLRU();
373
 
374
        for(int i=0; i<10; i++) {
375
            test1.go(i);
376
 
377
            System.out.println("Run " + i + " complete.");
378
        }
379
 
380
        System.out.println("[Main] thread end.");
381
    }
382
}

powered by: WebSVN 2.1.0

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