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

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_2_x/] [or1ksim/] [cache/] [dcache_model.c] - Blame information for rev 884

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 631 simons
    unsigned long line[MAX_DC_BLOCK_SIZE];
43 428 markom
    unsigned long tagaddr;  /* tag address */
44
    int lru;    /* least recently used */
45
  } way[MAX_DC_WAYS];
46
} dc[MAX_DC_SETS];
47 5 lampret
 
48
void dc_info()
49
{
50 428 markom
  if (!testsprbits(SPR_UPR, SPR_UPR_DCP)) {
51
    printf("DCache not implemented. Set UPR[DCP].\n");
52
    return;
53
  }
54
 
55
  printf("Data cache %dKB: ", config.dc.nsets * config.dc.blocksize * config.dc.nways / 1024);
56
  printf("%d ways, %d sets, block size %d bytes\n", config.dc.nways, config.dc.nsets, config.dc.blocksize);
57 5 lampret
}
58
 
59
/* First check if data is already in the cache and if it is:
60
    - increment DC read hit stats,
61 428 markom
    - set 'lru' at this way to config.dc.ustates - 1 and
62 5 lampret
      decrement 'lru' of other ways unless they have reached 0,
63
   and if not:
64
    - increment DC read miss stats
65
    - find lru way and entry and replace old tag with tag of the 'dataaddr'
66 428 markom
    - set 'lru' with config.dc.ustates - 1 and decrement 'lru' of other
67 5 lampret
      ways unless they have reached 0
68 631 simons
    - refill cache line
69 5 lampret
*/
70
 
71 631 simons
unsigned long dc_simulate_read(unsigned long dataaddr, int width)
72 5 lampret
{
73 428 markom
  int set, way = -1;
74
  int i;
75
  unsigned long tagaddr;
76 631 simons
  unsigned long tmp;
77 102 lampret
 
78 638 simons
  if ((!testsprbits(SPR_UPR, SPR_UPR_DCP)) ||
79
      (!testsprbits(SPR_SR, SPR_SR_DCE))   ||
80
      data_ci) {
81 631 simons
    if (width == 4)
82
      return evalsim_mem32(dataaddr);
83
    else if (width == 2)
84
      return (unsigned long)evalsim_mem16(dataaddr);
85
    else if (width == 1)
86
      return (unsigned long)evalsim_mem8(dataaddr);
87
  }
88 102 lampret
 
89 428 markom
  /* Which set to check out? */
90
  set = (dataaddr / config.dc.blocksize) % config.dc.nsets;
91
  tagaddr = (dataaddr / config.dc.blocksize) / config.dc.nsets;
92
 
93
  /* Scan all ways and try to find a matching way. */
94
  for (i = 0; i < config.dc.nways; i++)
95
    if (dc[set].way[i].tagaddr == tagaddr)
96
      way = i;
97
 
98
  /* Did we find our cached data? */
99
  if (way >= 0) { /* Yes, we did. */
100
    dc_stats.readhit++;
101 541 markom
 
102 428 markom
    for (i = 0; i < config.dc.nways; i++)
103 631 simons
      if (dc[set].way[i].lru > dc[set].way[way].lru)
104 428 markom
        dc[set].way[i].lru--;
105
    dc[set].way[way].lru = config.dc.ustates - 1;
106 884 markom
    runtime.sim.mem_cycles += config.dc.load_hitdelay;
107 631 simons
 
108
    tmp = dc[set].way[way].line[(dataaddr & (config.dc.blocksize - 1)) >> 2];
109
    if (width == 4)
110
      return tmp;
111
    else if (width == 2) {
112
      tmp = (unsigned long)((tmp >> ((dataaddr & 2) ? 0 : 16)) & 0xffff);
113
      return tmp;
114
    }
115
    else if (width == 1) {
116
      tmp = (unsigned long)((tmp  >> (8 * (3 - (dataaddr & 3)))) & 0xff);
117
      return tmp;
118
    }
119 541 markom
  } else {  /* No, we didn't. */
120 428 markom
    int minlru = config.dc.ustates - 1;
121
    int minway = 0;
122 5 lampret
 
123 631 simons
    dc_stats.readmiss++;
124 5 lampret
 
125 428 markom
    for (i = 0; i < config.dc.nways; i++)
126 631 simons
      if (dc[set].way[i].lru < minlru)
127 428 markom
        minway = i;
128
 
129 631 simons
    for (i = 0; i < (config.dc.blocksize); i += 4) {
130
      dc[set].way[minway].line[((dataaddr + i) & (config.dc.blocksize - 1)) >> 2] =
131
        evalsim_mem32((dataaddr & ~(config.dc.blocksize - 1)) + (((dataaddr & ~3ul)+ i) & (config.dc.blocksize - 1)));
132 638 simons
      if(!cur_area) {
133
        dc[set].way[minway].tagaddr = -1;
134
        dc[set].way[minway].lru = 0;
135 631 simons
        return 0;
136 638 simons
      }
137 631 simons
    }
138
 
139 428 markom
    dc[set].way[minway].tagaddr = tagaddr;
140
    for (i = 0; i < config.dc.nways; i++)
141
      if (dc[set].way[i].lru)
142
        dc[set].way[i].lru--;
143
    dc[set].way[minway].lru = config.dc.ustates - 1;
144 884 markom
    runtime.sim.mem_cycles += config.dc.load_missdelay;
145 631 simons
 
146
    tmp = dc[set].way[minway].line[(dataaddr & (config.dc.blocksize - 1)) >> 2];
147
    if (width == 4)
148
      return tmp;
149
    else if (width == 2) {
150
      tmp = (unsigned long)((tmp >> ((dataaddr & 2) ? 0 : 16)) & 0xffff);
151
      return tmp;
152
    }
153
    else if (width == 1) {
154
      tmp = (unsigned long)((tmp  >> (8 * (3 - (dataaddr & 3)))) & 0xff);
155
      return tmp;
156
    }
157 428 markom
  }
158 5 lampret
}
159
 
160
/* First check if data is already in the cache and if it is:
161
    - increment DC write hit stats,
162 428 markom
    - set 'lru' at this way to config.dc.ustates - 1 and
163 5 lampret
      decrement 'lru' of other ways unless they have reached 0,
164
   and if not:
165
    - increment DC write miss stats
166
    - find lru way and entry and replace old tag with tag of the 'dataaddr'
167 428 markom
    - set 'lru' with config.dc.ustates - 1 and decrement 'lru' of other
168 5 lampret
      ways unless they have reached 0
169
*/
170
 
171 631 simons
void dc_simulate_write(unsigned long dataaddr, unsigned long data, int width)
172 5 lampret
{
173 428 markom
  int set, way = -1;
174
  int i;
175
  unsigned long tagaddr;
176 631 simons
  unsigned long tmp;
177 102 lampret
 
178 631 simons
  if (width == 4)
179
    setsim_mem32(dataaddr, data);
180
  else if (width == 2)
181
    setsim_mem16(dataaddr, (unsigned short)data);
182
  else if (width == 1)
183
    setsim_mem8(dataaddr, (unsigned char)data);
184
 
185 638 simons
  if ((!testsprbits(SPR_UPR, SPR_UPR_DCP)) ||
186
      (!testsprbits(SPR_SR, SPR_SR_DCE)) ||
187
      data_ci ||
188
      (!cur_area))
189 631 simons
    return;
190 428 markom
 
191
  /* Which set to check out? */
192
  set = (dataaddr / config.dc.blocksize) % config.dc.nsets;
193
  tagaddr = (dataaddr / config.dc.blocksize) / config.dc.nsets;
194
 
195
  /* Scan all ways and try to find a matching way. */
196
  for (i = 0; i < config.dc.nways; i++)
197
    if (dc[set].way[i].tagaddr == tagaddr)
198
      way = i;
199
 
200
  /* Did we find our cached data? */
201
  if (way >= 0) { /* Yes, we did. */
202
    dc_stats.writehit++;
203
 
204
    for (i = 0; i < config.dc.nways; i++)
205 631 simons
      if (dc[set].way[i].lru > dc[set].way[way].lru)
206 428 markom
        dc[set].way[i].lru--;
207
    dc[set].way[way].lru = config.dc.ustates - 1;
208 884 markom
    runtime.sim.mem_cycles += config.dc.store_hitdelay;
209 631 simons
 
210
    tmp = dc[set].way[way].line[(dataaddr & (config.dc.blocksize - 1)) >> 2];
211
    if (width == 4)
212
      tmp = data;
213
    else if (width == 2) {
214
      tmp &= 0xffff << ((dataaddr & 2) ? 16 : 0);
215
      tmp |= (unsigned long)(data & 0xffff) << ((dataaddr & 2) ? 0 : 16);
216
    }
217
    else if (width == 1) {
218
      tmp &= ~(0xff << (8 * (3 - (dataaddr & 3))));
219
      tmp |= (unsigned long)(data & 0xff) << (8 * (3 - (dataaddr & 3)));
220
    }
221
    dc[set].way[way].line[(dataaddr & (config.dc.blocksize - 1)) >> 2] = tmp;
222 428 markom
  }
223
  else {  /* No, we didn't. */
224
    int minlru = config.dc.ustates - 1;
225
    int minway = 0;
226 5 lampret
 
227 631 simons
    dc_stats.writemiss++;
228 5 lampret
 
229 428 markom
    for (i = 0; i < config.dc.nways; i++)
230 631 simons
      if (dc[set].way[i].lru < minlru)
231 428 markom
        minway = i;
232
 
233 631 simons
    for (i = 0; i < (config.dc.blocksize); i += 4) {
234
      dc[set].way[minway].line[((dataaddr + i) & (config.dc.blocksize - 1)) >> 2] =
235
        evalsim_mem32((dataaddr & ~(config.dc.blocksize - 1)) + (((dataaddr & ~3ul)+ i) & (config.dc.blocksize - 1)));
236 638 simons
      if(!cur_area) {
237
        dc[set].way[minway].tagaddr = -1;
238
        dc[set].way[minway].lru = 0;
239 631 simons
        return;
240 638 simons
      }
241 631 simons
    }
242
 
243 428 markom
    dc[set].way[minway].tagaddr = tagaddr;
244
    for (i = 0; i < config.dc.nways; i++)
245
      if (dc[set].way[i].lru)
246
        dc[set].way[i].lru--;
247
    dc[set].way[minway].lru = config.dc.ustates - 1;
248 884 markom
    runtime.sim.mem_cycles += config.dc.store_missdelay;
249 428 markom
  }
250 5 lampret
}
251 102 lampret
 
252
/* First check if data is already in the cache and if it is:
253
    - invalidate block if way isn't locked
254
   otherwise don't do anything.
255
*/
256
 
257
void dc_inv(unsigned long dataaddr)
258
{
259 428 markom
  int set, way = -1;
260
  int i;
261
  unsigned long tagaddr;
262 102 lampret
 
263 428 markom
  if (!testsprbits(SPR_UPR, SPR_UPR_DCP))
264
    return;
265 102 lampret
 
266 428 markom
  /* Which set to check out? */
267
  set = (dataaddr / config.dc.blocksize) % config.dc.nsets;
268
  tagaddr = (dataaddr / config.dc.blocksize) / config.dc.nsets;
269
 
270 631 simons
  if (!testsprbits(SPR_SR, SPR_SR_DCE)) {
271
    for (i = 0; i < config.dc.nways; i++) {
272
      dc[set].way[i].tagaddr = -1;
273
      dc[set].way[i].lru = 0;
274
    }
275
    return;
276
  }
277
   /* Scan all ways and try to find a matching way. */
278 428 markom
  for (i = 0; i < config.dc.nways; i++)
279
    if (dc[set].way[i].tagaddr == tagaddr)
280
      way = i;
281
 
282
  /* Did we find our cached data? */
283 631 simons
  if (way >= 0) { /* Yes, we did. */
284 428 markom
    dc[set].way[way].tagaddr = -1;
285 631 simons
    dc[set].way[way].lru = 0;
286 428 markom
  }
287 102 lampret
}
288
 
289 261 markom
inline void dc_clock()
290 102 lampret
{
291 428 markom
  unsigned long addr;
292
 
293
  if (addr = mfspr(SPR_DCBPR)) {
294 631 simons
    dc_simulate_read(addr, 4);
295 428 markom
    mtspr(SPR_DCBPR, 0);
296
  }
297 631 simons
  if ((addr = mfspr(SPR_DCBFR)) != -1) {
298 428 markom
    dc_inv(addr);
299 631 simons
    mtspr(SPR_DCBFR, -1);
300 428 markom
  }
301
  if (addr = mfspr(SPR_DCBIR)) {
302
    dc_inv(addr);
303
    mtspr(SPR_DCBIR, 0);
304
  }
305
  if (addr = mfspr(SPR_DCBWR)) {
306
    mtspr(SPR_DCBWR, 0);
307
  }
308
  if (addr = mfspr(SPR_DCBLR)) {
309
    mtspr(SPR_DCBLR, 0);
310
  }
311 102 lampret
}

powered by: WebSVN 2.1.0

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