32 #include "debug/SimpleCache.hh" 37 latency(params->latency),
38 blockSize(params->
system->cacheLineSize()),
39 capacity(params->size / blockSize),
40 memPort(params->
name +
".mem_side", this),
41 blocked(false), originalPacket(nullptr), waitingPortId(-1)
47 for (
int i = 0;
i < params->port_cpu_side_connection_count; ++
i) {
56 if (if_name ==
"mem_side") {
58 "Mem side of simple cache not a vector port");
60 }
else if (if_name ==
"cpu_side" && idx <
cpuPorts.size()) {
74 panic_if(blockedPacket !=
nullptr,
"Should never try to send if blocked!");
78 if (!sendTimingResp(pkt)) {
87 return owner->getAddrRanges();
93 if (needRetry && blockedPacket ==
nullptr) {
105 return owner->handleFunctional(pkt);
113 if (blockedPacket || needRetry) {
120 if (!owner->handleRequest(pkt,
id)) {
135 assert(blockedPacket !=
nullptr);
139 blockedPacket =
nullptr;
154 panic_if(blockedPacket !=
nullptr,
"Should never try to send if blocked!");
157 if (!sendTimingReq(pkt)) {
166 return owner->handleResponse(pkt);
173 assert(blockedPacket !=
nullptr);
177 blockedPacket =
nullptr;
186 owner->sendRangeChange();
208 name() +
".accessEvent",
true),
233 panic_if(!hit,
"Should always hit after inserting");
301 unsigned size = pkt->
getSize();
302 if (addr == block_addr && size ==
blockSize) {
309 "Cannot handle accesses that span multiple cache lines");
318 panic(
"Unknown packet type in upgrade size");
346 }
else if (pkt->
isRead()) {
350 panic(
"Unknown packet type!");
370 int bucket, bucket_size;
373 }
while ( (bucket_size =
cacheStore.bucket_size(bucket)) == 0 );
374 auto block = std::next(
cacheStore.begin(bucket),
385 new_pkt->dataDynamic(block->second);
420 port.sendRangeChange();
431 .
desc(
"Number of hits")
435 .
desc(
"Number of misses")
439 .
desc(
"Ticks for misses to the cache")
444 .
desc(
"The ratio of hits to the total accesses to the cache")
453 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.
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)
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.
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
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 schedule(Event &event, Tick when)
void regStats() override
Register the stats.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
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...
virtual const std::string name() const
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...
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.
virtual void regStats()
Callback to set stat parameters.
AddrRangeList getAddrRanges() const override
Get a list of the non-overlapping address ranges the owner is responsible for.
#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.