头文件
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<math.h>
#include<stdbool.h>
#define MAX_CACHE_LINE 65536
enum associativity_way {
direct_mapped = 1,
set_associative,
full_associative
};
enum replacement_way {
none,
FIFO = 1,
LRU,
LFU,
Random
};
enum write_way{
write_through = 1,
write_back
};
typedef enum associativity_way ASSOC;
typedef enum replacement_way REPLACE;
typedef enum write_way WRITE;
extern char i_type;
extern unsigned int long i_cache_size;
extern unsigned int long i_cache_line_size;
extern unsigned int long i_cache_set;
extern unsigned int long i_num_line;
extern unsigned int long i_num_set;
extern ASSOC t_assoc;
extern REPLACE t_replace;
extern WRITE t_write;
extern short unsigned int bit_block;
extern short unsigned int bit_line;
extern short unsigned int bit_tag;
extern short unsigned int bit_set;
extern int cache_item[MAX_CACHE_LINE][32];
extern unsigned long int LRU_priority[MAX_CACHE_LINE];
extern unsigned long int current_line;
extern unsigned long int current_set;
extern unsigned long int i, j;
extern unsigned long int temp;
bool GetHitNum(char *address,char i_type);
bool IsHit(char* address);
void GetReplace(char* address);
void GetRead(char* address);
void GetWrite();
void LruHitProcess();
void LruUnhitSpace();
void LruUnhitUnspace();
.c 文件
#include "base.h"
char i_type = 's';
unsigned int long i_cache_size = 0;
unsigned int long i_cache_line_size = 0;
unsigned int long i_cache_set = 0;
unsigned int long i_num_line = 0;
unsigned int long i_num_set = 0;
ASSOC t_assoc = direct_mapped;
REPLACE t_replace = none;
WRITE t_write = write_back;
short unsigned int bit_block = 0;
short unsigned int bit_line = 0;
short unsigned int bit_tag = 0;
short unsigned int bit_set = 0;
int cache_item[MAX_CACHE_LINE][32];
unsigned long int LRU_priority[MAX_CACHE_LINE];
unsigned long int current_line = 0;
unsigned long int current_set = 0;
unsigned long int i = 0, j = 0;
unsigned long int temp = 0;
bool GetHitNum(char* address,char i_type)
{
bool is_store = false;
bool is_load = false;
bool is_space = false;
bool hit = false;
switch (i_type)
{
case's':
is_store = true;
break;
case'l':
is_load = true;
break;
case'\0':
is_space = true;
break;
default:
printf("The i_type is %c\n",&i_type);
printf("ERROR IN JUDGE\n");
return false;
}
hit = IsHit(address);
if (hit && is_load)
{
printf("Loading\n");
printf("Hit\n");
printf("Read from Cache!\n");
if (t_replace == LRU)
{
LruHitProcess();
}
}
else if (hit && is_store)
{
printf("Storing\n");
printf("Hit\n");
printf("write to Cache!\n");
cache_item[current_line][29]= 1;
if (t_replace == LRU)
{
LruHitProcess();
}
}
else if ((!hit) && is_load)
{
printf("Loading\n");
printf("Not Hit\n");
printf("read from memory!\n");
GetRead(address);
if (t_replace == LRU)
{
LruUnhitSpace();
}
}
else if ((!hit) && is_store)
{
printf("Storing\n");
printf("Not Hit\n");
printf("write to memory!\n");
GetRead(address);
cache_item[current_line][29]= 1;
if (t_replace == LRU)
{
LruUnhitSpace();
}
}
else
{
printf("something ERROR\n");
return false;
}
return true;
}
bool IsHit(char* address)
{
bool ret = false;
if (t_assoc == direct_mapped)
{
int num_line = 0;
for (j=1,i = 31 - (bit_block); i >31 - (bit_block + bit_line); i--,j++)
{
num_line += address[i]*pow(2,j);
}
current_line = num_line;
if (cache_item[current_line][30] == true)
{
ret = true;
for ( i = 31, j = 28; i > (31 - bit_tag); i--,j--)
{
if(address[i]!=cache_item[current_line][j])
{
ret = false;
break;
}
}
}
}
else if (t_assoc == full_associative)
{
for ( temp = 0; temp < i_num_line; temp++)
{
if (cache_item[temp][30] == true)
{
ret = true;
for (i = 31, j = 28; i > (31 - bit_tag); i--, j--)
{
if (address[i] != cache_item[current_line][j])
{
ret = false;
break;
}
}
}
if (ret == true)
{
current_line = temp;
break;
}
}
}
else if (t_assoc == set_associative)
{
int num_set = 0;
for (j = 1, i = 31 - (bit_block); i > 31 - (bit_block + bit_set); i--, j++)
{
num_set += address[i] * pow(2, j);
}
current_set = num_set;
for ( temp = (current_set*i_cache_set); temp < ((current_set+1)*i_cache_set); temp++)
{
if (cache_item[temp][30] == true)
{
ret = true;
for (i = 31, j = 28; i > (31 - bit_tag); i--, j--)
{
if (address[i] != cache_item[current_line][j])
{
ret = false;
break;
}
}
}
if (ret == true)
{
current_line = temp;
break;
}
}
}
return ret;
}
void GetRead(char* address)
{
if (t_assoc == direct_mapped)
{
if(cache_item[current_line][30] == false)
{
printf("Read from Main Memory to Cache\n");
for (i=31,j=28;i>(31-bit_tag);i--,j--)
{
cache_item[current_line][j] = address[i];
}
cache_item[current_line][30] = 1;
}
else
{
GetReplace(address);
}
}
else if (t_assoc == full_associative)
{
bool space = false;
for (temp = 0; temp < i_num_line; temp++)
{
if (cache_item[temp][30] == false)
{
space = true;
break;
}
}
if (space == true)
{
current_line = temp;
printf("Read from Main Memory to Cache\n");
for (i = 31, j = 28; i > (31 - bit_tag); i--, j--)
{
cache_item[current_line][j] = address[i];
}
cache_item[current_line][30] = 1;
if (t_replace == LRU)
{
LruUnhitSpace();
}
}
else
{
GetReplace(address);
}
}
else if (t_assoc == set_associative)
{
bool space = false;
for (temp = (current_set * i_cache_set); temp < ((current_set + 1) * i_cache_set); temp++)
{
if (cache_item[temp][30] == false)
{
space = true;
break;
}
}
if (space == true)
{
current_line = temp;
for (i = 31, j = 28; i > (31ul - bit_tag); i--, j--)
{
cache_item[current_line][j] = address[i];
assert(j > 0);
}
cache_item[current_line][30] = true;
if (t_replace == LRU)
{
LruUnhitSpace();
}
}
else
{
GetReplace(address);
}
}
}
void GetReplace(char* address)
{
if (t_assoc == direct_mapped)
{
}
else if (t_assoc == full_associative)
{
if (t_replace == Random)
{
current_line = rand() / (RAND_MAX / i_num_line + 1);
}
else if (t_replace == LRU)
{
LruUnhitUnspace();
}
}
else if (t_assoc == set_associative)
{
if (t_replace == Random)
{
temp = rand() / (RAND_MAX / i_cache_set + 1);
current_line = current_set * i_cache_set + temp;
}
else if (t_replace == LRU)
{
LruUnhitUnspace();
}
}
if (cache_item[current_line][29] == true)
{
GetWrite();
}
for (i = 31, j = 28; i > (31 - bit_tag); i--, j--)
{
cache_item[current_line][j] = address[i];
assert(j > 0);
}
cache_item[current_line][30] = true;
}
void GetWrite()
{
cache_item[current_line][29] = false;
cache_item[current_line][30] = false;
}
#include "base.h"
void LruHitProcess()
{
if (t_assoc == full_associative)
{
for ( i = 0; i < i_num_line; i++)
{
if (LRU_priority[i] < LRU_priority[current_line] && cache_item[i][30] == true)
{
LRU_priority[i]++;
}
}
LRU_priority[current_line] = 0;
}
else if (t_assoc == set_associative)
{
for (i = (current_set * i_cache_set); i < (current_set + 1) * i_cache_set; i++)
{
if (LRU_priority[i] < LRU_priority[current_line] && cache_item[i][30] == true)
{
LRU_priority[i]++;
}
}
LRU_priority[current_line] = 0;
}
}
void LruUnhitSpace()
{
if (t_assoc == full_associative)
{
for (i = 0; i < i_num_line; i++)
{
if (cache_item[i][30] == true)
{
LRU_priority[i]++;
}
}
LRU_priority[current_line] = 0;
}
else if (t_assoc == set_associative)
{
for (i = (current_set * i_cache_set); i < ((current_set + 1) * i_cache_set); i++)
{
if (cache_item[current_line][30] == true)
{
LRU_priority[i]++;
}
}
LRU_priority[current_line] = 0;
}
}
void LruUnhitUnspace()
{
if (t_assoc == full_associative)
{
temp = LRU_priority[0];
for (i = 0; i < i_num_line; i++)
{
if (LRU_priority[i] >= temp)
{
temp = LRU_priority[i];
j = i;
}
}
current_line = j;
}
if (t_assoc == set_associative)
{
temp = LRU_priority[current_set * i_cache_set];
for (i = (current_set * i_cache_set); i < ((current_set + 1) * i_cache_set); i++)
{
if (LRU_priority[i] >= temp)
{
temp = LRU_priority[i];
j = i;
}
}
current_line = j;
}
}