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(); }