URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/or1k/tags/or1k-1_0/or1ksim/bpb
- from Rev 249 to Rev 1765
- ↔ Reverse comparison
Rev 249 → Rev 1765
/branch_predict.c
0,0 → 1,199
/* branch_predict.c -- branch prediction simulation |
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org |
|
This file is part of OpenRISC 1000 Architectural Simulator. |
|
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 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. */ |
|
/* Branch prediction functions. |
At the moment this functions only simulate functionality of branch |
prediction and do not influence on fetche/decode/execute stages. |
They are here only to verify performance of various branch |
prediction configurations. |
|
*/ |
|
#include <stdio.h> |
#include <string.h> |
#include <errno.h> |
#include <stdarg.h> |
|
#include "branch_predict.h" |
#include "abstract.h" |
#include "stats.h" |
|
/* Branch prediction buffer */ |
|
/* Length of BPB */ |
#define BPB_LEN 32 |
|
/* Number of BPB ways (1, 2, 3 etc.). */ |
#define BPB_WAYS 2 |
|
/* Number of prediction states (2, 4, 8 etc.). */ |
#define BPB_PSTATES 2 |
|
/* Number of usage states (2, 3, 4 etc.). */ |
#define BPB_USTATES 2 |
|
/* branch prediction buffer entry */ |
struct bpb_entry { |
struct { |
unsigned long addr; /* address of a branch insn */ |
int taken; /* taken == 1, not taken == 0 OR */ |
/* strongly taken == 3, taken == 2, |
not taken == 1, strongly not taken == 0 */ |
int lru; /* least recently == 0 */ |
} way[BPB_WAYS]; |
} bpb[BPB_LEN]; |
|
/* First check if branch is already in the cache and if it is: |
- increment BPB hit stats, |
- set 'lru' at this way to BPB_USTATES - 1 and |
decrement 'lru' of other ways unless they have reached 0, |
- increment correct/incorrect stats according to BPB 'taken' field |
and 'taken' variable, |
- increment or decrement BPB taken field according to 'taken' variable |
and if not: |
- increment BPB miss stats |
- find lru way and entry and replace old address with 'addr' and |
'taken' field with (BPB_PSTATES/2 - 1) + 'taken' |
- set 'lru' with BPB_USTATES - 1 and decrement 'lru' of other |
ways unless they have reached 0 |
*/ |
|
void bpb_update(unsigned long addr, int taken) |
{ |
int entry, way = -1; |
int i; |
|
/* Calc entry. */ |
entry = addr % BPB_LEN; |
|
/* Scan all ways and try to find our addr. */ |
for (i = 0; i < BPB_WAYS; i++) |
if (bpb[entry].way[i].addr == addr) |
way = i; |
|
/* Did we find our cached branch? */ |
if (way >= 0) { /* Yes, we did. */ |
mstats.bpb.hit++; |
|
for (i = 0; i < BPB_WAYS; i++) |
if (bpb[entry].way[i].lru) |
bpb[entry].way[i].lru--; |
bpb[entry].way[way].lru = BPB_USTATES - 1; |
|
if (bpb[entry].way[way].taken / (BPB_PSTATES / 2) == taken) |
mstats.bpb.correct++; |
else |
mstats.bpb.incorrect++; |
|
if (taken && (bpb[entry].way[way].taken < BPB_PSTATES - 1)) |
bpb[entry].way[way].taken++; |
else |
if (!taken && (bpb[entry].way[way].taken)) |
bpb[entry].way[way].taken--; |
} |
else { /* No, we didn't. */ |
int minlru = BPB_USTATES - 1; |
int minway = 0; |
|
mstats.bpb.miss++; |
|
for (i = 0; i < BPB_WAYS; i++) |
if (bpb[entry].way[i].lru < minlru) |
minway = i; |
|
bpb[entry].way[minway].addr = addr; |
bpb[entry].way[minway].taken = (BPB_PSTATES / 2 - 1) + taken; |
for (i = 0; i < BPB_WAYS; i++) |
if (bpb[entry].way[i].lru) |
bpb[entry].way[i].lru--; |
bpb[entry].way[minway].lru = BPB_USTATES - 1; |
} |
} |
|
/* Branch target instruction cache */ |
|
/* Length of BTIC */ |
#define BTIC_LEN 32 |
|
/* Number of BTIC ways (1, 2, 3 etc.). */ |
#define BTIC_WAYS 2 |
|
/* Number of usage states (2, 3, 4 etc.). */ |
#define BTIC_USTATES 2 |
|
struct btic_entry { |
struct { |
unsigned long addr; /* cached target address of a branch */ |
int lru; /* least recently used */ |
char *insn; /* cached insn at target address (not used currently) */ |
} way[BTIC_WAYS]; |
} btic[BTIC_LEN]; |
|
/* First check if target addr is already in the cache and if it is: |
- increment BTIC hit stats, |
- set 'lru' at this way to BTIC_USTATES - 1 and |
decrement 'lru' of other ways unless they have reached 0, |
and if not: |
- increment BTIC miss stats |
- find lru way and entry and replace old address with 'addr' and |
'insn' with NULL |
- set 'lru' with BTIC_USTATES - 1 and decrement 'lru' of other |
ways unless they have reached 0 |
*/ |
|
void btic_update(unsigned long targetaddr) |
{ |
int entry, way = -1; |
int i; |
|
/* Calc entry. */ |
entry = targetaddr % BTIC_LEN; |
|
/* Scan all ways and try to find our addr. */ |
for (i = 0; i < BTIC_WAYS; i++) |
if (btic[entry].way[i].addr == targetaddr) |
way = i; |
|
/* Did we find our cached branch? */ |
if (way >= 0) { /* Yes, we did. */ |
mstats.btic.hit++; |
|
for (i = 0; i < BTIC_WAYS; i++) |
if (btic[entry].way[i].lru) |
btic[entry].way[i].lru--; |
btic[entry].way[way].lru = BTIC_USTATES - 1; |
} |
else { /* No, we didn't. */ |
int minlru = BTIC_USTATES - 1; |
int minway = 0; |
|
mstats.btic.miss++; |
|
for (i = 0; i < BTIC_WAYS; i++) |
if (btic[entry].way[i].lru < minlru) |
minway = i; |
|
btic[entry].way[minway].addr = targetaddr; |
btic[entry].way[minway].insn = NULL; |
for (i = 0; i < BTIC_WAYS; i++) |
if (btic[entry].way[i].lru) |
btic[entry].way[i].lru--; |
btic[entry].way[minway].lru = BTIC_USTATES - 1; |
} |
} |
/branch_predict.h
0,0 → 1,22
/* branch_predict.h -- branch prediction header file |
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org |
|
This file is part of OpenRISC 1000 Architectural Simulator. |
|
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 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. */ |
|
/* more or less useless at the moment */ |
|
void bpb_update(unsigned long addr, int taken); |