src/memory/memory.c
static Flag mem_complete_mlc_access(Mem_Req*         req,
                                    Mem_Queue_Entry* mlc_queue_entry,
                                    int*             l1_queue_insertion_count,
                                    int*             reserved_entry_count) {
  Addr      line_addr;
  MLC_Data* data;
  int       lru_position   = -1;
  Flag      update_mlc_lru = TRUE;

  if(!PREFETCH_UPDATE_LRU_MLC &&
     (req->type == MRT_DPRF || req->type == MRT_IPRF))
    update_mlc_lru = FALSE;
  data = (MLC_Data*)cache_access(&MLC(req->proc_id)->cache, req->addr,
                                 &line_addr, update_mlc_lru);  // access MLC

  if(data || PERFECT_MLC) { /* mlc hit */
    // if exclusive cache, invalidate the line in L2 if there is a done function
    // to transfer the data to MLC -- also need to propagate the dirty to MLC
    Flag mlc_hit_access = mem_process_mlc_hit_access(
      req, mlc_queue_entry, &line_addr, data, lru_position);
    if(!mlc_hit_access) {
      return FALSE;
    } else {
      if(!PREF_ORACLE_TRAIN_ON &&
         ((req->type == MRT_DFETCH) || (req->type == MRT_DSTORE) ||
          (PREF_I_TOGETHER && req->type == MRT_IFETCH) ||
          (PREF_TRAIN_ON_PREF_MISSES && req->type == MRT_DPRF))) {
        // Train the Data prefetcher
        ASSERT(req->proc_id, data);
        ASSERT(req->proc_id, req->proc_id == data->proc_id);
        ASSERT(req->proc_id, req->proc_id == req->addr >> 58);
        pref_umlc_hit(req->proc_id, req->addr, req->loadPC, req->global_hist);
      }

      if(MLC_WRITE_THROUGH && (req->type == MRT_WB)) {
        req->queue = &(mem->l1_queue);
        mem_insert_req_into_queue(req, req->queue,
                                  ALL_FIFO_QUEUES ? l1_seq_num : 0);
        l1_seq_num++;
        (*l1_queue_insertion_count) += 1;
        STAT_EVENT(req->proc_id, L1_ACCESS);
      }
      return TRUE;
    }
  } else { /* mlc miss */
    /* if req is wb then either fill mlc or try again */
    Flag mlc_miss_send_l1 = (MLC_WRITE_THROUGH && (req->type == MRT_WB)) ||
                            ((req->type != MRT_WB) &&
                             (req->type != MRT_WB_NODIRTY));
    Flag mlc_miss_access = mem_process_mlc_miss_access(req, mlc_queue_entry,
                                                       &line_addr, data);
    if(mlc_miss_access && mlc_miss_send_l1) {
      DEBUG(
        req->proc_id,
        "mlc miss request is inserted to l1 queue rc:%d mlc:%d bo:%d lf:%d\n",
        mem->req_count, mem->mlc_queue.entry_count, mem->l1_queue.entry_count,
        mem->mlc_fill_queue.entry_count);

      req->queue = &(mem->l1_queue);
      mem_insert_req_into_queue(
        req, req->queue,
        ALL_FIFO_QUEUES ? l1_seq_num : 0);  // queue full check is done in
                                            // mem_process_mlc_miss_access
      l1_seq_num++;
      (*l1_queue_insertion_count) += 1;
      if(HIER_MSHR_ON && (req->type != MRT_WB) &&
         (req->type != MRT_WB_NODIRTY)) {
        (*reserved_entry_count) += 1;
        req->reserved_entry_count += 1;
      }
      STAT_EVENT(req->proc_id, L1_ACCESS);

      if(!PREF_ORACLE_TRAIN_ON &&
         ((req->type == MRT_DFETCH) || (req->type == MRT_DSTORE) ||
          (PREF_I_TOGETHER && req->type == MRT_IFETCH) ||
          (PREF_TRAIN_ON_PREF_MISSES && req->type == MRT_DPRF))) {
        // Train the Data prefetcher
        pref_umlc_miss(req->proc_id, req->addr, req->loadPC, req->global_hist);
      }

      return TRUE;
    } else if(!mlc_miss_access) {
      return FALSE;
    }
    return TRUE;
  }
  ASSERT(req->proc_id, 0);
}
/**************************************************************************************/
/* mem_complete_mlc_access: */
/* Returns TRUE if mlc access is complete and needs to be removed from mlc_queue
 */
Returns TRUE if mlc access is complete and needs to be removed from mlc_queue
Returns TRUE if mlc access is complete and needs to be removed from mlc_queue
static Flag mem_complete_mlc_access(Mem_Req*         req,
                                    Mem_Queue_Entry* mlc_queue_entry,
                                    int*             l1_queue_insertion_count,
                                    int*             reserved_entry_count) {
  Addr      line_addr;
  MLC_Data* data;
  int       lru_position   = -1;
  Flag      update_mlc_lru = TRUE;
  if(!PREFETCH_UPDATE_LRU_MLC &&
     (req->type == MRT_DPRF || req->type == MRT_IPRF))
    update_mlc_lru = FALSE;
  data = (MLC_Data*)cache_access(&MLC(req->proc_id)->cache, req->addr,
                                 &line_addr, update_mlc_lru);  
  if(data || PERFECT_MLC) { 
    Flag mlc_hit_access = mem_process_mlc_hit_access(
      req, mlc_queue_entry, &line_addr, data, lru_position);
    if(!mlc_hit_access) {
      return FALSE;
    } else {
      if(!PREF_ORACLE_TRAIN_ON &&
         ((req->type == MRT_DFETCH) || (req->type == MRT_DSTORE) ||
          (PREF_I_TOGETHER && req->type == MRT_IFETCH) ||
          (PREF_TRAIN_ON_PREF_MISSES && req->type == MRT_DPRF))) {
        ASSERT(req->proc_id, data);
        ASSERT(req->proc_id, req->proc_id == data->proc_id);
        ASSERT(req->proc_id, req->proc_id == req->addr >> 58);
        pref_umlc_hit(req->proc_id, req->addr, req->loadPC, req->global_hist);
      }
      if(MLC_WRITE_THROUGH && (req->type == MRT_WB)) {
        req->queue = &(mem->l1_queue);
        mem_insert_req_into_queue(req, req->queue,
                                  ALL_FIFO_QUEUES ? l1_seq_num : 0);
        l1_seq_num++;
        (*l1_queue_insertion_count) += 1;
        STAT_EVENT(req->proc_id, L1_ACCESS);
      }
      return TRUE;
    }
  } else { 
    Flag mlc_miss_send_l1 = (MLC_WRITE_THROUGH && (req->type == MRT_WB)) ||
                            ((req->type != MRT_WB) &&
                             (req->type != MRT_WB_NODIRTY));
    Flag mlc_miss_access = mem_process_mlc_miss_access(req, mlc_queue_entry,
                                                       &line_addr, data);
    if(mlc_miss_access && mlc_miss_send_l1) {
      DEBUG(
        req->proc_id,
        "mlc miss request is inserted to l1 queue rc:%d mlc:%d bo:%d lf:%d\n",
        mem->req_count, mem->mlc_queue.entry_count, mem->l1_queue.entry_count,
        mem->mlc_fill_queue.entry_count);
      req->queue = &(mem->l1_queue);
      mem_insert_req_into_queue(
        req, req->queue,
        ALL_FIFO_QUEUES ? l1_seq_num : 0);  
      l1_seq_num++;
      (*l1_queue_insertion_count) += 1;
      if(HIER_MSHR_ON && (req->type != MRT_WB) &&
         (req->type != MRT_WB_NODIRTY)) {
        (*reserved_entry_count) += 1;
        req->reserved_entry_count += 1;
      }
      STAT_EVENT(req->proc_id, L1_ACCESS);
      if(!PREF_ORACLE_TRAIN_ON &&
         ((req->type == MRT_DFETCH) || (req->type == MRT_DSTORE) ||
          (PREF_I_TOGETHER && req->type == MRT_IFETCH) ||
          (PREF_TRAIN_ON_PREF_MISSES && req->type == MRT_DPRF))) {
        pref_umlc_miss(req->proc_id, req->addr, req->loadPC, req->global_hist);
      }
      return TRUE;
    } else if(!mlc_miss_access) {
      return FALSE;
    }
    return TRUE;
  }
  ASSERT(req->proc_id, 0);
}
static Flag mem_complete_mlc_access ( Mem_Req * req , Mem_Queue_Entry * mlc_queue_entry , int * l1_queue_insertion_count , int * reserved_entry_count ) { Addr line_addr ; MLC_Data * data ; int lru_position = -1 ; Flag update_mlc_lru = TRUE ; if ( ! PREFETCH_UPDATE_LRU_MLC && ( req -> type == MRT_DPRF || req -> type == MRT_IPRF ) ) update_mlc_lru = FALSE ; data = ( MLC_Data * ) cache_access ( & MLC ( req -> proc_id ) -> cache , req -> addr , & line_addr , update_mlc_lru ) ; if ( data || PERFECT_MLC ) { Flag mlc_hit_access = mem_process_mlc_hit_access ( req , mlc_queue_entry , & line_addr , data , lru_position ) ; if ( ! mlc_hit_access ) { return FALSE ; } else { if ( ! PREF_ORACLE_TRAIN_ON && ( ( req -> type == MRT_DFETCH ) || ( req -> type == MRT_DSTORE ) || ( PREF_I_TOGETHER && req -> type == MRT_IFETCH ) || ( PREF_TRAIN_ON_PREF_MISSES && req -> type == MRT_DPRF ) ) ) { ASSERT ( req -> proc_id , data ) ; ASSERT ( req -> proc_id , req -> proc_id == data -> proc_id ) ; ASSERT ( req -> proc_id , req -> proc_id == req -> addr >> 58 ) ; pref_umlc_hit ( req -> proc_id , req -> addr , req -> loadPC , req -> global_hist ) ; } if ( MLC_WRITE_THROUGH && ( req -> type == MRT_WB ) ) { req -> queue = & ( mem -> l1_queue ) ; mem_insert_req_into_queue ( req , req -> queue , ALL_FIFO_QUEUES ? l1_seq_num : 0 ) ; l1_seq_num ++ ; ( * l1_queue_insertion_count ) += 1 ; STAT_EVENT ( req -> proc_id , L1_ACCESS ) ; } return TRUE ; } } else { Flag mlc_miss_send_l1 = ( MLC_WRITE_THROUGH && ( req -> type == MRT_WB ) ) || ( ( req -> type != MRT_WB ) && ( req -> type != MRT_WB_NODIRTY ) ) ; Flag mlc_miss_access = mem_process_mlc_miss_access ( req , mlc_queue_entry , & line_addr , data ) ; if ( mlc_miss_access && mlc_miss_send_l1 ) { DEBUG ( req -> proc_id , " \n " , mem -> req_count , mem -> mlc_queue . entry_count , mem -> l1_queue . entry_count , mem -> mlc_fill_queue . entry_count ) ; req -> queue = & ( mem -> l1_queue ) ; mem_insert_req_into_queue ( req , req -> queue , ALL_FIFO_QUEUES ? l1_seq_num : 0 ) ; l1_seq_num ++ ; ( * l1_queue_insertion_count ) += 1 ; if ( HIER_MSHR_ON && ( req -> type != MRT_WB ) && ( req -> type != MRT_WB_NODIRTY ) ) { ( * reserved_entry_count ) += 1 ; req -> reserved_entry_count += 1 ; } STAT_EVENT ( req -> proc_id , L1_ACCESS ) ; if ( ! PREF_ORACLE_TRAIN_ON && ( ( req -> type == MRT_DFETCH ) || ( req -> type == MRT_DSTORE ) || ( PREF_I_TOGETHER && req -> type == MRT_IFETCH ) || ( PREF_TRAIN_ON_PREF_MISSES && req -> type == MRT_DPRF ) ) ) { pref_umlc_miss ( req -> proc_id , req -> addr , req -> loadPC , req -> global_hist ) ; } return TRUE ; } else if ( ! mlc_miss_access ) { return FALSE ; } return TRUE ; } ASSERT ( req -> proc_id , 0 ) ; }
mem_complete_mlc_access:
Returns TRUE if mlc access is complete and needs to be removed from mlc_queue
mem_complete_mlc_access : Returns TRUE if mlc access is complete and needs to be removed from mlc_queue
// access MLC /* mlc hit */ // if exclusive cache, invalidate the line in L2 if there is a done function // to transfer the data to MLC -- also need to propagate the dirty to MLC // Train the Data prefetcher /* mlc miss */ /* if req is wb then either fill mlc or try again */ // queue full check is done in // mem_process_mlc_miss_access // Train the Data prefetcher