Addr tag ind o'set Action
lw 0 = 0000 0 000 Bytes 0-7 loaded into cache index 0.
sw 44 = 0010 1 100 Bytes 40-47 brought into cache index 1;
bytes 44-47 modified; line marked "dirty".
lw 52 = 0011 0 100 Bytes 48-55 loaded into cache index 0,
previous contents discarded.
lw 88 = 0101 1 000 Bytes 88-95 loaded into cache line 1;
previous (dirty) contents written back;
line marked "clean".
At this point, cache holds bytes 48-55 and 88-95, so references to 48, 52, 88, and 92 would be cache hits.
Addr tag ind o'set Action
lw 0 = 0000 0 000 Bytes 0-7 loaded into cache index 0. Clean miss.
sw 52 = 0011 0 100 Bytes 48-55 loaded into cache index 0.
Clean miss (since discarded line is clean).
Line is marked "dirty".
lw 68 = 0010 0 100 Bytes 64-71 brought into cache index 0;
Dirty miss (since line was dirty);
The new line is also marked clean.
lw 44 = 0010 1 100 Bytes 40-47 loaded into cache line 1;
Clean miss. Line marked "clean".
We are told that this is a TLB hit, so one of the two entries in this set matches the tag (and the corresponding valid bit is "1"). So we take the 16 bit physical page number in the TLB and prepend it to the 12 bit offset of the virtual address to form the 28 bit physical address.
Now we need to use this physical address to look up the data in the data cache. To do so, we partition the 28 bit physical address into (from the left) a 14 bit tag, a 7 bit index, and a 7 bit offset. (The offset is 7 bits because the cacheline is 128=2^7 Bytes long; the index is 7 bits because there are 512/4 = 128 = 2^7 sets of 4 cachelines each). We use the index (bits 7-13 of the physical address) to choose a set, and compare the tag (bits 27-14 of the physical address) to the four tags stored in the chosen set.
Again, we are told it is a cache hit, so the corresponding line in cache has the desired data. We use the index field (bits 0-6) of the physical address to tell us which byte in the cacheline is the first byte of the data that we are looking for.
Again, we break the physical page number into tag-index-offset as described earlier, look for the data in cache, and don't find it. Thus, we go to main memory and bring into cache the line that holds the desired data, kicking out the least recently used of the four cachelines that are in the set at the referenced index. If that line happens to be dirty, we must also write it back to memory.