#include "interface.h" // Do NOT edit interface .h #include "sample_prefetcher.h" //#include "base.h" //#include "mshr.h" //#include "pref_mshr.h" //#include "accessmap.h" //#include "adaptive.h" // Storages. // MSHR for demand requests(0 bits) MissStatusHandlingRegister *mshr; // MSHR for prefetch requests(901 bits) PrefetchMissStatusHandlingRegister *mshrpf; // Memory Access Map Table(29147 bits) MemoryAccessMapTable *pref; // Adaptive Stream Prefetcher(1696 bits) AdaptiveStreamPrefetcher *asp; // Prefetch requests for generating prefetches. // * These registers are overwritten // * only when the new demand requests are reached to the prefetcher. int NumFwdPref; // 5 bit counter int NumBwdPref; // 5 bit counter bool FwdPrefMap[MAP_Size/2]; // 128 bit register bool BwdPrefMap[MAP_Size/2]; // 128 bit register CacheAddr_t AddressRegister; // 26 bit register // Pipeline registers total budget : 292 bit // Total Budget Size: 32036 bit // // Function to initialize the prefetchers. DO NOT change the prototype of this // function. You can change the body of the function by calling your necessary // initialization functions. // void InitPrefetchers() // DO NOT CHANGE THE PROTOTYPE { // INSERT YOUR CHANGES IN HERE mshrpf = new PrefetchMissStatusHandlingRegister(); mshr = new MissStatusHandlingRegister(); pref = new MemoryAccessMapTable(); asp = new AdaptiveStreamPrefetcher(); NumFwdPref = NumBwdPref = 0; } // // Function that is called every cycle to issue prefetches should the // prefetcher want to. The arguments to the function are the current cycle, // the demand requests to L1 and L2 cache. Again, DO NOT change the prototype of this // function. You can change the body of the function by calling your necessary // routines to invoke your prefetcher. // // DO NOT CHANGE THE PROTOTYPE void IssuePrefetches( COUNTER cycle, PrefetchData_t *L1Data, PrefetchData_t * L2Data ) { // INSERT YOUR CHANGES IN HERE ///////////////////////////////////////////////////// // Housekeeping ///////////////////////////////////////////////////// mshrpf->Housekeeping(cycle); mshr->Housekeeping(cycle); pref->Housekeeping(cycle); asp->Housekeeping(cycle); ///////////////////////////////////////////////////// // L1 Prefetching ///////////////////////////////////////////////////// // L1 Prefetch // This prefetcher is based on "Adaptive Stream Prefetcher" for(int i=0; i<4; i++) { if(L1Data[i].LastRequestCycle == cycle) { asp->IssuePrefetch(cycle, L1Data[i].DataAddr, L1Data[i].hit); } } ///////////////////////////////////////////////////// ///////////////////////////////////////////////////// // L2 Prefetching (AMPM Prefetching) // // Following part is pipelined Structure // Stage sequence is written in reverse order. // (This coding style might be similar to SimpleScalar) ///////////////////////////////////////////////////// ///////////////////////////////////////////////////// ///////////////////////////////////////////////////// // Stage 3. Issue Prefetch from MSHR ///////////////////////////////////////////////////// mshrpf->PrefetchHousekeeping(mshr, cycle); ///////////////////////////////////////////////////// // Stage 2. Issue Prefetch Request to MSHR ///////////////////////////////////////////////////// // Maximum issue rate to prefetch MSHR... static const int MAX_ISSUE = 1; // This loop is implemented as a priority encoder for(int i=1, count=0; ( NumFwdPref && (count < MAX_ISSUE) && (!mshrpf->Full()) && (i<(MAP_Size/2)) ); i++) { if(FwdPrefMap[i]) { CacheAddr_t PrefAddress = AddressRegister + (i * BLK_SIZE); FwdPrefMap[i] = false; // Update Memory Access Map pref->UpdateEntry(cycle, PrefAddress); //if((GetPrefetchBit(1, PrefAddress) < 0) && // !mshr->Search(PrefAddress)) { if(!mshr->Search(PrefAddress)) { mshrpf->Issue (cycle, PrefAddress); } NumFwdPref--; count++; } } // This loop is implemented as a priority encoder for(int i=1, count=0; ( NumBwdPref && (count < MAX_ISSUE) && (!mshrpf->Full()) && (i<(MAP_Size/2)) ); i++) { if(BwdPrefMap[i] && (AddressRegister > (i * BLK_SIZE))) { CacheAddr_t PrefAddress = AddressRegister - (i * BLK_SIZE); BwdPrefMap[i] = false; // Update Memory Access Map pref->UpdateEntry(cycle, PrefAddress); //if((GetPrefetchBit(1, PrefAddress) < 0) && // !mshr->Search(PrefAddress)) { if(!mshr->Search(PrefAddress)) { mshrpf->Issue (cycle, PrefAddress); } NumBwdPref--; count++; } } ///////////////////////////////////////////////////// // Stage 1. Access to Memory Access Map Table ///////////////////////////////////////////////////// // Memory Access Map Table Access if(L2Data->LastRequestCycle == cycle) { bool MSHR_hit = mshr->Search(L2Data->DataAddr) || mshrpf->Search(L2Data->DataAddr); // Update MSHR // This stored data is used for filtering prefetch requests... if(!MSHR_hit && !L2Data->hit) { mshr->Issue(cycle, L2Data->DataAddr); } // Read prefetch candidate from Memory Access Map Table pref->IssuePrefetch(cycle, L2Data->DataAddr, MSHR_hit, FwdPrefMap, BwdPrefMap, &NumFwdPref, &NumBwdPref); AddressRegister = L2Data->DataAddr; AddressRegister &= ~(BLK_SIZE-1); } }