Merge branch 'addressdecoder_unification' into 'master'

Address decoder unification

See merge request ems/astdm/dram.sys!245
This commit is contained in:
Matthias Jung
2020-04-15 11:07:04 +02:00
27 changed files with 426 additions and 1201 deletions

View File

@@ -66,13 +66,11 @@ include_directories(
add_library(DRAMSysLibrary
src/common/AddressDecoder.cpp
src/common/CongenAddressDecoder.cpp
src/common/DebugManager.cpp
src/common/dramExtensions.cpp
src/common/tlm2_base_protocol_checker.h
src/common/TlmRecorder.cpp
src/common/utils.cpp
src/common/XmlAddressDecoder.cpp
src/common/third_party/tinyxml2/tinyxml2.cpp
src/configuration/Configuration.cpp
@@ -140,11 +138,9 @@ add_library(DRAMSysLibrary
src/simulation/Arbiter.cpp
src/simulation/DRAMSys.cpp
src/simulation/ExampleInitiator.h
src/simulation/IArbiter.h
src/simulation/MemoryManager.cpp
src/simulation/ReorderBuffer.h
src/simulation/Setup.cpp
src/simulation/SimpleArbiter.h
src/simulation/StlPlayer.h
src/simulation/TemperatureController.cpp
src/simulation/TraceGenerator.h

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" ?>
<CONGEN>
<SOLUTION ID="0">
<XOR FIRST="13" SECOND="16"/>
<BYTE_BIT>0</BYTE_BIT>
<BYTE_BIT>1</BYTE_BIT>
<BYTE_BIT>2</BYTE_BIT>
<COLUMN_BIT>3</COLUMN_BIT>
<COLUMN_BIT>4</COLUMN_BIT>
<COLUMN_BIT>5</COLUMN_BIT>
<COLUMN_BIT>6</COLUMN_BIT>
<COLUMN_BIT>7</COLUMN_BIT>
<COLUMN_BIT>8</COLUMN_BIT>
<COLUMN_BIT>9</COLUMN_BIT>
<COLUMN_BIT>10</COLUMN_BIT>
<COLUMN_BIT>11</COLUMN_BIT>
<COLUMN_BIT>12</COLUMN_BIT>
<BANK_BIT>13</BANK_BIT>
<BANK_BIT>14</BANK_BIT>
<BANK_BIT>15</BANK_BIT>
<ROW_BIT>16</ROW_BIT>
<ROW_BIT>17</ROW_BIT>
<ROW_BIT>18</ROW_BIT>
<ROW_BIT>19</ROW_BIT>
<ROW_BIT>20</ROW_BIT>
<ROW_BIT>21</ROW_BIT>
<ROW_BIT>22</ROW_BIT>
<ROW_BIT>23</ROW_BIT>
<ROW_BIT>24</ROW_BIT>
<ROW_BIT>25</ROW_BIT>
<ROW_BIT>26</ROW_BIT>
<ROW_BIT>27</ROW_BIT>
<ROW_BIT>28</ROW_BIT>
<ROW_BIT>29</ROW_BIT>
</SOLUTION>
</CONGEN>

View File

@@ -31,32 +31,270 @@
*
* Authors:
* Johannes Feldmann
* Lukas Steiner
*/
#include <cmath>
#include <bitset>
#include "AddressDecoder.h"
#include "XmlAddressDecoder.h"
#include "CongenAddressDecoder.h"
#include "utils.h"
#include "../configuration/Configuration.h"
AddressDecoder *AddressDecoder::m_pInstance = nullptr;
AddressDecoder &AddressDecoder::getInstance()
tinyxml2::XMLElement *AddressDecoder::getXMLNode(tinyxml2::XMLElement
*pRoot, std::string strName)
{
assert(m_pInstance != nullptr);
return *m_pInstance;
}
void AddressDecoder::createInstance(Type t)
{
assert(m_pInstance == nullptr);
switch (t) {
case Type::XML:
m_pInstance = new XmlAddressDecoder;
break;
case Type::CONGEN:
m_pInstance = new CongenAddressDecoder;
break;
default:
throw std::logic_error("Instance type not supported.");
break;
tinyxml2::XMLElement *pNode = pRoot->FirstChildElement(strName.c_str());
if (pNode == nullptr) {
reportFatal("AddressDecorder",
"XML File corrupted. Missing node " + strName + ".");
}
return pNode;
}
unsigned int AddressDecoder::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("AddressDecoder",
"Node " + std::string(pRoot->Name()) + " is empty or not a number.");
return (unsigned)(-1);
}
return atol(str.c_str());
}
unsigned int AddressDecoder::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("AddressDecoder",
"Attribute " + strName + " is empty or not a number.");
return (unsigned)(-1);
}
return atol(str.c_str());
}
AddressDecoder::AddressDecoder(std::string pathToAddressMapping)
{
tinyxml2::XMLDocument doc;
loadXML(pathToAddressMapping, doc);
tinyxml2::XMLElement *pRoot = doc.RootElement();
std::string xmlNodeName(pRoot->Name());
if (xmlNodeName != "CONGEN")
reportFatal("AddressDecorder",
"Root node name differs from \"CONGEN\". File format not supported.");
// Load address mapping
tinyxml2::XMLElement *pNode;
for (pNode = pRoot->FirstChildElement("SOLUTION"); pNode != nullptr;
pNode = pNode->NextSiblingElement("SOLUTION"))
{
if (getUnsignedAttrFromXMLNode(pNode, "ID") == 0)
break;
}
if (pNode == nullptr)
SC_REPORT_FATAL("AddressDecoder", "No mapping with ID 0 was found.");
// get XOR connections
// An XOR connection needs two parameters: A first bit and a second bit.
for (tinyxml2::XMLElement *pXor = pNode->FirstChildElement("XOR");
pXor != nullptr; pXor = pXor->NextSiblingElement("XOR"))
{
vXor.push_back(std::pair<unsigned, unsigned>(getUnsignedAttrFromXMLNode(pXor, "FIRST"),
getUnsignedAttrFromXMLNode(pXor, "SECOND")));
}
for (tinyxml2::XMLElement *pChannel = pNode->FirstChildElement("CHANNEL_BIT");
pChannel != nullptr; pChannel = pChannel->NextSiblingElement("CHANNEL_BIT"))
vChannelBits.push_back(getUnsignedTextFromXMLNode(pChannel));
for (tinyxml2::XMLElement *pRank = pNode->FirstChildElement("RANK_BIT");
pRank != nullptr; pRank = pRank->NextSiblingElement("RANK_BIT"))
vRankBits.push_back(getUnsignedTextFromXMLNode(pRank));
for (tinyxml2::XMLElement *pBankGroup = pNode->FirstChildElement("BANKGROUP_BIT");
pBankGroup != nullptr; pBankGroup = pBankGroup->NextSiblingElement("BANKGROUP_BIT"))
vBankGroupBits.push_back(getUnsignedTextFromXMLNode(pBankGroup));
for (tinyxml2::XMLElement *pBank = pNode->FirstChildElement("BANK_BIT");
pBank != nullptr; pBank = pBank->NextSiblingElement("BANK_BIT"))
vBankBits.push_back(getUnsignedTextFromXMLNode(pBank));
for (tinyxml2::XMLElement *pRow = pNode->FirstChildElement("ROW_BIT");
pRow != nullptr; pRow = pRow->NextSiblingElement("ROW_BIT"))
vRowBits.push_back(getUnsignedTextFromXMLNode(pRow));
for (tinyxml2::XMLElement *pColumn = pNode->FirstChildElement("COLUMN_BIT");
pColumn != nullptr; pColumn = pColumn->NextSiblingElement("COLUMN_BIT"))
vColumnBits.push_back(getUnsignedTextFromXMLNode(pColumn));
for (tinyxml2::XMLElement *pByte = pNode->FirstChildElement("BYTE_BIT");
pByte != nullptr; pByte = pByte->NextSiblingElement("BYTE_BIT"))
vByteBits.push_back(getUnsignedTextFromXMLNode(pByte));
unsigned channels = pow(2.0, vChannelBits.size());
unsigned ranks = pow(2.0, vRankBits.size());
unsigned bankgroups = pow(2.0, vBankGroupBits.size());
unsigned banks = pow(2.0, vBankBits.size());
unsigned rows = pow(2.0, vRowBits.size());
unsigned columns = pow(2.0, vColumnBits.size());
unsigned bytes = pow(2.0, vByteBits.size());
maximumAddress = bytes * columns * rows * banks * bankgroups * ranks * channels - 1;
banksPerGroup = banks;
banks = banksPerGroup * bankgroups * ranks;
bankgroupsPerRank = bankgroups;
bankgroups = bankgroupsPerRank * ranks;
Configuration &config = Configuration::getInstance();
MemSpec *memSpec = config.memSpec;
if (config.numberOfMemChannels != channels || memSpec->numberOfRanks != ranks
|| memSpec->numberOfBankGroups != bankgroups || memSpec->numberOfBanks != banks
|| memSpec->numberOfRows != rows || memSpec->numberOfColumns != columns
|| config.numberOfDevicesOnDIMM * memSpec->bitWidth != bytes * 8)
SC_REPORT_FATAL("AddressDecoder", "Memspec and address mapping do not match");
}
DecodedAddress AddressDecoder::decodeAddress(uint64_t encAddr)
{
if (encAddr > maximumAddress)
SC_REPORT_WARNING("AddressDecoder", ("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 first bit and second bit. Apply a bitwise xor operator and save it back to the first bit.
for (auto it = vXor.begin(); it != vXor.end(); it++)
{
unsigned xoredBit;
xoredBit = (((encAddr >> it->first) & 1) ^ ((encAddr >> it->second) & 1));
encAddr &= ~(1 << it->first);
encAddr |= xoredBit << it->first;
}
DecodedAddress decAddr;
for (unsigned it = 0; it < vChannelBits.size(); it++)
decAddr.channel |= ((encAddr >> vChannelBits[it]) & 1) << it;
for (unsigned it = 0; it < vRankBits.size(); it++)
decAddr.rank |= ((encAddr >> vRankBits[it]) & 1) << it;
for (unsigned it = 0; it < vBankGroupBits.size(); it++)
decAddr.bankgroup |= ((encAddr >> vBankGroupBits[it]) & 1) << it;
for (unsigned it = 0; it < vBankBits.size(); it++)
decAddr.bank |= ((encAddr >> vBankBits[it]) & 1) << it;
for (unsigned it = 0; it < vRowBits.size(); it++)
decAddr.row |= ((encAddr >> vRowBits[it]) & 1) << it;
for (unsigned it = 0; it < vColumnBits.size(); it++)
decAddr.column |= ((encAddr >> vColumnBits[it]) & 1) << it;
for (unsigned it = 0; it < vByteBits.size(); it++)
decAddr.byte |= ((encAddr >> vByteBits[it]) & 1) << it;
decAddr.bankgroup = decAddr.bankgroup + decAddr.rank * bankgroupsPerRank;
decAddr.bank = decAddr.bank + decAddr.bankgroup * banksPerGroup;
return decAddr;
}
void AddressDecoder::print()
{
std::cout << headline << std::endl;
std::cout << "Used Address Mapping:" << std::endl;
std::cout << std::endl;
for (int it = vChannelBits.size() - 1; it >= 0; it--)
{
uint64_t addressBits = (1 << vChannelBits[it]);
for (auto it2 : vXor)
{
if (it2.first == vChannelBits[it])
addressBits |= (1 << it2.second);
}
std::cout << " Ch " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl;
}
for (int it = vRankBits.size() - 1; it >= 0; it--)
{
uint64_t addressBits = (1 << vRankBits[it]);
for (auto it2 : vXor)
{
if (it2.first == vRankBits[it])
addressBits |= (1 << it2.second);
}
std::cout << " Ra " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl;
}
for (int it = vBankGroupBits.size() - 1; it >= 0; it--)
{
uint64_t addressBits = (1 << vBankGroupBits[it]);
for (auto it2 : vXor)
{
if (it2.first == vBankGroupBits[it])
addressBits |= (1 << it2.second);
}
std::cout << " Bg " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl;
}
for (int it = vBankBits.size() - 1; it >= 0; it--)
{
uint64_t addressBits = (1 << vBankBits[it]);
for (auto it2 : vXor)
{
if (it2.first == vBankBits[it])
addressBits |= (1 << it2.second);
}
std::cout << " Ba " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl;
}
for (int it = vRowBits.size() - 1; it >= 0; it--)
{
uint64_t addressBits = (1 << vRowBits[it]);
for (auto it2 : vXor)
{
if (it2.first == vRowBits[it])
addressBits |= (1 << it2.second);
}
std::cout << " Ro " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl;
}
for (int it = vColumnBits.size() - 1; it >= 0; it--)
{
uint64_t addressBits = (1 << vColumnBits[it]);
for (auto it2 : vXor)
{
if (it2.first == vColumnBits[it])
addressBits |= (1 << it2.second);
}
std::cout << " Co " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl;
}
for (int it = vByteBits.size() - 1; it >= 0; it--)
{
uint64_t addressBits = (1 << vByteBits[it]);
for (auto it2 : vXor)
{
if (it2.first == vByteBits[it])
addressBits |= (1 << it2.second);
}
std::cout << " By " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl;
}
std::cout << std::endl;
}

View File

@@ -31,70 +31,69 @@
*
* Authors:
* Johannes Feldmann
* Lukas Steiner
*/
#ifndef ADDRESSDECODER_H
#define ADDRESSDECODER_H
#include <tlm.h>
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <vector>
struct DecodedAddress {
DecodedAddress() : channel(0),
rank(0),
bankgroup(0),
row(0),
bank(0),
column(0),
bytes(0)
{
}
#include "third_party/tinyxml2/tinyxml2.h"
unsigned int channel;
unsigned int rank;
unsigned int bankgroup;
unsigned int row;
unsigned int bank;
unsigned int column;
unsigned int bytes;
struct DecodedAddress
{
DecodedAddress(unsigned channel, unsigned rank,
unsigned bankgroup, unsigned bank,
unsigned row, unsigned column, unsigned bytes)
: channel(channel), rank(rank), bankgroup(bankgroup),
bank(bank), row(row), column(column), byte(bytes) {}
DecodedAddress()
: channel(0), rank(0), bankgroup(0),
bank(0), row(0), column(0), byte(0) {}
unsigned channel;
unsigned rank;
unsigned bankgroup;
unsigned bank;
unsigned row;
unsigned column;
unsigned byte;
};
class AddressDecoder
{
public:
enum class Type {
XML,
CONGEN
};
AddressDecoder(std::string);
DecodedAddress decodeAddress(uint64_t addr);
void print();
protected:
AddressDecoder() {}
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);
static AddressDecoder *m_pInstance;
public:
static AddressDecoder &getInstance();
static void createInstance(Type t);
unsigned banksPerGroup;
unsigned bankgroupsPerRank;
virtual void setConfiguration(std::string url) = 0;
uint64_t maximumAddress;
virtual DecodedAddress decodeAddress(uint64_t addr) = 0;
virtual uint64_t encodeAddress(DecodedAddress n) = 0;
virtual void print() = 0;
struct Amount
{
unsigned channel = 1;
unsigned rank = 1;
unsigned bankgroup = 1;
unsigned bank = 1;
unsigned row = 1;
unsigned column = 1;
unsigned bytes = 1;
} amount;
// This container stores for each used xor gate a pair of address bits, the first bit is overwritten with the result
std::vector<std::pair<unsigned, unsigned>> vXor;
std::vector<unsigned> vChannelBits;
std::vector<unsigned> vRankBits;
std::vector<unsigned> vBankGroupBits;
std::vector<unsigned> vBankBits;
std::vector<unsigned> vRowBits;
std::vector<unsigned> vColumnBits;
std::vector<unsigned> vByteBits;
};
#endif // ADDRESSDECODER_H

View File

@@ -1,341 +0,0 @@
/*
* Copyright (c) 2018, University of Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Johannes Feldmann
*/
#include "CongenAddressDecoder.h"
#include "utils.h"
#include <fstream>
#include <set>
using std::ifstream;
using std::cout;
using std::endl;
using std::set;
using std::pair;
using std::map;
using std::deque;
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 CongenAddressDecoder::setConfiguration(std::string url)
{
tinyxml2::XMLDocument doc;
loadXML(url, doc);
tinyxml2::XMLElement *pRoot = doc.RootElement();
std::string xmlNodeName(pRoot->Name());
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);
// 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;
}
// 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")));
}
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 (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 (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
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
m_vColumnBits.push_back(pair<unsigned, unsigned>(counter++, i));
}
// 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);
}
DecodedAddress CongenAddressDecoder::decodeAddress(uint64_t addr)
{
DecodedAddress result;
// 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++) {
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;
}
// Unsed
result.bankgroup = 0;
result.channel = 0;
result.rank = 0;
// Pass through of the three byte bits
result.bytes = addr & 0x7;
// 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;
}
// 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;
}
// 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;
}
return result;
}
uint64_t CongenAddressDecoder::encodeAddress(DecodedAddress n)
{
uint64_t address = 0;
// 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;
}
// 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;
}
// 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;
}
// Add the unchanged byte bits
address |= n.bytes;
// 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++) {
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;
}
return address;
}
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');
}
for (auto it = m_vRowBits.begin(); it != m_vRowBits.end(); it++) {
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');
}
// add byte bits
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;
for (unsigned i = 0; i < 32; i++) {
cout << " " << i << " ";
}
cout << endl;
for (unsigned i = 0; i < 32; i++) {
cout << " " << output[i].second << "(" << output[i].first << ") ";
}
cout << endl;
}

View File

@@ -1,108 +0,0 @@
/*
* Copyright (c) 2018, University of Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Johannes Feldmann
*/
#ifndef CONGENADDRESSDECODER_H
#define CONGENADDRESSDECODER_H
#include "AddressDecoder.h"
#include "third_party/tinyxml2/tinyxml2.h"
#include <vector>
#include <map>
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:
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
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"
//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:
CongenAddressDecoder();
virtual void setConfiguration(std::string url);
virtual DecodedAddress decodeAddress(uint64_t addr);
virtual uint64_t encodeAddress(DecodedAddress n);
static bool testConfigFile(std::string url);
virtual void print();
};
#endif // CONGENADDRESSDECODER_H

View File

@@ -41,7 +41,6 @@
#include "TlmRecorder.h"
#include "dramExtensions.h"
#include "XmlAddressDecoder.h"
#include "../configuration/Configuration.h"
#include "../controller/Command.h"

View File

@@ -49,7 +49,6 @@
#include <cerrno>
#include <tlm.h>
#include <systemc.h>
#include "XmlAddressDecoder.h"
#include "DebugManager.h"
#include "utils.h"

View File

@@ -1,188 +0,0 @@
/*
* Copyright (c) 2015, University of Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#include "XmlAddressDecoder.h"
#include <systemc.h>
#include "utils.h"
#include "bitset"
#include "../configuration/Configuration.h"
using namespace tinyxml2;
XmlAddressDecoder::XmlAddressDecoder()
{
addressmapping = NULL;
}
void XmlAddressDecoder::setConfiguration(std::string addressConfigURI)
{
tinyxml2::XMLDocument doc;
loadXML(addressConfigURI, doc);
tinyxml2::XMLElement *addressMap = doc.RootElement();
std::string xmlNodeName(addressMap->Name());
if (xmlNodeName != "addressmapping")
reportFatal("AddressDecorder", "addressmap node expected");
for (XMLElement *child = addressMap->FirstChildElement();
child != NULL; child = child->NextSiblingElement())
{
unsigned from;
unsigned to;
child->QueryAttribute("from", &from);
child->QueryAttribute("to", &to);
if (std::strcmp(child->Name(), "channel") == 0)
{
shifts.channel = from;
masks.channel = pow(2.0, to + 1.0) - pow(2.0, from + 0.0);
amount.channel = pow(2.0, to - from + 1.0);
}
else if (std::strcmp(child->Name(), "rank") == 0)
{
shifts.rank = from;
masks.rank = pow(2.0, to + 1.0) - pow(2.0, from + 0.0);
amount.rank = pow(2.0, to - from + 1.0);
}
else if (std::strcmp(child->Name(), "bankgroup") == 0)
{
shifts.bankgroup = from;
masks.bankgroup = pow(2.0, to + 1.0) - pow(2.0, from + 0.0);
amount.bankgroup = pow(2.0, to - from + 1.0);
}
else if (std::strcmp(child->Name(), "bank") == 0)
{
shifts.bank = from;
masks.bank = pow(2.0, to + 1.0) - pow(2.0, from + 0.0);
amount.bank = pow(2.0, to - from + 1.0);
}
else if (std::strcmp(child->Name(), "row") == 0)
{
shifts.row = from;
masks.row = pow(2.0, to + 1.0) - pow(2.0, from + 0.0);
amount.row = pow(2.0, to - from + 1.0);
}
else if (std::strcmp(child->Name(), "column") == 0)
{
shifts.column = from;
masks.column = pow(2.0, to + 1.0) - pow(2.0, from + 0.0);
amount.column = pow(2.0, to - from + 1.0);
}
else if (std::strcmp(child->Name(), "bytes") == 0)
{
shifts.bytes = from;
masks.bytes = pow(2.0, to + 1.0) - pow(2.0, from + 0.0);
amount.bytes = pow(2.0, to - from + 1.0);
}
else
SC_REPORT_FATAL("XmlAddressDecoder", ("Unknown field " + std::string(child->Name())).c_str());
}
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 XmlAddressDecoder::decodeAddress(uint64_t addr)
{
if (addr > maximumAddress)
SC_REPORT_WARNING("XmlAddressDecoder", ("Address " + std::to_string(addr) + " 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.rank * bankgroupsPerRank;
result.bank = ((addr & 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;
return result;
}
uint64_t XmlAddressDecoder::encodeAddress(DecodedAddress n)
{
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);
}
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()
{
std::cout << headline << std::endl;
std::cout << "Address Mapping:" << std::endl << std::endl;
std::cout << " channel: " << std::bitset<64>(masks.channel) << std::endl;
std::cout << " rank: " << std::bitset<64>(masks.rank) << std::endl;
std::cout << " bankgroup: " << std::bitset<64>(masks.bankgroup) << std::endl;
std::cout << " bank: " << std::bitset<64>(masks.bank) << std::endl;
std::cout << " row: " << std::bitset<64>(masks.row) << std::endl;
std::cout << " column: " << std::bitset<64>(masks.column) << std::endl;
std::cout << " bytes: " << std::bitset<64>(masks.bytes) << std::endl;
std::cout << std::endl;
}

View File

@@ -1,97 +0,0 @@
/*
* Copyright (c) 2015, University of Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef XMLADDRESSDECODER_H
#define XMLADDRESSDECODER_H
#include <math.h>
#include "utils.h"
#include "third_party/tinyxml2/tinyxml2.h"
#include "AddressDecoder.h"
class XmlAddressDecoder : private AddressDecoder
{
// Friendship needed so that the AddressDecoder can access the
// constructor of this class to create the object in CreateInstance.
friend class AddressDecoder;
private:
struct Masks
{
uint64_t channel = 0;
uint64_t rank = 0;
uint64_t bankgroup = 0;
uint64_t bank = 0;
uint64_t row = 0;
uint64_t column = 0;
uint64_t bytes = 0;
} masks;
struct Shifts
{
unsigned channel = 0;
unsigned rank = 0;
unsigned bankgroup = 0;
unsigned bank = 0;
unsigned row = 0;
unsigned column = 0;
unsigned bytes = 0;
} shifts;
unsigned banksPerGroup;
unsigned banksPerRank;
unsigned bankgroupsPerRank;
tinyxml2::XMLElement *addressmapping;
uint64_t maximumAddress;
public:
XmlAddressDecoder();
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();
};
#endif // XMLADDRESSDECODER_H

View File

@@ -40,7 +40,6 @@
#include "Configuration.h"
#include "ConfigurationLoader.h"
#include "../common/XmlAddressDecoder.h"
std::string Configuration::memspecUri = "";
std::string Configuration::mcconfigUri = "";
@@ -230,28 +229,13 @@ std::uint64_t Configuration::getSimMemSizeInBytes()
// The bus width is given in bits, e.g., 64-bit data bus, 128-bit data bus, etc.
unsigned int Configuration::getDataBusWidth()
{
unsigned int dataBusWidth = memSpec->bitWidth * numberOfDevicesOnDIMM;
assert(dataBusWidth > 0);
return dataBusWidth;
return memSpec->bitWidth * numberOfDevicesOnDIMM;
}
// Returns the number of bytes transfered in a burst
unsigned int Configuration::getBytesPerBurst()
{
// First multiply to get the number of bits in a burst, then divide by 8 to get the value in bytes. The order is important. Think on a single x4 device.
unsigned int bytesPerBurst = (memSpec->burstLength * getDataBusWidth()) / 8;
assert(bytesPerBurst > 0);
if (numberOfDevicesOnDIMM > 1) {
// The least significant bits of the physical address are the byte
// offset of the N-byte-wide memory module (DIMM) (a single data word
// or burst element has N bytes. N = 2^(# bits for byte offset)).
unsigned int burstElementSizeInBytes =
AddressDecoder::getInstance().amount.bytes;
assert(bytesPerBurst == (burstElementSizeInBytes * memSpec->burstLength));
}
return bytesPerBurst;
return (memSpec->burstLength * getDataBusWidth()) / 8;
}
// Changes the number of bytes depeding on the ECC Controller. This function is needed for modules which get data directly or indirectly from the ECC Controller

View File

@@ -8,7 +8,6 @@
#include "ECC/ECC.h"
#include "../common/XmlAddressDecoder.h"
#include "../common/DebugManager.h"
class ECCBaseClass : sc_module

View File

@@ -36,10 +36,13 @@
#include "errormodel.h"
#include "../common/DebugManager.h"
#include "../simulation/TemperatureController.h"
#include "../common/AddressDecoder.h"
#include "../common/dramExtensions.h"
#include <random>
#include <chrono>
#include <bitset>
#include <cmath>
void errorModel::init()
{
@@ -48,7 +51,7 @@ void errorModel::init()
// Get Configuration parameters:
burstLenght = Configuration::getInstance().memSpec->burstLength;
numberOfColumns = Configuration::getInstance().memSpec->numberOfColumns;
bytesPerColumn = AddressDecoder::getInstance().amount.bytes;
bytesPerColumn = std::log2(Configuration::getInstance().getDataBusWidth());
// Adjust number of bytes per column dynamically to the selected ecc controller
bytesPerColumn = Configuration::getInstance().adjustNumBytesAfterECC(
@@ -60,9 +63,8 @@ void errorModel::init()
// Initialize the lastRow Access array:
lastRowAccess = new sc_time[numberOfRows];
for (unsigned int i = 0; i < numberOfRows; i++) {
for (unsigned int i = 0; i < numberOfRows; i++)
lastRowAccess[i] = SC_ZERO_TIME;
}
// The name is set when the context is clear.
contextStr = "";
@@ -155,15 +157,17 @@ void errorModel::store(tlm::tlm_generic_payload &trans)
// Check wich bits have flipped during the last access and mark them as flipped:
markBitFlips();
// Get the key for the dataMap from the transaction's address:
DecodedAddress key = AddressDecoder::getInstance().decodeAddress(
trans.get_address());
// Get the key for the dataMap from the transaction's dram extension:
DramExtension &ext = DramExtension::getExtension(trans);
DecodedAddress key = DecodedAddress(ext.getChannel().ID(), ext.getRank().ID(),
ext.getBankGroup().ID(), ext.getBank().ID(),
ext.getRow().ID(), ext.getColumn().ID(), 0);
// Set context:
setContext(key);
std::stringstream msg;
msg << "bank: " << key.bank << " group: " << key.bankgroup << " bytes: " <<
key.bytes << " channel: " << key.channel << " column: " << key.column <<
key.byte << " channel: " << key.channel << " column: " << key.column <<
" rank: " << key.rank << " row: " << key.row;
PRINTDEBUGMESSAGE(name(), msg.str());
@@ -221,9 +225,11 @@ void errorModel::load(tlm::tlm_generic_payload &trans)
// Check wich bits have flipped during the last access and mark them as flipped:
markBitFlips();
// Get the key for the dataMap from the transaction's address:
DecodedAddress key = AddressDecoder::getInstance().decodeAddress(
trans.get_address());
// Get the key for the dataMap from the transaction's dram extension:
DramExtension &ext = DramExtension::getExtension(trans);
DecodedAddress key = DecodedAddress(ext.getChannel().ID(), ext.getRank().ID(),
ext.getBankGroup().ID(), ext.getBank().ID(),
ext.getRow().ID(), ext.getColumn().ID(), 0);
// Set context:
setContext(key);

View File

@@ -40,7 +40,7 @@
#include <iostream>
#include <systemc.h>
#include "../configuration/Configuration.h"
#include "../common/XmlAddressDecoder.h"
#include "../common/AddressDecoder.h"
#include "../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
class errorModel : public sc_module
@@ -113,13 +113,15 @@ private:
weakCell *weakCells;
// To use a map for storing the data a comparing function must be defined
struct DecodedAddressComparer {
bool operator()( const DecodedAddress &first ,
struct DecodedAddressComparer
{
bool operator() (const DecodedAddress &first ,
const DecodedAddress &second) const
{
uint64_t addrFirst = AddressDecoder::getInstance().encodeAddress(first);
uint64_t addrSecond = AddressDecoder::getInstance().encodeAddress(second);
return addrFirst < addrSecond;
if (first.row == second.row)
return first.column < second.column;
else
return first.row < second.row;
}
};

View File

@@ -36,10 +36,11 @@
*/
#include "Arbiter.h"
#include "../common/AddressDecoder.h"
using namespace tlm;
Arbiter::Arbiter(sc_module_name name) :
Arbiter::Arbiter(sc_module_name name, std::string pathToAddressMapping) :
sc_module(name), payloadEventQueue(this, &Arbiter::peqCallback)
{
// The arbiter communicates with one or more memory unity through one or more sockets (one or more memory channels).
@@ -60,6 +61,9 @@ Arbiter::Arbiter(sc_module_name name) :
tSocket.register_nb_transport_fw(this, &Arbiter::nb_transport_fw);
tSocket.register_transport_dbg(this, &Arbiter::transport_dbg);
addressDecoder = new AddressDecoder(pathToAddressMapping);
addressDecoder->print();
}
// Initiated by initiator side
@@ -114,8 +118,7 @@ unsigned int Arbiter::transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans)
trans.set_address(trans.get_address() -
Configuration::getInstance().addressOffset);
DecodedAddress decodedAddress = AddressDecoder::getInstance().decodeAddress(
trans.get_address());
DecodedAddress decodedAddress = addressDecoder->decodeAddress(trans.get_address());
return iSocket[decodedAddress.channel]->transport_dbg(trans);
}
@@ -213,33 +216,11 @@ void Arbiter::appendDramExtension(int socketId, tlm_generic_payload &payload)
payload.set_auto_extension(genExtension);
unsigned int burstlength = payload.get_streaming_width();
DecodedAddress decodedAddress = AddressDecoder::getInstance().decodeAddress(payload.get_address());
// Check the valid range of decodedAddress
if (addressIsValid(decodedAddress)) {
DramExtension *extension = new DramExtension(Thread(socketId),
Channel(decodedAddress.channel), Rank(decodedAddress.rank),
BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank),
Row(decodedAddress.row), Column(decodedAddress.column),
burstlength, nextPayloadID[decodedAddress.channel]++);
payload.set_auto_extension(extension);
} else {
SC_REPORT_FATAL("Arbiter", "Decoded Address is not inside the valid range");
}
}
bool Arbiter::addressIsValid(DecodedAddress &decodedAddress)
{
if (decodedAddress.channel >= AddressDecoder::getInstance().amount.channel)
return false;
if (decodedAddress.rank >= AddressDecoder::getInstance().amount.rank)
return false;
if (decodedAddress.bankgroup >= AddressDecoder::getInstance().amount.bankgroup)
return false;
if (decodedAddress.bank >= AddressDecoder::getInstance().amount.bank)
return false;
if (decodedAddress.row >= AddressDecoder::getInstance().amount.row)
return false;
if (decodedAddress.column >= AddressDecoder::getInstance().amount.column)
return false;
return true;
DecodedAddress decodedAddress = addressDecoder->decodeAddress(payload.get_address());
DramExtension *extension = new DramExtension(Thread(socketId),
Channel(decodedAddress.channel), Rank(decodedAddress.rank),
BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank),
Row(decodedAddress.row), Column(decodedAddress.column),
burstlength, nextPayloadID[decodedAddress.channel]++);
payload.set_auto_extension(extension);
}

View File

@@ -46,7 +46,7 @@
#include <tlm_utils/multi_passthrough_target_socket.h>
#include <tlm_utils/multi_passthrough_initiator_socket.h>
#include <tlm_utils/peq_with_cb_and_phase.h>
#include "../common/XmlAddressDecoder.h"
#include "../common/AddressDecoder.h"
#include "../common/dramExtensions.h"
#include "../configuration/ConfigurationLoader.h"
@@ -56,10 +56,12 @@ public:
tlm_utils::multi_passthrough_initiator_socket<Arbiter> iSocket;
tlm_utils::multi_passthrough_target_socket<Arbiter> tSocket;
Arbiter(sc_module_name);
Arbiter(sc_module_name, std::string);
SC_HAS_PROCESS(Arbiter);
private:
AddressDecoder *addressDecoder;
tlm_utils::peq_with_cb_and_phase<Arbiter> payloadEventQueue;
std::vector<bool> channelIsFree;
@@ -93,8 +95,6 @@ private:
void appendDramExtension(int socketId, tlm::tlm_generic_payload &payload);
std::vector<uint64_t> nextPayloadID;
bool addressIsValid(DecodedAddress &decodedAddress);
};
#endif // ARBITER_H

View File

@@ -44,10 +44,9 @@
#include "DRAMSys.h"
#include "Setup.h"
#include "../common/third_party/tinyxml2/tinyxml2.h"
#include "../common/TlmRecorder.h"
#include "../common/DebugManager.h"
#include "../common/XmlAddressDecoder.h"
#include "../common/CongenAddressDecoder.h"
#include "../configuration/ConfigurationLoader.h"
#include "../common/utils.h"
#include "../simulation/TemperatureController.h"
@@ -81,7 +80,6 @@ DRAMSys::DRAMSys(sc_module_name name,
std::string simconfig;
std::string thermalconfig;
// TODO: Setup never used?
Setup setup(simulationToRun,
memspec,
mcconfig,
@@ -112,25 +110,6 @@ DRAMSys::DRAMSys(sc_module_name name,
+ "configs/thermalsim/"
+ thermalconfig);
// Load addressmapping
if (XmlAddressDecoder::testConfigFile(pathToResources + "configs/amconfigs/" +
amconfig)) {
AddressDecoder::createInstance(AddressDecoder::Type::XML);
AddressDecoder::getInstance().setConfiguration(pathToResources
+ "configs/amconfigs/"
+ amconfig);
} 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. Unsupported file format");
}
AddressDecoder::getInstance().print();
// Setup the debug manager:
setupDebugManager(Configuration::getInstance().simulationName);
@@ -153,8 +132,9 @@ DRAMSys::DRAMSys(sc_module_name name,
}
}
}
// Instantiate all internal DRAMSys modules:
instantiateModules(simName, pathToResources);
instantiateModules(simName, pathToResources, amconfig);
// Connect all internal DRAMSys modules:
bindSockets();
@@ -163,8 +143,8 @@ DRAMSys::DRAMSys(sc_module_name name,
void DRAMSys::logo()
{
#define REDTXT(s) std::string("\033[0;31m"+std::string(s)+"\033[0m")
#define BOLDBLUETXT(s) std::string("\033[1;34m"+std::string(s)+"\033[0m")
#define REDTXT(s) std::string("\033[0;31m" + std::string(s) + "\033[0m")
#define BOLDBLUETXT(s) std::string("\033[1;34m" + std::string(s) + "\033[0m")
std::cout << std::endl;
std::cout << REDTXT(" |||") << std::endl;
std::cout << REDTXT(" +---+ Microelectronic Systems") << std::endl;
@@ -172,7 +152,7 @@ void DRAMSys::logo()
std::cout << REDTXT("=| |= ") << BOLDBLUETXT("University of Kaiserslautern")
<< std::endl;
std::cout << REDTXT(" +---+ ") << std::endl;
std::cout << REDTXT(" ||| ") << "DRAMSys v4.0" << std::endl;
std::cout << REDTXT(" ||| ") << "DRAMSys4.0" << std::endl;
std::cout << std::endl;
#undef REDTXT
#undef BOLDBLUETXT
@@ -180,7 +160,7 @@ void DRAMSys::logo()
void DRAMSys::setupDebugManager(const std::string &traceName __attribute__((unused)))
{
#ifdef DEBUGGING
#ifndef NDEBUG
auto &dbg = DebugManager::getInstance();
dbg.writeToConsole = false;
dbg.writeToFile = true;
@@ -219,7 +199,8 @@ void DRAMSys::setupTlmRecorders(const std::string &traceName,
}
void DRAMSys::instantiateModules(const std::string &traceName,
const std::string &pathToResources)
const std::string &pathToResources,
const std::string &amconfig)
{
// The first call to getInstance() creates the Temperature Controller.
// The same instance will be accessed by all other modules.
@@ -243,7 +224,7 @@ void DRAMSys::instantiateModules(const std::string &traceName,
Configuration::getInstance().pECC = ecc;
// Create arbiter
arbiter = new Arbiter("arbiter");
arbiter = new Arbiter("arbiter", pathToResources + "configs/amconfigs/" + amconfig);
// Create DRAM
std::string memoryType = Configuration::getInstance().memSpec->memoryType;

View File

@@ -48,7 +48,6 @@
#include "ReorderBuffer.h"
#include <tlm_utils/multi_passthrough_target_socket.h>
#include <tlm_utils/multi_passthrough_initiator_socket.h>
#include "../common/third_party/tinyxml2/tinyxml2.h"
#include "../common/tlm2_base_protocol_checker.h"
#include "../error/eccbaseclass.h"
#include "../controller/ControllerIF.h"
@@ -103,7 +102,8 @@ private:
void setupTlmRecorders(const std::string &traceName,
const std::string &pathToResources);
void instantiateModules(const std::string &traceName,
const std::string &pathToResources);
const std::string &pathToResources,
const std::string &amconfig);
void bindSockets();
void setupDebugManager(const std::string &traceName);
};

View File

@@ -1,135 +0,0 @@
/*
* Copyright (c) 2018, University of Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Felipe S. Prado
* Matthias Jung
*/
#ifndef IARBITER_H
#define IARBITER_H
#include <tlm.h>
#include <systemc.h>
#include <iostream>
#include <vector>
#include <queue>
#include <tlm_utils/multi_passthrough_target_socket.h>
#include <tlm_utils/multi_passthrough_initiator_socket.h>
#include "../configuration/ConfigurationLoader.h"
struct IArbiter : public sc_module
{
public:
tlm_utils::multi_passthrough_target_socket<IArbiter> tSocket;
tlm_utils::multi_passthrough_initiator_socket<IArbiter> iSocket;
SC_CTOR(IArbiter)
{
// One or more devices can accesss all the memory units through the arbiter.
// Devices' initiator sockets are bound to arbiter's target sockets.
// As soon the arbiter receives a request in any of its target sockets it should treat and forward it to the proper memory channel.
tSocket.register_nb_transport_fw(this, &IArbiter::nb_transport_fw);
// The arbiter communicates with one or more memory unity through one or more sockets (one or more memory channels).
// Each of the arbiter's initiator sockets is bound to a memory controller's target socket.
// Anytime an transaction comes from a memory unity to the arbiter the "bw" callback is called.
iSocket.register_nb_transport_bw(this, &IArbiter::nb_transport_bw);
tSocket.register_transport_dbg(this, &IArbiter::transport_dbg);
}
virtual void setTlmRecorder(TlmRecorder *recorder) = 0;
virtual bool isOutputBufferFull(unsigned int initiatorSocket) = 0;
virtual void incrementNumberOfOutputBufferTransactions(unsigned int
initiatorSocket) = 0;
protected:
// Initiated by initiator side
// This function is called when an arbiter's target socket receives a transaction from a device
virtual tlm::tlm_sync_enum nb_transport_fw(int id, tlm::tlm_generic_payload &payload,
tlm::tlm_phase &phase, sc_time &fwDelay) = 0;
// Initiated by dram side
// This function is called when an arbiter's initiator socket receives a transaction from a memory controller
virtual tlm::tlm_sync_enum nb_transport_bw(int channelId,
tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, sc_time &bwDelay) = 0;
virtual unsigned int transport_dbg(int /*id*/,
tlm::tlm_generic_payload &trans) = 0;
void appendDramExtension(int socketId, tlm::tlm_generic_payload &payload)
{
// Append Generation Extension
GenerationExtension *genExtension = new GenerationExtension(clkAlign(
sc_time_stamp(), Configuration::getInstance().ControllerClk));
payload.set_auto_extension(genExtension);
unsigned int burstlength = payload.get_streaming_width();
DecodedAddress decodedAddress = XmlAddressDecoder::getInstance().decodeAddress(
payload.get_address());
// 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, 0);
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;
}
};
#endif // IARBITER_H

View File

@@ -39,11 +39,14 @@
#include "../configuration/Configuration.h"
#include <iostream>
MemoryManager::MemoryManager(): numberOfAllocations(0), numberOfFrees(0) {}
using namespace tlm;
MemoryManager::MemoryManager()
: numberOfAllocations(0), numberOfFrees(0) {}
MemoryManager::~MemoryManager()
{
for (gp *payload : freePayloads) {
for (tlm_generic_payload *payload : freePayloads) {
delete[] payload->get_data_ptr();
delete payload;
numberOfFrees++;
@@ -54,11 +57,11 @@ MemoryManager::~MemoryManager()
//PRINTDEBUGMESSAGE("MemoryManager","Number of freed payloads: " + to_string(numberOfFrees));
}
gp *MemoryManager::allocate()
tlm_generic_payload *MemoryManager::allocate()
{
if (freePayloads.empty()) {
numberOfAllocations++;
gp *payload = new gp(this);
tlm_generic_payload *payload = new tlm_generic_payload(this);
// Allocate a data buffer and initialize it with zeroes:
unsigned int dataLength = Configuration::getInstance().getBytesPerBurst();
@@ -68,13 +71,13 @@ gp *MemoryManager::allocate()
payload->set_data_ptr(data);
return payload;
} else {
gp *result = freePayloads.back();
tlm_generic_payload *result = freePayloads.back();
freePayloads.pop_back();
return result;
}
}
void MemoryManager::free(gp *payload)
void MemoryManager::free(tlm_generic_payload *payload)
{
payload->reset(); // clears all extensions
freePayloads.push_back(payload);

View File

@@ -39,20 +39,19 @@
#include <tlm.h>
#include <vector>
typedef tlm::tlm_generic_payload gp;
class MemoryManager : public tlm::tlm_mm_interface
{
public:
MemoryManager();
virtual ~MemoryManager();
virtual gp *allocate();
virtual void free(gp *payload);
virtual tlm::tlm_generic_payload *allocate();
virtual void free(tlm::tlm_generic_payload *payload);
private:
unsigned int numberOfAllocations;
unsigned int numberOfFrees;
std::vector<gp *> freePayloads;
std::vector<tlm::tlm_generic_payload *> freePayloads;
};
#endif // MEMORYMANAGER_H

View File

@@ -1,137 +0,0 @@
/*
* Copyright (c) 2018, University of Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Felipe S. Prado
* Matthias Jung
*/
#ifndef SIMPLEARBITER_H
#define SIMPLEARBITER_H
#include "IArbiter.h"
#include "../common/XmlAddressDecoder.h"
#include "../common/dramExtensions.h"
// Annotated References [X,Y] --> Please refer to TLM AT Cheat Sheet on README
struct SimpleArbiter: public IArbiter {
public:
SimpleArbiter(sc_module_name name) : IArbiter(name)
{
}
void setTlmRecorder(TlmRecorder *recorder)
{
tlmRecorder = recorder;
}
virtual bool isOutputBufferFull(unsigned int /*initiatorSocket*/)
{
return false;
}
virtual void incrementNumberOfOutputBufferTransactions(unsigned
int /*initiatorSocket*/)
{
}
protected:
TlmRecorder *tlmRecorder;
// Initiated by initiator side
// This function is called when an arbiter's target socket receives a transaction from a device
virtual tlm::tlm_sync_enum nb_transport_fw(int id, tlm::tlm_generic_payload &payload,
tlm::tlm_phase &phase, sc_time &fwDelay)
{
if (phase == BEGIN_REQ) {
payload.acquire();
// adjust address offset, e.g. for gem5 simulation
payload.set_address(payload.get_address() -
Configuration::getInstance().AddressOffset);
// 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);
tlmRecorder->recordArbiterPhase(payload, phase, sc_time_stamp() + fwDelay);
tlmRecorder->recordArbiterPhase(payload, END_REQ, sc_time_stamp() + fwDelay);
tlmRecorder->recordPhase(payload, phase, sc_time_stamp() + fwDelay);
// Forward Path [1.0]
iSocket[getISocketIndex(payload)]->nb_transport_fw(payload, phase, fwDelay);
} else if (phase == END_RESP) {
payload.release();
tlmRecorder->recordArbiterPhase(payload, phase, sc_time_stamp() + fwDelay);
} else {
SC_REPORT_FATAL("Arbiter", "Illegal phase received by initiator");
}
// 4-Phase Handshake [1.1]
// 4-Phase Handshake [1.7]
return tlm::TLM_ACCEPTED;
}
// Initiated by dram side
// This function is called when an arbiter's initiator socket receives a transaction from a memory controller
virtual tlm::tlm_sync_enum nb_transport_bw(int /*channelId*/,
tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, sc_time &bwDelay)
{
tlmRecorder->recordPhase(payload, phase, bwDelay + sc_time_stamp());
tSocket[DramExtension::getThread(payload).ID()]->nb_transport_bw(payload,
TPhase, bwDelay);
if (phase == BEGIN_RESP) {
// Early Completion [3.1]
tlmRecorder->recordPhase(payload, END_RESP, bwDelay + sc_time_stamp());
tlmRecorder->recordArbiterPhase(payload, BEGIN_RESP, sc_time_stamp() + bwDelay);
return tlm::TLM_COMPLETED;
}
// 4-Phase Handshake [1.3]
return tlm::TLM_ACCEPTED;
}
virtual unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans)
{
// adjust address offset:
trans.set_address(trans.get_address() -
Configuration::getInstance().AddressOffset);
return iSocket[getISocketIndex(trans)]->transport_dbg(trans);
}
virtual unsigned int getISocketIndex(tlm::tlm_generic_payload &payload)
{
return DramExtension::getBank(payload).ID();
}
};
#endif // SIMPLEARBITER_H

View File

@@ -40,7 +40,7 @@
#ifndef STLPLAYER_H
#define STLPLAYER_H
#include "../common/XmlAddressDecoder.h"
#include <sstream>
#include "TracePlayer.h"
template<bool relative>
@@ -83,7 +83,7 @@ public:
numberOfTransactions++;
}
// Allocate a generic payload for this request.
gp *payload = this->allocatePayload();
tlm::tlm_generic_payload *payload = this->allocatePayload();
payload->acquire();
unsigned char *data = payload->get_data_ptr();
@@ -126,8 +126,8 @@ public:
iss >> address;
if (address.empty())
SC_REPORT_FATAL("StlPlayer",
("Malformed trace file. Address could not be found (line " + std::to_string(
lineCnt) + ").").c_str());
("Malformed trace file. Address could not be found (line "
+ std::to_string(lineCnt) + ").").c_str());
unsigned long long addr = std::stoull(address.c_str(), 0, 16);
// Get the data if necessary.

View File

@@ -60,7 +60,7 @@ public:
this->terminate();
}
gp *payload = this->allocatePayload();
tlm::tlm_generic_payload *payload = this->allocatePayload();
payload->acquire();
unsigned char *dataElement = new unsigned
char[16]; // TODO: column / burst breite

View File

@@ -47,11 +47,13 @@ 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;
}
gp *TracePlayer::allocatePayload()
tlm_generic_payload *TracePlayer::allocatePayload()
{
return memoryManager.allocate();
}

View File

@@ -49,7 +49,6 @@
#include "MemoryManager.h"
#include "../configuration/Configuration.h"
#include "../common/DebugManager.h"
#include "../common/XmlAddressDecoder.h"
#include "TracePlayerListener.h"
struct TracePlayer : public sc_module
@@ -61,13 +60,13 @@ public:
unsigned int getNumberOfLines(std::string pathToTrace);
protected:
gp *allocatePayload();
tlm::tlm_generic_payload *allocatePayload();
tlm_utils::peq_with_cb_and_phase<TracePlayer> payloadEventQueue;
void finish();
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,

View File

@@ -157,7 +157,15 @@ DramWideIO::DramWideIO(sc_module_name name) : Dram(name)
else
{
if (storeMode == StorageMode::ErrorModel)
SC_REPORT_FATAL("DramWideIO", "Error modeling without power analysis is not supported");
{
for (unsigned i = 0; i < memSpec->numberOfBanks; i++)
{
errorModel *em;
std::string errorModelStr = "errorModel_bank" + std::to_string(i);
em = new errorModel(errorModelStr.c_str());
ememory.push_back(em);
}
}
}
}