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++;
                    }
                }
            }
        }