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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_69/] [or1ksim/] [cache/] [dcache_model.c] - Blame information for rev 428

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

Line No. Rev Author Line
1 5 lampret
/* dcache_model.c -- data cache 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
/* Cache functions.
21
   At the moment this functions only simulate functionality of data
22
   caches and do not influence on fetche/decode/execute stages and timings.
23
   They are here only to verify performance of various cache configurations.
24
 */
25
 
26
#include <stdio.h>
27
#include <string.h>
28
#include <errno.h>
29
#include <stdarg.h>
30
 
31
#include "dcache_model.h"
32
#include "abstract.h"
33
#include "stats.h"
34 102 lampret
#include "spr_defs.h"
35
#include "sprs.h"
36 428 markom
#include "sim-config.h"
37 5 lampret
 
38
/* Data cache */
39
 
40
struct dc_set {
41 428 markom
  struct {
42
    unsigned long tagaddr;  /* tag address */
43
    int lru;    /* least recently used */
44
  } way[MAX_DC_WAYS];
45
} dc[MAX_DC_SETS];
46 5 lampret
 
47
void dc_info()
48
{
49 428 markom
  if (!testsprbits(SPR_UPR, SPR_UPR_DCP)) {
50
    printf("DCache not implemented. Set UPR[DCP].\n");
51
    return;
52
  }
53
 
54
  printf("Data cache %dKB: ", config.dc.nsets * config.dc.blocksize * config.dc.nways / 1024);
55
  printf("%d ways, %d sets, block size %d bytes\n", config.dc.nways, config.dc.nsets, config.dc.blocksize);
56 5 lampret
}
57
 
58
/* First check if data is already in the cache and if it is:
59
    - increment DC read hit stats,
60 428 markom
    - set 'lru' at this way to config.dc.ustates - 1 and
61 5 lampret
      decrement 'lru' of other ways unless they have reached 0,
62
   and if not:
63
    - increment DC read miss stats
64
    - find lru way and entry and replace old tag with tag of the 'dataaddr'
65 428 markom
    - set 'lru' with config.dc.ustates - 1 and decrement 'lru' of other
66 5 lampret
      ways unless they have reached 0
67
*/
68
 
69
void dc_simulate_read(unsigned long dataaddr)
70
{
71 428 markom
  int set, way = -1;
72
  int i;
73
  unsigned long tagaddr;
74 102 lampret
 
75 428 markom
  if ((!testsprbits(SPR_UPR, SPR_UPR_DCP)) || (!testsprbits(SPR_SR, SPR_SR_DCE)))
76
    return;
77 102 lampret
 
78 428 markom
  /* Which set to check out? */
79
  set = (dataaddr / config.dc.blocksize) % config.dc.nsets;
80
  tagaddr = (dataaddr / config.dc.blocksize) / config.dc.nsets;
81
 
82
  /* Scan all ways and try to find a matching way. */
83
  for (i = 0; i < config.dc.nways; i++)
84
    if (dc[set].way[i].tagaddr == tagaddr)
85
      way = i;
86
 
87
  /* Did we find our cached data? */
88
  if (way >= 0) { /* Yes, we did. */
89
    dc_stats.readhit++;
90
 
91
    for (i = 0; i < config.dc.nways; i++)
92
      if (dc[set].way[i].lru)
93
        dc[set].way[i].lru--;
94
    dc[set].way[way].lru = config.dc.ustates - 1;
95
  }
96
  else {  /* No, we didn't. */
97
    int minlru = config.dc.ustates - 1;
98
    int minway = 0;
99 5 lampret
 
100
                dc_stats.readmiss++;
101
 
102 428 markom
    for (i = 0; i < config.dc.nways; i++)
103
      if ((dc[set].way[i].lru < minlru) &&
104
          (getsprbits(SPR_DCCR, SPR_DCCR_EW) & (1 << i)))
105
        minway = i;
106
 
107
    dc[set].way[minway].tagaddr = tagaddr;
108
    for (i = 0; i < config.dc.nways; i++)
109
      if (dc[set].way[i].lru)
110
        dc[set].way[i].lru--;
111
    dc[set].way[minway].lru = config.dc.ustates - 1;
112
  }
113 5 lampret
}
114
 
115
/* First check if data is already in the cache and if it is:
116
    - increment DC write hit stats,
117 428 markom
    - set 'lru' at this way to config.dc.ustates - 1 and
118 5 lampret
      decrement 'lru' of other ways unless they have reached 0,
119
   and if not:
120
    - increment DC write miss stats
121
    - find lru way and entry and replace old tag with tag of the 'dataaddr'
122 428 markom
    - set 'lru' with config.dc.ustates - 1 and decrement 'lru' of other
123 5 lampret
      ways unless they have reached 0
124
*/
125
 
126
void dc_simulate_write(unsigned long dataaddr)
127
{
128 428 markom
  int set, way = -1;
129
  int i;
130
  unsigned long tagaddr;
131 102 lampret
 
132 428 markom
  if ((!testsprbits(SPR_UPR, SPR_UPR_DCP)) || (!testsprbits(SPR_SR, SPR_SR_DCE)))
133
    return;
134
 
135
  /* Which set to check out? */
136
  set = (dataaddr / config.dc.blocksize) % config.dc.nsets;
137
  tagaddr = (dataaddr / config.dc.blocksize) / config.dc.nsets;
138
 
139
  /* Scan all ways and try to find a matching way. */
140
  for (i = 0; i < config.dc.nways; i++)
141
    if (dc[set].way[i].tagaddr == tagaddr)
142
      way = i;
143
 
144
  /* Did we find our cached data? */
145
  if (way >= 0) { /* Yes, we did. */
146
    dc_stats.writehit++;
147
 
148
    for (i = 0; i < config.dc.nways; i++)
149
      if (dc[set].way[i].lru)
150
        dc[set].way[i].lru--;
151
    dc[set].way[way].lru = config.dc.ustates - 1;
152
  }
153
  else {  /* No, we didn't. */
154
    int minlru = config.dc.ustates - 1;
155
    int minway = 0;
156 5 lampret
 
157
                dc_stats.writemiss++;
158
 
159 428 markom
    for (i = 0; i < config.dc.nways; i++)
160
      if ((dc[set].way[i].lru < minlru) &&
161
          (getsprbits(SPR_DCCR, SPR_DCCR_EW) & (1 << i)))
162
        minway = i;
163
 
164
    dc[set].way[minway].tagaddr = tagaddr;
165
    for (i = 0; i < config.dc.nways; i++)
166
      if (dc[set].way[i].lru)
167
        dc[set].way[i].lru--;
168
    dc[set].way[minway].lru = config.dc.ustates - 1;
169
  }
170 5 lampret
}
171 102 lampret
 
172
/* First check if data is already in the cache and if it is:
173
    - invalidate block if way isn't locked
174
   otherwise don't do anything.
175
*/
176
 
177
void dc_inv(unsigned long dataaddr)
178
{
179 428 markom
  int set, way = -1;
180
  int i;
181
  unsigned long tagaddr;
182 102 lampret
 
183 428 markom
  if (!testsprbits(SPR_UPR, SPR_UPR_DCP))
184
    return;
185 102 lampret
 
186 428 markom
  /* Which set to check out? */
187
  set = (dataaddr / config.dc.blocksize) % config.dc.nsets;
188
  tagaddr = (dataaddr / config.dc.blocksize) / config.dc.nsets;
189
 
190
  /* Scan all ways and try to find a matching way. */
191
  for (i = 0; i < config.dc.nways; i++)
192
    if (dc[set].way[i].tagaddr == tagaddr)
193
      way = i;
194
 
195
  /* Did we find our cached data? */
196
  if ((way >= 0) && (getsprbits(SPR_DCCR, SPR_DCCR_EW) & (1 << way))) { /* Yes, we did. */
197
    dc[set].way[way].tagaddr = -1;
198
  }
199 102 lampret
}
200
 
201 261 markom
inline void dc_clock()
202 102 lampret
{
203 428 markom
  unsigned long addr;
204
 
205
  if (addr = mfspr(SPR_DCBPR)) {
206
    dc_simulate_read(addr);
207
    mtspr(SPR_DCBPR, 0);
208
  }
209
  if (addr = mfspr(SPR_DCBFR)) {
210
    dc_inv(addr);
211
    mtspr(SPR_DCBFR, 0);
212
  }
213
  if (addr = mfspr(SPR_DCBIR)) {
214
    dc_inv(addr);
215
    mtspr(SPR_DCBIR, 0);
216
  }
217
  if (addr = mfspr(SPR_DCBWR)) {
218
    mtspr(SPR_DCBWR, 0);
219
  }
220
  if (addr = mfspr(SPR_DCBLR)) {
221
    mtspr(SPR_DCBLR, 0);
222
  }
223 102 lampret
}

powered by: WebSVN 2.1.0

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