// Do not edit this file /** * Usage (after running make): make run or ./main memory.txt (must supply 1 CLI * argument). * * Main file for a cache simulator that implements the two cache mapping * functions (CMF): 1) direct mapping (DM) 2) fully associative (FA) * * This is an interactive simulator that allows the user to * 1) Select the cache mapping function (CMF) * 2) Enter hex memory addresses * 3) For the CMF selected, determine if the address results in a cache hit or * miss and display to the user 4) If a cache miss, determine the cache line to * be replaced for the chosen CMF. For FA, the replacement algorithm is least * frequently used (LFU) based on the minimum number of cache hits. */ #include #include #include #include #include "cache.h" #include "memory.h" char* CMFS[] = {"Direct Mapping", "Fully Associative"}; char* OP[] = {"MISS", "HIT"}; char* ROP[] = {"No Replacement", "Replacement"}; extern unsigned int addr_bits; int main(int argc, char* argv[]) { if (argc != 2) { fprintf(stderr, "Usage: ./main memory.txt\n"); exit(1); } unsigned int num_blocks; unsigned int cmf; unsigned int hex_addr; int byte; bool found, replace; addr_bits = read_memory_file(argv[1]); if (addr_bits != FAIL) { /* --------------------------------------------------- STEP 1: --------------------------------------------------- Calculate the number of blocks then display to the user the number of physical memory addressable bits and the total number of physical memory blocks. */ printf("\n------------------------\n"); printf("[STEP 1] Setting up physical memory\n"); printf("------------------------\n"); num_blocks = number_of_blocks(addr_bits, NUM_BLOCK_OFFSET_BITS); printf( "Physical memory addressable bits = %d, total number of blocks = " "%d\n", addr_bits, num_blocks); /* --------------------------------------------------- STEP 2: --------------------------------------------------- Initialize the block points, i.e. determine the physical memory starting address for each block. */ printf("\n------------------------\n"); printf("[STEP 2] Determining physical memory block locations\n"); printf("------------------------\n"); initialize_block_pointers(num_blocks, NUM_BLOCK_OFFSET_BITS); /* --------------------------------------------------- STEP 3: --------------------------------------------------- Ask the user to choose the cache mapping function (CMF) */ printf("\n------------------------\n"); printf("[STEP 3] Select cache mapping function (CMF)\n"); printf("------------------------\n"); printf("1 = Direct mapping\n"); printf("2 = Fully associative\n"); printf("------------------------\n"); printf("Please enter 1 or 2: "); scanf("%d", &cmf); if (cmf != DM && cmf != FA) { printf("Unknown CMF mode (%d) ... exiting\n", cmf); exit(1); } else { /* --------------------------------------------------- STEP 4: --------------------------------------------------- Initialize cache, that is, all the cache lines should be empty (i.e. no block of physical memory is loaded into any cache line). */ printf("\n------------------------\n"); printf("[STEP 4] initializing cache\n"); printf("------------------------\n"); initialize_cache(NUM_LINES); /* --------------------------------------------------- STEP 5: --------------------------------------------------- Ask the user to enter physical a memory address location in hexadecimal format (e.g. EA), then get and display physical memory value from cache and display to user. */ printf("\n------------------------\n"); printf("[STEP 5] Starting simulation\n"); printf("------------------------\n"); printf("CMF is %s\n", CMFS[cmf - 1]); printf("To exit simulation, press Ctrl+C\n"); while (true) { printf("\nPlease enter %d-bit hexadecimal address: ", addr_bits); scanf("%x", &hex_addr); printf( "Entered Hexadecimal (Base-16) address %02X (Base-10 value " "%d)\n", hex_addr, hex_addr); byte = cread(cmf, &hex_addr, &found, &replace); if (byte != FAIL) { printf( "[%s:%s] The byte value at memory address %02X is " "%02X\n", OP[found], ROP[replace], hex_addr, byte); } else { printf("Failed to read cache for memory location %02X\n", hex_addr); } } } } else { printf("Unable to read the memory file ( %s ) ... exiting\n", argv[1]); } return OK; }