included errormodel which is presented in DATE paper
This commit is contained in:
@@ -68,7 +68,9 @@ SOURCES += \
|
||||
../src/simulation/main.cpp \
|
||||
../src/controller/core/RowBufferStates.cpp \
|
||||
../src/controller/scheduler/Scheduler.cpp \
|
||||
../src/controller/scheduler/readwritegrouper.cpp
|
||||
../src/controller/scheduler/readwritegrouper.cpp \
|
||||
../src/error/nest_map.cpp \
|
||||
../src/error/flip_memory.cpp
|
||||
|
||||
HEADERS += \
|
||||
../src/common/third_party/tinyxml2.h \
|
||||
@@ -123,5 +125,7 @@ HEADERS += \
|
||||
../src/controller/core/RowBufferStates.h \
|
||||
../src/controller/scheduler/readwritegrouper.h \
|
||||
../src/simulation/ReorderBuffer.h \
|
||||
../src/controller/core/configuration/MemSpec.h
|
||||
../src/controller/core/configuration/MemSpec.h \
|
||||
../src/error/nest_map.h \
|
||||
../src/error/flip_memory.h
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
</addressmap>
|
||||
</dramconfig>
|
||||
-->
|
||||
<!--
|
||||
<dramconfig>
|
||||
<addressmap>
|
||||
<channel from="27" to="28" />
|
||||
@@ -19,3 +20,13 @@
|
||||
<bytes from="0" to="3" />
|
||||
</addressmap>
|
||||
</dramconfig>
|
||||
-->
|
||||
<dramconfig>
|
||||
<addressmap>
|
||||
<channel from="27" to="28" />
|
||||
<bank from="24" to="26" />
|
||||
<row from="11" to="23" />
|
||||
<column from="4" to="10" />
|
||||
<bytes from="0" to="3" />
|
||||
</addressmap>
|
||||
</dramconfig>
|
||||
|
||||
@@ -7,8 +7,11 @@
|
||||
<parameter id="maxNrOfTransactionsInDram" type="uint" value="50" />
|
||||
<parameter id="scheduler" type="string" value="FR_FCFS" />
|
||||
<parameter id="capsize" type="uint" value="5" />
|
||||
<parameter id="powerDownMode" type="string" value="Staggered" />
|
||||
<parameter id="powerDownTimeout" type="uint" value="100" />
|
||||
<parameter id="databaseRecordingEnabled" type="bool" value="1" />
|
||||
<parameter id="powerDownMode" type="string" value="TimeoutPDN" />
|
||||
<parameter id="powerDownTimeout" type="uint" value="9999999999999" />
|
||||
<parameter id="databaseRecordingEnabled" type="bool" value="0" />
|
||||
<parameter id="Chipseed" type="uint" value="42" />
|
||||
<parameter id="csvfile" type="string" value="/home/ehses/projects/dram.vp.system/dram/src/error/error_new.csv" />
|
||||
<parameter id="StorMo" type="uint" value="0"/><!--3 Modes: 0 no storage, 1 store data without errormodel, 2 store data with errormodel-->
|
||||
</memconfig>
|
||||
</memspec>
|
||||
|
||||
@@ -40,3 +40,14 @@ DecodedAddress xmlAddressDecoder::decodeAddress(sc_dt::uint64 addr)
|
||||
result.bytes = (addr & masks["bytes"]) >> shifts["bytes"];
|
||||
return result;
|
||||
}
|
||||
|
||||
sc_dt::uint64 xmlAddressDecoder::encodeAddress(DecodedAddress n)
|
||||
{
|
||||
return n.channel << shifts["channel"] |
|
||||
n.rank << shifts["rank"] |
|
||||
n.bankgroup << shifts["bankgroup"] |
|
||||
n.row << shifts["row"] |
|
||||
n.bank << shifts["bank"] |
|
||||
n.column << shifts["column"] |
|
||||
n.bytes << shifts["bytes"];
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@ public:
|
||||
}
|
||||
|
||||
DecodedAddress decodeAddress(sc_dt::uint64 addr);
|
||||
sc_dt::uint64 encodeAddress(DecodedAddress n);
|
||||
|
||||
|
||||
private:
|
||||
xmlAddressDecoder(std::string URI);
|
||||
|
||||
@@ -46,6 +46,11 @@ struct Configuration
|
||||
//Simulation Configuration
|
||||
bool databaseRecordingEnabled = true;
|
||||
|
||||
//Configs for Seed, csv file and StorageMode
|
||||
unsigned int Chipseed;
|
||||
std::string csvfile ="not defined.";
|
||||
unsigned int StorMode;
|
||||
|
||||
private:
|
||||
Configuration();
|
||||
};
|
||||
|
||||
@@ -51,6 +51,7 @@ struct MemSpec
|
||||
unsigned int nActivate;
|
||||
unsigned int DataRate;
|
||||
unsigned int NumberOfRows;
|
||||
unsigned int NumberOfColumns;
|
||||
|
||||
sc_time clk;
|
||||
sc_time tRP; //precharge-time (pre -> act same bank)
|
||||
|
||||
@@ -56,6 +56,12 @@ void MemSpecLoader::loadMemConfig(Configuration& config, XMLElement* memconfig)
|
||||
config.powerDownTimeout = queryUIntParameter(configuration, "powerDownTimeout") * config.memSpec.clk;
|
||||
|
||||
config.databaseRecordingEnabled = queryBoolParameter(configuration, "databaseRecordingEnabled");
|
||||
|
||||
//Specification for Chipseed, csvfile path and StorageMode
|
||||
config.Chipseed = queryUIntParameter(configuration, "Chipseed");
|
||||
config.csvfile = queryStringParameter(configuration, "csvfile");
|
||||
config.StorMode = queryUIntParameter(configuration, "StorMo");
|
||||
|
||||
}
|
||||
|
||||
void MemSpecLoader::loadMemSpec(Configuration& config, XMLElement* memspec)
|
||||
@@ -88,6 +94,7 @@ void MemSpecLoader::loadDDR4(Configuration& config, XMLElement* memspec)
|
||||
config.memSpec.nActivate = 4;
|
||||
config.memSpec.DataRate = queryUIntParameter(architecture, "dataRate");
|
||||
config.memSpec.NumberOfRows = queryUIntParameter(architecture, "nbrOfRows");
|
||||
config.memSpec.NumberOfColumns = queryUIntParameter(architecture, "nbrOfColumns");
|
||||
|
||||
//MemTimings
|
||||
XMLElement* timings = memspec->FirstChildElement("memtimingspec");
|
||||
@@ -137,6 +144,7 @@ void MemSpecLoader::loadWideIO(Configuration& config, XMLElement* memspec)
|
||||
config.memSpec.nActivate = 2;
|
||||
config.memSpec.DataRate = queryUIntParameter(architecture, "dataRate");
|
||||
config.memSpec.NumberOfRows = queryUIntParameter(architecture, "nbrOfRows");
|
||||
config.memSpec.NumberOfColumns = queryUIntParameter(architecture, "nbrOfColumns");
|
||||
|
||||
//MemTimings
|
||||
XMLElement* timings = memspec->FirstChildElement("memtimingspec");
|
||||
|
||||
20
dram/src/error/error_new.csv
Normal file
20
dram/src/error/error_new.csv
Normal file
@@ -0,0 +1,20 @@
|
||||
75,127,0,0,0,0
|
||||
80,127,0,0,0,0
|
||||
85,127,0,0,0,0
|
||||
89,127,2,0.03,2,0.06
|
||||
75,145,0,0,0,0
|
||||
80,145,0,0,0,0
|
||||
85,145,0,0,1,0.03
|
||||
89,145,13,0.195,3,0.09
|
||||
75,164,0,0,0,0
|
||||
80,164,0,0,0,0
|
||||
85,164,8,0.12,2,0.06
|
||||
89,164,24,0.36,4,0.12
|
||||
75,182,0,0,0,0
|
||||
80,182,0,0,1,0.03
|
||||
85,182,16,0.24,2,0.06
|
||||
89,182,41,0.615,8,0.24
|
||||
75,200,0,0,0,0
|
||||
80,200,5,0.075,3,0.09
|
||||
85,200,24,0.36,4,0.12
|
||||
89,200,67,1.005,15,0.45
|
||||
|
@@ -1,133 +1,200 @@
|
||||
/*
|
||||
* Created on: Juli, 2014
|
||||
* Author: patrick, peter
|
||||
*/
|
||||
|
||||
#include "flip_memory.h"
|
||||
#include <time.h>
|
||||
// Console out
|
||||
#include <iostream>
|
||||
|
||||
#include <random>
|
||||
// String conversion (debugging)
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <chrono>
|
||||
|
||||
#include "../common/third_party/DRAMPower/src/MemorySpecification.h"
|
||||
#include "../common/third_party/DRAMPower/src/MemCommand.h"
|
||||
#include "../controller/core/configuration/Configuration.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace core;
|
||||
|
||||
flip_memory::flip_memory() {
|
||||
void flip_memory::setBank(unsigned int b)
|
||||
{
|
||||
accordingBank = b;
|
||||
}
|
||||
|
||||
flip_memory::flip_memory()
|
||||
{
|
||||
// Initialize Random generator with current system time
|
||||
// Only do this once in a simulation
|
||||
srand(time(NULL));
|
||||
|
||||
// Fixed values for development process
|
||||
//srand(time(NULL));
|
||||
srand(Configuration::getInstance().Chipseed); // Chipseed constant, so that errors allways at the same address
|
||||
|
||||
// Fixed values for development process
|
||||
TEMPERATURE = 90;
|
||||
|
||||
|
||||
// Initialize number of bit errors
|
||||
BIT_ERR = 0;
|
||||
|
||||
errormap = new nest_map("errors.csv");
|
||||
xade = new xmlAddressDecoder("config.xml");
|
||||
|
||||
|
||||
// path of csv file
|
||||
errormap = new nest_map(Configuration::getInstance().csvfile);
|
||||
//xade = new xmlAddressDecoder("config.xml");
|
||||
|
||||
// Constants for address calculations
|
||||
ROWS_PER_BANK = xade->getRowSize();
|
||||
COLS_PER_ROW = xade->getColumSize();
|
||||
BYTES_PER_COL = xade->getBytesSize();
|
||||
ROWS_PER_BANK = Configuration::getInstance().memSpec.NumberOfRows; //8192
|
||||
COLS_PER_ROW = Configuration::getInstance().memSpec.NumberOfColumns; //changed later to variable 128
|
||||
BYTES_PER_COL = 16; //changed later to variable, wie genau, mit config file oder im programm selbst
|
||||
BITS_PER_ROW = COLS_PER_ROW * BYTES_PER_COL * 8;
|
||||
|
||||
// Fill array with random addresses
|
||||
|
||||
// Fill array with random addresses
|
||||
initWeakCells();
|
||||
}
|
||||
|
||||
flip_memory::~flip_memory() {
|
||||
flip_memory::~flip_memory()
|
||||
{
|
||||
cout << endl << endl << endl << "Bit-Fehler: " << BIT_ERR << endl << endl << endl;
|
||||
}
|
||||
|
||||
void flip_memory::getUnifiedNode(unsigned int addr, node *n) {
|
||||
xade->getNode(addr, n);
|
||||
n->channel = 0;
|
||||
n->bank = 0;
|
||||
DecodedAddress flip_memory::getUnifiedNode(unsigned int addr)
|
||||
{
|
||||
DecodedAddress n = xmlAddressDecoder::getInstance().decodeAddress(addr);
|
||||
//xade->getNode(addr, n);
|
||||
n.channel = 0;
|
||||
n.bank = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
// Decide which Cells will be weak cells
|
||||
void flip_memory::initWeakCells() {
|
||||
unsigned int maxWeakCells = errormap->getMaxWeakCells();
|
||||
weakCells = new unsigned int*[maxWeakCells];
|
||||
|
||||
for (unsigned int i=0; i<maxWeakCells; i++) {
|
||||
unsigned int row, col, bit;
|
||||
weakCells[i] = new unsigned int[4];
|
||||
|
||||
row = (unsigned int) (rand() % ROWS_PER_BANK);
|
||||
col = (unsigned int) (rand() % COLS_PER_ROW);
|
||||
bit = (unsigned int) (rand() % (BYTES_PER_COL*8));
|
||||
void flip_memory::initWeakCells()
|
||||
{
|
||||
unsigned int maxWeakCells = errormap->getMaxWeakCells();
|
||||
|
||||
weakCells = new unsigned int*[maxWeakCells];
|
||||
|
||||
for (unsigned int i=0; i<maxWeakCells; i++)
|
||||
{
|
||||
unsigned int row, col, bit;
|
||||
|
||||
weakCells[i] = new unsigned int[4];
|
||||
|
||||
row = (unsigned int) (rand() % ROWS_PER_BANK);
|
||||
col = (unsigned int) (rand() % COLS_PER_ROW);
|
||||
bit = (unsigned int) (rand() % (BYTES_PER_COL*8));
|
||||
|
||||
cout << "row" << row << "\t col" << col << "\t bit" << bit << endl;
|
||||
|
||||
// Avoid duplicates in weakCells[]
|
||||
bool found = false;
|
||||
|
||||
for (unsigned int k=0; k<i; k++) {
|
||||
if ((weakCells[k][0]==row) && (weakCells[k][1]==col) && (weakCells[k][2]==bit)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(found == true) {
|
||||
i--;
|
||||
}
|
||||
else
|
||||
{
|
||||
weakCells[i][0] = row;
|
||||
weakCells[i][1] = col;
|
||||
weakCells[i][2] = bit; // Bit position in column
|
||||
weakCells[i][3] = 0; // Flag whether this position has already flipped
|
||||
weakCells[i][4] = 0; // init dependency flag
|
||||
}
|
||||
//cout << i << ". weak cell, at row: " << weakCells[i][0] << " and column: " << weakCells[i][1] << " and bit: " << weakCells[i][2] << endl;
|
||||
}
|
||||
|
||||
for (unsigned int i = 1; i <= errormap->getMaxDependentCells(); i++)
|
||||
{
|
||||
unsigned int r = (rand()%maxWeakCells);
|
||||
|
||||
if(weakCells[r][4] == 1)
|
||||
{
|
||||
i--;
|
||||
}
|
||||
else
|
||||
{
|
||||
weakCells[r][4] = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Debug
|
||||
for (unsigned int i=0; i<maxWeakCells; i++)
|
||||
{
|
||||
cout << "row=" << weakCells[i][0];
|
||||
cout << "\tcol=" << weakCells[i][1];
|
||||
cout << "\tbit=" << weakCells[i][2];
|
||||
cout << "\tflip=" << weakCells[i][3];
|
||||
cout << "\tdep=" << weakCells[i][4] << endl;
|
||||
}
|
||||
|
||||
// Avoid duplicates in weakCells[]
|
||||
bool found = false;
|
||||
|
||||
for (unsigned int k=0; k<i; k++) {
|
||||
if ((weakCells[k][0]==row) && (weakCells[k][1]==col) && (weakCells[k][2]==bit)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(found == true) {
|
||||
i--;
|
||||
}
|
||||
else
|
||||
{
|
||||
weakCells[i][0] = row;
|
||||
weakCells[i][1] = col;
|
||||
weakCells[i][2] = bit; // Bit position in column
|
||||
weakCells[i][3] = 0; // Flag whether this position has already flipped
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Reset "HasFlipped"-Flag, set Refresh-Timestamp
|
||||
void flip_memory::resetCell(node n) {
|
||||
unsigned int arraySize = errormap->getMaxWeakCells();
|
||||
|
||||
for (unsigned int i=0; i<arraySize; i++) {
|
||||
if ((weakCells[i][0] == n.row) && (weakCells[i][1] == n.colum)) weakCells[i][3] = 0;
|
||||
}
|
||||
void flip_memory::resetCell(DecodedAddress n)
|
||||
{
|
||||
unsigned int arraySize = errormap->getMaxWeakCells();
|
||||
|
||||
refr[n.row] = sc_time_stamp();
|
||||
for (unsigned int i=0; i<arraySize; i++)
|
||||
{
|
||||
if ((weakCells[i][0] == n.row) && (weakCells[i][1] == n.column)) weakCells[i][3] = 0;
|
||||
}
|
||||
|
||||
refr[n.row] = sc_time_stamp();
|
||||
}
|
||||
|
||||
|
||||
// Store data in memory
|
||||
void flip_memory::store(tlm_generic_payload &trans) {
|
||||
void flip_memory::store(tlm::tlm_generic_payload &trans)
|
||||
{
|
||||
unsigned int t_addr, t_len;
|
||||
unsigned char* t_ptr;
|
||||
|
||||
t_addr = trans.get_address();
|
||||
t_len = trans.get_data_length();
|
||||
t_ptr = trans.get_data_ptr();
|
||||
|
||||
t_ptr = trans.get_data_ptr();
|
||||
|
||||
// Generate XML Node
|
||||
node no;
|
||||
getUnifiedNode(t_addr, &no);
|
||||
|
||||
for (unsigned int i = 0; i < t_len; i+=BYTES_PER_COL) {
|
||||
DecodedAddress no;
|
||||
no = getUnifiedNode(t_addr);
|
||||
|
||||
for (unsigned int i = 0; i < t_len; i+=BYTES_PER_COL)
|
||||
{
|
||||
// Store data in vector of size BYTES_PER_COL temporarily, later write to mem
|
||||
vector<unsigned char> v;
|
||||
for (unsigned int n = 0; n < BYTES_PER_COL; n++) v.push_back(*(t_ptr + i + n));
|
||||
|
||||
|
||||
// Switch to next column if necessary
|
||||
if (i > 0) no.colum++;
|
||||
if (i > 0) no.column++;
|
||||
|
||||
// Swap around if more columns addressed than exist
|
||||
if (no.colum>(COLS_PER_ROW - 1)) no.colum -= BURSTLENGTH*BYTES_PER_COL;
|
||||
if (no.column>(COLS_PER_ROW - 1)) no.column -= BURSTLENGTH*BYTES_PER_COL;
|
||||
|
||||
unsigned int addr = xade->getAddress(&no);
|
||||
unsigned int addr = xmlAddressDecoder::getInstance().encodeAddress(no);
|
||||
//cout << "ADDRESSE=" << addr << endl;
|
||||
|
||||
mem.insert(pair<unsigned int, vector<unsigned char> >(addr, v));
|
||||
|
||||
|
||||
// Reset weak cells; they have reliable data now till next check
|
||||
resetCell(no);
|
||||
}
|
||||
|
||||
|
||||
//cout << "STORE:" << endl;
|
||||
//debugMap();
|
||||
|
||||
trans.set_response_status(TLM_OK_RESPONSE);
|
||||
}
|
||||
|
||||
|
||||
void flip_memory::load(tlm_generic_payload &trans) {
|
||||
void flip_memory::load(tlm::tlm_generic_payload &trans)
|
||||
{
|
||||
unsigned int t_addr, t_len;
|
||||
unsigned char* t_ptr;
|
||||
|
||||
@@ -136,20 +203,21 @@ void flip_memory::load(tlm_generic_payload &trans) {
|
||||
t_ptr = trans.get_data_ptr();
|
||||
|
||||
// Generate XML Node
|
||||
node no;
|
||||
getUnifiedNode(t_addr, &no);
|
||||
|
||||
|
||||
DecodedAddress no;
|
||||
no = getUnifiedNode(t_addr);
|
||||
|
||||
|
||||
if (mem.count(t_addr) > 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < t_len; i += BYTES_PER_COL) {
|
||||
for (unsigned int i = 0; i < t_len; i += BYTES_PER_COL)
|
||||
{
|
||||
// Switch to next column if necessary
|
||||
if (i > 0) no.colum++;
|
||||
if (i > 0) no.column++;
|
||||
|
||||
// Swap around if more columns addressed than exist
|
||||
if (no.colum>(COLS_PER_ROW - 1)) no.colum -= BURSTLENGTH*BYTES_PER_COL;
|
||||
if (no.column>(COLS_PER_ROW - 1)) no.column -= BURSTLENGTH*BYTES_PER_COL;
|
||||
|
||||
unsigned int addr = xade->getAddress(&no);
|
||||
unsigned int addr = xmlAddressDecoder::getInstance().encodeAddress(no);
|
||||
|
||||
// Write out data
|
||||
for (unsigned int n = 0; n < BYTES_PER_COL; n++)
|
||||
@@ -157,7 +225,7 @@ void flip_memory::load(tlm_generic_payload &trans) {
|
||||
*(t_ptr + i + n) = mem[addr][n];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
trans.set_response_status(TLM_OK_RESPONSE);
|
||||
@@ -165,44 +233,166 @@ void flip_memory::load(tlm_generic_payload &trans) {
|
||||
|
||||
|
||||
// Function to trigger row refresh externally; errors are manifested
|
||||
void flip_memory::refresh(unsigned int row) {
|
||||
void flip_memory::refresh(unsigned int row)
|
||||
{
|
||||
// How many Bits have flipped?
|
||||
sc_time deltaT = sc_time_stamp() - refr[row];
|
||||
unsigned int n = errormap->getFlipRate(TEMPERATURE, deltaT);
|
||||
|
||||
// Flip the first n Bits in array
|
||||
for (unsigned int i=0; i<n; i++) {
|
||||
// Check if Bit has not flipped yet
|
||||
if (weakCells[i][3] == 0 && weakCells[i][0] == row) {
|
||||
node no;
|
||||
getUnifiedNode(0, &no);
|
||||
no.row = weakCells[i][0];
|
||||
no.colum = weakCells[i][1];
|
||||
|
||||
unsigned int addr = xade->getAddress(&no);
|
||||
unsigned int byte = weakCells[i][2] / 8; // Byte position in column
|
||||
unsigned int bit = weakCells[i][2] % 8; // Bit position in byte
|
||||
|
||||
unsigned char mask = pow(2, bit); // 1 Byte long character
|
||||
mask = ~mask; // invert mask (only one 0) and AND it later
|
||||
sc_time deltaT = sc_time_stamp() - refr[row];
|
||||
|
||||
|
||||
unsigned int n = errormap->getFlipRate(TEMPERATURE, deltaT);
|
||||
|
||||
//cout << sc_time_stamp() << ": deltaT=" << deltaT << " n=" << n << endl;
|
||||
|
||||
// Flip the first n Bits in array
|
||||
for (unsigned int i=0; i<n; i++) {
|
||||
// Check if Bit has not flipped yet
|
||||
if (weakCells[i][3] == 0 && weakCells[i][0] == row)
|
||||
{
|
||||
DecodedAddress no;
|
||||
no = getUnifiedNode(0);
|
||||
no.row = weakCells[i][0];
|
||||
no.column = weakCells[i][1];
|
||||
|
||||
int addr = xmlAddressDecoder::getInstance().encodeAddress(no);
|
||||
int byte = weakCells[i][2] / 8; // Byte position in column
|
||||
int bit = weakCells[i][2] % 8; // Bit position in byte
|
||||
|
||||
unsigned char mask = pow(2, bit); // 1 Byte long character
|
||||
mask = ~mask; // invert mask (only one 0) and AND it later
|
||||
|
||||
// Address has already been allocated?
|
||||
if (mem.count(addr) > 0)
|
||||
{
|
||||
char memBefore = mem[addr][byte];
|
||||
//cout << "Flip1?" << endl;
|
||||
|
||||
if(getBit(no.row,no.column,byte,bit) == 1) // flip only if it is really a one
|
||||
{
|
||||
//cout << "Flip2?" << endl;
|
||||
if(weakCells[i][4] == 1) // data dependent weak cell
|
||||
{
|
||||
// 0 1 2
|
||||
// 3 4 5
|
||||
// 6 7 8
|
||||
|
||||
unsigned int grid[9];
|
||||
|
||||
grid[0] = getBit(no.row-1,no.column,byte,bit-1);
|
||||
grid[1] = getBit(no.row-1,no.column,byte,bit );
|
||||
grid[2] = getBit(no.row-1,no.column,byte,bit+1);
|
||||
|
||||
grid[3] = getBit(no.row ,no.column,byte,bit-1);
|
||||
grid[4] = getBit(no.row ,no.column,byte,bit );
|
||||
grid[5] = getBit(no.row ,no.column,byte,bit+1);
|
||||
|
||||
grid[6] = getBit(no.row+1,no.column,byte,bit-1);
|
||||
grid[7] = getBit(no.row+1,no.column,byte,bit );
|
||||
grid[8] = getBit(no.row+1,no.column,byte,bit+1);
|
||||
|
||||
unsigned int sum = 0;
|
||||
for(int s = 0; s < 9; s++)
|
||||
{
|
||||
sum += grid[s];
|
||||
}
|
||||
|
||||
if(sum <= 4)
|
||||
{
|
||||
mem[addr][byte] &= mask;
|
||||
weakCells[i][3] = 1;
|
||||
cout << sc_time_stamp() << ": Bit flipped dependent at address=" << addr << " in byte=" << byte << "sum=" << sum << endl;
|
||||
cout << grid[0] << grid[1] << grid[2] <<endl;
|
||||
cout << grid[3] << grid[4] << grid[5] <<endl;
|
||||
cout << grid[6] << grid[7] << grid[8] <<endl;
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// cout << sc_time_stamp() << ": Bit not flipped dependent at address=" << addr << " in byte=" << byte << "sum=" << sum << endl;
|
||||
//}
|
||||
}
|
||||
else // data independent weak cell
|
||||
{
|
||||
mem[addr][byte] &= mask;
|
||||
weakCells[i][3] = 1;
|
||||
cout << sc_time_stamp() << ": Bit flipped independent at address=" << addr << " in byte=" << byte << endl;
|
||||
}
|
||||
}
|
||||
char memAfter = mem[addr][byte];
|
||||
|
||||
// Data has changed?
|
||||
if (memBefore!=memAfter)
|
||||
{
|
||||
BIT_ERR++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Address has already been allocated?
|
||||
if (mem.count(addr) > 0) {
|
||||
char memBefore = mem[addr][byte];
|
||||
|
||||
mem[addr][byte] &= mask;
|
||||
weakCells[i][3] = 1;
|
||||
|
||||
char memAfter = mem[addr][byte];
|
||||
|
||||
// Data has changed?
|
||||
if (memBefore!=memAfter) {
|
||||
BIT_ERR++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
refr[row] = sc_time_stamp();
|
||||
}
|
||||
|
||||
unsigned int flip_memory::getBit(int r, int c, int y, int b)
|
||||
{
|
||||
// Border-Exception handling:
|
||||
|
||||
// Switch the byte if bit under/overflow
|
||||
if(b < 0)
|
||||
{
|
||||
y--;
|
||||
b = 7;
|
||||
}
|
||||
else if(b >= 8)
|
||||
{
|
||||
y++;
|
||||
b = 0;
|
||||
}
|
||||
|
||||
// Switch the column if byte under/overflow
|
||||
if(y < 0)
|
||||
{
|
||||
c--;
|
||||
y = BYTES_PER_COL;
|
||||
}
|
||||
else if(y >= int(BYTES_PER_COL))
|
||||
{
|
||||
c++;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
// If we switch the row we return 0 (culumn under/overflow)
|
||||
if(c < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if(c >= int(COLS_PER_ROW))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// row over/underflow return 0
|
||||
if(r < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if(r >= int(ROWS_PER_BANK))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate the address for the map
|
||||
DecodedAddress no;
|
||||
no = getUnifiedNode(0);
|
||||
no.row = r;
|
||||
no.column = c;
|
||||
unsigned int addr = xmlAddressDecoder::getInstance().encodeAddress(no);
|
||||
|
||||
if(mem.count(addr) == 0) // If the address does not exist in the map tree the bit must be 0
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else // Return the value of the bit
|
||||
{
|
||||
unsigned char byte = mem[addr][y];
|
||||
unsigned char mask = pow(2, b);
|
||||
return (byte & mask) >> b;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +1,79 @@
|
||||
/*
|
||||
* Created on: Juli, 2014
|
||||
* Author: patrick, peter
|
||||
*/
|
||||
|
||||
#ifndef _FLIP_MEMORY_H
|
||||
#define _FLIP_MEMORY_H
|
||||
#include "nest_map.h"
|
||||
#include <tlm.h>
|
||||
#include <map>
|
||||
#include "common/xmlAddressdecoder.h"
|
||||
#include "../common/xmlAddressdecoder.h"
|
||||
#include "../common/third_party/DRAMPower/src/MemorySpecification.h"
|
||||
#include "../common/third_party/DRAMPower/src/MemCommand.h"
|
||||
#include "../controller/core/configuration/Configuration.h"
|
||||
|
||||
|
||||
using namespace tlm;
|
||||
using namespace std;
|
||||
|
||||
class flip_memory {
|
||||
private:
|
||||
xmlAddressDecoder *xade;
|
||||
class flip_memory
|
||||
{
|
||||
private:
|
||||
// Remember to adjust this value by hand when editing in simulation
|
||||
static const unsigned int BUSWIDTH = 128; //TODO
|
||||
static const unsigned int BURSTLENGTH = 2; //get from config file
|
||||
|
||||
// Remember to adjust this value by hand when editing in simulation
|
||||
static const unsigned int BUSWIDTH = 128;
|
||||
static const unsigned int BURSTLENGTH = 1;
|
||||
|
||||
// Compute number of generated bit errors
|
||||
unsigned int BIT_ERR;
|
||||
nest_map *errormap;
|
||||
map <unsigned int, vector<unsigned char> > mem;
|
||||
map <unsigned int, sc_time> refr;
|
||||
unsigned int **weakCells;
|
||||
|
||||
nest_map *errormap;
|
||||
map <unsigned int, vector<unsigned char> > mem;
|
||||
map <unsigned int, sc_time> refr;
|
||||
unsigned int **weakCells;
|
||||
|
||||
// This will be an input from ICE 3D
|
||||
unsigned int TEMPERATURE;
|
||||
|
||||
unsigned int ROWS_PER_BANK;
|
||||
unsigned int COLS_PER_ROW;
|
||||
unsigned int BYTES_PER_COL;
|
||||
unsigned int BITS_PER_ROW;
|
||||
// This will be an input from ICE 3D
|
||||
unsigned int TEMPERATURE;
|
||||
|
||||
// Generates an XML node which is tied to one memory class instance
|
||||
void getUnifiedNode(unsigned int addr, node *n);
|
||||
|
||||
// Decide randomly which cells are weak
|
||||
void initWeakCells();
|
||||
|
||||
// Reset "HasFlipped"-Flag, set Refresh-Timestamp
|
||||
void resetCell(node n);
|
||||
unsigned int ROWS_PER_BANK;
|
||||
unsigned int COLS_PER_ROW;
|
||||
unsigned int BYTES_PER_COL;
|
||||
unsigned int BITS_PER_ROW;
|
||||
unsigned int accordingBank;
|
||||
|
||||
// Generates an XML node which is tied to one memory class instance
|
||||
DecodedAddress getUnifiedNode(unsigned int addr);
|
||||
|
||||
// Decide randomly which cells are weak
|
||||
void initWeakCells();
|
||||
|
||||
// Reset "HasFlipped"-Flag, set Refresh-Timestamp
|
||||
void resetCell(DecodedAddress n);
|
||||
|
||||
public:
|
||||
// Compute number of generated bit errors
|
||||
unsigned int BIT_ERR;
|
||||
|
||||
flip_memory();
|
||||
~flip_memory();
|
||||
void setBank(unsigned int b);
|
||||
void store(tlm::tlm_generic_payload &trans);
|
||||
void load(tlm::tlm_generic_payload &trans);
|
||||
// Trigger row refresh externally; errors are manifested
|
||||
void refresh(unsigned int row);
|
||||
unsigned int getBit(int r, int c, int y, int b);
|
||||
|
||||
void debugMap()
|
||||
{
|
||||
typedef map<unsigned int, vector<unsigned char> >::const_iterator MapIterator;
|
||||
for (MapIterator iter = mem.begin(); iter != mem.end(); iter++)
|
||||
{
|
||||
cout << "Key: " << iter->first << endl << "Values: 0x";
|
||||
typedef vector<unsigned char>::const_iterator vectorIterator;
|
||||
for (vectorIterator list_iter = iter->second.begin(); list_iter != iter->second.end(); list_iter++)
|
||||
{
|
||||
cout << " " << hex << int(*list_iter);
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
flip_memory();
|
||||
~flip_memory();
|
||||
void store(tlm_generic_payload &trans);
|
||||
void load(tlm_generic_payload &trans);
|
||||
// Trigger row refresh externally; errors are manifested
|
||||
void refresh(unsigned int row);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,26 +1,39 @@
|
||||
/*
|
||||
* Created on: Juli, 2014
|
||||
* Author: patrick, peter
|
||||
*/
|
||||
|
||||
#include "nest_map.h"
|
||||
#include <limits>
|
||||
#include <chrono>
|
||||
#include <random>
|
||||
|
||||
nest_map::nest_map(string fn) {
|
||||
nest_map::nest_map(string fn)
|
||||
{
|
||||
initMap(fn);
|
||||
}
|
||||
|
||||
nest_map::~nest_map(void) {
|
||||
nest_map::~nest_map(void)
|
||||
{
|
||||
delete tr;
|
||||
}
|
||||
|
||||
// Read data from CSV file with filename "fn" and store it inside the errormap instance
|
||||
void nest_map::initMap(string fn) {
|
||||
void nest_map::initMap(string fn)
|
||||
{
|
||||
unsigned int noOfLines = 0;
|
||||
maxWeakCells = 0;
|
||||
maxWeakCells = 0;
|
||||
maxDependentCells=0;
|
||||
string line;
|
||||
|
||||
ifstream input;
|
||||
input.open(fn.c_str(), ios::in);
|
||||
|
||||
if (input.is_open()) {
|
||||
// Count number of entries in CSV file
|
||||
while (getline(input, line)) {
|
||||
if (input.is_open())
|
||||
{
|
||||
// Count number of entries in CSV file
|
||||
while (getline(input, line))
|
||||
{
|
||||
++noOfLines;
|
||||
}
|
||||
input.clear();
|
||||
@@ -28,26 +41,52 @@ void nest_map::initMap(string fn) {
|
||||
|
||||
// Knowing the size, allocate the errormap
|
||||
size = noOfLines;
|
||||
tr = new triple[noOfLines];
|
||||
|
||||
// Copy entries from CSV to errormap
|
||||
for (unsigned int i = 0; i < noOfLines; i++) {
|
||||
tr = new quadrupel[noOfLines];
|
||||
|
||||
// Copy entries from CSV to errormap
|
||||
for (unsigned int i = 0; i < noOfLines; i++)
|
||||
{
|
||||
getline(input, line);
|
||||
|
||||
// "split" returns a 3d vector with temperature, time, number of errors (this order)
|
||||
// "split" returns a matrix with 6 columns with temperature, retention time, number of data indipendent errors, sigma, number of data dependent errors, sigma (this order)
|
||||
vector<string> tmp = split(line, *",");
|
||||
|
||||
tr[i].T = atoi(tmp[0].c_str());
|
||||
// Don't forget to set right unit for times from CSV here
|
||||
// Don't forget to set right unit for times from CSV here
|
||||
tr[i].t = sc_time(atoi(tmp[1].c_str()), SC_MS);
|
||||
tr[i].n = atoi(tmp[2].c_str());
|
||||
|
||||
// Search the largest entry of n in list
|
||||
if (tr[i].n > maxWeakCells) {
|
||||
maxWeakCells = tr[i].n;
|
||||
}
|
||||
|
||||
double mean = atoi(tmp[2].c_str());
|
||||
|
||||
double sigma = atoi(tmp[3].c_str()); //(mean/100)*1.5 saved in csv file
|
||||
|
||||
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
|
||||
|
||||
std::default_random_engine generator(seed);
|
||||
std::normal_distribution<double> distribution(mean,sigma);
|
||||
|
||||
tr[i].n = ceil(distribution(generator)); //calculate normal distribution of # of independent errors
|
||||
|
||||
double mean2 = atoi(tmp[4].c_str()); //data dependent errors from file reading
|
||||
double sigma2 = atoi(tmp[5].c_str()); //(mean/100)*3 from csv file
|
||||
std::default_random_engine generator2(seed);
|
||||
std::normal_distribution<double> distribution2(mean2,sigma2);
|
||||
tr[i].d = ceil(distribution2(generator2)); // calculate normal distribution of # of dependent errors
|
||||
|
||||
//print normal distribution of csv file
|
||||
cout << "T=\t" << tr[i].T << "\t t=" << tr[i].t << "\t n=" << tr[i].n << "\t s=" << sigma << "\t d=" << tr[i].d << "\t s=" << sigma2 << endl;
|
||||
|
||||
// Search the largest entry of n in list
|
||||
if ((tr[i].n + tr[i].d)> maxWeakCells)
|
||||
{
|
||||
maxWeakCells = (tr[i].n + tr[i].d);
|
||||
}
|
||||
|
||||
if (tr[i].d > maxDependentCells)
|
||||
{
|
||||
maxDependentCells = tr[i].d;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
input.close();
|
||||
}
|
||||
else cout << "Fehler beim Oeffnen der Daten" << endl;
|
||||
@@ -55,48 +94,64 @@ void nest_map::initMap(string fn) {
|
||||
|
||||
|
||||
// Retrieve number of flipping bits which fits best to temperature input and time since last refresh
|
||||
unsigned int nest_map::getFlipRate(unsigned int T_in, sc_time t_in) {
|
||||
unsigned int nest_map::getFlipRate(unsigned int T_in, sc_time t_in)
|
||||
{
|
||||
unsigned int temperatureClosest = 0;
|
||||
unsigned int noOfWeakCells = 0;
|
||||
sc_time timeLowerBound = sc_time(0,SC_SEC);
|
||||
|
||||
unsigned int noOfWeakCells = 0;
|
||||
sc_time timeLowerBound = sc_time(0,SC_SEC);
|
||||
|
||||
// Search all entries in LUT for temperature closest to T_in
|
||||
for (unsigned int i = 0; i < size; i++) {
|
||||
if (abs((double)tr[i].T-(double)T_in)<abs((double)temperatureClosest-(double)T_in)) {
|
||||
temperatureClosest = tr[i].T;
|
||||
}
|
||||
}
|
||||
|
||||
// Which time mark has already been passed?
|
||||
for (unsigned int i = 0; i < size; i++) {
|
||||
// Only check entries with temperature temperatureClosest
|
||||
if (tr[i].T == temperatureClosest) {
|
||||
if ((tr[i].t.value() > timeLowerBound.value()) && (t_in.value() >= tr[i].t.value())) {
|
||||
timeLowerBound = tr[i].t;
|
||||
noOfWeakCells = tr[i].n;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (unsigned int i = 0; i < size; i++)
|
||||
{
|
||||
if (abs((double)tr[i].T-(double)T_in)<abs((double)temperatureClosest-(double)T_in))
|
||||
{
|
||||
temperatureClosest = tr[i].T;
|
||||
}
|
||||
}
|
||||
|
||||
// Which time mark has already been passed?
|
||||
for (unsigned int i = 0; i < size; i++)
|
||||
{
|
||||
// Only check entries with temperature temperatureClosest
|
||||
if (tr[i].T == temperatureClosest)
|
||||
{
|
||||
if ((tr[i].t.value() > timeLowerBound.value()) && (t_in.value() >= tr[i].t.value()))
|
||||
{
|
||||
timeLowerBound = tr[i].t;
|
||||
noOfWeakCells = tr[i].n + tr[i].d;
|
||||
}
|
||||
}
|
||||
}
|
||||
return noOfWeakCells;
|
||||
}
|
||||
|
||||
|
||||
unsigned int nest_map::getMaxWeakCells() {
|
||||
return maxWeakCells;
|
||||
unsigned int nest_map::getMaxWeakCells()
|
||||
{
|
||||
return maxWeakCells;
|
||||
}
|
||||
|
||||
unsigned int nest_map::getMaxDependentCells()
|
||||
{
|
||||
return maxDependentCells;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Remove all spaces out of a string and split it at every occurance of char c
|
||||
vector<string> nest_map::split(string str, char c) {
|
||||
vector<string> nest_map::split(string str, char c)
|
||||
{
|
||||
vector<string> tmp_v;
|
||||
string tmp_str = str;
|
||||
|
||||
// Remove spaces
|
||||
while (true){
|
||||
while (true)
|
||||
{
|
||||
size_t posSpace = tmp_str.find_first_of(" ");
|
||||
if (posSpace == string::npos) {
|
||||
break;
|
||||
}
|
||||
if (posSpace == string::npos)
|
||||
{
|
||||
break;
|
||||
}
|
||||
tmp_str.erase(posSpace, 1);
|
||||
}
|
||||
|
||||
@@ -104,7 +159,8 @@ vector<string> nest_map::split(string str, char c) {
|
||||
while (true)
|
||||
{
|
||||
size_t pos_del = tmp_str.find_first_of(c);
|
||||
if (pos_del == string::npos) {
|
||||
if (pos_del == string::npos)
|
||||
{
|
||||
tmp_v.push_back(tmp_str);
|
||||
break;
|
||||
}
|
||||
@@ -114,4 +170,4 @@ vector<string> nest_map::split(string str, char c) {
|
||||
}
|
||||
|
||||
return tmp_v;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Created on: Juli, 2014
|
||||
* Author: patrick, peter
|
||||
*/
|
||||
|
||||
#ifndef _NEST_MAP_H
|
||||
#define _NEST_MAP_H
|
||||
|
||||
@@ -10,25 +15,29 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
class nest_map {
|
||||
class nest_map
|
||||
{
|
||||
private:
|
||||
// Helper class to store triples of temperature, (retention) time and number of errors
|
||||
struct triple {
|
||||
unsigned int T;
|
||||
sc_time t;
|
||||
unsigned int n;
|
||||
// Helper class to store 6 values of temperature, (retention) time, # of independent errors, sigma, # of dependent errors, sigma
|
||||
struct quadrupel
|
||||
{
|
||||
unsigned int T; //Temperature
|
||||
sc_time t; //retention time
|
||||
unsigned int n; //data independent errors
|
||||
unsigned int d; //data dependent errors
|
||||
};
|
||||
|
||||
// Array of "triple" with dynamic size
|
||||
triple *tr;
|
||||
// Array of "6 values" with dynamic size
|
||||
quadrupel *tr;
|
||||
|
||||
// Number of entrys in tr[]
|
||||
// Number of entrys in tr[]
|
||||
unsigned int size;
|
||||
|
||||
// Largest value of n in tr[]
|
||||
unsigned int maxWeakCells;
|
||||
|
||||
// Default CSV filename
|
||||
|
||||
// Largest value of n in tr[]
|
||||
unsigned int maxWeakCells;
|
||||
unsigned int maxDependentCells;
|
||||
|
||||
// Default CSV filename
|
||||
const string def_fn;
|
||||
|
||||
void initMap(string fn);
|
||||
@@ -37,10 +46,11 @@ class nest_map {
|
||||
public:
|
||||
nest_map(string fn);
|
||||
~nest_map();
|
||||
|
||||
// Retrieve number of flipping bits which fits best to temperature input and time since last refresh
|
||||
|
||||
// Retrieve number of flipping bits which fits best to temperature input and time since last refresh
|
||||
unsigned int getFlipRate(unsigned int T, sc_time t);
|
||||
|
||||
unsigned int getMaxWeakCells();
|
||||
|
||||
unsigned int getMaxWeakCells();
|
||||
unsigned int getMaxDependentCells();
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -21,8 +21,9 @@
|
||||
#include "../common/TlmRecorder.h"
|
||||
#include "../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
||||
#include "../common/third_party/DRAMPower/src/xmlparser/MemSpecParser.h"
|
||||
#include "../common/third_party/DRAMPower/src/MemorySpecification.h"
|
||||
#include "../common/third_party/DRAMPower/src/MemCommand.h"
|
||||
|
||||
#include "../error/flip_memory.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace tlm;
|
||||
@@ -46,6 +47,10 @@ struct Dram: sc_module
|
||||
tlm_utils::simple_target_socket<Dram, BUSWIDTH, tlm::tlm_base_protocol_types> tSocket;
|
||||
IFPOW(libDRAMPower *DRAMPower);
|
||||
|
||||
const unsigned int StorageMode = Configuration::getInstance().StorMode; // 0 no storage, 1 store, 2 error model read form file TODO
|
||||
|
||||
flip_memory * fmemory;
|
||||
//Configuration::getInstance().memSpec.NumberOfBanks];
|
||||
map< unsigned long int, unsigned char[BUSWIDTH/2] > memory;
|
||||
|
||||
SC_CTOR(Dram) : tSocket("socket")
|
||||
@@ -62,7 +67,16 @@ struct Dram: sc_module
|
||||
IFPOW( DRAMPower->calcEnergy() );
|
||||
IFPOW( cout << endl << endl << "Total Energy" << "\t" << DRAMPower->getEnergy().total_energy << endl);
|
||||
IFPOW( cout << "Average Power" << "\t" << DRAMPower->getPower().average_power << endl );
|
||||
std::cout << "Simulated Memory Size: " << memory.size() << endl;
|
||||
for(int b = 0; b < 8; b++)
|
||||
cout << "BIT_ERRORS Bank: " <<b <<"="<< fmemory[b].BIT_ERR << endl;
|
||||
//cout << "Simulation finished!!!" << endl; // TODO Aufrauemen!
|
||||
//delete fmemory; // TODO Testen!
|
||||
//std::cout << "Simulated Memory Size: " << memory.size() << endl; // TODO Aufrauemen
|
||||
|
||||
if(StorageMode == 2) // TODO Testen!
|
||||
{
|
||||
fmemory = new flip_memory[1]; // TODO number of banks!!
|
||||
}
|
||||
}
|
||||
|
||||
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& payload, tlm::tlm_phase& phase, sc_time& delay)
|
||||
@@ -87,13 +101,31 @@ struct Dram: sc_module
|
||||
{
|
||||
IFPOW(DRAMPower->doCommand(MemCommand::ACT, bank, cycle));
|
||||
sendToController(payload, END_ACT, delay + getExecutionTime(Command::Activate, payload));
|
||||
unsigned int row = DramExtension::getExtension(payload).getRow().ID();
|
||||
|
||||
if (StorageMode == 2)
|
||||
{
|
||||
fmemory[bank].refresh(row);
|
||||
}
|
||||
}
|
||||
else if (phase == BEGIN_WR)
|
||||
{
|
||||
IFPOW(DRAMPower->doCommand(MemCommand::WR, bank, cycle));
|
||||
|
||||
//save data:
|
||||
memcpy(&memory[payload.get_address()], payload.get_data_ptr(), BUSWIDTH/8);
|
||||
sendToController(payload, END_WR, delay + getExecutionTime(Command::Write, payload));
|
||||
if (StorageMode == 0)
|
||||
{
|
||||
// Don't store data
|
||||
}
|
||||
else if (StorageMode == 1) //don't use StorageMode
|
||||
{
|
||||
memcpy(&memory[payload.get_address()], payload.get_data_ptr(), BUSWIDTH/8);
|
||||
}
|
||||
else
|
||||
{
|
||||
fmemory[bank].store(payload);
|
||||
sendToController(payload, END_WR, delay + getExecutionTime(Command::Write, payload));
|
||||
}
|
||||
}
|
||||
else if (phase == BEGIN_RD)
|
||||
{
|
||||
@@ -101,13 +133,20 @@ struct Dram: sc_module
|
||||
sendToController(payload, END_RD, delay + getExecutionTime(Command::Read, payload));
|
||||
|
||||
// Load data:
|
||||
if(memory.count(payload.get_address()) == 1)
|
||||
if (StorageMode == 1) //don't use StorageMode
|
||||
{
|
||||
memcpy(payload.get_data_ptr(), &memory[payload.get_address()], BUSWIDTH/8);
|
||||
if(memory.count(payload.get_address()) == 1)
|
||||
{
|
||||
memcpy(payload.get_data_ptr(), &memory[payload.get_address()], BUSWIDTH/8);
|
||||
}
|
||||
else
|
||||
{
|
||||
//SC_REPORT_WARNING ("DRAM", "Reading from an empty memory location.");
|
||||
}
|
||||
}
|
||||
else
|
||||
else // use StorageMode
|
||||
{
|
||||
//SC_REPORT_WARNING ("DRAM", "Reading from an empty memory location.");
|
||||
fmemory[bank].load(payload);
|
||||
}
|
||||
}
|
||||
else if (phase == BEGIN_WRA)
|
||||
@@ -124,6 +163,12 @@ struct Dram: sc_module
|
||||
{
|
||||
IFPOW(DRAMPower->doCommand(MemCommand::REF, bank, cycle));
|
||||
sendToController(payload, END_REFA, delay + getExecutionTime(Command::AutoRefresh, payload));
|
||||
unsigned int row = DramExtension::getExtension(payload).getRow().ID();
|
||||
|
||||
if (StorageMode == 2)
|
||||
{
|
||||
fmemory[bank].refresh(row);
|
||||
}
|
||||
}
|
||||
|
||||
else if (phase == BEGIN_REFB)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include "../common/Utils.h"
|
||||
#include "../error/flip_memory.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "ISimulation.h"
|
||||
#include <string>
|
||||
#include <systemc.h>
|
||||
#include "../error/flip_memory.h"
|
||||
|
||||
|
||||
namespace simulation {
|
||||
|
||||
|
||||
@@ -96,16 +96,16 @@ void TracePlayer<BUSWIDTH>::generateNextPayload()
|
||||
iss >> time >> command >> address;
|
||||
if (time.empty() || command.empty() || address.empty() )
|
||||
return;
|
||||
long parsedAdress = std::stoi(address.c_str(), 0, 16);
|
||||
unsigned int parsedAdress = std::stoi(address.c_str(), 0, 16);
|
||||
|
||||
gp* payload = memoryManager.allocate();
|
||||
payload->set_address(parsedAdress);
|
||||
|
||||
// Set data pointer
|
||||
unsigned char * dataElement = new unsigned char[16]; // TODO: column / burst breite
|
||||
payload->set_data_length(16); // TODO: column / burst breite
|
||||
unsigned char * dataElement = new unsigned char[16*2]; // TODO: column / burst breite
|
||||
payload->set_data_length(16*2); // TODO: column / burst breite
|
||||
payload->set_data_ptr(dataElement);
|
||||
for(int i = 0; i < 16; i++) // TODO: column / burst breite
|
||||
for(int i = 0; i < 16*2; i++) // TODO: column / burst breite
|
||||
dataElement[i] = 0;
|
||||
|
||||
if (command == "read")
|
||||
@@ -124,7 +124,7 @@ void TracePlayer<BUSWIDTH>::generateNextPayload()
|
||||
{
|
||||
//cout << "parsing write data: " << data << std::endl;
|
||||
|
||||
for(int i = 0; i < 16; i++) // TODO column / burst breite
|
||||
for(int i = 0; i < 16*2; i++) // TODO column / burst breite
|
||||
{
|
||||
std::string byteString = "0x";
|
||||
byteString.append(data.substr(2*(i+1), 2));
|
||||
@@ -144,7 +144,7 @@ void TracePlayer<BUSWIDTH>::generateNextPayload()
|
||||
payload->set_byte_enable_length(0);
|
||||
payload->set_streaming_width(burstlenght);
|
||||
|
||||
sc_time sendingTime = std::stoi(time.c_str())*clk;
|
||||
sc_time sendingTime = std::stoull(time.c_str())*clk;
|
||||
GenerationExtension* genExtension = new GenerationExtension(sendingTime);
|
||||
payload->set_auto_extension(genExtension);
|
||||
|
||||
@@ -256,6 +256,18 @@ void TracePlayer<BUSWIDTH>::peqCallback(tlm_generic_payload &payload, const tlm_
|
||||
sendToTarget(payload, END_RESP, SC_ZERO_TIME);
|
||||
payload.release();
|
||||
|
||||
unsigned char * dataElement = payload.get_data_ptr();
|
||||
|
||||
// if(payload.get_command() == TLM_READ_COMMAND)
|
||||
// {
|
||||
// cout << "0x";
|
||||
// for(int i=0; i < 16*2; i++)
|
||||
// {
|
||||
// cout << hex << int(dataElement[i]);
|
||||
// }
|
||||
// cout << endl;
|
||||
// }
|
||||
|
||||
simulationManager->transactionFinished();
|
||||
numberOfPendingTransactions--;
|
||||
transactionsReceived++;
|
||||
|
||||
Reference in New Issue
Block a user