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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user