Almost everyhing is integrated now:

* File Parsing
  * Initialisation
  * Load
  * Store

The only thing that is missing is the bit flip procedure in an
activate/refresh.
This commit is contained in:
Matthias Jung
2015-07-31 23:34:29 +02:00
parent 8fa9083676
commit 91e6ecd714
3 changed files with 242 additions and 14 deletions

View File

@@ -37,7 +37,7 @@
#include <random>
#include <chrono>
errorModel::errorModel()
errorModel::errorModel(const char * name)
{
// Get Configuration parameters:
busWidth = Configuration::getInstance().Buswidth;
@@ -53,8 +53,12 @@ errorModel::errorModel()
lastRowAccess[i] = SC_ZERO_TIME;
}
// Set name of parent component
this->name = name;
// Parse data input:
parseInputData();
prepareWeakCells();
}
errorModel::~errorModel()
@@ -72,6 +76,9 @@ errorModel::~errorModel()
// Clean errorMap
errorMap.clear();
// Clean list of weak cells:
delete [] weakCells;
}
void errorModel::store(tlm::tlm_generic_payload &trans)
@@ -104,17 +111,28 @@ void errorModel::store(tlm::tlm_generic_payload &trans)
// Save part of the burst in the dataMap
dataMap.insert(std::pair<DecodedAddress, unsigned char*>(key,data));
// Reset flipped weak cells in this area, since they are rewritten now
for(unsigned int i = 0; i < maxNumberOfWeakCells; i++)
{
// If the current written column in a row has a week cell:
if(weakCells[i].row == key.row && weakCells[i].col == key.column)
{
// If the bit was marked as flipped due to a retention error
// mark it as unflipped:
if(weakCells[i].flipped == true)
{
weakCells[i].flipped = false;
}
}
}
// The next burst element is handled, therfore the column address must be increased
key.column++;
// Check that there is no column overfow:
assert(key.column <= numberOfColumns);
// Reset flipped weak cells in this area, since they are rewritten now
// TODO
}
//trans.set_response_status(TLM_OK_RESPONSE);
}
void errorModel::load(tlm::tlm_generic_payload &trans)
@@ -167,7 +185,7 @@ void errorModel::parseInputData()
std::string fileName = Configuration::getInstance().ErrorCSVFile;
std::ifstream inputFile(fileName);
std::cout << "Parsing Error File: " << fileName << std::endl;
std::cout << std::endl << name <<", Parsing Error File: " << fileName << std::endl;
if(inputFile.is_open())
{
@@ -190,7 +208,7 @@ void errorModel::parseInputData()
>> str_mu_dependent
>> str_sigma_dependent;
unsigned int temperature = std::stoi(str_temperature.c_str(), 0, 10);
double temperature = std::stod(str_temperature.c_str(), 0);
sc_time retentionTime = sc_time(std::stod(str_retentionTime.c_str(),0),SC_MS);
unsigned int mu_independent = std::stod(str_mu_independent.c_str(),0);
@@ -221,12 +239,200 @@ void errorModel::parseInputData()
<< " dependent = " << errorMap[temperature][retentionTime].dependent
<< std::endl;
}
inputFile.close();
// Get the
std::cout << std::endl;
inputFile.close();
}
else
{
SC_REPORT_FATAL("errormodel","Cannot open ErrorCSVFile");
}
}
void errorModel::prepareWeakCells()
{
// Get the Maxium number of weak cells by iterating over the errorMap:
maxNumberOfWeakCells = 0;
maxNumberOfDepWeakCells = 0;
for( const auto &i : errorMap )
{
for( const auto &j : i.second )
{
// Get number of dependent weak cells:
if( j.second.dependent > maxNumberOfDepWeakCells)
{
maxNumberOfDepWeakCells = j.second.dependent;
}
// Get the total number of weak cells (independet + dependent):
if( j.second.independent + j.second.dependent > maxNumberOfWeakCells)
{
maxNumberOfWeakCells = j.second.independent + j.second.dependent;
}
}
}
// Get the highest temperature in the error map:
maxTemperature = 0;
for( const auto &i : errorMap )
{
if(i.first > maxTemperature)
{
maxTemperature = i.first;
}
}
// Get the highest time in the error map:
maxTime = SC_ZERO_TIME;
for( const auto &i : errorMap )
{
for( const auto &j : i.second )
{
if(j.first > maxTime)
{
maxTime = j.first;
}
}
}
// Generate weak cells:
weakCells = new weakCell[maxNumberOfWeakCells];
for (unsigned int i=0; i<maxNumberOfWeakCells; i++)
{
unsigned int row, col, bit;
// Select positions of weak cells randomly, uniformly distributed:
row = (unsigned int) (rand() % numberOfRows);
col = (unsigned int) (rand() % numberOfColumns);
bit = (unsigned int) (rand() % (bytesPerColumn*8));
// Test if weak cell has been chosen already before:
bool found = false;
for (unsigned int k=0; k<i; k++)
{
if ((weakCells[k].row==row) && (weakCells[k].col==col) && (weakCells[k].bit==bit))
{
found = true;
break;
}
}
// If a cell was already choosen as weak we have to roll the dice again:
if(found == true) {
i--;
}
else
{
weakCells[i].row = row; // Row in the bank
weakCells[i].col = col; // Column in the row
weakCells[i].bit = bit; // Bit position in column
weakCells[i].flipped = false; // Flag whether this position has already flipped
weakCells[i].dependent = false; // init dependency flag with false, dependent cells will be estimated in the next step
}
}
// Generate dependent weak cells:
for (unsigned int i = 1; i <= maxNumberOfDepWeakCells; i++)
{
unsigned int r = (rand()%maxNumberOfWeakCells);
// If the dependent weak cell was choosen before roll the dice again:
if(weakCells[r].dependent == true)
{
i--;
}
else
{
weakCells[r].dependent = true;
}
}
// Debug output where the weak cells are located:
for (unsigned int i=0; i<maxNumberOfWeakCells; i++)
{
std::cout << "row=" << weakCells[i].row
<< "\tcol=" << weakCells[i].col
<< "\tbit=" << weakCells[i].bit
<< "\tflip=" << weakCells[i].flipped
<< "\tdep=" << weakCells[i].dependent << std::endl;
}
// Test:
// If you want to test the function that get the number
// of bit errors for a given temperature and time
// uncomment the following lines:
//
//std::cout << "MAXTemp:" << maxTemperature << std::endl;
//std::cout << "MAXTime:" << maxTime << std::endl;
//getNumberOfFlips(45.0,sc_time(200.0,SC_MS));
//getNumberOfFlips(45.0,sc_time(190.0,SC_MS));
//getNumberOfFlips(45.0,sc_time(180.0,SC_MS));
//getNumberOfFlips(75.0,sc_time(200.0,SC_MS));
//getNumberOfFlips(75.0,sc_time(190.0,SC_MS));
//getNumberOfFlips(75.0,sc_time(180.0,SC_MS));
//getNumberOfFlips(85.0,sc_time(200.0,SC_MS));
//getNumberOfFlips(85.0,sc_time(190.0,SC_MS));
//getNumberOfFlips(85.0,sc_time(180.0,SC_MS));
//getNumberOfFlips(88.0,sc_time(200.0,SC_MS));
//getNumberOfFlips(88.0,sc_time(190.0,SC_MS));
//getNumberOfFlips(88.0,sc_time(180.0,SC_MS));
//getNumberOfFlips(89.0,sc_time(64.0,SC_MS));
//getNumberOfFlips(89.0,sc_time(64.0,SC_MS));
//getNumberOfFlips(89.0,sc_time(64.0,SC_MS));
}
// Retrieve number of flipping bits which fits best to temperature input and time since last refresh
unsigned int errorModel::getNumberOfFlips(double temp, sc_time time)
{
// Check if the provided temperature and time are in a valid range that
// is covered by the input data stored in the errorMap:
if(temp > maxTemperature)
{
SC_REPORT_FATAL("errormodel","temperature out of range");
}
else if(time > maxTime)
{
SC_REPORT_FATAL("errormodel","time out of range");
}
else
{
// Find nearest temperature:
double nearestTemperature = 0;
for( const auto &i : errorMap )
{
if(i.first >= temp) // for worst case reasons we go to the next bin
{
nearestTemperature = i.first;
break;
}
}
// Find nearest time:
sc_time nearestTime;
for( const auto &i : errorMap[nearestTemperature])
{
if(i.first >= time) // for worst case reasons we go to the next bin
{
nearestTime = i.first;
break;
}
}
errors e = errorMap[nearestTemperature][nearestTime];
// Find nearest time:
std::cout << "XXX temp:" << temp
<< " time:" << time
<< " nearestTemp:" << nearestTemperature
<< " nearestTime:" << nearestTime
<< " ind:" << e.independent
<< " dep:" << e.dependent << std::endl;
return e.independent + e.dependent;
}
}

View File

@@ -43,7 +43,7 @@
class errorModel
{
public:
errorModel();
errorModel(const char * name);
~errorModel();
// Access Methods:
@@ -52,6 +52,7 @@ class errorModel
void refresh(unsigned int row);
void activate(unsigned int row);
void setTemperature(double t);
unsigned int getNumberOfFlips(double temp, sc_time time);
private:
// Configuration Parameters:
@@ -61,11 +62,15 @@ class errorModel
unsigned int bytesPerColumn;
unsigned int numberOfRows;
// Name:
std::string name;
// Online Parameters:
double temperature;
// Input data related things:
void parseInputData();
void prepareWeakCells();
struct errors
{
@@ -73,7 +78,26 @@ class errorModel
double dependent;
};
std::map<unsigned int, std::map<sc_time, errors> > errorMap;
// temperature time number of errors
// | | |
std::map<double, std::map<sc_time, errors> > errorMap;
unsigned int maxNumberOfWeakCells;
unsigned int maxNumberOfDepWeakCells;
double maxTemperature;
sc_time maxTime;
// Storage of weak cells:
struct weakCell
{
unsigned int row;
unsigned int col;
unsigned int bit;
bool flipped;
bool dependent;
};
weakCell * weakCells;
// To use a map for storing the data a comparing function must be defined
struct DecodedAddressComparer

View File

@@ -69,7 +69,7 @@ struct Dram : sc_module
// Error Model related:
ErrorStorageMode ErrorStoreMode = Configuration::getInstance().ErrorStoreMode;
errorModel ememory;
errorModel ememory = errorModel(name());
// Data Storage:
map< unsigned long int, unsigned char[BUSWIDTH/2] > memory;
@@ -180,8 +180,6 @@ struct Dram : sc_module
{
//cout << "BIT_ERRORS Bank: " <<b <<"="<< fmemory[b].BIT_ERR << endl;
}
// TODO Aufrauemen!
//delete fmemory; // TODO Testen!
//std::cout << "Simulated Memory Size: " << memory.size() << endl; // TODO Aufrauemen
}