public void PrintStatus() { DEBUG.WriteLine(); DEBUG.WriteLine(); DEBUG.WriteLine("++++++++++++++++++++++ Statistics ++++++++++++++++++++"); DEBUG.WriteLine(); DEBUG.WriteLine(); foreach (var item in proc) { item.PrintStatus(); } Mctrl.PrintStatus(); if (Config.use_pim) { PIMMctrl.PrintStatus(); } ins_p.PrintStatus(); foreach (var item in pim.unit) { item.PrintStatus(); } }
public void run() { UInt64 execution = UInt64.MaxValue; if (Config.sim_type == SIM_TYPE.cycle) { execution = Config.sim_cycle; } for (UInt64 i = 0; i < execution; i++) { trace.Step(); ins_p.Step(); foreach (var mem in MemorySelector.MemoryInfo) { if (GlobalTimer.ifMemoryStep(0)) { mem.Item3.Step(); } } Mctrl.Step(); PIMMctrl.Step(); for (int j = 0; j < Config.N; j++) { if (GlobalTimer.ifProcStep(j)) { proc[j].Step(); } } if (GlobalTimer.ifPIMUnitStep(0)) { pim.Step(); } if (Config.sim_type == SIM_TYPE.file) { bool done = true; proc.ForEach(x => done = done && x.done()); if (Config.use_pim) { pim.unit.ForEach(x => done = done && x.done()); } MemorySelector.MemoryInfo.ForEach(x => done = done && x.Item3.done()); if (done & ins_p.done() & Mctrl.done() & PIMMctrl.done()) { return; } } GlobalTimer.Step(); } }
public override void Step() { cycle++; current_statue = Macros.HMC_OK; MemRequest req_ = new MemRequest(); while (Mctrl.get_req(this.pid, ref req_)) { TransationQueue.Add(req_); } if (Config.use_pim) { while (PIMMctrl.get_req(this.pid, ref req_)) { TransationQueue.Add(req_); } } bool restart = false; while (!restart) { restart = true; for (int i = 0; i < TransationQueue.Count; i++) { for (int j = 0; j < TransationQueue.Count; j++) { if (i != j && TransationQueue[i].address == TransationQueue[j].address && TransationQueue[i].pim == TransationQueue[j].pim) { foreach (var id in TransationQueue[j].pid) { TransationQueue[i].pid.Add(id); } TransationQueue.RemoveAt(j); restart = false; continue; } } } } if (TransationQueue.Count() > 0) { MemRequest req = TransationQueue[0]; UInt64[] packet = new UInt64[Macros.HMC_MAX_UQ_PACKET]; hmc_rqst type = hmc_rqst.RD64; UInt64 d_response_head = 0; UInt64 d_response_tail = 0; hmc_response d_type = hmc_response.MD_RD_RS; uint d_length = 0; UInt16 d_tag = 0; uint d_rtn_tag = 0; uint d_src_link = 0; uint d_rrp = 0; uint d_frp = 0; uint d_seq = 0; uint d_dinv = 0; uint d_errstat = 0; uint d_rtc = 0; UInt32 d_crc = 0; zero_packet(ref packet); switch (req.memtype) { case MemReqType.READ: type = hmc_rqst.RD64; break; case MemReqType.WRITE: type = hmc_rqst.WR64; break; case MemReqType.FLUSH: type = hmc_rqst.WR64; break; case MemReqType.LOAD: type = hmc_rqst.RD64; break; case MemReqType.STORE: type = hmc_rqst.WR64; break; case MemReqType.RETURN_DATA: default: break; } if (current_statue != Macros.HMC_STALL) { uint cub = 0; uint link = 0; ulong[] payload = { 0x00L, 0x00L, 0x00L, 0x00L, 0x00L, 0x00L, 0x00L, 0x00L }; UInt64 head = 0x00L; UInt64 tail = 0x00L; hmc.hmcsim_build_memrequest( cub, req.address, tag, type, link, payload, ref head, ref tail); /* * read packets have: * head + * tail * */ tag++; if (type == hmc_rqst.RD64) { packet[0] = head; packet[1] = tail; } if (type == hmc_rqst.WR64) { packet[0] = head; packet[1] = 0x05L; packet[2] = 0x06L; packet[3] = 0x07L; packet[4] = 0x08L; packet[5] = 0x09L; packet[6] = 0x0AL; packet[7] = 0x0BL; packet[8] = 0x0CL; packet[9] = tail; } current_statue = hmc.hmcsim_send(packet); if (current_statue == 0) { var newitem = new CallBackInfo(req.address, req.block_addr, req.pim, req.pid); if (req.memtype == MemReqType.FLUSH) { newitem.flush = true; } if (req.memtype == MemReqType.LOAD) { newitem.load = true; newitem.stage_id = req.stage_id; } if (req.memtype == MemReqType.STORE) { newitem.store = true; newitem.stage_id = req.stage_id; } callback.Add(new Tuple <ulong, CallBackInfo>(tag - 1, newitem)); TransationQueue.RemoveAt(0); current_statue = Macros.HMC_OK; while (current_statue != Macros.HMC_STALL) { int stall_sig = 0; for (int z = 0; z < hmc.num_links; z++) { int res = hmc.hmcsim_recv(cub, (uint)z, ref packet); if (res == Macros.HMC_STALL) { stall_sig++; } else { /* successfully received a packet */ if (Config.DEBUG_MEMORY) { DEBUG.WriteLine("SUCCESS : RECEIVED A SUCCESSFUL PACKET RESPONSE"); } hmc.hmcsim_decode_memresponse( packet, ref d_response_head, ref d_response_tail, ref d_type, ref d_length, ref d_tag, ref d_rtn_tag, ref d_src_link, ref d_rrp, ref d_frp, ref d_seq, ref d_dinv, ref d_errstat, ref d_rtc, ref d_crc); if (Config.DEBUG_MEMORY) { DEBUG.WriteLine("RECV tag=" + d_tag + "; rtn_tag=" + d_rtn_tag); } // all_recv++; var item = callback.FindIndex(s => s.Item1 == d_tag); if (item < 0) { //read none if (Config.DEBUG_MEMORY) { DEBUG.WriteLine(""); } } if (d_type == hmc_response.RD_RS) { if (callback[item].Item2.load) { foreach (var pimunit in (callback[item].Item2.getsource() as List <ComputationalUnit>)) { pimunit.read_callback(callback[item].Item2); } goto end; } if (!callback[item].Item2.pim) { foreach (var proc in (callback[item].Item2.getsource() as List <Proc>)) { proc.read_callback(callback[item].Item2); } } else { if (PIMConfigs.unit_type == PIM_Unit_Type.Processors) { foreach (var pimproc in (callback[item].Item2.getsource() as List <PIMProc>)) { pimproc.read_callback(callback[item].Item2); } } else { foreach (var pimunit in (callback[item].Item2.getsource() as List <ComputationalUnit>)) { pimunit.read_callback(callback[item].Item2); } } } } else { if (d_type == hmc_response.WR_RS) { if (callback[item].Item2.store) { foreach (var pimunit in (callback[item].Item2.getsource() as List <ComputationalUnit>)) { pimunit.write_callback(callback[item].Item2); } goto end; } if (callback[item].Item2.flush) { Coherence.flush_queue.Remove(callback[item].Item2.block_addr); DEBUG.WriteLine("-- Flushed data : [" + callback[item].Item2.block_addr + "] [" + callback[item].Item2.address + "]"); } else { if (!callback[item].Item2.pim) { foreach (var proc in (callback[item].Item2.getsource() as List <Proc>)) { proc.write_callback(callback[item].Item2); } } else { if (PIMConfigs.unit_type == PIM_Unit_Type.Processors) { foreach (var pimproc in (callback[item].Item2.getsource() as List <PIMProc>)) { pimproc.write_callback(callback[item].Item2); } } else { foreach (var pimunit in (callback[item].Item2.getsource() as List <ComputationalUnit>)) { pimunit.write_callback(callback[item].Item2); } } } } } else { //error Environment.Exit(0); } } //if (Coherence.consistency == Consistency.SpinLock) //{ // if (callback[item].Item5) // { // Coherence.spin_lock.relese_lock(callback[item].Item4); // } //} end: callback.RemoveAt(item); } /* * zero the packet * */ zero_packet(ref packet); } if (stall_sig == hmc.num_links) { /* * if all links returned stalls, * then we're done receiving packets * */ if (Config.DEBUG_MEMORY) { DEBUG.WriteLine("STALLED : STALLED IN RECEIVING"); } current_statue = Macros.HMC_STALL; } stall_sig = 0; } } else { // hmc.hmcsim_clock(); } hmc.hmcsim_clock(); } } else { uint cub = 0; UInt64[] packet = new UInt64[Macros.HMC_MAX_UQ_PACKET]; uint d_length = 0; UInt16 d_tag = 0; uint d_rtn_tag = 0; uint d_src_link = 0; uint d_rrp = 0; uint d_frp = 0; uint d_seq = 0; uint d_dinv = 0; uint d_errstat = 0; uint d_rtc = 0; UInt32 d_crc = 0; UInt64 d_response_head = 0; UInt64 d_response_tail = 0; hmc_response d_type = hmc_response.MD_RD_RS; zero_packet(ref packet); for (int z = 0; z < hmc.num_links; z++) { int res = hmc.hmcsim_recv(cub, (uint)z, ref packet); if (res == Macros.HMC_STALL) { //stall_sig++; } else { /* successfully received a packet */ if (Config.DEBUG_MEMORY) { DEBUG.WriteLine("SUCCESS : RECEIVED A SUCCESSFUL PACKET RESPONSE"); } hmc.hmcsim_decode_memresponse( packet, ref d_response_head, ref d_response_tail, ref d_type, ref d_length, ref d_tag, ref d_rtn_tag, ref d_src_link, ref d_rrp, ref d_frp, ref d_seq, ref d_dinv, ref d_errstat, ref d_rtc, ref d_crc); if (Config.DEBUG_MEMORY) { DEBUG.WriteLine("RECV tag=" + d_tag + "; rtn_tag=" + d_rtn_tag); } var item = callback.FindIndex(s => s.Item1 == d_tag); if (item < 0) { //error if (Config.DEBUG_MEMORY) { DEBUG.WriteLine(""); } } if (d_type == hmc_response.RD_RS) { if (callback[item].Item2.load) { foreach (var pimunit in (callback[item].Item2.getsource() as List <ComputationalUnit>)) { pimunit.read_callback(callback[item].Item2); } goto endr; } if (!callback[item].Item2.pim) { foreach (var procs in (callback[item].Item2.getsource() as List <Proc>)) { procs.read_callback(callback[item].Item2); } } else { if (PIMConfigs.unit_type == PIM_Unit_Type.Processors) { foreach (var pimproc in (callback[item].Item2.getsource() as List <ComputationalUnit>)) { (pimproc as PIMProc).read_callback(callback[item].Item2); } } else { foreach (var pimunit in (callback[item].Item2.getsource() as List <ComputationalUnit>)) { pimunit.read_callback(callback[item].Item2); } } } } else { if (d_type == hmc_response.WR_RS) { if (callback[item].Item2.store) { foreach (var pimunit in (callback[item].Item2.getsource() as List <ComputationalUnit>)) { pimunit.write_callback(callback[item].Item2); } goto endr; } if (callback[item].Item2.flush) { Coherence.flush_queue.Remove(callback[item].Item2.block_addr); DEBUG.WriteLine("-- Flushed data : [" + callback[item].Item2.block_addr + "] [" + callback[item].Item2.address + "]"); } else { if (!callback[item].Item2.pim) { foreach (var proc in (callback[item].Item2.getsource() as List <Proc>)) { proc.write_callback(callback[item].Item2); } } else { if (PIMConfigs.unit_type == PIM_Unit_Type.Processors) { foreach (var pimproc in (callback[item].Item2.getsource() as List <ComputationalUnit>)) { (pimproc as PIMProc).write_callback(callback[item].Item2); } } else { foreach (var pimunit in (callback[item].Item2.getsource() as List <ComputationalUnit>)) { pimunit.write_callback(callback[item].Item2); } } } } } else { //error Environment.Exit(0); } } //if (Coherence.consistency == Consistency.SpinLock) //{ // if (callback[item].Item5) // { // Coherence.spin_lock.relese_lock(callback[item].Item4); // } //} endr: callback.RemoveAt(item); // all_recv++; } /* * zero the packet * */ zero_packet(ref packet); } hmc.hmcsim_clock(); } }
public override void Step() { cycle++; //get requests MemRequest req_ = new MemRequest(); while (Mctrl.get_req(this.pid, ref req_)) { TransationQueue.Add(req_); } if (Config.use_pim) { while (PIMMctrl.get_req(this.pid, ref req_)) { TransationQueue.Add(req_); } } //marge same requests bool restart = false; while (!restart) { restart = true; for (int i = 0; i < TransationQueue.Count; i++) { for (int j = 0; j < TransationQueue.Count; j++) { if (i != j && TransationQueue[i].address == TransationQueue[j].address && TransationQueue[i].pim == TransationQueue[j].pim) { foreach (var id in TransationQueue[j].pid) { TransationQueue[i].pid.Add(id); } TransationQueue.RemoveAt(j); restart = false; continue; } } } } //update memory if (!pendingTrans) { if (TransationQueue.Count() > 0) { MemRequest req = TransationQueue[0]; switch (req.memtype) { case MemReqType.READ: transType = TransactionType.DATA_READ; break; case MemReqType.WRITE: transType = TransactionType.DATA_WRITE; break; case MemReqType.RETURN_DATA: transType = TransactionType.RETURN_DATA; break; case MemReqType.FLUSH: transType = TransactionType.DATA_WRITE; break; case MemReqType.LOAD: transType = TransactionType.DATA_READ; break; case MemReqType.STORE: transType = TransactionType.DATA_WRITE; break; default: transType = TransactionType.RETURN_DATA; break; } TransationQueue.RemoveAt(0); if (transType != TransactionType.DATA_READ && transType != TransactionType.DATA_WRITE) { return; } CallBackInfo callback = new CallBackInfo(); callback.address = req.address; callback.block_addr = req.block_addr; callback.pid = req.pid; callback.pim = req.pim; if (req.memtype == MemReqType.FLUSH) { callback.flush = true; transType = TransactionType.DATA_WRITE; } if (req.memtype == MemReqType.LOAD) { callback.load = true; transType = TransactionType.DATA_READ; callback.stage_id = req.stage_id; } if (req.memtype == MemReqType.STORE) { callback.store = true; transType = TransactionType.DATA_WRITE; callback.stage_id = req.stage_id; } trans = new Transaction(transType, req.address, req.data, callback);//addr, data, req.block_addr, req.pid, req.pim); if (Config.DEBUG_MEMORY) { DEBUG.WriteLine("--DDR[" + this.pid + "] ADD transaction: [" + req.address.ToString("X") + "]"); } alignTransactionAddress(ref trans); if (cycle >= clockCycle) { if (!memorySystem.addTransaction(ref trans)) { pendingTrans = true; } else { if (Config.dram_config.RETURN_TRANSACTIONS) { transactionReceiver.add_pending(trans, cycle); } //#endif // the memory system accepted our request so now it takes ownership of it trans = null; } } else { pendingTrans = true; } } } else { if (pendingTrans && cycle >= clockCycle) { pendingTrans = !memorySystem.addTransaction(ref trans); if (!pendingTrans) { //#ifdef RETURN_TRANSACTIONS transactionReceiver.add_pending(trans, cycle); //#endif trans = null; } } } memorySystem.update(); }
public PIMSimulator(string[] args) { initAllconfigs(args); trace = new TraceFetcher(); ins_p = new InsPartition(); pg = new PageConverter(); if (Config.shared_cache) { shared_cache = new Shared_Cache(); } proc = new List <Proc>(); for (int i = 0; i < Config.N; i++) { Proc to_add = new Proc(ref ins_p, i); if (Config.shared_cache) { to_add.attach_shared_cache(ref shared_cache); } to_add.attach_tlb(ref pg); proc.Add(to_add); } int count = 0; foreach (var item in Config.memory) { if (item.Key.Equals("HMC")) { var tp = new HMCMem(count++) as MemObject; MemorySelector.add(item.Value, ref tp); } else { if (item.Key.Equals("DRAM") || item.Key.Equals("PCM")) { var tp = new DDRMem(count++) as MemObject; MemorySelector.add(item.Value, ref tp); } else { //error DEBUG.Error("Unknown Memory Type."); Environment.Exit(3); } } } Mctrl.init_queue(); PIMMctrl.init_queue(); pim = new PIM.PIM(ref ins_p); Coherence.init(); Coherence.linkproc(proc); GlobalTimer.InitClock(); BuildTopology(); }