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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_67/] [or1ksim/] [sim-config.c] - Diff between revs 1460 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 1460 Rev 1765
/* sim-config.c -- Simulator configuration
/* sim-config.c -- Simulator configuration
   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 configuration. Eventually this one will be a lot bigger. */
/* Simulator configuration. Eventually this one will be a lot bigger. */
 
 
#include <stdlib.h>
#include <stdlib.h>
#include <limits.h>
#include <limits.h>
#include <string.h>
#include <string.h>
#include <ctype.h>
#include <ctype.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 "sim-config.h"
#include "sim-config.h"
#include "abstract.h"
#include "abstract.h"
#include "opcode/or32.h"
#include "opcode/or32.h"
#include "spr_defs.h"
#include "spr_defs.h"
#include "execute.h"
#include "execute.h"
#include "sprs.h"
#include "sprs.h"
#include "pic.h"
#include "pic.h"
#include "stats.h"
#include "stats.h"
#include "icache_model.h"
#include "icache_model.h"
#include "dcache_model.h"
#include "dcache_model.h"
 
 
#include "profiler.h"
#include "profiler.h"
#include "mprofiler.h"
#include "mprofiler.h"
#include "cuc.h"
#include "cuc.h"
 
 
#include "debug.h"
#include "debug.h"
 
 
DEFAULT_DEBUG_CHANNEL(config);
DEFAULT_DEBUG_CHANNEL(config);
 
 
#define WARNING(s) fprintf (stderr, "WARNING: config.%s: %s\n", cur_section->name, (s))
#define WARNING(s) fprintf (stderr, "WARNING: config.%s: %s\n", cur_section->name, (s))
#define MERROR(s) {fprintf (stderr, "ERROR: %s\n", s); if (runtime.sim.init) exit (1);}
#define MERROR(s) {fprintf (stderr, "ERROR: %s\n", s); if (runtime.sim.init) exit (1);}
 
 
struct config config;
struct config config;
struct runtime runtime;
struct runtime runtime;
 
 
struct config_section *cur_section;
struct config_section *cur_section;
 
 
struct config_section *sections = NULL;
struct config_section *sections = NULL;
 
 
void init_defconfig()
void init_defconfig()
{
{
  int i;
  int i;
 
 
  memset(&config, 0, sizeof(config));
  memset(&config, 0, sizeof(config));
  /* Sim */
  /* Sim */
  config.sim.exe_log = 0;
  config.sim.exe_log = 0;
  config.sim.exe_log_type = EXE_LOG_HARDWARE;
  config.sim.exe_log_type = EXE_LOG_HARDWARE;
  config.sim.exe_log_start = 0;
  config.sim.exe_log_start = 0;
  config.sim.exe_log_end = 0;
  config.sim.exe_log_end = 0;
  config.sim.exe_log_marker = 0;
  config.sim.exe_log_marker = 0;
  config.sim.spr_log = 0;
  config.sim.spr_log = 0;
  strcpy (config.sim.exe_log_fn, "executed.log");
  strcpy (config.sim.exe_log_fn, "executed.log");
  strcpy (config.sim.spr_log_fn, "spr.log");
  strcpy (config.sim.spr_log_fn, "spr.log");
  config.sim.profile = 0;
  config.sim.profile = 0;
  config.sim.mprofile = 0;
  config.sim.mprofile = 0;
 
 
  config.sim.debug = 0;
  config.sim.debug = 0;
  config.sim.verbose = 1;
  config.sim.verbose = 1;
 
 
  strcpy (config.sim.prof_fn, "sim.profile");
  strcpy (config.sim.prof_fn, "sim.profile");
  strcpy (config.sim.mprof_fn, "sim.mprofile");
  strcpy (config.sim.mprof_fn, "sim.mprofile");
  strcpy (config.sim.fstdout, "stdout.txt");
  strcpy (config.sim.fstdout, "stdout.txt");
  strcpy (runtime.sim.script_fn, "(default)");
  strcpy (runtime.sim.script_fn, "(default)");
  config.sim.clkcycle_ps = 4000; /* 4000 for 4ns (250MHz) */
  config.sim.clkcycle_ps = 4000; /* 4000 for 4ns (250MHz) */
  if (config.sim.clkcycle_ps) config.sim.system_kfreq = (long)((1000000000.0 / (double)config.sim.clkcycle_ps));
  if (config.sim.clkcycle_ps) config.sim.system_kfreq = (long)((1000000000.0 / (double)config.sim.clkcycle_ps));
  else config.sim.system_kfreq = INT_MAX;
  else config.sim.system_kfreq = INT_MAX;
  if (config.sim.system_kfreq <= 0) config.sim.system_kfreq = 1;
  if (config.sim.system_kfreq <= 0) config.sim.system_kfreq = 1;
 
 
  /* Memory */
  /* Memory */
  config.memory.type = MT_UNKNOWN;
  config.memory.type = MT_UNKNOWN;
  config.memory.pattern = 0;
  config.memory.pattern = 0;
  config.memory.random_seed = -1;  /* Generate new seed */
  config.memory.random_seed = -1;  /* Generate new seed */
  for (i = 0; i < MAX_MEMORIES; i++)
  for (i = 0; i < MAX_MEMORIES; i++)
    config.memory.table[i].ce = -1;     /* memory is disabled by default */
    config.memory.table[i].ce = -1;     /* memory is disabled by default */
 
 
  /* IMMU & DMMU*/
  /* IMMU & DMMU*/
  config.immu.enabled = 0;
  config.immu.enabled = 0;
  config.immu.hitdelay = 1;
  config.immu.hitdelay = 1;
  config.immu.missdelay = 1;
  config.immu.missdelay = 1;
  config.dmmu.enabled = 0;
  config.dmmu.enabled = 0;
  config.dmmu.hitdelay = 1;
  config.dmmu.hitdelay = 1;
  config.dmmu.missdelay = 1;
  config.dmmu.missdelay = 1;
 
 
  /* IC & DC */
  /* IC & DC */
  config.ic.enabled = 0;
  config.ic.enabled = 0;
  config.ic.hitdelay = 1;
  config.ic.hitdelay = 1;
  config.ic.missdelay = 1;
  config.ic.missdelay = 1;
  config.ic.nways = 0;
  config.ic.nways = 0;
  config.ic.nsets = 0;
  config.ic.nsets = 0;
  config.ic.ustates = 0;
  config.ic.ustates = 0;
  config.dc.enabled = 0;
  config.dc.enabled = 0;
  config.dc.load_hitdelay = 2;
  config.dc.load_hitdelay = 2;
  config.dc.load_missdelay = 2;
  config.dc.load_missdelay = 2;
  config.dc.nways = 0;
  config.dc.nways = 0;
  config.dc.nsets = 0;
  config.dc.nsets = 0;
  config.dc.ustates = 0;
  config.dc.ustates = 0;
  config.dc.store_hitdelay = 0;
  config.dc.store_hitdelay = 0;
  config.dc.store_missdelay = 0;
  config.dc.store_missdelay = 0;
 
 
  /* CPU */
  /* CPU */
  config.cpu.superscalar = 0;
  config.cpu.superscalar = 0;
  config.sim.history = 0;
  config.sim.history = 0;
  config.cpu.hazards = 0;
  config.cpu.hazards = 0;
  config.cpu.dependstats = 0;
  config.cpu.dependstats = 0;
  config.cpu.sbuf_len = 0;
  config.cpu.sbuf_len = 0;
  config.cpu.upr = SPR_UPR_UP | SPR_UPR_DCP | SPR_UPR_ICP | SPR_UPR_DMP
  config.cpu.upr = SPR_UPR_UP | SPR_UPR_DCP | SPR_UPR_ICP | SPR_UPR_DMP
                 | SPR_UPR_IMP | SPR_UPR_OB32P | SPR_UPR_DUP | SPR_UPR_PICP
                 | SPR_UPR_IMP | SPR_UPR_OB32P | SPR_UPR_DUP | SPR_UPR_PICP
                 | SPR_UPR_PMP | SPR_UPR_TTP;
                 | SPR_UPR_PMP | SPR_UPR_TTP;
  config.cpu.sr = 0x00008001;
  config.cpu.sr = 0x00008001;
 
 
  /* Debug */
  /* Debug */
  config.debug.enabled = 0;
  config.debug.enabled = 0;
  config.debug.gdb_enabled = 0;
  config.debug.gdb_enabled = 0;
  config.debug.server_port = 0;
  config.debug.server_port = 0;
 
 
  /* VAPI */
  /* VAPI */
  config.vapi.enabled = 0;
  config.vapi.enabled = 0;
  strcpy (config.vapi.vapi_fn, "vapi.log");
  strcpy (config.vapi.vapi_fn, "vapi.log");
 
 
  /* PM */
  /* PM */
  config.pm.enabled = 0;
  config.pm.enabled = 0;
 
 
  /* CUC */
  /* CUC */
  strcpy (config.cuc.timings_fn, "virtex.tim");
  strcpy (config.cuc.timings_fn, "virtex.tim");
  config.cuc.memory_order = MO_STRONG;
  config.cuc.memory_order = MO_STRONG;
  config.cuc.calling_convention = 1;
  config.cuc.calling_convention = 1;
  config.cuc.enable_bursts = 1;
  config.cuc.enable_bursts = 1;
  config.cuc.no_multicycle = 1;
  config.cuc.no_multicycle = 1;
 
 
  /* Configure runtime */
  /* Configure runtime */
  memset(&runtime, 0, sizeof(runtime));
  memset(&runtime, 0, sizeof(runtime));
 
 
  /* Sim */
  /* Sim */
  runtime.sim.fexe_log = NULL;
  runtime.sim.fexe_log = NULL;
  runtime.sim.fspr_log = NULL;
  runtime.sim.fspr_log = NULL;
  runtime.sim.iprompt = 0;
  runtime.sim.iprompt = 0;
  runtime.sim.fprof = NULL;
  runtime.sim.fprof = NULL;
  runtime.sim.fmprof = NULL;
  runtime.sim.fmprof = NULL;
  runtime.sim.init = 1;
  runtime.sim.init = 1;
  runtime.sim.fout = stdout;
  runtime.sim.fout = stdout;
  runtime.sim.script_file_specified = 0;
  runtime.sim.script_file_specified = 0;
  runtime.simcmd.profile = 0;
  runtime.simcmd.profile = 0;
  runtime.simcmd.mprofile = 0;
  runtime.simcmd.mprofile = 0;
 
 
  /* VAPI */
  /* VAPI */
  runtime.vapi.vapi_file = NULL;
  runtime.vapi.vapi_file = NULL;
  runtime.vapi.enabled = 0;
  runtime.vapi.enabled = 0;
}
}
 
 
int parse_args(int argc, char *argv[])
int parse_args(int argc, char *argv[])
{
{
  argv++; argc--;
  argv++; argc--;
  while (argc) {
  while (argc) {
    if (strcmp(*argv, "profiler") == 0) {
    if (strcmp(*argv, "profiler") == 0) {
      exit (main_profiler (argc, argv));
      exit (main_profiler (argc, argv));
    } else
    } else
    if (strcmp(*argv, "mprofiler") == 0) {
    if (strcmp(*argv, "mprofiler") == 0) {
      exit (main_mprofiler (argc, argv));
      exit (main_mprofiler (argc, argv));
    } else
    } else
    if (*argv[0] != '-') {
    if (*argv[0] != '-') {
      runtime.sim.filename = argv[0];
      runtime.sim.filename = argv[0];
      argc--;
      argc--;
      argv++;
      argv++;
    } else
    } else
    if (strcmp(*argv, "-f") == 0 || strcmp(*argv, "--file") == 0) {
    if (strcmp(*argv, "-f") == 0 || strcmp(*argv, "--file") == 0) {
      argv++; argc--;
      argv++; argc--;
      if (argv[0]) {
      if (argv[0]) {
        read_script_file(argv[0]);
        read_script_file(argv[0]);
        argv++; argc--;
        argv++; argc--;
      } else {
      } else {
        fprintf(stderr, "Configure filename not specified!\n");
        fprintf(stderr, "Configure filename not specified!\n");
        return 1;
        return 1;
      }
      }
    } else
    } else
    if (strcmp(*argv, "--nosrv") == 0) {  /* (CZ) */
    if (strcmp(*argv, "--nosrv") == 0) {  /* (CZ) */
      config.debug.gdb_enabled = 0;
      config.debug.gdb_enabled = 0;
      argv++; argc--;
      argv++; argc--;
    } else
    } else
    if (strcmp(*argv, "--srv") == 0) {  /* (CZ) */
    if (strcmp(*argv, "--srv") == 0) {  /* (CZ) */
      char *s;
      char *s;
      if(!--argc)
      if(!--argc)
        return 1;
        return 1;
      config.debug.enabled = 1;
      config.debug.enabled = 1;
      config.debug.gdb_enabled = 1;
      config.debug.gdb_enabled = 1;
      config.debug.server_port = strtol(*(++argv),&s,10);
      config.debug.server_port = strtol(*(++argv),&s,10);
      if(*s)
      if(*s)
        return 1;
        return 1;
      argv++; argc--;
      argv++; argc--;
    } else
    } else
    if (strcmp(*argv, "-i") == 0) {
    if (strcmp(*argv, "-i") == 0) {
      runtime.sim.iprompt = 1;
      runtime.sim.iprompt = 1;
      argv++; argc--;
      argv++; argc--;
    } else
    } else
    if (strcmp(*argv, "-v") == 0) {
    if (strcmp(*argv, "-v") == 0) {
      version();
      version();
      exit(0);
      exit(0);
    } else
    } else
    if (strcmp(*argv, "--enable-profile") == 0) {
    if (strcmp(*argv, "--enable-profile") == 0) {
      runtime.simcmd.profile = 1;
      runtime.simcmd.profile = 1;
      argv++; argc--;
      argv++; argc--;
    } else
    } else
    if (strcmp(*argv, "--enable-mprofile") == 0) {
    if (strcmp(*argv, "--enable-mprofile") == 0) {
      runtime.simcmd.mprofile = 1;
      runtime.simcmd.mprofile = 1;
      argv++; argc--;
      argv++; argc--;
    } else
    } else
    if (strcmp(*argv, "-d") == 0) {
    if (strcmp(*argv, "-d") == 0) {
      parse_dbchs(*(++argv));
      parse_dbchs(*(++argv));
      argv++; argc -= 2;
      argv++; argc -= 2;
    } else {
    } else {
      fprintf(stderr, "Unknown option: %s\n", *argv);
      fprintf(stderr, "Unknown option: %s\n", *argv);
      return 1;
      return 1;
    }
    }
  }
  }
 
 
  if (!argc)
  if (!argc)
    return 0;
    return 0;
 
 
  return 0;
  return 0;
}
}
 
 
void print_config()
void print_config()
{
{
  if (config.sim.verbose) {
  if (config.sim.verbose) {
    char temp[20];
    char temp[20];
    PRINTF("Verbose on, ");
    PRINTF("Verbose on, ");
    if (config.sim.debug)
    if (config.sim.debug)
      PRINTF("simdebug on, ");
      PRINTF("simdebug on, ");
    else
    else
      PRINTF("simdebug off, ");
      PRINTF("simdebug off, ");
    if (runtime.sim.iprompt)
    if (runtime.sim.iprompt)
      PRINTF("interactive prompt on\n");
      PRINTF("interactive prompt on\n");
    else
    else
      PRINTF("interactive prompt off\n");
      PRINTF("interactive prompt off\n");
 
 
    PRINTF("Machine initialization...\n");
    PRINTF("Machine initialization...\n");
    generate_time_pretty (temp, config.sim.clkcycle_ps);
    generate_time_pretty (temp, config.sim.clkcycle_ps);
    PRINTF("Clock cycle: %s\n", temp);
    PRINTF("Clock cycle: %s\n", temp);
    if (testsprbits(SPR_UPR, SPR_UPR_DCP))
    if (testsprbits(SPR_UPR, SPR_UPR_DCP))
      PRINTF("Data cache present.\n");
      PRINTF("Data cache present.\n");
    else
    else
      PRINTF("No data cache.\n");
      PRINTF("No data cache.\n");
    if (testsprbits(SPR_UPR, SPR_UPR_ICP))
    if (testsprbits(SPR_UPR, SPR_UPR_ICP))
      PRINTF("Insn cache tag present.\n");
      PRINTF("Insn cache tag present.\n");
    else
    else
      PRINTF("No instruction cache.\n");
      PRINTF("No instruction cache.\n");
    if (config.bpb.enabled)
    if (config.bpb.enabled)
      PRINTF("BPB simulation on.\n");
      PRINTF("BPB simulation on.\n");
    else
    else
      PRINTF("BPB simulation off.\n");
      PRINTF("BPB simulation off.\n");
    if (config.bpb.btic)
    if (config.bpb.btic)
      PRINTF("BTIC simulation on.\n");
      PRINTF("BTIC simulation on.\n");
    else
    else
      PRINTF("BTIC simulation off.\n");
      PRINTF("BTIC simulation off.\n");
  }
  }
}
}
 
 
struct config_param {
struct config_param {
  char *name;
  char *name;
  enum param_t type;
  enum param_t type;
  void (*func)(union param_val, void *dat);
  void (*func)(union param_val, void *dat);
  struct config_param *next;
  struct config_param *next;
};
};
 
 
/* FIXME: These will be removed */
/* FIXME: These will be removed */
int current_device = -1;
int current_device = -1;
void change_device (union param_val val, void *dat) {
void change_device (union param_val val, void *dat) {
  current_device = val.int_val;
  current_device = val.int_val;
}
}
 
 
void end_device (union param_val val, void *dat) {
void end_device (union param_val val, void *dat) {
  current_device = -1;
  current_device = -1;
}
}
 
 
void base_include (union param_val val, void *dat) {
void base_include (union param_val val, void *dat) {
  read_script_file (val.str_val);
  read_script_file (val.str_val);
  cur_section = NULL;
  cur_section = NULL;
}
}
 
 
/*----------------------------------------------[ Simulator configuration ]---*/
/*----------------------------------------------[ Simulator configuration ]---*/
void sim_debug (union param_val val, void *dat) {
void sim_debug (union param_val val, void *dat) {
  config.sim.debug = val.int_val;
  config.sim.debug = val.int_val;
}
}
 
 
void sim_verbose (union param_val val, void *dat) {
void sim_verbose (union param_val val, void *dat) {
  config.sim.verbose = val.int_val;
  config.sim.verbose = val.int_val;
}
}
 
 
void sim_profile (union param_val val, void *dat) {
void sim_profile (union param_val val, void *dat) {
  config.sim.profile = val.int_val;
  config.sim.profile = val.int_val;
}
}
 
 
void sim_prof_fn (union param_val val, void *dat) {
void sim_prof_fn (union param_val val, void *dat) {
  strcpy(config.sim.prof_fn, val.str_val);
  strcpy(config.sim.prof_fn, val.str_val);
}
}
 
 
void sim_mprofile (union param_val val, void *dat) {
void sim_mprofile (union param_val val, void *dat) {
  config.sim.mprofile = val.int_val;
  config.sim.mprofile = val.int_val;
}
}
 
 
void sim_mprof_fn (union param_val val, void *dat) {
void sim_mprof_fn (union param_val val, void *dat) {
  strcpy(config.sim.mprof_fn, val.str_val);
  strcpy(config.sim.mprof_fn, val.str_val);
}
}
 
 
void sim_history (union param_val val, void *dat) {
void sim_history (union param_val val, void *dat) {
  config.sim.history = val.int_val;
  config.sim.history = val.int_val;
}
}
 
 
void sim_exe_log (union param_val val, void *dat) {
void sim_exe_log (union param_val val, void *dat) {
  config.sim.exe_log = val.int_val;
  config.sim.exe_log = val.int_val;
}
}
 
 
void sim_exe_log_type (union param_val val, void *dat) {
void sim_exe_log_type (union param_val val, void *dat) {
  if (strcmp (val.str_val, "default") == 0)
  if (strcmp (val.str_val, "default") == 0)
    config.sim.exe_log_type = EXE_LOG_HARDWARE;
    config.sim.exe_log_type = EXE_LOG_HARDWARE;
  else if (strcmp (val.str_val, "hardware") == 0)
  else if (strcmp (val.str_val, "hardware") == 0)
    config.sim.exe_log_type = EXE_LOG_HARDWARE;
    config.sim.exe_log_type = EXE_LOG_HARDWARE;
  else if (strcmp (val.str_val, "simple") == 0)
  else if (strcmp (val.str_val, "simple") == 0)
    config.sim.exe_log_type = EXE_LOG_SIMPLE;
    config.sim.exe_log_type = EXE_LOG_SIMPLE;
  else if (strcmp (val.str_val, "software") == 0) {
  else if (strcmp (val.str_val, "software") == 0) {
    config.sim.exe_log_type = EXE_LOG_SOFTWARE;
    config.sim.exe_log_type = EXE_LOG_SOFTWARE;
  } else {
  } else {
    char tmp[200];
    char tmp[200];
    sprintf (tmp, "invalid execute log type '%s'.\n", val.str_val);
    sprintf (tmp, "invalid execute log type '%s'.\n", val.str_val);
    CONFIG_ERROR(tmp);
    CONFIG_ERROR(tmp);
  }
  }
}
}
 
 
void sim_exe_log_start (union param_val val, void *dat) {
void sim_exe_log_start (union param_val val, void *dat) {
  config.sim.exe_log_start = val.int_val;
  config.sim.exe_log_start = val.int_val;
}
}
 
 
void sim_exe_log_end (union param_val val, void *dat) {
void sim_exe_log_end (union param_val val, void *dat) {
  config.sim.exe_log_end = val.int_val;
  config.sim.exe_log_end = val.int_val;
}
}
 
 
void sim_exe_log_marker (union param_val val, void *dat) {
void sim_exe_log_marker (union param_val val, void *dat) {
  config.sim.exe_log_marker = val.int_val;
  config.sim.exe_log_marker = val.int_val;
}
}
 
 
void sim_exe_log_fn (union param_val val, void *dat) {
void sim_exe_log_fn (union param_val val, void *dat) {
  strcpy(config.sim.exe_log_fn, val.str_val);
  strcpy(config.sim.exe_log_fn, val.str_val);
}
}
 
 
void sim_clkcycle (union param_val val, void *dat) {
void sim_clkcycle (union param_val val, void *dat) {
  int len = strlen (val.str_val);
  int len = strlen (val.str_val);
  int pos = len - 1;
  int pos = len - 1;
  long time;
  long time;
  if (len < 2) goto err;
  if (len < 2) goto err;
  if (val.str_val[pos--] != 's') goto err;
  if (val.str_val[pos--] != 's') goto err;
  switch (val.str_val[pos--]) {
  switch (val.str_val[pos--]) {
    case 'p': time = 1; break;
    case 'p': time = 1; break;
    case 'n': time = 1000; break;
    case 'n': time = 1000; break;
    case 'u': time = 1000000; break;
    case 'u': time = 1000000; break;
    case 'm': time = 1000000000; break;
    case 'm': time = 1000000000; break;
  default:
  default:
    goto err;
    goto err;
  }
  }
  val.str_val[pos + 1] = 0;
  val.str_val[pos + 1] = 0;
  config.sim.clkcycle_ps = time * atol (val.str_val);
  config.sim.clkcycle_ps = time * atol (val.str_val);
  return;
  return;
err:
err:
  CONFIG_ERROR("invalid time format.");
  CONFIG_ERROR("invalid time format.");
}
}
 
 
void sim_stdout (union param_val val, void *dat) {
void sim_stdout (union param_val val, void *dat) {
  strcpy(config.sim.fstdout, val.str_val);
  strcpy(config.sim.fstdout, val.str_val);
}
}
 
 
void sim_spr_log (union param_val val, void *dat) {
void sim_spr_log (union param_val val, void *dat) {
  config.sim.spr_log = val.int_val;
  config.sim.spr_log = val.int_val;
}
}
 
 
void sim_spr_log_fn (union param_val val, void *dat) {
void sim_spr_log_fn (union param_val val, void *dat) {
  strcpy(config.sim.spr_log_fn, val.str_val);
  strcpy(config.sim.spr_log_fn, val.str_val);
}
}
 
 
void reg_sim_sec (void) {
void reg_sim_sec (void) {
  struct config_section *sec = reg_config_sec("sim", NULL, NULL);
  struct config_section *sec = reg_config_sec("sim", NULL, NULL);
 
 
  reg_config_param(sec, "debug", paramt_int, sim_debug);
  reg_config_param(sec, "debug", paramt_int, sim_debug);
  reg_config_param(sec, "verbose", paramt_int, sim_verbose);
  reg_config_param(sec, "verbose", paramt_int, sim_verbose);
  reg_config_param(sec, "profile", paramt_int, sim_profile);
  reg_config_param(sec, "profile", paramt_int, sim_profile);
  reg_config_param(sec, "prof_fn", paramt_str, sim_prof_fn);
  reg_config_param(sec, "prof_fn", paramt_str, sim_prof_fn);
  reg_config_param(sec, "mprofile", paramt_int, sim_mprofile);
  reg_config_param(sec, "mprofile", paramt_int, sim_mprofile);
  reg_config_param(sec, "mprof_fn", paramt_str, sim_mprof_fn);
  reg_config_param(sec, "mprof_fn", paramt_str, sim_mprof_fn);
  reg_config_param(sec, "history", paramt_int, sim_history);
  reg_config_param(sec, "history", paramt_int, sim_history);
  reg_config_param(sec, "exe_log", paramt_int, sim_exe_log);
  reg_config_param(sec, "exe_log", paramt_int, sim_exe_log);
  reg_config_param(sec, "exe_log_type", paramt_word, sim_exe_log_type);
  reg_config_param(sec, "exe_log_type", paramt_word, sim_exe_log_type);
  reg_config_param(sec, "exe_log_start", paramt_int, sim_exe_log_start);
  reg_config_param(sec, "exe_log_start", paramt_int, sim_exe_log_start);
  reg_config_param(sec, "exe_log_end", paramt_int, sim_exe_log_end);
  reg_config_param(sec, "exe_log_end", paramt_int, sim_exe_log_end);
  reg_config_param(sec, "exe_log_marker", paramt_int, sim_exe_log_marker);
  reg_config_param(sec, "exe_log_marker", paramt_int, sim_exe_log_marker);
  reg_config_param(sec, "exe_log_fn", paramt_str, sim_exe_log_fn);
  reg_config_param(sec, "exe_log_fn", paramt_str, sim_exe_log_fn);
  reg_config_param(sec, "spr_log", paramt_int, sim_spr_log);
  reg_config_param(sec, "spr_log", paramt_int, sim_spr_log);
  reg_config_param(sec, "spr_log_fn", paramt_str, sim_spr_log_fn);
  reg_config_param(sec, "spr_log_fn", paramt_str, sim_spr_log_fn);
  reg_config_param(sec, "clkcycle", paramt_word, sim_clkcycle);
  reg_config_param(sec, "clkcycle", paramt_word, sim_clkcycle);
  reg_config_param(sec, "stdout", paramt_str, sim_stdout);
  reg_config_param(sec, "stdout", paramt_str, sim_stdout);
}
}
 
 
/*-------------------------------------------------[ Memory configuration ]---*/
/*-------------------------------------------------[ Memory configuration ]---*/
void memory_random_seed(union param_val val, void *dat) {
void memory_random_seed(union param_val val, void *dat) {
  config.memory.random_seed = val.int_val;
  config.memory.random_seed = val.int_val;
}
}
 
 
void memory_pattern(union param_val val, void *dat) {
void memory_pattern(union param_val val, void *dat) {
  config.memory.pattern = val.int_val;
  config.memory.pattern = val.int_val;
}
}
 
 
void memory_nmemories (union param_val val, void *dat) {
void memory_nmemories (union param_val val, void *dat) {
  if (val.int_val >= 0 && val.int_val < MAX_MEMORIES)
  if (val.int_val >= 0 && val.int_val < MAX_MEMORIES)
    config.memory.nmemories = val.int_val;
    config.memory.nmemories = val.int_val;
  else
  else
    CONFIG_ERROR("invalid number of devices.");
    CONFIG_ERROR("invalid number of devices.");
}
}
 
 
void memory_type (union param_val val, void *dat) {
void memory_type (union param_val val, void *dat) {
  if (strcmp (val.str_val, "unknown") == 0)
  if (strcmp (val.str_val, "unknown") == 0)
    config.memory.type = MT_UNKNOWN;
    config.memory.type = MT_UNKNOWN;
  else if (strcmp (val.str_val, "random") == 0)
  else if (strcmp (val.str_val, "random") == 0)
    config.memory.type = MT_RANDOM;
    config.memory.type = MT_RANDOM;
  else if (strcmp (val.str_val, "pattern") == 0)
  else if (strcmp (val.str_val, "pattern") == 0)
    config.memory.type = MT_PATTERN;
    config.memory.type = MT_PATTERN;
  else if (strcmp (val.str_val, "zero") == 0) {
  else if (strcmp (val.str_val, "zero") == 0) {
    config.memory.type = MT_PATTERN;
    config.memory.type = MT_PATTERN;
    config.memory.pattern = 0;
    config.memory.pattern = 0;
  } else {
  } else {
    char tmp[200];
    char tmp[200];
    sprintf (tmp, "invalid memory type '%s'.\n", val.str_val);
    sprintf (tmp, "invalid memory type '%s'.\n", val.str_val);
    CONFIG_ERROR(tmp);
    CONFIG_ERROR(tmp);
  }
  }
}
}
 
 
void memory_ce (union param_val val, void *dat) {
void memory_ce (union param_val val, void *dat) {
  if (current_device >= 0 && current_device < config.memory.nmemories)
  if (current_device >= 0 && current_device < config.memory.nmemories)
    config.memory.table[current_device].ce = val.int_val;
    config.memory.table[current_device].ce = val.int_val;
  else
  else
    CONFIG_ERROR("invalid device number.");
    CONFIG_ERROR("invalid device number.");
}
}
 
 
void memory_baseaddr (union param_val val, void *dat) {
void memory_baseaddr (union param_val val, void *dat) {
  if (current_device >= 0 && current_device < config.memory.nmemories)
  if (current_device >= 0 && current_device < config.memory.nmemories)
    config.memory.table[current_device].baseaddr = val.addr_val;
    config.memory.table[current_device].baseaddr = val.addr_val;
  else
  else
    CONFIG_ERROR("invalid device number.");
    CONFIG_ERROR("invalid device number.");
}
}
 
 
void memory_size (union param_val val, void *dat) {
void memory_size (union param_val val, void *dat) {
  if (current_device >= 0 && current_device < config.memory.nmemories)
  if (current_device >= 0 && current_device < config.memory.nmemories)
    config.memory.table[current_device].size = val.int_val;
    config.memory.table[current_device].size = val.int_val;
  else
  else
    CONFIG_ERROR("invalid device number.");
    CONFIG_ERROR("invalid device number.");
}
}
 
 
void memory_name (union param_val val, void *dat) {
void memory_name (union param_val val, void *dat) {
  if (current_device >= 0 && current_device < config.memory.nmemories)
  if (current_device >= 0 && current_device < config.memory.nmemories)
    strcpy (config.memory.table[current_device].name, val.str_val);
    strcpy (config.memory.table[current_device].name, val.str_val);
  else
  else
    CONFIG_ERROR("invalid device number.");
    CONFIG_ERROR("invalid device number.");
}
}
 
 
void memory_log (union param_val val, void *dat) {
void memory_log (union param_val val, void *dat) {
  if (current_device >= 0 && current_device < config.memory.nmemories)
  if (current_device >= 0 && current_device < config.memory.nmemories)
    strcpy (config.memory.table[current_device].log, val.str_val);
    strcpy (config.memory.table[current_device].log, val.str_val);
  else
  else
    CONFIG_ERROR("invalid device number.");
    CONFIG_ERROR("invalid device number.");
}
}
 
 
void memory_delayr (union param_val val, void *dat) {
void memory_delayr (union param_val val, void *dat) {
  if (current_device >= 0 && current_device < config.memory.nmemories)
  if (current_device >= 0 && current_device < config.memory.nmemories)
    config.memory.table[current_device].delayr = val.int_val;
    config.memory.table[current_device].delayr = val.int_val;
  else
  else
    CONFIG_ERROR("invalid device number.");
    CONFIG_ERROR("invalid device number.");
}
}
 
 
void memory_delayw (union param_val val, void *dat) {
void memory_delayw (union param_val val, void *dat) {
  if (current_device >= 0 && current_device < config.memory.nmemories)
  if (current_device >= 0 && current_device < config.memory.nmemories)
    config.memory.table[current_device].delayw = val.int_val;
    config.memory.table[current_device].delayw = val.int_val;
  else
  else
    CONFIG_ERROR("invalid device number.");
    CONFIG_ERROR("invalid device number.");
}
}
 
 
void reg_memory_sec(void) {
void reg_memory_sec(void) {
  struct config_section *sec = reg_config_sec("memory", NULL, NULL);
  struct config_section *sec = reg_config_sec("memory", NULL, NULL);
 
 
  reg_config_param(sec, "random_seed", paramt_int, memory_random_seed);
  reg_config_param(sec, "random_seed", paramt_int, memory_random_seed);
  reg_config_param(sec, "pattern", paramt_int, memory_pattern);
  reg_config_param(sec, "pattern", paramt_int, memory_pattern);
  reg_config_param(sec, "type", paramt_word, memory_type);
  reg_config_param(sec, "type", paramt_word, memory_type);
  reg_config_param(sec, "nmemories", paramt_int, memory_nmemories);
  reg_config_param(sec, "nmemories", paramt_int, memory_nmemories);
  reg_config_param(sec, "device", paramt_int, change_device);
  reg_config_param(sec, "device", paramt_int, change_device);
  reg_config_param(sec, "enddevice", paramt_none, end_device);
  reg_config_param(sec, "enddevice", paramt_none, end_device);
  reg_config_param(sec, "ce", paramt_int, memory_ce);
  reg_config_param(sec, "ce", paramt_int, memory_ce);
  reg_config_param(sec, "baseaddr", paramt_addr, memory_baseaddr);
  reg_config_param(sec, "baseaddr", paramt_addr, memory_baseaddr);
  reg_config_param(sec, "size", paramt_int, memory_size);
  reg_config_param(sec, "size", paramt_int, memory_size);
  reg_config_param(sec, "name", paramt_str, memory_name);
  reg_config_param(sec, "name", paramt_str, memory_name);
  reg_config_param(sec, "log", paramt_str, memory_log);
  reg_config_param(sec, "log", paramt_str, memory_log);
  reg_config_param(sec, "delayr", paramt_int, memory_delayr);
  reg_config_param(sec, "delayr", paramt_int, memory_delayr);
  reg_config_param(sec, "delayw", paramt_int, memory_delayw);
  reg_config_param(sec, "delayw", paramt_int, memory_delayw);
}
}
 
 
/*----------------------------------------------------[ CPU configuration ]---*/
/*----------------------------------------------------[ CPU configuration ]---*/
void cpu_ver (union param_val val, void *dat) {
void cpu_ver (union param_val val, void *dat) {
  config.cpu.ver = val.int_val;
  config.cpu.ver = val.int_val;
}
}
 
 
void cpu_rev (union param_val val, void *dat) {
void cpu_rev (union param_val val, void *dat) {
  config.cpu.rev = val.int_val;
  config.cpu.rev = val.int_val;
}
}
 
 
void cpu_upr (union param_val val, void *dat) {
void cpu_upr (union param_val val, void *dat) {
  config.cpu.upr = val.int_val;
  config.cpu.upr = val.int_val;
}
}
 
 
void cpu_sr (union param_val val, void *dat) {
void cpu_sr (union param_val val, void *dat) {
  config.cpu.sr = val.int_val;
  config.cpu.sr = val.int_val;
}
}
 
 
void cpu_hazards (union param_val val, void *dat) {
void cpu_hazards (union param_val val, void *dat) {
  config.cpu.hazards = val.int_val;
  config.cpu.hazards = val.int_val;
}
}
 
 
void cpu_superscalar (union param_val val, void *dat) {
void cpu_superscalar (union param_val val, void *dat) {
  config.cpu.superscalar = val.int_val;
  config.cpu.superscalar = val.int_val;
}
}
 
 
void cpu_dependstats (union param_val val, void *dat) {
void cpu_dependstats (union param_val val, void *dat) {
  config.cpu.dependstats = val.int_val;
  config.cpu.dependstats = val.int_val;
}
}
 
 
void cpu_sbuf_len (union param_val val, void *dat) {
void cpu_sbuf_len (union param_val val, void *dat) {
  if (val.int_val >= MAX_SBUF_LEN) {
  if (val.int_val >= MAX_SBUF_LEN) {
    config.cpu.sbuf_len = MAX_SBUF_LEN - 1;
    config.cpu.sbuf_len = MAX_SBUF_LEN - 1;
    WARNING("sbuf_len too large; truncated.");
    WARNING("sbuf_len too large; truncated.");
  } else if (val.int_val < 0) {
  } else if (val.int_val < 0) {
    config.cpu.sbuf_len = 0;
    config.cpu.sbuf_len = 0;
    WARNING("sbuf_len negative; disabled.");
    WARNING("sbuf_len negative; disabled.");
  } else
  } else
    config.cpu.sbuf_len = val.int_val;
    config.cpu.sbuf_len = val.int_val;
}
}
 
 
void reg_cpu_sec(void)
void reg_cpu_sec(void)
{
{
  struct config_section *sec = reg_config_sec("cpu", NULL, NULL);
  struct config_section *sec = reg_config_sec("cpu", NULL, NULL);
 
 
  reg_config_param(sec, "ver", paramt_int, cpu_ver);
  reg_config_param(sec, "ver", paramt_int, cpu_ver);
  reg_config_param(sec, "rev", paramt_int, cpu_rev);
  reg_config_param(sec, "rev", paramt_int, cpu_rev);
  reg_config_param(sec, "upr", paramt_int, cpu_upr);
  reg_config_param(sec, "upr", paramt_int, cpu_upr);
  reg_config_param(sec, "sr", paramt_int, cpu_sr);
  reg_config_param(sec, "sr", paramt_int, cpu_sr);
  reg_config_param(sec, "hazards", paramt_int, cpu_hazards);
  reg_config_param(sec, "hazards", paramt_int, cpu_hazards);
  reg_config_param(sec, "superscalar", paramt_int, cpu_superscalar);
  reg_config_param(sec, "superscalar", paramt_int, cpu_superscalar);
  reg_config_param(sec, "dependstats", paramt_int, cpu_dependstats);
  reg_config_param(sec, "dependstats", paramt_int, cpu_dependstats);
  reg_config_param(sec, "sbuf_len", paramt_int, cpu_sbuf_len);
  reg_config_param(sec, "sbuf_len", paramt_int, cpu_sbuf_len);
}
}
 
 
int is_power2 (int x) {
int is_power2 (int x) {
  while (!(x & 1))
  while (!(x & 1))
    x >>= 1;
    x >>= 1;
  return x == 1;
  return x == 1;
}
}
 
 
int log2 (int x) {
int log2 (int x) {
  int log=-1;
  int log=-1;
  while (x)
  while (x)
  {
  {
    x >>= 1;
    x >>= 1;
    log++;
    log++;
  }
  }
  return log;
  return log;
}
}
 
 
void reg_config_secs(void)
void reg_config_secs(void)
{
{
  reg_config_param(reg_config_sec("base", NULL, NULL), "include", paramt_str,
  reg_config_param(reg_config_sec("base", NULL, NULL), "include", paramt_str,
                   base_include);
                   base_include);
 
 
  reg_sim_sec();
  reg_sim_sec();
  reg_cpu_sec();
  reg_cpu_sec();
  reg_memory_sec();
  reg_memory_sec();
  reg_mc_sec();
  reg_mc_sec();
  reg_uart_sec();
  reg_uart_sec();
  reg_dma_sec();
  reg_dma_sec();
  reg_debug_sec();
  reg_debug_sec();
  reg_vapi_sec();
  reg_vapi_sec();
  reg_ethernet_sec();
  reg_ethernet_sec();
  reg_immu_sec();
  reg_immu_sec();
  reg_dmmu_sec();
  reg_dmmu_sec();
  reg_ic_sec();
  reg_ic_sec();
  reg_dc_sec();
  reg_dc_sec();
  reg_gpio_sec();
  reg_gpio_sec();
  reg_bpb_sec();
  reg_bpb_sec();
  reg_pm_sec();
  reg_pm_sec();
  reg_vga_sec();
  reg_vga_sec();
  reg_fb_sec();
  reg_fb_sec();
  reg_kbd_sec();
  reg_kbd_sec();
  reg_ata_sec();
  reg_ata_sec();
  reg_cuc_sec();
  reg_cuc_sec();
  reg_test_sec();
  reg_test_sec();
}
}
 
 
/* Returns a user friendly string of type */
/* Returns a user friendly string of type */
static char *get_paramt_str(enum param_t type)
static char *get_paramt_str(enum param_t type)
{
{
  switch(type) {
  switch(type) {
  case paramt_int:
  case paramt_int:
    return "integer";
    return "integer";
  case paramt_addr:
  case paramt_addr:
    return "address";
    return "address";
  case paramt_str:
  case paramt_str:
    return "string";
    return "string";
  case paramt_word:
  case paramt_word:
    return "word";
    return "word";
  case paramt_none:
  case paramt_none:
    return "none";
    return "none";
  }
  }
  return "";
  return "";
}
}
 
 
void reg_config_param(struct config_section *sec, const char *param,
void reg_config_param(struct config_section *sec, const char *param,
                      enum param_t type,
                      enum param_t type,
                      void (*param_cb)(union param_val, void *))
                      void (*param_cb)(union param_val, void *))
{
{
  struct config_param *new = malloc(sizeof(struct config_param));
  struct config_param *new = malloc(sizeof(struct config_param));
 
 
  TRACE("Registering config param `%s' to section `%s', type %s\n", param,
  TRACE("Registering config param `%s' to section `%s', type %s\n", param,
        sec->name, get_paramt_str(type));
        sec->name, get_paramt_str(type));
 
 
  if(!new) {
  if(!new) {
    fprintf(stderr, "Out-of-memory\n");
    fprintf(stderr, "Out-of-memory\n");
    exit(1);
    exit(1);
  }
  }
 
 
  if(!(new->name = strdup(param))) {
  if(!(new->name = strdup(param))) {
    fprintf(stderr, "Out-of-memory\n");
    fprintf(stderr, "Out-of-memory\n");
    exit(1);
    exit(1);
  }
  }
 
 
  new->func = param_cb;
  new->func = param_cb;
  new->type = type;
  new->type = type;
 
 
  new->next = sec->params;
  new->next = sec->params;
  sec->params = new;
  sec->params = new;
}
}
 
 
struct config_section *reg_config_sec(const char *section,
struct config_section *reg_config_sec(const char *section,
                                      void *(*sec_start)(void),
                                      void *(*sec_start)(void),
                                      void (*sec_end)(void *))
                                      void (*sec_end)(void *))
{
{
  struct config_section *new = malloc(sizeof(struct config_section));
  struct config_section *new = malloc(sizeof(struct config_section));
 
 
  TRACE("Registering config section `%s'\n", section);
  TRACE("Registering config section `%s'\n", section);
 
 
  if(!new) {
  if(!new) {
    fprintf(stderr, "Out-of-memory\n");
    fprintf(stderr, "Out-of-memory\n");
    exit(1);
    exit(1);
  }
  }
 
 
  if(!(new->name = strdup(section))) {
  if(!(new->name = strdup(section))) {
    fprintf(stderr, "Out-of-memory\n");
    fprintf(stderr, "Out-of-memory\n");
    exit(1);
    exit(1);
  }
  }
 
 
  new->next = sections;
  new->next = sections;
  new->sec_start = sec_start;
  new->sec_start = sec_start;
  new->sec_end = sec_end;
  new->sec_end = sec_end;
  new->params = NULL;
  new->params = NULL;
 
 
  sections = new;
  sections = new;
 
 
  return new;
  return new;
}
}
 
 
static void switch_param(char *param, struct config_param *cur_param)
static void switch_param(char *param, struct config_param *cur_param)
{
{
  char *end_p;
  char *end_p;
  union param_val val;
  union param_val val;
 
 
    /* Skip over an = sign if it exists */
    /* Skip over an = sign if it exists */
  if(*param == '=') {
  if(*param == '=') {
    param++;
    param++;
    while(*param && isspace(*param)) param++;
    while(*param && isspace(*param)) param++;
  }
  }
 
 
  switch (cur_param->type) {
  switch (cur_param->type) {
  case paramt_int:
  case paramt_int:
    val.int_val = strtol(param, NULL, 0);
    val.int_val = strtol(param, NULL, 0);
  case paramt_addr:
  case paramt_addr:
    val.addr_val = strtoul(param, NULL, 0);
    val.addr_val = strtoul(param, NULL, 0);
    break;
    break;
  case paramt_str:
  case paramt_str:
    if(*param != '"') {
    if(*param != '"') {
      CONFIG_ERROR("String value expected\n");
      CONFIG_ERROR("String value expected\n");
      return;
      return;
    }
    }
 
 
    param++;
    param++;
    end_p = param;
    end_p = param;
    while(*end_p && (*end_p != '"')) end_p++;
    while(*end_p && (*end_p != '"')) end_p++;
    *end_p = '\0';
    *end_p = '\0';
    val.str_val = param;
    val.str_val = param;
    break;
    break;
  case paramt_word:
  case paramt_word:
    end_p = param;
    end_p = param;
    while(*end_p && !isspace(*end_p)) end_p++;
    while(*end_p && !isspace(*end_p)) end_p++;
    *end_p = '\0';
    *end_p = '\0';
    val.str_val = param;
    val.str_val = param;
    break;
    break;
  case paramt_none:
  case paramt_none:
    break;
    break;
  }
  }
 
 
  cur_param->func(val, cur_section->dat);
  cur_param->func(val, cur_section->dat);
}
}
 
 
/* Read environment from a script file. Does not fail - assumes default configuration instead.
/* Read environment from a script file. Does not fail - assumes default configuration instead.
   The syntax of script file is:
   The syntax of script file is:
   param = value
   param = value
   section x
   section x
     data
     data
     param = value
     param = value
   end
   end
 
 
   Example:
   Example:
   section mc
   section mc
     memory_table_file = sim.mem
     memory_table_file = sim.mem
     enable = 1
     enable = 1
     POC = 0x47892344
     POC = 0x47892344
   end
   end
 
 
 */
 */
 
 
void read_script_file (char *filename)
void read_script_file (char *filename)
{
{
  FILE *f;
  FILE *f;
  char *home = getenv("HOME");
  char *home = getenv("HOME");
  char ctmp[STR_SIZE];
  char ctmp[STR_SIZE];
  int local = 1;
  int local = 1;
  cur_section = NULL;
  cur_section = NULL;
 
 
  sprintf(ctmp, "%s/.or1k/%s", home, filename);
  sprintf(ctmp, "%s/.or1k/%s", home, filename);
  if ((f = fopen (filename, "rt")) != NULL
  if ((f = fopen (filename, "rt")) != NULL
      || home != NULL && !(local = 0) && (f = fopen (ctmp, "rt")) != NULL) {
      || home != NULL && !(local = 0) && (f = fopen (ctmp, "rt")) != NULL) {
    if (config.sim.verbose)
    if (config.sim.verbose)
      PRINTF ("Reading script file from '%s'...\n", local ? filename : ctmp);
      PRINTF ("Reading script file from '%s'...\n", local ? filename : ctmp);
    strcpy (runtime.sim.script_fn, local ? filename : ctmp);
    strcpy (runtime.sim.script_fn, local ? filename : ctmp);
 
 
    while (!feof(f)) {
    while (!feof(f)) {
      char param[STR_SIZE];
      char param[STR_SIZE];
      if (fscanf(f, "%s ", param) != 1) break;
      if (fscanf(f, "%s ", param) != 1) break;
      /* Is this a section? */
      /* Is this a section? */
      if (strcmp (param, "section") == 0) {
      if (strcmp (param, "section") == 0) {
        struct config_section *cur;
        struct config_section *cur;
        cur_section = NULL;
        cur_section = NULL;
        if (fscanf (f, "%s\n", param) != 1) {
        if (fscanf (f, "%s\n", param) != 1) {
          fprintf (stderr, "%s: ERROR: Section name required.\n", local ? filename : ctmp);
          fprintf (stderr, "%s: ERROR: Section name required.\n", local ? filename : ctmp);
          exit (1);
          exit (1);
        }
        }
        TRACE("Came across section `%s'\n", param);
        TRACE("Came across section `%s'\n", param);
        for (cur = sections; cur; cur = cur->next)
        for (cur = sections; cur; cur = cur->next)
          if (strcmp (cur->name, param) == 0) {
          if (strcmp (cur->name, param) == 0) {
            cur_section = cur;
            cur_section = cur;
            break;
            break;
          }
          }
        if (!cur) {
        if (!cur) {
          fprintf (stderr, "WARNING: config: Unknown section: %s; ignoring.", param);
          fprintf (stderr, "WARNING: config: Unknown section: %s; ignoring.", param);
          /* just skip section */
          /* just skip section */
          while (fscanf (f, "%s\n", param) != 1 && strcmp (param, "end"));
          while (fscanf (f, "%s\n", param) != 1 && strcmp (param, "end"));
        } else {
        } else {
          cur->dat = NULL;
          cur->dat = NULL;
          if (cur->sec_start)
          if (cur->sec_start)
            cur->dat = cur->sec_start();
            cur->dat = cur->sec_start();
        }
        }
      } else if (strcmp (param, "end") == 0) {
      } else if (strcmp (param, "end") == 0) {
        if(cur_section->sec_end)
        if(cur_section->sec_end)
          cur_section->sec_end(cur_section->dat);
          cur_section->sec_end(cur_section->dat);
        cur_section = NULL;
        cur_section = NULL;
      } else if (strncmp (param, "/*", 2) == 0) {
      } else if (strncmp (param, "/*", 2) == 0) {
        char c0 = 0, c1 = 0;
        char c0 = 0, c1 = 0;
        while (c0 != '*' || c1 != '/') {
        while (c0 != '*' || c1 != '/') {
          c0 = c1;
          c0 = c1;
          c1 = fgetc(f);
          c1 = fgetc(f);
          if (feof(f)) {
          if (feof(f)) {
            fprintf (stderr, "%s: ERROR: Comment reached EOF.\n", local ? filename : ctmp);
            fprintf (stderr, "%s: ERROR: Comment reached EOF.\n", local ? filename : ctmp);
            exit (1);
            exit (1);
          }
          }
        }
        }
      } else {
      } else {
        struct config_param *cur_param;
        struct config_param *cur_param;
        char *cur_p;
        char *cur_p;
        TRACE("Came across parameter `%s' in section `%s'\n", param,
        TRACE("Came across parameter `%s' in section `%s'\n", param,
              cur_section->name);
              cur_section->name);
        for (cur_param = cur_section->params; cur_param; cur_param = cur_param->next)
        for (cur_param = cur_section->params; cur_param; cur_param = cur_param->next)
          if (strcmp (cur_param->name, param) == 0) {
          if (strcmp (cur_param->name, param) == 0) {
            break;
            break;
          }
          }
        if (!cur_param) {
        if (!cur_param) {
          char tmp[200];
          char tmp[200];
          sprintf (tmp, "Invalid parameter: %s; ignoring.\n", param);
          sprintf (tmp, "Invalid parameter: %s; ignoring.\n", param);
          WARNING(tmp);
          WARNING(tmp);
          while (fgetc(f) != '\n' || feof(f));
          while (fgetc(f) != '\n' || feof(f));
          continue;
          continue;
        }
        }
 
 
        if(cur_param->type == paramt_none)
        if(cur_param->type == paramt_none)
          continue;
          continue;
 
 
        /* Parse parameter value */
        /* Parse parameter value */
        cur_p = fgets (param, STR_SIZE, f);
        cur_p = fgets (param, STR_SIZE, f);
 
 
        while(*cur_p && isspace(*cur_p)) cur_p++;
        while(*cur_p && isspace(*cur_p)) cur_p++;
 
 
        switch_param(cur_p, cur_param);
        switch_param(cur_p, cur_param);
      }
      }
    }
    }
    fclose (f);
    fclose (f);
    runtime.sim.script_file_specified = 1;
    runtime.sim.script_file_specified = 1;
  } else
  } else
    if (config.sim.verbose)
    if (config.sim.verbose)
      fprintf (stderr, "WARNING: Cannot read script file from '%s',\nneither '%s'.\n", filename, ctmp);
      fprintf (stderr, "WARNING: Cannot read script file from '%s',\nneither '%s'.\n", filename, ctmp);
}
}
 
 
/* Utility for execution of set sim command.  */
/* Utility for execution of set sim command.  */
static int set_config (int argc, char **argv)
static int set_config (int argc, char **argv)
{
{
  struct config_section *cur;
  struct config_section *cur;
  struct config_param *cur_param;
  struct config_param *cur_param;
 
 
  if (argc < 2) return 1;
  if (argc < 2) return 1;
 
 
  PRINTF ("sec:%s\n", argv[1]);
  PRINTF ("sec:%s\n", argv[1]);
  cur_section = NULL;
  cur_section = NULL;
  for (cur = sections; cur; cur = cur->next)
  for (cur = sections; cur; cur = cur->next)
    if (strcmp (cur->name, argv[1]) == 0) {
    if (strcmp (cur->name, argv[1]) == 0) {
      cur_section = cur;
      cur_section = cur;
      break;
      break;
    }
    }
 
 
  if (!cur_section) return 1;
  if (!cur_section) return 1;
 
 
  if (argc < 3) return 2;
  if (argc < 3) return 2;
 
 
  PRINTF ("item:%s\n", argv[2]);
  PRINTF ("item:%s\n", argv[2]);
  {
  {
    for (cur_param = cur->params; cur_param; cur_param = cur_param->next)
    for (cur_param = cur->params; cur_param; cur_param = cur_param->next)
      if (strcmp (cur_param->name, argv[2]) == 0) {
      if (strcmp (cur_param->name, argv[2]) == 0) {
        break;
        break;
      }
      }
    if (!cur_param) return 2;
    if (!cur_param) return 2;
 
 
    /* Parse parameter value */
    /* Parse parameter value */
    if (cur_param->type) {
    if (cur_param->type) {
      if (argc < 4) return 3;
      if (argc < 4) return 3;
      PRINTF ("params:%s\n", argv[3]);
      PRINTF ("params:%s\n", argv[3]);
    }
    }
 
 
    switch_param(argv[3], cur_param);
    switch_param(argv[3], cur_param);
  }
  }
  return 0;
  return 0;
}
}
 
 
/* Executes set sim command, displays error.  */
/* Executes set sim command, displays error.  */
void set_config_command(int argc, char **argv)
void set_config_command(int argc, char **argv)
{
{
  struct config_section *cur;
  struct config_section *cur;
  struct config_param *cur_param;
  struct config_param *cur_param;
 
 
  switch (set_config (argc, argv)) {
  switch (set_config (argc, argv)) {
    case 1:
    case 1:
      PRINTF ("Invalid or missing section name.  One of valid sections must be specified:\n");
      PRINTF ("Invalid or missing section name.  One of valid sections must be specified:\n");
      for (cur = sections; cur; cur = cur->next)
      for (cur = sections; cur; cur = cur->next)
        PRINTF ("%s ", cur->name);
        PRINTF ("%s ", cur->name);
      PRINTF ("\n");
      PRINTF ("\n");
      break;
      break;
    case 2:
    case 2:
      PRINTF ("Invalid or missing item name.  One of valid items must be specified:\n");
      PRINTF ("Invalid or missing item name.  One of valid items must be specified:\n");
      for (cur_param = cur_section->params; cur_param; cur_param = cur_param->next)
      for (cur_param = cur_section->params; cur_param; cur_param = cur_param->next)
        PRINTF ("%s ", cur_param->name);
        PRINTF ("%s ", cur_param->name);
      PRINTF ("\n");
      PRINTF ("\n");
      break;
      break;
    case 3:
    case 3:
      PRINTF ("Invalid parameters specified.\n");
      PRINTF ("Invalid parameters specified.\n");
      break;
      break;
  }
  }
}
}
 
 
 
 

powered by: WebSVN 2.1.0

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