File mshr_file.h
File List > cache > mshr_file.h
Go to the documentation of this file
#pragma once
#include <vector>
#include "mem/cache/cache.h"
namespace simtix {
namespace mem {
class MshrFile {
public:
struct MSHR {
explicit MSHR(size_t block_size, uint32_t core_req_queue_depth)
: valid(false),
core_req_queue(core_req_queue_depth),
data_buf(block_size) {}
MSHR(const MSHR &other)
: valid(false),
core_req_queue(other.core_req_queue.capacity()),
data_buf(other.data_buf.size()) {}
bool valid;
Cache::Payload payload;
sim::SizedQueue<CacheImpl::CoreRequest> core_req_queue;
std::vector<uint8_t> data_buf;
};
explicit MshrFile(const Cache::Param ¶m);
~MshrFile();
bool CanAcceptCoreRequestEarly(const CacheImpl::CoreRequest &req,
const uint32_t data_array_req_queue_size);
bool CanAcceptCoreRequest(const CacheImpl::CoreRequest &req);
bool AcceptCoreRequest(CacheImpl::CoreRequest &&req);
bool NotifyFill(uint32_t mshr_id);
sim::SizedQueue<uint32_t> &pending_mshr_req_queue() {
return pending_mshr_req_queue_;
}
Cache::Payload GetMshrPayload(uint32_t mshr_id);
const CacheImpl::CoreRequest &GetMshrCoreReqQueueFront(uint32_t mshr_id);
uint8_t *GetMshrDataBuffer(uint32_t mshr_id);
bool HasPendingReplayRequest();
std::optional<CacheImpl::CoreRequest> GetPendingReplayRequest();
bool HasFreeMshr() { return !free_mshrs_.empty(); }
bool HasFreeMshrEarly() {
return free_mshrs_.size() > kDataArrayReqQueueDepth;
}
bool HasPendingMshr() { return !free_mshrs_.full(); }
std::optional<MSHR *> CheckIfMshrHit(const CacheImpl::CoreRequest &req) {
uint64_t line_addr = ToLineAddr(req.payload.addr);
for (auto &mshr : mshrs_) {
if (mshr.valid && mshr.payload.addr == line_addr * kBlockSizeBytes) {
// MSHR hit, but no room for buffering new core reqeust.
return &mshr;
}
}
return std::nullopt;
}
protected:
inline uint64_t ToLineAddr(uint64_t addr) { return addr / kBlockSizeBytes; }
sim::SizedQueue<uint32_t> pending_mshr_req_queue_;
sim::SizedQueue<uint32_t> pending_mshr_replay_queue_;
sim::SizedQueue<uint32_t> free_mshrs_;
std::vector<MSHR> mshrs_;
uint32_t kDataArrayReqQueueDepth;
const size_t kBlockSizeBytes; // block size in bytes
};
} // namespace mem
} // namespace simtix