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

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc1/] [or1ksim/] [toplevel.c] - Blame information for rev 1480

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 cvs
/* toplevel.c -- Top level simulator source file
2
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
3
 
4
This file is part of OpenRISC 1000 Architectural Simulator.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
/* Simulator commands. Help and version output. SIGINT processing.
21
Stdout redirection is specific to linux (I need to fix this). */
22
 
23 16 jrydberg
 
24 2 cvs
#include <stdio.h>
25
#include <ctype.h>
26
#include <string.h>
27
#include <stdlib.h>
28 46 lampret
#include <unistd.h>
29 2 cvs
#include <signal.h>
30
#include <stdarg.h>
31 123 markom
#include <fcntl.h>
32 728 markom
#include <limits.h>
33 1308 phoenix
#include <time.h>
34 2 cvs
 
35 1350 nogj
#include "config.h"
36
 
37
#ifdef HAVE_INTTYPES_H
38
#include <inttypes.h>
39
#endif
40
 
41
#include "port.h"
42 2 cvs
#include "arch.h"
43
#include "parse.h"
44
#include "abstract.h"
45 261 markom
#include "labels.h"
46 69 lampret
#include "sim-config.h"
47 1432 nogj
#include "opcode/or32.h"
48 103 lampret
#include "spr_defs.h"
49 1432 nogj
#include "execute.h"
50 518 markom
#include "sprs.h"
51 304 markom
#include "vapi.h"
52 479 markom
#include "gdbcomm.h"
53
#include "debug_unit.h"
54 28 lampret
#include "coff.h"
55 728 markom
#include "sched.h"
56 632 ivang
#include "profiler.h"
57
#include "mprofiler.h"
58 1308 phoenix
#include "pm.h"
59
#include "pic.h"
60
#include "stats.h"
61
#include "immu.h"
62
#include "dmmu.h"
63
#include "dcache_model.h"
64
#include "icache_model.h"
65
#include "branch_predict.h"
66
#include "dumpverilog.h"
67
#include "trace.h"
68
#include "cuc.h"
69 632 ivang
 
70 2 cvs
/* CVS revision number. */
71 1480 nogj
const char rcsrev[] = "$Revision: 1.126 $";
72 2 cvs
 
73 344 markom
inline void debug(int level, const char *format, ...)
74 2 cvs
{
75 7 jrydberg
  char *p;
76
  va_list ap;
77 2 cvs
 
78 344 markom
  if (config.sim.debug >= level) {
79 69 lampret
    if ((p = malloc(1000)) == NULL)
80
      return;
81
    va_start(ap, format);
82
    (void) vsnprintf(p, 1000, format, ap);
83
    va_end(ap);
84 997 markom
    PRINTF("%s", p);
85 69 lampret
    fflush(stdout);
86
    free(p);
87
  } else {
88
#if DEBUG
89 7 jrydberg
  if ((p = malloc(1000)) == NULL)
90
    return;
91
  va_start(ap, format);
92
  (void) vsnprintf(p, 1000, format, ap);
93
  va_end(ap);
94 997 markom
  PRINTF("%s\n", p);
95 7 jrydberg
  fflush(stdout);
96
  free(p);
97 2 cvs
#endif
98 69 lampret
  }
99 2 cvs
}
100
 
101 304 markom
void ctrl_c(signum)
102 7 jrydberg
     int signum;
103 2 cvs
{
104 1480 nogj
  /* Incase the user pressed ctrl+c twice without the sim reacting kill it.
105
   * This is incase the sim locks up in a high level routine, without executeing
106
   * any (or) code */
107
  /* FIXME: Don't kill the sim in handle_sim_command */
108
  if(runtime.sim.iprompt)
109
    sim_done();
110 551 markom
  runtime.sim.iprompt = 1;
111 7 jrydberg
  signal(SIGINT, ctrl_c);
112 2 cvs
}
113
 
114 1471 nogj
/* Periodically checks runtime.sim.iprompt to see if ctrl_c has been pressed */
115
void check_int(void *dat)
116 2 cvs
{
117 1471 nogj
  if(runtime.sim.iprompt) {
118
    set_stall_state (0);
119
    handle_sim_command();
120
  }
121
  SCHED_ADD(check_int, NULL, CHECK_INT_TIME);
122
}
123
 
124
void version(void)
125
{
126 997 markom
  PRINTF ("\n");
127
  PRINTF ("OpenRISC 1000 (OR32) Architectural Simulator, %s\n", rcsrev);
128
  PRINTF ("Copyright (C) 1999 Damjan Lampret, lampret@opencores.org\n");
129
  PRINTF ("Copyright (C) 2000 Damjan Lampret, lampret@opencores.org\n");
130
  PRINTF ("                   Jimmy Chen-Min Chen, jimmy@ee.nctu.edu.tw\n");
131
  PRINTF ("                   Johan Rydberg, johan.rydberg@insight.se\n");
132
  PRINTF ("                   Marko Mlinar, markom@opencores.org\n");
133
  PRINTF ("Copyright (C) 2001 Simon Srot, simons@opencores.org\n");
134
  PRINTF ("                   Marko Mlinar, markom@opencores.org\n");
135
  PRINTF ("Copyright (C) 2002 Marko Mlinar, markom@opencores.org\n");
136
  PRINTF ("                   Simon Srot, simons@opencores.org\n");
137
  PRINTF ("Visit http://www.opencores.org for more information about ");
138
  PRINTF ("OpenRISC 1000 and\nother open source cores.\n\n");
139
  PRINTF ("This software comes with ABSOLUTELY NO WARRANTY; for ");
140
  PRINTF ("details see COPYING.\nThis is free software, and you ");
141
  PRINTF ("are welcome to redistribute it under certain\nconditions; ");
142
  PRINTF ("for details see COPYING.\n");
143 2 cvs
}
144
 
145 1360 nogj
struct sim_reset_hook {
146
  void *dat;
147
  void (*reset_hook)(void *);
148
  struct sim_reset_hook *next;
149
};
150 21 cmchen
 
151 1360 nogj
struct sim_reset_hook *sim_reset_hooks = NULL;
152
 
153
/* Registers a new reset hook, called when sim_reset below is called */
154
void reg_sim_reset(void (*reset_hook)(void *), void *dat)
155
{
156
  struct sim_reset_hook *new = malloc(sizeof(struct sim_reset_hook));
157
 
158
  if(!new) {
159
    fprintf(stderr, "reg_sim_reset: Out-of-memory\n");
160
    exit(1);
161
  }
162
 
163
  new->dat = dat;
164
  new->reset_hook = reset_hook;
165
  new->next = sim_reset_hooks;
166
  sim_reset_hooks = new;
167
}
168
 
169 479 markom
/* Resets all subunits */
170 1353 nogj
void sim_reset (void)
171 479 markom
{
172 1360 nogj
  struct sim_reset_hook *cur_reset = sim_reset_hooks;
173
 
174 1390 nogj
  /* We absolutely MUST reset the scheduler first */
175
  sched_reset();
176 1360 nogj
 
177
  while(cur_reset) {
178
    cur_reset->reset_hook(cur_reset->dat);
179
    cur_reset = cur_reset->next;
180
  }
181
 
182 479 markom
  tick_reset();
183
  pm_reset();
184
  pic_reset();
185
  du_reset ();
186 1452 nogj
 
187 1471 nogj
  /* Make sure that runtime.sim.iprompt is the first thing to get checked */
188
  SCHED_ADD(check_int, NULL, 0);
189
 
190 1452 nogj
  lock_memory_table ();
191
 
192
  /* FIXME: Lame-ass way to get runtime.sim.mem_cycles not going into overly
193
   * negative numbers.  This happens because parse.c uses setsim_mem32 to load
194
   * the program but set_mem32 calls dc_simulate_write, which inturn calls
195
   * setsim_mem32.  This mess of memory statistics needs to be sorted out for
196
   * good one day */
197
  runtime.sim.mem_cycles = 0;
198 557 markom
  cpu_reset();
199 479 markom
}
200
 
201 304 markom
/* Initalizes all devices and sim */
202
void sim_init ()
203 2 cvs
{
204 424 markom
  init_memory_table ();
205 269 markom
  init_labels();
206
  init_breakpoints();
207 361 markom
  initstats();
208
  build_automata();
209 1390 nogj
 
210 1452 nogj
#if DYNAMIC_EXECUTION
211
  /* Note: This must be called before the scheduler is used */
212
  init_dyn_recomp();
213
#endif
214
 
215 1390 nogj
  sched_init();
216 361 markom
 
217 305 markom
  if (config.sim.profile) {
218 361 markom
    runtime.sim.fprof = fopen(config.sim.prof_fn, "wt+");
219
    if(!runtime.sim.fprof) {
220 551 markom
      fprintf(stderr, "ERROR: Problems opening profile file.\n");
221
      exit (1);
222 173 markom
    } else
223 897 markom
      fprintf(runtime.sim.fprof, "+00000000 FFFFFFFF FFFFFFFF [outside_functions]\n");
224 173 markom
  }
225 294 markom
 
226 547 markom
  if (config.sim.mprofile) {
227
    runtime.sim.fmprof = fopen(config.sim.mprof_fn, "wb+");
228
    if(!runtime.sim.fmprof) {
229 551 markom
      fprintf(stderr, "ERROR: Problems opening memory profile file.\n");
230
      exit (1);
231 547 markom
    }
232
  }
233
 
234 294 markom
  if (config.sim.exe_log) {
235 361 markom
    runtime.sim.fexe_log = fopen(config.sim.exe_log_fn, "wt+");
236
    if(!runtime.sim.fexe_log) {
237 997 markom
      PRINTF("ERROR: Problems opening exe_log file.\n");
238 551 markom
      exit (1);
239 294 markom
    }
240
  }
241 263 markom
 
242 624 ivang
  if (config.sim.spr_log) {
243 997 markom
    PRINTF("OPENING SPRLOG\n");
244 624 ivang
    runtime.sim.fspr_log = fopen(config.sim.spr_log_fn, "wt+");
245
    if (!runtime.sim.fspr_log) {
246 997 markom
      PRINTF("ERROR: Problems opening spr_log file.\n");
247 624 ivang
      exit(1);
248
    }
249
  }
250
 
251 262 markom
  /* Initialize memory */
252
  {
253 361 markom
    extern struct dev_memarea *dev_list;
254 554 markom
    struct dev_memarea *area;
255 361 markom
    int i;
256
    if (config.memory.type == MT_RANDOM) {
257
      unsigned int val = 0;
258 123 markom
 
259 262 markom
      if (config.memory.random_seed == -1) {
260 551 markom
        runtime.memory.random_seed = time(NULL);
261 262 markom
        /* Print out the seed just in case we ever need to debug */
262 997 markom
        PRINTF("Seeding random generator with value %d\n", config.memory.random_seed);
263 551 markom
      } else
264
        runtime.memory.random_seed = config.memory.random_seed;
265
      srandom(runtime.memory.random_seed);
266 262 markom
 
267 554 markom
      for (area = dev_list; area; area = area->next)
268
        for(i = 0; i < area->size; i++) {
269 221 markom
          val = random();
270 554 markom
          setsim_mem8(i + area->addr_compare, val & 0xFF);
271 221 markom
        }
272 262 markom
    } else if(config.memory.type == MT_PATTERN) {
273 554 markom
      for (area = dev_list; area; area = area->next)
274
        for(i = 0; i < area->size; i++)
275
          setsim_mem8(i + area->addr_compare, config.memory.pattern);
276 269 markom
    } else if (config.memory.type != MT_UNKNOWN) {
277 262 markom
      fprintf(stderr, "Invalid memory configuration type.\n");
278 361 markom
      exit(1);
279 221 markom
    }
280 242 markom
  }
281 262 markom
 
282 361 markom
  if(runtime.sim.filename) {
283
    unsigned long endaddr = 0xFFFFFFFF;
284
    endaddr = loadcode(runtime.sim.filename, 0, 0); /* MM170901 always load at address zero.  */
285
    if (endaddr == -1) {
286
      fprintf(stderr, "Problems loading boot code.\n");
287
      exit(1);
288
    }
289
  }
290 551 markom
 
291 361 markom
  /* Disable gdb debugging, if debug module is not available.  */
292
  if (config.debug.gdb_enabled && !config.debug.enabled) {
293
    config.debug.gdb_enabled = 0;
294
    if (config.sim.verbose)
295
      fprintf (stderr, "WARNING: Debug module not enabled, cannot start gdb.\n");
296
  }
297 551 markom
 
298 550 markom
  if (config.debug.gdb_enabled)
299 479 markom
    gdbcomm_init ();
300 551 markom
 
301 361 markom
  /* Enable dependency stats, if we want to do history analisis */
302 394 markom
  if (config.sim.history && !config.cpu.dependstats) {
303
    config.cpu.dependstats = 1;
304 361 markom
    if (config.sim.verbose)
305 394 markom
      fprintf (stderr, "WARNING: dependstats stats must be enabled to do history analisis.\n");
306 361 markom
  }
307 551 markom
 
308 361 markom
  /* Debug forces verbose */
309
  if (config.sim.debug && !config.sim.verbose) {
310
    config.sim.verbose = 1;
311
    fprintf (stderr, "WARNING: verbose turned on.\n");
312
  }
313
 
314
  /* Start VAPI before device initialization.  */
315
  if (config.vapi.enabled) {
316 551 markom
    runtime.vapi.enabled = 1;
317 361 markom
    vapi_init ();
318
    if (config.sim.verbose)
319 997 markom
      PRINTF ("VAPI started, waiting for clients.\n");
320 361 markom
  }
321 538 markom
 
322 479 markom
  sim_reset ();
323 424 markom
 
324 361 markom
  /* Wait till all test are connected.  */
325 551 markom
  if (runtime.vapi.enabled) {
326 361 markom
    int numu = vapi_num_unconnected (0);
327
    if (numu) {
328 997 markom
      PRINTF ("\nWaiting for VAPI tests with ids:\n");
329 361 markom
      vapi_num_unconnected (1);
330 997 markom
      PRINTF ("\n");
331 1308 phoenix
      while ((numu = vapi_num_unconnected (0))) {
332 361 markom
        vapi_check ();
333 997 markom
        PRINTF ("\rStill waiting for %i VAPI test(s) to connect.       ", numu);
334 361 markom
        usleep (100);
335
      }
336 997 markom
      PRINTF ("\n");
337 361 markom
    }
338 997 markom
    PRINTF ("All devices connected                         \n");
339 361 markom
  }
340
  /* simulator is initialized */
341
  runtime.sim.init = 0;
342 304 markom
}
343 7 jrydberg
 
344 304 markom
/* Cleanup */
345 1446 nogj
void sim_done (void)
346 304 markom
{
347
  if (config.sim.profile) {
348 1350 nogj
    fprintf(runtime.sim.fprof,"-%08llX FFFFFFFF\n", runtime.sim.cycles);
349 361 markom
    fclose(runtime.sim.fprof);
350 304 markom
  }
351 547 markom
 
352 847 markom
  if (config.sim.mprofile) fclose(runtime.sim.fmprof);
353 361 markom
  if (config.sim.exe_log)   fclose(runtime.sim.fexe_log);
354 551 markom
  if (runtime.vapi.enabled)  vapi_done ();
355 426 markom
  done_memory_table ();
356 304 markom
  exit(0);
357
}
358
 
359 728 markom
/* Executes jobs in time queue */
360 1452 nogj
#if !(DYNAMIC_EXECUTION)
361
static inline
362
#endif
363
void do_scheduler (void)
364 728 markom
{
365 1390 nogj
  struct sched_entry *tmp;
366 632 ivang
 
367 728 markom
  /* Execute all jobs till now */
368
  do {
369 1390 nogj
    tmp = scheduler.job_queue;
370
    scheduler.job_queue = tmp->next;
371
    tmp->next = scheduler.free_job_queue;
372
    scheduler.free_job_queue = tmp;
373
 
374 1452 nogj
#if DYNAMIC_EXECUTION
375
    /* This is done here and not after the loop has run because the job function
376
     * may raise an exception in which case set_sched_cycle would never be
377
     * called. */
378
    set_sched_cycle(scheduler.job_queue->time);
379
#endif
380
    TRACE_(sched)("Setting to-go cycles to %"PRIi32" at %lli\n",
381
                  scheduler.job_queue->time, runtime.sim.cycles);
382
 
383 1390 nogj
    tmp->func (tmp->param);
384
  } while (scheduler.job_queue->time <= 0);
385 728 markom
}
386 632 ivang
 
387 1471 nogj
void recalc_do_stats(void)
388
{
389
  extern int do_stats;
390
  do_stats = config.cpu.dependstats || config.cpu.superscalar ||
391
             config.cpu.dependstats || config.sim.history || config.sim.exe_log;
392
}
393
 
394 728 markom
/* Main function */
395 304 markom
int main(argc, argv)
396
     int argc;
397
     char *argv[];
398
{
399 361 markom
  srand(getpid());
400
  init_defconfig();
401 1358 nogj
  reg_config_secs();
402 361 markom
  if (parse_args(argc, argv)) {
403 997 markom
    PRINTF("Usage: %s [options] <filename>\n", argv[0]);
404
    PRINTF("Options:\n");
405
    PRINTF(" -v                   version and copyright note\n");
406
    PRINTF(" -i                   enable interactive command prompt\n");
407
    PRINTF(" --nosrv              do not launch JTAG proxy server\n"); /* (CZ) */
408
    PRINTF(" --srv <n>            launch JTAG proxy server on port <n>; [random]\n"); /* (CZ) */
409
    PRINTF(" -f or --file         load script file [sim.cfg]\n");
410
    PRINTF(" --enable-profile     enable profiling.\n");
411
    PRINTF(" --enable-mprofile    enable memory profiling.\n");
412
    PRINTF("\nor   : %s ", argv[0]);
413 847 markom
    mp_help ();
414 997 markom
    PRINTF("\nor   : %s ", argv[0]);
415 847 markom
    prof_help ();
416 361 markom
    exit(-1);
417
  }
418 304 markom
 
419
  /* Read configuration file.  */
420 361 markom
  if (!runtime.sim.script_file_specified)
421
    read_script_file ("sim.cfg");
422 883 markom
 
423
  /* Overide parameters with command line ones */
424
  if (runtime.simcmd.profile) config.sim.profile = 1;
425
  if (runtime.simcmd.mprofile) config.sim.mprofile = 1;
426
 
427 424 markom
  if (!runtime.sim.script_file_specified && config.sim.verbose)
428
    fprintf (stderr, "WARNING: No config file read, assuming default configuration.\n");
429 304 markom
  print_config();
430
  signal(SIGINT, ctrl_c);
431 335 markom
 
432 1353 nogj
  runtime.sim.hush = 1;
433 1471 nogj
  recalc_do_stats();
434 1353 nogj
 
435 1471 nogj
  sim_init ();
436
 
437 361 markom
  while(1) {
438 1471 nogj
    long long time_start = runtime.sim.cycles;
439
    if (config.debug.enabled) {
440
      du_clock(); // reset watchpoints
441
      while (runtime.cpu.stalled) {
442
        if(config.debug.gdb_enabled) {
443
          BlockJTAG();
444
          HandleServerSocket(false);
445
        } else {
446
          fprintf (stderr, "WARNING: CPU stalled and gdb connection not enabled.\n");
447
          /* Dump the user into interactive mode.  From there he can decide what
448
           * to do. */
449
          handle_sim_command();
450
          sim_done();
451 557 markom
        }
452 1471 nogj
        if(runtime.sim.iprompt)
453
          handle_sim_command();
454 479 markom
      }
455 1471 nogj
    }
456 127 chris
 
457 1471 nogj
    /* Each cycle has counter of mem_cycles; this value is joined with cycles
458
       at the end of the cycle; no sim originated memory accesses should be
459
       performed inbetween. */
460
    runtime.sim.mem_cycles = 0;
461
    if (!config.pm.enabled || !testsprbits(SPR_PMR, SPR_PMR_DME | SPR_PMR_SME))
462
      if (cpu_clock ())
463
        /* A breakpoint has been hit, drop to interactive mode */
464
        handle_sim_command();
465 304 markom
 
466 1471 nogj
    if (config.vapi.enabled && runtime.vapi.enabled) vapi_check();
467
    if (config.debug.gdb_enabled) HandleServerSocket(false); /* block & check_stdin = false */
468
    if(config.debug.enabled)
469
      if (testsprbits(SPR_DMR1, SPR_DMR1_ST)) set_stall_state (1);
470 557 markom
 
471 1471 nogj
    runtime.sim.cycles += runtime.sim.mem_cycles;
472
    scheduler.job_queue->time -= runtime.sim.cycles - time_start;
473
    if (scheduler.job_queue->time <= 0) do_scheduler ();
474 361 markom
  }
475
  sim_done();
476 2 cvs
}

powered by: WebSVN 2.1.0

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