public String Read(int Addr) {
        
        String WORD="";
        Integer OffSet, TAG;
        
        boolean OntheCache = false;
        
        OffSet = Addr%4; 
        TAG = Addr - OffSet; // block's TAG: we have first block's physical address only
        String sOffSet = ""; //00,01,10,11
        sOffSet = (OffSet<=1) ? "0" + String.format("%s", OffSet) : Long.toBinaryString(OffSet);
        int block=0;
        
        // check if it is in the CACHE block by block
        for(int i=0; i<=15; i++) {
            
            if (GetBlockTag(i) == TAG){ 
                /** READ HIT !.. **/
                //Set offSet bits to select the word asked
                CACHE_DATA[i][5] = Integer.parseInt(sOffSet.substring(0,1)); // first bit of offset 01 -> 1
                CACHE_DATA[i][6] = Integer.parseInt(sOffSet.substring(1,2)); // second bit of offset 01 -> 0
               //System.out.println("Read Hit!");
               // ControlPanel.jMessages.append("Read Hit!\n");
                
                
                OntheCache = true;
                block = i; // found in the ith block
                break;
            }
        }
        
        if (!OntheCache) {
            
            /** READ MISS !..
             * Fetch words from Memory
             * Since Direct Mapping is used, after read-miss data will be exchanged between memory and cache 
             * new block is placed in  cache index  which is modulo 16 of the asked address 
             * for example: asked address is 2046: 2046-(2046mod4)=2044
             * 2044 mod 16 = 12th block on the cache will be swapped
             * 4 words will be fetched since one block has 4 words
             * fetch from 2044, 2045, 2046, 2047; 2046-(2046mod4)=2044
             * Before fetching, current data on the cache must be checked if it is updated 
             * Since we use Write-Back method, if dirty Bit is set, data must be written to memory
             * But we will give the priority to read, therefore first we will save the data on
             * write buffer, after read-miss finishes, write-back will be done
             */
            //System.out.println("Read Miss!");
           // ControlPanel.jMessages.append("Read Miss!\n");
            
            block = TAG%16; // This block will be exchanged
            if  (CACHE_DATA[block][1] == 1) { //if it is dirty, write back to memory
                WriteBuffer.set(TakeDataBitsFromtheBlock(block,0,99)); //data saved on the buffer
                WriteBack(block); 
            }
            Fetch(TAG); 
           
            //Select the Word asked by setting offset bits
            CACHE_DATA[block][5] = Integer.parseInt(sOffSet.substring(0,1)); // second bit of offset 01 -> 0
            CACHE_DATA[block][6] = Integer.parseInt(sOffSet.substring(1,2)); // first bit of offset 01 -> 1
                 
       }
        
        WORD = GetWordFromBlock(block);
                
        return WORD;
    }