/* toplevel.c -- Top level simulator source file
|
/* toplevel.c -- Top level simulator source file
|
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
|
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
|
|
|
This file is part of OpenRISC 1000 Architectural Simulator.
|
This file is part of OpenRISC 1000 Architectural Simulator.
|
|
|
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
(at your option) any later version.
|
(at your option) any later version.
|
|
|
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
GNU General Public License for more details.
|
GNU General Public License for more details.
|
|
|
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|
|
/* Simulator commands. Help and version output. SIGINT processing.
|
/* Simulator commands. Help and version output. SIGINT processing.
|
Stdout redirection is specific to linux (I need to fix this). */
|
Stdout redirection is specific to linux (I need to fix this). */
|
|
|
|
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <ctype.h>
|
#include <ctype.h>
|
#include <string.h>
|
#include <string.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <unistd.h>
|
#include <unistd.h>
|
#include <signal.h>
|
#include <signal.h>
|
#include <stdarg.h>
|
#include <stdarg.h>
|
#include <fcntl.h>
|
#include <fcntl.h>
|
#include <limits.h>
|
#include <limits.h>
|
#include <time.h>
|
#include <time.h>
|
|
|
#include "config.h"
|
#include "config.h"
|
|
|
#ifdef HAVE_INTTYPES_H
|
#ifdef HAVE_INTTYPES_H
|
#include <inttypes.h>
|
#include <inttypes.h>
|
#endif
|
#endif
|
|
|
#include "port.h"
|
#include "port.h"
|
#include "arch.h"
|
#include "arch.h"
|
#include "parse.h"
|
#include "parse.h"
|
#include "abstract.h"
|
#include "abstract.h"
|
#include "labels.h"
|
#include "labels.h"
|
#include "execute.h"
|
#include "execute.h"
|
#include "sim-config.h"
|
#include "sim-config.h"
|
#include "spr_defs.h"
|
#include "spr_defs.h"
|
#include "sprs.h"
|
#include "sprs.h"
|
#include "vapi.h"
|
#include "vapi.h"
|
#include "gdbcomm.h"
|
#include "gdbcomm.h"
|
#include "debug_unit.h"
|
#include "debug_unit.h"
|
#include "coff.h"
|
#include "coff.h"
|
#include "sched.h"
|
#include "sched.h"
|
#include "profiler.h"
|
#include "profiler.h"
|
#include "mprofiler.h"
|
#include "mprofiler.h"
|
#include "pm.h"
|
#include "pm.h"
|
#include "pic.h"
|
#include "pic.h"
|
#include "opcode/or32.h"
|
#include "opcode/or32.h"
|
#include "stats.h"
|
#include "stats.h"
|
#include "immu.h"
|
#include "immu.h"
|
#include "dmmu.h"
|
#include "dmmu.h"
|
#include "dcache_model.h"
|
#include "dcache_model.h"
|
#include "icache_model.h"
|
#include "icache_model.h"
|
#include "branch_predict.h"
|
#include "branch_predict.h"
|
#include "dumpverilog.h"
|
#include "dumpverilog.h"
|
#include "trace.h"
|
#include "trace.h"
|
#include "cuc.h"
|
#include "cuc.h"
|
|
|
/* CVS revision number. */
|
/* CVS revision number. */
|
const char rcsrev[] = "$Revision: 1.115 $";
|
const char rcsrev[] = "$Revision: 1.116 $";
|
|
|
inline void debug(int level, const char *format, ...)
|
inline void debug(int level, const char *format, ...)
|
{
|
{
|
char *p;
|
char *p;
|
va_list ap;
|
va_list ap;
|
|
|
if (config.sim.debug >= level) {
|
if (config.sim.debug >= level) {
|
if ((p = malloc(1000)) == NULL)
|
if ((p = malloc(1000)) == NULL)
|
return;
|
return;
|
va_start(ap, format);
|
va_start(ap, format);
|
(void) vsnprintf(p, 1000, format, ap);
|
(void) vsnprintf(p, 1000, format, ap);
|
va_end(ap);
|
va_end(ap);
|
PRINTF("%s", p);
|
PRINTF("%s", p);
|
fflush(stdout);
|
fflush(stdout);
|
free(p);
|
free(p);
|
} else {
|
} else {
|
#if DEBUG
|
#if DEBUG
|
if ((p = malloc(1000)) == NULL)
|
if ((p = malloc(1000)) == NULL)
|
return;
|
return;
|
va_start(ap, format);
|
va_start(ap, format);
|
(void) vsnprintf(p, 1000, format, ap);
|
(void) vsnprintf(p, 1000, format, ap);
|
va_end(ap);
|
va_end(ap);
|
PRINTF("%s\n", p);
|
PRINTF("%s\n", p);
|
fflush(stdout);
|
fflush(stdout);
|
free(p);
|
free(p);
|
#endif
|
#endif
|
}
|
}
|
}
|
}
|
|
|
void ctrl_c(signum)
|
void ctrl_c(signum)
|
int signum;
|
int signum;
|
{
|
{
|
runtime.sim.cont_run = runtime.cpu.stalled ? 0 : 1;
|
runtime.sim.cont_run = runtime.cpu.stalled ? 0 : 1;
|
runtime.sim.iprompt = 1;
|
runtime.sim.iprompt = 1;
|
set_stall_state (0);
|
set_stall_state (0);
|
signal(SIGINT, ctrl_c);
|
signal(SIGINT, ctrl_c);
|
}
|
}
|
|
|
void version()
|
void version()
|
{
|
{
|
PRINTF ("\n");
|
PRINTF ("\n");
|
PRINTF ("OpenRISC 1000 (OR32) Architectural Simulator, %s\n", rcsrev);
|
PRINTF ("OpenRISC 1000 (OR32) Architectural Simulator, %s\n", rcsrev);
|
PRINTF ("Copyright (C) 1999 Damjan Lampret, lampret@opencores.org\n");
|
PRINTF ("Copyright (C) 1999 Damjan Lampret, lampret@opencores.org\n");
|
PRINTF ("Copyright (C) 2000 Damjan Lampret, lampret@opencores.org\n");
|
PRINTF ("Copyright (C) 2000 Damjan Lampret, lampret@opencores.org\n");
|
PRINTF (" Jimmy Chen-Min Chen, jimmy@ee.nctu.edu.tw\n");
|
PRINTF (" Jimmy Chen-Min Chen, jimmy@ee.nctu.edu.tw\n");
|
PRINTF (" Johan Rydberg, johan.rydberg@insight.se\n");
|
PRINTF (" Johan Rydberg, johan.rydberg@insight.se\n");
|
PRINTF (" Marko Mlinar, markom@opencores.org\n");
|
PRINTF (" Marko Mlinar, markom@opencores.org\n");
|
PRINTF ("Copyright (C) 2001 Simon Srot, simons@opencores.org\n");
|
PRINTF ("Copyright (C) 2001 Simon Srot, simons@opencores.org\n");
|
PRINTF (" Marko Mlinar, markom@opencores.org\n");
|
PRINTF (" Marko Mlinar, markom@opencores.org\n");
|
PRINTF ("Copyright (C) 2002 Marko Mlinar, markom@opencores.org\n");
|
PRINTF ("Copyright (C) 2002 Marko Mlinar, markom@opencores.org\n");
|
PRINTF (" Simon Srot, simons@opencores.org\n");
|
PRINTF (" Simon Srot, simons@opencores.org\n");
|
PRINTF ("Visit http://www.opencores.org for more information about ");
|
PRINTF ("Visit http://www.opencores.org for more information about ");
|
PRINTF ("OpenRISC 1000 and\nother open source cores.\n\n");
|
PRINTF ("OpenRISC 1000 and\nother open source cores.\n\n");
|
PRINTF ("This software comes with ABSOLUTELY NO WARRANTY; for ");
|
PRINTF ("This software comes with ABSOLUTELY NO WARRANTY; for ");
|
PRINTF ("details see COPYING.\nThis is free software, and you ");
|
PRINTF ("details see COPYING.\nThis is free software, and you ");
|
PRINTF ("are welcome to redistribute it under certain\nconditions; ");
|
PRINTF ("are welcome to redistribute it under certain\nconditions; ");
|
PRINTF ("for details see COPYING.\n");
|
PRINTF ("for details see COPYING.\n");
|
}
|
}
|
|
|
struct sim_reset_hook {
|
struct sim_reset_hook {
|
void *dat;
|
void *dat;
|
void (*reset_hook)(void *);
|
void (*reset_hook)(void *);
|
struct sim_reset_hook *next;
|
struct sim_reset_hook *next;
|
};
|
};
|
|
|
struct sim_reset_hook *sim_reset_hooks = NULL;
|
struct sim_reset_hook *sim_reset_hooks = NULL;
|
|
|
/* Registers a new reset hook, called when sim_reset below is called */
|
/* Registers a new reset hook, called when sim_reset below is called */
|
void reg_sim_reset(void (*reset_hook)(void *), void *dat)
|
void reg_sim_reset(void (*reset_hook)(void *), void *dat)
|
{
|
{
|
struct sim_reset_hook *new = malloc(sizeof(struct sim_reset_hook));
|
struct sim_reset_hook *new = malloc(sizeof(struct sim_reset_hook));
|
|
|
if(!new) {
|
if(!new) {
|
fprintf(stderr, "reg_sim_reset: Out-of-memory\n");
|
fprintf(stderr, "reg_sim_reset: Out-of-memory\n");
|
exit(1);
|
exit(1);
|
}
|
}
|
|
|
new->dat = dat;
|
new->dat = dat;
|
new->reset_hook = reset_hook;
|
new->reset_hook = reset_hook;
|
new->next = sim_reset_hooks;
|
new->next = sim_reset_hooks;
|
sim_reset_hooks = new;
|
sim_reset_hooks = new;
|
}
|
}
|
|
|
/* Resets all subunits */
|
/* Resets all subunits */
|
void sim_reset (void)
|
void sim_reset (void)
|
{
|
{
|
struct sim_reset_hook *cur_reset = sim_reset_hooks;
|
struct sim_reset_hook *cur_reset = sim_reset_hooks;
|
|
|
SCHED_INIT();
|
SCHED_INIT();
|
|
|
while(cur_reset) {
|
while(cur_reset) {
|
cur_reset->reset_hook(cur_reset->dat);
|
cur_reset->reset_hook(cur_reset->dat);
|
cur_reset = cur_reset->next;
|
cur_reset = cur_reset->next;
|
}
|
}
|
|
|
tick_reset();
|
tick_reset();
|
pm_reset();
|
pm_reset();
|
pic_reset();
|
pic_reset();
|
du_reset ();
|
du_reset ();
|
cpu_reset();
|
cpu_reset();
|
}
|
}
|
|
|
/* Initalizes all devices and sim */
|
/* Initalizes all devices and sim */
|
void sim_init ()
|
void sim_init ()
|
{
|
{
|
init_memory_table ();
|
init_memory_table ();
|
init_labels();
|
init_labels();
|
init_breakpoints();
|
init_breakpoints();
|
initstats();
|
initstats();
|
build_automata();
|
build_automata();
|
|
|
if (config.sim.profile) {
|
if (config.sim.profile) {
|
runtime.sim.fprof = fopen(config.sim.prof_fn, "wt+");
|
runtime.sim.fprof = fopen(config.sim.prof_fn, "wt+");
|
if(!runtime.sim.fprof) {
|
if(!runtime.sim.fprof) {
|
fprintf(stderr, "ERROR: Problems opening profile file.\n");
|
fprintf(stderr, "ERROR: Problems opening profile file.\n");
|
exit (1);
|
exit (1);
|
} else
|
} else
|
fprintf(runtime.sim.fprof, "+00000000 FFFFFFFF FFFFFFFF [outside_functions]\n");
|
fprintf(runtime.sim.fprof, "+00000000 FFFFFFFF FFFFFFFF [outside_functions]\n");
|
}
|
}
|
|
|
if (config.sim.mprofile) {
|
if (config.sim.mprofile) {
|
runtime.sim.fmprof = fopen(config.sim.mprof_fn, "wb+");
|
runtime.sim.fmprof = fopen(config.sim.mprof_fn, "wb+");
|
if(!runtime.sim.fmprof) {
|
if(!runtime.sim.fmprof) {
|
fprintf(stderr, "ERROR: Problems opening memory profile file.\n");
|
fprintf(stderr, "ERROR: Problems opening memory profile file.\n");
|
exit (1);
|
exit (1);
|
}
|
}
|
}
|
}
|
|
|
if (config.sim.exe_log) {
|
if (config.sim.exe_log) {
|
runtime.sim.fexe_log = fopen(config.sim.exe_log_fn, "wt+");
|
runtime.sim.fexe_log = fopen(config.sim.exe_log_fn, "wt+");
|
if(!runtime.sim.fexe_log) {
|
if(!runtime.sim.fexe_log) {
|
PRINTF("ERROR: Problems opening exe_log file.\n");
|
PRINTF("ERROR: Problems opening exe_log file.\n");
|
exit (1);
|
exit (1);
|
}
|
}
|
}
|
}
|
|
|
if (config.sim.spr_log) {
|
if (config.sim.spr_log) {
|
PRINTF("OPENING SPRLOG\n");
|
PRINTF("OPENING SPRLOG\n");
|
runtime.sim.fspr_log = fopen(config.sim.spr_log_fn, "wt+");
|
runtime.sim.fspr_log = fopen(config.sim.spr_log_fn, "wt+");
|
if (!runtime.sim.fspr_log) {
|
if (!runtime.sim.fspr_log) {
|
PRINTF("ERROR: Problems opening spr_log file.\n");
|
PRINTF("ERROR: Problems opening spr_log file.\n");
|
exit(1);
|
exit(1);
|
}
|
}
|
}
|
}
|
|
|
/* Initialize memory */
|
/* Initialize memory */
|
{
|
{
|
extern struct dev_memarea *dev_list;
|
extern struct dev_memarea *dev_list;
|
struct dev_memarea *area;
|
struct dev_memarea *area;
|
int i;
|
int i;
|
if (config.memory.type == MT_RANDOM) {
|
if (config.memory.type == MT_RANDOM) {
|
unsigned int val = 0;
|
unsigned int val = 0;
|
|
|
if (config.memory.random_seed == -1) {
|
if (config.memory.random_seed == -1) {
|
runtime.memory.random_seed = time(NULL);
|
runtime.memory.random_seed = time(NULL);
|
/* Print out the seed just in case we ever need to debug */
|
/* Print out the seed just in case we ever need to debug */
|
PRINTF("Seeding random generator with value %d\n", config.memory.random_seed);
|
PRINTF("Seeding random generator with value %d\n", config.memory.random_seed);
|
} else
|
} else
|
runtime.memory.random_seed = config.memory.random_seed;
|
runtime.memory.random_seed = config.memory.random_seed;
|
srandom(runtime.memory.random_seed);
|
srandom(runtime.memory.random_seed);
|
|
|
for (area = dev_list; area; area = area->next)
|
for (area = dev_list; area; area = area->next)
|
for(i = 0; i < area->size; i++) {
|
for(i = 0; i < area->size; i++) {
|
val = random();
|
val = random();
|
setsim_mem8(i + area->addr_compare, val & 0xFF);
|
setsim_mem8(i + area->addr_compare, val & 0xFF);
|
}
|
}
|
} else if(config.memory.type == MT_PATTERN) {
|
} else if(config.memory.type == MT_PATTERN) {
|
for (area = dev_list; area; area = area->next)
|
for (area = dev_list; area; area = area->next)
|
for(i = 0; i < area->size; i++)
|
for(i = 0; i < area->size; i++)
|
setsim_mem8(i + area->addr_compare, config.memory.pattern);
|
setsim_mem8(i + area->addr_compare, config.memory.pattern);
|
} else if (config.memory.type != MT_UNKNOWN) {
|
} else if (config.memory.type != MT_UNKNOWN) {
|
fprintf(stderr, "Invalid memory configuration type.\n");
|
fprintf(stderr, "Invalid memory configuration type.\n");
|
exit(1);
|
exit(1);
|
}
|
}
|
}
|
}
|
|
|
if(runtime.sim.filename) {
|
if(runtime.sim.filename) {
|
unsigned long endaddr = 0xFFFFFFFF;
|
unsigned long endaddr = 0xFFFFFFFF;
|
endaddr = loadcode(runtime.sim.filename, 0, 0); /* MM170901 always load at address zero. */
|
endaddr = loadcode(runtime.sim.filename, 0, 0); /* MM170901 always load at address zero. */
|
if (endaddr == -1) {
|
if (endaddr == -1) {
|
fprintf(stderr, "Problems loading boot code.\n");
|
fprintf(stderr, "Problems loading boot code.\n");
|
exit(1);
|
exit(1);
|
}
|
}
|
}
|
}
|
|
|
#if !FAST_SIM /* We assume we have valid configuration with fsim*/
|
|
/* Disable gdb debugging, if debug module is not available. */
|
/* Disable gdb debugging, if debug module is not available. */
|
if (config.debug.gdb_enabled && !config.debug.enabled) {
|
if (config.debug.gdb_enabled && !config.debug.enabled) {
|
config.debug.gdb_enabled = 0;
|
config.debug.gdb_enabled = 0;
|
if (config.sim.verbose)
|
if (config.sim.verbose)
|
fprintf (stderr, "WARNING: Debug module not enabled, cannot start gdb.\n");
|
fprintf (stderr, "WARNING: Debug module not enabled, cannot start gdb.\n");
|
}
|
}
|
#endif
|
|
|
|
if (config.debug.gdb_enabled)
|
if (config.debug.gdb_enabled)
|
gdbcomm_init ();
|
gdbcomm_init ();
|
|
|
#if !FAST_SIM /* We assume we have valid configuration with fsim*/
|
|
/* Enable dependency stats, if we want to do history analisis */
|
/* Enable dependency stats, if we want to do history analisis */
|
if (config.sim.history && !config.cpu.dependstats) {
|
if (config.sim.history && !config.cpu.dependstats) {
|
config.cpu.dependstats = 1;
|
config.cpu.dependstats = 1;
|
if (config.sim.verbose)
|
if (config.sim.verbose)
|
fprintf (stderr, "WARNING: dependstats stats must be enabled to do history analisis.\n");
|
fprintf (stderr, "WARNING: dependstats stats must be enabled to do history analisis.\n");
|
}
|
}
|
#endif
|
|
|
|
#if !FAST_SIM /* We assume we have valid configuration with fsim*/
|
|
/* Debug forces verbose */
|
/* Debug forces verbose */
|
if (config.sim.debug && !config.sim.verbose) {
|
if (config.sim.debug && !config.sim.verbose) {
|
config.sim.verbose = 1;
|
config.sim.verbose = 1;
|
fprintf (stderr, "WARNING: verbose turned on.\n");
|
fprintf (stderr, "WARNING: verbose turned on.\n");
|
}
|
}
|
#endif
|
|
|
|
/* Start VAPI before device initialization. */
|
/* Start VAPI before device initialization. */
|
if (config.vapi.enabled) {
|
if (config.vapi.enabled) {
|
runtime.vapi.enabled = 1;
|
runtime.vapi.enabled = 1;
|
vapi_init ();
|
vapi_init ();
|
if (config.sim.verbose)
|
if (config.sim.verbose)
|
PRINTF ("VAPI started, waiting for clients.\n");
|
PRINTF ("VAPI started, waiting for clients.\n");
|
}
|
}
|
|
|
sim_reset ();
|
sim_reset ();
|
|
|
lock_memory_table ();
|
lock_memory_table ();
|
|
|
/* Wait till all test are connected. */
|
/* Wait till all test are connected. */
|
if (runtime.vapi.enabled) {
|
if (runtime.vapi.enabled) {
|
int numu = vapi_num_unconnected (0);
|
int numu = vapi_num_unconnected (0);
|
if (numu) {
|
if (numu) {
|
PRINTF ("\nWaiting for VAPI tests with ids:\n");
|
PRINTF ("\nWaiting for VAPI tests with ids:\n");
|
vapi_num_unconnected (1);
|
vapi_num_unconnected (1);
|
PRINTF ("\n");
|
PRINTF ("\n");
|
while ((numu = vapi_num_unconnected (0))) {
|
while ((numu = vapi_num_unconnected (0))) {
|
vapi_check ();
|
vapi_check ();
|
PRINTF ("\rStill waiting for %i VAPI test(s) to connect. ", numu);
|
PRINTF ("\rStill waiting for %i VAPI test(s) to connect. ", numu);
|
usleep (100);
|
usleep (100);
|
}
|
}
|
PRINTF ("\n");
|
PRINTF ("\n");
|
}
|
}
|
PRINTF ("All devices connected \n");
|
PRINTF ("All devices connected \n");
|
}
|
}
|
/* simulator is initialized */
|
/* simulator is initialized */
|
runtime.sim.init = 0;
|
runtime.sim.init = 0;
|
}
|
}
|
|
|
/* Cleanup */
|
/* Cleanup */
|
void sim_done ()
|
void sim_done ()
|
{
|
{
|
if (config.sim.profile) {
|
if (config.sim.profile) {
|
fprintf(runtime.sim.fprof,"-%08llX FFFFFFFF\n", runtime.sim.cycles);
|
fprintf(runtime.sim.fprof,"-%08llX FFFFFFFF\n", runtime.sim.cycles);
|
fclose(runtime.sim.fprof);
|
fclose(runtime.sim.fprof);
|
}
|
}
|
|
|
if (config.sim.mprofile) fclose(runtime.sim.fmprof);
|
if (config.sim.mprofile) fclose(runtime.sim.fmprof);
|
if (config.sim.exe_log) fclose(runtime.sim.fexe_log);
|
if (config.sim.exe_log) fclose(runtime.sim.fexe_log);
|
if (runtime.vapi.enabled) vapi_done ();
|
if (runtime.vapi.enabled) vapi_done ();
|
done_memory_table ();
|
done_memory_table ();
|
exit(0);
|
exit(0);
|
}
|
}
|
|
|
/* Executes jobs in time queue */
|
/* Executes jobs in time queue */
|
static inline void do_scheduler ()
|
static inline void do_scheduler ()
|
{
|
{
|
void (*func)(void *);
|
void (*func)(void *);
|
void *param;
|
void *param;
|
|
|
/* Execute all jobs till now */
|
/* Execute all jobs till now */
|
do {
|
do {
|
func = SCHED_PEEK().func;
|
func = SCHED_PEEK().func;
|
param = SCHED_PEEK().param;
|
param = SCHED_PEEK().param;
|
SCHED_REMOVE();
|
SCHED_REMOVE();
|
func (param);
|
func (param);
|
} while (runtime.sim.cycles >= SCHED_PEEK().time);
|
} while (runtime.sim.cycles >= SCHED_PEEK().time);
|
}
|
}
|
|
|
/* Main function */
|
/* Main function */
|
int main(argc, argv)
|
int main(argc, argv)
|
int argc;
|
int argc;
|
char *argv[];
|
char *argv[];
|
{
|
{
|
srand(getpid());
|
srand(getpid());
|
init_defconfig();
|
init_defconfig();
|
reg_config_secs();
|
reg_config_secs();
|
if (parse_args(argc, argv)) {
|
if (parse_args(argc, argv)) {
|
PRINTF("Usage: %s [options] <filename>\n", argv[0]);
|
PRINTF("Usage: %s [options] <filename>\n", argv[0]);
|
PRINTF("Options:\n");
|
PRINTF("Options:\n");
|
PRINTF(" -v version and copyright note\n");
|
PRINTF(" -v version and copyright note\n");
|
PRINTF(" -i enable interactive command prompt\n");
|
PRINTF(" -i enable interactive command prompt\n");
|
PRINTF(" --nosrv do not launch JTAG proxy server\n"); /* (CZ) */
|
PRINTF(" --nosrv do not launch JTAG proxy server\n"); /* (CZ) */
|
PRINTF(" --srv <n> launch JTAG proxy server on port <n>; [random]\n"); /* (CZ) */
|
PRINTF(" --srv <n> launch JTAG proxy server on port <n>; [random]\n"); /* (CZ) */
|
#if !FAST_SIM
|
|
PRINTF(" -f or --file load script file [sim.cfg]\n");
|
PRINTF(" -f or --file load script file [sim.cfg]\n");
|
PRINTF(" --enable-profile enable profiling.\n");
|
PRINTF(" --enable-profile enable profiling.\n");
|
PRINTF(" --enable-mprofile enable memory profiling.\n");
|
PRINTF(" --enable-mprofile enable memory profiling.\n");
|
#endif
|
|
PRINTF(" --output-cfg prints C structure of current\n");
|
PRINTF(" --output-cfg prints C structure of current\n");
|
PRINTF(" configuration to standard output\n");
|
PRINTF(" configuration to standard output\n");
|
PRINTF("\nor : %s ", argv[0]);
|
PRINTF("\nor : %s ", argv[0]);
|
mp_help ();
|
mp_help ();
|
PRINTF("\nor : %s ", argv[0]);
|
PRINTF("\nor : %s ", argv[0]);
|
prof_help ();
|
prof_help ();
|
exit(-1);
|
exit(-1);
|
}
|
}
|
|
|
#if !FAST_SIM
|
|
/* Read configuration file. */
|
/* Read configuration file. */
|
if (!runtime.sim.script_file_specified)
|
if (!runtime.sim.script_file_specified)
|
read_script_file ("sim.cfg");
|
read_script_file ("sim.cfg");
|
|
|
/* Overide parameters with command line ones */
|
/* Overide parameters with command line ones */
|
if (runtime.simcmd.profile) config.sim.profile = 1;
|
if (runtime.simcmd.profile) config.sim.profile = 1;
|
if (runtime.simcmd.mprofile) config.sim.mprofile = 1;
|
if (runtime.simcmd.mprofile) config.sim.mprofile = 1;
|
|
|
if (!runtime.sim.script_file_specified && config.sim.verbose)
|
if (!runtime.sim.script_file_specified && config.sim.verbose)
|
fprintf (stderr, "WARNING: No config file read, assuming default configuration.\n");
|
fprintf (stderr, "WARNING: No config file read, assuming default configuration.\n");
|
#else
|
|
PRINTF ("\n\tNOTE: running fast sim with fixed configuration!\n\n");
|
|
#endif
|
|
if (runtime.sim.output_cfg) {
|
if (runtime.sim.output_cfg) {
|
output_cfg (stdout);
|
output_cfg (stdout);
|
exit (0);
|
exit (0);
|
}
|
}
|
print_config();
|
print_config();
|
sim_init ();
|
sim_init ();
|
signal(SIGINT, ctrl_c);
|
signal(SIGINT, ctrl_c);
|
|
|
runtime.sim.hush = 1;
|
runtime.sim.hush = 1;
|
runtime.sim.cont_run = -1;
|
runtime.sim.cont_run = -1;
|
|
|
while(1) {
|
while(1) {
|
if (runtime.sim.iprompt)
|
if (runtime.sim.iprompt)
|
handle_sim_command();
|
handle_sim_command();
|
|
|
{ /* Needed by execution */
|
{ /* Needed by execution */
|
extern int do_stats;
|
extern int do_stats;
|
do_stats = config.cpu.dependstats || config.cpu.superscalar || config.cpu.dependstats
|
do_stats = config.cpu.dependstats || config.cpu.superscalar || config.cpu.dependstats
|
|| config.sim.history || config.sim.exe_log;
|
|| config.sim.history || config.sim.exe_log;
|
}
|
}
|
|
|
/* MM: 'run -1' means endless execution. */
|
/* MM: 'run -1' means endless execution. */
|
while(runtime.sim.cont_run) {
|
while(runtime.sim.cont_run) {
|
IFF (config.debug.enabled) {
|
if (config.debug.enabled) {
|
du_clock(); // reset watchpoints
|
du_clock(); // reset watchpoints
|
if (runtime.cpu.stalled) {
|
if (runtime.cpu.stalled) {
|
if(config.debug.gdb_enabled) {
|
if(config.debug.gdb_enabled) {
|
BlockJTAG();
|
BlockJTAG();
|
HandleServerSocket(false);
|
HandleServerSocket(false);
|
} else {
|
} else {
|
fprintf (stderr, "WARNING: CPU stalled and gdb connection not enabled.");
|
fprintf (stderr, "WARNING: CPU stalled and gdb connection not enabled.");
|
runtime.sim.cont_run = 0;
|
runtime.sim.cont_run = 0;
|
}
|
}
|
continue;
|
continue;
|
}
|
}
|
}
|
}
|
|
|
/* Each cycle has counter of mem_cycles; this value is joined with cycles
|
/* Each cycle has counter of mem_cycles; this value is joined with cycles
|
at the end of the cycle; no sim originated memory accesses should be
|
at the end of the cycle; no sim originated memory accesses should be
|
performed inbetween. */
|
performed inbetween. */
|
runtime.sim.mem_cycles = 0;
|
runtime.sim.mem_cycles = 0;
|
if (!config.pm.enabled || !testsprbits(SPR_PMR, SPR_PMR_DME | SPR_PMR_SME)) {
|
if (!config.pm.enabled || !testsprbits(SPR_PMR, SPR_PMR_DME | SPR_PMR_SME)) {
|
if (runtime.sim.cont_run > 0) runtime.sim.cont_run--;
|
if (runtime.sim.cont_run > 0) runtime.sim.cont_run--;
|
pic_clock ();
|
pic_clock ();
|
if (cpu_clock ()) break;
|
if (cpu_clock ()) break;
|
if (config.dc.enabled) dc_clock();
|
if (config.dc.enabled) dc_clock();
|
if (config.ic.enabled) ic_clock();
|
if (config.ic.enabled) ic_clock();
|
}
|
}
|
|
|
if (config.vapi.enabled && runtime.vapi.enabled) vapi_check();
|
if (config.vapi.enabled && runtime.vapi.enabled) vapi_check();
|
if (config.debug.gdb_enabled) HandleServerSocket(false); /* block & check_stdin = false */
|
if (config.debug.gdb_enabled) HandleServerSocket(false); /* block & check_stdin = false */
|
IFF(config.debug.enabled)
|
if(config.debug.enabled)
|
if (testsprbits(SPR_DMR1, SPR_DMR1_ST)) set_stall_state (1);
|
if (testsprbits(SPR_DMR1, SPR_DMR1_ST)) set_stall_state (1);
|
|
|
runtime.sim.cycles += runtime.sim.mem_cycles;
|
runtime.sim.cycles += runtime.sim.mem_cycles;
|
if (runtime.sim.cycles >= SCHED_PEEK().time) do_scheduler ();
|
if (runtime.sim.cycles >= SCHED_PEEK().time) do_scheduler ();
|
if (!runtime.sim.hush) dumpreg();
|
if (!runtime.sim.hush) dumpreg();
|
}
|
}
|
runtime.sim.hush = 0;
|
runtime.sim.hush = 0;
|
fflush(stdout);
|
fflush(stdout);
|
runtime.sim.fout = stdout;
|
runtime.sim.fout = stdout;
|
|
|
if (!runtime.sim.iprompt) /* non-interactive quit */
|
if (!runtime.sim.iprompt) /* non-interactive quit */
|
sim_done();
|
sim_done();
|
}
|
}
|
sim_done();
|
sim_done();
|
}
|
}
|
|
|