예제 #1
0
        private static Cmd base_cmd_issue(ReqType r, MemAddr a, Cmd cmd, NodeMachine bank, NodeMachine subarray)
        {
            Dbg.Assert(bank.OpenChildrenId.Count <= 1);

            // closed bank
            if (bank.OpenChildrenId.Count == 0)
            {
                cmd.Type = CmdType.ACT;
                return(cmd);
            }

            // subarray-miss
            if (bank.OpenChildrenId[0] != a.said)
            {
                cmd.Type = CmdType.PRE_BANK;
                return(cmd);
            }

            // row-miss
            if (subarray.OpenChildrenId[0] != a.rowid)
            {
                cmd.Type = CmdType.PRE_BANK;
                return(cmd);
            }

            // row-hit
            cmd.Type = r == ReqType.READ ? CmdType.RD : CmdType.WR;
            return(cmd);
        }
예제 #2
0
        private static Cmd salp1_cmd_issue(ReqType r, MemAddr a, Cmd cmd, NodeMachine bank, NodeMachine subarray)
        {
            Dbg.Assert(bank.OpenChildrenId.Count <= 1);

            // closed bank
            if (bank.OpenChildrenId.Count == 0)
            {
                cmd.Type = CmdType.ACT;
                return(cmd);
            }

            // subarray-miss
            if (bank.OpenChildrenId[0] != a.said)
            {
                cmd.Type      = CmdType.PRE_SA;
                cmd.Addr.said = (uint)bank.OpenChildrenId[0]; // close the opened sibling
                return(cmd);
            }

            // row-miss
            if (subarray.OpenChildrenId[0] != a.rowid)
            {
                cmd.Type = CmdType.PRE_SA;
                return(cmd);
            }

            // row-hit
            cmd.Type = r == ReqType.READ ? CmdType.RD : CmdType.WR;
            return(cmd);
        }
예제 #3
0
        private static Cmd masa_cmd_issue(ReqType r, MemAddr a, Cmd cmd, NodeMachine bank, NodeMachine subarray)
        {
            var open_said = bank.OpenChildrenId;

            // subarray-miss
            if (!open_said.Contains(a.said))
            {
                cmd.Type = CmdType.ACT;
                return(cmd);
            }

            // row-miss
            if (!subarray.OpenChildrenId.Contains(a.rowid))
            {
                cmd.Type = CmdType.PRE_SA;
                return(cmd);
            }

            // not the most-recently-opened subarray
            if (open_said[0] != a.said && !Config.mctrl.b_piggyback_SEL_SA)
            {
                cmd.Type = CmdType.SEL_SA;
                return(cmd);
            }

            // row-hit
            cmd.Type = r == ReqType.READ ? CmdType.RD : CmdType.WR;
            return(cmd);
        }
예제 #4
0
        private static Cmd salp2_cmd_issue(ReqType r, MemAddr a, Cmd cmd, NodeMachine bank, NodeMachine subarray)
        {
            Dbg.Assert(bank.OpenChildrenId.Count <= 2);

            // closed bank
            if (bank.OpenChildrenId.Count == 0)
            {
                cmd.Type = CmdType.ACT;
                return(cmd);
            }
            // open bank (one subarray)
            if (bank.OpenChildrenId.Count == 1)
            {
                // subarray-miss
                if (bank.OpenChildrenId[0] != a.said)
                {
                    cmd.Type = CmdType.ACT;
                    return(cmd);
                }

                // row-miss
                if (subarray.OpenChildrenId[0] != a.rowid)
                {
                    cmd.Type = CmdType.PRE_SA;
                    return(cmd);
                }

                // row-hit
                cmd.Type = r == ReqType.READ ? CmdType.RD : CmdType.WR;
                return(cmd);
            }
            // open bank (two subarrays)
            // all subarray-miss
            if (!bank.OpenChildrenId.Contains(a.said))
            {
                cmd.Type      = CmdType.PRE_SA;
                cmd.Addr.said = (uint)bank.OpenChildrenId[1]; // close least-recently-opened subarray
                return(cmd);
            }

            // not the most-recently-opened subarray
            if (bank.OpenChildrenId[0] != a.said)
            {
                cmd.Type      = CmdType.PRE_SA;
                cmd.Addr.said = (uint)bank.OpenChildrenId[1]; // close least-recently-opened subarray
                return(cmd);
            }

            // row-miss
            if (subarray.OpenChildrenId[0] != a.rowid)
            {
                cmd.Type = CmdType.PRE_SA;
                return(cmd);
            }

            // row-hit
            cmd.Type = r == ReqType.READ ? CmdType.RD : CmdType.WR;
            return(cmd);
        }
예제 #5
0
 public MemAddr(MemAddr addr)
 {
     cid   = addr.cid;
     rid   = addr.rid;
     bid   = addr.bid;
     said  = addr.said;
     rowid = addr.rowid;
     colid = addr.colid;
 }
예제 #6
0
        /* Updates the DRAM state based on the DRAM command that has been issued */

        public void Update(CmdType c, MemAddr a, long cycles)
        {
            ulong[] addrArray = { a.cid, a.rid, a.bid, a.said, a.rowid };

            // activate || switch open subarray
            if (c == CmdType.ACT || c == CmdType.SEL_SA)
            {
                _channel.Open(addrArray, cycles);
                return;
            }

            // precharge
            if (c == CmdType.PRE_RANK || c == CmdType.PRE_BANK || c == CmdType.PRE_SA)
            {
                var level = NodeMachine.Level.RANK;

                if (c == CmdType.PRE_RANK)
                {
                    level = NodeMachine.Level.RANK;
                }
                else if (c == CmdType.PRE_BANK)
                {
                    level = NodeMachine.Level.BANK;
                }
                else if (c == CmdType.PRE_SA)
                {
                    level = NodeMachine.Level.SUBARRAY;
                }

                var node = _channel.Get(level, addrArray);
                node.Close();
                return;
            }

            // read/write + autoprecharge
            if (c == CmdType.RD_AP || c == CmdType.WR_AP)
            {
                var node =
                    _channel.Get(Config.mctrl.salp == SALP.NONE ? NodeMachine.Level.BANK : NodeMachine.Level.SUBARRAY,
                                 addrArray);
                node.Close();
                return;
            }

            // More than one row buffer -- Put the most recently accessed row at the front of the list
            if (Config.mem.max_row_buffer_count <= 1 ||
                (c != CmdType.RD && c != CmdType.RD_AP && c != CmdType.WR && c != CmdType.WR_AP))
            {
                return;
            }
            var saNode = _channel.Get(NodeMachine.Level.SUBARRAY, addrArray);

            Dbg.Assert(saNode.OpenChildrenId.Remove(a.rowid));
            saNode.OpenChildrenId.Insert(0, a.rowid);
        }
예제 #7
0
 public void Update(long cycles, CmdType c, MemAddr a, bool villaCache = false,
                    bool chargeCacheHit = false)
 {
     uint[] addrArray = { a.cid, a.rid, a.bid, a.said };
     Channel.Update(cycles, (int)c, addrArray, villaCache, chargeCacheHit);
 }
예제 #8
0
 public bool Check(long cycles, CmdType c, MemAddr a)
 {
     uint[] addrArray = { a.cid, a.rid, a.bid, a.said };
     return(Channel.Check(cycles, (int)c, addrArray));
 }
예제 #9
0
        //MemoryAddress
        public static MemAddr Translate(ulong paddr)
        {
            MemAddr addr = new MemAddr();

            /* step 1: channel index */
            addr.cid = (uint)((paddr & _chanMask) >> (int)_chanOffset);

            /* step 2: rank index */
            addr.rid = (uint)((paddr & _rankMask) >> (int)_rankOffset);

            /* step 3: bank index */
            if (_bank2Bits == 0)
            {
                addr.bid = (uint)((paddr & _bankMask) >> (int)_bankOffset);
            }
            else
            {
                // special provisioning: split bank index */
                uint bid2 = (uint)((paddr & _bank2Mask) >> (int)_bank2Offset);
                uint bid1 = (uint)((paddr & _bank1Mask) >> (int)_bank1Offset);
                uint bid  = bid2 + (bid1 << (int)_bank2Bits);
                addr.bid = bid;
            }

            /* step 4: row index (no mask, comes from MSb) */
            addr.rowid = paddr >> (int)_rowOffset;

            /* step 5: column index */
            if (_col2Bits == 0)
            {
                addr.colid = (uint)((paddr & _colMask) >> (int)_colOffset);
            }
            else
            {
                // special provisioning for split column index
                uint col2id = (uint)((paddr & _col2Mask) >> (int)_col2Offset);
                uint col1id = (uint)((paddr & _col1Mask) >> (int)_col1Offset);
                uint colid  = col2id + (col1id << (int)_col2Bits);
                addr.colid = colid;
            }

            /* step 6: subarray index */
            if (_subarrayOffset == 0)
            {
                // default: subarray index is LSb of row index
                _subarrayMask = (1UL << (int)_subarrayBits) - 1;
                addr.said     = (uint)(addr.rowid & _subarrayMask);
            }
            else if (_subarrayBits != 0)
            {
                // special provisioning: subarray index at specified location
                addr.said = (uint)((paddr & _subarrayMask) >> (int)_subarrayOffset);

                // CAUTION: subarray index must be included in the row index.
                // This is because row-buffer hit status is determined solely
                // on the row index at the granularity of a bank in the
                // baseline system without SALP. If sa index is not included,
                // accessing two different rows with the same row index in
                // different subarrays within the same bank would be considered
                // as a row hit.
                addr.rowid <<= (int)_subarrayBits;
                addr.rowid  += addr.said;
            }

            /* step 7: we're done */
            return(addr);
        }