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

Subversion Repositories igor

[/] [igor/] [trunk/] [simulator/] [main.c] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 atypic
#include <stdio.h>
2
#include <unistd.h>
3
#include <getopt.h>
4
#include <stdlib.h>
5
#include <err.h>
6
#include <string.h>
7
#include <readline/readline.h>
8
#include <readline/history.h>
9
#include <signal.h>
10
#include <ctype.h>
11
 
12
#include "regs.h"
13
#include "instructions.h"
14
#include "memory.h"
15
#include "microcode.h"
16
#include "object.h"
17
#include "machine.h"
18
#include "debug.h"
19
#include "breakpoint.h"
20
#include "print.h"
21
#include "io.h"
22
#include "profiler.h"
23
//globals considered harmful
24
int sim_autorun;
25
char* sim_name;
26
 
27
 
28
void
29
usage(void)
30
{
31
        errx(1, "[-m memory file] [-s memory size] [-c microprogram file]");
32
}
33
 
34
void
35
dump_microcode_to_file(FILE *f)
36
{
37
        int i;
38
        for (i = 0; i < microcode_size(); i++) {
39
                print_instruction_to_file(f, i);
40
        }
41
}
42
 
43
void
44
dump_microcode(void)
45
{
46
        dump_microcode_to_file(stdout);
47
}
48
 
49
// Set this to 0 to jump out of the run loop
50
int stop_execution;
51
 
52
void
53
cmd_run(char *cmd)
54
{
55
        reg_t to_addr, nxt;
56
        int with_to_addr = 0;
57
 
58
        if (strlen(cmd) > 2) {
59
                sscanf(&cmd[2], "%X", &to_addr);
60
                with_to_addr = 1;
61
        }
62
 
63
        stop_execution = 0;
64
        while (machine_up()) {
65
                if (stop_execution)
66
                        break;
67
                do_next_instruction();
68
                nxt = next_instr_addr();
69
                if (with_to_addr && nxt == to_addr) {
70
                        printf("reached destination: ");
71
                        print_instruction(nxt);
72
                        return;
73
                }
74
                if (breakpoint_at(nxt)) {
75
                        printf("breakpoint: ");
76
                        print_instruction(nxt);
77
                        return;
78
                }
79
        }
80
}
81
 
82
void
83
cmd_step(char *cmd)
84
{
85
        int n, i;
86
 
87
        if (strlen(cmd) > 2) {
88
                sscanf(&cmd[2], "%X", &n);
89
        } else {
90
                n = 1;
91
        }
92
 
93
        if (machine_up()) {
94
                for (i = 0; i < n; i++)
95
                        do_next_instruction();
96
        } else {
97
                printf("cannot step instruction: machine down\n");
98
        }
99
}
100
 
101
void
102
cmd_print(char *cmd)
103
{
104
        char what;
105
        uint32_t start_addr;
106
        uint32_t end_addr;
107
        uint32_t addr;
108
        reg_t val = 0;
109
 
110
        if (strlen(cmd) < 4) {
111
                printf("what do you want me to print?\n");
112
                return;
113
        }
114
 
115
        what = cmd[2];
116
#if 0
117
        if (islower(what) && sscanf(&cmd[3], "%X", &addr) != 1) {
118
                fprintf(stderr, "an address, please\n");
119
                return;
120
        }
121
#endif
122
 
123
        if (what=='r') {
124
                int n;
125
                struct di_const *c;
126
 
127
                if (cmd[3] == ' ') {
128
                        val = debug_get_key(&cmd[4], "reg");
129
                        if (val == 0xdeadbeef) {
130
                                printf("Unknown register: %s\n", &cmd[3]);
131
                        } else {
132
                                printf("Dumping register: 0x%X\n", val);
133
                                val = reg_get(val);
134
                                object_dump(val);
135
                        }
136
                } else if((n = sscanf(&cmd[3], "%X-r%X", &start_addr,
137
                    &end_addr)) == 1) {
138
                        c = debug_get1_filter(start_addr, "reg");
139
                        if (c != NULL)
140
                                printf("Named register: %s\n", c->name);
141
                        if (start_addr < 0 || start_addr >= N_REGS) {
142
                                printf("That is not a register!\n");
143
                                return;
144
                        }
145
                        val=reg_get(start_addr);
146
                        object_dump(val);
147
                } else if (n == 2) {
148
                        for(uint32_t i=start_addr; i<=end_addr; i++)
149
                        {
150
                                c = debug_get1_filter(i, "reg");
151
                                printf("r%X (%s):\n", i, c == NULL? "" : c->name);
152
                                val=reg_get(i);
153
                                object_dump(val);
154
                        }
155
                } else {
156
                        printf("Unknown print format\n");
157
                }
158
        } else if (what=='m') {
159
                struct di_const *c;
160
 
161
                if (sscanf(&cmd[3], "%X", &addr) != 1) {
162
                        fprintf(stderr, "an address, please\n");
163
                        return;
164
                }
165
 
166
                if (sscanf(&cmd[3], "%X-m%X", &addr, &end_addr)==1)
167
                        end_addr=addr;
168
                for(uint32_t i=addr; i<=end_addr; i++) {
169
                        c = debug_get1_filter(i, "memory");
170
                        if (c != NULL)
171
                                printf("Named memory: %s (0x%X)\n", c->name, i);
172
                        else if (addr < end_addr)
173
                                printf("Memory location 0x%X:\n",i);
174
                        val = memory_get(i);
175
                        object_dump(val);
176
                }
177
        } else if (what=='s') {
178
                if (sscanf(&cmd[3], "%X", &addr) != 1) {
179
                        fprintf(stderr, "an address, please\n");
180
                        return;
181
                }
182
                print(addr);
183
                printf("\n");
184
        } else {
185
                printf("what is '%c'?\n", what);
186
                return;
187
        }
188
}
189
 
190
void
191
compact_print(reg_t object)
192
{
193
        struct di_const *c;
194
        char *type;
195
 
196
        c = debug_get1_filter(OBJECT_TYPE(object), "type");
197
        if (c == NULL)
198
                type = "unknown";
199
        else
200
                type = c->name;
201
        printf("%-9s %d 0x%X\n",type, OBJECT_GC(object), OBJECT_DATUM(object));
202
}
203
 
204
void
205
cmd_compact_print(char *cmd)
206
{
207
        uint32_t start_addr;
208
        uint32_t end_addr;
209
        uint32_t n;
210
        char what;
211
        char a1[80],a2[80];
212
        reg_t val;
213
 
214
        if (strlen(cmd) < 4) {
215
                printf("what do you want me to print?\n");
216
                return;
217
        }
218
        if (strlen(cmd) > 75) {
219
                printf("too long command line, i refuse to parse.\n");
220
                return;
221
        }
222
        what = cmd[2];
223
        n = sscanf (cmd,"c %[rm]%X-%[rm]%X", a1, &start_addr, a2, &end_addr);
224
        if (n!= 4 || a1[0]!=a2[0]) {
225
                printf("you didn't adhere to the correct syntax format.\n");
226
                return;
227
        }
228
        if (what == 'r') {
229
                if (start_addr < 0 || end_addr >= N_REGS) {
230
                        printf("please enter a legal register range.\n");
231
                        return;
232
                }
233
                for(uint32_t i=start_addr; i<=end_addr; i++) {
234
                        val = reg_get(i);
235
                        printf("r%X: ",i);
236
                        compact_print(val);
237
                }
238
 
239
        } else if (what == 'm') {
240
          /* TODO find out memory size */
241
                if (start_addr < 0 /* || end_addr >= ?? */) {
242
                        printf("please enter a legal memory address range.\n");
243
                        return;
244
                }
245
                for(uint32_t i=start_addr; i<=end_addr; i++) {
246
                        val = memory_get(i);
247
                        printf("m%X: ",i);
248
                        compact_print(val);
249
                }
250
        }
251
        return;
252
}
253
 
254
void
255
cmd_breakpoint(char *cmd)
256
{
257
        int len = strlen(cmd);
258
        int arg;
259
 
260
        if (len == 1) {
261
                breakpoint_list();
262
                return;
263
        }
264
        if (len < 4) {
265
                printf("invalid b syntax\n");
266
                return;
267
        }
268
 
269
        arg = debug_get_key(&cmd[3], "label");
270
        if (arg == 0xdeadbeef) {
271
                if (sscanf(&cmd[3], "%X", &arg) != 1) {
272
                        printf("No thingy\n");
273
                        return;
274
                }
275
        }
276
 
277
        switch (cmd[1]) {
278
        case 's':
279
                breakpoint_set(arg);
280
                break;
281
        case 'd':
282
                breakpoint_del(arg);
283
                break;
284
        default:
285
                printf("invalid b syntax\n");
286
                return;
287
        }
288
}
289
 
290
void
291
cmd_toggle_instr_print(char *cmd)
292
{
293
        print_instructions = 1-print_instructions;
294
        printf("Instruction printing turned %s\n",
295
               print_instructions ? "on" : "off");
296
}
297
 
298
void
299
cmd_help(char *cmd)
300
{
301
        printf("%s",
302
               "commands:\n"
303
               "r [ADDR] -- run to ADDR (if given) or breakpoint or halt\n"
304
               "         (whichever occurs first)\n" "s [N]    -- step N (default 1) instructions\n"
305
               "p rN     -- print register N\n"
306
               "p rN-rM  -- print registers from N to M\n"
307
               "p r name -- print register with that name\n"
308
               "p mN     -- print memory cell N\n"
309
               "p mN-mM  -- print memory cells from N to M\n"
310
               "p sN     -- print S-expression starting at memory location N\n"
311
               "c rN-rM  -- print registers from N to M in compact form\n"
312
               "c mN-mM  -- print memory cells from N to M in compact form\n"
313
               "b        -- list breakpoints\n"
314
               "bs ADDR  -- set breakpoint\n"
315
               "bd ADDR  -- delete breakpoint\n"
316
               "d        -- dump microcode\n"
317
               "i        -- turn instruction printing on/off\n"
318
               "q        -- quit\n"
319
               "h        -- help\n"
320
               "(all numerical arguments are written hexadecimally)\n");
321
}
322
 
323
void
324
cmd_dump(char *cmd)
325
{
326
        printf("Microprogram listing:\n");
327
        dump_microcode();
328
        printf("\n");
329
}
330
 
331
 
332
 
333
void
334
command_loop(void)
335
{
336
        char lastcmd[512];
337
 
338
        lastcmd[0] = '\0';
339
        lastcmd[sizeof(lastcmd)-1] = '\0';
340
        for (;;) {
341
                char *cmd = readline("hwemu> ");
342
                if (cmd == NULL)
343
                        cmd = "q"; //EOF
344
                if (cmd[0] == '\0' && lastcmd[0] != '\0')
345
                        cmd = lastcmd;
346
                else
347
                        strncpy(lastcmd, cmd, sizeof(lastcmd)-1);
348
 
349
                switch (cmd[0]) {
350
                case 'r':
351
                        cmd_run(cmd);
352
                        break;
353
                case 's':
354
                        cmd_step(cmd);
355
                        break;
356
                case 'p':
357
                        cmd_print(cmd);
358
                        break;
359
                case 'b':
360
                        cmd_breakpoint(cmd);
361
                        break;
362
                case 'q':
363
                        printf("happy happy joy joy\n");
364
                        return;
365
                case 'h':
366
                        cmd_help(cmd);
367
                        break;
368
                case 'd':
369
                        cmd_dump(cmd);
370
                        break;
371
                case 'i':
372
                        cmd_toggle_instr_print(cmd);
373
                        break;
374
                case 'c':
375
                  cmd_compact_print(cmd);
376
                        break;
377
                case 'z':
378
                        profiler_dump_program(sim_name);
379
                        profiler_new();
380
                        break;
381
                default:
382
                        printf("?\n");
383
                }
384
                if (cmd != lastcmd)
385
                        free(cmd);
386
        }
387
}
388
 
389
/*
390
 * Signal handlers
391
 */
392
void
393
sig_stop_execution(int sig)
394
{
395
        stop_execution = 1;
396
        signal(SIGINT, sig_stop_execution);
397
}
398
 
399
extern int verify_written_memory;
400
int
401
main(int argc, char **argv)
402
{
403
        int opt;
404
        unsigned int availmem;
405
        char *microcodepath, *memorypath, *regpath;
406
        int cache_size = 0;
407
        unsigned int branch_buffer_size = 0;
408
        char* branch_pred_scheme = NULL;
409
        sim_autorun = 0;
410
 
411
        io_init();
412
 
413
        availmem = DEFAULT_MEMORY_SIZE;
414
        microcodepath = "/tmp/microcode";
415
        memorypath = NULL; //"memory.bin";
416
        regpath = NULL;
417
        verify_written_memory = 0;
418
        while ((opt = getopt(argc, argv, "t:h:a:s:c:m:r:f:Mz:")) != -1) {
419
                switch (opt) {
420
                case 't':
421
                        branch_pred_scheme = strdup(optarg);
422
                        break;
423
                case 'h':
424
                        branch_buffer_size = atoi(optarg);
425
                        printf("Branch buffer size: %u\n", branch_buffer_size);
426
                        break;
427
                case 'a':
428
                        printf("Cache size: %s\n",optarg);
429
                        cache_size = atoi(optarg);
430
                        break;
431
                case 'c':
432
                        microcodepath = optarg;
433
                        break;
434
                case 's':
435
                        availmem = atoi(optarg);
436
                        printf("Size of memory: %x\n", availmem);
437
                        break;
438
                case 'm':
439
                        memorypath = optarg;
440
                        break;
441
                case 'r':
442
                        regpath = optarg;
443
                        break;
444
                case 'f':
445
                        if (strlen(optarg) < 3 || optarg[1] != ':') {
446
                                printf("invalid -f argument '%s'\n", optarg);
447
                                usage();
448
                        }
449
                        switch (optarg[0]) {
450
                        case 'b': io_set_file(DEV_BOOT, &optarg[2]); break;
451
                        case 'k': io_set_files(DEV_TERMINAL, &optarg[2], NULL); break;
452
                        case 's': io_set_files(DEV_TERMINAL, NULL, &optarg[2]); break;
453
                        case 'i': io_set_files(DEV_SERIAL, &optarg[2], NULL); break;
454
                        case 'o': io_set_files(DEV_SERIAL, NULL, &optarg[2]); break;
455
                        case 'f': io_set_file(DEV_STORAGE, &optarg[2]); break;
456
                        }
457
                        break;
458
                case 'M':
459
                        verify_written_memory = 1;
460
                        break;
461
                case 'z':
462
                        printf("simulation name: %s\n", optarg);
463
                        sim_name = strdup(optarg);
464
                        sim_autorun = 1;
465
                        break;
466
                default:
467
                        usage();
468
                }
469
        }
470
 
471
 
472
        signal(SIGINT, sig_stop_execution);
473
        debug_init(microcodepath);
474
        machine_init(microcodepath, memorypath, availmem, regpath, cache_size);
475
        machine_shutup();
476
        if(sim_autorun == 1){
477
                sim_init(sim_name, microcode_size(), cache_size, availmem, branch_buffer_size, branch_pred_scheme);
478
        }
479
//      else 
480
//              sim_init(NULL, "gurba", microcode_size(), 512, availmem, branch_buffer_size);
481
 
482
        /*
483
        printf("Microprogram listing:\n");
484
        dump_microcode();
485
        printf("\n");
486
        */
487
 
488
        //FILE *mcdumpfile = fopen("mcdump.txt", "w");
489
        //dump_microcode_to_file(mcdumpfile);
490
        //fclose(mcdumpfile);
491
 
492
        printf("Starting execution\n");
493
        if(sim_autorun == 1){
494
                printf("Starting simulation autorun.\n");
495
                cmd_run("");
496
                printf("Done with simulation. Going to write file now...\n");
497
                profiler_dump_program(sim_name);
498
        } else {
499
                command_loop();
500
        }
501
 
502
//      FILE *profilingfile = fopen("profiling.txt", "w");
503
//      profiler_dump_program(profilingfile);
504
//      fclose(profilingfile);
505
 
506
        return 0;
507
}

powered by: WebSVN 2.1.0

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