Example #1
0
////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// This function is called by the cache after every cache hit/miss            //
// The arguments are: the set index, the physical way of the cache,           //
// the pointer to the physical line (should contestants need access           //
// to information of the line filled or hit upon), the thread id              //
// of the request, the PC of the request, the accesstype, and finall          //
// whether the line was a cachehit or not (cacheHit=true implies hit)         //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
void CACHE_REPLACEMENT_STATE::UpdateReplacementState( 
    UINT32 setIndex, INT32 updateWayID, const LINE_STATE *currLine, 
    UINT32 tid, Addr_t PC, UINT32 accessType, bool cacheHit )
{
    // What replacement policy?
    if( replPolicy == CRC_REPL_LRU ) 
    {
        UpdateLRU( setIndex, updateWayID );
    }
    else if( replPolicy == CRC_REPL_RANDOM )
    {
        // Random replacement requires no replacement state update
    }
    else if( replPolicy == CRC_REPL_CONTESTANT )
    {
      if (cacheHit) 
      {
        

      }
    }


}
Example #2
0
/*============================================================================
**
** Function Name:       Read
**
** Visibility:          Public
**
** Description:         Read data from the cache. On a miss, 
**                      identifies LRU and evicts the data prior to reading data 
**                      from next lower level memory.
**
** Invocation:          By the CPU of adjecent memory hierarchy.
**
** Input Parameters:    const UINT32 address, 
**
** Return Values:       UINT8 data
**                      
**==========================================================================*/
UINT8 CCacheWriteThru::Read(const UINT32 address)
{
	// Separate tag, index and offset bits
    UINT32 offset = GetOffsetBits(address);
    UINT32 index = GetIndexBits(address);
    UINT32 tag = GetTagBits(address);
    
    UINT32 way_to_read = WAY_INVALID;
	
    // The byte to be returned
    UINT8 data = 0xFF;
    
    // Starting address of a line. 
    // Useful for reading a line from next memory hierarchy.
    UINT32 line_start_add;

#ifdef __debug__
    std::cout << std::endl << "--------------------------------------------------------" << std::endl;
    std::cout << " Address =  " << std::hex << address << std::dec << " Set No = " << index << std::endl;
#endif

	// Make sure sets exists
    if(m_sets)
    {
        // All is well
        way_to_read = MatchTagBits(m_sets[index], tag);

		if(WAY_INVALID != way_to_read)
        {
            // Cache Read hit. Yay!
            // Do nothing
            m_hits++;

#ifdef __debug__
std::cout << "Cache Read Hit. " << " Way to read = " << way_to_read << std::endl;         
#endif
        }
        else
        {
			UINT32 empty_way = GetEmptyWay(m_sets[index]);
            if(empty_way != WAY_INVALID)
            {
                // The set is not full, an empty way has been found
                m_misses++;
                way_to_read = empty_way;

#ifdef __debug__
    std::cout << "Cache miss. Set not full. " << " Way to read = " << way_to_read << std::endl;         
#endif
            }
            else
            {
                // The set is full
                // Cache read miss
                m_misses++;

                UINT32 way_lru = GetLRU(m_sets[index]);
                
                way_to_read = way_lru;

            } // if(empty_way == WAY_INVALID)

            // Need to read new cache line from L2 (Common to Is there an empty way, Conflict / Compulsory misses)
            line_start_add = (m_sets[index].lines[way_to_read].tag << (m_num_offset_bits + m_num_index_bits)) |
                                (index << m_num_offset_bits);

            for(UINT32 item_offset = 0; item_offset < m_line_size; item_offset++)
            {
                m_sets[index].lines[way_to_read].line_data[item_offset] = m_next_mem->Read(line_start_add + item_offset);
            }

		} // if(WAY_INVALID == way_to_read)

		// Get the requested byte and update the state bits
		data = m_sets[index].lines[way_to_read].line_data[offset];
        m_sets[index].lines[way_to_read].valid = 1;
        m_sets[index].lines[way_to_read].tag = tag;

        m_num_reads++;
		UpdateLRU(m_sets[index],way_to_read);

#ifdef __debug__
        printf("Data Read = %x\n", data); 
        std::cout << std::dec << "Stats: Total Reads = " << m_num_reads << " Total Writes = " << m_num_writes << std::endl;         
        std::cout << "Stats: Total Hits = " << m_hits << " Total Misses = " << m_misses << std::endl; 
        for(UINT32 item_offset = 0; item_offset < m_line_size; item_offset++)
        {
            printf("\n Line data %d = %x ", item_offset, m_sets[index].lines[way_to_read].line_data[item_offset]);
        }
#endif

	}
	else
	{
	// Sets not allocated!! SERIOUS ERROR!!!
        
	}

	return data;

}
Example #3
0
/*============================================================================
**
** Function Name:       Write
**
** Visibility:          Public
**
** Description:         Write data into the cache. Writes through to second 
**                      level memory to maintain inclusivity. On a miss, 
**                      identifies LRU and evicts the data prior to reading data 
**                      from next lower level memory
**
** Invocation:          By the CPU or adjecent memory hierarchy.
**
** Input Parameters:    const UINT32 address, const UINT8 data
**
** Return Values:       CACHE_HM // Cache hit or miss info
**                      
**==========================================================================*/
CACHE_HM CCacheWriteThru::Write(const UINT32 address, const UINT8 data)
{
    CACHE_HM hm_type = CACHE_HIT;

    // Separate Tag, index, offset bits
    UINT32 offset = GetOffsetBits(address);
    UINT32 index = GetIndexBits(address);
    UINT32 tag = GetTagBits(address);
    
    UINT32 way_to_write = WAY_INVALID;
    
    // Starting address of a line. 
    // Useful for reading a line from next memory hierarchy.
    UINT32 line_start_add;

#ifdef __debug__
    std::cout << std::endl << "--------------------------------------------------------" << std::endl;
    std::cout << " Address =  " << std::hex << address << " Data = " << data << std::dec << " Set No = " << index << std::endl;
#endif
    // Make sure sets exists
    if(m_sets)
    {
        // All is well
        way_to_write = MatchTagBits(m_sets[index], tag);
            
        if(WAY_INVALID != way_to_write)
        {
            // Cache write hit
            // Do nothing
            m_hits++;
            hm_type = CACHE_HIT;
#ifdef __debug__
std::cout << "Cache Hit. " << " Way to write = " << way_to_write << std::endl;         
#endif
        }
        else
        {
            UINT32 empty_way = GetEmptyWay(m_sets[index]);
            if(empty_way != WAY_INVALID)
            {
                // The set is not full
                m_misses++;
                hm_type = CACHE_MISS;
                way_to_write = empty_way;

#ifdef __debug__
    std::cout << "Cache miss. Set not full. " << " Way to write = " << way_to_write << std::endl;         
#endif
            }
            else
            {
                // The set is full
                // Cache write miss
                m_misses++;
                hm_type = CACHE_MISS;

                UINT32 way_lru = GetLRU(m_sets[index]);
                
                way_to_write = way_lru;
        

            }// if(WAY_INVALID == way_to_write)

            // Need to read new cache line from L2. Common to compuslory and confilct misses
            line_start_add = (m_sets[index].lines[way_to_write].tag << (m_num_offset_bits + m_num_index_bits)) |
                                        (index << m_num_offset_bits);

            for(UINT32 item_offset = 0; item_offset < m_line_size; item_offset++)
            {
                m_sets[index].lines[way_to_write].line_data[item_offset] = m_next_mem->Read(line_start_add + item_offset);
            }

        }

        m_sets[index].lines[way_to_write].line_data[offset] = data;

        // Need to write to next memeory hierarchy (L2) to maintain inclusivity

        line_start_add = (m_sets[index].lines[way_to_write].tag << (m_num_offset_bits + m_num_index_bits)) |
                                    (index << m_num_offset_bits);

        // No need to write the whole line, since we write only one byte at time.
        m_next_mem->Write(address, data);
      
        m_sets[index].lines[way_to_write].valid = 1;
        m_sets[index].lines[way_to_write].tag = tag;

        m_num_writes++;

        UpdateLRU(m_sets[index],way_to_write);
#ifdef __debug__
        std::cout << "Stats: Total Reads = " << m_num_reads << " Total Writes = " << m_num_writes << std::endl;         
        std::cout << "Stats: Total Hits = " << m_hits << " Total Misses = " << m_misses << std::endl;
        for(UINT32 item_offset = 0; item_offset < m_line_size; item_offset++)
        {
            printf("\n Line data %d = %x ", item_offset, m_sets[index].lines[way_to_write].line_data[item_offset]);
        }
#endif


    }
    else
    {
        // Sets not allocated!! SERIOUS ERROR!!!
        hm_type = hm_type;
    }

    return hm_type;

}