34 #include "debug/SimpleCache.hh" 39 latency(params->latency),
40 blockSize(params->
system->cacheLineSize()),
41 capacity(params->size / blockSize),
42 memPort(params->
name +
".mem_side", this),
43 blocked(false), originalPacket(nullptr), waitingPortId(-1)
49 for (
int i = 0;
i < params->port_cpu_side_connection_count; ++
i) {
58 if (if_name ==
"mem_side") {
60 "Mem side of simple cache not a vector port");
62 }
else if (if_name ==
"cpu_side" && idx <
cpuPorts.size()) {
76 panic_if(blockedPacket !=
nullptr,
"Should never try to send if blocked!");
80 if (!sendTimingResp(pkt)) {
89 return owner->getAddrRanges();
95 if (needRetry && blockedPacket ==
nullptr) {
107 return owner->handleFunctional(pkt);
115 if (blockedPacket || needRetry) {
122 if (!owner->handleRequest(pkt,
id)) {
137 assert(blockedPacket !=
nullptr);
141 blockedPacket =
nullptr;
156 panic_if(blockedPacket !=
nullptr,
"Should never try to send if blocked!");
159 if (!sendTimingReq(pkt)) {
168 return owner->handleResponse(pkt);
175 assert(blockedPacket !=
nullptr);
179 blockedPacket =
nullptr;
188 owner->sendRangeChange();
210 name() +
".accessEvent",
true),
235 panic_if(!hit,
"Should always hit after inserting");
303 unsigned size = pkt->
getSize();
304 if (addr == block_addr && size ==
blockSize) {
311 "Cannot handle accesses that span multiple cache lines");
320 panic(
"Unknown packet type in upgrade size");
348 }
else if (pkt->
isRead()) {
352 panic(
"Unknown packet type!");
372 int bucket, bucket_size;
375 }
while ( (bucket_size =
cacheStore.bucket_size(bucket)) == 0 );
376 auto block = std::next(
cacheStore.begin(bucket),
387 new_pkt->dataDynamic(block->second);
422 port.sendRangeChange();
433 .
desc(
"Number of hits")
437 .
desc(
"Number of misses")
441 .
desc(
"Ticks for misses to the cache")
446 .
desc(
"The ratio of hits to the total accesses to the cache")
455 SimpleCacheParams::create()
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
#define panic(...)
This implements a cprintf based panic() function.
Stats::Scalar hits
Cache statistics.
Ports are used to interface objects to each other.
void recvRangeChange() override
Called to receive an address range change from the peer slave port.
void sendPacket(PacketPtr pkt)
Send a packet across this port.
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
const std::string & name()
const PortID InvalidPortID
A very simple cache object.
void handleFunctional(PacketPtr pkt)
Handle a packet functionally.
int waitingPortId
The port to send the response when we recieve it back.
const unsigned blockSize
The block size for the cache.
SimpleCache(SimpleCacheParams *params)
constructor
std::shared_ptr< Request > RequestPtr
const unsigned capacity
Number of blocks in the cache (size of cache / block size)
bool handleRequest(PacketPtr pkt, int port_id)
Handle the request from the CPU side.
#define DDUMP(x, data, count)
virtual void regStats()
Callback to set stat parameters.
Histogram & init(size_type size)
Set the parameters of this histogram.
std::enable_if< std::is_integral< T >::value, T >::type random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
Addr getBlockAddr(unsigned int blk_size) const
RequestPtr req
A pointer to the original request.
AddrRangeList getAddrRanges() const
Return the address ranges this cache is responsible for.
void sendResponse(PacketPtr pkt)
Send the packet to the CPU side.
void accessTiming(PacketPtr pkt)
Access the cache for a timing access.
Tick curTick()
The current simulated tick.
std::string csprintf(const char *format, const Args &...args)
bool needsResponse() const
void trySendRetry()
Send a retry to the peer port only if it is needed.
bool handleResponse(PacketPtr pkt)
Handle the respone from the memory side.
std::unordered_map< Addr, uint8_t * > cacheStore
An incredibly simple cache storage. Maps block addresses to data.
void sendRangeChange() const
Tell the CPU side to ask for our memory ranges.
bool recvTimingReq(PacketPtr pkt) override
Receive a timing request from the master port.
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
void insert(PacketPtr pkt)
Insert a block into the cache.
void recvReqRetry() override
Called by the slave port if sendTimingReq was called on this master port (causing recvTimingReq to be...
void recvFunctional(PacketPtr pkt) override
Receive a functional request packet from the master port.
void regStats() override
Register the stats.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
virtual const std::string name() const
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
const Cycles latency
Latency to check the cache. Number of cycles for both hit and miss.
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
void setDataFromBlock(const uint8_t *blk_data, int blkSize)
Copy data into the packet from the provided block pointer, which is aligned to the given block size...
bool recvTimingResp(PacketPtr pkt) override
Receive a timing response from the slave port.
Tick missTime
For tracking the miss latency.
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
AddrRangeList getAddrRanges() const
Get the address ranges of the connected slave port.
MemSidePort memPort
Instantiation of the memory-side port.
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
void writeDataToBlock(uint8_t *blk_data, int blkSize) const
Copy data from the packet to the provided block pointer, which is aligned to the given block size...
void schedule(Event &event, Tick when)
const T * getConstPtr() const
PacketPtr originalPacket
Packet that we are currently handling.
std::vector< CPUSidePort > cpuPorts
Instantiation of the CPU-side port.
void sendFunctional(PacketPtr pkt) const
Send a functional request packet, where the data is instantly updated everywhere in the memory system...
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
void sendPacket(PacketPtr pkt)
Send a packet across this port.
AddrRangeList getAddrRanges() const override
Get a list of the non-overlapping address ranges the owner is responsible for.
static const int NumArgumentRegs M5_VAR_USED
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Stats::Histogram missLatency
bool accessFunctional(PacketPtr pkt)
This is where we actually update / read from the cache.
void recvRespRetry() override
Called by the master port if sendTimingResp was called on this slave port (causing recvTimingResp to ...
bool blocked
True if this cache is currently blocked waiting for a response.
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
void allocate()
Allocate memory for the packet.
ProbePointArg< PacketInfo > Packet
Packet probe point.