/* ** Write_Cache - this writes a word to the cache, and also writes ** the value out to memory. */ void Write_Cache(unsigned long int address, unsigned long int data){ int i; unsigned long int word; unsigned long int tag; unsigned long int set; unsigned long int cache_line; tag = address & TAG_MASK; word = address & WORD_MASK; set = address & SET_MASK; cache_line = set >> SET_SHIFT; if( (tags[cache_line] == tag) && (IS_VALID(cache_line)) ){ cache_hits++; LRU_Access(cache_line); rammem[set + tag + word] = cache[cache_line][word] = data; } else { cache_misses++; for(i = 0; i < NUM_WORDS_PER_LINE; i++){ cache[cache_line][i] = rammem[tag + set + i]; } tags[cache_line] = tag; LRU_Access(cache_line); rammem[set + tag + word] = cache[cache_line][word] = data; } }
/* ** Write_Cache - this writes a word to the cache, and also writes ** the value out to memory. */ void Write_Cache(unsigned long int address, unsigned long int data){ int i,j; int invalid_line = -1; int victim = 0; unsigned long int word; unsigned long int block; block = address & TAG_MASK; word = address & WORD_MASK; for(i = 0; i < NUM_CACHE_LINES; i++){ if( !IS_VALID(i) ){ invalid_line = i; } else{ if(block == tags[i]) break; } } if(i == NUM_CACHE_LINES){ /* cache miss -- find a victim */ cache_misses++; if(invalid_line != -1){ for(j = 0; j < NUM_WORDS_PER_LINE; j++){ cache[invalid_line][j] = rammem[block + j]; } tags[invalid_line] = block; LRU_Access(invalid_line); rammem[block + word] = data; cache[invalid_line][word] = data; } else{ for(j = 0; j < NUM_CACHE_LINES; j++){ if(mem_count[j] > mem_count[victim]){ victim = j; } } for(j = 0; j < NUM_WORDS_PER_LINE; j++){ cache[victim][j] = rammem[block + j]; } tags[victim] = block; LRU_Access(victim); rammem[block + word] = data; cache[victim][word] = data; } } else{ /* cache hit - just write the puppy out */ cache_hits++; LRU_Access(i); rammem[block + word] = data; cache[i][word] = data; } }