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 1085

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

powered by: WebSVN 2.1.0

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