Implement coherence check for all payload extensions

This commit is contained in:
Tran Anh Quoc
2016-09-15 23:13:11 +02:00
parent aa04416033
commit 36312974d9

View File

@@ -101,10 +101,18 @@ private:
std::vector<TlmRecorder*> tlmRecorders;
//used to map the transaction from devices to the arbiter's target socket ID.
std::map<tlm_generic_payload*,int> routeMap;
// Initiated by dram side
// This function is called when an arbiter's initiator socket receives a transaction from a memory controller
tlm_sync_enum nb_transport_bw(int channelId, tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay)
{
// Check channel ID
assert((unsigned int)channelId < iSocket.size());
if ((unsigned int)channelId != DramExtension::getExtension(payload).getChannel().ID()) {
SC_REPORT_FATAL("Arbiter", "Payload extension was corrupted");
}
sc_time recTime = bwDelay + sc_time_stamp();
sc_time notDelay = bwDelay;
@@ -122,12 +130,17 @@ private:
// This function is called when an arbiter's target socket receives a transaction from a device
tlm_sync_enum nb_transport_fw(int id, tlm_generic_payload& payload, tlm_phase& phase, sc_time& fwDelay)
{
assert ((unsigned int)id < tSocket.size());
if (phase == BEGIN_REQ) {
// Map the payload with socket id.
routeMap[&payload] = id;
// In the begin request phase the socket ID is appended to the payload.
// It will extracted from the payload and used later.
appendDramExtension(id, payload);
payload.acquire();
} else if (phase == END_RESP) {
// Erase before the payload is released.
routeMap.erase(&payload);
payload.release();
}
@@ -147,7 +160,9 @@ private:
unsigned int initiatorSocket = DramExtension::getExtension(payload).getThread().ID()-1;
unsigned int channelId = DramExtension::getExtension(payload).getChannel().ID();
// TODO: here check if the channel and the initiatorSocket ID are valid. If not, the payload extension was corrupted.
// Check the valid range of initiatorSocket ID and channel Id
assert(initiatorSocket < Configuration::getInstance().NumberOfTracePlayers);
assert(channelId < Configuration::getInstance().NumberOfMemChannels);
// Phases initiated by the intiator side from arbiter's point of view (devices performing memory requests to the arbiter)
if (phase == BEGIN_REQ) {
@@ -177,6 +192,10 @@ private:
// Phases initiated by the target side from arbiter's point of view (memory side)
else if (phase == END_REQ) {
channelIsFree[channelId] = true;
// Validate the initiatorSocket ID
if ((int)initiatorSocket != routeMap[&payload]) {
SC_REPORT_FATAL("Arbiter", "Payload extension was corrupted");
}
// The arbiter receives a transaction which phase is END_REQ from memory controller and forwards it to the requester device.
sendToInitiator(initiatorSocket, payload, phase, SC_ZERO_TIME);
@@ -190,6 +209,10 @@ private:
channelIsFree[channelId] = false;
}
} else if (phase == BEGIN_RESP) {
// Validate the initiatorSocket ID
if ((int)initiatorSocket != routeMap[&payload]) {
SC_REPORT_FATAL("Arbiter", "Payload extension was corrupted");
}
// The arbiter receives a transaction in BEGIN_RESP phase (that came from the memory side) and forwards it to the requester device
if (receivedResponses[initiatorSocket].empty())
sendToInitiator(initiatorSocket, payload, phase, SC_ZERO_TIME);
@@ -216,12 +239,35 @@ private:
void appendDramExtension(int socketId, tlm_generic_payload& payload)
{
// TODO: check if channel valid before appending.
// TODO: check if all parts of the decodedAddress are inside the valid range (devices should not perform invalid requests to the arbiter, right?).
unsigned int burstlength = payload.get_streaming_width();
DecodedAddress decodedAddress = xmlAddressDecoder::getInstance().decodeAddress(payload.get_address());
DramExtension* extension = new DramExtension(Thread(socketId+1), Channel(decodedAddress.channel), Bank(decodedAddress.bank), BankGroup(decodedAddress.bankgroup), Row(decodedAddress.row), Column(decodedAddress.column),burstlength);
payload.set_auto_extension(extension);
// Check the valid range of decodedAddress
if (addressIsValid(decodedAddress)) {
DramExtension* extension = new DramExtension(Thread(socketId+1), Channel(decodedAddress.channel), Bank(decodedAddress.bank), BankGroup(decodedAddress.bankgroup), Row(decodedAddress.row), Column(decodedAddress.column),burstlength);
payload.set_auto_extension(extension);
} else {
SC_REPORT_FATAL("Arbiter", "Decoded Address are not inside the valid range");
}
}
bool addressIsValid(DecodedAddress& decodedAddress)
{
if (decodedAddress.channel >= xmlAddressDecoder::getInstance().amount["channel"]) {
return false;
}
if (decodedAddress.bank >= xmlAddressDecoder::getInstance().amount["bank"]) {
return false;
}
if (decodedAddress.bankgroup > xmlAddressDecoder::getInstance().amount["bankgroup"]) {
return false;
}
if (decodedAddress.column >= xmlAddressDecoder::getInstance().amount["column"]) {
return false;
}
if (decodedAddress.row >= xmlAddressDecoder::getInstance().amount["row"]) {
return false;
}
return true;
}
void printDebugMessage(std::string message)