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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [cpu/] [common/] [stats.c] - Diff between revs 1731 and 1748

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

Rev 1731 Rev 1748
Line 1... Line 1...
/* 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
 
 
This file is part of OpenRISC 1000 Architectural Simulator.
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
 
 
This program is free software; you can redistribute it and/or modify
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
it under the terms of the GNU General Public License as published by
 
the Free Software Foundation; either version 2 of the License, or
 
(at your option) any later version.
 
 
 
This program is distributed in the hope that it will be useful,
 
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
GNU General Public License for more details.
 
 
 
You should have received a copy of the GNU General Public License
 
along with this program; if not, write to the Free Software
 
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 
 
#include <stdio.h>
 
#include <ctype.h>
 
#include <string.h>
 
 
 
#include "config.h"
   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
 
   Software Foundation; either version 3 of the License, or (at your option)
 
   any later version.
 
 
#ifdef HAVE_INTTYPES_H
   This program is distributed in the hope that it will be useful, but WITHOUT
#include <inttypes.h>
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#endif
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 
   more details.
 
 
 
   You should have received a copy of the GNU General Public License along
 
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 
/* This program is commented throughout in a fashion suitable for processing
 
   with Doxygen. */
 
 
 
 
 
/* Autoconf and/or portability configuration */
 
#include "config.h"
#include "port.h"
#include "port.h"
#include "arch.h"
 
#include "abstract.h"
/* Package includes */
 
#include "stats.h"
#include "sim-config.h"
#include "sim-config.h"
#include "spr_defs.h"
#include "icache-model.h"
#include "opcode/or32.h"
#include "spr-defs.h"
#include "execute.h"
#include "execute.h"
#include "sprs.h"
 
#include "debug.h"
 
#include "stats.h"
 
#include "icache_model.h"
 
 
 
struct branchstat {
 
 
#define DSTATS_LEN      3000
 
#define SSTATS_LEN      300
 
#define FSTATS_LEN      200
 
#define RAW_RANGE       1000
 
 
 
/* Used by safe division - increment divisor by one if it is zero */
 
#define SD(X) (X != 0 ? X : 1)
 
 
 
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 */
const char func_unit_str[30][30] = { "unknown", "exception", "arith", "shift", "compare",
static const char func_unit_str[30][30] = {
  "branch", "jump", "load", "store", "movimm", "move", "extend", "nop", "mac" };
  "unknown",
 
  "exception",
struct dstats_entry dstats[DSTATS_LEN];       /* dependency stats */
  "arith",
struct sstats_entry sstats[SSTATS_LEN];       /* single stats */
  "shift",
struct fstats_entry fstats[FSTATS_LEN];       /* functional units stats */
  "compare",
struct mstats_entry or1k_mstats = {0};             /* misc units stats */
  "branch",
struct cachestats_entry ic_stats = {0};       /* instruction cache stats */
  "jump",
struct cachestats_entry dc_stats = {0};       /* data cache stats */
  "load",
struct immustats_entry immu_stats = {0};      /* insn mmu stats */
  "store",
struct dmmustats_entry dmmu_stats = {0};      /* data mmu stats */
  "movimm",
struct raw_stats raw_stats;                   /* RAW hazard stats */
  "move",
 
  "extend",
 
  "nop",
 
  "mac"
 
};
 
 
 
struct dstats_entry
 
{
 
  int insn1;
 
  int insn2;
 
  int cnt_dynamic;
 
  int depend;
 
};                              /*!< double stats */
 
 
 
struct sstats_entry
 
{
 
  int insn;
 
  int cnt_dynamic;
 
};                              /*!< single stats */
 
 
 
struct fstats_entry
 
{
 
  enum insn_type insn1;
 
  enum insn_type insn2;
 
  int cnt_dynamic;
 
  int depend;
 
};                              /*!< functional units stats */
 
 
void addsstats(int item, int cnt_dynamic)
struct raw_stats
 
{
 
  int reg[64];
 
  int range[RAW_RANGE];
 
};                              /*!< RAW hazard stats */
 
 
 
/* Globally visible statistics data. Renamed mstats to or1k_mstats because Mac
 
   OS X has a lib function called mstats */
 
struct mstats_entry      or1k_mstats = { 0 };    /*!< misc units stats */
 
struct cachestats_entry  ic_stats    = { 0 };    /*!< instruction cache stats */
 
struct cachestats_entry  dc_stats    = { 0 };    /*!< data cache stats */
 
struct immustats_entry   immu_stats  = { 0 };    /*!< insn MMU stats */
 
struct dmmustats_entry   dmmu_stats  = { 0 };    /*!< data MMU stats */
 
 
 
/* Statistics data strutures used just here */
 
static struct dstats_entry  dstats[DSTATS_LEN]; /*!< dependency stats */
 
static struct sstats_entry  sstats[SSTATS_LEN]; /*!< single stats */
 
static struct fstats_entry  fstats[FSTATS_LEN]; /*!< func units stats */
 
static struct raw_stats     raw_stats;          /*!< RAW hazard stats */
 
 
 
 
 
void
 
addsstats (int item, int cnt_dynamic)
{
{
  int i = 0;
  int i = 0;
 
 
  while(sstats[i].insn != item && sstats[i].insn >= 0 && i < SSTATS_LEN) i++;
  while (sstats[i].insn != item && sstats[i].insn >= 0 && i < SSTATS_LEN)
 
    i++;
 
 
  if (i >= SSTATS_LEN - 1) return;
  if (i >= SSTATS_LEN - 1)
 
    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 adddstats(int item1, int item2, int cnt_dynamic, int depend)
void
 
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) && (i < DSTATS_LEN) && dstats[i].insn1 >= 0) i++;
  while ((dstats[i].insn1 != item1 || dstats[i].insn2 != item2)
 
         && (i < DSTATS_LEN) && dstats[i].insn1 >= 0)
 
    i++;
 
 
  if (i >= DSTATS_LEN - 1) return;
  if (i >= DSTATS_LEN - 1)
 
    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 addfstats(enum insn_type item1, enum insn_type item2, int cnt_dynamic, int depend)
void
 
addfstats (enum insn_type item1, enum insn_type item2, int cnt_dynamic,
 
           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) &&
         (fstats[i].insn1 != it_unknown) && (i < FSTATS_LEN))
        (i < FSTATS_LEN))
 
    i++;
    i++;
 
 
  if (i >= FSTATS_LEN - 1) return;
  if (i >= FSTATS_LEN - 1)
 
    return;
 
 
  if ((fstats[i].insn1 == item1) &&
  if ((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;
  }
  }
  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 initstats()
void
 
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;
Line 133... Line 203...
  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));
}
}
 
 
void printotherstats(int which)
static void
 
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];
Line 152... Line 224...
    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, (bf.taken * 100) / SD(bf_all));
      PRINTF ("bnf: %d (%ld%%) taken,", bf.taken,
    PRINTF(" %d (%ld%%) not taken,", bf.nottaken, (bf.nottaken * 100) / SD(bf_all));
              (bf.taken * 100) / SD (bf_all));
    PRINTF(" %d (%ld%%) forward,", bf.forward, (bf.forward * 100) / SD(bf_all));
      PRINTF (" %d (%ld%%) not taken,", bf.nottaken,
    PRINTF(" %d (%ld%%) backward\n", bf.backward, (bf.backward * 100) / SD(bf_all));
              (bf.nottaken * 100) / SD (bf_all));
    PRINTF("bf: %d (%ld%%) taken,", bnf.taken, (bnf.taken * 100) / SD(bnf_all));
      PRINTF (" %d (%ld%%) forward,", bf.forward,
    PRINTF(" %d (%ld%%) not taken,", bnf.nottaken, (bnf.nottaken * 100) / SD(bnf_all));
              (bf.forward * 100) / SD (bf_all));
    PRINTF(" %d (%ld%%) forward,", bnf.forward, (bnf.forward * 100) / SD(bnf_all));
      PRINTF (" %d (%ld%%) backward\n", bf.backward,
    PRINTF(" %d (%ld%%) backward\n", bnf.backward, (bnf.backward * 100) / SD(bnf_all));
              (bf.backward * 100) / SD (bf_all));
 
      PRINTF ("bf: %d (%ld%%) taken,", bnf.taken,
    PRINTF("StaticBP bnf(%s): correct %ld%%\n", config.bpb.sbp_bnf_fwd ? "forward" : "backward",
              (bnf.taken * 100) / SD (bnf_all));
      (or1k_mstats.bnf[0][config.bpb.sbp_bnf_fwd] * 100) / SD(bnf_all));
      PRINTF (" %d (%ld%%) not taken,", bnf.nottaken,
    PRINTF("StaticBP bf(%s): correct %ld%%\n", config.bpb.sbp_bf_fwd ? "forward" : "backward",
              (bnf.nottaken * 100) / SD (bnf_all));
      (or1k_mstats.bnf[1][config.bpb.sbp_bf_fwd] * 100) / SD(bf_all));
      PRINTF (" %d (%ld%%) forward,", bnf.forward,
    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.miss);
              (bnf.forward * 100) / SD (bnf_all));
  } else
      PRINTF (" %d (%ld%%) backward\n", bnf.backward,
 
              (bnf.backward * 100) / SD (bnf_all));
 
 
 
      PRINTF ("StaticBP bnf(%s): correct %ld%%\n",
 
              config.bpb.sbp_bnf_fwd ? "forward" : "backward",
 
              (or1k_mstats.bnf[0][config.bpb.sbp_bnf_fwd] * 100) /
 
              SD (bnf_all));
 
      PRINTF ("StaticBP bf(%s): correct %ld%%\n",
 
              config.bpb.sbp_bf_fwd ? "forward" : "backward",
 
              (or1k_mstats.bnf[1][config.bpb.sbp_bf_fwd] * 100) /
 
              SD (bf_all));
 
      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.miss);
 
    }
 
  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, (or1k_mstats.btic.hit * 100) / SD(or1k_mstats.btic.hit + or1k_mstats.btic.miss), or1k_mstats.btic.miss);
    {
  } else
      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.miss),
 
              or1k_mstats.btic.miss);
 
    }
 
  else
    PRINTF("BTIC simulation disabled. Enabled it to see BTIC analysis\n");
    PRINTF("BTIC simulation disabled. Enabled it to see BTIC analysis\n");
 
 
  if(ic_state->enabled) {
  if (ic_state->enabled)
    PRINTF("IC read:  hit %d(%d%%), miss %d\n", ic_stats.readhit, (ic_stats.readhit * 100) / SD(ic_stats.readhit + ic_stats.readmiss), ic_stats.readmiss);
    {
  } else
      PRINTF ("IC read:  hit %d(%d%%), miss %d\n", ic_stats.readhit,
 
              (ic_stats.readhit * 100) / SD (ic_stats.readhit +
 
                                             ic_stats.readmiss),
 
              ic_stats.readmiss);
 
    }
 
  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, (dc_stats.readhit * 100) / SD(dc_stats.readhit + dc_stats.readmiss), dc_stats.readmiss);
    {
    PRINTF("DC write: hit %d(%d%%), miss %d\n", dc_stats.writehit, (dc_stats.writehit * 100) / SD(dc_stats.writehit + dc_stats.writemiss), dc_stats.writemiss);
      PRINTF ("DC read:  hit %d(%d%%), miss %d\n", dc_stats.readhit,
  } else
              (dc_stats.readhit * 100) / SD (dc_stats.readhit +
 
                                             dc_stats.readmiss),
 
              dc_stats.readmiss);
 
      PRINTF ("DC write: hit %d(%d%%), miss %d\n", dc_stats.writehit,
 
              (dc_stats.writehit * 100) / SD (dc_stats.writehit +
 
                                              dc_stats.writemiss),
 
              dc_stats.writemiss);
 
    }
 
  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, (immu_stats.fetch_tlbhit * 100) / SD(immu_stats.fetch_tlbhit + immu_stats.fetch_tlbmiss), immu_stats.fetch_tlbmiss);
    {
  } else
      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_tlbmiss),
 
              immu_stats.fetch_tlbmiss);
 
    }
 
  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, (dmmu_stats.loads_tlbhit * 100) / SD(dmmu_stats.loads_tlbhit + dmmu_stats.loads_tlbmiss), dmmu_stats.loads_tlbmiss);
    {
  } else
      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_tlbmiss),
 
              dmmu_stats.loads_tlbmiss);
 
    }
 
  else
    PRINTF("No DMMU. Set UPR[DMP]\n");
    PRINTF("No DMMU. Set UPR[DMP]\n");
 
 
  PRINTF("Additional LOAD CYCLES: %u  STORE CYCLES: %u\n", runtime.sim.loadcycles, runtime.sim.storecycles);
  PRINTF ("Additional LOAD CYCLES: %u  STORE CYCLES: %u\n",
 
          runtime.sim.loadcycles, runtime.sim.storecycles);
}
}
 
 
void printstats(int which)
void
 
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("Hazard analysis disabled. Enable it to see analysis results.\n");
    {
 
      PRINTF
 
        ("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:
Line 219... Line 339...
    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), sstats[i].cnt_dynamic, (sstats[i].cnt_dynamic * 100.)/SD(all));
          PRINTF ("  %-15s used %6dx (%5.1f%%)\n", insn_name (sstats[i].insn),
 
                  sstats[i].cnt_dynamic,
 
                  (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), insn_name(dstats[i].insn2));
            sprintf (temp, "%s, %s ", insn_name (dstats[i].insn1),
        PRINTF("  %-30s %6dx (%5.1f%%)", temp, dstats[i].cnt_dynamic, (dstats[i].cnt_dynamic * 100.)/SD(all));
                     insn_name (dstats[i].insn2));
        PRINTF("   depend: %5.1f%%\n", (dstats[i].depend * 100.) / dstats[i].cnt_dynamic);
            PRINTF ("  %-30s %6dx (%5.1f%%)", temp, dstats[i].cnt_dynamic,
 
                    (dstats[i].cnt_dynamic * 100.) / SD (all));
 
            PRINTF ("   depend: %5.1f%%\n",
 
                    (dstats[i].depend * 100.) / dstats[i].cnt_dynamic);
      }
      }
 
 
    PRINTF("%d instructions (dynamic, dependency stats)  depend: %d%%\n", all, (dependall * 100) / SD(all));
      PRINTF ("%d instructions (dynamic, dependency stats)  depend: %d%%\n",
 
              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], func_unit_str[fstats[i].insn2]);
            sprintf (temp, "%s, %s", func_unit_str[fstats[i].insn1],
        PRINTF("  %-30s %6dx (%5.1f%%)", temp, fstats[i].cnt_dynamic, (fstats[i].cnt_dynamic * 100.)/SD(all));
                     func_unit_str[fstats[i].insn2]);
        PRINTF("   depend: %5.1f%%\n", (fstats[i].depend * 100.) / fstats[i].cnt_dynamic);
            PRINTF ("  %-30s %6dx (%5.1f%%)", temp, fstats[i].cnt_dynamic,
      }
                    (fstats[i].cnt_dynamic * 100.) / SD (all));
    PRINTF ("%d instructions (dynamic, functional units stats)  depend: %d%%\n\n", all, (dependall * 100) / SD(all));
            PRINTF ("   depend: %5.1f%%\n",
 
                    (fstats[i].depend * 100.) / fstats[i].cnt_dynamic);
 
          }
 
      PRINTF
 
        ("%d instructions (dynamic, functional units stats)  depend: %d%%\n\n",
 
         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 < MAX_RANGE); i++)
    for(i = 0; (i < MAX_RANGE); i++)
      PRINTF("  Register set and reused in %d. cycle: %d cases\n", i, raw_stats.range[i]);
        PRINTF ("  Register set and reused in %d. cycle: %d cases\n", 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", sbuf_total_cyc,
          PRINTF ("Number of total memory store cycles: %i/%lli\n",
 
                  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", sbuf_wait_cyc);
          PRINTF ("Number of cycles waiting for memory stores: %i\n",
      PRINTF ("Number of memory cycles spared: %i\n", sbuf_total_cyc - sbuf_wait_cyc);
                  sbuf_wait_cyc);
      PRINTF ("Store speedup %3.2f%%, total speedup %3.2f%%\n", 100.*(sbuf_total_cyc - sbuf_wait_cyc)/sbuf_total_cyc,
          PRINTF ("Number of memory cycles spared: %i\n",
                                                                100.*(sbuf_total_cyc - sbuf_wait_cyc) / (runtime.sim.cycles + sbuf_total_cyc - sbuf_wait_cyc));
                  sbuf_total_cyc - sbuf_wait_cyc);
    } else
          PRINTF ("Store speedup %3.2f%%, total speedup %3.2f%%\n",
      PRINTF ("Store buffer analysis disabled. Enable it to see analysis results.\n");
                  100. * (sbuf_total_cyc - sbuf_wait_cyc) / sbuf_total_cyc,
 
                  100. * (sbuf_total_cyc -
 
                          sbuf_wait_cyc) / (runtime.sim.cycles +
 
                                            sbuf_total_cyc - sbuf_wait_cyc));
 
        }
 
      else
 
        PRINTF
 
          ("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;
  }
  }
  #if 0
 
    PRINTF("Byte ADD: %d instructions\n", or1k_mstats.byteadd);
 
  #endif
 
}
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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