From a366ed8f91bbd7f7f7a77b95b1550bd74c43fe3e Mon Sep 17 00:00:00 2001 From: Peter Ehses Date: Tue, 16 Sep 2014 10:27:14 +0200 Subject: [PATCH 1/7] easy error model from patrick implemented --- dram/src/error/flip_memory.cpp | 208 +++++++++++++++++++++++++++++++++ dram/src/error/flip_memory.h | 53 +++++++++ dram/src/error/nest_map.cpp | 117 +++++++++++++++++++ dram/src/error/nest_map.h | 46 ++++++++ 4 files changed, 424 insertions(+) create mode 100644 dram/src/error/flip_memory.cpp create mode 100644 dram/src/error/flip_memory.h create mode 100644 dram/src/error/nest_map.cpp create mode 100644 dram/src/error/nest_map.h diff --git a/dram/src/error/flip_memory.cpp b/dram/src/error/flip_memory.cpp new file mode 100644 index 00000000..9b2b5071 --- /dev/null +++ b/dram/src/error/flip_memory.cpp @@ -0,0 +1,208 @@ +#include "flip_memory.h" +#include +// Console out +#include + +// String conversion (debugging) +#include +#include + +using namespace std; + +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 + TEMPERATURE = 90; + + // Initialize number of bit errors + BIT_ERR = 0; + + errormap = new nest_map("errors.csv"); + xade = new xmlAddressDecoder("config.xml"); + + // Constants for address calculations + ROWS_PER_BANK = xade->getRowSize(); + COLS_PER_ROW = xade->getColumSize(); + BYTES_PER_COL = xade->getBytesSize(); + BITS_PER_ROW = COLS_PER_ROW * BYTES_PER_COL * 8; + + // Fill array with random addresses + initWeakCells(); +} + +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; +} + +// 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(); + + 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++; + + // Swap around if more columns addressed than exist + if (no.colum>(COLS_PER_ROW - 1)) no.colum -= BURSTLENGTH*BYTES_PER_COL; + + unsigned int addr = xade->getAddress(&no); + + mem.insert(pair >(addr, v)); + + // Reset weak cells; they have reliable data now till next check + resetCell(no); + } + + trans.set_response_status(TLM_OK_RESPONSE); +} + + +void flip_memory::load(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(); + + // Generate XML Node + node no; + getUnifiedNode(t_addr, &no); + + + if (mem.count(t_addr) > 0) + { + for (unsigned int i = 0; i < t_len; i += BYTES_PER_COL) { + // Switch to next column if necessary + if (i > 0) no.colum++; + + // Swap around if more columns addressed than exist + if (no.colum>(COLS_PER_ROW - 1)) no.colum -= BURSTLENGTH*BYTES_PER_COL; + + unsigned int addr = xade->getAddress(&no); + + // Write out data + for (unsigned int n = 0; n < BYTES_PER_COL; n++) + { + *(t_ptr + i + n) = mem[addr][n]; + } + } + + } + + trans.set_response_status(TLM_OK_RESPONSE); +} + + +// Function to trigger row refresh externally; errors are manifested +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 + + // 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(); +} + diff --git a/dram/src/error/flip_memory.h b/dram/src/error/flip_memory.h new file mode 100644 index 00000000..cc4abb75 --- /dev/null +++ b/dram/src/error/flip_memory.h @@ -0,0 +1,53 @@ +#ifndef _FLIP_MEMORY_H +#define _FLIP_MEMORY_H +#include "nest_map.h" +#include +#include +#include "common/xmlAddressdecoder.h" + + +using namespace tlm; +using namespace std; + +class flip_memory { +private: + xmlAddressDecoder *xade; + + // 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; + + // 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; + + // 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); + +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 new file mode 100644 index 00000000..25aaa009 --- /dev/null +++ b/dram/src/error/nest_map.cpp @@ -0,0 +1,117 @@ +#include "nest_map.h" +#include + +nest_map::nest_map(string fn) { + initMap(fn); +} + +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) { + unsigned int noOfLines = 0; + maxWeakCells = 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)) { + ++noOfLines; + } + input.clear(); + input.seekg(0, ios::beg); + + // 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++) { + getline(input, line); + + // "split" returns a 3d vector with temperature, time, number of errors (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 + 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; + } + } + + input.close(); + } + else cout << "Fehler beim Oeffnen der Daten" << endl; +} + + +// 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 temperatureClosest = 0; + 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; + } + } + } + return noOfWeakCells; +} + + +unsigned int nest_map::getMaxWeakCells() { + return maxWeakCells; +} + + +// 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 tmp_v; + string tmp_str = str; + + // Remove spaces + while (true){ + size_t posSpace = tmp_str.find_first_of(" "); + if (posSpace == string::npos) { + break; + } + tmp_str.erase(posSpace, 1); + } + + // Split string at every occurance of char c + while (true) + { + size_t pos_del = tmp_str.find_first_of(c); + if (pos_del == string::npos) { + tmp_v.push_back(tmp_str); + break; + } + + tmp_v.push_back(tmp_str.substr(0, pos_del)); + tmp_str.erase(0, pos_del + 1); + } + + 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 new file mode 100644 index 00000000..58ce02b7 --- /dev/null +++ b/dram/src/error/nest_map.h @@ -0,0 +1,46 @@ +#ifndef _NEST_MAP_H +#define _NEST_MAP_H + +#include +#include +#include +#include +#include +#include + +using namespace std; + +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; + }; + + // Array of "triple" with dynamic size + triple *tr; + + // Number of entrys in tr[] + unsigned int size; + + // Largest value of n in tr[] + unsigned int maxWeakCells; + + // Default CSV filename + const string def_fn; + + void initMap(string fn); + vector split(string str, char c); + + public: + nest_map(string fn); + ~nest_map(); + + // 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(); +}; +#endif From 905e75ca32ca875f0ac11a28c8e39c181441b53e Mon Sep 17 00:00:00 2001 From: Peter Ehses Date: Tue, 2 Dec 2014 14:44:46 +0100 Subject: [PATCH 2/7] included errormodel which is presented in DATE paper --- dram/dramSys/dramSys.pro | 8 +- .../resources/configs/amconfigs/am_wideio.xml | 11 + dram/resources/configs/memconfigs/fr_fcfs.xml | 9 +- dram/src/common/xmlAddressdecoder.cpp | 11 + dram/src/common/xmlAddressdecoder.h | 2 + .../core/configuration/Configuration.h | 5 + .../controller/core/configuration/MemSpec.h | 1 + .../core/configuration/MemSpecLoader.cpp | 8 + dram/src/error/error_new.csv | 20 + dram/src/error/flip_memory.cpp | 424 +++++++++++++----- dram/src/error/flip_memory.h | 100 +++-- dram/src/error/nest_map.cpp | 154 +++++-- dram/src/error/nest_map.h | 46 +- dram/src/simulation/Dram.h | 63 ++- dram/src/simulation/Simulation.cpp | 1 + dram/src/simulation/Simulation.h | 2 + dram/src/simulation/TracePlayer.h | 24 +- 17 files changed, 648 insertions(+), 241 deletions(-) create mode 100644 dram/src/error/error_new.csv 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++; From 571e717224134c5fca438cc172c1880d3b137a3a Mon Sep 17 00:00:00 2001 From: Peter Ehses Date: Tue, 2 Dec 2014 16:05:13 +0100 Subject: [PATCH 3/7] removed some errors --- dram/dramSys/dramSys.pro | 6 +++--- dram/src/error/flip_memory.cpp | 10 +++++++--- dram/src/simulation/Dram.h | 22 ++++++++++++++-------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/dram/dramSys/dramSys.pro b/dram/dramSys/dramSys.pro index fc4cba8e..5bb67401 100644 --- a/dram/dramSys/dramSys.pro +++ b/dram/dramSys/dramSys.pro @@ -72,7 +72,7 @@ SOURCES += \ ../src/controller/scheduler/Scheduler.cpp \ ../src/controller/scheduler/readwritegrouper.cpp \ ../src/controller/core/configuration/ConfigurationLoader.cpp \ - ../src/controller/core/powerdown/NoPowerDown.cpp + ../src/controller/core/powerdown/NoPowerDown.cpp \ ../src/error/nest_map.cpp \ ../src/error/flip_memory.cpp @@ -131,8 +131,8 @@ HEADERS += \ ../src/simulation/StlPlayer.h \ ../src/simulation/TracePlayerListener.h \ ../src/simulation/TraceGenerator.h \ - ../src/controller/core/powerdown/NoPowerDown.h - ../src/controller/core/configuration/ConfigurationLoader.h + ../src/controller/core/powerdown/NoPowerDown.h \ + ../src/controller/core/configuration/ConfigurationLoader.h \ ../src/error/nest_map.h \ ../src/error/flip_memory.h diff --git a/dram/src/error/flip_memory.cpp b/dram/src/error/flip_memory.cpp index 3662c524..31c8ef2b 100644 --- a/dram/src/error/flip_memory.cpp +++ b/dram/src/error/flip_memory.cpp @@ -41,16 +41,20 @@ flip_memory::flip_memory() // path of csv file errormap = new nest_map(Configuration::getInstance().csvfile); - //xade = new xmlAddressDecoder("config.xml"); // Constants for address calculations 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 + BYTES_PER_COL = 16; //TODO 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 initWeakCells(); + + for(unsigned int i = 0; i < ROWS_PER_BANK; i++) + { + refr[i] = SC_ZERO_TIME; + } } flip_memory::~flip_memory() @@ -61,7 +65,6 @@ flip_memory::~flip_memory() 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; @@ -236,6 +239,7 @@ void flip_memory::load(tlm::tlm_generic_payload &trans) void flip_memory::refresh(unsigned int row) { // How many Bits have flipped? + cout << "TEST=" << refr[row] << endl; sc_time deltaT = sc_time_stamp() - refr[row]; diff --git a/dram/src/simulation/Dram.h b/dram/src/simulation/Dram.h index 82b46ab1..0f414022 100644 --- a/dram/src/simulation/Dram.h +++ b/dram/src/simulation/Dram.h @@ -62,6 +62,12 @@ struct Dram: sc_module IFPOW( MemorySpecification memSpec(MemSpecParser::getMemSpecFromXML(Configuration::getInstance().memspecUri)) ); IFPOW( DRAMPower = new libDRAMPower( memSpec, 0 ) ); + cout << "StorageMode = " << StorageMode << endl; + + if(StorageMode == 2) + { + fmemory = new flip_memory[Configuration::getInstance().memSpec.NumberOfBanks]; + } } ~Dram() @@ -70,16 +76,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 ); - for(int b = 0; b < 8; b++) - cout << "BIT_ERRORS Bank: " < Date: Wed, 25 Mar 2015 14:21:37 +0100 Subject: [PATCH 4/7] small changes and comments --- .../configuration/ConfigurationLoader.cpp | 2 ++ .../controller/core/configuration/MemSpec.h | 1 + dram/src/error/flip_memory.cpp | 23 ++++++++++--------- dram/src/error/flip_memory.h | 5 ++-- dram/src/error/nest_map.cpp | 2 +- dram/src/simulation/Dram.h | 12 ++++------ dram/src/simulation/StlPlayer.h | 6 ++--- dram/src/simulation/TracePlayer.h | 17 ++++++++++++-- 8 files changed, 42 insertions(+), 26 deletions(-) diff --git a/dram/src/controller/core/configuration/ConfigurationLoader.cpp b/dram/src/controller/core/configuration/ConfigurationLoader.cpp index 5e1499b9..2969426e 100644 --- a/dram/src/controller/core/configuration/ConfigurationLoader.cpp +++ b/dram/src/controller/core/configuration/ConfigurationLoader.cpp @@ -115,6 +115,7 @@ void ConfigurationLoader::loadDDR4(Configuration& config, XMLElement* memspec) config.memSpec.DataRate = queryUIntParameter(architecture, "dataRate"); config.memSpec.NumberOfRows = queryUIntParameter(architecture, "nbrOfRows"); config.memSpec.NumberOfColumns = queryUIntParameter(architecture, "nbrOfColumns"); + config.memSpec.BusWidth = queryUIntParameter(architecture, "width"); //MemTimings XMLElement* timings = memspec->FirstChildElement("memtimingspec"); @@ -166,6 +167,7 @@ void ConfigurationLoader::loadWideIO(Configuration& config, XMLElement* memspec) config.memSpec.DataRate = queryUIntParameter(architecture, "dataRate"); config.memSpec.NumberOfRows = queryUIntParameter(architecture, "nbrOfRows"); config.memSpec.NumberOfColumns = queryUIntParameter(architecture, "nbrOfColumns"); + config.memSpec.BusWidth = queryUIntParameter(architecture, "width"); //MemTimings XMLElement* timings = memspec->FirstChildElement("memtimingspec"); diff --git a/dram/src/controller/core/configuration/MemSpec.h b/dram/src/controller/core/configuration/MemSpec.h index 80890d9c..0f8b02af 100644 --- a/dram/src/controller/core/configuration/MemSpec.h +++ b/dram/src/controller/core/configuration/MemSpec.h @@ -54,6 +54,7 @@ struct MemSpec unsigned int DataRate; unsigned int NumberOfRows; unsigned int NumberOfColumns; + unsigned int BusWidth; sc_time clk; sc_time tRP; //precharge-time (pre -> act same bank) diff --git a/dram/src/error/flip_memory.cpp b/dram/src/error/flip_memory.cpp index 31c8ef2b..c6cb7e17 100644 --- a/dram/src/error/flip_memory.cpp +++ b/dram/src/error/flip_memory.cpp @@ -69,7 +69,8 @@ DecodedAddress flip_memory::getUnifiedNode(unsigned int addr) n.bank = 0; return n; } - +//TODO: here get map createt on which address errors will occur, so insert here errormap from board. +// dont forget to delete this line // Decide which Cells will be weak cells void flip_memory::initWeakCells() { @@ -87,7 +88,7 @@ void flip_memory::initWeakCells() 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; + cout << "row" << row << "\t col" << col << "\t bit" << bit << endl; // Avoid duplicates in weakCells[] bool found = false; @@ -128,14 +129,14 @@ void flip_memory::initWeakCells() } // Debug - for (unsigned int i=0; i 0) { char memBefore = mem[addr][byte]; - //cout << "Flip1?" << endl; + //cout << "Flip1?" << endl; if(getBit(no.row,no.column,byte,bit) == 1) // flip only if it is really a one { diff --git a/dram/src/error/flip_memory.h b/dram/src/error/flip_memory.h index 77eb1ad4..2ef22e7b 100644 --- a/dram/src/error/flip_memory.h +++ b/dram/src/error/flip_memory.h @@ -16,13 +16,14 @@ using namespace tlm; using namespace std; +using namespace core; 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 + unsigned int BUSWIDTH = Configuration::getInstance().memSpec.BusWidth; //static const unsigned int BUSWIDTH=128; + unsigned int BURSTLENGTH = Configuration::getInstance().memSpec.BurstLength; //static const unsigned int BURSTLENGTH = 2; but in wideIO.xml its 4 nest_map *errormap; map > mem; diff --git a/dram/src/error/nest_map.cpp b/dram/src/error/nest_map.cpp index a602dcdf..75fb96a6 100644 --- a/dram/src/error/nest_map.cpp +++ b/dram/src/error/nest_map.cpp @@ -73,7 +73,7 @@ void nest_map::initMap(string fn) 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; + //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) diff --git a/dram/src/simulation/Dram.h b/dram/src/simulation/Dram.h index 0f414022..8188c02c 100644 --- a/dram/src/simulation/Dram.h +++ b/dram/src/simulation/Dram.h @@ -50,7 +50,7 @@ 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 + const unsigned int StorageMode = Configuration::getInstance().StorMode; // 0 no storage, 1 store, 2 error model flip_memory * fmemory; //Configuration::getInstance().memSpec.NumberOfBanks]; @@ -83,7 +83,7 @@ struct Dram: sc_module cout << "BIT_ERRORS Bank: " <allocatePayload(); - unsigned char * dataElement = new unsigned char[16]; // TODO: column / burst breite + unsigned char * dataElement = new unsigned char[16*2]; // TODO: column / burst breite payload->set_address(parsedAdress); payload->set_response_status(TLM_INCOMPLETE_RESPONSE); @@ -60,7 +60,7 @@ public: { //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)); @@ -75,7 +75,7 @@ public: (string("Corrupted tracefile, command ") + command + string(" unknown")).c_str()); } - sc_time sendingTime = std::stoi(time.c_str())*clk; + sc_time sendingTime = std::stoull(time.c_str())*clk; if (sendingTime <= sc_time_stamp()) { diff --git a/dram/src/simulation/TracePlayer.h b/dram/src/simulation/TracePlayer.h index 55f8ae48..d5c35961 100644 --- a/dram/src/simulation/TracePlayer.h +++ b/dram/src/simulation/TracePlayer.h @@ -86,9 +86,9 @@ template void TracePlayer::setDataPointer(gp* payload, unsigned char * dataElement) { //check if payload takes ownership - payload->set_data_length(16); // TODO: column / burst breite ..... buswidth * burst /8 + payload->set_data_length(16*2); // TODO: column / burst breite ..... buswidth * burst /8 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; } @@ -120,6 +120,19 @@ void TracePlayer::peqCallback(tlm_generic_payload &payload, const tlm_ } else if (phase == BEGIN_RESP) { +//TODO: cleanup: +// 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; +// } + sendToTarget(payload, END_RESP, SC_ZERO_TIME); payload.release(); } From 2a587436d9100454d5d3b50daea721aa44dce64e Mon Sep 17 00:00:00 2001 From: Peter Ehses Date: Thu, 9 Apr 2015 10:01:27 +0200 Subject: [PATCH 5/7] Fixed small bug --- dram/src/simulation/Dram.h | 43 +++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/dram/src/simulation/Dram.h b/dram/src/simulation/Dram.h index 8188c02c..cf5bdaaa 100644 --- a/dram/src/simulation/Dram.h +++ b/dram/src/simulation/Dram.h @@ -64,7 +64,7 @@ struct Dram: sc_module IFPOW( DRAMPower = new libDRAMPower( memSpec, 0 ) ); cout << "StorageMode = " << StorageMode << endl; - if(StorageMode == 2) + if(StorageMode == 2) { fmemory = new flip_memory[Configuration::getInstance().memSpec.NumberOfBanks]; } @@ -126,20 +126,19 @@ struct Dram: sc_module { // Don't store data } - else if (StorageMode == 1) //don't use StorageMode + else if (StorageMode == 1) // Use Storage { memcpy(&memory[payload.get_address()], payload.get_data_ptr(), BUSWIDTH/8); } - else + else // == 2 Use Storage with Error Model { fmemory[bank].store(payload); - sendToController(payload, END_WR, delay + getExecutionTime(Command::Write, payload)); } + sendToController(payload, END_WR, delay + getExecutionTime(Command::Write, payload)); } else if (phase == BEGIN_RD) { IFPOW(DRAMPower->doCommand(MemCommand::RD, bank, cycle)); - sendToController(payload, END_RD, delay + getExecutionTime(Command::Read, payload)); // Load data: if (StorageMode == 1) //use StorageMode @@ -157,15 +156,49 @@ struct Dram: sc_module { fmemory[bank].load(payload); } + + sendToController(payload, END_RD, delay + getExecutionTime(Command::Read, payload)); } else if (phase == BEGIN_WRA) { IFPOW(DRAMPower->doCommand(MemCommand::WRA, bank, cycle)); + + //save data: + if (StorageMode == 0) + { + // Don't store data + } + else if (StorageMode == 1) // Use Storage + { + memcpy(&memory[payload.get_address()], payload.get_data_ptr(), BUSWIDTH/8); + } + else // == 2 Use Storage with Error Model + { + fmemory[bank].store(payload); + } sendToController(payload, END_WRA, delay + getExecutionTime(Command::WriteA, payload)); } else if (phase == BEGIN_RDA) { IFPOW(DRAMPower->doCommand(MemCommand::RDA, bank, cycle)); + + // Load data: + if (StorageMode == 1) //use StorageMode + { + 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 if(StorageMode == 2)// use StorageMode with errormodel + { + fmemory[bank].load(payload); + } + sendToController(payload, END_RDA, delay + getExecutionTime(Command::ReadA, payload)); } else if (phase == BEGIN_REFA) From 7f67a822877e2ba5f19fae39d5ff629913ddc535 Mon Sep 17 00:00:00 2001 From: Matthias Jung Date: Thu, 9 Apr 2015 10:33:02 +0200 Subject: [PATCH 6/7] added error model to the configs --- dram/resources/configs/memconfigs/fifo.xml | 10 +++++++--- dram/resources/configs/memconfigs/fifoStrict.xml | 6 +++++- dram/resources/configs/memconfigs/fr_fcfs.xml | 3 ++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/dram/resources/configs/memconfigs/fifo.xml b/dram/resources/configs/memconfigs/fifo.xml index 35395479..094a261e 100644 --- a/dram/resources/configs/memconfigs/fifo.xml +++ b/dram/resources/configs/memconfigs/fifo.xml @@ -1,9 +1,13 @@ - - + + - + + + + + diff --git a/dram/resources/configs/memconfigs/fifoStrict.xml b/dram/resources/configs/memconfigs/fifoStrict.xml index 35395479..64424430 100644 --- a/dram/resources/configs/memconfigs/fifoStrict.xml +++ b/dram/resources/configs/memconfigs/fifoStrict.xml @@ -1,9 +1,13 @@ - + + + + + diff --git a/dram/resources/configs/memconfigs/fr_fcfs.xml b/dram/resources/configs/memconfigs/fr_fcfs.xml index ad7c1ec4..546b3223 100644 --- a/dram/resources/configs/memconfigs/fr_fcfs.xml +++ b/dram/resources/configs/memconfigs/fr_fcfs.xml @@ -6,9 +6,10 @@ + - +