simple_mem_bank_impl.hh
来自「linux下基于c++的处理器仿真平台。具有处理器流水线」· HH 代码 · 共 261 行
HH
261 行
/* * Copyright (c) 2002, 2003, 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator, developed by Nathan Binkert, * Erik Hallnor, Steve Raasch, and Steve Reinhardt, with contributions * from Ron Dreslinski, Dave Greene, Lisa Hsu, Kevin Lim, Ali Saidi, * and Andrew Schultz. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. *//** * @file * Definition of a simple main memory. */#include <sstream>#include <string>#include <vector>#include "config/full_system.hh"#include "cpu/base.hh"#include "cpu/exec_context.hh" // for reading from memory#include "cpu/smt.hh"#include "mem/bus/bus.hh"#include "mem/bus/bus_interface.hh"#include "mem/bus/slave_interface.hh"#include "mem/functional/functional.hh"#include "mem/memory_interface.hh"#include "mem/mem_req.hh"#include "mem/timing/simple_mem_bank.hh"#include "sim/builder.hh"using namespace std;template <class Compression>SimpleMemBank<Compression>::SimpleMemBank(const string &name, HierParams *hier, BaseMemory::Params params) : BaseMemory(name, hier, params){}template <class Compression>voidSimpleMemBank<Compression>::regStats(){ using namespace Stats; BaseMemory::regStats(); bytesRequested .init(maxThreadsPerCPU) .name(name() + ".bytes_requested") .desc("total number of bytes requested") .flags(total) ; bytesSent .init(maxThreadsPerCPU) .name(name() + ".bytes_sent") .desc("total number of bytes sent") .flags(total) ; compressedAccesses .init(maxThreadsPerCPU) .name(name() + ".compressed_responses") .desc("total number of accesses that are compressed") .flags(total) ; }/* Handle memory bank access latencies */template <class Compression>MemAccessResultSimpleMemBank<Compression>::access(MemReqPtr &req){ Tick response_time;#if !FULL_SYSTEM // For full system, there is just one funcMem that is a // data member of the BaseMemory object. For syscall // emulation, the functional memory is per thread, so we // have to get it from the request. assert(req->xc != NULL); FunctionalMemory *funcMem = req->xc->mem;#endif assert(req->thread_num < SMT_MAX_THREADS); accesses[req->thread_num]++; if (!req->isUncacheable()) { response_time = hitLatency + curTick; } else { response_time = uncacheLatency + curTick; } if (!req->isSatisfied()) { req->flags |= SATISFIED; if (doData()) { // doing real data transfers: read or write data on // functional memory object /** * @todo * Need to remove this dummy untranslation once we unify the * memory objects. */ Addr addr = (req->paddr & ULL(1) << 47) ? (req->paddr | ULL(0xff) << 48) : (req->paddr & ((ULL(1) << 48) - ULL(1))); if (req->cmd.isRead()) { bytesRequested[req->thread_num] += req->size; uint8_t tmp_data[req->size]; int data_size = req->size; funcMem->access(Read, addr, req->data, data_size); if (!(req->flags & UNCACHEABLE)){ // Compress data to ship data_size = compress.compress(tmp_data, req->data, data_size); if (data_size < req->size) { req->flags |= COMPRESSED; req->actualSize = req->size; req->size = data_size; } } bytesSent[req->thread_num] += req->size; } else if (req->cmd.isWrite() && doWrites) { if (req->isCompressed()) { funcMem->access(Write, addr, req->data, req->actualSize); } else { funcMem->access(Write, addr, req->data, req->size); } } } if (!(req->cmd.isInvalidate() && !req->cmd.isRead() && !req->cmd.isWrite())) { //No response on upgrade/invalidates si->respond(req, response_time); } } else if (snarfUpdates) { // Memory request has been satisfied by another device (i.e., // a cache-to-cache transfer). Update memory value from // request. This line should be removed if an ownerhsip-based // coherence protocol is used. if (doData() && doWrites && (req->cmd.isRead() || req->cmd.isWrite())){ Addr addr = (req->paddr & ULL(1) << 47) ? (req->paddr | ULL(0xff) << 48) : (req->paddr & ((ULL(1) << 48) - ULL(1))); if (req->isCompressed()) { funcMem->access(Write, addr, req->data, req->actualSize); } else { funcMem->access(Write, addr, req->data, req->size); } } } if (req->flags & COMPRESSED) { compressedAccesses[req->thread_num]++; } return MA_HIT;}template <class Compression>TickSimpleMemBank<Compression>::probe(MemReqPtr &req, bool update){ Tick response_time;#if !FULL_SYSTEM // For full system, there is just one funcMem that is a // data member of the BaseMemory object. For syscall // emulation, the functional memory is per thread, so we // have to get it from the request. assert(req->xc != NULL); FunctionalMemory *funcMem = req->xc->mem;#endif if (update) { accesses[req->thread_num]++; } if (!req->isUncacheable()) { response_time = hitLatency + curTick; } else { response_time = uncacheLatency + curTick; } if (!req->isSatisfied()) { if (doData()) { // doing real data transfers: read or write data on // functional memory object /** * @todo * Need to remove this dummy untranslation once we unify the * memory objects. */ Addr addr = (req->paddr & ULL(1) << 47) ? (req->paddr | ULL(0xff) << 48) : (req->paddr & ((ULL(1) << 48) - ULL(1))); if (req->cmd.isRead()) { funcMem->access(Read, addr, req->data, req->size); } else if (req->cmd.isWrite() && doWrites) { if (req->isCompressed()) { funcMem->access(Write, addr, req->data, req->actualSize); } else { funcMem->access(Write, addr, req->data, req->size); } } } req->flags |= SATISFIED; } else if (snarfUpdates) { // Memory request has been satisfied by another device (i.e., // a cache-to-cache transfer). Update memory value from // request. This line should be removed if an ownerhsip-based // coherence protocol is used. if (doData() && doWrites && (req->cmd.isRead() || req->cmd.isWrite())){ Addr addr = (req->paddr & ULL(1) << 47) ? (req->paddr | ULL(0xff) << 48) : (req->paddr & ((ULL(1) << 48) - ULL(1))); if (req->isCompressed()) { funcMem->access(Write, addr, req->data, req->actualSize); } else { funcMem->access(Write, addr, req->data, req->size); } } } return response_time;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?