src/memory/memory.c
Flag mem_process_l1_hit_access(Mem_Req* req, Mem_Queue_Entry* l1_queue_entry,
                               Addr* line_addr, L1_Data* data,
                               int lru_position) {
  Flag fill_mlc = MLC_PRESENT && req->destination != DEST_L1 &&
                  (req->type != MRT_WB && req->type != MRT_WB_NODIRTY);

  if(data) { /* not perfect l1 */
    if((req->type == MRT_DFETCH) || (req->type == MRT_DSTORE) ||
       (req->type == MRT_IFETCH)) {
      if(L1_CACHE_HIT_POSITION_COLLECT) {
        ASSERT(data->proc_id, lru_position != -1);
        if(data->prefetch && !data->seen_prefetch)  // prefetch hit
          STAT_EVENT(data->proc_id, CORE_L1_PREF_USED_POS0 + lru_position);
        else  // demand hit
          STAT_EVENT(data->proc_id, CORE_L1_DEMAND_USED_POS0 + lru_position);
      }

      if(L1_DYNAMIC_PARTITION_ENABLE &&
         L1_DYNAMIC_PARTITION_POLICY == MARGINAL_UTIL) {
        ASSERT(data->proc_id, lru_position != -1);
      }

      if(data->prefetch) {  // prefetch hit
        DEBUG(req->proc_id, "%7lld l1 prefetch hit %d\n", cycle_count,
              (int)(req->addr));
        STAT_EVENT(req->proc_id, L1_PREF_HIT);
        if(!data->seen_prefetch) {
          data->seen_prefetch = TRUE;
          // pref_ul1_pref_hit(req->proc_id, req->addr, req->loadPC,
          // lru_position, data->prefetcher_id);   // this is the last version.
          // the new change affects only 2dc prefetcher sine req->loadPC is used
          // only there in the pref_ul1_pref_hit function
          pref_ul1_pref_hit(
            req->proc_id, req->addr, data->pref_loadPC, data->global_hist,
            lru_position, data->prefetcher_id);  // FIXME: lru position FOR CMP

          STAT_EVENT(req->proc_id, L1_PREF_UNIQUE_HIT);
          STAT_EVENT(req->proc_id, PREF_L1_TOTAL_USED);
          STAT_EVENT(req->proc_id, CORE_PREF_L1_USED);
          STAT_EVENT(req->proc_id, CORE_L1_PREF_FILL_USED);
          STAT_EVENT(req->proc_id, NORESET_L1_PREF_USED);
        }
      }
    }

    if(req->type == MRT_DPRF || req->type == MRT_IPRF ||
       req->demand_match_prefetch) {
      STAT_EVENT(req->proc_id, L1_PREF_REQ_HIT);
      STAT_EVENT(req->proc_id, CORE_L1_PREF_REQ_HIT);
    } else if((req->type == MRT_DFETCH) || (req->type == MRT_DSTORE) ||
              (req->type == MRT_IFETCH)) {
      STAT_EVENT(req->proc_id, L1_DEMAND_HIT);
      STAT_EVENT(req->proc_id, CORE_L1_DEMAND_HIT);
    } else {  // CMP Watch out RA
      STAT_EVENT(req->proc_id, L1_WB_HIT);
      STAT_EVENT(req->proc_id, CORE_L1_WB_HIT);
    }
    data->dirty |= (req->type == MRT_WB);
  }

  DEBUG(req->proc_id,
        "Mem request hit in the L1  index:%ld  type:%s  addr:0x%s  l1_bank:%d  "
        "size:%d\n",
        (long int)(req - mem->req_buffer), Mem_Req_Type_str(req->type),
        hexstr64s(req->addr), req->l1_bank, req->size);

  if((req->type == MRT_DFETCH) || (req->type == MRT_DSTORE) ||
     (req->type == MRT_IFETCH)) {
    STAT_EVENT(req->proc_id, L1_HIT);
    STAT_EVENT(req->proc_id, CORE_L1_HIT);
    STAT_EVENT(req->proc_id, L1_HIT_ONPATH + req->off_path);
    if(0 && DEBUG_EXC_INSERTS) {
      printf("addr:%s hit in L1 type:%s\n", hexstr64s(req->addr),
             Mem_Req_Type_str(req->type));
    }
  }

  STAT_EVENT_ALL(L1_HIT_ALL);
  STAT_EVENT_ALL(L1_HIT_ALL_ONPATH + req->off_path);

  // cmp IGNORE
  if(req->off_path)
    STAT_EVENT(req->proc_id, L1_HIT_OFFPATH_IFETCH + MIN2(req->type, 6));
  else
    STAT_EVENT(req->proc_id, L1_HIT_ONPATH_IFETCH + MIN2(req->type, 6));

  if(!req->demand_match_prefetch &&
     (req->type == MRT_DFETCH || req->type == MRT_DSTORE ||
      req->type == MRT_IFETCH)) {
    DEBUG(req->proc_id, "Req index:%d no longer a chip demand\n", req->id);
  }

  // this is just a stat collection
  wp_process_l1_hit(data, req);

  if(L1_WRITE_THROUGH && (req->type == MRT_WB)) {
    req->state     = MRS_BUS_NEW;
    req->rdy_cycle = cycle_count + L1Q_TO_FSB_TRANSFER_LATENCY;
  } else if(fill_mlc) {
    req->state     = MRS_FILL_MLC;
    req->rdy_cycle = cycle_count + 1;
    // insert into mlc queue
    req->queue = &(mem->mlc_fill_queue);
    if(!ORDER_BEYOND_BUS)
      mem_insert_req_into_queue(
        req, req->queue,
        ALL_FIFO_QUEUES ? mlc_fill_seq_num : l1_queue_entry->priority);
    else
      mem_insert_req_into_queue(req, req->queue,
                                ALL_FIFO_QUEUES ? mlc_fill_seq_num : 0);
    mlc_fill_seq_num++;
  } else if(!req->done_func) {
    req->state = MRS_L1_HIT_DONE;
    // Free the request buffer
    mem_free_reqbuf(req);
  } else {
    req->state     = MRS_L1_HIT_DONE;
    req->rdy_cycle = freq_cycle_count(
      FREQ_DOMAIN_CORES[req->proc_id]);  // no +1 to match old performance
    // insert into core fill queue
    req->queue = &(mem->core_fill_queues[req->proc_id]);
    if(!ORDER_BEYOND_BUS)
      mem_insert_req_into_queue(req, req->queue,
                                ALL_FIFO_QUEUES ?
                                  core_fill_seq_num[req->proc_id] :
                                  l1_queue_entry->priority);
    else
      mem_insert_req_into_queue(
        req, req->queue, ALL_FIFO_QUEUES ? core_fill_seq_num[req->proc_id] : 0);
    core_fill_seq_num[req->proc_id]++;
  }

  /* Set the priority so that this entry will be removed from the l1_queue */
  l1_queue_entry->priority = Mem_Req_Priority_Offset[MRT_MIN_PRIORITY];


  if(L2L1PREF_ON)
    l2l1pref_mem(req);

  return TRUE;
}
/**************************************************************************************/
/* mem_process_l1_hit_access: */
/* Returns TRUE if l1 access is complete and needs to be removed from l1_queue
 */
Returns TRUE if l1 access is complete and needs to be removed from l1_queue
Returns TRUE if l1 access is complete and needs to be removed from l1_queue
Flag mem_process_l1_hit_access(Mem_Req* req, Mem_Queue_Entry* l1_queue_entry,
                               Addr* line_addr, L1_Data* data,
                               int lru_position) {
  Flag fill_mlc = MLC_PRESENT && req->destination != DEST_L1 &&
                  (req->type != MRT_WB && req->type != MRT_WB_NODIRTY);
  if(data) { 
    if((req->type == MRT_DFETCH) || (req->type == MRT_DSTORE) ||
       (req->type == MRT_IFETCH)) {
      if(L1_CACHE_HIT_POSITION_COLLECT) {
        ASSERT(data->proc_id, lru_position != -1);
        if(data->prefetch && !data->seen_prefetch)  
          STAT_EVENT(data->proc_id, CORE_L1_PREF_USED_POS0 + lru_position);
        else  
          STAT_EVENT(data->proc_id, CORE_L1_DEMAND_USED_POS0 + lru_position);
      }
      if(L1_DYNAMIC_PARTITION_ENABLE &&
         L1_DYNAMIC_PARTITION_POLICY == MARGINAL_UTIL) {
        ASSERT(data->proc_id, lru_position != -1);
      }
      if(data->prefetch) {  
        DEBUG(req->proc_id, "%7lld l1 prefetch hit %d\n", cycle_count,
              (int)(req->addr));
        STAT_EVENT(req->proc_id, L1_PREF_HIT);
        if(!data->seen_prefetch) {
          data->seen_prefetch = TRUE;
          pref_ul1_pref_hit(
            req->proc_id, req->addr, data->pref_loadPC, data->global_hist,
            lru_position, data->prefetcher_id);  
          STAT_EVENT(req->proc_id, L1_PREF_UNIQUE_HIT);
          STAT_EVENT(req->proc_id, PREF_L1_TOTAL_USED);
          STAT_EVENT(req->proc_id, CORE_PREF_L1_USED);
          STAT_EVENT(req->proc_id, CORE_L1_PREF_FILL_USED);
          STAT_EVENT(req->proc_id, NORESET_L1_PREF_USED);
        }
      }
    }
    if(req->type == MRT_DPRF || req->type == MRT_IPRF ||
       req->demand_match_prefetch) {
      STAT_EVENT(req->proc_id, L1_PREF_REQ_HIT);
      STAT_EVENT(req->proc_id, CORE_L1_PREF_REQ_HIT);
    } else if((req->type == MRT_DFETCH) || (req->type == MRT_DSTORE) ||
              (req->type == MRT_IFETCH)) {
      STAT_EVENT(req->proc_id, L1_DEMAND_HIT);
      STAT_EVENT(req->proc_id, CORE_L1_DEMAND_HIT);
    } else {  
      STAT_EVENT(req->proc_id, L1_WB_HIT);
      STAT_EVENT(req->proc_id, CORE_L1_WB_HIT);
    }
    data->dirty |= (req->type == MRT_WB);
  }
  DEBUG(req->proc_id,
        "Mem request hit in the L1  index:%ld  type:%s  addr:0x%s  l1_bank:%d  "
        "size:%d\n",
        (long int)(req - mem->req_buffer), Mem_Req_Type_str(req->type),
        hexstr64s(req->addr), req->l1_bank, req->size);
  if((req->type == MRT_DFETCH) || (req->type == MRT_DSTORE) ||
     (req->type == MRT_IFETCH)) {
    STAT_EVENT(req->proc_id, L1_HIT);
    STAT_EVENT(req->proc_id, CORE_L1_HIT);
    STAT_EVENT(req->proc_id, L1_HIT_ONPATH + req->off_path);
    if(0 && DEBUG_EXC_INSERTS) {
      printf("addr:%s hit in L1 type:%s\n", hexstr64s(req->addr),
             Mem_Req_Type_str(req->type));
    }
  }
  STAT_EVENT_ALL(L1_HIT_ALL);
  STAT_EVENT_ALL(L1_HIT_ALL_ONPATH + req->off_path);
  if(req->off_path)
    STAT_EVENT(req->proc_id, L1_HIT_OFFPATH_IFETCH + MIN2(req->type, 6));
  else
    STAT_EVENT(req->proc_id, L1_HIT_ONPATH_IFETCH + MIN2(req->type, 6));
  if(!req->demand_match_prefetch &&
     (req->type == MRT_DFETCH || req->type == MRT_DSTORE ||
      req->type == MRT_IFETCH)) {
    DEBUG(req->proc_id, "Req index:%d no longer a chip demand\n", req->id);
  }
  wp_process_l1_hit(data, req);
  if(L1_WRITE_THROUGH && (req->type == MRT_WB)) {
    req->state     = MRS_BUS_NEW;
    req->rdy_cycle = cycle_count + L1Q_TO_FSB_TRANSFER_LATENCY;
  } else if(fill_mlc) {
    req->state     = MRS_FILL_MLC;
    req->rdy_cycle = cycle_count + 1;
    req->queue = &(mem->mlc_fill_queue);
    if(!ORDER_BEYOND_BUS)
      mem_insert_req_into_queue(
        req, req->queue,
        ALL_FIFO_QUEUES ? mlc_fill_seq_num : l1_queue_entry->priority);
    else
      mem_insert_req_into_queue(req, req->queue,
                                ALL_FIFO_QUEUES ? mlc_fill_seq_num : 0);
    mlc_fill_seq_num++;
  } else if(!req->done_func) {
    req->state = MRS_L1_HIT_DONE;
    mem_free_reqbuf(req);
  } else {
    req->state     = MRS_L1_HIT_DONE;
    req->rdy_cycle = freq_cycle_count(
      FREQ_DOMAIN_CORES[req->proc_id]);  
    req->queue = &(mem->core_fill_queues[req->proc_id]);
    if(!ORDER_BEYOND_BUS)
      mem_insert_req_into_queue(req, req->queue,
                                ALL_FIFO_QUEUES ?
                                  core_fill_seq_num[req->proc_id] :
                                  l1_queue_entry->priority);
    else
      mem_insert_req_into_queue(
        req, req->queue, ALL_FIFO_QUEUES ? core_fill_seq_num[req->proc_id] : 0);
    core_fill_seq_num[req->proc_id]++;
  }
  l1_queue_entry->priority = Mem_Req_Priority_Offset[MRT_MIN_PRIORITY];
  if(L2L1PREF_ON)
    l2l1pref_mem(req);
  return TRUE;
}
Flag mem_process_l1_hit_access ( Mem_Req * req , Mem_Queue_Entry * l1_queue_entry , Addr * line_addr , L1_Data * data , int lru_position ) { Flag fill_mlc = MLC_PRESENT && req -> destination != DEST_L1 && ( req -> type != MRT_WB && req -> type != MRT_WB_NODIRTY ) ; if ( data ) { if ( ( req -> type == MRT_DFETCH ) || ( req -> type == MRT_DSTORE ) || ( req -> type == MRT_IFETCH ) ) { if ( L1_CACHE_HIT_POSITION_COLLECT ) { ASSERT ( data -> proc_id , lru_position != -1 ) ; if ( data -> prefetch && ! data -> seen_prefetch ) STAT_EVENT ( data -> proc_id , CORE_L1_PREF_USED_POS0 + lru_position ) ; else STAT_EVENT ( data -> proc_id , CORE_L1_DEMAND_USED_POS0 + lru_position ) ; } if ( L1_DYNAMIC_PARTITION_ENABLE && L1_DYNAMIC_PARTITION_POLICY == MARGINAL_UTIL ) { ASSERT ( data -> proc_id , lru_position != -1 ) ; } if ( data -> prefetch ) { DEBUG ( req -> proc_id , " \n " , cycle_count , ( int ) ( req -> addr ) ) ; STAT_EVENT ( req -> proc_id , L1_PREF_HIT ) ; if ( ! data -> seen_prefetch ) { data -> seen_prefetch = TRUE ; pref_ul1_pref_hit ( req -> proc_id , req -> addr , data -> pref_loadPC , data -> global_hist , lru_position , data -> prefetcher_id ) ; STAT_EVENT ( req -> proc_id , L1_PREF_UNIQUE_HIT ) ; STAT_EVENT ( req -> proc_id , PREF_L1_TOTAL_USED ) ; STAT_EVENT ( req -> proc_id , CORE_PREF_L1_USED ) ; STAT_EVENT ( req -> proc_id , CORE_L1_PREF_FILL_USED ) ; STAT_EVENT ( req -> proc_id , NORESET_L1_PREF_USED ) ; } } } if ( req -> type == MRT_DPRF || req -> type == MRT_IPRF || req -> demand_match_prefetch ) { STAT_EVENT ( req -> proc_id , L1_PREF_REQ_HIT ) ; STAT_EVENT ( req -> proc_id , CORE_L1_PREF_REQ_HIT ) ; } else if ( ( req -> type == MRT_DFETCH ) || ( req -> type == MRT_DSTORE ) || ( req -> type == MRT_IFETCH ) ) { STAT_EVENT ( req -> proc_id , L1_DEMAND_HIT ) ; STAT_EVENT ( req -> proc_id , CORE_L1_DEMAND_HIT ) ; } else { STAT_EVENT ( req -> proc_id , L1_WB_HIT ) ; STAT_EVENT ( req -> proc_id , CORE_L1_WB_HIT ) ; } data -> dirty |= ( req -> type == MRT_WB ) ; } DEBUG ( req -> proc_id , " " " \n " , ( long int ) ( req - mem -> req_buffer ) , Mem_Req_Type_str ( req -> type ) , hexstr64s ( req -> addr ) , req -> l1_bank , req -> size ) ; if ( ( req -> type == MRT_DFETCH ) || ( req -> type == MRT_DSTORE ) || ( req -> type == MRT_IFETCH ) ) { STAT_EVENT ( req -> proc_id , L1_HIT ) ; STAT_EVENT ( req -> proc_id , CORE_L1_HIT ) ; STAT_EVENT ( req -> proc_id , L1_HIT_ONPATH + req -> off_path ) ; if ( 0 && DEBUG_EXC_INSERTS ) { printf ( " \n " , hexstr64s ( req -> addr ) , Mem_Req_Type_str ( req -> type ) ) ; } } STAT_EVENT_ALL ( L1_HIT_ALL ) ; STAT_EVENT_ALL ( L1_HIT_ALL_ONPATH + req -> off_path ) ; if ( req -> off_path ) STAT_EVENT ( req -> proc_id , L1_HIT_OFFPATH_IFETCH + MIN2 ( req -> type , 6 ) ) ; else STAT_EVENT ( req -> proc_id , L1_HIT_ONPATH_IFETCH + MIN2 ( req -> type , 6 ) ) ; if ( ! req -> demand_match_prefetch && ( req -> type == MRT_DFETCH || req -> type == MRT_DSTORE || req -> type == MRT_IFETCH ) ) { DEBUG ( req -> proc_id , " \n " , req -> id ) ; } wp_process_l1_hit ( data , req ) ; if ( L1_WRITE_THROUGH && ( req -> type == MRT_WB ) ) { req -> state = MRS_BUS_NEW ; req -> rdy_cycle = cycle_count + L1Q_TO_FSB_TRANSFER_LATENCY ; } else if ( fill_mlc ) { req -> state = MRS_FILL_MLC ; req -> rdy_cycle = cycle_count + 1 ; req -> queue = & ( mem -> mlc_fill_queue ) ; if ( ! ORDER_BEYOND_BUS ) mem_insert_req_into_queue ( req , req -> queue , ALL_FIFO_QUEUES ? mlc_fill_seq_num : l1_queue_entry -> priority ) ; else mem_insert_req_into_queue ( req , req -> queue , ALL_FIFO_QUEUES ? mlc_fill_seq_num : 0 ) ; mlc_fill_seq_num ++ ; } else if ( ! req -> done_func ) { req -> state = MRS_L1_HIT_DONE ; mem_free_reqbuf ( req ) ; } else { req -> state = MRS_L1_HIT_DONE ; req -> rdy_cycle = freq_cycle_count ( FREQ_DOMAIN_CORES [ req -> proc_id ] ) ; req -> queue = & ( mem -> core_fill_queues [ req -> proc_id ] ) ; if ( ! ORDER_BEYOND_BUS ) mem_insert_req_into_queue ( req , req -> queue , ALL_FIFO_QUEUES ? core_fill_seq_num [ req -> proc_id ] : l1_queue_entry -> priority ) ; else mem_insert_req_into_queue ( req , req -> queue , ALL_FIFO_QUEUES ? core_fill_seq_num [ req -> proc_id ] : 0 ) ; core_fill_seq_num [ req -> proc_id ] ++ ; } l1_queue_entry -> priority = Mem_Req_Priority_Offset [ MRT_MIN_PRIORITY ] ; if ( L2L1PREF_ON ) l2l1pref_mem ( req ) ; return TRUE ; }
mem_process_l1_hit_access:
Returns TRUE if l1 access is complete and needs to be removed from l1_queue
mem_process_l1_hit_access : Returns TRUE if l1 access is complete and needs to be removed from l1_queue
/* not perfect l1 */ // prefetch hit // demand hit // prefetch hit // pref_ul1_pref_hit(req->proc_id, req->addr, req->loadPC, // lru_position, data->prefetcher_id);   // this is the last version. // the new change affects only 2dc prefetcher sine req->loadPC is used // only there in the pref_ul1_pref_hit function // FIXME: lru position FOR CMP // CMP Watch out RA // cmp IGNORE // this is just a stat collection // insert into mlc queue // Free the request buffer // no +1 to match old performance // insert into core fill queue /* Set the priority so that this entry will be removed from the l1_queue */