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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_34/] [or1ksim/] [cpu/] [or32/] [execute.c] - Diff between revs 804 and 884

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 804 Rev 884
Line 50... Line 50...
/* Is current insn in execution a delay insn? */
/* Is current insn in execution a delay insn? */
int delay_insn;
int delay_insn;
 
 
/* Benchmark multi issue execution */
/* Benchmark multi issue execution */
int multissue[20];
int multissue[20];
int supercycles;
 
int issued_per_cycle = 4;
int issued_per_cycle = 4;
int hazardwait = 0;
 
 
 
/* Whether break was hit - so we can step over a break */
/* Whether break was hit - so we can step over a break */
static int break_just_hit = 0;
static int break_just_hit = 0;
 
 
/* freemem 'pointer' */
/* freemem 'pointer' */
Line 82... Line 80...
int flag;
int flag;
 
 
/* CCR (for dependency calculation) */
/* CCR (for dependency calculation) */
char ccr_flag[10] = "flag";
char ccr_flag[10] = "flag";
 
 
/* Cycles counts fetch stages */
 
int 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
 
   performed inbetween. */
 
int mem_cycles;
 
 
 
/* Instructions executed */
 
int instructions;
 
 
 
/* Load and store stalls */
 
int loadcycles, storecycles;
 
 
 
/* Store buffer analysis - stores are accumulated and commited when IO is idle */
/* Store buffer analysis - stores are accumulated and commited when IO is idle */
static int sbuf_head = 0, sbuf_tail = 0, sbuf_count = 0;
static int sbuf_head = 0, sbuf_tail = 0, sbuf_count = 0;
static int sbuf_buf[MAX_SBUF_LEN] = {0};
static int sbuf_buf[MAX_SBUF_LEN] = {0};
static int sbuf_prev_cycles = 0;
static int sbuf_prev_cycles = 0;
 
 
Line 125... Line 109...
{
{
  if (regno < MAX_GPRS) {
  if (regno < MAX_GPRS) {
    return reg[regno];
    return reg[regno];
  } else {
  } else {
    printf("\nABORT: read out of registers\n");
    printf("\nABORT: read out of registers\n");
    cont_run = 0;
    runtime.sim.cont_run = 0;
    return 0;
    return 0;
  }
  }
}
}
 
 
/* Implementation specific.
/* Implementation specific.
Line 142... Line 126...
 
 
  if (regno < MAX_GPRS) {
  if (regno < MAX_GPRS) {
    reg[regno] = value;
    reg[regno] = value;
  } else {
  } else {
    printf("\nABORT: write out of registers\n");
    printf("\nABORT: write out of registers\n");
    cont_run = 0;
    runtime.sim.cont_run = 0;
  }
  }
}
}
 
 
/* Implementation specific.
/* Implementation specific.
   Get an actual value of a specific register. */
   Get an actual value of a specific register. */
 
 
inline static unsigned long eval_reg32(int regno)
inline static unsigned long eval_reg32(int regno)
{
{
  if (regno < MAX_GPRS) {
  if (regno < MAX_GPRS) {
#if RAW_RANGE_STATS
#if RAW_RANGE_STATS
      int delta = (cycles - raw_stats.reg[regno]);
      int delta = (runtime.sim.cycles - raw_stats.reg[regno]);
      if ((unsigned long)delta < (unsigned long)MAX_RAW_RANGE)
      if ((unsigned long)delta < (unsigned long)MAX_RAW_RANGE)
        raw_stats.range[delta]++;
        raw_stats.range[delta]++;
#endif /* RAW_RANGE */
#endif /* RAW_RANGE */
    return reg[regno];
    return reg[regno];
  } else {
  } else {
    printf("\nABORT: read out of registers\n");
    printf("\nABORT: read out of registers\n");
    cont_run = 0;
    runtime.sim.cont_run = 0;
    return 0;
    return 0;
  }
  }
}
}
 
 
/* Implementation specific.
/* Implementation specific.
Line 185... Line 169...
#endif
#endif
 
 
  if (regno < MAX_GPRS) {
  if (regno < MAX_GPRS) {
    reg[regno] = value;
    reg[regno] = value;
#if RAW_RANGE_STATS
#if RAW_RANGE_STATS
    raw_stats.reg[regno] = cycles;
    raw_stats.reg[regno] = runtime.sim.cycles;
#endif /* RAW_RANGE */
#endif /* RAW_RANGE */
  } else {
  } else {
    printf("\nABORT: write out of registers\n");
    printf("\nABORT: write out of registers\n");
    cont_run = 0;
    runtime.sim.cont_run = 0;
  }
  }
}
}
 
 
/* Does srcoperand depend on computation of dstoperand? Return
/* Does srcoperand depend on computation of dstoperand? Return
   non-zero if yes.
   non-zero if yes.
Line 280... Line 264...
      break_just_hit = 1;
      break_just_hit = 1;
      return 1; /* Breakpoint set. */
      return 1; /* Breakpoint set. */
    }
    }
    break_just_hit = 0;
    break_just_hit = 0;
  }
  }
  instructions++;
  runtime.cpu.instructions++;
 
 
  pc_phy &= ~0x03;
  pc_phy &= ~0x03;
 
 
  /* Fetch instruction. */
  /* Fetch instruction. */
  iqueue[0].insn_addr = pc;
  iqueue[0].insn_addr = pc;
Line 320... Line 304...
    addsstats(current->insn_index, 1);
    addsstats(current->insn_index, 1);
  }
  }
 
 
  if (config.cpu.superscalar) {
  if (config.cpu.superscalar) {
    if ((current->func_unit == it_branch) || (current->func_unit == it_jump))
    if ((current->func_unit == it_branch) || (current->func_unit == it_jump))
      storecycles += 0;
      runtime.sim.storecycles += 0;
 
 
    if (current->func_unit == it_store)
    if (current->func_unit == it_store)
      storecycles += 1;
      runtime.sim.storecycles += 1;
 
 
    if (current->func_unit == it_load)
    if (current->func_unit == it_load)
      loadcycles += 1;
      runtime.sim.loadcycles += 1;
#if 0        
#if 0        
    if ((icomplet[0].func_unit == it_load) && check_depend())
    if ((icomplet[0].func_unit == it_load) && check_depend())
      loadcycles++;
      runtime.sim.loadcycles++;
#endif
#endif
 
 
    /* Pseudo multiple issue benchmark */
    /* Pseudo multiple issue benchmark */
    if ((multissue[current->func_unit] < 1) || (check_depend())
    if ((multissue[current->func_unit] < 1) || (check_depend())
     || (issued_per_cycle < 1)) {
     || (issued_per_cycle < 1)) {
      int i;
      int i;
      for (i = 0; i < 20; i++)
      for (i = 0; i < 20; i++)
        multissue[i] = 2;
        multissue[i] = 2;
      issued_per_cycle = 2;
      issued_per_cycle = 2;
      supercycles++;
      runtime.cpu.supercycles++;
      if (check_depend())
      if (check_depend())
        hazardwait++;
        runtime.cpu.hazardwait++;
      multissue[it_unknown] = 2;
      multissue[it_unknown] = 2;
      multissue[it_shift] = 2;
      multissue[it_shift] = 2;
      multissue[it_compare] = 1;
      multissue[it_compare] = 1;
      multissue[it_branch] = 1;
      multissue[it_branch] = 1;
      multissue[it_jump] = 1;
      multissue[it_jump] = 1;
Line 377... Line 361...
  if (config.sim.exe_log) dump_exe_log();
  if (config.sim.exe_log) dump_exe_log();
}
}
 
 
/* Store buffer analysis - stores are accumulated and commited when IO is idle */
/* Store buffer analysis - stores are accumulated and commited when IO is idle */
static inline sbuf_store (int cyc) {
static inline sbuf_store (int cyc) {
  int delta = cycles - sbuf_prev_cycles;
  int delta = runtime.sim.cycles - sbuf_prev_cycles;
  sbuf_total_cyc += cyc;
  sbuf_total_cyc += cyc;
  sbuf_prev_cycles = cycles;
  sbuf_prev_cycles = runtime.sim.cycles;
 
 
  //printf (">STORE %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
  //printf (">STORE %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
  //printf ("|%i,%i\n", sbuf_total_cyc, sbuf_wait_cyc);
  //printf ("|%i,%i\n", sbuf_total_cyc, sbuf_wait_cyc);
  /* Take stores from buffer, that occured meanwhile */
  /* Take stores from buffer, that occured meanwhile */
  while (sbuf_count && delta >= sbuf_buf[sbuf_tail]) {
  while (sbuf_count && delta >= sbuf_buf[sbuf_tail]) {
Line 395... Line 379...
    sbuf_buf[sbuf_tail] -= delta;
    sbuf_buf[sbuf_tail] -= delta;
 
 
  /* Store buffer is full, take one out */
  /* Store buffer is full, take one out */
  if (sbuf_count >= config.cpu.sbuf_len) {
  if (sbuf_count >= config.cpu.sbuf_len) {
    sbuf_wait_cyc += sbuf_buf[sbuf_tail];
    sbuf_wait_cyc += sbuf_buf[sbuf_tail];
    mem_cycles += sbuf_buf[sbuf_tail];
    runtime.sim.mem_cycles += sbuf_buf[sbuf_tail];
    sbuf_prev_cycles += sbuf_buf[sbuf_tail];
    sbuf_prev_cycles += sbuf_buf[sbuf_tail];
    sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
    sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
    sbuf_count--;
    sbuf_count--;
  }
  }
  /* Put newest store in the buffer */
  /* Put newest store in the buffer */
Line 409... Line 393...
  //printf ("|STORE %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
  //printf ("|STORE %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
}
}
 
 
/* Store buffer analysis - previous stores should commit, before any load */
/* Store buffer analysis - previous stores should commit, before any load */
static inline sbuf_load () {
static inline sbuf_load () {
  int delta = cycles - sbuf_prev_cycles;
  int delta = runtime.sim.cycles - sbuf_prev_cycles;
  sbuf_prev_cycles = cycles;
  sbuf_prev_cycles = runtime.sim.cycles;
 
 
  //printf (">LOAD  %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
  //printf (">LOAD  %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
  //printf ("|%i,%i\n", sbuf_total_cyc, sbuf_wait_cyc);
  //printf ("|%i,%i\n", sbuf_total_cyc, sbuf_wait_cyc);
  /* Take stores from buffer, that occured meanwhile */
  /* Take stores from buffer, that occured meanwhile */
  while (sbuf_count && delta >= sbuf_buf[sbuf_tail]) {
  while (sbuf_count && delta >= sbuf_buf[sbuf_tail]) {
Line 426... Line 410...
    sbuf_buf[sbuf_tail] -= delta;
    sbuf_buf[sbuf_tail] -= delta;
 
 
  /* Wait for all stores to complete */
  /* Wait for all stores to complete */
  while (sbuf_count > 0) {
  while (sbuf_count > 0) {
    sbuf_wait_cyc += sbuf_buf[sbuf_tail];
    sbuf_wait_cyc += sbuf_buf[sbuf_tail];
    mem_cycles += sbuf_buf[sbuf_tail];
    runtime.sim.mem_cycles += sbuf_buf[sbuf_tail];
    sbuf_prev_cycles += sbuf_buf[sbuf_tail];
    sbuf_prev_cycles += sbuf_buf[sbuf_tail];
    sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
    sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
    sbuf_count--;
    sbuf_count--;
  }
  }
  //printf ("|LOAD  %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
  //printf ("|LOAD  %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
Line 440... Line 424...
void dump_exe_log ()
void dump_exe_log ()
{
{
  unsigned long i = iqueue[0].insn_addr;
  unsigned long i = iqueue[0].insn_addr;
 
 
  if (i == 0xffffffff) return;
  if (i == 0xffffffff) return;
  if (config.sim.exe_log_start <= instructions && (config.sim.exe_log_end <= 0 || instructions <= config.sim.exe_log_end)) {
  if (config.sim.exe_log_start <= runtime.cpu.instructions && (config.sim.exe_log_end <= 0 || runtime.cpu.instructions <= config.sim.exe_log_end)) {
    if (config.sim.exe_log_marker && instructions % config.sim.exe_log_marker == 0) {
    if (config.sim.exe_log_marker && runtime.cpu.instructions % config.sim.exe_log_marker == 0) {
      fprintf (runtime.sim.fexe_log, "--------------------- %8i instruction ---------------------\n", instructions);
      fprintf (runtime.sim.fexe_log, "--------------------- %8i instruction ---------------------\n", runtime.cpu.instructions);
    }
    }
    switch (config.sim.exe_log_type) {
    switch (config.sim.exe_log_type) {
    case EXE_LOG_HARDWARE:
    case EXE_LOG_HARDWARE:
      fprintf (runtime.sim.fexe_log, "\nEXECUTED(): %.8lx:  ", i);
      fprintf (runtime.sim.fexe_log, "\nEXECUTED(): %.8lx:  ", i);
      fprintf (runtime.sim.fexe_log, "%.2x%.2x", evalsim_mem8(i), evalsim_mem8(i + 1));
      fprintf (runtime.sim.fexe_log, "%.2x%.2x", evalsim_mem8(i), evalsim_mem8(i + 1));
Line 498... Line 482...
{
{
  int i;
  int i;
  char temp[100];
  char temp[100];
 
 
  dumpmemory(iqueue[0].insn_addr, iqueue[0].insn_addr + 4, 1, 0);
  dumpmemory(iqueue[0].insn_addr, iqueue[0].insn_addr + 4, 1, 0);
  generate_time_pretty (temp, cycles);
  generate_time_pretty (temp, runtime.sim.cycles);
  printf(" (executed) [time %s, #%i]\n", temp, instructions);
  printf(" (executed) [time %s, #%i]\n", temp, runtime.cpu.instructions);
  if (config.cpu.superscalar)
  if (config.cpu.superscalar)
    printf ("Superscalar CYCLES: %u", supercycles);
    printf ("Superscalar CYCLES: %u", runtime.cpu.supercycles);
  if (config.cpu.hazards)
  if (config.cpu.hazards)
    printf ("  HAZARDWAIT: %u\n", hazardwait);
    printf ("  HAZARDWAIT: %u\n", runtime.cpu.hazardwait);
  else
  else
    if (config.cpu.superscalar)
    if (config.cpu.superscalar)
      printf ("\n");
      printf ("\n");
 
 
  dumpmemory(pc, pc + 4, 1, 0);
  dumpmemory(pc, pc + 4, 1, 0);
Line 550... Line 534...
 
 
/* Reset the CPU */
/* Reset the CPU */
void cpu_reset()
void cpu_reset()
{
{
  int i;
  int i;
  cycles = 0;
  runtime.sim.cycles = 0;
  instructions = 0;
  runtime.sim.loadcycles = 0;
  supercycles = 0;
  runtime.sim.storecycles = 0;
  loadcycles = 0;
  runtime.cpu.instructions = 0;
  storecycles = 0;
  runtime.cpu.supercycles = 0;
 
  runtime.cpu.hazardwait = 0;
  for (i = 0; i < MAX_GPRS; i++)
  for (i = 0; i < MAX_GPRS; i++)
    set_reg32 (i, 0);
    set_reg32 (i, 0);
  memset(iqueue, 0, sizeof(iqueue));
  memset(iqueue, 0, sizeof(iqueue));
  memset(icomplet, 0, sizeof(icomplet));
  memset(icomplet, 0, sizeof(icomplet));
 
 
Line 587... Line 572...
/* Simulates one CPU clock cycle */
/* Simulates one CPU clock cycle */
inline int cpu_clock ()
inline int cpu_clock ()
{
{
  if(fetch()) {
  if(fetch()) {
    printf ("Breakpoint hit.\n");
    printf ("Breakpoint hit.\n");
    cont_run = 0; /* memory breakpoint encountered */
    runtime.sim.cont_run = 0; /* memory breakpoint encountered */
    return 1;
    return 1;
  }
  }
  decode_execute_wrapper (&iqueue[0]);
  decode_execute_wrapper (&iqueue[0]);
  update_pc();
  update_pc();
  return 0;
  return 0;

powered by: WebSVN 2.1.0

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