new public void __dequeue_req(Req req)
        {
            req.ts_departure = cycles;
            Dbg.Assert(req.ts_departure - req.ts_arrival > 0);

            if ((!req.migrated_request) && (Config.proc.cache_insertion_policy == "PFA"))
            {
                RowStat.UpdateMLP(RowStat.DramDict, req);
                Measurement.mem_num_dec(req);
//                   Measurement.DramServiceTimeUpdate (req);
//                   Measurement.DramCoreReqNumDec (req);
            }
            if (Config.proc.cache_insertion_policy == "PFA")
            {
                Measurement.DramCoreReqNumDec(req);
            }

            /*            if (Config.proc.cache_insertion_policy == "RBLAMLP" || Config.proc.cache_insertion_policy == "PFA")
             *                Measurement.DramSetCorePrevRowid (req);
             */
            //sched
            meta_mctrl.dequeue_req(req);

            //load stat management
            if (!req.migrated_request)
            {
                if (req.type == ReqType.RD)
                {
                    rload--;
                    rload_per_proc[req.pid]--;
                    rload_per_procrankbank[req.pid, req.addr.rid, req.addr.bid]--;
                    Dbg.Assert(rload >= 0);
                    Dbg.Assert(rload_per_proc[req.pid] >= 0);
                    Dbg.Assert(rload_per_procrankbank[req.pid, req.addr.rid, req.addr.bid] >= 0);
                }
                else
                {
                    wload--;
                    wload_per_proc[req.pid]--;
                    wload_per_procrankbank[req.pid, req.addr.rid, req.addr.bid]--;
                    Dbg.Assert(wload >= 0);
                    Dbg.Assert(wload_per_proc[req.pid] >= 0);
                    Dbg.Assert(wload_per_procrankbank[req.pid, req.addr.rid, req.addr.bid] >= 0);
                    //                RequestPool.CacheWrite--;
                }
            }
            else
            {
                if (req.type == ReqType.RD)
                {
                    rload--;
                }
                else
                {
                    wload--;
                }
            }

/*            //dequeue proper
 *          if (req.type == ReqType.RD) {
 *              //traverse crossbar
 *              //Sim.xbar.enqueue(req);
 *
 *              Callback cb = req.cache_callback;
 *              cb(req);
 *
 *
 *          }
 *          else {
 *              bool removeok = mctrl_writeq.Remove(req);
 *              Dbg.Assert(removeok);
 *              req.latency = (int)(req.ts_departure - req.ts_arrival);
 *
 *              Callback cb = req.cache_callback;
 *              cb(req);
 *
 *
 *              RequestPool.enpool(req);
 *         }*/


//yang:
            //dequeue proper
            if (req.type == ReqType.RD)
            {
                Callback cb = req.cache_callback;
                cb(req);
            }
            else
            {
                bool removeok = mctrl_writeq.Remove(req);
                Dbg.Assert(removeok);
                req.latency = (int)(req.ts_departure - req.ts_arrival);
                Callback cb = req.cache_callback;
                cb(req);

                /*            Callback cb1 = req.callback;
                 *          if (cb1!=null)
                 *          {
                 *             Console.WriteLine("Position3");
                 *                  RequestPool.CacheWrite--;
                 *          }*/
            }
        }
        new public void __enqueue_req(Req req, List <Req> q)
        {
            //timestamp
            //           req.ts_arrival = cycles;

/*            // do any analysis
 *          if (Config.collect_reuse == true) {
 *              if (Sim.reuse[req.pid].ContainsKey(req.block_addr))
 *                  Sim.reuse[req.pid][req.block_addr] = Sim.reuse[req.pid][req.block_addr] + 1;
 *              else
 *                  Sim.reuse[req.pid].Add(req.block_addr, 1);
 *          }
 *
 */
            if (Config.proc.cache_insertion_policy == "PFA")
            {
                Measurement.DramCoreReqNumInc(req);
            }

            // check if cache hit
            bool cache_serviced = false;

            /*
             * // TODO: add support for DRAM caching
             * // don't allow cache writeback requests to be re-cached
             * if (Config.proc.cache && Sim.caches[Sim.get_cache(req.pid)].is_cached(req) && !req.cache_wb) {
             *  Sim.caches[Sim.get_cache(req.pid)].promote(req);
             *  //stats
             *  if (req.type == ReqType.RD) {
             *      Stat.procs[req.pid].cache_read.Collect();
             *      Stat.procs[req.pid].cache_hit_rate_read.Collect(1);
             *      Sim.caches[Sim.get_cache(req.pid)].service(req);
             *      cache_serviced = true;
             *  }
             *  else {
             *      switch (Config.proc.cache_write_policy) {
             *          case "WriteThrough":
             *              // displace entry
             *              Sim.caches[Sim.get_cache(req.pid)].displace(req);
             *              break;
             *          case "WriteBack":
             *              Stat.procs[req.pid].cache_write.Collect();
             *              Stat.procs[req.pid].cache_hit_rate_write.Collect(1);
             *              Sim.caches[Sim.get_cache(req.pid)].service(req);
             *              cache_serviced = true;
             *              break;
             *      }
             *  }
             * }
             */

            if (!cache_serviced)
            {
                /*              if (Sim.in_hot_region(req))
                 *                Sim.thread_criticality[req.pid]++;
                 *
                 *            //add to queue
                 */

                if (!req.migrated_request)
                {
                    Sim.Dram_req_num = Sim.Dram_req_num + 1;
                }

                q.Add(req);

                if (req.type == ReqType.WR)
                {
                    Dbg.Assert(mctrl_writeq.Count < mctrl_writeq.Capacity);
                    mctrl_writeq.Add(req);
                }

                //sched
                meta_mctrl.enqueue_req(req);    //does nothing for now

                //stats
                if (!req.migrated_request)
                {
                    if (req.type == ReqType.RD)
                    {
                        rload++;
                        rload_per_proc[req.pid]++;
                        rload_per_procrankbank[req.pid, req.addr.rid, req.addr.bid]++;
                        Stat.procs[req.pid].cache_hit_rate_read.Collect(0);
                    }
                    else
                    {
                        wload++;
                        wload_per_proc[req.pid]++;
                        wload_per_procrankbank[req.pid, req.addr.rid, req.addr.bid]++;
                        Stat.procs[req.pid].cache_hit_rate_write.Collect(0);
                    }
                }
                else
                {
                    if (req.type == ReqType.RD)
                    {
                        rload++;
                    }
                    else
                    {
                        wload++;
                    }
                }
            }
        }
        new public void tick()
        {
            //must be the very first thing that's done
            cycles++;
            meta_mctrl.tick(cid);
            wbthrottle.tick();
            mwbmode.tick(cid);

            //load stats
            for (int p = 0; p < Config.N; p++)
            {
                //read load
                if (rload_per_proc[p] > 0)
                {
                    Stat.mctrls2[cid].rbinaryloadtick_per_proc[p].Collect();
                }
                Stat.mctrls2[cid].rloadtick_per_proc[p].Collect(rload_per_proc[p]);

                //write load
                if (wload_per_proc[p] > 0)
                {
                    Stat.mctrls2[cid].wbinaryloadtick_per_proc[p].Collect();
                }
                Stat.mctrls2[cid].wloadtick_per_proc[p].Collect(wload_per_proc[p]);
            }

            //busy/idle stats
            if (rload > 0)
            {
                read_loaded_time++;
                if (read_unloaded_time > 0)
                {
                    //Stat.mctrls2[cid].read_unloaded_time.Collect(read_unloaded_time);
                }
                read_unloaded_time = 0;
            }
            else
            {
                read_unloaded_time++;
                if (read_loaded_time > 0)
                {
                    //Stat.mctrls2[cid].read_loaded_time.Collect(read_loaded_time);
                }
                read_loaded_time = 0;
            }

            /*** writeback mode ***/
            update_wb_mode();

            /*
             * if (wb_mode && cid == 0) {
             *  Console.WriteLine("==={0}==============================================", cycles);
             *  Console.WriteLine("Reads to Drain:  {0}", reads_to_drain);
             *  Console.WriteLine("Writes Serviced: {0}", ((DecoupledWBFullServeN) mwbmode).serve_cnt[0]);
             *  uint r = 0;
             *  for (uint b = 0; b < bmax; b++) {
             *      Console.Write("{0}\t", b);
             *      foreach (Cmd cmd in cmdqs[r, b]) {
             *          Console.Write("{0} {1}\t", cmd.type.ToString(), can_schedule_cmd(cmd));
             *      }
             *      Console.WriteLine();
             *  }
             * }
             */

            /*** clock factor ***/
            if (cycles % Config.mem.clock_factor != 0)
            {
                return;
            }

            if ((Config.proc.cache_insertion_policy == "PFA") && (cycles % (6 * Config.mem.clock_factor) == 0))
            {
                int indexi, indexj;
                for (indexi = 0; indexi < rmax; indexi++)
                {
                    for (indexj = 0; indexj < bmax; indexj++)
                    {
                        Measurement.read_MLP_cal(ref readqs[indexi, indexj]);
                        Measurement.write_MLP_cal(ref writeqs[indexi, indexj]);
                        Measurement.MLP_cal(ref inflightqs[indexi, indexj]);
                    }
                }
            }

            /*** serve completed request ***/
            if (bus_q.Count > 0 && bus_q[0].ts <= cycles)
            {
                MemAddr addr = bus_q[0].addr;
                bus_q.RemoveAt(0);

                List <Req> inflight_q = inflightqs[addr.rid, addr.bid];


                Dbg.Assert(inflight_q.Count > 0);

                Dbg.Assert(addr == inflight_q[0].addr);
                Req req = inflight_q[0];
                inflight_q.RemoveAt(0);

                if (Config.proc.cache_insertion_policy == "PFA")
                {
                    Measurement.DramBankPidDeUpdate(req);
                }

                dequeue_req(req);
            }

            Cmd best_cmd = find_best_cmd();
            Req best_req = find_best_req();

            //nothing to issue
            if (best_cmd == null && best_req == null)
            {
                if (Config.proc.cache_insertion_policy == "PFA")
                {
                    CheckBusConflict();
                }
                return;
            }

            //arbitrate between command and request
            bool is_issue_req = false;

            if (best_req != null && best_cmd == null)
            {
                is_issue_req = true;
            }
            else if (best_req == null && best_cmd != null)
            {
                is_issue_req = false;
            }
            else
            {
                if (best_req == __better_req(best_cmd.req, best_req))
                {
                    is_issue_req = true;
                }
                else
                {
                    is_issue_req = false;
                }
            }

            //issue command or request
            if (is_issue_req)
            {
                if (!best_req.migrated_request)
                {
                    if (Config.proc.cache_insertion_policy == "RBLA")
                    {
                        RowStat.UpdateDict(RowStat.DramDict, best_req, this);
                    }
                    else if (Config.proc.cache_insertion_policy == "PFA")
                    {
                        RowStat.UpdateDict(RowStat.DramDict, best_req, this);
//                       Measurement.DramBankPidEnUpdate(best_req);
                    }
//                    if (Config.proc.cache_insertion_policy == "PFA")
//                        Measurement.DramBankPidEnUpdate(best_req);
                }

                if (Config.proc.cache_insertion_policy == "PFA")
                {
                    Measurement.DramBankPidEnUpdate(best_req);
                }

                issue_req(best_req);
            }
            else
            {
                issue_cmd(best_cmd);
            }

            if (Config.proc.cache_insertion_policy == "PFA")
            {
                CheckBusConflict();
            }
        }
        new public void update_wb_mode()
        {
            bool prev_wb_mode = wb_mode;

            wb_mode = mwbmode.is_wb_mode(cid);
            if (wb_mode)
            {
                Stat.mctrls2[cid].wbmode_fraction.Collect();
            }

            if (prev_wb_mode == false && wb_mode == true)
            {
                //stats
                ts_start_wbmode = cycles;
                if (ts_end_wbmode != -1)
                {
                    Stat.mctrls2[cid].wbmode_distance.Collect((int)(ts_start_wbmode - ts_end_wbmode));
                }

                /*
                 * if (cid == 0) {
                 *  Console.WriteLine("=====Start: {0,8}======================================", cycles);
                 *  Console.Write("\t");
                 *  for (uint b = 0; b < bmax; b++) {
                 *      Console.Write("{0,4}", readqs[0, b].Count);
                 *  }
                 *  Console.WriteLine();
                 *
                 *  Console.Write("\t");
                 *  for (uint b = 0; b < bmax; b++) {
                 *      Console.Write("{0,4}", writeqs[0, b].Count);
                 *  }
                 *  Console.WriteLine();
                 * }
                 */

                //stats: longest write transaction
                int longest_transaction = 0;
                for (uint r = 0; r < rmax; r++)
                {
                    for (uint b = 0; b < bmax; b++)
                    {
                        List <Req> q = writeqs[r, b];
                        Dictionary <ulong, int> dict = new Dictionary <ulong, int>();
                        foreach (Req req in q)
                        {
                            if (!dict.ContainsKey(req.addr.rowid))
                            {
                                dict.Add(req.addr.rowid, 0);
                            }
                            dict[req.addr.rowid] += 1;
                        }

                        foreach (int transaction in dict.Values)
                        {
                            if (transaction > longest_transaction)
                            {
                                longest_transaction = transaction;
                            }
                        }
                    }
                }
                Stat.mctrls2[cid].wbmode_longest_transaction.Collect(longest_transaction);

                /*
                 * if (cid == 0)
                 *  Console.WriteLine("Longest Transaction: {0}", longest_transaction);
                 */

                //flush/drain reads
                reads_to_drain = 0;
                for (uint r = 0; r < rmax; r++)
                {
                    for (uint b = 0; b < bmax; b++)
                    {
                        List <Cmd> cmdq = cmdqs[r, b];
                        if (cmdq.Count == 0)
                        {
                            continue;
                        }

                        //only column command
                        if (cmdq.Count == 1)
                        {
                            //increment the number of reads to drain during the first part of the writeback mode
                            Dbg.Assert(cmdq[0].type == Cmd.TypeEnum.READ || cmdq[0].type == Cmd.TypeEnum.WRITE);
                            if (cmdq[0].type == Cmd.TypeEnum.READ)
                            {
                                reads_to_drain++;
                                cmdq[0].is_drain = true;
                            }
                            continue;
                        }

                        //activate+column command
                        Dbg.Assert(cmdq.Count == 2);
                        Dbg.Assert(cmdq[0].type == Cmd.TypeEnum.ACTIVATE);
                        Dbg.Assert(cmdq[1].type == Cmd.TypeEnum.READ || cmdq[1].type == Cmd.TypeEnum.WRITE);

                        //write requests don't matter
                        if (cmdq[1].type == Cmd.TypeEnum.WRITE)
                        {
                            continue;
                        }

                        //don't flush read request
                        if (Config.mctrl.read_bypass)
                        {
                            if (writeqs[r, b].Count == 0)
                            {
                                continue;
                            }
                        }

                        //flush read request
                        Req req = cmdq[1].req;

                        List <Req> inflightq = get_inflight_q(req);
                        Req        last_req  = inflightq[inflightq.Count - 1];
                        Dbg.Assert(last_req.block_addr == req.block_addr);
                        inflightq.RemoveAt(inflightq.Count - 1);

                        if (Config.proc.cache_insertion_policy == "PFA")
                        {
                            Measurement.DramResetRowBufferChange(req);
                        }


                        List <Req> q = get_q(req);

                        //               Dbg.Assert(q.Count <= q.Capacity);
                        q.Add(req);

                        //flush read command
                        cmdq.RemoveRange(0, 2);

                        if (Config.proc.cache_insertion_policy == "PFA")
                        {
                            Measurement.Dram_bus_conflict_reset(req.pid);
                        }
                    }
                }
            }
            else if (prev_wb_mode == true && wb_mode == false)
            {
                //stats
                ts_end_wbmode = cycles;
                Stat.mctrls2[cid].wbmode_length.Collect((int)(ts_end_wbmode - ts_start_wbmode));

                /*
                 * if (cid == 0) {
                 *  Console.WriteLine("Length: {0}", cycles-ts_start_wbmode);
                 *  Console.WriteLine("Rds: {0}", rds_per_wb_mode);
                 *  Console.WriteLine("Wrs: {0}", wbs_per_wb_mode);
                 *  Console.WriteLine("=====End: {0,8}======================================", cycles);
                 * }
                 */

                Stat.mctrls2[cid].rds_per_wb_mode.Collect(rds_per_wb_mode);
                Stat.mctrls2[cid].wbs_per_wb_mode.Collect(wbs_per_wb_mode);
                rds_per_wb_mode = 0;
                wbs_per_wb_mode = 0;

                //flush/drain writes
                writes_to_drain = 0;
                foreach (List <Cmd> cmdq in cmdqs)
                {
                    if (cmdq.Count == 0)
                    {
                        continue;
                    }

                    //only column command
                    if (cmdq.Count == 1)
                    {
                        //increment the number of reads to drain during the first part of the writeback mode
                        Dbg.Assert(cmdq[0].type == Cmd.TypeEnum.READ || cmdq[0].type == Cmd.TypeEnum.WRITE);
                        if (cmdq[0].type == Cmd.TypeEnum.WRITE)
                        {
                            writes_to_drain++;
                            cmdq[0].is_drain = true;
                        }
                        continue;
                    }

                    //activate+column command
                    Dbg.Assert(cmdq.Count == 2);
                    Dbg.Assert(cmdq[0].type == Cmd.TypeEnum.ACTIVATE);
                    Dbg.Assert(cmdq[1].type == Cmd.TypeEnum.READ || cmdq[1].type == Cmd.TypeEnum.WRITE);

                    if (cmdq[1].type == Cmd.TypeEnum.READ)
                    {
                        continue;
                    }

                    //flush read request
                    Req req = cmdq[1].req;

                    List <Req> inflightq = get_inflight_q(req);
                    Req        last_req  = inflightq[inflightq.Count - 1];
                    Dbg.Assert(last_req.block_addr == req.block_addr);
                    inflightq.RemoveAt(inflightq.Count - 1);

                    if (Config.proc.cache_insertion_policy == "PFA")
                    {
                        Measurement.DramResetRowBufferChange(req);
                    }

                    List <Req> q = get_q(req);

                    //             Dbg.Assert(q.Count <= q.Capacity);
                    q.Add(req);

                    //flush read command
                    cmdq.RemoveRange(0, 2);

                    if (Config.proc.cache_insertion_policy == "PFA")
                    {
                        Measurement.Dram_bus_conflict_reset(req.pid);
                    }
                }
            }
        }
        private void issue_cmd(Cmd cmd)
        {
            MemAddr addr = cmd.addr;

            /*
             * if (cid == 0 && wb_mode) {
             *  Console.Write("@{0}\t", cycles - ts_start_wbmode);
             *  for (uint b = 0; b < addr.bid; b++) {
             *      Console.Write("{0,4}", "-");
             *  }
             *  Console.Write("{0,4}", cmd.type.ToString()[0]);
             *  for (uint b = addr.bid; b < bmax; b++) {
             *      Console.Write("{0,4}", "-");
             *  }
             *  Console.WriteLine();
             * }
             */

            List <Cmd> cmd_q = cmdqs[addr.rid, addr.bid];

            Dbg.Assert(cmd == cmd_q[0]);
            cmd_q.RemoveAt(0);
            BankStat bank_stat = Stat.banks2[addr.cid, addr.rid, addr.bid];
            BusStat  bus_stat  = Stat.busses2[addr.cid];

            //writeback mode stats
            if (wb_mode)
            {
                if (cmd.type == Cmd.TypeEnum.READ)
                {
                    rds_per_wb_mode++;
                }
                else if (cmd.type == Cmd.TypeEnum.WRITE)
                {
                    wbs_per_wb_mode++;
                }
            }

            //string dbg;
            switch (cmd.type)
            {
            case Cmd.TypeEnum.ACTIVATE:
                activate(addr);

                /*dbg = String.Format("@{0,6} DRAM ACTI: Channel {1}, Rank {2}, Bank {3}, Row {4}, Col {5}",
                 *  cycles, cid, addr.rid, addr.bid, addr.rowid, addr.colid);*/
                //stats
                bank_stat.cmd_activate.Collect();
                bank_stat.utilization.Collect(timing.tRCD);

                //shadow row-buffer id
                shadow_rowid_per_procrankbank[cmd.pid, addr.rid, addr.bid] = addr.rowid;
                break;

            case Cmd.TypeEnum.PRECHARGE:
                precharge(addr);

                /*dbg = String.Format("@{0,6} DRAM PREC: Channel {1}, Rank {2}, Bank {3}, Row {4}, Col {5}",
                 *  cycles, cid, addr.rid, addr.bid, addr.rowid, addr.colid);*/
                //stats
                bank_stat.cmd_precharge.Collect();
                bank_stat.utilization.Collect(timing.tRP);
                break;

            case Cmd.TypeEnum.READ:
                read(addr);

                if (Config.proc.cache_insertion_policy == "PFA")
                {
                    Measurement.Dram_bus_conflict_reset(cmd.req.pid);
                }

                /*dbg = String.Format("@{0,6} DRAM READ: Channel {1}, Rank {2}, Bank {3}, Row {4}, Col {5}",
                 *  cycles, cid, addr.rid, addr.bid, addr.rowid, addr.colid);*/

                //writeback mode
                if (wb_mode && cmd.is_drain)
                {
                    Dbg.Assert(reads_to_drain > 0);
                    reads_to_drain--;
                }

                //stats
                bank_stat.cmd_read.Collect();
                bank_stat.utilization.Collect(timing.tCL);
                bus_stat.access.Collect();
                bus_stat.utilization.Collect(timing.tBL);
                break;

            case Cmd.TypeEnum.WRITE:
                write(addr);
                if (Config.proc.cache_insertion_policy == "PFA")
                {
                    Measurement.Dram_bus_conflict_reset(cmd.req.pid);
                }

                /*dbg = String.Format("@{0,6} DRAM WRTE: Channel {1}, Rank {2}, Bank {3}, Row {4}, Col {5}",
                 *  cycles, cid, addr.rid, addr.bid, addr.rowid, addr.colid);*/

                //writeback mode
                if (!wb_mode && cmd.is_drain)
                {
                    Dbg.Assert(writes_to_drain > 0);
                    writes_to_drain--;
                }
                else
                {
                    mwbmode.issued_write_cmd(cmd);
                }

                //stats
                bank_stat.cmd_write.Collect();
                bank_stat.utilization.Collect(timing.tCL);
                bus_stat.access.Collect();
                bus_stat.utilization.Collect(timing.tBL);
                break;

            default:
                //should never get here
                throw new System.Exception("DRAM: Invalid Cmd.");
            }
            //Debug.WriteLine(dbg);
        }
        private void issue_req(Req req)
        {
            //remove request from waiting queue
            List <Req> q = get_q(req);

            Dbg.Assert(q.Contains(req));
            q.Remove(req);

            //add to inflight queue
            MemAddr    addr       = req.addr;
            List <Req> inflight_q = inflightqs[addr.rid, addr.bid];

            Dbg.Assert(inflight_q.Count < inflight_q.Capacity);
            inflight_q.Add(req);

            //add to command queue
            List <Cmd> cmd_q = cmdqs[addr.rid, addr.bid];

            Dbg.Assert(cmd_q.Count == 0);
            List <Cmd> new_cmd_q = decode_req(req);

            Dbg.Assert(new_cmd_q.Count > 0);
            cmd_q.AddRange(new_cmd_q);

            Cmd cmd = cmd_q[0];

            //meta_mctrl
            meta_mctrl.issue_req(req);

            Dbg.Assert(cmd.req.addr.rowid == req.addr.rowid);

            //stats
            BankStat bstat = Stat.banks2[addr.cid, addr.rid, addr.bid];

            bstat.access.Collect();
            if (cmd.type == Cmd.TypeEnum.PRECHARGE || cmd.type == Cmd.TypeEnum.ACTIVATE)
            {
                //bank stat
                bstat.row_miss.Collect();
                bstat.row_miss_perproc[req.pid].Collect();

                //proc stat
                if (cmd.req.type == ReqType.RD)
                {
                    Stat.procs[req.pid].row_hit_rate_read.Collect(0);
                    Stat.procs[req.pid].row_miss_read.Collect();
                }
                else
                {
                    Stat.procs[req.pid].row_hit_rate_write.Collect(0);
                    Stat.procs[req.pid].row_miss_write.Collect();
                }


                req.hit = 2;

// Power Measurement:
                Sim.DRAM_power_statistics(req.pid, req.migrated_request, req.type, false);
//

                if (Config.proc.cache_insertion_policy == "PFA")
                {
//                      if ((!req.migrated_request) && (req.type == ReqType.RD))
                    Measurement.DramMissSetRowBufferChange(req);
                }
            }
            else
            {
                //bank stat
                bstat.row_hit.Collect();
                bstat.row_hit_perproc[req.pid].Collect();

                //proc stat
                if (cmd.req.type == ReqType.RD)
                {
                    Stat.procs[req.pid].row_hit_rate_read.Collect(1);
                    Stat.procs[req.pid].row_hit_read.Collect();
                }
                else
                {
                    Stat.procs[req.pid].row_hit_rate_write.Collect(1);
                    Stat.procs[req.pid].row_hit_write.Collect();
                }


                req.hit = 1;

// Power Measurement:
                Sim.DRAM_power_statistics(req.pid, req.migrated_request, req.type, true);
//

                if (Config.proc.cache_insertion_policy == "PFA")
                {
                    Measurement.DramHitSetRowBufferChange(req);
                }
            }

            if (Config.proc.cache_insertion_policy == "PFA")
            {
                Measurement.DramSetCorePrevRowid(req);
            }

            //issue command
            issue_cmd(cmd);

            if (cmd.addr != req.addr)
            {
                Console.Write("big error!");
            }
        }
        public void __enqueue_req(Req req, List <Req> q)
        {
            //timestamp
            req.ts_arrival = cycles;

/*            // do any analysis
 *          if (Config.collect_reuse == true) {
 *              if (Sim.reuse[req.pid].ContainsKey(req.block_addr))
 *                  Sim.reuse[req.pid][req.block_addr] = Sim.reuse[req.pid][req.block_addr] + 1;
 *              else
 *                  Sim.reuse[req.pid].Add(req.block_addr, 1);
 *          }
 */
            // check if cache hit
            bool cache_serviced = false;


            // don't allow cache writeback requests to be re-cached
            if (Config.proc.cache && Sim.caches[Sim.get_cache(req.pid)].is_cached(req) && (!req.migrated_request))
            {
                if (Config.proc.cache_insertion_policy == "PFA")
                {
                    Measurement.mem_num_inc(req);
                }

                Sim.caches[Sim.get_cache(req.pid)].promote(req);
                //stats
                if (req.type == ReqType.RD)
                {
                    Stat.procs[req.pid].cache_read.Collect();
                    Stat.procs[req.pid].cache_hit_rate_read.Collect(1);
                    Sim.caches[Sim.get_cache(req.pid)].service(req);
                    cache_serviced = true;
                }
                else
                {
                    switch (Config.proc.cache_write_policy)
                    {
                    case "WriteThrough":
                        // displace entry
                        Sim.caches[Sim.get_cache(req.pid)].displace(req);
                        break;

                    case "WriteBack":
                        Stat.procs[req.pid].cache_write.Collect();
                        Stat.procs[req.pid].cache_hit_rate_write.Collect(1);
                        Sim.caches[Sim.get_cache(req.pid)].service(req);
                        cache_serviced = true;
                        break;
                    }
                }
            }

            if (!cache_serviced)
            {
                if (!req.migrated_request)
                {
                    Sim.NVM_req_num = Sim.NVM_req_num + 1;
                }

                if ((!req.migrated_request) && (Config.proc.cache_insertion_policy == "PFA"))
                {
                    Measurement.mem_num_inc(req);
                }
                if (Config.proc.cache_insertion_policy == "PFA")
                {
                    Measurement.NVMCoreReqNumInc(req);
                }
                q.Add(req);
                if (req.type == ReqType.WR)
                {
                    Dbg.Assert(mctrl_writeq.Count < mctrl_writeq.Capacity);
                    mctrl_writeq.Add(req);
                }
                //sched
                meta_mctrl.enqueue_req(req);    //does nothing for now

                //stats
                if (!req.cache_wb)
                {
                    if (req.type == ReqType.RD)
                    {
                        rload++;
                        rload_per_proc[req.pid]++;
                        rload_per_procrankbank[req.pid, req.addr.rid, req.addr.bid]++;
                        Stat.procs[req.pid].cache_hit_rate_read.Collect(0);
                    }
                    else
                    {
                        wload++;
                        wload_per_proc[req.pid]++;
                        wload_per_procrankbank[req.pid, req.addr.rid, req.addr.bid]++;
                        Stat.procs[req.pid].cache_hit_rate_write.Collect(0);
                    }
                }
                else
                {
                    if (req.type == ReqType.RD)
                    {
                        rload++;
                    }
                    else
                    {
                        wload++;
                    }
                }
            }
        }
        public void __dequeue_req(Req req)
        {
            req.ts_departure = cycles;
            Dbg.Assert(req.ts_departure - req.ts_arrival > 0);


            if (!req.migrated_request)
            {
                if (Config.proc.cache_insertion_policy == "PFA")
                {
                    RowStat.UpdateMLP(RowStat.NVMDict, req);
                    Measurement.mem_num_dec(req);
//                    Measurement.NVMServiceTimeUpdate (req);
//                    Measurement.NVMCoreReqNumDec (req);
                    Row_Migration_Policies.target     = true;
                    Row_Migration_Policies.target_req = req;
                }
                else if (Config.proc.cache_insertion_policy == "RBLA")
                {
                    Row_Migration_Policies.target     = true;
                    Row_Migration_Policies.target_req = req;
                }
            }
            if (Config.proc.cache_insertion_policy == "PFA")
            {
                Measurement.NVMCoreReqNumDec(req);
            }

/*            if (Config.proc.cache_insertion_policy == "PFA")
 *          {
 *                 Measurement.NVMSetCorePrevRowid (req);
 *          }
 */
            //sched
            meta_mctrl.dequeue_req(req);

            //load stat management
            if (!req.cache_wb)
            {
                if (req.type == ReqType.RD)
                {
                    rload--;
                    rload_per_proc[req.pid]--;
                    rload_per_procrankbank[req.pid, req.addr.rid, req.addr.bid]--;
                    Dbg.Assert(rload >= 0);
                    Dbg.Assert(rload_per_proc[req.pid] >= 0);
                    Dbg.Assert(rload_per_procrankbank[req.pid, req.addr.rid, req.addr.bid] >= 0);
                }
                else
                {
                    wload--;
                    wload_per_proc[req.pid]--;
                    wload_per_procrankbank[req.pid, req.addr.rid, req.addr.bid]--;
                    Dbg.Assert(wload >= 0);
                    Dbg.Assert(wload_per_proc[req.pid] >= 0);
                    Dbg.Assert(wload_per_procrankbank[req.pid, req.addr.rid, req.addr.bid] >= 0);
                }
            }
            else
            {
                if (req.type == ReqType.RD)
                {
                    rload--;
                }
                else
                {
                    wload--;
                }
            }

/*           //dequeue proper
 *         if (req.type == ReqType.RD) {
 *              //traverse crossbar
 *            Sim.xbar.enqueue(req);
 *
 *              //cache
 *             Sim.caches[Sim.get_cache(req.pid)].meta_insert(req);
 *          }
 *          else {
 *              bool removeok = mctrl_writeq.Remove(req);
 *              Dbg.Assert(removeok);
 *              req.latency = (int)(req.ts_departure - req.ts_arrival);
 *
 *              Callback cb = req.callback;
 *              cb(req);
 *
 *              if (!req.cache_wb) {
 *                  //cache
 *                  switch (Config.proc.cache_write_policy) {
 *                      case "WriteThrough":
 *                          // do nothing
 *                          break;
 *                      case "WriteBack":
 *                            Sim.caches[Sim.get_cache(req.pid)].meta_insert(req);
 *                          break;
 *                  }
 *              }
 *              else
 *                  RequestPool.enpool(req);
 *          }
 */


            if (req.type == ReqType.RD)
            {
                if (!Sim.caches[Sim.get_cache(req.pid)].is_cached(req))
                {
                    Sim.caches[Sim.get_cache(req.pid)].meta_insert(req);
                }
                //      if (req.callback != null)
                Sim.xbar.enqueue(req);
                //      else
                //           RequestPool.enpool(req);
            }
            else
            {
                bool removeok = mctrl_writeq.Remove(req);
                Dbg.Assert(removeok);
                req.latency = (int)(req.ts_departure - req.ts_arrival);
                Callback cb = req.callback;
                if (!req.cache_wb)
                {
                    switch (Config.proc.cache_write_policy)
                    {
                    case "WriteThrough":
                        break;

                    case "WriteBack":
                        if (!Sim.caches[Sim.get_cache(req.pid)].is_cached(req))
                        {
                            Sim.caches[Sim.get_cache(req.pid)].meta_insert(req);
                        }
                        break;
                    }
                    if (cb != null)
                    {
                        cb(req);
                    }
                    //           else
                    //             RequestPool.enpool(req);
                }
                else
                {
                    RequestPool.enpool(req);
                }
            }
        }
Example #9
0
        static void initialize()
        {
            if (Config.task_based == true)
            {
                string task_fname = Config.traceFileNames[0];
                if (Config.sim_type == Config.SIM_TYPE.GROUPED)
                {
                    task_fname = Config.traceFileNames[Config.group_boundary];
                }
                foreach (string dir in Config.TraceDirs.Split(',', ' '))
                {
                    if (File.Exists(dir + "/" + task_fname))
                    {
                        task_fname = dir + "/" + task_fname;
                    }
                }
                Dbg.Assert(File.Exists(task_fname));
                StreamReader tasks = new StreamReader(File.OpenRead(task_fname));
                while (true)
                {
                    string line = tasks.ReadLine();
                    if (line == null)
                    {
                        break;
                    }
                    task_queue.Enqueue(line);
                }
                tasks.Close();
            }

            Dram_Utilization_size = 0;
            Dram_req_num          = 0;
            NVM_req_num           = 0;

            //randomized page table
            ulong          page_size = 4 * 1024;
            PageRandomizer prand     = new PageRandomizer(page_size);

            Req.prand = prand;

            //processors
            procs = new Proc[Config.N];
            for (int p = 0; p < Config.N; p++)
            {
                if ((Config.task_based == true && Config.sim_type != Config.SIM_TYPE.GROUPED) ||
                    (Config.task_based == true && Config.sim_type == Config.SIM_TYPE.GROUPED && p >= Config.group_boundary && p < Config.N))
                {
                    procs[p] = new Proc(task_queue.Dequeue());
                }
                else
                {
                    procs[p] = new Proc(Config.traceFileNames[p]);
                }
            }

            //crossbar
            xbar = new Xbar();

// warmup phase
            proc_warmup        = new bool[Config.N];
            proc_warmup_cycles = new ulong[Config.N];
            for (int p = 0; p < Config.N; p++)
            {
                proc_warmup[p]        = false;
                proc_warmup_cycles[p] = 0;
            }

// Power Measurement:
            processor_finished        = new bool[Config.N];
            DRAM_processor_read_hit   = new ulong[Config.N];
            DRAM_processor_read_miss  = new ulong[Config.N];
            DRAM_processor_write_hit  = new ulong[Config.N];
            DRAM_processor_write_miss = new ulong[Config.N];
            DRAM_migration_read_hit   = new ulong[Config.N];
            DRAM_migration_read_miss  = new ulong[Config.N];
            DRAM_migration_write_hit  = new ulong[Config.N];
            DRAM_migration_write_miss = new ulong[Config.N];
            NVM_processor_read_hit    = new ulong[Config.N];
            NVM_processor_read_miss   = new ulong[Config.N];
            NVM_processor_write_hit   = new ulong[Config.N];
            NVM_processor_write_miss  = new ulong[Config.N];
            NVM_migration_read_hit    = new ulong[Config.N];
            NVM_migration_read_miss   = new ulong[Config.N];
            NVM_migration_write_hit   = new ulong[Config.N];
            NVM_migration_write_miss  = new ulong[Config.N];
            processor_cycles          = new ulong[Config.N];

            for (int p = 0; p < Config.N; p++)
            {
                processor_finished[p]        = false;
                DRAM_processor_read_hit[p]   = 0;
                DRAM_processor_read_miss[p]  = 0;
                DRAM_processor_write_hit[p]  = 0;
                DRAM_processor_write_miss[p] = 0;
                DRAM_migration_read_hit[p]   = 0;
                DRAM_migration_read_miss[p]  = 0;
                DRAM_migration_write_hit[p]  = 0;
                DRAM_migration_write_miss[p] = 0;
                NVM_processor_read_hit[p]    = 0;
                NVM_processor_read_miss[p]   = 0;
                NVM_processor_write_hit[p]   = 0;
                NVM_processor_write_miss[p]  = 0;
                NVM_migration_read_hit[p]    = 0;
                NVM_migration_read_miss[p]   = 0;
                NVM_migration_write_hit[p]   = 0;
                NVM_migration_write_miss[p]  = 0;
                processor_cycles[p]          = 0;
            }
//

            //Jin: Row Migration Policies
            rmp   = new Row_Migration_Policies();
            mesur = new Measurement();

            //ddr3
            DDR3DRAM ddr3 = new DDR3DRAM(Config.mem.ddr3_type, Config.mem.clock_factor, Config.mem.tWR, Config.mem.tWTR);
            uint     cmax = (uint)Config.mem.channel_max;
            uint     rmax = (uint)Config.mem.rank_max;

            //sequential page table
            PageSequencer pseq = new PageSequencer(page_size, cmax, rmax, ddr3.BANK_MAX);

            Req.pseq = pseq;


            //memory mapping
            MemMap.init(Config.mem.map_type, Config.mem.channel_max, Config.mem.rank_max, Config.mem.col_per_subrow, ddr3);

            //memory controllers
            mctrls = new MemCtrl[Config.mem.mctrl_num][];
            for (int n = 0; n < Config.mem.mctrl_num; n++)
            {
                mctrls[n] = new MemCtrl[cmax];
                for (int i = 0; i < mctrls[n].Length; i++)
                {
                    mctrls[n][i] = new MemCtrl(rmax, ddr3);
                }
            }

            //memory schedulers and metamemory controllers
            if (!Config.sched.is_omniscient)
            {
                MemSched[][] scheds = new MemSched[Config.mem.mctrl_num][];
                for (int n = 0; n < Config.mem.mctrl_num; n++)
                {
                    scheds[n] = new MemSched[cmax];
                    for (int i = 0; i < cmax; i++)
                    {
                        scheds[n][i] = Activator.CreateInstance(Config.sched.typeof_sched_algo) as MemSched;
                    }
                }

                MemSched[][] wbscheds = new MemSched[Config.mem.mctrl_num][];
                for (int n = 0; n < Config.mem.mctrl_num; n++)
                {
                    wbscheds[n] = new MemSched[cmax];
                    if (!Config.sched.same_sched_algo)
                    {
                        for (int i = 0; i < cmax; i++)
                        {
                            wbscheds[n][i] = Activator.CreateInstance(Config.sched.typeof_wbsched_algo) as MemSched;
                        }
                    }
                    else
                    {
                        for (int i = 0; i < cmax; i++)
                        {
                            wbscheds[n][i] = scheds[n][i];
                        }
                    }
                }

                MetaMemCtrl[][] meta_mctrls = new MetaMemCtrl[Config.mem.mctrl_num][];
                for (int n = 0; n < Config.mem.mctrl_num; n++)
                {
                    meta_mctrls[n] = new MetaMemCtrl[cmax];
                    for (int i = 0; i < cmax; i++)
                    {
                        meta_mctrls[n][i]       = new MetaMemCtrl(mctrls[n][i], scheds[n][i], wbscheds[n][i]);
                        mctrls[n][i].meta_mctrl = meta_mctrls[n][i];
                        scheds[n][i].meta_mctrl = meta_mctrls[n][i];
                        scheds[n][i].initialize();
                        wbscheds[n][i].meta_mctrl = meta_mctrls[n][i];
                        wbscheds[n][i].initialize();
                    }
                }
            }
            else
            {
                MemSched[] sched   = new MemSched[Config.mem.mctrl_num];
                MemSched[] wbsched = new MemSched[Config.mem.mctrl_num];
                for (int n = 0; n < Config.mem.mctrl_num; n++)
                {
                    sched[n] = Activator.CreateInstance(Config.sched.typeof_sched_algo) as MemSched;
                    if (!Config.sched.same_sched_algo)
                    {
                        wbsched[n] = Activator.CreateInstance(Config.sched.typeof_wbsched_algo) as MemSched;
                    }
                    else
                    {
                        wbsched[n] = sched[n];
                    }
                }

                MetaMemCtrl[] meta_mctrl = new MetaMemCtrl[Config.mem.mctrl_num];
                for (int n = 0; n < Config.mem.mctrl_num; n++)
                {
                    meta_mctrl[n] = new MetaMemCtrl(mctrls[n], sched[n], wbsched[n]);
                    for (int i = 0; i < cmax; i++)
                    {
                        mctrls[n][i].meta_mctrl = meta_mctrl[n];
                    }
                    sched[n].meta_mctrl = meta_mctrl[n];
                    sched[n].initialize();
                    wbsched[n].meta_mctrl = meta_mctrl[n];
                    wbsched[n].initialize();
                }
            }

            //wbmode
            for (int n = 0; n < Config.mem.mctrl_num; n++)
            {
                mwbmode = Activator.CreateInstance(Config.mctrl.typeof_wbmode_algo, new Object[] { mctrls[n] }) as MemWBMode;
                for (int i = 0; i < cmax; i++)
                {
                    mctrls[n][i].mwbmode = mwbmode;
                }

                //blp tracker
                blptracker = new BLPTracker(mctrls[n]);
            }
        }