bool memory_c::store_load_forwarding(Op *mem_op,int threadid) { m_mshr_entry_s *entry; if(mem_op->mem_type == 1) entry = search_matching_mshr(mem_op->ld_vaddr); if(mem_op->mem_type == 2) entry = search_matching_mshr(mem_op->st_vaddr); //check the cache block address not the actual address since the whole cache block is brought in. if(!entry) return false; else{ if(mem_op->mem_type ==1 && entry->m_mem_req->m_type == 2){ ADDRINT entry_addr = entry->m_mem_req->m_addr; entry_addr += entry->m_mem_req->m_size; ADDRINT mem_addr = mem_op->ld_vaddr; mem_addr += mem_op->mem_read_size; if ((entry->m_mem_req->m_addr <= mem_op->ld_vaddr) && (entry_addr >= mem_addr)){ store_load_forwarding_count += 1; store_load_forwarding_count_thread[threadid] +=1 ; return true;} return false;} if(mem_op->mem_type ==2 && entry->m_mem_req->m_type == 2){ ADDRINT entry_addr = entry->m_mem_req->m_addr; entry_addr += entry->m_mem_req->m_size; ADDRINT mem_addr = mem_op->st_vaddr; mem_addr += mem_op->mem_write_size; if ((entry->m_mem_req->m_addr <= mem_op->st_vaddr) && (entry_addr >= mem_addr)){ // store_load_forwarding_count += 1; return true;} return false;} else return false;} /* For Lab #2, you need to fill out this function */ }
bool memory_c::store_store_forwarding(Op *mem_op) { /* For Lab #2, you need to fill out this function */ bool forward_success=false; m_mshr_entry_s *entry = search_matching_mshr(mem_op->st_vaddr); if(entry!=NULL) { ADDRINT current_m_addr = mem_op->st_vaddr; int current_m_size = mem_op->mem_write_size; list<Op *>::const_iterator cii; for (cii = entry->req_ops.begin() ; cii != entry->req_ops.end(); cii++) { Op *match_op = (*cii); if(match_op->mem_type == MEM_ST) { ADDRINT matched_m_addr = match_op->st_vaddr; int matched_m_size = match_op->mem_write_size; if ((matched_m_addr <= current_m_addr) && ((matched_m_addr + matched_m_size) >= (current_m_addr + current_m_size))) { forward_success=true; break; } } } } return forward_success; }
void memory_c::fill_queue() { /* For Lab #2, you need to fill out this function */ /* CAUTION!: This function is not completed. Please complete this function */ if (dram_out_queue.empty()) return; dram_out_queue.sort(); mem_req_s *req = dram_out_queue.front(); dram_out_queue.pop_front(); /* insert into cache */ cache_insert(data_cache,req->m_addr); /* search for matching mshr entry */ m_mshr_entry_s *entry = search_matching_mshr(req->m_addr); while(entry->req_ops.size()) { Op *w_op = entry->req_ops.front(); broadcast_rdy_op(w_op); entry->req_ops.pop_front(); } /* The following code will free mshr entry */ list<m_mshr_entry_s *>::iterator mii = search_matching_mshr_itr(req->m_addr); m_mshr.erase(mii); free_mshr_entry(entry); }
bool memory_c::check_piggyback(Op *mem_op) { bool match = false; ADDRINT addr; if (mem_op->mem_type == MEM_LD) addr = mem_op->ld_vaddr; else addr = mem_op->st_vaddr; m_mshr_entry_s *entry = search_matching_mshr(addr); if(!entry) { return false; } else { // cout << "\nFOUND PIGGYBACKING!" ; //if(mem_op->mem_type == entry->m_mem_req->m_type || (mem_op->mem_type==MEM_LD && entry->m_mem_req->m_type==MRT_DSTORE)){ // if(mem_op->mem_type==MEM_LD){ entry->req_ops.push_back(mem_op); //} //else // entry->req_ops.push_back(NULL); // cout << "returning true"; return true; } }
void memory_c::fill_queue(void) { /* For Lab #2, you need to fill out this function */ /* CAUTION!: This function is not completed. Please complete this function */ if (dram_out_queue.empty()) return; mem_req_s *req = dram_out_queue.front(); dram_out_queue.pop_front(); /* search for matching mshr entry */ if(!(req->m_state == MEM_DRAM_OUT)) return; // cout << "\nIN fill queue"; //req->m_state = MEM_DRAM_OUT; // cout << "\nnumber of entries in out queue " << dram_out_queue.size(); m_mshr_entry_s *entry = search_matching_mshr(req->m_addr); dcache_insert(req->m_addr); // cout << "\ninserted into dcache " << req->m_addr; //in insert insert the physical address , insert the PTE as well. // cout << "\nNumber of entries in req ops " << entry->req_ops.size(); while(entry->req_ops.size()) { Op *w_op = new Op; w_op = entry->req_ops.front(); // if(w_op->mem_type == 1) // dcache_insert(w_op->ld_vaddr); // if(w_op->mem_type == 2) // dcache_insert(w_op->st_vaddr); //cout << "broadcastin now\n"; w_op->write_flag = false; //if(entry->m_mem_req->m_type == MRT_DSTORE) // w_op = NULL; broadcast_rdy_op(w_op); entry->req_ops.pop_front(); } //dcache_insert(req->m_addr); //insert the value into the DCACHE /* The following code will free mshr entry */ list<m_mshr_entry_s *>::iterator mii = search_matching_mshr_itr(req->m_addr); m_mshr.erase(mii); free_mshr_entry(entry); }
void memory_c::fill_queue() { //static bool delay_pte_load_done = false; /* For Lab #2, you need to fill out this function */ /* CAUTION!: This function is not completed. Please complete this function */ // if(delay_pte_load_done) // { // pte_load_done = true; // delay_pte_load_done = false; // } while(!temp_mem_queue.empty()) { Op *WB_op = temp_mem_queue.front(); fill_retire_queue(WB_op); temp_mem_queue.pop_front(); } if (dram_out_queue.empty()) return; mem_req_s *req = dram_out_queue.front(); dram_out_queue.pop_front(); /* search for matching mshr entry */ m_mshr_entry_s *entry = search_matching_mshr(req->m_addr); dcache_insert(req->m_addr); while(entry->req_ops.size()) { Op *w_op = entry->req_ops.front(); if(w_op->opcode == OP_LD_PTE) { pte_load_done = true; } else broadcast_rdy_op(w_op); entry->req_ops.pop_front(); } /* The following code will free mshr entry */ list<m_mshr_entry_s *>::iterator mii = search_matching_mshr_itr(req->m_addr); m_mshr.erase(mii); free_mshr_entry(entry); }
bool memory_c::check_piggyback(Op *mem_op) { bool match = false; ADDRINT addr; if (mem_op->mem_type == MEM_LD) addr = mem_op->ld_vaddr; else addr = mem_op->st_vaddr; m_mshr_entry_s *entry = search_matching_mshr(addr); if(!entry) { return false; } else { entry->req_ops.push_back(mem_op); return true; } }
bool memory_c::store_store_forwarding(Op *mem_op) { /* This function is called only if mem_op is a LOAD instruction. Search for a matching address in the MSHR. If found, check if forwarding is possible. If yes, return TRUE else return FALSE */ bool can_forward=false; ADDRINT current_m_addr,current_m_size; if(mem_op->mem_type==MEM_ST) // for store-store forwarding { current_m_addr=mem_op->st_vaddr; current_m_size=(ADDRINT)mem_op->mem_write_size; } m_mshr_entry_s *entry = search_matching_mshr(current_m_addr); if(entry!=NULL) { list <Op *>::const_iterator cii; for(cii=entry->req_ops.begin(); cii != entry->req_ops.end(); cii++) { Op* op=(*cii); if (op->mem_type == MEM_ST) { if ((op->st_vaddr <= current_m_addr) && (op->st_vaddr + op->mem_write_size >= current_m_addr + current_m_size)) { // store-store forwarding possible can_forward=true; break; } } } } return can_forward; }