diff --git a/src/csim.c b/src/csim.c index 6913410..5f44374 100644 --- a/src/csim.c +++ b/src/csim.c @@ -6,36 +6,58 @@ #include #include -#include +#include #include #include #include #include "cachelab.h" +int v = -1; /* verbose */ +int s = -1; /* set index */ +int E = -1; /* Set of cache lines */ +int b = -1; /* Block offset */ +int S; /* Set of Set of cache lines*/ +int B; /* Block size */ +long long time = 0; +FILE *tracefile; /* File to trace from */ +struct cache_line **cache; /* cache */ + +int hit = 0, miss = 0, eviction = 0; + struct cache_line { unsigned char v; unsigned int tag; unsigned int timestamp; }; -typedef struct cache_line cache_line_t; - void print_help() { - printf("Usage: ./csim-ref [-hv] -s -E -b -t "); - printf(" -h: Optional help flag that prints usage info"); - printf(" -v: Optional verbose flag that displays trace info"); - printf(" -s : Number of set index bits (S = 2 s is the number of sets)"); - printf(" -E : Associativity (number of lines per set)"); - printf(" -b : Number of block bits (B = 2 b is the block size)"); - printf(" -t : Name of the valgrind trace to replay"); + printf("Usage: ./csim-ref [-hv] -s -E -b -t \n"); + printf(" -h: Optional help flag that prints usage info\n"); + printf(" -v: Optional verbose flag that displays trace info\n"); + printf(" -s : Number of set index bits (S = 2 s is the number of sets)\n"); + printf(" -E : Associativity (number of lines per set)\n"); + printf(" -b : Number of block bits (B = 2 b is the block size)\n"); + printf(" -t : Name of the valgrind trace to replay\n"); } -int main(int argc, char *argv[]) { - int c; - int v = -1, s = -1, E = -1, b = -1, S, B; - FILE *tracefile = NULL; - int hit = 0, miss = 0, eviction = 0; +void accessMem (struct cache_line **cache, unsigned int address) { + unsigned int set_bits = address >> (s + b); + unsigned int tag_bits = address << (64-s-b) >> (64 - s); + for (int i = 0; i < E; i++) { + if (cache[set_bits][i].v == 1 && cache[set_bits][i].tag == tag_bits) { + cache[set_bits][i].timestamp = time; + hit++; + break; + } else { + + } + } + time++; +} + +void opt (int argc, char **argv) { + char c; while ((c = getopt(argc, argv, "s:E:b:t:vh")) != -1) { switch (c) { case 'h': @@ -45,6 +67,9 @@ int main(int argc, char *argv[]) { case 'v': v = 1; break; + case 's': + s = atoi(optarg); + break; case 'E': E = atoi(optarg); break; @@ -57,18 +82,20 @@ int main(int argc, char *argv[]) { } } - if (v == -1 || s == -1 || E == -1 || b == -1 || tracefile == NULL) { + if (s == -1 || E == -1 || b == -1 || tracefile == NULL) { print_help(); exit(0); } S = pow(2, s); B = pow(2, b); +} - cache_line_t **cache = malloc(S*sizeof(cache_line_t*)); +void Init() { + cache = (struct cache_line **) malloc(S*sizeof(struct cache_line *)); - for (int i = 0; i < (S * sizeof(cache_line_t*)); i++) { - cache_line_t *cache_set = malloc(E*sizeof(struct cache_line)); + for (int i = 0; i < S; i++) { + struct cache_line* cache_set = (struct cache_line *) malloc(E*sizeof(struct cache_line)); cache[i] = cache_set; for (int j = 0; j < E; j++) { cache_set[j].v = '\0'; @@ -76,17 +103,48 @@ int main(int argc, char *argv[]) { cache_set[j].timestamp = 0; } } +} +void CleanUp() { + for (int i = 0; i < S; i++) { + free(cache[i]); + } + free(cache); + fclose(tracefile); +} +void traceCache() { char op; // I = instruction, L = data load, S = data store, M = data modify unsigned address; int size; - while (fscanf(tracefile, "%c %x %d", &op, &address, &size) > 0 ) { + while (fscanf(tracefile, " %c %x,%d", &op, &address, &size) > 0 ) { + if (v == 1) { + printf("%c %x,%d", op, address, size); + } + switch (op) { + case 'M': + accessMem(cache, address); + accessMem(cache, address); + break; + case 'L': + accessMem(cache, address); + break; + case 'S': + accessMem(cache, address); + break; + } + printf("\n"); } +} - fclose(tracefile); - free(cache); - printSummary(0, 0, 0); +int main(int argc, char *argv[]) { + opt(argc, argv); + + Init(); + traceCache(); + CleanUp(); + + printSummary(hit, miss, eviction); return 0; }