In this lab, you will implement a direct-mapped cache for read-only memory in Logisim. While this lab is required, it includes an open-ended component at the end where you can earn some extra credit for making improvements to the cache. You must make at least one improvement, but you can add additional functionality to the cache for up to an assignment worth of extra credit (three additional improvements).
The memory system you are implementing will use eight bit addresses and a four-entry cache with four byte cache lines. Before starting your implementation, answer the following questions:
Start Logisim with the following command:
$ java -jar /home/curtsinger/bin/logisim.jar &
Create a new Logisim file named cache.circ
. You will build the main cache in the main
subcircuit, but first we need to build a single cache entry. Create a subcircuit called cache-entry
and add the following input pins:
tag
byte_offset
clock
data_in
You should also set up the following output pins:
data_out
(8 bits)miss
(1 bit)Once you have set up your subcircuit inputs and outputs, you will need to add six registers to your entry. Four eight bit data registers to hold the four bytes held in this cache entry, a one bit valid
register that indicates when a cache holds valid data, and a tag
register to store the tag for the currently cached data.
Use the byte_offset
input and a multiplexor to select the appropriate cached byte in your cache entry subcircuit.
Use a comparator element (available under Logisim’s “Arithmetic” category) to check whether the tag
input pin matches the tag stored in your tag register. Use the result of this comparison and the value stored in the valid register to determine whether or not there was a cache miss.
When there is a cache miss, the main circuit will load the requested data from memory and pass this to the data_in
pin. Use a splitter (available in Logisim’s “Wiring” category) to break the data_in
pin into four separate bytes to be stored in each of the four data registers.
Set up your cache entry to store the value passed in on data_in
when there is a cache miss. Once you have tested your cache entry circuit, raise your hand and I will double-check it with you.
Use your completed cache entry subcircuit to build a four-entry cache in the main
subcircuit. You will need the following elements:
cache-entry
subcircuitsaddress
input pindata_out
output pinSet up your ROM element to use 32 bit data width; it will return all four bytes for a cache entry in one read. Because you will load four bytes at a time, the ROM element will only need six bit addresses. These will be the six most-significant bits of the requested address; all four of the bytes selected with the byte offset bits will be returned in the 32 bit result.
address
input into the tag, index, and byte offset bits.tag
and byte_offset
values to all four cache entries.data_in
.data_in
pins on each cache entry.There are a few problems with this cache implementation. Fix at least one of these problems. If you fix more than one, you may earn extra credit.
miss
output from the appropriate cache entry to determine whether ROM is accessed. Hint: the sel
input will be useful for controlling whether or not memory is accessed.write_data
and write_enable
pins to the main circuit. You will need to change your ROM element to a RAM element. You should implement a write-through policy; every write goes to both the cache and RAM. Other policies are more complex.If there is a different problem with this cache that you would like to fix instead, talk to me or send an email describing the problem and your planned fix.