-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_l2.c
More file actions
190 lines (139 loc) · 6.12 KB
/
Copy pathtest_l2.c
File metadata and controls
190 lines (139 loc) · 6.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "memory_subsystem_constants.h"
#include "l2_cache.h"
//number of cache entries (2^15)
#define L2_NUM_CACHE_ENTRIES (1<<15)
int main()
{
printf("Initializing L2\n");
l2_initialize();
uint32_t read_data[WORDS_PER_CACHE_LINE];
uint32_t write_data[WORDS_PER_CACHE_LINE];
uint32_t evicted_writeback_data[WORDS_PER_CACHE_LINE];
uint32_t evicted_writeback_address;
uint8_t status;
uint32_t i,j;
//write to each cache line in the L2 cache using
//l2_cache_access(). If there's a cache miss (as
//there should be initially), call l2_insert_line
printf("Pass 1: Writing to each entry of empty L2 cache\n");
// Here, i is the word offset in memory of the beginning of the cache line
for(i=0; i < (L2_NUM_CACHE_ENTRIES * WORDS_PER_CACHE_LINE); i += WORDS_PER_CACHE_LINE) {
for(j=0; j < WORDS_PER_CACHE_LINE; j++)
write_data[j] = i+j;
// the address of the cache line to be written to is i * BYTES_PER_WORD (which is 4)
l2_cache_access(i<<2, write_data, WRITE_ENABLE_MASK, NULL, &status);
if (!(status & 0x1)) { //if cache miss, indicated by lsb of status = 0
//call l2_insert_line
l2_insert_line(i<<2, write_data, &evicted_writeback_address,
evicted_writeback_data, &status);
if (status & 0x1) { //if writeback line was evicted, indicated by lsb of status = 1
//something was wrong.
printf("Error: No cache line to evict and write back in Pass 1\n");
exit(1);
}
}
else { //cache hit, which shouldn't happen initially
printf("Error: No cache line hits should happen in Pass 1\n");
exit(1);
}
}
printf("Pass 2: Reading from each entry of L2 cache\n");
//Now, second time through the cache, reading, should be a cache hit every time.
for(i=0; i < (L2_NUM_CACHE_ENTRIES * WORDS_PER_CACHE_LINE); i += WORDS_PER_CACHE_LINE) {
l2_cache_access(i<<2, NULL, READ_ENABLE_MASK, read_data, &status);
if (!(status & 0x1)) { //if cache miss, indicated by lsb of status = 0
printf("Error: Cache miss upon read in Pass 2\n");
exit(1);
}
for(j=0; j < WORDS_PER_CACHE_LINE; j++)
if (read_data[j] != i+j) {
printf("Error: Data read in Pass 2 does not match data written in Pass 1\n");
exit(1);
}
}
printf("Pass 3: Replacing each entry of L2 cache with new cache line\n");
for(i = L2_NUM_CACHE_ENTRIES * WORDS_PER_CACHE_LINE;
i < (2 * L2_NUM_CACHE_ENTRIES * WORDS_PER_CACHE_LINE);
i += WORDS_PER_CACHE_LINE) {
for(j=0; j < WORDS_PER_CACHE_LINE; j++)
write_data[j] = i+j;
l2_cache_access(i<<2, write_data, WRITE_ENABLE_MASK, NULL, &status);
if (!(status & 0x1)) { //if cache miss, indicated by lsb of status = 0
//call l2_insert_line
l2_insert_line(i<<2, write_data, &evicted_writeback_address,
evicted_writeback_data, &status);
if (status & 0x1) { //if writeback line was evicted, indicated by lsb of status = 1
//something was wrong.
printf("Error: No cache line should be evicted and written back in Pass 3\n");
exit(1);
}
}
else { //cache hit, which shouldn't happen
printf("Error: No cache hits should happen in Pass 3\n");
exit(1);
}
}
printf("Pass 4: Writing to cache lines already resident in L2 cache\n");
for(i = L2_NUM_CACHE_ENTRIES * WORDS_PER_CACHE_LINE;
i < (2 * L2_NUM_CACHE_ENTRIES * WORDS_PER_CACHE_LINE);
i += WORDS_PER_CACHE_LINE) {
for(j=0; j < WORDS_PER_CACHE_LINE; j++)
write_data[j] = (i+j) << 2;
l2_cache_access(i<<2, write_data, WRITE_ENABLE_MASK, NULL, &status);
if (!(status & 0x1)) { //if cache miss, indicated by lsb of status = 0
printf("Error: Cache miss in Pass 4 \n");
exit(1);
}
}
printf("Pass 5: Reading from cache lines written in Pass 1, should miss every time\n");
//Now reading using addresses from Pass 1, should be a cache miss every time.
for(i=0; i < (L2_NUM_CACHE_ENTRIES * WORDS_PER_CACHE_LINE); i += WORDS_PER_CACHE_LINE) {
l2_cache_access(i<<2, NULL, READ_ENABLE_MASK, read_data, &status);
if (status & 0x1) { //if cache hit, indicated by lsb of status = 1
printf("Error: Cache hit upon read in Pass 5\n");
exit(1);
}
}
printf("Pass 6: Reading from cache lines written in Pass 4\n");
for(i = L2_NUM_CACHE_ENTRIES * WORDS_PER_CACHE_LINE;
i < (2 * L2_NUM_CACHE_ENTRIES * WORDS_PER_CACHE_LINE);
i += WORDS_PER_CACHE_LINE) {
l2_cache_access(i<<2, NULL, READ_ENABLE_MASK, read_data, &status);
if (!(status & 0x1)) { //if cache miss, indicated by lsb of status = 0
printf("Error: Cache miss in Pass 6\n");
exit(1);
}
for(j=0; j < WORDS_PER_CACHE_LINE; j++)
if (read_data[j] != ((i+j) << 2)) {
printf("Error: Data read in Pass 6 is different from that written in Pass 4\n");
printf("Should have read %d but read %d instead\n", ((i+j) << 2), read_data[j]);
exit(1);
}
}
printf("Pass 7: Repeating pass 1 to write to cache lines that are not in L2 and then,\n");
printf(" upon each miss, calling l2_insert_line. Each line evicted should be\n");
printf(" written back\n");
for(i=0; i < (L2_NUM_CACHE_ENTRIES * WORDS_PER_CACHE_LINE); i += WORDS_PER_CACHE_LINE) {
for(j=0; j < WORDS_PER_CACHE_LINE; j++)
write_data[j] = i+j;
l2_cache_access(i<<2, write_data, WRITE_ENABLE_MASK, NULL, &status);
if (!(status & 0x1)) { //if cache miss, indicated by lsb of status = 0
//call l2_insert_line
l2_insert_line(i<<2, write_data, &evicted_writeback_address,
evicted_writeback_data, &status);
if (!(status & 0x1)) { //if writeback line was not evicted, indicated by lsb of status = 0
//something was wrong.
printf("Error: Each evicted cache line should be written back in Pass 7, but wasn't\n");
exit(1);
}
}
else { //cache hit, which shouldn't happen initially
printf("Error: No cache line hits should happen in Pass 7\n");
exit(1);
}
}
printf("Passed\n");
}