diff --git a/dram/dramSys/dramSys.pro b/dram/dramSys/dramSys.pro index 1b3163b3..35a52edf 100644 --- a/dram/dramSys/dramSys.pro +++ b/dram/dramSys/dramSys.pro @@ -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 diff --git a/dram/resources/configs/amconfigs/am_wideio.xml b/dram/resources/configs/amconfigs/am_wideio.xml index fc29d918..85ec0876 100755 --- a/dram/resources/configs/amconfigs/am_wideio.xml +++ b/dram/resources/configs/amconfigs/am_wideio.xml @@ -10,6 +10,7 @@ --> + + + + + + + + + + diff --git a/dram/resources/configs/memconfigs/fr_fcfs.xml b/dram/resources/configs/memconfigs/fr_fcfs.xml index 8aa70731..0cb3b908 100644 --- a/dram/resources/configs/memconfigs/fr_fcfs.xml +++ b/dram/resources/configs/memconfigs/fr_fcfs.xml @@ -7,8 +7,11 @@ - - - + + + + + + diff --git a/dram/src/common/xmlAddressdecoder.cpp b/dram/src/common/xmlAddressdecoder.cpp index 67eb278c..03aadf0e 100644 --- a/dram/src/common/xmlAddressdecoder.cpp +++ b/dram/src/common/xmlAddressdecoder.cpp @@ -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"]; +} diff --git a/dram/src/common/xmlAddressdecoder.h b/dram/src/common/xmlAddressdecoder.h index 3cd3d6fe..9cb71734 100755 --- a/dram/src/common/xmlAddressdecoder.h +++ b/dram/src/common/xmlAddressdecoder.h @@ -47,6 +47,8 @@ public: } DecodedAddress decodeAddress(sc_dt::uint64 addr); + sc_dt::uint64 encodeAddress(DecodedAddress n); + private: xmlAddressDecoder(std::string URI); diff --git a/dram/src/controller/core/configuration/Configuration.h b/dram/src/controller/core/configuration/Configuration.h index feefaf3b..609671e6 100644 --- a/dram/src/controller/core/configuration/Configuration.h +++ b/dram/src/controller/core/configuration/Configuration.h @@ -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(); }; diff --git a/dram/src/controller/core/configuration/MemSpec.h b/dram/src/controller/core/configuration/MemSpec.h index 9a47ce35..87e29b40 100644 --- a/dram/src/controller/core/configuration/MemSpec.h +++ b/dram/src/controller/core/configuration/MemSpec.h @@ -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) diff --git a/dram/src/controller/core/configuration/MemSpecLoader.cpp b/dram/src/controller/core/configuration/MemSpecLoader.cpp index de3fd88a..44cc5b97 100644 --- a/dram/src/controller/core/configuration/MemSpecLoader.cpp +++ b/dram/src/controller/core/configuration/MemSpecLoader.cpp @@ -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"); diff --git a/dram/src/error/error_new.csv b/dram/src/error/error_new.csv new file mode 100644 index 00000000..7f50ae2c --- /dev/null +++ b/dram/src/error/error_new.csv @@ -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 diff --git a/dram/src/error/flip_memory.cpp b/dram/src/error/flip_memory.cpp index 9b2b5071..3662c524 100644 --- a/dram/src/error/flip_memory.cpp +++ b/dram/src/error/flip_memory.cpp @@ -1,133 +1,200 @@ +/* + * Created on: Juli, 2014 + * Author: patrick, peter + */ + #include "flip_memory.h" #include // Console out #include - +#include // String conversion (debugging) #include #include +#include + +#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; igetMaxWeakCells(); + + weakCells = new unsigned int*[maxWeakCells]; + + for (unsigned int i=0; igetMaxDependentCells(); i++) + { + unsigned int r = (rand()%maxWeakCells); + + if(weakCells[r][4] == 1) + { + i--; + } + else + { + weakCells[r][4] = 1; + } + + } + + // Debug + for (unsigned int i=0; igetMaxWeakCells(); - - for (unsigned int i=0; igetMaxWeakCells(); - refr[n.row] = sc_time_stamp(); + for (unsigned int i=0; i 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 >(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; igetAddress(&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 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] < #include -#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 > mem; + map refr; + unsigned int **weakCells; - nest_map *errormap; - map > mem; - map 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 >::const_iterator MapIterator; + for (MapIterator iter = mem.begin(); iter != mem.end(); iter++) + { + cout << "Key: " << iter->first << endl << "Values: 0x"; + typedef vector::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 diff --git a/dram/src/error/nest_map.cpp b/dram/src/error/nest_map.cpp index 25aaa009..a602dcdf 100644 --- a/dram/src/error/nest_map.cpp +++ b/dram/src/error/nest_map.cpp @@ -1,26 +1,39 @@ +/* + * Created on: Juli, 2014 + * Author: patrick, peter + */ + #include "nest_map.h" #include +#include +#include -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 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 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 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) 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) 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 nest_map::split(string str, char c) { +vector nest_map::split(string str, char c) +{ vector 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 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 nest_map::split(string str, char c) { } return tmp_v; -} \ No newline at end of file +} diff --git a/dram/src/error/nest_map.h b/dram/src/error/nest_map.h index 58ce02b7..5b9134f3 100644 --- a/dram/src/error/nest_map.h +++ b/dram/src/error/nest_map.h @@ -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 diff --git a/dram/src/simulation/Dram.h b/dram/src/simulation/Dram.h index b740c295..89520ab9 100644 --- a/dram/src/simulation/Dram.h +++ b/dram/src/simulation/Dram.h @@ -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 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: " <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) diff --git a/dram/src/simulation/Simulation.cpp b/dram/src/simulation/Simulation.cpp index 21823831..c980e64d 100644 --- a/dram/src/simulation/Simulation.cpp +++ b/dram/src/simulation/Simulation.cpp @@ -15,6 +15,7 @@ #include #include #include "../common/Utils.h" +#include "../error/flip_memory.h" using namespace std; diff --git a/dram/src/simulation/Simulation.h b/dram/src/simulation/Simulation.h index 8b4d5dc0..98790c28 100644 --- a/dram/src/simulation/Simulation.h +++ b/dram/src/simulation/Simulation.h @@ -16,6 +16,8 @@ #include "ISimulation.h" #include #include +#include "../error/flip_memory.h" + namespace simulation { diff --git a/dram/src/simulation/TracePlayer.h b/dram/src/simulation/TracePlayer.h index 9c32810f..96b59e85 100644 --- a/dram/src/simulation/TracePlayer.h +++ b/dram/src/simulation/TracePlayer.h @@ -96,16 +96,16 @@ void TracePlayer::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::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::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::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++;