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

Subversion Repositories leros

[/] [leros/] [trunk/] [java/] [tools/] [src/] [leros/] [sim/] [LerosSim.java] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 martin
/*
2
   Copyright 2011 Martin Schoeberl <masca@imm.dtu.dk>,
3
                  Technical University of Denmark, DTU Informatics.
4
   All rights reserved.
5
 
6
   Redistribution and use in source and binary forms, with or without
7
   modification, are permitted provided that the following conditions are met:
8
 
9
      1. Redistributions of source code must retain the above copyright notice,
10
         this list of conditions and the following disclaimer.
11
 
12
      2. Redistributions in binary form must reproduce the above copyright
13
         notice, this list of conditions and the following disclaimer in the
14
         documentation and/or other materials provided with the distribution.
15
 
16
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS
17
   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19
   NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20
   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 
27
   The views and conclusions contained in the software and documentation are
28
   those of the authors and should not be interpreted as representing official
29
   policies, either expressed or implied, of the copyright holder.
30
 */
31
 
32
package leros.sim;
33
 
34
import java.io.*;
35
 
36
/**
37
 * A crude simulation of Leros. Pipeline effects (branch delay slots) are
38
 * currently ignored.
39
 *
40
 * @author Martin Schoeberl
41
 *
42
 */
43
public class LerosSim {
44
 
45
        String fname;
46
        // no real use of dstDir
47
        String dstDir = "./";
48
        String srcDir = "./";
49
        boolean log;
50
 
51 4 martin
        ILerosIO io;
52 3 martin
 
53
        final static int IM_SIZE = 1024;
54
        final static int DM_SIZE = 1024;
55
        char im[] = new char[IM_SIZE];
56
        char dm[] = new char[DM_SIZE];
57
        int progSize = 0;
58
 
59 4 martin
        int executedInstructions;
60
 
61 3 martin
        public LerosSim(LerosIO io, String[] args) {
62
 
63
                this.io = io;
64
 
65
                String s = System.getProperty("log");
66
                if (s != null) {
67
                        log = s.equals("true");
68
                }
69 4 martin
                log=false;
70 3 martin
                srcDir = System.getProperty("user.dir");
71
                dstDir = System.getProperty("user.dir");
72
                processOptions(args);
73
                if (!srcDir.endsWith(File.separator))
74
                        srcDir += File.separator;
75
                if (!dstDir.endsWith(File.separator))
76
                        dstDir += File.separator;
77
 
78
                BufferedReader instr = null;
79
                try {
80
                        instr = new BufferedReader(new FileReader(srcDir + fname));
81
                        String l;
82
                        while ((l = instr.readLine()) != null) {
83
                                im[progSize] = (char) Integer.parseInt(l);
84
                                ++progSize;
85
                        }
86
                        System.out.println("Instruction memory " + (progSize * 2)
87
                                        + " bytes");
88
                } catch (IOException e) {
89
                        e.printStackTrace();
90
                } finally {
91
                        if (instr != null) {
92
                                try {
93
                                        instr.close();
94
                                } catch (IOException e) {
95
                                        e.printStackTrace();
96
                                }
97
                        }
98
 
99
                }
100
        }
101
 
102
        private boolean processOptions(String clist[]) {
103
                boolean success = true;
104
 
105
                for (int i = 0; i < clist.length; i++) {
106
                        if (clist[i].equals("-s")) {
107
                                srcDir = clist[++i];
108
                        } else if (clist[i].equals("-d")) {
109
                                dstDir = clist[++i];
110 4 martin
                        } else if (clist[i].equals("-qio")) {
111
                                QuickIO qio = new QuickIO();
112
                                qio.setVisible(true);
113
                                io = qio;
114
 
115 3 martin
                        } else {
116
                                fname = clist[i];
117
                        }
118
                }
119
 
120
                return success;
121
        }
122
 
123
        /**
124
         * Run the simulation. First instruction is not executed as in the hardware.
125
         */
126
        public void simulate() {
127
 
128
                int ar, pc, accu;
129
                int accu_dly, accu_dly1;
130
 
131
                pc = 1;
132
                accu = 0;
133
                ar = 0;
134
                accu_dly = accu_dly1 = 0;
135
 
136
                for (;;) {
137
 
138
                        // two cycles delay for branch
139
                        // condition modeling
140
                        // We should model the 'real' pipeline in the simulator...
141
                        accu_dly = accu_dly1;
142
                        accu_dly1 = accu;
143
 
144
                        int next_pc = pc + 1;
145
                        if (pc >= progSize) {
146 4 martin
                            System.out.println("Excuted = " + executedInstructions );
147 3 martin
                                return;
148
                        }
149
                        int instr = im[pc];
150
                        int val;
151
                        // immediate value
152
                        if ((instr & 0x0100) != 0) {
153
                                // take o bit from the instruction
154
                                val = instr & 0xff;
155
                                // sign extension to 16 bit
156
                                if ((val & 0x80)!=0) { val |= 0xff00; }
157
                        } else {
158
                                val = dm[instr & 0xff];
159
                        }
160 4 martin
                        executedInstructions++;
161
 
162 3 martin
                        switch (instr & 0xfe00) {
163
                        case 0x0000: // nop
164
                                break;
165
                        case 0x0800: // add
166
                                accu += val;
167
                                break;
168
                        case 0x0c00: // sub
169
                                accu -= val;
170
                                break;
171
                        case 0x1000: // shr
172
                                accu >>>= 1;
173
                                break;
174
                        case 0x2000: // load
175
                                accu = val;
176
                                break;
177
                        case 0x2200: // and
178
                                accu &= val;
179
                                break;
180
                        case 0x2400: // or
181
                                accu |= val;
182
                                break;
183
                        case 0x2600: // xor
184
                                accu ^= val;
185
                                break;
186
                        case 0x2800: // loadh
187
                                accu = (accu & 0xff) + (val << 8);
188
                                break;
189
                        case 0x3000: // store
190
                                dm[instr & 0x00ff] = (char) accu;
191
                                break;
192
                        case 0x3800: // out
193
                                io.write(instr & 0xff, accu);
194
                                break;
195
                        case 0x3c00: // in
196
                                accu = io.read(instr & 0xff);
197
                                break;
198
                        case 0x4000: // jal
199
                                dm[instr & 0xff] = (char) (pc+1);
200
                                next_pc = accu_dly;
201
                                break;
202
                        case 0x5000: // loadaddr
203
                                // nop, as it is only available one cycle later
204
                                break;
205
                        case 0x6000: // load indirect
206
                                accu = dm[ar + (instr & 0xff)];
207
                                break;
208
                        case 0x7000: // store indirect
209
                                dm[ar + (instr & 0xff)] = (char) accu;
210
                                break;
211
                        // case 7: // I/O (ld/st indirect)
212
                        // break;
213
                        // case 8: // brl
214
                        // break;
215
                        // case 9: // br conditional
216
                        // break;
217
                        default:
218
                                // branches use the immediate bit for decode
219
                                // TODO: we could change the encoding so it
220
                                // does not 'consume' the immediate bit - would
221
                                // this be simpler (and lead to less HW?)
222
                                switch (instr & 0xff00) {
223
                                case 0x4800: // branch
224
                                        // at the moment just 8 bits offset (sign extension)
225
                                        next_pc = pc + ((instr << 24) >> 24);
226
                                        break;
227
                                case 0x4900: // brz
228
                                        if (accu_dly == 0) {
229
                                                // at the moment just 8 bits offset (sign extension)
230
                                                next_pc = pc + ((instr << 24) >> 24);
231
                                        }
232
                                        break;
233
                                case 0x4a00: // brnz
234
                                        if (accu_dly != 0) {
235
                                                // at the moment just 8 bits offset (sign extension)
236
                                                next_pc = pc + ((instr << 24) >> 24);
237
                                        }
238
                                        break;
239
                                case 0x4b00: // brp
240
                                        if ((accu_dly & 0x8000) == 0) {
241
                                                // at the moment just 8 bits offset (sign extension)
242
                                                next_pc = pc + ((instr << 24) >> 24);
243
                                        }
244
                                        break;
245
                                case 0x4c00: // brn
246
                                        if ((accu_dly & 0x8000) != 0) {
247
                                                // at the moment just 8 bits offset (sign extension)
248
                                                next_pc = pc + ((instr << 24) >> 24);
249
                                        }
250
                                        break;
251
 
252
                                default:
253
                                        throw new Error("Instruction " + instr + " at address " + pc
254
                                                        + " not implemented");
255
                                }
256
                        }
257 4 martin
 
258 3 martin
 
259
                        // keep it in 16 bit
260
                        accu &= 0xffff;
261
                        // the address register is only available for one
262
                        // cycle later
263
                        ar = dm[instr & 0xff];
264
 
265
                        if (log) {
266
                                System.out.print("PC: " + pc + " accu: " + accu + " "
267
                                                + accu_dly + " ar: " + ar + " Mem: ");
268
                                for (int i = 0; i < 16; ++i) {
269
                                        System.out.print(((int) dm[i]) + " ");
270
                                }
271
                                System.out.println();
272
                        }
273
                        pc = next_pc;
274
 
275
                }
276 4 martin
 
277
 
278 3 martin
        }
279
 
280
        /**
281
         * @param args
282
         */
283
        public static void main(String[] args) {
284
 
285
                if (args.length < 1) {
286 4 martin
                        System.out.println("usage: java LerosSim [-s srcDir] [-qio] filename");
287 3 martin
                        System.exit(-1);
288
                }
289
                LerosSim ls = new LerosSim(new LerosIO(), args);
290
                ls.simulate();
291
        }
292
 
293 4 martin
}

powered by: WebSVN 2.1.0

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