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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_52/] [or1ksim/] [cache/] [dcache_model.c] - Blame information for rev 1344

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

powered by: WebSVN 2.1.0

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