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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [cpu/] [common/] [stats.c] - Diff between revs 19 and 230

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

Rev 19 Rev 230
/* stats.c -- Various statistics about instruction scheduling etc.
/* stats.c -- Various statistics about instruction scheduling etc.
 
 
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
   Copyright (C) 2008 Embecosm Limited
   Copyright (C) 2008 Embecosm Limited
 
 
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
 
 
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
 
 
   This program is free software; you can redistribute it and/or modify it
   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 the Free
   under the terms of the GNU General Public License as published by the Free
   Software Foundation; either version 3 of the License, or (at your option)
   Software Foundation; either version 3 of the License, or (at your option)
   any later version.
   any later version.
 
 
   This program is distributed in the hope that it will be useful, but WITHOUT
   This program is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
   more details.
 
 
   You should have received a copy of the GNU General Public License along
   You should have received a copy of the GNU General Public License along
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
/* This program is commented throughout in a fashion suitable for processing
/* This program is commented throughout in a fashion suitable for processing
   with Doxygen. */
   with Doxygen. */
 
 
 
 
/* Autoconf and/or portability configuration */
/* Autoconf and/or portability configuration */
#include "config.h"
#include "config.h"
#include "port.h"
#include "port.h"
 
 
/* Package includes */
/* Package includes */
#include "stats.h"
#include "stats.h"
#include "sim-config.h"
#include "sim-config.h"
#include "icache-model.h"
#include "icache-model.h"
#include "spr-defs.h"
#include "spr-defs.h"
#include "execute.h"
#include "execute.h"
 
 
 
 
#define DSTATS_LEN      3000
#define DSTATS_LEN      3000
#define SSTATS_LEN      300
#define SSTATS_LEN      300
#define FSTATS_LEN      200
#define FSTATS_LEN      200
 
 
/* Used by safe division - increment divisor by one if it is zero */
/* Used by safe division - increment divisor by one if it is zero */
#define SD(X) (X != 0 ? X : 1)
#define SD(X) (X != 0 ? X : 1)
 
 
struct branchstat
struct branchstat
{
{
  int taken;
  int taken;
  int nottaken;
  int nottaken;
  int forward;
  int forward;
  int backward;
  int backward;
};
};
 
 
/*! @see also enum insn_type in abstract.h */
/*! @see also enum insn_type in abstract.h */
static const char func_unit_str[30][30] = {
static const char func_unit_str[30][30] = {
  "unknown",
  "unknown",
  "exception",
  "exception",
  "arith",
  "arith",
  "shift",
  "shift",
  "compare",
  "compare",
  "branch",
  "branch",
  "jump",
  "jump",
  "load",
  "load",
  "store",
  "store",
  "movimm",
  "movimm",
  "move",
  "move",
  "extend",
  "extend",
  "nop",
  "nop",
  "mac"
  "mac"
};
};
 
 
struct dstats_entry
struct dstats_entry
{
{
  int insn1;
  int insn1;
  int insn2;
  int insn2;
  int cnt_dynamic;
  int cnt_dynamic;
  int depend;
  int depend;
};                              /*!< double stats */
};                              /*!< double stats */
 
 
struct sstats_entry
struct sstats_entry
{
{
  int insn;
  int insn;
  int cnt_dynamic;
  int cnt_dynamic;
};                              /*!< single stats */
};                              /*!< single stats */
 
 
struct fstats_entry
struct fstats_entry
{
{
  enum insn_type insn1;
  enum insn_type insn1;
  enum insn_type insn2;
  enum insn_type insn2;
  int cnt_dynamic;
  int cnt_dynamic;
  int depend;
  int depend;
};                              /*!< functional units stats */
};                              /*!< functional units stats */
 
 
/* Globally visible statistics data. Renamed mstats to or1k_mstats because Mac
/* Globally visible statistics data. Renamed mstats to or1k_mstats because Mac
   OS X has a lib function called mstats */
   OS X has a lib function called mstats */
struct mstats_entry      or1k_mstats = { 0 };    /*!< misc units stats */
struct mstats_entry      or1k_mstats = { 0 };    /*!< misc units stats */
struct cachestats_entry  ic_stats    = { 0 };    /*!< instruction cache stats */
struct cachestats_entry  ic_stats    = { 0 };    /*!< instruction cache stats */
struct cachestats_entry  dc_stats    = { 0 };    /*!< data cache stats */
struct cachestats_entry  dc_stats    = { 0 };    /*!< data cache stats */
struct immustats_entry   immu_stats  = { 0 };    /*!< insn MMU stats */
struct immustats_entry   immu_stats  = { 0 };    /*!< insn MMU stats */
struct dmmustats_entry   dmmu_stats  = { 0 };    /*!< data MMU stats */
struct dmmustats_entry   dmmu_stats  = { 0 };    /*!< data MMU stats */
struct raw_stats         raw_stats;             /*!< RAW hazard stats */
struct raw_stats         raw_stats;             /*!< RAW hazard stats */
 
 
/* Statistics data strutures used just here */
/* Statistics data strutures used just here */
static struct dstats_entry  dstats[DSTATS_LEN]; /*!< dependency stats */
static struct dstats_entry  dstats[DSTATS_LEN]; /*!< dependency stats */
static struct sstats_entry  sstats[SSTATS_LEN]; /*!< single stats */
static struct sstats_entry  sstats[SSTATS_LEN]; /*!< single stats */
static struct fstats_entry  fstats[FSTATS_LEN]; /*!< func units stats */
static struct fstats_entry  fstats[FSTATS_LEN]; /*!< func units stats */
 
 
 
 
void
void
addsstats (int item, int cnt_dynamic)
addsstats (int item, int cnt_dynamic)
{
{
  int i = 0;
  int i = 0;
 
 
  while (sstats[i].insn != item && sstats[i].insn >= 0 && i < SSTATS_LEN)
  while (sstats[i].insn != item && sstats[i].insn >= 0 && i < SSTATS_LEN)
    i++;
    i++;
 
 
  if (i >= SSTATS_LEN - 1)
  if (i >= SSTATS_LEN - 1)
    return;
    return;
 
 
  if (sstats[i].insn >= 0)
  if (sstats[i].insn >= 0)
    {
    {
      sstats[i].cnt_dynamic += cnt_dynamic;
      sstats[i].cnt_dynamic += cnt_dynamic;
    }
    }
  else
  else
    {
    {
      sstats[i].insn = item;
      sstats[i].insn = item;
      sstats[i].cnt_dynamic = cnt_dynamic;
      sstats[i].cnt_dynamic = cnt_dynamic;
    }
    }
}
}
 
 
void
void
adddstats (int item1, int item2, int cnt_dynamic, int depend)
adddstats (int item1, int item2, int cnt_dynamic, int depend)
{
{
  int i = 0;
  int i = 0;
 
 
  while ((dstats[i].insn1 != item1 || dstats[i].insn2 != item2)
  while ((dstats[i].insn1 != item1 || dstats[i].insn2 != item2)
         && (i < DSTATS_LEN) && dstats[i].insn1 >= 0)
         && (i < DSTATS_LEN) && dstats[i].insn1 >= 0)
    i++;
    i++;
 
 
  if (i >= DSTATS_LEN - 1)
  if (i >= DSTATS_LEN - 1)
    return;
    return;
 
 
  if (dstats[i].insn1 >= 0)
  if (dstats[i].insn1 >= 0)
    {
    {
      dstats[i].cnt_dynamic += cnt_dynamic;
      dstats[i].cnt_dynamic += cnt_dynamic;
      dstats[i].depend += depend;
      dstats[i].depend += depend;
    }
    }
  else
  else
    {
    {
      dstats[i].insn1 = item1;
      dstats[i].insn1 = item1;
      dstats[i].insn2 = item2;
      dstats[i].insn2 = item2;
      dstats[i].cnt_dynamic = cnt_dynamic;
      dstats[i].cnt_dynamic = cnt_dynamic;
      dstats[i].depend = depend;
      dstats[i].depend = depend;
    }
    }
}
}
 
 
void
void
addfstats (enum insn_type item1, enum insn_type item2, int cnt_dynamic,
addfstats (enum insn_type item1, enum insn_type item2, int cnt_dynamic,
           int depend)
           int depend)
{
{
  int i = 0;
  int i = 0;
 
 
  while (((fstats[i].insn1 != item1) || (fstats[i].insn2 != item2)) &&
  while (((fstats[i].insn1 != item1) || (fstats[i].insn2 != item2)) &&
         (fstats[i].insn1 != it_unknown) && (i < FSTATS_LEN))
         (fstats[i].insn1 != it_unknown) && (i < FSTATS_LEN))
    i++;
    i++;
 
 
  if (i >= FSTATS_LEN - 1)
  if (i >= FSTATS_LEN - 1)
    return;
    return;
 
 
  if ((fstats[i].insn1 == item1) && (fstats[i].insn2 == item2))
  if ((fstats[i].insn1 == item1) && (fstats[i].insn2 == item2))
    {
    {
      fstats[i].cnt_dynamic += cnt_dynamic;
      fstats[i].cnt_dynamic += cnt_dynamic;
      fstats[i].depend += depend;
      fstats[i].depend += depend;
    }
    }
  else
  else
    {
    {
      fstats[i].insn1 = item1;
      fstats[i].insn1 = item1;
      fstats[i].insn2 = item2;
      fstats[i].insn2 = item2;
      fstats[i].cnt_dynamic = cnt_dynamic;
      fstats[i].cnt_dynamic = cnt_dynamic;
      fstats[i].depend = depend;
      fstats[i].depend = depend;
    }
    }
}
}
 
 
void
void
initstats ()
initstats ()
{
{
  int i;
  int i;
  memset (sstats, 0, sizeof (sstats));
  memset (sstats, 0, sizeof (sstats));
  for (i = 0; i < SSTATS_LEN; i++)
  for (i = 0; i < SSTATS_LEN; i++)
    sstats[i].insn = -1;
    sstats[i].insn = -1;
  memset (dstats, 0, sizeof (dstats));
  memset (dstats, 0, sizeof (dstats));
  for (i = 0; i < DSTATS_LEN; i++)
  for (i = 0; i < DSTATS_LEN; i++)
    dstats[i].insn1 = dstats[i].insn2 = -1;
    dstats[i].insn1 = dstats[i].insn2 = -1;
  memset (fstats, 0, sizeof (fstats));
  memset (fstats, 0, sizeof (fstats));
  memset (&or1k_mstats, 0, sizeof (or1k_mstats));
  memset (&or1k_mstats, 0, sizeof (or1k_mstats));
  memset (&ic_stats, 0, sizeof (ic_stats));
  memset (&ic_stats, 0, sizeof (ic_stats));
  memset (&dc_stats, 0, sizeof (dc_stats));
  memset (&dc_stats, 0, sizeof (dc_stats));
  memset (&raw_stats, 0, sizeof (raw_stats));
  memset (&raw_stats, 0, sizeof (raw_stats));
}
}
 
 
static void
static void
printotherstats (int which)
printotherstats (int which)
{
{
  PRINTF ("\n");
  PRINTF ("\n");
  if (config.bpb.enabled)
  if (config.bpb.enabled)
    {
    {
      struct branchstat bf;
      struct branchstat bf;
      struct branchstat bnf;
      struct branchstat bnf;
      long bf_all, bnf_all;
      long bf_all, bnf_all;
      bf.taken = or1k_mstats.bf[1][0] + or1k_mstats.bf[1][1];
      bf.taken = or1k_mstats.bf[1][0] + or1k_mstats.bf[1][1];
      bf.nottaken = or1k_mstats.bf[0][0] + or1k_mstats.bf[0][1];
      bf.nottaken = or1k_mstats.bf[0][0] + or1k_mstats.bf[0][1];
      bf.forward = or1k_mstats.bf[0][1] + or1k_mstats.bf[1][1];
      bf.forward = or1k_mstats.bf[0][1] + or1k_mstats.bf[1][1];
      bf.backward = or1k_mstats.bf[0][0] + or1k_mstats.bf[1][0];
      bf.backward = or1k_mstats.bf[0][0] + or1k_mstats.bf[1][0];
      bf_all = bf.forward + bf.backward;
      bf_all = bf.forward + bf.backward;
 
 
      bnf.taken = or1k_mstats.bnf[1][0] + or1k_mstats.bf[1][1];
      bnf.taken = or1k_mstats.bnf[1][0] + or1k_mstats.bf[1][1];
      bnf.nottaken = or1k_mstats.bnf[0][0] + or1k_mstats.bf[0][1];
      bnf.nottaken = or1k_mstats.bnf[0][0] + or1k_mstats.bf[0][1];
      bnf.forward = or1k_mstats.bnf[0][1] + or1k_mstats.bf[1][1];
      bnf.forward = or1k_mstats.bnf[0][1] + or1k_mstats.bf[1][1];
      bnf.backward = or1k_mstats.bnf[0][0] + or1k_mstats.bf[1][0];
      bnf.backward = or1k_mstats.bnf[0][0] + or1k_mstats.bf[1][0];
      bnf_all = bnf.forward + bnf.backward;
      bnf_all = bnf.forward + bnf.backward;
 
 
      PRINTF ("bnf: %d (%ld%%) taken,", bf.taken,
      PRINTF ("bnf: %d (%ld%%) taken,", bf.taken,
              (bf.taken * 100) / SD (bf_all));
              (bf.taken * 100) / SD (bf_all));
      PRINTF (" %d (%ld%%) not taken,", bf.nottaken,
      PRINTF (" %d (%ld%%) not taken,", bf.nottaken,
              (bf.nottaken * 100) / SD (bf_all));
              (bf.nottaken * 100) / SD (bf_all));
      PRINTF (" %d (%ld%%) forward,", bf.forward,
      PRINTF (" %d (%ld%%) forward,", bf.forward,
              (bf.forward * 100) / SD (bf_all));
              (bf.forward * 100) / SD (bf_all));
      PRINTF (" %d (%ld%%) backward\n", bf.backward,
      PRINTF (" %d (%ld%%) backward\n", bf.backward,
              (bf.backward * 100) / SD (bf_all));
              (bf.backward * 100) / SD (bf_all));
      PRINTF ("bf: %d (%ld%%) taken,", bnf.taken,
      PRINTF ("bf: %d (%ld%%) taken,", bnf.taken,
              (bnf.taken * 100) / SD (bnf_all));
              (bnf.taken * 100) / SD (bnf_all));
      PRINTF (" %d (%ld%%) not taken,", bnf.nottaken,
      PRINTF (" %d (%ld%%) not taken,", bnf.nottaken,
              (bnf.nottaken * 100) / SD (bnf_all));
              (bnf.nottaken * 100) / SD (bnf_all));
      PRINTF (" %d (%ld%%) forward,", bnf.forward,
      PRINTF (" %d (%ld%%) forward,", bnf.forward,
              (bnf.forward * 100) / SD (bnf_all));
              (bnf.forward * 100) / SD (bnf_all));
      PRINTF (" %d (%ld%%) backward\n", bnf.backward,
      PRINTF (" %d (%ld%%) backward\n", bnf.backward,
              (bnf.backward * 100) / SD (bnf_all));
              (bnf.backward * 100) / SD (bnf_all));
 
 
      PRINTF ("StaticBP bnf(%s): correct %ld%%\n",
      PRINTF ("StaticBP bnf(%s): correct %ld%%\n",
              config.bpb.sbp_bnf_fwd ? "forward" : "backward",
              config.bpb.sbp_bnf_fwd ? "forward" : "backward",
              (or1k_mstats.bnf[0][config.bpb.sbp_bnf_fwd] * 100) /
              (or1k_mstats.bnf[0][config.bpb.sbp_bnf_fwd] * 100) /
              SD (bnf_all));
              SD (bnf_all));
      PRINTF ("StaticBP bf(%s): correct %ld%%\n",
      PRINTF ("StaticBP bf(%s): correct %ld%%\n",
              config.bpb.sbp_bf_fwd ? "forward" : "backward",
              config.bpb.sbp_bf_fwd ? "forward" : "backward",
              (or1k_mstats.bnf[1][config.bpb.sbp_bf_fwd] * 100) /
              (or1k_mstats.bnf[1][config.bpb.sbp_bf_fwd] * 100) /
              SD (bf_all));
              SD (bf_all));
      PRINTF ("BPB: hit %d (correct %d%%), miss %d\n", or1k_mstats.bpb.hit,
      PRINTF ("BPB: hit %d (correct %d%%), miss %d\n", or1k_mstats.bpb.hit,
              (or1k_mstats.bpb.correct * 100) / SD (or1k_mstats.bpb.hit),
              (or1k_mstats.bpb.correct * 100) / SD (or1k_mstats.bpb.hit),
              or1k_mstats.bpb.miss);
              or1k_mstats.bpb.miss);
    }
    }
  else
  else
    PRINTF ("BPB simulation disabled. Enable it to see BPB analysis\n");
    PRINTF ("BPB simulation disabled. Enable it to see BPB analysis\n");
 
 
  if (config.bpb.btic)
  if (config.bpb.btic)
    {
    {
      PRINTF ("BTIC: hit %d(%d%%), miss %d\n", or1k_mstats.btic.hit,
      PRINTF ("BTIC: hit %d(%d%%), miss %d\n", or1k_mstats.btic.hit,
              (or1k_mstats.btic.hit * 100) / SD (or1k_mstats.btic.hit +
              (or1k_mstats.btic.hit * 100) / SD (or1k_mstats.btic.hit +
                                                 or1k_mstats.btic.miss),
                                                 or1k_mstats.btic.miss),
              or1k_mstats.btic.miss);
              or1k_mstats.btic.miss);
    }
    }
  else
  else
    PRINTF ("BTIC simulation disabled. Enabled it to see BTIC analysis\n");
    PRINTF ("BTIC simulation disabled. Enabled it to see BTIC analysis\n");
 
 
  if ((NULL != ic_state) && ic_state->enabled)
  if ((NULL != ic_state) && ic_state->enabled)
    {
    {
      PRINTF ("IC read:  hit %d(%d%%), miss %d\n", ic_stats.readhit,
      PRINTF ("IC read:  hit %d(%d%%), miss %d\n", ic_stats.readhit,
              (ic_stats.readhit * 100) / SD (ic_stats.readhit +
              (ic_stats.readhit * 100) / SD (ic_stats.readhit +
                                             ic_stats.readmiss),
                                             ic_stats.readmiss),
              ic_stats.readmiss);
              ic_stats.readmiss);
    }
    }
  else
  else
    PRINTF ("No ICache. Enable it to see IC results.\n");
    PRINTF ("No ICache. Enable it to see IC results.\n");
 
 
  if (config.dc.enabled)
  if (config.dc.enabled)
    {
    {
      PRINTF ("DC read:  hit %d(%d%%), miss %d\n", dc_stats.readhit,
      PRINTF ("DC read:  hit %d(%d%%), miss %d\n", dc_stats.readhit,
              (dc_stats.readhit * 100) / SD (dc_stats.readhit +
              (dc_stats.readhit * 100) / SD (dc_stats.readhit +
                                             dc_stats.readmiss),
                                             dc_stats.readmiss),
              dc_stats.readmiss);
              dc_stats.readmiss);
      PRINTF ("DC write: hit %d(%d%%), miss %d\n", dc_stats.writehit,
      PRINTF ("DC write: hit %d(%d%%), miss %d\n", dc_stats.writehit,
              (dc_stats.writehit * 100) / SD (dc_stats.writehit +
              (dc_stats.writehit * 100) / SD (dc_stats.writehit +
                                              dc_stats.writemiss),
                                              dc_stats.writemiss),
              dc_stats.writemiss);
              dc_stats.writemiss);
    }
    }
  else
  else
    PRINTF ("No DCache. Enable it to see DC results.\n");
    PRINTF ("No DCache. Enable it to see DC results.\n");
 
 
  if (cpu_state.sprs[SPR_UPR] & SPR_UPR_IMP)
  if (cpu_state.sprs[SPR_UPR] & SPR_UPR_IMP)
    {
    {
      PRINTF ("IMMU read:  hit %d(%d%%), miss %d\n", immu_stats.fetch_tlbhit,
      PRINTF ("IMMU read:  hit %d(%d%%), miss %d\n", immu_stats.fetch_tlbhit,
              (immu_stats.fetch_tlbhit * 100) / SD (immu_stats.fetch_tlbhit +
              (immu_stats.fetch_tlbhit * 100) / SD (immu_stats.fetch_tlbhit +
                                                    immu_stats.fetch_tlbmiss),
                                                    immu_stats.fetch_tlbmiss),
              immu_stats.fetch_tlbmiss);
              immu_stats.fetch_tlbmiss);
    }
    }
  else
  else
    PRINTF ("No IMMU. Set UPR[IMP]\n");
    PRINTF ("No IMMU. Set UPR[IMP]\n");
 
 
  if (cpu_state.sprs[SPR_UPR] & SPR_UPR_DMP)
  if (cpu_state.sprs[SPR_UPR] & SPR_UPR_DMP)
    {
    {
      PRINTF ("DMMU read:  hit %d(%d%%), miss %d\n", dmmu_stats.loads_tlbhit,
      PRINTF ("DMMU read:  hit %d(%d%%), miss %d\n", dmmu_stats.loads_tlbhit,
              (dmmu_stats.loads_tlbhit * 100) / SD (dmmu_stats.loads_tlbhit +
              (dmmu_stats.loads_tlbhit * 100) / SD (dmmu_stats.loads_tlbhit +
                                                    dmmu_stats.loads_tlbmiss),
                                                    dmmu_stats.loads_tlbmiss),
              dmmu_stats.loads_tlbmiss);
              dmmu_stats.loads_tlbmiss);
    }
    }
  else
  else
    PRINTF ("No DMMU. Set UPR[DMP]\n");
    PRINTF ("No DMMU. Set UPR[DMP]\n");
 
 
  PRINTF ("Additional LOAD CYCLES: %u  STORE CYCLES: %u\n",
  PRINTF ("Additional LOAD CYCLES: %u  STORE CYCLES: %u\n",
          runtime.sim.loadcycles, runtime.sim.storecycles);
          runtime.sim.loadcycles, runtime.sim.storecycles);
}
}
 
 
void
void
printstats (int which)
printstats (int which)
{
{
  int i, all = 0, dependall = 0;
  int i, all = 0, dependall = 0;
 
 
  if (which > 1 && which <= 5 && !config.cpu.dependstats)
  if (which > 1 && which <= 5 && !config.cpu.dependstats)
    {
    {
      PRINTF
      PRINTF
        ("Hazard analysis disabled. Enable it to see analysis results.\n");
        ("Hazard analysis disabled. Enable it to see analysis results.\n");
      return;
      return;
    }
    }
 
 
  switch (which)
  switch (which)
    {
    {
    case 1:
    case 1:
      PRINTF ("stats 1: Misc stats\n");
      PRINTF ("stats 1: Misc stats\n");
      printotherstats (which);
      printotherstats (which);
      break;
      break;
    case 2:
    case 2:
      PRINTF ("stats 2: Instruction usage\n");
      PRINTF ("stats 2: Instruction usage\n");
      for (i = 0; i < SSTATS_LEN; i++)
      for (i = 0; i < SSTATS_LEN; i++)
        all += sstats[i].cnt_dynamic;
        all += sstats[i].cnt_dynamic;
 
 
      for (i = 0; i < SSTATS_LEN; i++)
      for (i = 0; i < SSTATS_LEN; i++)
        if (sstats[i].cnt_dynamic)
        if (sstats[i].cnt_dynamic)
          PRINTF ("  %-15s used %6dx (%5.1f%%)\n", insn_name (sstats[i].insn),
          PRINTF ("  %-15s used %6dx (%5.1f%%)\n", or1ksim_insn_name (sstats[i].insn),
                  sstats[i].cnt_dynamic,
                  sstats[i].cnt_dynamic,
                  (sstats[i].cnt_dynamic * 100.) / SD (all));
                  (sstats[i].cnt_dynamic * 100.) / SD (all));
 
 
      PRINTF ("%d instructions (dynamic, single stats)\n", all);
      PRINTF ("%d instructions (dynamic, single stats)\n", all);
      break;
      break;
 
 
    case 3:
    case 3:
      PRINTF ("stats 3: Instruction dependencies\n");
      PRINTF ("stats 3: Instruction dependencies\n");
      for (i = 0; i < DSTATS_LEN; i++)
      for (i = 0; i < DSTATS_LEN; i++)
        {
        {
          all += dstats[i].cnt_dynamic;
          all += dstats[i].cnt_dynamic;
          dependall += dstats[i].depend;
          dependall += dstats[i].depend;
        }
        }
 
 
      for (i = 0; i < DSTATS_LEN; i++)
      for (i = 0; i < DSTATS_LEN; i++)
        if (dstats[i].cnt_dynamic)
        if (dstats[i].cnt_dynamic)
          {
          {
            char temp[100];
            char temp[100];
            sprintf (temp, "%s, %s ", insn_name (dstats[i].insn1),
            sprintf (temp, "%s, %s ", or1ksim_insn_name (dstats[i].insn1),
                     insn_name (dstats[i].insn2));
                     or1ksim_insn_name (dstats[i].insn2));
            PRINTF ("  %-30s %6dx (%5.1f%%)", temp, dstats[i].cnt_dynamic,
            PRINTF ("  %-30s %6dx (%5.1f%%)", temp, dstats[i].cnt_dynamic,
                    (dstats[i].cnt_dynamic * 100.) / SD (all));
                    (dstats[i].cnt_dynamic * 100.) / SD (all));
            PRINTF ("   depend: %5.1f%%\n",
            PRINTF ("   depend: %5.1f%%\n",
                    (dstats[i].depend * 100.) / dstats[i].cnt_dynamic);
                    (dstats[i].depend * 100.) / dstats[i].cnt_dynamic);
          }
          }
 
 
      PRINTF ("%d instructions (dynamic, dependency stats)  depend: %d%%\n",
      PRINTF ("%d instructions (dynamic, dependency stats)  depend: %d%%\n",
              all, (dependall * 100) / SD (all));
              all, (dependall * 100) / SD (all));
      break;
      break;
 
 
    case 4:
    case 4:
      PRINTF ("stats 4: Functional units dependencies\n");
      PRINTF ("stats 4: Functional units dependencies\n");
      for (i = 0; i < FSTATS_LEN; i++)
      for (i = 0; i < FSTATS_LEN; i++)
        {
        {
          all += fstats[i].cnt_dynamic;
          all += fstats[i].cnt_dynamic;
          dependall += fstats[i].depend;
          dependall += fstats[i].depend;
        }
        }
 
 
      for (i = 0; i < FSTATS_LEN; i++)
      for (i = 0; i < FSTATS_LEN; i++)
        if (fstats[i].cnt_dynamic)
        if (fstats[i].cnt_dynamic)
          {
          {
            char temp[100];
            char temp[100];
            sprintf (temp, "%s, %s", func_unit_str[fstats[i].insn1],
            sprintf (temp, "%s, %s", func_unit_str[fstats[i].insn1],
                     func_unit_str[fstats[i].insn2]);
                     func_unit_str[fstats[i].insn2]);
            PRINTF ("  %-30s %6dx (%5.1f%%)", temp, fstats[i].cnt_dynamic,
            PRINTF ("  %-30s %6dx (%5.1f%%)", temp, fstats[i].cnt_dynamic,
                    (fstats[i].cnt_dynamic * 100.) / SD (all));
                    (fstats[i].cnt_dynamic * 100.) / SD (all));
            PRINTF ("   depend: %5.1f%%\n",
            PRINTF ("   depend: %5.1f%%\n",
                    (fstats[i].depend * 100.) / fstats[i].cnt_dynamic);
                    (fstats[i].depend * 100.) / fstats[i].cnt_dynamic);
          }
          }
      PRINTF
      PRINTF
        ("%d instructions (dynamic, functional units stats)  depend: %d%%\n\n",
        ("%d instructions (dynamic, functional units stats)  depend: %d%%\n\n",
         all, (dependall * 100) / SD (all));
         all, (dependall * 100) / SD (all));
      break;
      break;
 
 
    case 5:
    case 5:
      PRINTF ("stats 5: Raw register usage over time\n");
      PRINTF ("stats 5: Raw register usage over time\n");
#if RAW_RANGE_STATS
#if RAW_RANGE_STATS
      for (i = 0; (i < RAW_RANGE); i++)
      for (i = 0; (i < RAW_RANGE); i++)
        PRINTF ("  Register set and reused in %d. cycle: %d cases\n", i,
        PRINTF ("  Register set and reused in %d. cycle: %d cases\n", i,
                raw_stats.range[i]);
                raw_stats.range[i]);
#endif
#endif
      break;
      break;
    case 6:
    case 6:
      if (config.cpu.sbuf_len)
      if (config.cpu.sbuf_len)
        {
        {
          extern int sbuf_total_cyc, sbuf_wait_cyc;
          extern int sbuf_total_cyc, sbuf_wait_cyc;
          PRINTF ("stats 6: Store buffer analysis\n");
          PRINTF ("stats 6: Store buffer analysis\n");
          PRINTF ("Using store buffer of length %i.\n", config.cpu.sbuf_len);
          PRINTF ("Using store buffer of length %i.\n", config.cpu.sbuf_len);
          PRINTF ("Number of total memory store cycles: %i/%lli\n",
          PRINTF ("Number of total memory store cycles: %i/%lli\n",
                  sbuf_total_cyc,
                  sbuf_total_cyc,
                  runtime.sim.cycles + sbuf_total_cyc - sbuf_wait_cyc);
                  runtime.sim.cycles + sbuf_total_cyc - sbuf_wait_cyc);
          PRINTF ("Number of cycles waiting for memory stores: %i\n",
          PRINTF ("Number of cycles waiting for memory stores: %i\n",
                  sbuf_wait_cyc);
                  sbuf_wait_cyc);
          PRINTF ("Number of memory cycles spared: %i\n",
          PRINTF ("Number of memory cycles spared: %i\n",
                  sbuf_total_cyc - sbuf_wait_cyc);
                  sbuf_total_cyc - sbuf_wait_cyc);
          PRINTF ("Store speedup %3.2f%%, total speedup %3.2f%%\n",
          PRINTF ("Store speedup %3.2f%%, total speedup %3.2f%%\n",
                  100. * (sbuf_total_cyc - sbuf_wait_cyc) / sbuf_total_cyc,
                  100. * (sbuf_total_cyc - sbuf_wait_cyc) / sbuf_total_cyc,
                  100. * (sbuf_total_cyc -
                  100. * (sbuf_total_cyc -
                          sbuf_wait_cyc) / (runtime.sim.cycles +
                          sbuf_wait_cyc) / (runtime.sim.cycles +
                                            sbuf_total_cyc - sbuf_wait_cyc));
                                            sbuf_total_cyc - sbuf_wait_cyc));
        }
        }
      else
      else
        PRINTF
        PRINTF
          ("Store buffer analysis disabled. Enable it to see analysis results.\n");
          ("Store buffer analysis disabled. Enable it to see analysis results.\n");
      break;
      break;
    default:
    default:
      PRINTF ("Please specify a stats group (1-6).\n");
      PRINTF ("Please specify a stats group (1-6).\n");
      break;
      break;
    }
    }
}
}
 
 

powered by: WebSVN 2.1.0

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