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

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_2_x/] [or1ksim/] [bpb/] [branch_predict.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 cvs
/* branch_predict.c -- branch prediction simulation
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
/* Branch prediction functions.
21
   At the moment this functions only simulate functionality of branch
22
   prediction and do not influence on fetche/decode/execute stages.
23
   They are here only to verify performance of various branch
24
   prediction configurations.
25
 
26
 */
27
 
28
#include <stdio.h>
29
#include <string.h>
30
#include <errno.h>
31
#include <stdarg.h>
32
 
33 1350 nogj
#include "config.h"
34
 
35
#ifdef HAVE_INTTYPES_H
36
#include <inttypes.h>
37
#endif
38
 
39
#include "port.h"
40
#include "arch.h"
41 2 cvs
#include "branch_predict.h"
42 1350 nogj
#include "abstract.h"
43 1344 nogj
#include "opcode/or32.h"
44 2 cvs
#include "stats.h"
45 102 lampret
#include "sim-config.h"
46 2 cvs
 
47
/* Branch prediction buffer */
48
 
49
/* Length of BPB */
50 28 lampret
#define BPB_LEN 64
51 2 cvs
 
52
/* Number of BPB ways (1, 2, 3 etc.). */
53 6 lampret
#define BPB_WAYS 1
54 2 cvs
 
55
/* Number of prediction states (2, 4, 8 etc.). */
56 28 lampret
#define BPB_PSTATES 2
57 2 cvs
 
58
/* Number of usage states (2, 3, 4 etc.). */
59 28 lampret
#define BPB_USTATES 2
60 2 cvs
 
61
/* branch prediction buffer entry */
62
struct bpb_entry {
63
        struct {
64 1350 nogj
                oraddr_t addr;          /* address of a branch insn */
65 2 cvs
                int taken;              /* taken == 1, not taken == 0  OR */
66
                                        /* strongly taken == 3, taken == 2,
67
                                           not taken == 1, strongly not taken == 0 */
68
                int lru;                /* least recently == 0 */
69
        } way[BPB_WAYS];
70
} bpb[BPB_LEN];
71
 
72 6 lampret
void bpb_info()
73
{
74 541 markom
        if (!config.bpb.enabled) {
75 997 markom
                PRINTF("BPB not simulated. Check -bpb option.\n");
76 102 lampret
                return;
77
        }
78
 
79 997 markom
        PRINTF("BPB %d bytes: ", BPB_LEN * BPB_WAYS * (BPB_PSTATES + BPB_USTATES) / 8);
80
        PRINTF("%d ways, %d sets, %d bits/prediction\n", BPB_WAYS, BPB_LEN, BPB_PSTATES + BPB_USTATES);
81 6 lampret
}
82
 
83 2 cvs
/* First check if branch is already in the cache and if it is:
84
    - increment BPB hit stats,
85
    - set 'lru' at this way to BPB_USTATES - 1 and
86
      decrement 'lru' of other ways unless they have reached 0,
87
    - increment correct/incorrect stats according to BPB 'taken' field
88
      and 'taken' variable,
89
    - increment or decrement BPB taken field according to 'taken' variable
90
   and if not:
91
    - increment BPB miss stats
92
    - find lru way and entry and replace old address with 'addr' and
93
      'taken' field with (BPB_PSTATES/2 - 1) + 'taken'
94
    - set 'lru' with BPB_USTATES - 1 and decrement 'lru' of other
95
      ways unless they have reached 0
96
*/
97
 
98 1350 nogj
void bpb_update(oraddr_t addr, int taken)
99 2 cvs
{
100
        int entry, way = -1;
101
        int i;
102 102 lampret
 
103
        /* BPB simulation enabled/disabled. */
104 541 markom
        if (!config.bpb.enabled)
105 102 lampret
                return;
106
 
107 2 cvs
        /* Calc entry. */
108
        entry = addr % BPB_LEN;
109
 
110
        /* Scan all ways and try to find our addr. */
111
        for (i = 0; i < BPB_WAYS; i++)
112
                if (bpb[entry].way[i].addr == addr)
113
                        way = i;
114
 
115
        /* Did we find our cached branch? */
116
        if (way >= 0) { /* Yes, we did. */
117 1243 hpanther
                or1k_mstats.bpb.hit++;
118 2 cvs
 
119
                for (i = 0; i < BPB_WAYS; i++)
120
                        if (bpb[entry].way[i].lru)
121
                                bpb[entry].way[i].lru--;
122
                bpb[entry].way[way].lru = BPB_USTATES - 1;
123
 
124
                if (bpb[entry].way[way].taken / (BPB_PSTATES / 2) == taken)
125 1243 hpanther
                        or1k_mstats.bpb.correct++;
126 2 cvs
                else
127 1243 hpanther
                        or1k_mstats.bpb.incorrect++;
128 2 cvs
 
129
                if (taken && (bpb[entry].way[way].taken < BPB_PSTATES - 1))
130
                        bpb[entry].way[way].taken++;
131
                else
132
                if (!taken && (bpb[entry].way[way].taken))
133
                        bpb[entry].way[way].taken--;
134
        }
135
        else {  /* No, we didn't. */
136
                int minlru = BPB_USTATES - 1;
137
                int minway = 0;
138
 
139 1243 hpanther
                or1k_mstats.bpb.miss++;
140 2 cvs
 
141
                for (i = 0; i < BPB_WAYS; i++)
142
                        if (bpb[entry].way[i].lru < minlru)
143
                                minway = i;
144
 
145
                bpb[entry].way[minway].addr = addr;
146
                bpb[entry].way[minway].taken = (BPB_PSTATES / 2 - 1) + taken;
147
                for (i = 0; i < BPB_WAYS; i++)
148
                        if (bpb[entry].way[i].lru)
149
                                bpb[entry].way[i].lru--;
150
                bpb[entry].way[minway].lru = BPB_USTATES - 1;
151
        }
152
}
153
 
154
/* Branch target instruction cache */
155
 
156
/* Length of BTIC */
157 6 lampret
#define BTIC_LEN 128
158 2 cvs
 
159
/* Number of BTIC ways (1, 2, 3 etc.). */
160
#define BTIC_WAYS 2
161
 
162
/* Number of usage states (2, 3, 4 etc.). */
163
#define BTIC_USTATES 2
164
 
165 6 lampret
/* Target block size in bytes. */
166
#define BTIC_BLOCKSIZE 4
167
 
168 2 cvs
struct btic_entry {
169
        struct {
170 1350 nogj
                oraddr_t addr;          /* cached target address of a branch */
171 2 cvs
                int lru;                /* least recently used */
172
                char *insn;             /* cached insn at target address (not used currently) */
173
        } way[BTIC_WAYS];
174
} btic[BTIC_LEN];
175
 
176 6 lampret
void btic_info()
177
{
178 541 markom
        if (!config.bpb.btic) {
179 997 markom
                PRINTF("BTIC not simulated. Check --btic option.\n");
180 102 lampret
                return;
181
        }
182
 
183 997 markom
        PRINTF("BTIC %d bytes: ", BTIC_LEN * BTIC_WAYS * (BTIC_USTATES + BTIC_BLOCKSIZE * 8) / 8);
184
        PRINTF("%d ways, %d sets, %d bits/target\n", BTIC_WAYS, BTIC_LEN, BTIC_USTATES + BTIC_BLOCKSIZE * 8);
185 6 lampret
}
186
 
187 2 cvs
/* First check if target addr is already in the cache and if it is:
188
    - increment BTIC hit stats,
189
    - set 'lru' at this way to BTIC_USTATES - 1 and
190
      decrement 'lru' of other ways unless they have reached 0,
191
   and if not:
192
    - increment BTIC miss stats
193
    - find lru way and entry and replace old address with 'addr' and
194
      'insn' with NULL
195
    - set 'lru' with BTIC_USTATES - 1 and decrement 'lru' of other
196
      ways unless they have reached 0
197
*/
198
 
199 1350 nogj
void btic_update(oraddr_t targetaddr)
200 2 cvs
{
201
        int entry, way = -1;
202
        int i;
203
 
204 102 lampret
        /* BTIC simulation enabled/disabled. */
205 541 markom
        if (!config.bpb.btic)
206 102 lampret
                return;
207
 
208 2 cvs
        /* Calc entry. */
209
        entry = targetaddr % BTIC_LEN;
210
 
211
        /* Scan all ways and try to find our addr. */
212
        for (i = 0; i < BTIC_WAYS; i++)
213
                if (btic[entry].way[i].addr == targetaddr)
214
                        way = i;
215
 
216
        /* Did we find our cached branch? */
217
        if (way >= 0) { /* Yes, we did. */
218 1243 hpanther
                or1k_mstats.btic.hit++;
219 2 cvs
 
220
                for (i = 0; i < BTIC_WAYS; i++)
221
                        if (btic[entry].way[i].lru)
222
                                btic[entry].way[i].lru--;
223
                btic[entry].way[way].lru = BTIC_USTATES - 1;
224
        }
225
        else {  /* No, we didn't. */
226
                int minlru = BTIC_USTATES - 1;
227
                int minway = 0;
228
 
229 1243 hpanther
                or1k_mstats.btic.miss++;
230 2 cvs
 
231
                for (i = 0; i < BTIC_WAYS; i++)
232
                        if (btic[entry].way[i].lru < minlru)
233
                                minway = i;
234
 
235
                btic[entry].way[minway].addr = targetaddr;
236
                btic[entry].way[minway].insn = NULL;
237
                for (i = 0; i < BTIC_WAYS; i++)
238
                        if (btic[entry].way[i].lru)
239
                                btic[entry].way[i].lru--;
240
                btic[entry].way[minway].lru = BTIC_USTATES - 1;
241
        }
242
}
243 1358 nogj
 
244
/*----------------------------------------------------[ BPB configuration ]---*/
245
void bpb_enabled(union param_val val, void *dat)
246
{
247
  config.bpb.enabled = val.int_val;
248
}
249
 
250
void bpb_btic(union param_val val, void *dat)
251
{
252
  config.bpb.btic = val.int_val;
253
}
254
 
255
void bpb_sbp_bnf_fwd(union param_val val, void *dat)
256
{
257
  config.bpb.sbp_bnf_fwd = val.int_val;
258
}
259
 
260
void bpb_sbp_bf_fwd(union param_val val, void *dat)
261
{
262
  config.bpb.sbp_bf_fwd = val.int_val;
263
}
264
 
265
void bpb_missdelay(union param_val val, void *dat)
266
{
267
  config.bpb.missdelay = val.int_val;
268
}
269
 
270
void bpb_hitdelay(union param_val val, void *dat)
271
{
272
  config.bpb.hitdelay = val.int_val;
273
}
274
 
275
void reg_bpb_sec(void)
276
{
277
  struct config_section *sec = reg_config_sec("bpb", NULL, NULL);
278
 
279
  reg_config_param(sec, "enabled", paramt_int, bpb_enabled);
280
  reg_config_param(sec, "btic", paramt_int, bpb_btic);
281
  reg_config_param(sec, "sbp_bnf_fwd", paramt_int, bpb_sbp_bnf_fwd);
282
  reg_config_param(sec, "sbp_bf_fwd", paramt_int, bpb_sbp_bf_fwd);
283
  reg_config_param(sec, "missdelay", paramt_int, bpb_missdelay);
284
  reg_config_param(sec, "hitdelay", paramt_int, bpb_hitdelay);
285
}

powered by: WebSVN 2.1.0

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