Changed JSONAdressDecoder to ConGenAddressDecoder.

This commit is contained in:
Johannes Feldmann
2018-11-28 11:50:32 +01:00
parent 97a5b3e8d1
commit 193f26585c
10 changed files with 205 additions and 129 deletions

View File

@@ -125,8 +125,8 @@ SOURCES += \
src/controller/scheduler/Fr_Fcfs_grouper.cpp \
src/controller/RecordableController.cpp \
src/common/AddressDecoder.cpp \
src/common/jsonAddressDecoder.cpp \
src/controller/scheduler/grp.cpp
src/controller/scheduler/grp.cpp \
src/common/congenAddressDecoder.cpp
HEADERS += \
src/common/third_party/tinyxml2/tinyxml2.h \
@@ -206,8 +206,8 @@ HEADERS += \
src/controller/RecordableController.h \
src/simulation/RecordableDram.h \
src/common/AddressDecoder.h \
src/common/jsonAddressDecoder.h \
src/controller/scheduler/grp.h
src/controller/scheduler/grp.h \
src/common/congenAddressDecoder.h
#src/common/third_party/json/include/nlohmann/json.hpp \
thermalsim = $$(THERMALSIM)

View File

@@ -1,45 +0,0 @@
{
"Config": {
"numberOfBankBits": 3,
"numberOfRowBits": 14,
"numberOfColumnBits": 10,
"numberOfByteBits": 3,
"numberOfBLBits": 3
},
"Name": "merged_sorted",
"Solutions": [
{
"XOR": [
],
"Banks Rows": [
{
"bank_bits": [
27,
28,
29
],
"rows": {
"row_bits": [
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26
],
"costs": 477468
},
"costs": 477468
}
]
}
]
}

View File

@@ -8,7 +8,7 @@
<!-- Memory Device Specification: Which Device is on the DDR3 DIMM -->
<memspec src="MICRON_1Gb_DDR3-1600_8bit_G.xml"></memspec>
<!-- Addressmapping Configuration of the Memory Controller -->
<addressmapping src="am_ddr3_8x1Gbx8_dimm_p1KB_brc.xml"></addressmapping>
<addressmapping src="ConGenTest.xml"></addressmapping>
<!-- Memory Controller Configuration: -->
<mcconfig src="fifoStrict.xml"/>
<!--

View File

@@ -35,7 +35,7 @@
#include "AddressDecoder.h"
#include "xmlAddressdecoder.h"
#include "jsonAddressDecoder.h"
#include "congenAddressDecoder.h"
AddressDecoder *AddressDecoder::m_pInstance = nullptr;
@@ -52,8 +52,8 @@ void AddressDecoder::createInstance(Type t)
case Type::XML:
m_pInstance = new xmlAddressDecoder;
break;
case Type::JSON:
m_pInstance = new JSONAddressDecoder;
case Type::CONGEN:
m_pInstance = new CongenAddressDecoder;
break;
default:
throw std::logic_error("Instance type not supported.");

View File

@@ -67,7 +67,7 @@ class AddressDecoder
public:
enum class Type {
XML,
JSON
CONGEN
};
protected:

View File

@@ -33,7 +33,7 @@
* Johannes Feldmann
*/
#include "jsonAddressDecoder.h"
#include "congenAddressDecoder.h"
#include "Utils.h"
#include <fstream>
@@ -42,80 +42,137 @@ using std::ifstream;
using std::cout;
using std::endl;
#if 0 // Problems with gcc version on KOA for more details refer to pull-request #190 and issue #198
#include <nlohmann/json.hpp>
using json = nlohmann::json;
#endif
#include <set>
using std::set;
JSONAddressDecoder::JSONAddressDecoder()
tinyxml2::XMLElement *CongenAddressDecoder::GetXMLNode(tinyxml2::XMLElement
*pRoot, std::string strName)
{
tinyxml2::XMLElement *pNode = pRoot->FirstChildElement(strName.c_str());
if (pNode == nullptr) {
reportFatal("ConGenAddressDecorder",
"XML File corrupted. Missing node " + strName + ".");
}
return pNode;
}
unsigned int CongenAddressDecoder::GetUnsignedTextFromXMLNode(
tinyxml2::XMLElement *pRoot)
{
std::string str = pRoot->GetText();
if (str.empty() || std::find_if(str.begin(), str.end(), [](char c) {
return !std::isdigit(c);
}) != str.end()) {
reportFatal("ConGenAddressDecoder",
"Node " + std::string(pRoot->Name()) + " is empty or not a number.");
return (unsigned)(-1);
}
return atol(str.c_str());
}
unsigned int CongenAddressDecoder::GetUnsignedAttrFromXMLNode(
tinyxml2::XMLElement *pRoot, std::string strName)
{
std::string str = pRoot->Attribute(strName.c_str());
if (str.empty() || std::find_if(str.begin(), str.end(), [](char c) {
return !std::isdigit(c);
}) != str.end()) {
reportFatal("ConGenAddressDecoder",
"Attribute " + strName + " is empty or not a number.");
return (unsigned)(-1);
}
return atol(str.c_str());
}
CongenAddressDecoder::CongenAddressDecoder()
{
}
void JSONAddressDecoder::setConfiguration(std::string url)
void CongenAddressDecoder::setConfiguration(std::string url)
{
ifstream file;
tinyxml2::XMLDocument doc;
loadXML(url, doc);
tinyxml2::XMLElement *pRoot = doc.RootElement();
std::string xmlNodeName(pRoot->Name());
file.open(url);
if ( xmlNodeName != "CONGEN") {
reportFatal("ConGenAddressDecorder",
"Root node name differs from \"CONGEN\". File format not supported.");
}
if (!file.is_open()) {
cout << "Unable to open file " << url << endl;
// 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);
// 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;
}
}
// 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 0 //XXX: Problems with gcc version on KOA for more details refer to pull-request #190 and issue #198
// parse json file
json data;
file >> data;
file.close();
// extract data
// For simplicity take the first solution of one or more available ones.
auto sol = data["Solutions"].begin();
assert(sol != data["Solutions"].end());
// Set for connected bits. Used to find the remaining bits, which are not part of the json file = column bits.
set<unsigned> sUsed;
// get XOR connections
// An XOR connection needs two parameters: A bank bit and a Row bit.
// These parameters are all stored in one array with the following pattern: bank0, bank1, ..., row0, row1, ...
unsigned num = (*sol)["XOR"].size() >> 1;
for (unsigned i = 0; i < num; i++) {
m_vXor.push_back(pair<unsigned, unsigned> ((*sol)["XOR"].at(i),
(*sol)["XOR"].at(i + num)));
for (tinyxml2::XMLElement *pXor = pNode->FirstChildElement("XOR");
pXor != nullptr; pXor = pXor->NextSiblingElement("XOR")) {
m_vXor.push_back(XOR(GetUnsignedAttrFromXMLNode(pXor, "BANK"),
GetUnsignedAttrFromXMLNode(pXor, "ROW")));
}
set<unsigned> sUsed;
// 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;
for (auto it = (*sol)["Banks Rows"][0]["bank_bits"].begin();
it != (*sol)["Banks Rows"][0]["bank_bits"].end(); it++) {
m_vBankBits.push_back(pair<unsigned, unsigned>(counter++, (*it)));
sUsed.insert((unsigned)(*it));
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);
}
// get all row bits bits
// Each Row bit of the address will be stored with a counter value which assigns the bit position DecodedAddress struct.
counter = 0;
for (auto it = (*sol)["Banks Rows"][0]["rows"]["row_bits"].begin();
it != (*sol)["Banks Rows"][0]["rows"]["row_bits"].end(); it++) {
m_vRowBits.push_back(pair<unsigned, unsigned>(counter++, (*it)));
sUsed.insert((unsigned)(*it));
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);
}
// Add byte bits (fixed)
sUsed.insert(0);
sUsed.insert(1);
sUsed.insert(2);
// Add byte bits
for (unsigned i = 0; i < m_nByteBits; i++) {
sUsed.insert(i);
}
// Theset bits are ignored
// Theset bits are ignored (fixed in Congen)
sUsed.insert(30);
sUsed.insert(31);
@@ -135,11 +192,10 @@ void JSONAddressDecoder::setConfiguration(std::string url)
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, 3);
#endif
amount["bytes"] = pow(2.0, m_nByteBits);
}
DecodedAddress JSONAddressDecoder::decodeAddress(sc_dt::uint64 addr)
DecodedAddress CongenAddressDecoder::decodeAddress(sc_dt::uint64 addr)
{
DecodedAddress result;
@@ -149,9 +205,9 @@ DecodedAddress JSONAddressDecoder::decodeAddress(sc_dt::uint64 addr)
for (auto it = m_vXor.begin(); it != m_vXor.end(); it++) {
unsigned new_bank_bit;
// Bank Row
new_bank_bit = (((addr >> it->first) & 1) ^ ((addr >> it->second) & 1));
addr &= ~(1 << it->first);
addr |= new_bank_bit << it->first;
new_bank_bit = (((addr >> it->nBank) & 1) ^ ((addr >> it->nRow) & 1));
addr &= ~(1 << it->nBank);
addr |= new_bank_bit << it->nBank;
}
// Unsed
@@ -195,7 +251,7 @@ DecodedAddress JSONAddressDecoder::decodeAddress(sc_dt::uint64 addr)
return result;
}
sc_dt::uint64 JSONAddressDecoder::encodeAddress(DecodedAddress n)
sc_dt::uint64 CongenAddressDecoder::encodeAddress(DecodedAddress n)
{
sc_dt::uint64 address = 0;
@@ -232,32 +288,44 @@ sc_dt::uint64 JSONAddressDecoder::encodeAddress(DecodedAddress n)
// 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++) {
unsigned new_bank_bit;
new_bank_bit = (((address >> it->first) & 1) ^ ((address >> it->second) & 1));
address &= ~(1 << it->first);
address |= new_bank_bit << it->first;
new_bank_bit = (((address >> it->nBank) & 1) ^ ((address >> it->nRow) & 1));
address &= ~(1 << it->nBank);
address |= new_bank_bit << it->nBank;
}
return address;
}
void JSONAddressDecoder::print()
bool CongenAddressDecoder::testConfigFile(std::string url)
{
// Simple test if the root node has the correct name.
// This is suitable for now, but can be extended in future.
tinyxml2::XMLDocument doc;
loadXML(url, doc);
tinyxml2::XMLElement *pRoot = doc.RootElement();
return (strcmp(pRoot->Name(), "CONGEN") == 0);
}
void CongenAddressDecoder::print()
{
map<unsigned, pair<unsigned, char>> output;
for (auto it = m_vBankBits.begin(); it != m_vBankBits.end(); it++) {
output[it->second] = pair<unsigned, char>(it->first , 'B');
output[it->second] = 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');
output[it->second] = 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');
output[it->second] = 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] = pair<unsigned, char>(0, 'b');
output[1] = pair<unsigned, char>(1, 'b');
output[2] = pair<unsigned, char>(2, 'b');
cout << "Used addressmapping:" << endl;
cout << headline << endl;

View File

@@ -33,11 +33,13 @@
* Johannes Feldmann
*/
#ifndef JSONADDRESSDECODER_H
#define JSONADDRESSDECODER_H
#ifndef CONGENADDRESSDECODER_H
#define CONGENADDRESSDECODER_H
#include "AddressDecoder.h"
#include "third_party/tinyxml2/tinyxml2.h"
#include <vector>
#include <map>
@@ -45,17 +47,42 @@ using std::vector;
using std::pair;
using std::map;
class JSONAddressDecoder
class CongenAddressDecoder
: private AddressDecoder
{
// Friendship needed so that the AddressDecoder can access the
// constructor of this class to create the object in CreateInstance.
friend class AddressDecoder;
public:
struct XOR {
unsigned nBank;
unsigned nRow;
XOR() {};
XOR(unsigned bank, unsigned row) : nBank(bank), nRow(row) {};
};
// Member variables
private:
vector<pair<unsigned, unsigned>>
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::string m_strName; // The Name of this mapping
unsigned int
m_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
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"
vector<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"
vector<pair<unsigned, unsigned>>
@@ -63,15 +90,24 @@ private:
vector<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"
//Methods
private:
tinyxml2::XMLElement *GetXMLNode(tinyxml2::XMLElement *pRoot,
std::string strName);
unsigned int GetUnsignedTextFromXMLNode(tinyxml2::XMLElement *pRoot);
unsigned int GetUnsignedAttrFromXMLNode(tinyxml2::XMLElement *pRoot,
std::string strName);
public:
JSONAddressDecoder();
CongenAddressDecoder();
virtual void setConfiguration(std::string url);
virtual DecodedAddress decodeAddress(sc_dt::uint64 addr);
virtual sc_dt::uint64 encodeAddress(DecodedAddress n);
static bool testConfigFile(std::string url);
virtual void print();
};
#endif // JSONADDRESSDECODER_H
#endif // CONGENADDRESSDECODER_H

View File

@@ -103,6 +103,18 @@ sc_dt::uint64 xmlAddressDecoder::encodeAddress(DecodedAddress n)
n.bytes << shifts["bytes"];
}
bool xmlAddressDecoder::testConfigFile(std::string url)
{
// Simple test if the root node has the correct name.
// This is suitable for now, but can be extended in future.
tinyxml2::XMLDocument doc;
loadXML(url, doc);
tinyxml2::XMLElement *addressMap = doc.RootElement();
return (strcmp(addressMap->Name(), "addressmapping") == 0);
}
void xmlAddressDecoder::print()
{
cout << headline << endl;

View File

@@ -65,6 +65,8 @@ public:
void setConfiguration(std::string url);
static bool testConfigFile(std::string url);
public:
virtual void print();
};

View File

@@ -47,6 +47,7 @@
#include "../common/TlmRecorder.h"
#include "../common/DebugManager.h"
#include "../common/xmlAddressdecoder.h"
#include "../common/congenAddressDecoder.h"
#include "../controller/core/ControllerCore.h"
#include "../controller/core/configuration/ConfigurationLoader.h"
#include "../common/Utils.h"
@@ -85,18 +86,20 @@ DRAMSys::DRAMSys(sc_module_name __attribute__((unused)) name,
// ConfigurationLoader because some information from the xmlAddressDecoder
// is needed to assure the coherence of the configuration.
if (amconfig.find(".xml") != string::npos) {
if (xmlAddressDecoder::testConfigFile(pathToResources + "configs/amconfigs/" +
amconfig)) {
AddressDecoder::createInstance(AddressDecoder::Type::XML);
AddressDecoder::getInstance().setConfiguration(pathToResources
+ "configs/amconfigs/"
+ amconfig);
} else if (amconfig.find(".json") != string::npos) {
AddressDecoder::createInstance(AddressDecoder::Type::JSON);
} else if (CongenAddressDecoder::testConfigFile(pathToResources +
"configs/amconfigs/" + amconfig)) {
AddressDecoder::createInstance(AddressDecoder::Type::CONGEN);
AddressDecoder::getInstance().setConfiguration(pathToResources
+ "configs/amconfigs/"
+ amconfig);
} else {
throw std::runtime_error("No address mapping loaded. Unknown file extension");
throw std::runtime_error("No address mapping loaded. Unsupported file format");
}
AddressDecoder::getInstance().print();