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 541

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 541 markom
  extern int mem_cycles;
75 102 lampret
 
76 428 markom
  if ((!testsprbits(SPR_UPR, SPR_UPR_DCP)) || (!testsprbits(SPR_SR, SPR_SR_DCE)))
77
    return;
78 102 lampret
 
79 428 markom
  /* Which set to check out? */
80
  set = (dataaddr / config.dc.blocksize) % config.dc.nsets;
81
  tagaddr = (dataaddr / config.dc.blocksize) / config.dc.nsets;
82
 
83
  /* Scan all ways and try to find a matching way. */
84
  for (i = 0; i < config.dc.nways; i++)
85
    if (dc[set].way[i].tagaddr == tagaddr)
86
      way = i;
87
 
88
  /* Did we find our cached data? */
89
  if (way >= 0) { /* Yes, we did. */
90
    dc_stats.readhit++;
91 541 markom
 
92 428 markom
    for (i = 0; i < config.dc.nways; i++)
93
      if (dc[set].way[i].lru)
94
        dc[set].way[i].lru--;
95
    dc[set].way[way].lru = config.dc.ustates - 1;
96 541 markom
    mem_cycles += config.dc.load_hitdelay;
97
  } else {  /* No, we didn't. */
98 428 markom
    int minlru = config.dc.ustates - 1;
99
    int minway = 0;
100 5 lampret
 
101
                dc_stats.readmiss++;
102
 
103 428 markom
    for (i = 0; i < config.dc.nways; i++)
104
      if ((dc[set].way[i].lru < minlru) &&
105
          (getsprbits(SPR_DCCR, SPR_DCCR_EW) & (1 << i)))
106
        minway = i;
107
 
108
    dc[set].way[minway].tagaddr = tagaddr;
109
    for (i = 0; i < config.dc.nways; i++)
110
      if (dc[set].way[i].lru)
111
        dc[set].way[i].lru--;
112
    dc[set].way[minway].lru = config.dc.ustates - 1;
113 541 markom
    mem_cycles += config.dc.load_missdelay;
114 428 markom
  }
115 5 lampret
}
116
 
117
/* First check if data is already in the cache and if it is:
118
    - increment DC write hit stats,
119 428 markom
    - set 'lru' at this way to config.dc.ustates - 1 and
120 5 lampret
      decrement 'lru' of other ways unless they have reached 0,
121
   and if not:
122
    - increment DC write miss stats
123
    - find lru way and entry and replace old tag with tag of the 'dataaddr'
124 428 markom
    - set 'lru' with config.dc.ustates - 1 and decrement 'lru' of other
125 5 lampret
      ways unless they have reached 0
126
*/
127
 
128
void dc_simulate_write(unsigned long dataaddr)
129
{
130 428 markom
  int set, way = -1;
131
  int i;
132
  unsigned long tagaddr;
133 541 markom
  extern int mem_cycles;
134 102 lampret
 
135 428 markom
  if ((!testsprbits(SPR_UPR, SPR_UPR_DCP)) || (!testsprbits(SPR_SR, SPR_SR_DCE)))
136
    return;
137
 
138
  /* Which set to check out? */
139
  set = (dataaddr / config.dc.blocksize) % config.dc.nsets;
140
  tagaddr = (dataaddr / config.dc.blocksize) / config.dc.nsets;
141
 
142
  /* Scan all ways and try to find a matching way. */
143
  for (i = 0; i < config.dc.nways; i++)
144
    if (dc[set].way[i].tagaddr == tagaddr)
145
      way = i;
146
 
147
  /* Did we find our cached data? */
148
  if (way >= 0) { /* Yes, we did. */
149
    dc_stats.writehit++;
150
 
151
    for (i = 0; i < config.dc.nways; i++)
152
      if (dc[set].way[i].lru)
153
        dc[set].way[i].lru--;
154
    dc[set].way[way].lru = config.dc.ustates - 1;
155 541 markom
    mem_cycles += config.dc.store_hitdelay;
156 428 markom
  }
157
  else {  /* No, we didn't. */
158
    int minlru = config.dc.ustates - 1;
159
    int minway = 0;
160 5 lampret
 
161
                dc_stats.writemiss++;
162
 
163 428 markom
    for (i = 0; i < config.dc.nways; i++)
164
      if ((dc[set].way[i].lru < minlru) &&
165
          (getsprbits(SPR_DCCR, SPR_DCCR_EW) & (1 << i)))
166
        minway = i;
167
 
168
    dc[set].way[minway].tagaddr = tagaddr;
169
    for (i = 0; i < config.dc.nways; i++)
170
      if (dc[set].way[i].lru)
171
        dc[set].way[i].lru--;
172
    dc[set].way[minway].lru = config.dc.ustates - 1;
173 541 markom
    mem_cycles += config.dc.store_missdelay;
174 428 markom
  }
175 5 lampret
}
176 102 lampret
 
177
/* First check if data is already in the cache and if it is:
178
    - invalidate block if way isn't locked
179
   otherwise don't do anything.
180
*/
181
 
182
void dc_inv(unsigned long dataaddr)
183
{
184 428 markom
  int set, way = -1;
185
  int i;
186
  unsigned long tagaddr;
187 102 lampret
 
188 428 markom
  if (!testsprbits(SPR_UPR, SPR_UPR_DCP))
189
    return;
190 102 lampret
 
191 428 markom
  /* 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) && (getsprbits(SPR_DCCR, SPR_DCCR_EW) & (1 << way))) { /* Yes, we did. */
202
    dc[set].way[way].tagaddr = -1;
203
  }
204 102 lampret
}
205
 
206 261 markom
inline void dc_clock()
207 102 lampret
{
208 428 markom
  unsigned long addr;
209
 
210
  if (addr = mfspr(SPR_DCBPR)) {
211
    dc_simulate_read(addr);
212
    mtspr(SPR_DCBPR, 0);
213
  }
214
  if (addr = mfspr(SPR_DCBFR)) {
215
    dc_inv(addr);
216
    mtspr(SPR_DCBFR, 0);
217
  }
218
  if (addr = mfspr(SPR_DCBIR)) {
219
    dc_inv(addr);
220
    mtspr(SPR_DCBIR, 0);
221
  }
222
  if (addr = mfspr(SPR_DCBWR)) {
223
    mtspr(SPR_DCBWR, 0);
224
  }
225
  if (addr = mfspr(SPR_DCBLR)) {
226
    mtspr(SPR_DCBLR, 0);
227
  }
228 102 lampret
}

powered by: WebSVN 2.1.0

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