This project will give you intimate knowledge of cache logic through implementation of the actual caching logic. We will be providing you a MIPS simulator called TIPS (Thousands of Instructions Per Second), that will be able to run MIPS instructions. However, the cache logic is broken (read: conveniently nonexistent)!Your job is to implement the cache logic behind the cache so that TIPS can make use of the many beneJits caching entails. You may choose to complete this project either by yourself or with a partner. The initial TIPS code has a default cache size of 0 since there is no cache logic present. You can conJigure the cache by clicking on the ConJig Cache button at the lower left of the interface.GUI WalkthroughThe GUI was designed to be straightforward. There are four main components to the GUI interface:register display, execution log, cache display, and control panel.QA description of each of the GUI widgets are described as follows:1. Register display detailed view of the current state of the registers2. Execution log log of actions by TIPS. Messages can be displayed in this box using theappend_log()function.3. Cache display current snapshot of the state of the cache. The meaning of the column headings oneach unit are: Blk block number V valid bit D dirty bit LRU LRU data Tag Tag for the block Numbers (00, 04, etc.) offset in the cache block data4. ConJig Cache conJigure the cache parameters5. Load Program loads a dump Jile for execution6. Step execute one instruction7. Run automate execution8. CPU reset the PC and reinitialize registers9. Cache Jlush the cache10. Output clear the execution log11. Quit exit TIPSThere is also a text-based version of the GUI for those who prefer it. You can run it with the following call:$ ./tips -noguiType help at the TIPS prompt to get a list of commands usable in this mode. When you are moving things between cache and physical memory, a BLOCK is transferred, NOTjust a word nor a byte. Thus, if the block size is 16 bytes, when you want to move data from cacheto memory (or vice versa) you must make sure 16 bytes travel between the cache and physicalmemory on youraccessDRAM() function call. Write Through policy requires the ENTIRE block be transferred to physical memory on a writeoperation. To move data to and from a cache block, the memcpy() function should be used. The functionprototype of memcpy() is deJined as follows:void* memcpy(void* dest, void* src, size_t amount);where dest is the destination pointer, src is the memory to be copied, and amount is the number ofbytes to copy. A more detailed description of this function can be found in K&R.QYour TaskTo complete this project, you must complete the accessMemory() function in cachelogic.c. This functionwill handle accessing actual memory, using theaccessDRAM() function. Thus, the code in theaccessMemory() function will behave as a cache that will call the accessDRAM() function as needed (forcache misses).To ensure a variety of caches can be simulated, you will be required to dynamically support 5 properties: Associativity (ranges from 1 to 5) Number of unique indexes (2n where n ranges from 0 to 4) Block size (2n bytes where n ranges from 2 to 5) Replacement Policy (LRU and Random) Memory Synchronization Policy (Write Back and Write Through)More information about the variables you will be working with and the functions at your disposal can beascertained by looking over tips.h.You should keep the following things in mind when formulating the code: accessDRAM() requires a byte pointer when it is called. There are 4 bytes in 1 word. The tag information must be right aligned. For example, if the tag is only 25 bits for a given cacheconJiguration, the top 7 bits must always be 0. During a cache hit, highlight the word (not the whole block) you are accessing in GREEN color. During a cache miss, highlight the word (not the whole block) you are accessing in RED color. During a cache miss, you need to use a bounding box to indicate the block you are replacing
When you are moving things between cache and physical memory, a BLOCK is transferred, NOTjust a word nor a byte. Thus, if the block size is 16 bytes, when you want to move data from cacheto memory (or vice versa) you must make sure 16 bytes travel between the cache and physicalmemory on youraccessDRAM() function call. Write Through policy requires the ENTIRE block be transferred to physical memory on a writeoperation. To move data to and from a cache block, the memcpy() function should be used. The functionprototype of memcpy() is deJined as follows:void* memcpy(void* dest, void* src, size_t amount);where dest is the destination pointer, src is the memory to be copied, and amount is the number ofbytes to copy. A more detailed description of this function can be found in K&R.
Getting StartedLook over tips.h and cachelogic.c. tips.h gives you an overview of how the cache simulator is put together.A section of that Jile has been marked as important, so read it to get an idea of what functions andvariables you will be using. cachelogic.c contains a slightly more detailed explanation of what you will bewriting in the accessMemory() function.The cache data structure is divided into three levels: The Jirst level of entry is selecting which set you want. For example, cache[2] states that you aregoing to be accessing the 3rd set of the cache. This level is regulated by set_count. The next level is selecting the block you want in the set. That is speciJied by the block Jield. Forexample, cache[2].block[4] accesses the 5th block of the 3rd set. In the block is the tag, valid bit,dirty bit, and lru information. This level is regulated by the associativity of the cache. The Jinal level of entry is selecting which bytes of the block do you want retrieve or modify. Thedata contained in a block is represented by the data Jield of that block. Using the offset, a particularbyte can be referenced.There are two methods to access the LRU information of a block. The Jirst method is via lru.value, a Jieldthat will hold LRU information in integer format. The other method is via lru.data, a Jield that will holdLRU information represented in another format (its type is void*, which means it can be a pointer toanything). You are free to use either method to represent the LRU information, so long as the LRU behavesin a deterministic fashion (i.e. no two valid blocks will ever be candidates for replacement at the sametime).
y Jile other than cachelogic.c. Do notchange the prototypes of existing functions. To summarize, you can modify only the body of the givenfunctions, adding helper functions if needed.Creating Dump Files for TestingIf you prefer to use the Mars GUI, go ahead and start Mars and open your assembly Jile. Ensure that theDelayed Branching setting is enabled in the Settings menu. Now, assemble the source Jile. Then, selectthe Dump Memory option from the File menu. Ensure that the .text memory segment is selected andthat the dump format is Binary, and you should be good to go. If you prefer to use the command line, youcan do something like this:java -jar Mars.jar a db dump .text Binary output.dump input.sGetting StartedLook over tips.h and cachelogic.c. tips.h gives you an overview of how the cache simulator is put together.A section of that Jile has been marked as important, so read it to get an idea of what functions andvariables you will be using. cachelogic.c contains a slightly more detailed explanation of what you will bewriting in the accessMemory() function.The cache data structure is divided into three levels: The Jirst level of entry is selecting which set you want. For example, cache[2] states that you aregoing to be accessing the 3rd set of the cache. This level is regulated by set_count. The next level is selecting the block you want in the set. That is speciJied by the block Jield. Forexample, cache[2].block[4] accesses the 5th block of the 3rd set. In the block is the tag, valid bit,dirty bit, and lru information. This level is regulated by the associativity of the cache. The Jinal level of entry is selecting which bytes of the block do you want retrieve or modify. Thedata contained in a block is represented by the data Jield of that block. Using the offset, a particularbyte can be referenced.There are two methods to access the LRU information of a block. The Jirst method is via lru.value, a Jieldthat will hold LRU information in integer format. The other method is via lru.data, a Jield that will holdLRU information represented in another format (its type is void*, which means it can be a pointer toanything). You are free to use either method to represent the LRU information, so long as the LRU behavesin a deterministic fashion (i.e. no two valid blocks will ever be candidates for replacement at the sametime).Organization of the memory functions in TIPSIn a nutshell, the accessMemory() function acts as a communication layer between the CPU and DRAM.The code within accessMemory() manipulates the cache data structure deJined in tips.h.All your code MUST be contained in cachelogic.c speciJically in accessMemory() and possibly the LRUfunctions (depending on how you implement the LRU algorithm).
Reviews
There are no reviews yet.