-
Notifications
You must be signed in to change notification settings - Fork 0
/
cache.c
144 lines (111 loc) · 5.01 KB
/
cache.c
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
/* Cache do simulador MIPS 32 */
/* Autor Bruno Cesar, bcesar.g6@gmail.com */
#include "cache.h"
word barr_mem_dados;
word barr_mem_texto;
void cpyMemBlock(unsigned int cache_id, endereco addr){
unsigned int linha = addr.end.linha;
unsigned int tag = addr.end.tag;
unsigned int byte = addr.end.byte;
/* Descobrir o endereço do inicio do bloco de leitura */
//ENDEREÇO DO BLOCO = Linha * (tam_byte) + tag * (tam_byte + tam_linha)
unsigned int block_addr = (linha * TAM_LINHA * sizeof(unsigned int)) + (tag * 16);
if(cache_id == CACHE_DADOS) block_addr += TEXT_SIZE;
if(cache_id == CACHE_DADOS){
if(get_flag(FLAG_DEBUG)) printf("Endereço do bloco movido para cache-dados: %d (linha= %d| tag= %d| byte= %d)\n", block_addr, linha, tag, byte);
/* Mecanismo Write_back */
if(cache_dados[linha].v == 1){
if(get_flag(FLAG_DEBUG)) printf("\n---- Write back ---\n");
//Faz escrita na memoria na posição de inicio do bloco dos dados antigos (como identificar tag?)
unsigned int target_block_addr = (linha * TAM_LINHA * sizeof(unsigned int)) + (cache_texto[linha].tag * 16);
write(target_block_addr, cache_dados[linha].dados, sizeof(unsigned int) * TAM_LINHA);
cache_dados[linha].v = 0;
}
read(barr_mem_dados, block_addr, sizeof(unsigned int) * TAM_LINHA);
if(get_flag(FLAG_VERBOSE)) printaBloco(barr_mem_dados, TAM_LINHA);
} else{
if(get_flag(FLAG_DEBUG)) printf("Endereço do bloco movido para cache-texto: %d (linha= %d| tag= %d| byte= %d)\n", block_addr, linha, tag, byte);
read(barr_mem_texto, block_addr, sizeof(unsigned int) * TAM_LINHA);
if(get_flag(FLAG_VERBOSE)) printaBloco(barr_mem_texto, TAM_LINHA);
}
}
void cWrite(unsigned int cache_id, endereco addr, unsigned int dado){
if(cache_id == CACHE_TEXTO) launchError(7);
unsigned int linha = addr.end.linha;
unsigned int tag = addr.end.tag;
unsigned int byte = addr.end.byte;
if(get_flag(FLAG_DEBUG)){
printf("Printando o bloco da linha %d da cache-dados:\n", linha);
printaBloco(cache_dados[linha].dados, TAM_LINHA);
}
if(cache_dados[linha].tag == tag){
//hit
if(get_flag(FLAG_VERBOSE)) printf("HIT - Cache-dados linha %d\n", linha);
} else{
//miss
if(get_flag(FLAG_VERBOSE)) printf("MISS - Cache-dados linha %d\n", linha);
cpyMemBlock(cache_id, addr);
cache_dados[linha].dados = barr_mem_dados;
cache_dados[linha].tag = tag;
}
//Escrita na cache
cache_texto[linha].dados[byte / TAM_LINHA] = dado;
cache_dados[linha].v = 1; //Verificador de escrita
}
unsigned int cRead(unsigned int cache_id, endereco addr){
unsigned int linha = addr.end.linha;
unsigned int tag = addr.end.tag;
unsigned int byte = addr.end.byte;
if(cache_id == CACHE_TEXTO){
if(cache_texto[linha].tag == tag){
//hit
if(get_flag(FLAG_VERBOSE)) printf("HIT - Cache-texto linha %d\n", linha);
} else{
//miss
if(get_flag(FLAG_VERBOSE)) printf("MISS - Cache-texto linha %d\n", linha);
cpyMemBlock(cache_id, addr);
cache_texto[linha].dados = barr_mem_texto;
cache_texto[linha].tag = tag;
}
return cache_texto[linha].dados[addr.end.byte / TAM_LINHA];
} else if (cache_id == CACHE_DADOS){
if(cache_dados[linha].tag == tag){
//hit
if(get_flag(FLAG_VERBOSE)) printf("HIT - Cache-dados linha %d\n", linha);
} else{
//miss
if(get_flag(FLAG_VERBOSE)) printf("MISS - Cache-dados linha %d\n", linha);
cpyMemBlock(cache_id, addr);
cache_dados[linha].dados = barr_mem_dados;
cache_dados[linha].tag = tag;
}
return cache_dados[linha].dados[byte / TAM_LINHA];
}
}
void flushCache(unsigned int cache_id){
int i;
for(i = 0; i < NUM_LINHA; i++){
if(cache_id == CACHE_TEXTO) cache_texto[i].v = 0;
if(cache_id == CACHE_DADOS) cache_dados[i].v = 0;
if(cache_id == CACHE_TEXTO) cache_texto[i].tag = FLAG_BLANK;
if(cache_id == CACHE_DADOS) cache_dados[i].tag = FLAG_BLANK;
// cache_dados[i].dados = malloc(TAM_LINHA * sizeof(unsigned int));
//cache_texto[i].dados = malloc(TAM_LINHA * sizeof(unsigned int));
}
}
/* Função auxiliar: Inicializa o componente Cache */
void cacheInit(){
int i;
cache_texto = malloc(NUM_LINHA * sizeof(c_linha)); //32k
cache_dados = malloc(NUM_LINHA * sizeof(c_linha)); //32k
for(i = 0; i < NUM_LINHA; i++){
cache_texto[i].v = 0;
cache_dados[i].v = 0;
cache_texto[i].tag = FLAG_BLANK;
cache_dados[i].tag = FLAG_BLANK;
cache_dados[i].dados = malloc(TAM_LINHA * sizeof(unsigned int));
cache_texto[i].dados = malloc(TAM_LINHA * sizeof(unsigned int));
}
barr_mem_dados = malloc(sizeof(unsigned int) * 4); //128 Bits
barr_mem_texto = malloc(sizeof(unsigned int) * 4); //128 Bits
}