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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [cpu/] [common/] [stats.c] - Blame information for rev 1782

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 cvs
/* stats.c -- Various statistics about instruction scheduling etc.
2
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
3
 
4
This file is part of OpenRISC 1000 Architectural Simulator.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
#include <stdio.h>
21
#include <ctype.h>
22
#include <string.h>
23
 
24 1350 nogj
#include "config.h"
25
 
26
#ifdef HAVE_INTTYPES_H
27
#include <inttypes.h>
28
#endif
29
 
30
#include "port.h"
31
#include "arch.h"
32 2 cvs
#include "abstract.h"
33 102 lampret
#include "sim-config.h"
34 518 markom
#include "sprs.h"
35 102 lampret
#include "spr_defs.h"
36 1308 phoenix
#include "execute.h"
37
#include "opcode/or32.h"
38
#include "debug.h"
39 1344 nogj
#include "stats.h"
40 30 lampret
 
41 535 markom
struct branchstat {
42
        int taken;
43
        int nottaken;
44
        int forward;
45
        int backward;
46
};
47 2 cvs
 
48 535 markom
/* See also enum insn_type in abstract.h */
49
const char func_unit_str[30][30] = { "unknown", "exception", "arith", "shift", "compare",
50
  "branch", "jump", "load", "store", "movimm", "move", "extend", "nop", "mac" };
51
 
52 694 markom
struct dstats_entry dstats[DSTATS_LEN];       /* dependency stats */
53
struct sstats_entry sstats[SSTATS_LEN];       /* single stats */
54
struct fstats_entry fstats[FSTATS_LEN];       /* functional units stats */
55 1244 hpanther
struct mstats_entry or1k_mstats = {0};             /* misc units stats */
56 692 markom
struct cachestats_entry ic_stats = {0};       /* instruction cache stats */
57
struct cachestats_entry dc_stats = {0};       /* data cache stats */
58
struct immustats_entry immu_stats = {0};      /* insn mmu stats */
59
struct dmmustats_entry dmmu_stats = {0};      /* data mmu stats */
60
struct raw_stats raw_stats = {0};             /* RAW hazard stats */
61 2 cvs
 
62
/* Dependency */
63
 
64
int check_depend()
65 532 markom
{
66 479 markom
  debug(5,"check_depend\n");
67 138 markom
  return depend_operands(&icomplet[0], &iqueue[0]);
68 2 cvs
}
69
 
70 535 markom
void addsstats(int item, int cnt_dynamic)
71 2 cvs
{
72 532 markom
  int i = 0;
73
 
74 535 markom
  while(sstats[i].insn != item && sstats[i].insn >= 0 && i < SSTATS_LEN) i++;
75 2 cvs
 
76 532 markom
  if (i >= SSTATS_LEN - 1) return;
77
 
78 535 markom
  if (sstats[i].insn >= 0) {
79 532 markom
    sstats[i].cnt_dynamic += cnt_dynamic;
80 535 markom
  } else {
81
    sstats[i].insn = item;
82 532 markom
    sstats[i].cnt_dynamic = cnt_dynamic;
83
  }
84 2 cvs
}
85
 
86 535 markom
void adddstats(int item1, int item2, int cnt_dynamic, int depend)
87 2 cvs
{
88 532 markom
  int i = 0;
89
 
90 702 ivang
  debug(7,"adddstats start\n");
91 2 cvs
 
92 535 markom
  while((dstats[i].insn1 != item1 || dstats[i].insn2 != item2) && (i < DSTATS_LEN) && dstats[i].insn1 >= 0) i++;
93 2 cvs
 
94 532 markom
  if (i >= DSTATS_LEN - 1) return;
95
 
96 535 markom
  if (dstats[i].insn1 >= 0) {
97 532 markom
    dstats[i].cnt_dynamic += cnt_dynamic;
98
    dstats[i].depend += depend;
99 535 markom
  } else {
100
    dstats[i].insn1 = item1;
101
    dstats[i].insn2 = item2;
102 532 markom
    dstats[i].cnt_dynamic = cnt_dynamic;
103
    dstats[i].depend = depend;
104
  }
105 2 cvs
}
106
 
107
void addfstats(enum insn_type item1, enum insn_type item2, int cnt_dynamic, int depend)
108
{
109 532 markom
  int i = 0;
110
 
111
  while(((fstats[i].insn1 != item1) || (fstats[i].insn2 != item2)) &&
112
        (fstats[i].insn1 != it_unknown) &&
113
        (i < FSTATS_LEN))
114
    i++;
115 2 cvs
 
116 532 markom
  if (i >= FSTATS_LEN - 1) return;
117
 
118
  if ((fstats[i].insn1 == item1) &&
119
      (fstats[i].insn2 == item2)) {
120
    fstats[i].cnt_dynamic += cnt_dynamic;
121
    fstats[i].depend += depend;
122
  }
123
  else {
124
    fstats[i].insn1 = item1;
125
    fstats[i].insn2 = item2;
126
    fstats[i].cnt_dynamic = cnt_dynamic;
127
    fstats[i].depend = depend;
128
  }
129 2 cvs
}
130
 
131
void initstats()
132
{
133 535 markom
  int i;
134 532 markom
  memset(sstats, 0, sizeof(sstats));
135 1323 phoenix
  for (i = 0; i < SSTATS_LEN; i++)
136 535 markom
    sstats[i].insn = -1;
137 532 markom
  memset(dstats, 0, sizeof(dstats));
138 535 markom
  for (i = 0; i < DSTATS_LEN; i++)
139
    dstats[i].insn1 = dstats[i].insn2 = -1;
140 532 markom
  memset(fstats, 0, sizeof(fstats));
141 1244 hpanther
  memset(&or1k_mstats, 0, sizeof(or1k_mstats));
142 532 markom
  memset(&ic_stats, 0, sizeof(ic_stats));
143
  memset(&dc_stats, 0, sizeof(dc_stats));
144
  memset(&raw_stats, 0, sizeof(raw_stats));
145 2 cvs
}
146
 
147 535 markom
void printotherstats(int which)
148 2 cvs
{
149 997 markom
  PRINTF ("\n");
150 541 markom
  if (config.bpb.enabled) {
151 535 markom
    struct branchstat bf;
152
    struct branchstat bnf;
153
    long bf_all, bnf_all;
154 1244 hpanther
    bf.taken = or1k_mstats.bf[1][0] + or1k_mstats.bf[1][1];
155
    bf.nottaken = or1k_mstats.bf[0][0] + or1k_mstats.bf[0][1];
156
    bf.forward = or1k_mstats.bf[0][1] + or1k_mstats.bf[1][1];
157
    bf.backward = or1k_mstats.bf[0][0] + or1k_mstats.bf[1][0];
158 535 markom
    bf_all = bf.forward + bf.backward;
159
 
160 1244 hpanther
    bnf.taken = or1k_mstats.bnf[1][0] + or1k_mstats.bf[1][1];
161
    bnf.nottaken = or1k_mstats.bnf[0][0] + or1k_mstats.bf[0][1];
162
    bnf.forward = or1k_mstats.bnf[0][1] + or1k_mstats.bf[1][1];
163
    bnf.backward = or1k_mstats.bnf[0][0] + or1k_mstats.bf[1][0];
164 535 markom
    bnf_all = bnf.forward + bnf.backward;
165
 
166 1308 phoenix
    PRINTF("bnf: %d (%ld%%) taken,", bf.taken, (bf.taken * 100) / SD(bf_all));
167
    PRINTF(" %d (%ld%%) not taken,", bf.nottaken, (bf.nottaken * 100) / SD(bf_all));
168
    PRINTF(" %d (%ld%%) forward,", bf.forward, (bf.forward * 100) / SD(bf_all));
169
    PRINTF(" %d (%ld%%) backward\n", bf.backward, (bf.backward * 100) / SD(bf_all));
170
    PRINTF("bf: %d (%ld%%) taken,", bnf.taken, (bnf.taken * 100) / SD(bnf_all));
171
    PRINTF(" %d (%ld%%) not taken,", bnf.nottaken, (bnf.nottaken * 100) / SD(bnf_all));
172
    PRINTF(" %d (%ld%%) forward,", bnf.forward, (bnf.forward * 100) / SD(bnf_all));
173
    PRINTF(" %d (%ld%%) backward\n", bnf.backward, (bnf.backward * 100) / SD(bnf_all));
174 535 markom
 
175 1308 phoenix
    PRINTF("StaticBP bnf(%s): correct %ld%%\n", config.bpb.sbp_bnf_fwd ? "forward" : "backward",
176 1244 hpanther
      (or1k_mstats.bnf[0][config.bpb.sbp_bnf_fwd] * 100) / SD(bnf_all));
177 1308 phoenix
    PRINTF("StaticBP bf(%s): correct %ld%%\n", config.bpb.sbp_bf_fwd ? "forward" : "backward",
178 1244 hpanther
      (or1k_mstats.bnf[1][config.bpb.sbp_bf_fwd] * 100) / SD(bf_all));
179
    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);
180 532 markom
  } else
181 997 markom
    PRINTF("BPB simulation disabled. Enable it to see BPB analysis\n");
182 102 lampret
 
183 541 markom
  if (config.bpb.btic) {
184 1244 hpanther
    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);
185 532 markom
  } else
186 997 markom
    PRINTF("BTIC simulation disabled. Enabled it to see BTIC analysis\n");
187 556 markom
 
188 692 markom
  if (config.ic.enabled) {
189 997 markom
    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);
190 532 markom
  } else
191 997 markom
    PRINTF("No ICache. Enable it to see IC results.\n");
192 532 markom
 
193 692 markom
  if (config.dc.enabled) {
194 997 markom
    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);
195
    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);
196 532 markom
  } else
197 997 markom
    PRINTF("No DCache. Enable it to see DC results.\n");
198 102 lampret
 
199 532 markom
  if (testsprbits(SPR_UPR, SPR_UPR_IMP)) {
200 997 markom
    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);
201 532 markom
  } else
202 997 markom
    PRINTF("No IMMU. Set UPR[IMP]\n");
203 102 lampret
 
204 532 markom
  if (testsprbits(SPR_UPR, SPR_UPR_DMP)) {
205 997 markom
    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);
206 532 markom
  } else
207 997 markom
    PRINTF("No DMMU. Set UPR[DMP]\n");
208 535 markom
 
209 997 markom
  PRINTF("Additional LOAD CYCLES: %u  STORE CYCLES: %u\n", runtime.sim.loadcycles, runtime.sim.storecycles);
210 102 lampret
}
211
 
212
void printstats(int which)
213
{
214 535 markom
  int i, all = 0, dependall = 0;
215
 
216 555 markom
  if (which > 1 && which <= 5 && !config.cpu.dependstats) {
217 997 markom
    PRINTF("Hazard analysis disabled. Enable it to see analysis results.\n");
218 535 markom
    return;
219
  }
220
 
221
  switch (which) {
222
  case 1:
223 997 markom
    PRINTF("stats 1: Misc stats\n");
224 532 markom
    printotherstats(which);
225 535 markom
    break;
226
  case 2:
227 997 markom
    PRINTF ("stats 2: Instruction usage\n");
228 535 markom
    for(i = 0; i < SSTATS_LEN; i++)
229
      all += sstats[i].cnt_dynamic;
230
 
231
    for(i = 0; i < SSTATS_LEN; i++)
232
      if (sstats[i].cnt_dynamic)
233 997 markom
        PRINTF("  %-15s used %6dx (%5.1f%%)\n", insn_name(sstats[i].insn), sstats[i].cnt_dynamic, (sstats[i].cnt_dynamic * 100.)/SD(all));
234 535 markom
 
235 997 markom
    PRINTF("%d instructions (dynamic, single stats)\n", all);
236 535 markom
    break;
237
 
238
  case 3:
239 997 markom
    PRINTF ("stats 3: Instruction dependencies\n");
240 535 markom
    for(i = 0; i < DSTATS_LEN; i++) {
241
      all += dstats[i].cnt_dynamic;
242
      dependall += dstats[i].depend;
243
    }
244
 
245
    for(i = 0; i < DSTATS_LEN; i++)
246
      if (dstats[i].cnt_dynamic) {
247
        char temp[100];
248
        sprintf(temp, "%s, %s ", insn_name(dstats[i].insn1), insn_name(dstats[i].insn2));
249 997 markom
        PRINTF("  %-30s %6dx (%5.1f%%)", temp, dstats[i].cnt_dynamic, (dstats[i].cnt_dynamic * 100.)/SD(all));
250
        PRINTF("   depend: %5.1f%%\n", (dstats[i].depend * 100.) / dstats[i].cnt_dynamic);
251 535 markom
      }
252
 
253 997 markom
    PRINTF("%d instructions (dynamic, dependency stats)  depend: %d%%\n", all, (dependall * 100) / SD(all));
254 535 markom
    break;
255
 
256
  case 4:
257 997 markom
    PRINTF("stats 4: Functional units dependencies\n");
258 535 markom
    for(i = 0; i < FSTATS_LEN; i++) {
259
      all += fstats[i].cnt_dynamic;
260
      dependall += fstats[i].depend;
261
    }
262
 
263
    for(i = 0; i < FSTATS_LEN; i++)
264
      if (fstats[i].cnt_dynamic) {
265
        char temp[100];
266
        sprintf(temp, "%s, %s", func_unit_str[fstats[i].insn1], func_unit_str[fstats[i].insn2]);
267 997 markom
        PRINTF("  %-30s %6dx (%5.1f%%)", temp, fstats[i].cnt_dynamic, (fstats[i].cnt_dynamic * 100.)/SD(all));
268
        PRINTF("   depend: %5.1f%%\n", (fstats[i].depend * 100.) / fstats[i].cnt_dynamic);
269 535 markom
      }
270 997 markom
    PRINTF ("%d instructions (dynamic, functional units stats)  depend: %d%%\n\n", all, (dependall * 100) / SD(all));
271 535 markom
    break;
272
 
273
  case 5:
274 997 markom
    PRINTF("stats 5: Raw register usage over time\n");
275 713 markom
#if RAW_RANGE_STATS
276
    for(i = 0; (i < MAX_RANGE); i++)
277 997 markom
      PRINTF("  Register set and reused in %d. cycle: %d cases\n", i, raw_stats.range[i]);
278 713 markom
#endif
279 535 markom
    break;
280 626 markom
  case 6:
281
    if (config.cpu.sbuf_len) {
282
      extern int sbuf_total_cyc, sbuf_wait_cyc;
283 997 markom
      PRINTF ("stats 6: Store buffer analysis\n");
284
      PRINTF ("Using store buffer of length %i.\n", config.cpu.sbuf_len);
285 1350 nogj
      PRINTF ("Number of total memory store cycles: %i/%lli\n", sbuf_total_cyc,
286
              runtime.sim.cycles + sbuf_total_cyc - sbuf_wait_cyc);
287 997 markom
      PRINTF ("Number of cycles waiting for memory stores: %i\n", sbuf_wait_cyc);
288
      PRINTF ("Number of memory cycles spared: %i\n", sbuf_total_cyc - sbuf_wait_cyc);
289
      PRINTF ("Store speedup %3.2f%%, total speedup %3.2f%%\n", 100.*(sbuf_total_cyc - sbuf_wait_cyc)/sbuf_total_cyc,
290 884 markom
                                                                100.*(sbuf_total_cyc - sbuf_wait_cyc) / (runtime.sim.cycles + sbuf_total_cyc - sbuf_wait_cyc));
291 626 markom
    } else
292 997 markom
      PRINTF ("Store buffer analysis disabled. Enable it to see analysis results.\n");
293 626 markom
    break;
294 535 markom
  default:
295 997 markom
    PRINTF ("Please specify a stats group (1-6).\n");
296 535 markom
    break;
297
  }
298
  #if 0
299 1244 hpanther
    PRINTF("Byte ADD: %d instructions\n", or1k_mstats.byteadd);
300 535 markom
  #endif
301 102 lampret
}

powered by: WebSVN 2.1.0

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