$30
Implement a Cache that meets the specifications below.
Cache Specifications
Parameter
Value
CPU Address
10 bits
Cache Data Size
24 Bytes
Number of Sets
2
Number of Ways (Blocks per Set)
3
Block Size
4 Bytes
Write Policy
Write Back
Eviction Policy
LRU
Inputs
Input Pin
Size (bits)
Description
CpuAddress
10 bits
The address the CPU wants to read from or write to
CpuRead
1 bit
1 If the CPU wants to Read and 0 otherwise
CpuWrite
1 bit
1 if the CPU wants to Write and 0 otherwise
CpuWriteValue
8 bits
The value the CPU wants to Write. Will only have a meaningful value is CpuWrite = 1
LineFromMem
32 bits
The contents of the block you requested to read from memory
All of the inputs will only be valid during the SINGLE clock cycle that your Cache says it is Ready. This means that you will have to save your inputs if you need them beyond that first clock cycle.
The only exception to this is LineFromMem. It will be valid as long as you say you want to read from memory. If you aren’t reading from memory LineFromMem will be EEE… and Red (an Error). Don’t worry about this. It is normal behavior. As soon as your request to read from memory it will be the value at MemAddress.
Outputs
Output Pin
Size (in bits)
Description
Ready
1 bit
1 if your Cache is ready to start a new request. If you are ready to start a new request it means you must have finished the old request. So at this point in time, your output will be checked.
DidContain
1 bit
1 if your Cache contained the value the CPU asked for and 0 otherwise. Checked when Ready == 1
ByteRead
8 bits
The value at the address the CPU requested to read. Checked when Ready == 1 and the last request the CPU made was a read.
MemAddress
8 bits
The address of the block you want to read from memory or the address of the block that you want to write Line2Memory back to.
MemRead
1 bit
1 if you want to read the block at MemAddress and 0 otherwise.
MemWrite
1 bit
1 if you want to write Line2Mem to MemAddress and 0 otherwise.
Line2Mem
32 bits
The block you want to write to MemAddress
Why is MemAddress 8 bits instead of 10?
Our Memory is going to be Block Addressable instead of Byte Addressable. This means that each block has an address instead of each byte. This enables you to read a block from/write a block to memory in a single clock cycle which should help simplify your design a little. It should be pretty easy to figure out which bits to drop to form MemAddress. Hint: it is bits that help you pick out the byte within a block.
When are outputs checked?
● DidContain: At the end of every operation once your circuit becomes Ready.
● ByteRead: At the end of a read operation once your circuit becomes Ready.
● MemRead: Whenever you read from memory it increments the MissCounter.
Timing Restrictions
Your circuit must be able to complete a Read/Write request within 10 clock cycles. If you take longer than 10 clock cycles the tester will automatically advance to the next case. This will cause your Cache to start to “desync” from the tester and so will get everything wrong if you are taking too long. You can certainly finish in less than 10 clock cycles, I only took 7 but I’ve seen students get as low as 2.
Testing
Open the grading circuit
Click on the Cache folder and select reload library
Double-check that your updates are visible inside of the grader. If your changes don’t show up, close your solution circuit and try reloading again. If the changes still fail to show up, close the grader and reopen it and then reload the library.
Open the subcircuit named CheckerCirc and
Right-click the ROM inside of it
Select Load Image
Select one of the provided files that ends in _sol.txt.
Eample: seq_read1_seq_mem_sol.txt
Open the subcircuit named InputGeneratorCirc and
Right-click the ROM inside of it
Select Load Image
Select the corresponding input file that matches with the solution file. This will be the file that shares its name with the first part of the solution file.
Example: seq_read1.txt
Go back to the main subcircuit
Right-click the RAM
Select Load Image
Select the corresponding memory file that matches with the solution file. This will be the file that shares its name with the second part of the solution file.
Example: seq_mem.txt
Anytime your reset a test case you must RELOAD the RAM! The RAM is the only one that has to be reloaded. The ROM’s will maintain the last value you put in them.
At the bottom of the the main circuit you will find probes that show your circuit’s inputs, outputs, answers, how many reads you got correct, how many times you said you hit, and how many misses(memory reads) you had. This is a good place to look when you are debugging to get a high level overview of what your cache is doing.
If you open the solution files in a text editor you will find what the correct values for all of the stats should be for that test case.
Testing Order
I recommend running the test cases in the following order
seq_read1_seq_mem_sol.txt
seq_write1_seq_mem_sol.txt
set1_targeted_read_seq_mem_sol.txt
set0_targeted_write_seq_mem_sol.txt
random0_seq_mem_sol.txt
final_test_rand_mem_mem_sol.txt.
User Created Tests
If you want to make your own test, you can use cache_test_maker.py to create your own tests. It should be fairly easy to follow the documentation inside if you feel like using it.