Extended congen address decoder to channels, ranks and bank groups.
This commit is contained in:
@@ -48,15 +48,13 @@ AddressDecoder &AddressDecoder::getInstance()
|
||||
void AddressDecoder::createInstance(Type t)
|
||||
{
|
||||
assert(m_pInstance == nullptr);
|
||||
switch (t) {
|
||||
switch (t)
|
||||
{
|
||||
case Type::XML:
|
||||
m_pInstance = new XmlAddressDecoder;
|
||||
m_pInstance = new XmlAddressDecoder();
|
||||
break;
|
||||
case Type::CONGEN:
|
||||
m_pInstance = new CongenAddressDecoder;
|
||||
break;
|
||||
default:
|
||||
throw std::logic_error("Instance type not supported.");
|
||||
m_pInstance = new CongenAddressDecoder();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,24 +42,25 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
struct DecodedAddress {
|
||||
DecodedAddress() : channel(0),
|
||||
struct DecodedAddress
|
||||
{
|
||||
DecodedAddress() :
|
||||
channel(0),
|
||||
rank(0),
|
||||
bankgroup(0),
|
||||
row(0),
|
||||
bank(0),
|
||||
column(0),
|
||||
bytes(0)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
unsigned int channel;
|
||||
unsigned int rank;
|
||||
unsigned int bankgroup;
|
||||
unsigned int row;
|
||||
unsigned int bank;
|
||||
unsigned int column;
|
||||
unsigned int bytes;
|
||||
unsigned channel;
|
||||
unsigned rank;
|
||||
unsigned bankgroup;
|
||||
unsigned row;
|
||||
unsigned bank;
|
||||
unsigned column;
|
||||
unsigned bytes;
|
||||
};
|
||||
|
||||
class AddressDecoder
|
||||
@@ -95,6 +96,13 @@ public:
|
||||
unsigned column = 1;
|
||||
unsigned bytes = 1;
|
||||
} amount;
|
||||
|
||||
protected:
|
||||
unsigned banksPerGroup;
|
||||
unsigned banksPerRank;
|
||||
unsigned bankgroupsPerRank;
|
||||
|
||||
uint64_t maximumAddress;
|
||||
};
|
||||
|
||||
#endif // ADDRESSDECODER_H
|
||||
|
||||
@@ -33,21 +33,15 @@
|
||||
* Johannes Feldmann
|
||||
*/
|
||||
|
||||
#include "CongenAddressDecoder.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <set>
|
||||
#include <systemc.h>
|
||||
|
||||
using std::ifstream;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::set;
|
||||
using std::pair;
|
||||
using std::map;
|
||||
using std::deque;
|
||||
#include "CongenAddressDecoder.h"
|
||||
#include "utils.h"
|
||||
#include "../configuration/Configuration.h"
|
||||
|
||||
tinyxml2::XMLElement *CongenAddressDecoder::GetXMLNode(tinyxml2::XMLElement
|
||||
tinyxml2::XMLElement *CongenAddressDecoder::getXMLNode(tinyxml2::XMLElement
|
||||
*pRoot, std::string strName)
|
||||
{
|
||||
tinyxml2::XMLElement *pNode = pRoot->FirstChildElement(strName.c_str());
|
||||
@@ -58,7 +52,7 @@ tinyxml2::XMLElement *CongenAddressDecoder::GetXMLNode(tinyxml2::XMLElement
|
||||
return pNode;
|
||||
}
|
||||
|
||||
unsigned int CongenAddressDecoder::GetUnsignedTextFromXMLNode(
|
||||
unsigned int CongenAddressDecoder::getUnsignedTextFromXMLNode(
|
||||
tinyxml2::XMLElement *pRoot)
|
||||
{
|
||||
std::string str = pRoot->GetText();
|
||||
@@ -72,7 +66,7 @@ unsigned int CongenAddressDecoder::GetUnsignedTextFromXMLNode(
|
||||
return atol(str.c_str());
|
||||
}
|
||||
|
||||
unsigned int CongenAddressDecoder::GetUnsignedAttrFromXMLNode(
|
||||
unsigned int CongenAddressDecoder::getUnsignedAttrFromXMLNode(
|
||||
tinyxml2::XMLElement *pRoot, std::string strName)
|
||||
{
|
||||
std::string str = pRoot->Attribute(strName.c_str());
|
||||
@@ -86,11 +80,6 @@ unsigned int CongenAddressDecoder::GetUnsignedAttrFromXMLNode(
|
||||
return atol(str.c_str());
|
||||
}
|
||||
|
||||
CongenAddressDecoder::CongenAddressDecoder()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CongenAddressDecoder::setConfiguration(std::string url)
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
@@ -98,64 +87,87 @@ void CongenAddressDecoder::setConfiguration(std::string url)
|
||||
tinyxml2::XMLElement *pRoot = doc.RootElement();
|
||||
std::string xmlNodeName(pRoot->Name());
|
||||
|
||||
if ( xmlNodeName != "CONGEN") {
|
||||
if (xmlNodeName != "CONGEN")
|
||||
reportFatal("ConGenAddressDecorder",
|
||||
"Root node name differs from \"CONGEN\". File format not supported.");
|
||||
}
|
||||
|
||||
// Load basic configuration
|
||||
tinyxml2::XMLElement *pNode = GetXMLNode(pRoot, "NAME");
|
||||
m_strName = pNode->GetText();
|
||||
pNode = GetXMLNode(pRoot, "COSTS");
|
||||
m_nCost = GetUnsignedTextFromXMLNode(pNode);
|
||||
tinyxml2::XMLElement *pConfig = GetXMLNode(pRoot, "CONFIG");
|
||||
pNode = GetXMLNode(pConfig, "NUM_BANK_BITS");
|
||||
m_nBankBits = GetUnsignedTextFromXMLNode(pNode);
|
||||
pNode = GetXMLNode(pConfig, "NUM_ROW_BITS");
|
||||
m_nRowBits = GetUnsignedTextFromXMLNode(pNode);
|
||||
pNode = GetXMLNode(pConfig, "NUM_COLUMN_BITS");
|
||||
m_nColumnBits = GetUnsignedTextFromXMLNode(pNode);
|
||||
pNode = GetXMLNode(pConfig, "NUM_BL_BITS");
|
||||
m_nBurstLengthBits = GetUnsignedTextFromXMLNode(pNode);
|
||||
pNode = GetXMLNode(pConfig, "NUM_BYTE_BITS");
|
||||
m_nByteBits = GetUnsignedTextFromXMLNode(pNode);
|
||||
tinyxml2::XMLElement *pNode = getXMLNode(pRoot, "NAME");
|
||||
strName = pNode->GetText();
|
||||
pNode = getXMLNode(pRoot, "COSTS");
|
||||
nCost = getUnsignedTextFromXMLNode(pNode);
|
||||
tinyxml2::XMLElement *pConfig = getXMLNode(pRoot, "CONFIG");
|
||||
pNode = getXMLNode(pConfig, "NUM_CHANNEL_BITS");
|
||||
nChannelBits = getUnsignedTextFromXMLNode(pNode);
|
||||
pNode = getXMLNode(pConfig, "NUM_RANK_BITS");
|
||||
nRankBits = getUnsignedTextFromXMLNode(pNode);
|
||||
pNode = getXMLNode(pConfig, "NUM_BANKGROUP_BITS");
|
||||
nBankGroupBits = getUnsignedTextFromXMLNode(pNode);
|
||||
pNode = getXMLNode(pConfig, "NUM_BANK_BITS");
|
||||
nBankBits = getUnsignedTextFromXMLNode(pNode);
|
||||
pNode = getXMLNode(pConfig, "NUM_ROW_BITS");
|
||||
nRowBits = getUnsignedTextFromXMLNode(pNode);
|
||||
pNode = getXMLNode(pConfig, "NUM_COLUMN_BITS");
|
||||
nColumnBits = getUnsignedTextFromXMLNode(pNode);
|
||||
pNode = getXMLNode(pConfig, "NUM_BYTE_BITS");
|
||||
nByteBits = getUnsignedTextFromXMLNode(pNode);
|
||||
|
||||
// Load address mapping
|
||||
unsigned id = 0;
|
||||
|
||||
for (pNode = pRoot->FirstChildElement("SOLUTION"); pNode != nullptr;
|
||||
pNode = pNode->NextSiblingElement("SOLUTION")) {
|
||||
if (GetUnsignedAttrFromXMLNode(pNode, "ID") == id) {
|
||||
// Correct mapping was found.
|
||||
break;
|
||||
}
|
||||
pNode = pNode->NextSiblingElement("SOLUTION"))
|
||||
{
|
||||
if (getUnsignedAttrFromXMLNode(pNode, "ID") == id)
|
||||
break; // Correct mapping was found.
|
||||
}
|
||||
|
||||
// If no mapping was found report error and return
|
||||
if (pNode == nullptr) {
|
||||
reportFatal("ConGenAddressDecoder",
|
||||
"No mapping with ID " + std::to_string(id) + " was found.");
|
||||
return;
|
||||
}
|
||||
// If no mapping was found report error
|
||||
if (pNode == nullptr)
|
||||
SC_REPORT_FATAL("ConGenAddressDecoder",
|
||||
("No mapping with ID " + std::to_string(id) + " was found.").c_str());
|
||||
|
||||
// get XOR connections
|
||||
// An XOR connection needs two parameters: A bank bit and a Row bit.
|
||||
for (tinyxml2::XMLElement *pXor = pNode->FirstChildElement("XOR");
|
||||
pXor != nullptr; pXor = pXor->NextSiblingElement("XOR")) {
|
||||
m_vXor.push_back(XOR(GetUnsignedAttrFromXMLNode(pXor, "BANK"),
|
||||
GetUnsignedAttrFromXMLNode(pXor, "ROW")));
|
||||
pXor != nullptr; pXor = pXor->NextSiblingElement("XOR"))
|
||||
{
|
||||
vXor.push_back(XOR(getUnsignedAttrFromXMLNode(pXor, "BANK"),
|
||||
getUnsignedAttrFromXMLNode(pXor, "ROW")));
|
||||
}
|
||||
|
||||
set<unsigned> sUsed;
|
||||
unsigned counter = 0;
|
||||
for (tinyxml2::XMLElement *pChannel = pNode->FirstChildElement("CHANNEL_BIT");
|
||||
pChannel != nullptr; pChannel = pChannel->NextSiblingElement("CHANNEL_BIT"))
|
||||
{
|
||||
unsigned nChannel = getUnsignedTextFromXMLNode(pChannel);
|
||||
vChannelBits.push_back(std::pair<unsigned, unsigned>(counter++, nChannel));
|
||||
}
|
||||
|
||||
counter = 0;
|
||||
for (tinyxml2::XMLElement *pRank = pNode->FirstChildElement("RANK_BIT");
|
||||
pRank != nullptr; pRank = pRank->NextSiblingElement("RANK_BIT"))
|
||||
{
|
||||
unsigned nRank = getUnsignedTextFromXMLNode(pRank);
|
||||
vRankBits.push_back(std::pair<unsigned, unsigned>(counter++, nRank));
|
||||
}
|
||||
|
||||
counter = 0;
|
||||
for (tinyxml2::XMLElement *pBankGroup = pNode->FirstChildElement("BANKGROUP_BIT");
|
||||
pBankGroup != nullptr; pBankGroup = pBankGroup->NextSiblingElement("BANKGROUP_BIT"))
|
||||
{
|
||||
unsigned nBankGroup = getUnsignedTextFromXMLNode(pBankGroup);
|
||||
vBankGroupBits.push_back(std::pair<unsigned, unsigned>(counter++, nBankGroup));
|
||||
}
|
||||
|
||||
// get all bank bits
|
||||
// Each bank bit of the address will be stored with a counter value which assigns the bit position DecodedAddress struct.
|
||||
unsigned counter = 0;
|
||||
counter = 0;
|
||||
for (tinyxml2::XMLElement *pBank = pNode->FirstChildElement("BANK_BIT");
|
||||
pBank != nullptr; pBank = pBank->NextSiblingElement("BANK_BIT")) {
|
||||
unsigned nBank = GetUnsignedTextFromXMLNode(pBank);
|
||||
m_vBankBits.push_back(pair<unsigned, unsigned>(counter++, nBank));
|
||||
sUsed.insert(nBank);
|
||||
pBank != nullptr; pBank = pBank->NextSiblingElement("BANK_BIT"))
|
||||
{
|
||||
unsigned nBank = getUnsignedTextFromXMLNode(pBank);
|
||||
vBankBits.push_back(std::pair<unsigned, unsigned>(counter++, nBank));
|
||||
}
|
||||
|
||||
// get all row bits bits
|
||||
@@ -163,138 +175,172 @@ void CongenAddressDecoder::setConfiguration(std::string url)
|
||||
counter = 0;
|
||||
for (tinyxml2::XMLElement *pRow = pNode->FirstChildElement("ROW_BIT");
|
||||
pRow != nullptr; pRow = pRow->NextSiblingElement("ROW_BIT")) {
|
||||
unsigned nRow = GetUnsignedTextFromXMLNode(pRow);
|
||||
m_vRowBits.push_back(pair<unsigned, unsigned>(counter++, nRow));
|
||||
sUsed.insert(nRow);
|
||||
unsigned nRow = getUnsignedTextFromXMLNode(pRow);
|
||||
vRowBits.push_back(std::pair<unsigned, unsigned>(counter++, nRow));
|
||||
}
|
||||
|
||||
// Add byte bits
|
||||
for (unsigned i = 0; i < m_nByteBits; i++) {
|
||||
sUsed.insert(i);
|
||||
}
|
||||
|
||||
// Theset bits are ignored (fixed in Congen)
|
||||
sUsed.insert(30);
|
||||
sUsed.insert(31);
|
||||
|
||||
// Create Column mapping
|
||||
// These bits are not stored in the JSON file, but can be generated. All bits, which are until now not used for any other purpose are column bits.
|
||||
// Each column bit of the address will be stored with a counter value which assigns the bit position DecodedAddress struct.
|
||||
counter = 0;
|
||||
for (unsigned i = 0; i < 32; i++) {
|
||||
if (sUsed.find(i) != sUsed.end())
|
||||
continue; // Already mapped
|
||||
for (tinyxml2::XMLElement *pColumn = pNode->FirstChildElement("COLUMN_BIT");
|
||||
pColumn != nullptr; pColumn = pColumn->NextSiblingElement("COLUMN_BIT"))
|
||||
{
|
||||
unsigned nColumn = getUnsignedTextFromXMLNode(pColumn);
|
||||
vColumnBits.push_back(std::pair<unsigned, unsigned>(counter++, nColumn));
|
||||
}
|
||||
|
||||
m_vColumnBits.push_back(pair<unsigned, unsigned>(counter++, i));
|
||||
counter = 0;
|
||||
for (tinyxml2::XMLElement *pByte = pNode->FirstChildElement("BYTE_BIT");
|
||||
pByte != nullptr; pByte = pByte->NextSiblingElement("BYTE_BIT"))
|
||||
{
|
||||
unsigned nByte = getUnsignedTextFromXMLNode(pByte);
|
||||
vByteBits.push_back(std::pair<unsigned, unsigned>(counter++, nByte));
|
||||
}
|
||||
|
||||
// Fill the amount map. This is copied from xmlAddressDecoder without further investigation
|
||||
amount.channel = 1;
|
||||
amount.bank = pow(2.0, m_vBankBits.size());
|
||||
amount.row = pow(2.0, m_vRowBits.size());
|
||||
amount.column = pow(2.0, m_vColumnBits.size());
|
||||
amount.bytes = pow(2.0, m_nByteBits);
|
||||
amount.channel = pow(2.0, vChannelBits.size());
|
||||
amount.rank = pow(2.0, vRankBits.size());
|
||||
amount.bankgroup = pow(2.0, vBankGroupBits.size());
|
||||
amount.bank = pow(2.0, vBankBits.size());
|
||||
amount.row = pow(2.0, vRowBits.size());
|
||||
amount.column = pow(2.0, vColumnBits.size());
|
||||
amount.bytes = pow(2.0, vByteBits.size());
|
||||
|
||||
banksPerGroup = amount.bank;
|
||||
amount.bank = banksPerGroup * amount.bankgroup * amount.rank;
|
||||
|
||||
bankgroupsPerRank = amount.bankgroup;
|
||||
amount.bankgroup = bankgroupsPerRank * amount.rank;
|
||||
|
||||
maximumAddress = amount.bytes * amount.column * amount.row * banksPerGroup * bankgroupsPerRank * amount.rank * amount.channel - 1;
|
||||
|
||||
Configuration &config = Configuration::getInstance();
|
||||
MemSpec *memSpec = config.memSpec;
|
||||
|
||||
if (config.numberOfMemChannels != amount.channel || memSpec->numberOfRanks != amount.rank
|
||||
|| memSpec->numberOfBankGroups != amount.bankgroup || memSpec->numberOfBanks != amount.bank
|
||||
|| memSpec->numberOfRows != amount.row || memSpec->numberOfColumns != amount.column
|
||||
|| config.numberOfDevicesOnDIMM * memSpec->bitWidth != amount.bytes * 8)
|
||||
SC_REPORT_FATAL("XmlAddressDecoder", "Memspec and addressmapping do not match");
|
||||
}
|
||||
|
||||
DecodedAddress CongenAddressDecoder::decodeAddress(uint64_t addr)
|
||||
DecodedAddress CongenAddressDecoder::decodeAddress(uint64_t encAddr)
|
||||
{
|
||||
DecodedAddress result;
|
||||
if (encAddr > maximumAddress)
|
||||
SC_REPORT_WARNING("CongenAddressDecoder", ("Address " + std::to_string(encAddr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str());
|
||||
|
||||
// Apply XOR
|
||||
// For each used xor:
|
||||
// Get the bank bit and row bit. Apply a bitwise xor operator and save it back to the bank bit.
|
||||
for (auto it = m_vXor.begin(); it != m_vXor.end(); it++) {
|
||||
for (auto it = vXor.begin(); it != vXor.end(); it++)
|
||||
{
|
||||
unsigned new_bank_bit;
|
||||
// Bank Row
|
||||
new_bank_bit = (((addr >> it->nBank) & 1) ^ ((addr >> it->nRow) & 1));
|
||||
addr &= ~(1 << it->nBank);
|
||||
addr |= new_bank_bit << it->nBank;
|
||||
new_bank_bit = (((encAddr >> it->nBank) & 1) ^ ((encAddr >> it->nRow) & 1));
|
||||
encAddr &= ~(1 << it->nBank);
|
||||
encAddr |= new_bank_bit << it->nBank;
|
||||
}
|
||||
|
||||
// Unsed
|
||||
result.bankgroup = 0;
|
||||
result.channel = 0;
|
||||
result.rank = 0;
|
||||
DecodedAddress decAddr;
|
||||
|
||||
// Pass through of the three byte bits
|
||||
result.bytes = addr & 0x7;
|
||||
decAddr.channel = 0;
|
||||
for (auto it = vChannelBits.begin(); it != vChannelBits.end(); it++)
|
||||
decAddr.channel |= ((encAddr >> it->second) & 1) << it->first;
|
||||
|
||||
decAddr.rank = 0;
|
||||
for (auto it = vRankBits.begin(); it != vRankBits.end(); it++)
|
||||
decAddr.rank |= ((encAddr >> it->second) & 1) << it->first;
|
||||
|
||||
decAddr.bankgroup = 0;
|
||||
for (auto it = vBankGroupBits.begin(); it != vBankGroupBits.end(); it++)
|
||||
decAddr.bankgroup |= ((encAddr >> it->second) & 1) << it->first;
|
||||
|
||||
// Bank
|
||||
// it->second: position of the target bit in the address
|
||||
// it->first: target position of the bit in the variable
|
||||
// For each bank bit:
|
||||
// shift address bit to position 0. Clear all other bits. shift it the right bank bit. Add it to the set of bank bits.
|
||||
result.bank = 0;
|
||||
for (auto it = m_vBankBits.begin(); it != m_vBankBits.end(); it++) {
|
||||
result.bank |= ((addr >> it->second) & 1) << it->first;
|
||||
}
|
||||
decAddr.bank = 0;
|
||||
for (auto it = vBankBits.begin(); it != vBankBits.end(); it++)
|
||||
decAddr.bank |= ((encAddr >> it->second) & 1) << it->first;
|
||||
|
||||
// Row
|
||||
// it->second: position of the target bit in the address
|
||||
// it->first: target position of the bit in the variable
|
||||
// For each row bit:
|
||||
// shift address bit to position 0. Clear all other bits. shift it the right row bit. Add it to the set of row bits.
|
||||
result.row = 0;
|
||||
for (auto it = m_vRowBits.begin(); it != m_vRowBits.end(); it++) {
|
||||
result.row |= ((addr >> it->second) & 1) << it->first;
|
||||
}
|
||||
decAddr.row = 0;
|
||||
for (auto it = vRowBits.begin(); it != vRowBits.end(); it++)
|
||||
decAddr.row |= ((encAddr >> it->second) & 1) << it->first;
|
||||
|
||||
// Column
|
||||
// it->second: position of the target bit in the address
|
||||
// it->first: target position of the bit in the variable
|
||||
// For each column bit:
|
||||
// shift address bit to position 0. Clear all other bits. shift it the right column bit. Add it to the set of column bits.
|
||||
result.column = 0;
|
||||
for (auto it = m_vColumnBits.begin(); it != m_vColumnBits.end(); it++) {
|
||||
result.column |= ((addr >> it->second) & 1) << it->first;
|
||||
}
|
||||
decAddr.column = 0;
|
||||
for (auto it = vColumnBits.begin(); it != vColumnBits.end(); it++)
|
||||
decAddr.column |= ((encAddr >> it->second) & 1) << it->first;
|
||||
|
||||
return result;
|
||||
decAddr.bankgroup = decAddr.bankgroup + decAddr.rank * bankgroupsPerRank;
|
||||
decAddr.bank = decAddr.bank + decAddr.bankgroup * banksPerGroup;
|
||||
|
||||
return decAddr;
|
||||
}
|
||||
|
||||
uint64_t CongenAddressDecoder::encodeAddress(DecodedAddress n)
|
||||
uint64_t CongenAddressDecoder::encodeAddress(DecodedAddress decAddr)
|
||||
{
|
||||
uint64_t address = 0;
|
||||
decAddr.bankgroup = decAddr.bankgroup % bankgroupsPerRank;
|
||||
decAddr.bank = decAddr.bank % banksPerGroup;
|
||||
|
||||
uint64_t encAddr = 0;
|
||||
|
||||
for (auto it = vChannelBits.begin(); it != vChannelBits.end(); it++)
|
||||
encAddr |= ((decAddr.channel >> it->first) & 1) << it->second;
|
||||
|
||||
for (auto it = vRankBits.begin(); it != vRankBits.end(); it++)
|
||||
encAddr |= ((decAddr.rank >> it->first) & 1) << it->second;
|
||||
|
||||
for (auto it = vBankGroupBits.begin(); it != vBankGroupBits.end(); it++)
|
||||
encAddr |= ((decAddr.bankgroup >> it->first) & 1) << it->second;
|
||||
|
||||
// Bank
|
||||
// it->first: position of the target bit in the DecodedAddress struct field
|
||||
// it->second: target position of the bit in the address
|
||||
// For each bank bit:
|
||||
// shift bank bit to position 0. Clear all other bits. shift it the right address bit. Add it to the set of address bits.
|
||||
for (auto it = m_vBankBits.begin(); it != m_vBankBits.end(); it++) {
|
||||
address |= ((n.bank >> it->first) & 1) << it->second;
|
||||
}
|
||||
for (auto it = vBankBits.begin(); it != vBankBits.end(); it++)
|
||||
encAddr |= ((decAddr.bank >> it->first) & 1) << it->second;
|
||||
|
||||
// Row
|
||||
// it->first: position of the target bit in the DecodedAddress struct field
|
||||
// it->second: target position of the bit in the address
|
||||
// For each row bit:
|
||||
// shift row bit to position 0. Clear all other bits. shift it the right address bit. Add it to the set of address bits.
|
||||
for (auto it = m_vRowBits.begin(); it != m_vRowBits.end(); it++) {
|
||||
address |= ((n.row >> it->first) & 1) << it->second;
|
||||
}
|
||||
for (auto it = vRowBits.begin(); it != vRowBits.end(); it++)
|
||||
encAddr |= ((decAddr.row >> it->first) & 1) << it->second;
|
||||
|
||||
// Column
|
||||
// it->first: position of the target bit in the DecodedAddress struct field
|
||||
// it->second: target position of the bit in the address
|
||||
// For each column bit:
|
||||
// shift column bit to position 0. Clear all other bits. shift it the right address bit. Add it to the set of address bits.
|
||||
for (auto it = m_vColumnBits.begin(); it != m_vColumnBits.end(); it++) {
|
||||
address |= ((n.column >> it->first) & 1) << it->second;
|
||||
}
|
||||
for (auto it = vColumnBits.begin(); it != vColumnBits.end(); it++)
|
||||
encAddr |= ((decAddr.column >> it->first) & 1) << it->second;
|
||||
|
||||
// Add the unchanged byte bits
|
||||
address |= n.bytes;
|
||||
for (auto it = vByteBits.begin(); it != vByteBits.end(); it++)
|
||||
encAddr |= ((decAddr.bytes >> it->first) & 1) << it->second;
|
||||
|
||||
// Apply XOR
|
||||
// For each used xor:
|
||||
// Get the bank bit and row bit. Apply a bitwise xor operator and save it back to the bank bit.
|
||||
for (auto it = m_vXor.begin(); it != m_vXor.end(); it++) {
|
||||
for (auto it = vXor.begin(); it != vXor.end(); it++)
|
||||
{
|
||||
unsigned new_bank_bit;
|
||||
new_bank_bit = (((address >> it->nBank) & 1) ^ ((address >> it->nRow) & 1));
|
||||
address &= ~(1 << it->nBank);
|
||||
address |= new_bank_bit << it->nBank;
|
||||
new_bank_bit = (((encAddr >> it->nBank) & 1) ^ ((encAddr >> it->nRow) & 1));
|
||||
encAddr &= ~(1 << it->nBank);
|
||||
encAddr |= new_bank_bit << it->nBank;
|
||||
}
|
||||
|
||||
return address;
|
||||
return encAddr;
|
||||
}
|
||||
|
||||
bool CongenAddressDecoder::testConfigFile(std::string url)
|
||||
@@ -311,31 +357,31 @@ bool CongenAddressDecoder::testConfigFile(std::string url)
|
||||
|
||||
void CongenAddressDecoder::print()
|
||||
{
|
||||
map<unsigned, pair<unsigned, char>> output;
|
||||
std::map<unsigned, std::pair<unsigned, char>> output;
|
||||
|
||||
for (auto it = m_vBankBits.begin(); it != m_vBankBits.end(); it++) {
|
||||
output[it->second] = pair<unsigned, char>(it->first, 'B');
|
||||
for (auto it = vBankBits.begin(); it != vBankBits.end(); it++) {
|
||||
output[it->second] = std::pair<unsigned, char>(it->first, 'B');
|
||||
}
|
||||
for (auto it = m_vRowBits.begin(); it != m_vRowBits.end(); it++) {
|
||||
output[it->second] = pair<unsigned, char>(it->first, 'R');
|
||||
for (auto it = vRowBits.begin(); it != vRowBits.end(); it++) {
|
||||
output[it->second] = std::pair<unsigned, char>(it->first, 'R');
|
||||
}
|
||||
for (auto it = m_vColumnBits.begin(); it != m_vColumnBits.end(); it++) {
|
||||
output[it->second] = pair<unsigned, char>(it->first, 'C');
|
||||
for (auto it = vColumnBits.begin(); it != vColumnBits.end(); it++) {
|
||||
output[it->second] = std::pair<unsigned, char>(it->first, 'C');
|
||||
}
|
||||
|
||||
// add byte bits
|
||||
output[0] = pair<unsigned, char>(0, 'b');
|
||||
output[1] = pair<unsigned, char>(1, 'b');
|
||||
output[2] = pair<unsigned, char>(2, 'b');
|
||||
output[0] = std::pair<unsigned, char>(0, 'b');
|
||||
output[1] = std::pair<unsigned, char>(1, 'b');
|
||||
output[2] = std::pair<unsigned, char>(2, 'b');
|
||||
|
||||
cout << "Used addressmapping:" << endl;
|
||||
cout << headline << endl;
|
||||
std::cout << "Used addressmapping:" << std::endl;
|
||||
std::cout << headline << std::endl;
|
||||
for (unsigned i = 0; i < 32; i++) {
|
||||
cout << " " << i << " ";
|
||||
std::cout << " " << i << " ";
|
||||
}
|
||||
cout << endl;
|
||||
std::cout << std::endl;
|
||||
for (unsigned i = 0; i < 32; i++) {
|
||||
cout << " " << output[i].second << "(" << output[i].first << ") ";
|
||||
std::cout << " " << output[i].second << "(" << output[i].first << ") ";
|
||||
}
|
||||
cout << endl;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
@@ -50,51 +50,50 @@ class CongenAddressDecoder : private AddressDecoder
|
||||
friend class AddressDecoder;
|
||||
|
||||
public:
|
||||
struct XOR {
|
||||
struct XOR
|
||||
{
|
||||
unsigned nBank;
|
||||
unsigned nRow;
|
||||
XOR() {};
|
||||
XOR(unsigned bank, unsigned row) : nBank(bank), nRow(row) {};
|
||||
XOR() {}
|
||||
XOR(unsigned bank, unsigned row) : nBank(bank), nRow(row) {}
|
||||
};
|
||||
|
||||
// Member variables
|
||||
private:
|
||||
std::string m_strName; // The Name of this mapping
|
||||
std::string strName; // The Name of this mapping
|
||||
|
||||
unsigned int
|
||||
m_nCost; // Number of row misses produced by this mapping
|
||||
unsigned nCost; // Number of row misses produced by this mapping
|
||||
|
||||
unsigned int
|
||||
m_nBankBits; // Number of Bank bits used by this mapping
|
||||
unsigned int
|
||||
m_nRowBits; // Number of Row bits used by this mapping
|
||||
unsigned int
|
||||
m_nColumnBits; // Number of Column bits used by this mapping
|
||||
unsigned int
|
||||
m_nBurstLengthBits; // Number of Burst length bits used by this mapping
|
||||
unsigned int
|
||||
m_nByteBits; // Number of Byte bits used by this mapping
|
||||
unsigned nChannelBits;
|
||||
unsigned nRankBits;
|
||||
unsigned nBankGroupBits;
|
||||
unsigned nBankBits; // Number of Bank bits used by this mapping
|
||||
unsigned nRowBits; // Number of Row bits used by this mapping
|
||||
unsigned nColumnBits; // Number of Column bits used by this mapping
|
||||
unsigned nByteBits; // Number of Byte bits used by this mapping
|
||||
|
||||
|
||||
std::vector<XOR>
|
||||
m_vXor; // This container stores for each used xor gate a pair which consists of "First/Number of an address bit which corresponds to a bank" and "Second/Number of an address bit which corresponds to a row"
|
||||
std::vector<std::pair<unsigned, unsigned>>
|
||||
m_vBankBits; // This container stores for each bank bit a pair which consists of "First/Number of the bank bit" and "Second/Number of the address bit"
|
||||
std::vector<std::pair<unsigned, unsigned>>
|
||||
m_vRowBits; // This container stores for each row bit a pair which consists of "First/Number of the row bit" and "Second/Number of the address bit"
|
||||
std::vector<std::pair<unsigned, unsigned>>
|
||||
m_vColumnBits; // This container stores for each column bit a pair which consists of "First/Number of the column bit" and "Second/Number of the address bit"
|
||||
// This container stores for each used xor gate a pair which consists of "First/Number of an address bit which corresponds to a bank" and "Second/Number of an address bit which corresponds to a row"
|
||||
std::vector<XOR> vXor;
|
||||
std::vector<std::pair<unsigned, unsigned>> vChannelBits;
|
||||
std::vector<std::pair<unsigned, unsigned>> vRankBits;
|
||||
std::vector<std::pair<unsigned, unsigned>> vBankGroupBits;
|
||||
// This container stores for each bank bit a pair which consists of "First/Number of the bank bit" and "Second/Number of the address bit"
|
||||
std::vector<std::pair<unsigned, unsigned>> vBankBits;
|
||||
// This container stores for each row bit a pair which consists of "First/Number of the row bit" and "Second/Number of the address bit"
|
||||
std::vector<std::pair<unsigned, unsigned>> vRowBits;
|
||||
// This container stores for each column bit a pair which consists of "First/Number of the column bit" and "Second/Number of the address bit"
|
||||
std::vector<std::pair<unsigned, unsigned>> vColumnBits;
|
||||
std::vector<std::pair<unsigned, unsigned>> vByteBits;
|
||||
|
||||
//Methods
|
||||
private:
|
||||
tinyxml2::XMLElement *GetXMLNode(tinyxml2::XMLElement *pRoot,
|
||||
tinyxml2::XMLElement *getXMLNode(tinyxml2::XMLElement *pRoot,
|
||||
std::string strName);
|
||||
unsigned int GetUnsignedTextFromXMLNode(tinyxml2::XMLElement *pRoot);
|
||||
unsigned int GetUnsignedAttrFromXMLNode(tinyxml2::XMLElement *pRoot,
|
||||
unsigned int getUnsignedTextFromXMLNode(tinyxml2::XMLElement *pRoot);
|
||||
unsigned int getUnsignedAttrFromXMLNode(tinyxml2::XMLElement *pRoot,
|
||||
std::string strName);
|
||||
public:
|
||||
CongenAddressDecoder();
|
||||
|
||||
virtual void setConfiguration(std::string url);
|
||||
|
||||
virtual DecodedAddress decodeAddress(uint64_t addr);
|
||||
|
||||
@@ -132,33 +132,33 @@ void XmlAddressDecoder::setConfiguration(std::string addressConfigURI)
|
||||
}
|
||||
|
||||
|
||||
DecodedAddress XmlAddressDecoder::decodeAddress(uint64_t addr)
|
||||
DecodedAddress XmlAddressDecoder::decodeAddress(uint64_t encAddr)
|
||||
{
|
||||
if (addr > maximumAddress)
|
||||
SC_REPORT_WARNING("XmlAddressDecoder", ("Address " + std::to_string(addr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str());
|
||||
if (encAddr > maximumAddress)
|
||||
SC_REPORT_WARNING("XmlAddressDecoder", ("Address " + std::to_string(encAddr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str());
|
||||
|
||||
DecodedAddress result;
|
||||
result.channel = (addr & masks.channel) >> shifts.channel;
|
||||
result.rank = (addr & masks.rank) >> shifts.rank;
|
||||
result.bankgroup = ((addr & masks.bankgroup) >> shifts.bankgroup)
|
||||
result.channel = (encAddr & masks.channel) >> shifts.channel;
|
||||
result.rank = (encAddr & masks.rank) >> shifts.rank;
|
||||
result.bankgroup = ((encAddr & masks.bankgroup) >> shifts.bankgroup)
|
||||
+ result.rank * bankgroupsPerRank;
|
||||
result.bank = ((addr & masks.bank) >> shifts.bank)
|
||||
result.bank = ((encAddr & masks.bank) >> shifts.bank)
|
||||
+ result.bankgroup * banksPerGroup;
|
||||
result.row = (addr & masks.row) >> shifts.row;
|
||||
result.column = (addr & masks.column) >> shifts.column;
|
||||
result.bytes = (addr & masks.bytes) >> shifts.bytes;
|
||||
result.row = (encAddr & masks.row) >> shifts.row;
|
||||
result.column = (encAddr & masks.column) >> shifts.column;
|
||||
result.bytes = (encAddr & masks.bytes) >> shifts.bytes;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint64_t XmlAddressDecoder::encodeAddress(DecodedAddress n)
|
||||
uint64_t XmlAddressDecoder::encodeAddress(DecodedAddress decAddr)
|
||||
{
|
||||
return (n.channel << shifts.channel) |
|
||||
(n.rank << shifts.rank) |
|
||||
((n.bankgroup % bankgroupsPerRank) << shifts.bankgroup) |
|
||||
((n.bank % banksPerGroup) << shifts.bank) |
|
||||
(n.row << shifts.row) |
|
||||
(n.column << shifts.column) |
|
||||
(n.bytes << shifts.bytes);
|
||||
return (decAddr.channel << shifts.channel) |
|
||||
(decAddr.rank << shifts.rank) |
|
||||
((decAddr.bankgroup % bankgroupsPerRank) << shifts.bankgroup) |
|
||||
((decAddr.bank % banksPerGroup) << shifts.bank) |
|
||||
(decAddr.row << shifts.row) |
|
||||
(decAddr.column << shifts.column) |
|
||||
(decAddr.bytes << shifts.bytes);
|
||||
}
|
||||
|
||||
bool XmlAddressDecoder::testConfigFile(std::string url)
|
||||
|
||||
@@ -51,6 +51,8 @@ class XmlAddressDecoder : private AddressDecoder
|
||||
friend class AddressDecoder;
|
||||
|
||||
private:
|
||||
tinyxml2::XMLElement *addressmapping;
|
||||
|
||||
struct Masks
|
||||
{
|
||||
uint64_t channel = 0;
|
||||
@@ -73,24 +75,16 @@ private:
|
||||
unsigned bytes = 0;
|
||||
} shifts;
|
||||
|
||||
unsigned banksPerGroup;
|
||||
unsigned banksPerRank;
|
||||
unsigned bankgroupsPerRank;
|
||||
|
||||
tinyxml2::XMLElement *addressmapping;
|
||||
uint64_t maximumAddress;
|
||||
|
||||
public:
|
||||
XmlAddressDecoder();
|
||||
|
||||
virtual void setConfiguration(std::string url);
|
||||
|
||||
virtual DecodedAddress decodeAddress(uint64_t addr);
|
||||
virtual uint64_t encodeAddress(DecodedAddress n);
|
||||
|
||||
void setConfiguration(std::string url);
|
||||
|
||||
static bool testConfigFile(std::string url);
|
||||
|
||||
public:
|
||||
virtual void print();
|
||||
};
|
||||
|
||||
|
||||
@@ -47,7 +47,9 @@ TracePlayer::TracePlayer(sc_module_name name, TracePlayerListener *listener) :
|
||||
{
|
||||
iSocket.register_nb_transport_bw(this, &TracePlayer::nb_transport_bw);
|
||||
|
||||
if (Configuration::getInstance().storeMode != "NoStorage")
|
||||
if (Configuration::getInstance().storeMode == "NoStorage")
|
||||
storageEnabled = false;
|
||||
else
|
||||
storageEnabled = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ protected:
|
||||
void terminate();
|
||||
void setNumberOfTransactions(unsigned int n);
|
||||
unsigned int numberOfTransactions = 0;
|
||||
bool storageEnabled;
|
||||
bool storageEnabled = false;
|
||||
|
||||
private:
|
||||
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase,
|
||||
|
||||
Reference in New Issue
Block a user