68 writes.insert(std::make_pair(serial,
75 auto it = writes.find(serial);
77 if (it == writes.end()) {
78 warn(
"Could not locate write transaction: serial = %d, complete = %d\n",
85 it->second.complete = _complete;
88 if (completeMax < _complete) {
89 completeMax = _complete;
92 if (--numIncomplete == 0) {
99 complete = completeMax;
106 if (!writes.erase(serial)) {
107 warn(
"Could not locate write transaction: serial = %d\n", serial);
111 if (--numIncomplete == 0 && !writes.empty()) {
114 complete = completeMax;
125 outstandingReads.insert(std::make_pair(serial,
132 _lastExpectedData.clear();
134 bool wc_overlap =
true;
138 *lastCompletedTransaction(&readObservations, start);
143 for (
auto cluster = writeClusters.rbegin();
144 cluster != writeClusters.rend() && wc_overlap; ++cluster) {
145 for (
const auto& addr_write : cluster->writes) {
155 if (write.
data == data) {
161 _lastExpectedData.push_back(write.
data);
181 last_obs_valid =
false;
188 if (last_obs_valid) {
192 if (last_obs.
data == data) {
197 _lastExpectedData.push_back(last_obs.
data);
203 if (!writeClusters.empty() && wc_overlap) {
205 assert(writeClusters.begin()->start < complete &&
206 writeClusters.rbegin()->complete > start);
211 if (_lastExpectedData.empty()) {
216 "complete = %d, data = %#x\n", start, complete, data);
226 auto it = outstandingReads.find(serial);
228 if (it == outstandingReads.end()) {
230 warn(
"Could not locate read transaction: serial = %d, complete = %d\n",
235 Tick start = it->second.start;
236 outstandingReads.erase(it);
239 const bool result = inExpectedData(start, complete, data);
241 readObservations.emplace_back(serial, start, complete, data);
250 if (writeClusters.empty() || writeClusters.back().isComplete()) {
251 writeClusters.emplace_back();
254 return &writeClusters.back();
261 getIncompleteWriteCluster()->startWrite(serial, start, data);
267 getIncompleteWriteCluster()->completeWrite(serial, complete);
274 getIncompleteWriteCluster()->abortWrite(serial);
283 const Tick before = outstandingReads.empty() ?
curTick() :
284 outstandingReads.begin()->second.start;
287 readObservations.erase(readObservations.begin(),
288 lastCompletedTransaction(&readObservations, before));
291 if (!writeClusters.empty()) {
292 writeClusters.erase(writeClusters.begin(),
293 lastCompletedTransaction(&writeClusters, before));
304 "completing read: serial = %d, complete = %d, "
305 "addr = %#llx, size = %d\n", serial, complete, addr, size);
307 for (
size_t i = 0;
i <
size; ++
i) {
321 "failed: received %#x, expected ",
322 (
unsigned long long)(addr + i), data[i]);
345 for (
size_t i = 0;
i <
size; ++
i) {
351 MemCheckerParams::create()
#define chatty_assert(cond,...)
The chatty assert macro will function like a normal assert, but will allow the specification of addit...
void abortWrite(Serial serial)
Aborts a write transaction.
Tick complete
Completion tick.
bool completeRead(Serial serial, Tick complete, Addr addr, size_t size, uint8_t *data)
Completes a previously started read transaction.
ByteTracker * getByteTracker(Addr addr)
Returns the instance of ByteTracker for the requested location.
The Transaction class captures the lifetimes of read and write operations, and the values they consum...
std::unordered_map< Serial, Transaction > writes
Map of Serial –> Transaction of all writes in cluster; contains all, in-flight or already completed...
void completeWrite(Serial serial, Tick _complete)
Completes a write transaction.
uint64_t Serial
The Serial type is used to be able to uniquely identify a transaction as it passes through the system...
MemChecker(const MemCheckerParams *p)
Tick curTick()
The current simulated tick.
std::string csprintf(const char *format, const Args &...args)
std::unordered_map< Addr, ByteTracker > byte_trackers
Maintain a map of address –> byte-tracker.
uint64_t Tick
Tick count type.
The ByteTracker keeps track of transactions for the same byte – all outstanding reads, the completed reads (and what they observed) and write clusters (see WriteCluster).
void reset()
Resets the entire checker.
std::string errorMessage
Detailed error message of the last violation in completeRead.
void completeWrite(Serial serial, Tick complete)
Completes a write transaction.
WriteCluster * getIncompleteWriteCluster()
Convenience function to return the most recent incomplete write cluster.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
const std::vector< uint8_t > & lastExpectedData() const
This function returns the expected data that inExpectedData iterated through in the last call...
void startWrite(Serial serial, Tick start, uint8_t data)
Starts a write transaction.
bool inExpectedData(Tick start, Tick complete, uint8_t data)
Given a start and end time (of any read transaction), this function iterates through all data that su...
static const Tick TICK_INITIAL
The initial tick the system starts with.
The WriteCluster class captures sets of writes where all writes are overlapping with at least one oth...
Tick start
Start of earliest write in cluster.
bool completeRead(Serial serial, Tick complete, uint8_t data)
Completes a read transaction that is still outstanding.
void abortWrite(Serial serial)
Aborts a write transaction.
uint8_t data
Depending on the memory operation, the data value either represents: for writes, the value written up...
void startWrite(Serial serial, Tick _start, uint8_t data)
Starts a write transaction.
void pruneTransactions()
Prunes no longer needed transactions.
static const Tick TICK_FUTURE
The maximum value that curTick() could ever return.
Tick complete
Completion of last write in cluster.
void startRead(Serial serial, Tick start)
Starts a read transaction.