void memory_c::push_dram_sch_queue() { if(dram_in_queue.empty()) return; list<mem_req_s *>::iterator cii; for(cii=dram_in_queue.begin();cii!=dram_in_queue.end();) { mem_req_s* ii = (*cii); // cout << "\nPUSHING IN DRAM "; if((ii)->m_state == MEM_DRAM_IN){ // (ii)->m_state = MEM_DRAM_SCH; //mem_req_s* temp = (ii);//get_new_mem_request(); //insert temp into dram back; int temp = (ii)->m_addr/((KNOB(KNOB_DRAM_PAGE_SIZE))->getValue()*1024); int bank_id = temp%(KNOB(KNOB_DRAM_BANK_NUM)->getValue()); //mem_req_s *temp = (ii); dram_bank_sch_queue[bank_id].push_back(ii); cii = dram_in_queue.erase(cii); break; } else{ cii++; continue;} } /* For Lab #2, you need to fill out this function */ }
bool run_a_cycle(){ int i = 0; for (;;) { if (((KNOB(KNOB_MAX_SIM_COUNT)->getValue() && (cycle_count >= KNOB(KNOB_MAX_SIM_COUNT)->getValue())) || (KNOB(KNOB_MAX_INST_COUNT)->getValue() && (retired_instruction >= KNOB(KNOB_MAX_INST_COUNT)->getValue())) || (sim_end_condition))) { // please complete sim_end_condition // finish the simulation print_heartbeat(); print_stats(); return TRUE; } cycle_count++; if (!(cycle_count%5000)) { print_heartbeat(); } WB_stage(); MEM_stage(); EX_stage(); ID_stage(); FE_stage(); if (KNOB(KNOB_PRINT_PIPE_FREQ)->getValue() && !(cycle_count%KNOB(KNOB_PRINT_PIPE_FREQ)->getValue())) print_pipeline(); } return TRUE; }
void init_structures(memory_c *main_memory) // please modify init_structures function argument /** NEW-LAB2 */ { init_op_pool(); init_op_latency(); init_latches(); init_registers(); // initializing processor registers to TRUE since no data dependency when processor is powered on main_memory->init_mem(); // initializing DRAM and MSHR cache_init(data_cache, KNOB(KNOB_DCACHE_SIZE)->getValue(), KNOB(KNOB_BLOCK_SIZE)->getValue(), KNOB(KNOB_DCACHE_WAY)->getValue(), "L1 Cache"); // initializing cache }
void init_structures(memory_c *main_memory) // please modify init_structures function argument /** NEW-LAB2 */ { init_op_pool(); init_op_latency(); /* please initialize other data stucturs */ /* you must complete the function */ init_latches(); init_register_file(); //fn added by apkarande main_memory->init_mem(); //initialize main memory cache_init(data_cache,KNOB(KNOB_DCACHE_SIZE)->getValue(),KNOB(KNOB_BLOCK_SIZE)->getValue(),KNOB(KNOB_DCACHE_WAY)->getValue(),"L1 dcache"); //initialize data cache }
int get_dram_bank_id(ADDRINT addr) // NEW-LAB2 { // NEW-LAB2 // NEW-LAB2 /* utility functions that you might want to implement */ // NEW-LAB2 /* if you want to use it, you should find the right math! */ // NEW-LAB2 return (((addr)/((KNOB(KNOB_DRAM_PAGE_SIZE)->getValue()) * 1024)) % (KNOB(KNOB_DRAM_BANK_NUM)->getValue())); // (addr >> 6); // NEW-LAB2 // return 1; // NEW-LAB2 } // NEW-LAB2
void memory_c::dram_schedule() { // Traverse all entries in all the dram_bank_sch_queues. // If there is an unscheduled memory request, check the corresponding DRAM bank and see whether the DRAM bank is available. // If the corresponding bank is idle, check the last row buffer number. // If the memory request has the same row id, its a row buffer hit. So, you set req->m_rdy_cycle = cycle_count + KNOB_MEM_LATENCY_ROW_HIT // Else if row buffer miss, you set req->m_rdy_cycle = cycle_count + KNOB_MEM_LATENCY_ROW_MISS, and also set row buffer id as the row id of the memory request. // You also set dram_bank_rdy_cycle = req->m_rdy_cycle; int req_dram_row_id; list<mem_req_s *>::const_iterator cii; for(int i=0;i<m_dram_bank_num;i++) { if(dram_bank_sch_queue[i].empty()) continue; for (cii= dram_bank_sch_queue[i].begin() ; cii != dram_bank_sch_queue[i].end(); cii++) { mem_req_s* m_req = (*cii); if(m_req->m_state==MEM_DRAM_SCH) // unscheduled memory request waiting to be scheduled { if (dram_bank_rdy_cycle[i] < cycle_count) // DRAM bank output is available in row buffer { req_dram_row_id=get_dram_row_id(m_req->m_addr); if(dram_bank_open_row[i]==req_dram_row_id) // ASK: is this right way of comparing??? row buffer hit { m_req->m_rdy_cycle = cycle_count + KNOB(KNOB_MEM_LATENCY_ROW_HIT)->getValue(); dram_row_buffer_hit_count++; } else { dram_row_buffer_miss_count++; m_req->m_rdy_cycle = cycle_count + KNOB(KNOB_MEM_LATENCY_ROW_MISS)->getValue(); } dram_bank_open_row[i]=req_dram_row_id; dram_bank_rdy_cycle[i] = m_req->m_rdy_cycle; m_req->m_state=MEM_DRAM_DONE; break; // since only 1 mem request in a particular bank can be scheduled } else break; // dont iterate through the rest of the mem requests since cycle_count is < dram_bank_rdy_cycle[i] for all of them. } } } }
int get_dram_bank_id(ADDRINT addr) // NEW-LAB2 { // NEW-LAB2 // (addr >> 6); // NEW-LAB2 int dram_page_size,dram_bank_num,dram_bank_id; dram_page_size = KNOB(KNOB_DRAM_PAGE_SIZE)->getValue(); dram_bank_num = KNOB(KNOB_DRAM_BANK_NUM)->getValue(); dram_bank_id=(addr/(dram_page_size*1024))%dram_bank_num; return dram_bank_id; //return 1; // NEW-LAB2 } // NEW-LAB2
bool get_op(Op *op) { static UINT64 unique_count = 0; Trace_op trace_op; bool success = FALSE; // read trace // fill out op info // return FALSE if the end of trace //success = (gzread(g_stream, &trace_op, sizeof(Trace_op)) >0 ); success = (gzread(g_stream, &trace_op, sizeof(Trace_op)) == sizeof(Trace_op)); /* copy trace structure to op */ if (success) { if (KNOB(KNOB_PRINT_INST)->getValue()) dprint_trace(&trace_op); copy_trace_op(&trace_op, op); op->inst_id = unique_count++; op->valid = TRUE; last_inst_id = op->inst_id + 1; } else { if(unique_count == 0) { //cout << "Error in trace file" << endl; exit(0); } //last_inst_id = unique_count - 1; trace_over = true; } return success; }
void memory_c::run_a_cycle() { if (KNOB(KNOB_PRINT_MEM_DEBUG)->getValue()) { dprint_queues(); dprint_dram_banks(); } /* This function is called from run_a_cycle() every cycle */ /* You do not add new code here */ /* insert D-cache/I-cache (D-cache for only Lab #2) and wakes up instructions */ fill_queue(); /* move memory requests from dram to cache and MSHR*/ /* out queue */ send_bus_out_queue(); /* memory requests are scheduled */ dram_schedule(); /* memory requests are moved from bus_queue to DRAM scheduler */ push_dram_sch_queue(); /* new memory requests send from MSRH to in_bus_queue */ send_bus_in_queue(); }
bool icache_access(uint32_t addr) { /* For Lab #1, you assume that all I-cache hit */ bool hit = FALSE; if (KNOB(KNOB_PERFECT_ICACHE)->getValue()) hit = TRUE; return hit; }
bool icache_access(ADDRINT addr) { /** please change uint32_t to ADDRINT NEW-LAB2 */ /* For Lab #1, you assume that all I-cache hit */ bool hit = FALSE; if (KNOB(KNOB_PERFECT_ICACHE)->getValue()) hit = TRUE; return hit; }
void memory_c::init_mem() { /* For Lab #2, you do not need to modify this code */ /* you can add other code here if you want */ /* init mshr */ m_mshr_size = KNOB(KNOB_MSHR_SIZE)->getValue(); m_dram_bank_num = KNOB(KNOB_DRAM_BANK_NUM)->getValue(); m_block_size = KNOB(KNOB_BLOCK_SIZE)->getValue(); for (int ii = 0 ; ii < m_mshr_size; ii++) { m_mshr_entry_s* entry = new m_mshr_entry_s; entry->m_mem_req = new mem_req_s; // create a memory rquest data structure here entry->valid = false; entry->insert_time = 0; m_mshr_free_list.push_back(entry); } /* init DRAM scheduler queues */ dram_in_queue.clear(); dram_out_queue.clear(); //cout << "SIZE OF DRAM IN AND OUT" << dram_in_queue.size() << dram_out_queue.size(); // cout << "INIT MEM\n"; dram_bank_sch_queue = new list<mem_req_s*>[m_dram_bank_num]; dram_bank_open_row = new int64_t[m_dram_bank_num]; dram_bank_rdy_cycle = new uint64_t[m_dram_bank_num]; for(int ii=0;ii<m_dram_bank_num;ii++) { dram_bank_open_row[ii] = -1; dram_bank_rdy_cycle[ii] = 0; } //dram_bank_rdy_cycle[i] = -1; }
void memory_c::dram_schedule() { /* For Lab #2, you need to fill out this function */ list<mem_req_s *>::const_iterator cii; /* if the in queue is empty, return */ // if(dram_in_queue.empty()) // return; /* iterate over dram_bank_sch_queue to get elements */ for(int bank_id = 0 ; bank_id < m_dram_bank_num ; bank_id++) { if(dram_bank_sch_queue[bank_id].empty()) continue; for(cii = dram_bank_sch_queue[bank_id].begin() ; cii != dram_bank_sch_queue[bank_id].end() ; cii++) { mem_req_s *req = (*cii); if(req && (req->m_state == MEM_DRAM_SCH) && (dram_bank_rdy_cycle[bank_id] < cycle_count)) { /* bank is available. we can schedule it */ /* check for row buffer hit */ int64_t reqd_row_id = get_dram_row_id(req->m_addr); // int reqd_row_id = ((req->m_addr)/((KNOB(KNOB_DRAM_PAGE_SIZE)->getValue())*1024)); if(reqd_row_id == dram_bank_open_row[bank_id]) { /* row buffer hit */ req->m_rdy_cycle = cycle_count + (KNOB(KNOB_MEM_LATENCY_ROW_HIT)->getValue()); dram_row_buffer_hit_count++; } else { /* row buffer miss */ req->m_rdy_cycle = cycle_count + (KNOB(KNOB_MEM_LATENCY_ROW_MISS)->getValue()); dram_bank_open_row[bank_id] = reqd_row_id; dram_row_buffer_miss_count++; } dram_bank_rdy_cycle[bank_id] = req->m_rdy_cycle; req->m_state = MEM_DRAM_DONE; break; } } } }
bool dcache_access(ADDRINT addr) { /** please change uint32_t to ADDRINT NEW-LAB2 */ /* For Lab #1, you assume that all D-cache hit */ /* For Lab #2, you need to connect cache here */ // NEW-LAB2 bool hit = FALSE; if (KNOB(KNOB_PERFECT_DCACHE)->getValue()) hit = TRUE; else { hit=cache_access(data_cache,addr); } return hit; }
int64_t get_dram_row_id(ADDRINT addr) // NEW-LAB2 { // NEW-LAB2 // NEW-LAB2 /* utility functions that you might want to implement */ // NEW-LAB2 /* if you want to use it, you should find the right math! */ // NEW-LAB2 /* pleaes carefull with that DRAM_PAGE_SIZE UNIT !!! */ // NEW-LAB2 // addr >> 6; // NEW-LAB2 return ((addr)/((KNOB(KNOB_DRAM_PAGE_SIZE)->getValue())*1024)); // return 2; // NEW-LAB2 } // NEW-LAB2
void read_trace_file(void) { g_stream[0] = gzopen((KNOB(KNOB_TRACE_FILE)->getValue()).c_str(), "r"); if ((KNOB(KNOB_RUN_THREAD_NUM)->getValue())<2) return; /** NEW-LAB4 **/ g_stream[1] = gzopen((KNOB(KNOB_TRACE_FILE2)->getValue()).c_str(), "r"); /** NEW-LAB4 **/ if ((KNOB(KNOB_RUN_THREAD_NUM)->getValue())<3) return; /** NEW-LAB4 **/ g_stream[2] = gzopen((KNOB(KNOB_TRACE_FILE3)->getValue()).c_str(), "r"); /** NEW-LAB4 **/ if ((KNOB(KNOB_RUN_THREAD_NUM)->getValue())<4) return; /** NEW-LAB4 **/ g_stream[3] = gzopen((KNOB(KNOB_TRACE_FILE4)->getValue()).c_str(), "r"); /** NEW-LAB4 **/ }
bool run_a_cycle(memory_c *main_memory){ // please modify run_a_cycle function argument /** NEW-LAB2 */ int i = 0; for (;;) { if (((KNOB(KNOB_MAX_SIM_COUNT)->getValue() && (cycle_count >= KNOB(KNOB_MAX_SIM_COUNT)->getValue())) || (KNOB(KNOB_MAX_INST_COUNT)->getValue() && (retired_instruction >= KNOB(KNOB_MAX_INST_COUNT)->getValue())) || (sim_end_condition))) { // please complete sim_end_condition // finish the simulation print_heartbeat(); print_stats(); return TRUE; } cycle_count++; if (!(cycle_count%5000)) { print_heartbeat(); } main_memory->run_a_cycle(); // *NEW-LAB2 WB_stage(main_memory); MEM_stage(main_memory); // please modify MEM_stage function argument /** NEW-LAB2 */ EX_stage(); ID_stage(); FE_stage(); if (KNOB(KNOB_PRINT_PIPE_FREQ)->getValue() && !(cycle_count%KNOB(KNOB_PRINT_PIPE_FREQ)->getValue())) print_pipeline(); } return TRUE; }
int get_dram_row_id(ADDRINT addr) // NEW-LAB2 { // addr >> 6; // NEW-LAB2 int dram_page_size,dram_row_id; dram_page_size = KNOB(KNOB_DRAM_PAGE_SIZE)->getValue(); dram_row_id=(addr/(dram_page_size*1024)); return dram_row_id; // return 2; }
void print_stats() { std::ofstream out((KNOB(KNOB_OUTPUT_FILE)->getValue()).c_str()); /* Do not modify this function. This messages will be used for grading */ out << "Total instruction: " << retired_instruction << endl; out << "Total cycles: " << cycle_count << endl; float ipc = (cycle_count ? ((float)retired_instruction/(float)cycle_count): 0 ); out << "Total IPC: " << ipc << endl; out << "Total D-cache miss: " << dcache_miss_count << endl; out << "Total D-cache hit: " << dcache_hit_count << endl; out << "Total data hazard: " << data_hazard_count << endl; out << "Total control hazard : " << control_hazard_count << endl; out << "Total DRAM ROW BUFFER Hit: " << dram_row_buffer_hit_count << endl; out << "Total DRAM ROW BUFFER Miss: "<< dram_row_buffer_miss_count << endl; out << "Total Store-load forwarding: " << store_load_forwarding_count << endl; out << "Total Branch Predictor Mispredictions: " << bpred_mispred_count << endl; out << "Total Branch Predictor OK predictions: " << bpred_okpred_count << endl; out << "Total DTLB Hit: " << dtlb_hit_count << endl; out << "Total DTLB Miss: " << dtlb_miss_count << endl; out << endl << endl << endl; for (int ii = 0; ii < (KNOB(KNOB_RUN_THREAD_NUM)->getValue()); ii++ ) { out << "THREAD instruction: " << retired_instruction_thread[ii] << " Thread id: " << ii << endl; float thread_ipc = (cycle_count ? ((float)retired_instruction_thread[ii]/(float)cycle_count): 0 ); out << "THREAD IPC: " << thread_ipc << endl; out << "THREAD D-cache miss: " << dcache_miss_count_thread[ii] << " Thread id: " << ii << endl; out << "THREAD D-cache hit: " << dcache_hit_count_thread[ii] << " Thread id: " << ii << endl; out << "THREAD data hazard: " << data_hazard_count_thread[ii] << " Thread id: " << ii << endl; out << "THREAD control hazard : " << control_hazard_count_thread[ii] << " Thread id: " << ii << endl; out << "THREAD Store-load forwarding: " << store_load_forwarding_count_thread[ii] << " Thread id: " << ii << endl; out << "THREAD Branch Predictor Mispredictions: " << bpred_mispred_count_thread[ii] << " Thread id: " << ii << endl; out << "THREAD Branch Predictor OK predictions: " << bpred_okpred_count_thread[ii] << " Thread id: " << ii << endl; out << "THREAD DTLB Hit: " << dtlb_hit_count_thread[ii] << " Thread id: " << ii << endl; out << "THREAD DTLB Miss: " << dtlb_miss_count_thread[ii] << " Thread id: " << ii << endl; } out.close(); }
void print_stats() { /* DO NOT MODIFY */ std::ofstream out((KNOB(KNOB_OUTPUT_FILE)->getValue()).c_str()); /* Do not modify this function. This messages will be used for grading */ out << "Total instruction: " << retired_instruction << endl; out << "Total cycles: " << cycle_count << endl; float ipc = (cycle_count ? ((float)retired_instruction/(float)cycle_count): 0 ); out << "IPC: " << ipc << endl; out << "Total I-cache miss: " << icache_miss_count << endl; out << "Total D-cache miss: " << dcache_miss_count << endl; out << "Total L2-cache miss: " << l2_cache_miss_count << endl; out << "Total data hazard: " << data_hazard_count << endl; out << "Total control hazard : " << control_hazard_count << endl; out.close(); }
void print_heartbeat() { static uint64_t last_cycle_thread[HW_MAX_THREAD] ; static uint64_t last_inst_count_thread[HW_MAX_THREAD]; for (int ii = 0; ii < (KNOB(KNOB_RUN_THREAD_NUM)->getValue()); ii++ ) { float temp_ipc = float(retired_instruction_thread[ii] - last_inst_count_thread[ii]) /(float)(cycle_count-last_cycle_thread[ii]) ; float ipc = float(retired_instruction_thread[ii]) /(float)(cycle_count) ; /* Do not modify this function. This messages will be used for grading */ cout <<"**Heartbeat** cycle_count: " << cycle_count << " inst:" << retired_instruction_thread[ii] << " IPC: " << temp_ipc << " Overall IPC: " << ipc << " thread_id " << ii << endl; last_cycle_thread[ii] = cycle_count; last_inst_count_thread[ii] = retired_instruction_thread[ii]; } }
void memory_c::send_bus_out_queue() { //list<mem_req_s *>::iterator ii; int jj ; for(jj=0;jj<KNOB(KNOB_DRAM_BANK_NUM)->getValue();jj++){ //cout << "\nKNOB BANKS " << KNOB(KNOB_DRAM_BANK_NUM)->getValue(); //mem_req_s *dii = (*ii); list<mem_req_s *>::iterator ii; if(dram_bank_sch_queue[jj].empty()) continue; //cout << "size is \n" << dram_bank_sch_queue[jj].size(); for(ii=(dram_bank_sch_queue[jj]).begin();ii!=(dram_bank_sch_queue[jj]).end();) //check all enteries and see which one is free. { //cout << "\nwithin OUT QUEUE of each bank"; mem_req_s* dii = (*ii); assert(dii != NULL); // cout <<"\nREADY CYCLES" << (*ii)->m_rdy_cycle; if((dii)->m_rdy_cycle < cycle_count && (dii)->m_state==MEM_DRAM_SCH){ (dii)->m_state = MEM_DRAM_DONE; // cout << (dii)->m_addr << "\nis ready"; dram_out_queue.push_back(dii); //keep pushing al entries into out queue. (dii)->m_state = MEM_DRAM_OUT; //dram_bank_rdy_cycle[jj] = 0; ii = dram_bank_sch_queue[jj].erase(ii); break; } else ii++; } /* For Lab #2, you need to fill out this function */ } }
void print_stats() { std::ofstream out((KNOB(KNOB_OUTPUT_FILE)->getValue()).c_str()); /* Do not modify this function. This messages will be used for grading */ out << "Total instruction: " << retired_instruction << endl; out << "Total cycles: " << cycle_count << endl; float ipc = (cycle_count ? ((float)retired_instruction/(float)cycle_count): 0 ); out << "IPC: " << ipc << endl; out << "Total I-cache miss: " << icache_miss_count << endl; out << "Total D-cache miss: " << dcache_miss_count << endl; out << "Total D-cache hit: " << dcache_hit_count << endl; out << "Total data hazard: " << data_hazard_count << endl; out << "Total control hazard : " << control_hazard_count << endl; out << "Total DRAM ROW BUFFER Hit: " << dram_row_buffer_hit_count << endl; out << "Total DRAM ROW BUFFER Miss: "<< dram_row_buffer_miss_count << endl; out << "Total Store-load forwarding: " << store_load_forwarding_count << endl; // new for LAB3 out << "Total Branch Predictor Mispredictions: " << bpred_mispred_count << endl; out << "Total Branch Predictor OK predictions: " << bpred_okpred_count << endl; out << "Total DTLB Hit: " << dtlb_hit_count << endl; out << "Total DTLB Miss: " << dtlb_miss_count << endl<< endl; //new for LAB4 out << "For LAB4 : " << endl << endl; out << "Total float count: " << float_count << endl; out << "Total integer count: " << integer_count << endl ; out << "Total branch count: " << branch_count <<endl; out << "Total load count: " << load_count << endl; out << "Total store count: " << store_count << endl; out << "Total I cache access count: " << retired_instruction << endl; out << "Total integer register read count: " << int_reg_count << endl; out << "Total float point register read count: " << fp_reg_count << endl; out << "Total multiple count: " << multiple_count << endl; out << "Total D cache read count: " << dcache_read_count << endl; out << "Total D cache write count: " << dcache_write_count << endl; out << "Total memory access count: " << dram_row_buffer_hit_count + dram_row_buffer_miss_count<< endl; out << "Total integer register write count: " << int_reg_w_count << endl; out << "Total float point register write count: " << fp_reg_w_count << endl; out << "Total integer scheduler access count: " << integer_scheduler_count << endl; out << "Total float point scheduler access count: " << float_scheduler_count << endl; out.close(); }
bool dcache_access(ADDRINT addr) { /** please change uint32_t to ADDRINT NEW-LAB2 */ /* For Lab #1, you assume that all D-cache hit */ /* For Lab #2, you need to connect cache here */ // NEW-LAB2 // bool cache_hit; bool hit = FALSE; if (KNOB(KNOB_PERFECT_DCACHE)->getValue()) hit = TRUE; else { // cache_hit=(bool)cache_access(data_cache,addr); hit=(bool)cache_access(data_cache,addr); // std::cout<<"cache hit="<<cache_hit; // return cache_hit; } // std::cout<<"cache hit="<<hit; return hit; }
void print_stats() { std::ofstream out((KNOB(KNOB_OUTPUT_FILE)->getValue()).c_str()); /* Do not modify this function. This messages will be used for grading */ out << "Total instruction: " << retired_instruction << endl; out << "Total cycles: " << cycle_count << endl; float ipc = (cycle_count ? ((float)retired_instruction/(float)cycle_count): 0 ); out << "IPC: " << ipc << endl; out << "Total I-cache miss: " << icache_miss_count << endl; out << "Total D-cache hit: " << dcache_hit_count << endl; out << "Total D-cache miss: " << dcache_miss_count << endl; out << "Total L2-cache miss: " << l2_cache_miss_count << endl; out << "Total data hazard: " << data_hazard_count << endl; out << "Total control hazard : " << control_hazard_count << endl; out << "Total DRAM ROW BUFFER Hit: " << dram_row_buffer_hit_count << endl; // NEW-LAB2 out << "Total DRAM ROW BUFFER Miss: "<< dram_row_buffer_miss_count << endl; // NEW-LAB2 out <<" Total Store-load forwarding: " << store_load_forwarding_count << endl; // NEW-LAB2 out.close(); }
bool dcache_access(ADDRINT addr) { /** please change uint32_t to ADDRINT NEW-LAB2 */ /* For Lab #1, you assume that all D-cache hit */ /* For Lab #2, you need to connect cache here */ // NEW-LAB2 bool hit = FALSE; if (KNOB(KNOB_PERFECT_DCACHE)->getValue()) /* always get a hit for perfect dcache */ { hit = TRUE; return hit; } if(cache_read(data_cache,addr)) { /* cache hit */ return true; } else return false; /* cache miss */ }
bool get_op(Op *op) { static UINT64 unique_count = 0; Trace_op trace_op; bool success = FALSE; // read trace // fill out op info // return FALSE if the end of trace success = (gzread(g_stream, &trace_op, sizeof(Trace_op)) >0 ); if (KNOB(KNOB_PRINT_INST)->getValue()) dprint_trace(&trace_op); /* copy trace structure to op */ if (success) { copy_trace_op(&trace_op, op); op->inst_id = unique_count++; op->valid = TRUE; } return success; }
/* getOp */ bool get_op(Op *op, int fetch_id) { static UINT64 unique_count = 0; if(end_of_stream[fetch_id]) return false; Trace_op trace_op; bool success = false; // read trace // fill out op info // return FALSE if the end of trace int read_size; read_size = gzread(g_stream[fetch_id], &trace_op, sizeof(Trace_op)); success = read_size>0; if(read_size!=sizeof(Trace_op) && read_size>0) { printf( "ERROR!! gzread reads corrupted op! @cycle:%llu\n", cycle_count); success = false; } if (KNOB(KNOB_PRINT_INST)->getValue()) dprint_trace(&trace_op); /* copy trace structure to op */ if (success) { copy_trace_op(&trace_op, op); op->inst_id = unique_count++; op->valid = TRUE; op->thread_id = fetch_id; return success; // get op so return } else end_of_stream[fetch_id] = true; return success; }
bool run_a_cycle(memory_c *main_memory){ long int retired_instruction_cpy=0; int terminate_count=0; bool terminate_program=false; for (;;) { if ((KNOB(KNOB_MAX_SIM_COUNT)->getValue() && (cycle_count >= KNOB(KNOB_MAX_SIM_COUNT)->getValue())) || (KNOB(KNOB_MAX_INST_COUNT)->getValue() && (retired_instruction >= KNOB(KNOB_MAX_INST_COUNT)->getValue())) || (sim_end_condition) || terminate_program) { // please complete sim_end_condition // finish the simulation print_heartbeat(); print_stats(); return TRUE; } cycle_count++; if (!(cycle_count%5000)) { print_heartbeat(); } /*section to terminate the program if it fails to exit normally*/ if(terminate_count>1000) { if(retired_instruction_cpy==retired_instruction) terminate_program=true; else { retired_instruction_cpy=retired_instruction; terminate_count=0; } } else terminate_count++; /*section to terminate the program if it fails to exit normally*/ main_memory->run_a_cycle(); // *NEW-LAB2 WB_stage(); MEM_stage(main_memory); // please modify MEM_stage function argument /** NEW-LAB2 */ EX_stage(); ID_stage(); FE_stage(); if(trace_over && main_memory->all_mem_structures_empty() && pipeline_latches_empty()) sim_end_condition = true; if (KNOB(KNOB_PRINT_PIPE_FREQ)->getValue() && !(cycle_count%KNOB(KNOB_PRINT_PIPE_FREQ)->getValue())) print_pipeline(); } return TRUE; }
void memory_c::init_mem() { /* For Lab #2, you do not need to modify this code */ /* you can add other code here if you want */ /* init mshr */ m_mshr_size = KNOB(KNOB_MSHR_SIZE)->getValue(); m_dram_bank_num = KNOB(KNOB_DRAM_BANK_NUM)->getValue(); m_block_size = KNOB(KNOB_BLOCK_SIZE)->getValue(); m_page_size = KNOB(KNOB_DRAM_PAGE_SIZE)->getValue(); //added by apk m_row_hit_latency=KNOB(KNOB_MEM_LATENCY_ROW_HIT)->getValue(); //added by apk m_row_miss_latency=KNOB(KNOB_MEM_LATENCY_ROW_MISS)->getValue(); //added by apk for (int ii = 0 ; ii < m_mshr_size; ii++) { m_mshr_entry_s* entry = new m_mshr_entry_s; entry->m_mem_req = new mem_req_s; // create a memory rquest data structure here entry->valid = false; entry->insert_time = 0; m_mshr_free_list.push_back(entry); } /* init DRAM scheduler queues */ dram_in_queue.clear(); dram_out_queue.clear(); dram_bank_sch_queue = new list<mem_req_s*>[m_dram_bank_num]; dram_bank_open_row = new int64_t[m_dram_bank_num]; dram_bank_rdy_cycle = new uint64_t[m_dram_bank_num]; for(int ii=0;ii<m_dram_bank_num;ii++) { dram_bank_open_row[ii]=-1; dram_bank_rdy_cycle[ii] = 0; } }