this is a test program to try to get my bitwise shift operations to work. I am hoping to add this to my cache simulator program, but I can't even get this part to work. My plan is to use bit shift (<<) and (>>) to isolate parts of a given memory address (tag, set, word, etc.) but it seems that in shifting the bits back right, it is filling with the values which were previously there, rather than with 0's. Here is the program first.
#include<iostream>
#include <cmath>
struct Address{
unsigned int tag;
unsigned int r;
unsigned int word;
};
int main(){
unsigned int tempAddress = 27; //0011011
int ramSize = 128;
int cacheSize = 64;
int blockSize = 8;
int cacheLines = cacheSize / blockSize;
int addressLength = log(ramSize)/log(2);
int wordBits = log(blockSize)/log(2);
int rBits = log(cacheLines)/log(2);
int tagBits = addressLength - (wordBits + rBits);
struct Address address;
address.tag = tempAddress >> (rBits + wordBits);
address.r = tempAddress << (tagBits) >> (tagBits + wordBits);
address.word = tempAddress << (rBits + tagBits) >> (rBits + tagBits);
std::cout << "tag is: " << address.tag << "\n";
std::cout << "r is: " << address.r << "\n";
std::cout << "word is: " << address.word << "\n";
}
I've found that when my tempAddress is [0-7] it works fine because binary 7 only affects the first 3 bits. Similarly, when it is [8-63], tag and r are correct because 63 affects the first 6 bits. Upon testing many addresses, I've found that when shifting right after shifting left, the bits are being replaced with what they were before, rather than with 0s as I think they should be.
(r is the part that is in the middle. I am calling it r because in direct mapping it is called line, and in set-associative mapping it is called set)
EDIT:
As someone pointed out, expected and produced outcome would be helpful. I'd first like to keep the cache size, ram size, and block size constant, and only change the address.
So, given tempAddress = 27(0011011 in binary), word should be 011 (first 3 bits), r should be 011 (next 3), and set should be 0 (remaining bits). Output is this:
tag is: 0
r is: 3
word is: 27
I've found this to be the trend if every address between 0 and 63(inclusive) that tag and r are correct, but word is equal to address.
Now, for address = 65(1000001) Expected:
tag is: 1
r is: 0
word is: 1
Output:
tag is: 1
r is: 8
word is: 65
With these ram, cache, and block sizes, to find r, I am left shifting 1 time, and right shifting 4 times. To find word, I am left shifting 4 times, then right shifting 4 times. As I understand it, when left shifting the bits on the right are filled with 0, and when right shifting an unsigned integer, the bits on the left are filled with 0. My thought was that if I left shift until I only have the bits I need, then right shift them back to the first bits, I will have the correct values. However, consistent throughout numerous addresses, after left shifting then right shifting, the places that had 1s still do. That is why word is always equal to address, because I am shifting 4 bits both left then right. And r is always equal to the 7 bits shifted right 3 times (because I go left 1 then right 4). Am I misunderstanding how bitwise shifting works?