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 541

Go to most recent revision | 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
#include "branch_predict.h"
34
#include "abstract.h"
35
#include "stats.h"
36 102 lampret
#include "sim-config.h"
37 2 cvs
 
38
/* Branch prediction buffer */
39
 
40
/* Length of BPB */
41 28 lampret
#define BPB_LEN 64
42 2 cvs
 
43
/* Number of BPB ways (1, 2, 3 etc.). */
44 6 lampret
#define BPB_WAYS 1
45 2 cvs
 
46
/* Number of prediction states (2, 4, 8 etc.). */
47 28 lampret
#define BPB_PSTATES 2
48 2 cvs
 
49
/* Number of usage states (2, 3, 4 etc.). */
50 28 lampret
#define BPB_USTATES 2
51 2 cvs
 
52
/* branch prediction buffer entry */
53
struct bpb_entry {
54
        struct {
55
                unsigned long addr;     /* address of a branch insn */
56
                int taken;              /* taken == 1, not taken == 0  OR */
57
                                        /* strongly taken == 3, taken == 2,
58
                                           not taken == 1, strongly not taken == 0 */
59
                int lru;                /* least recently == 0 */
60
        } way[BPB_WAYS];
61
} bpb[BPB_LEN];
62
 
63 6 lampret
void bpb_info()
64
{
65 541 markom
        if (!config.bpb.enabled) {
66 102 lampret
                printf("BPB not simulated. Check -bpb option.\n");
67
                return;
68
        }
69
 
70 6 lampret
        printf("BPB %d bytes: ", BPB_LEN * BPB_WAYS * (BPB_PSTATES + BPB_USTATES) / 8);
71
        printf("%d ways, %d sets, %d bits/prediction\n", BPB_WAYS, BPB_LEN, BPB_PSTATES + BPB_USTATES);
72
}
73
 
74 2 cvs
/* First check if branch is already in the cache and if it is:
75
    - increment BPB hit stats,
76
    - set 'lru' at this way to BPB_USTATES - 1 and
77
      decrement 'lru' of other ways unless they have reached 0,
78
    - increment correct/incorrect stats according to BPB 'taken' field
79
      and 'taken' variable,
80
    - increment or decrement BPB taken field according to 'taken' variable
81
   and if not:
82
    - increment BPB miss stats
83
    - find lru way and entry and replace old address with 'addr' and
84
      'taken' field with (BPB_PSTATES/2 - 1) + 'taken'
85
    - set 'lru' with BPB_USTATES - 1 and decrement 'lru' of other
86
      ways unless they have reached 0
87
*/
88
 
89
void bpb_update(unsigned long addr, int taken)
90
{
91
        int entry, way = -1;
92
        int i;
93 102 lampret
 
94
        /* BPB simulation enabled/disabled. */
95 541 markom
        if (!config.bpb.enabled)
96 102 lampret
                return;
97
 
98 2 cvs
        /* Calc entry. */
99
        entry = addr % BPB_LEN;
100
 
101
        /* Scan all ways and try to find our addr. */
102
        for (i = 0; i < BPB_WAYS; i++)
103
                if (bpb[entry].way[i].addr == addr)
104
                        way = i;
105
 
106
        /* Did we find our cached branch? */
107
        if (way >= 0) { /* Yes, we did. */
108
                mstats.bpb.hit++;
109
 
110
                for (i = 0; i < BPB_WAYS; i++)
111
                        if (bpb[entry].way[i].lru)
112
                                bpb[entry].way[i].lru--;
113
                bpb[entry].way[way].lru = BPB_USTATES - 1;
114
 
115
                if (bpb[entry].way[way].taken / (BPB_PSTATES / 2) == taken)
116
                        mstats.bpb.correct++;
117
                else
118
                        mstats.bpb.incorrect++;
119
 
120
                if (taken && (bpb[entry].way[way].taken < BPB_PSTATES - 1))
121
                        bpb[entry].way[way].taken++;
122
                else
123
                if (!taken && (bpb[entry].way[way].taken))
124
                        bpb[entry].way[way].taken--;
125
        }
126
        else {  /* No, we didn't. */
127
                int minlru = BPB_USTATES - 1;
128
                int minway = 0;
129
 
130
                mstats.bpb.miss++;
131
 
132
                for (i = 0; i < BPB_WAYS; i++)
133
                        if (bpb[entry].way[i].lru < minlru)
134
                                minway = i;
135
 
136
                bpb[entry].way[minway].addr = addr;
137
                bpb[entry].way[minway].taken = (BPB_PSTATES / 2 - 1) + taken;
138
                for (i = 0; i < BPB_WAYS; i++)
139
                        if (bpb[entry].way[i].lru)
140
                                bpb[entry].way[i].lru--;
141
                bpb[entry].way[minway].lru = BPB_USTATES - 1;
142
        }
143
}
144
 
145
/* Branch target instruction cache */
146
 
147
/* Length of BTIC */
148 6 lampret
#define BTIC_LEN 128
149 2 cvs
 
150
/* Number of BTIC ways (1, 2, 3 etc.). */
151
#define BTIC_WAYS 2
152
 
153
/* Number of usage states (2, 3, 4 etc.). */
154
#define BTIC_USTATES 2
155
 
156 6 lampret
/* Target block size in bytes. */
157
#define BTIC_BLOCKSIZE 4
158
 
159 2 cvs
struct btic_entry {
160
        struct {
161
                unsigned long addr;     /* cached target address of a branch */
162
                int lru;                /* least recently used */
163
                char *insn;             /* cached insn at target address (not used currently) */
164
        } way[BTIC_WAYS];
165
} btic[BTIC_LEN];
166
 
167 6 lampret
void btic_info()
168
{
169 541 markom
        if (!config.bpb.btic) {
170 264 markom
                printf("BTIC not simulated. Check --btic option.\n");
171 102 lampret
                return;
172
        }
173
 
174 6 lampret
        printf("BTIC %d bytes: ", BTIC_LEN * BTIC_WAYS * (BTIC_USTATES + BTIC_BLOCKSIZE * 8) / 8);
175
        printf("%d ways, %d sets, %d bits/target\n", BTIC_WAYS, BTIC_LEN, BTIC_USTATES + BTIC_BLOCKSIZE * 8);
176
}
177
 
178 2 cvs
/* First check if target addr is already in the cache and if it is:
179
    - increment BTIC hit stats,
180
    - set 'lru' at this way to BTIC_USTATES - 1 and
181
      decrement 'lru' of other ways unless they have reached 0,
182
   and if not:
183
    - increment BTIC miss stats
184
    - find lru way and entry and replace old address with 'addr' and
185
      'insn' with NULL
186
    - set 'lru' with BTIC_USTATES - 1 and decrement 'lru' of other
187
      ways unless they have reached 0
188
*/
189
 
190
void btic_update(unsigned long targetaddr)
191
{
192
        int entry, way = -1;
193
        int i;
194
 
195 102 lampret
        /* BTIC simulation enabled/disabled. */
196 541 markom
        if (!config.bpb.btic)
197 102 lampret
                return;
198
 
199 2 cvs
        /* Calc entry. */
200
        entry = targetaddr % BTIC_LEN;
201
 
202
        /* Scan all ways and try to find our addr. */
203
        for (i = 0; i < BTIC_WAYS; i++)
204
                if (btic[entry].way[i].addr == targetaddr)
205
                        way = i;
206
 
207
        /* Did we find our cached branch? */
208
        if (way >= 0) { /* Yes, we did. */
209
                mstats.btic.hit++;
210
 
211
                for (i = 0; i < BTIC_WAYS; i++)
212
                        if (btic[entry].way[i].lru)
213
                                btic[entry].way[i].lru--;
214
                btic[entry].way[way].lru = BTIC_USTATES - 1;
215
        }
216
        else {  /* No, we didn't. */
217
                int minlru = BTIC_USTATES - 1;
218
                int minway = 0;
219
 
220
                mstats.btic.miss++;
221
 
222
                for (i = 0; i < BTIC_WAYS; i++)
223
                        if (btic[entry].way[i].lru < minlru)
224
                                minway = i;
225
 
226
                btic[entry].way[minway].addr = targetaddr;
227
                btic[entry].way[minway].insn = NULL;
228
                for (i = 0; i < BTIC_WAYS; i++)
229
                        if (btic[entry].way[i].lru)
230
                                btic[entry].way[i].lru--;
231
                btic[entry].way[minway].lru = BTIC_USTATES - 1;
232
        }
233
}

powered by: WebSVN 2.1.0

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