public void HandleNewRequest() { curr_ins = null; curr_ins = get_ins_from_insp(); curr_req = null; curr_req = new ProcRequest(); curr_req.parse_ins(curr_ins); }
/// <summary> /// process current requests /// </summary> public void handle_current_req() { //if core had processed a memory operation, mem_restrct will be set to 0. //the loop will not be executed. while (mem_restrict.WaitOne()) { if (ins_w.full()) { return; } bool hit = ins_w.if_exist(curr_req.block_addr); if (hit) { bool ready = ins_w.get_readyinfo(curr_req.block_addr); ins_w.add_ins(curr_ins, this.cycle); ins_w.setLast(ready); curr_ins = null; curr_ins = get_ins_from_insp(); curr_req = null; curr_req = new ProcRequest(); curr_req.parse_ins(curr_ins); continue; } if (PIMConfigs.use_l1_cache) { bool l1_hit = L1Cache.search_block(curr_req.block_addr, curr_req.type); if (l1_hit) { //l1 cache hit curr_ins.is_mem = true; curr_ins.ready = true; ins_w.add_ins(curr_ins, this.cycle); curr_ins = null; curr_ins = get_ins_from_insp(); curr_req = null; curr_req = new ProcRequest(); curr_req.parse_ins(curr_ins); continue; } bool mshr = add_to_mshr(curr_req); if (!mshr) { mshr_retry = true; return; } //l1 miss } curr_ins.is_mem = true; curr_ins.ready = false; ins_w.add_ins(curr_ins, this.cycle); bool mctrl_ = add_to_mctrl(curr_req); if (!mctrl_) { mctrl_retry = true; return; } curr_ins = null; curr_ins = get_ins_from_insp(); curr_req = null; curr_req = new ProcRequest(); curr_req.parse_ins(curr_ins); } }
/// <summary> /// One cycle of Core. /// </summary> public override void Step() { cycle++; if (Config.DEBUG_PIM) { DEBUG.WriteLine(); DEBUG.WriteLine("----------PIM CPU [" + this.pid + "] Update [Cycle " + cycle + "]------------"); DEBUG.WriteLine(); } //reset all restriction reset_restrict(); //period statics if (cycle % Config.pim_static_period == 0 && cycle != 0) { //static } //init current request and instruction when cycle 1. //otherwise current request and instruction cannot be null. if (curr_ins == null || curr_req == null) { curr_ins = get_ins_from_insp(); if (!started) { if (curr_ins.type == InstructionType.NOP) { return; } else { started = true; } } if (curr_req == null) { curr_req = new ProcRequest(); } curr_req.parse_ins(curr_ins); } if (Config.trace_type == Trace_Type.PC) { pc++; Console.WriteLine(pc.ToString("x")); //if (curr_req.type != RequestType.NOP) //{ // if (pc > curr_req.pc) // { // pc = curr_req.pc; // } //} } if (Config.sim_type == SIM_TYPE.cycle) { //simulater has reach max sim cysle,exit if (cycle > Config.sim_cycle) { return; } } if (Config.trace_type != Trace_Type.PC) { //if no memory operation, insert ins to ALU if (!curr_ins.is_mem) { //current instruction is an alg ins or NOP while (cal_restrict.WaitOne()) { if (curr_ins.type == InstructionType.NOP) { continue; } else { alu.add_ins(curr_ins); } } } alu.Step(); } if (PIMConfigs.use_l1_cache) { handle_cache_req(); } update_ins_w(); if (outstanding_requests()) { memory_cycle++; } if (Config.writeback) { //handle write-back queue if (writeback_req.Count > 0) { //each step handles only one write-back req bool res = handle_writeback_queue(); if (res) { writeback_req.RemoveAt(0); } res = write_b_stall(); if (res) { //too many writeback req to be handled return; } } } // if MSHR or MCTRL queue are full last cycyle , system has to process last request bool prcessed = false; if (mshr_retry || mctrl_retry) { if (ins_w.full()) { if (Config.DEBUG_PROC) { DEBUG.WriteLine("-- InsWd : Queue Full."); } return; } //mshr/mctrl stall prcessed = handle_last(); if (!prcessed) { return; } //reissue success prcessed = true; curr_ins = null; curr_ins = get_ins_from_insp(); curr_req = null; curr_req = new ProcRequest(); curr_req.parse_ins(curr_ins); } if (curr_req.if_mem) { handle_current_req(); } else { curr_ins = null; curr_ins = get_ins_from_insp(); curr_req = null; curr_req = new ProcRequest(); curr_req.parse_ins(curr_ins); } }
/// <summary> /// One cycle of Core. /// </summary> public override void Step() { cycle++; if (Config.DEBUG_PROC) { DEBUG.WriteLine(); DEBUG.WriteLine("----------Host CPU [" + this.pid + "] Update [Cycle " + cycle + "]------------"); DEBUG.WriteLine(); } //if (Config.trace_type == Trace_Type.PC) //{ // if (curr_req != null && curr_req.pc > 0 && pc == 0) // pc = curr_req.pc; // else // { // get_ins_from_insp(); // return; // } //} /** * Free all the restricts to enable a new round of CPU cycles. **/ reset_restrict(); //reset all restriction //period statics if (cycle % Config.proc_static_period == 0 && cycle != 0) { //static } //init current request and instruction when cycle 1. //otherwise current request and instruction cannot be null. if (curr_ins == null || curr_req == null) { curr_ins = get_ins_from_insp(); if (curr_req == null) { curr_req = new ProcRequest(); } curr_req.parse_ins(curr_ins); } if (Config.trace_type == Trace_Type.PC) { pc++; Console.WriteLine(pc.ToString("x")); //if (curr_req.type != RequestType.NOP) //{ // if (pc > curr_req.pc) // { // pc = curr_req.pc; // } //} } if (Config.sim_type == SIM_TYPE.cycle) { //simulater has reach max sim cysle,exit if (cycle > Config.sim_cycle) { return; } } if (Config.trace_type != Trace_Type.PC) { /** * In PC trace mode, CPU only simulates cache and memory * behaviours. ALU should be disabled due to the lack of * detailed instruction information. Because that the trace * file is fetched by physical mechines, which provide * the correctness of execution. PIMSim just needs to * send memory or cache requests at exact time. **/ if (!curr_ins.is_mem) { //current instruction is an alg ins or NOP while (cal_restrict.WaitOne()) { if (curr_ins.type == InstructionType.NOP) { continue; } else { alu.add_ins(curr_ins); } } } alu.Step(); } if (Config.use_cache) { handle_cache_req(); } update_ins_w(); if (outstanding_requests()) { memory_cycle++; } if (Config.writeback) { //handle write-back queue if (writeback_req.Count > 0) { //each step handles only one write-back req bool res = handle_writeback_queue(); if (res) { writeback_req.RemoveAt(0); } res = write_b_stall(); if (res) { //too many writeback req to be handled return; } } } bool prcessed = false; if (mshr_retry || mctrl_retry) { if (ins_w.full()) { if (Config.DEBUG_PROC) { DEBUG.WriteLine("-- InsWd : Queue Full."); } return; } //mshr/mctrl stall prcessed = handle_last(); if (!prcessed) { return; } mem_restrict.WaitOne(); HandleNewRequest(); } if (curr_req.if_mem) { handle_current_req(); } else { HandleNewRequest(); } }