diff --git a/dram/dramSys/dramSys.pro b/dram/dramSys/dramSys.pro index d4ccf183..2a6a23bb 100644 --- a/dram/dramSys/dramSys.pro +++ b/dram/dramSys/dramSys.pro @@ -72,7 +72,9 @@ SOURCES += \ ../src/controller/ControllerState.cpp \ ../src/controller/RowBufferStates.cpp \ ../src/controller/scheduler/IScheduler.cpp \ - ../src/controller/scheduler/FifoStrict.cpp + ../src/controller/scheduler/FifoStrict.cpp \ + ../src/error/nest_map.cpp \ + ../src/error/flip_memory.cpp HEADERS += \ ../src/common/third_party/tinyxml2.h \ @@ -128,6 +130,8 @@ HEADERS += \ ../src/controller/core/powerdown/IPowerDownManager.h \ ../src/controller/scheduler/IScheduler.h \ ../src/controller/scheduler/FifoStrict.h \ - ../src/controller/IController.h - ../src/controller/core/configuration/ConfigurationLoader.h + ../src/controller/IController.h \ + ../src/controller/core/configuration/ConfigurationLoader.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 781f4d1e..76d14bac 100755 --- a/dram/resources/configs/amconfigs/am_wideio.xml +++ b/dram/resources/configs/amconfigs/am_wideio.xml @@ -1,4 +1,3 @@ - @@ -6,4 +5,14 @@ + + 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 d2605c7e..546b3223 100644 --- a/dram/resources/configs/memconfigs/fr_fcfs.xml +++ b/dram/resources/configs/memconfigs/fr_fcfs.xml @@ -6,11 +6,16 @@ + + + + - \ No newline at end of file + diff --git a/dram/src/common/xmlAddressdecoder.cpp b/dram/src/common/xmlAddressdecoder.cpp index 7cb20b4a..1fb7aa26 100644 --- a/dram/src/common/xmlAddressdecoder.cpp +++ b/dram/src/common/xmlAddressdecoder.cpp @@ -60,6 +60,17 @@ DecodedAddress xmlAddressDecoder::decodeAddress(sc_dt::uint64 addr) 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"]; +} + void xmlAddressDecoder::print() { cout << "Used addressmapping:" << endl; diff --git a/dram/src/common/xmlAddressdecoder.h b/dram/src/common/xmlAddressdecoder.h index 29823346..383e436c 100755 --- a/dram/src/common/xmlAddressdecoder.h +++ b/dram/src/common/xmlAddressdecoder.h @@ -54,6 +54,8 @@ static tinyxml2::XMLElement* addressmapping; } DecodedAddress decodeAddress(sc_dt::uint64 addr); + sc_dt::uint64 encodeAddress(DecodedAddress n); + void print(); private: diff --git a/dram/src/controller/core/configuration/Configuration.cpp b/dram/src/controller/core/configuration/Configuration.cpp index 5d46c639..d073900c 100644 --- a/dram/src/controller/core/configuration/Configuration.cpp +++ b/dram/src/controller/core/configuration/Configuration.cpp @@ -78,10 +78,11 @@ void Configuration::setParameter(std::string name, std::string value) Buswidth = string2int(value); else if(name == "ReadWriteGrouping") ReadWriteGrouping = string2bool(value); - else if(name == "ModelStorage") - ModelStorage = string2bool(value); - else if(name == "ModelErrorInjection") - ModelErrorInjection = string2bool(value); + //removed because of Peters error model TODO clean up! + //else if(name == "ModelStorage") + // ModelStorage = string2bool(value); + //else if(name == "ModelErrorInjection") + // ModelErrorInjection = string2bool(value); else if(name == "ReorderBuffer") ReorderBuffer = string2bool(value); @@ -92,6 +93,13 @@ void Configuration::setParameter(std::string name, std::string value) PowerAnalysys = string2bool(value); else if(name == "Debug") Debug = string2bool(value); + //Specification for Chipseed, csvfile path and StorageMode + else if(name == "Chipseed") + Chipseed = string2int(value); + else if(name == "csvfile") + csvfile = value; + else if(name == "StorMo") + StorMode = string2int(value); else { SC_REPORT_FATAL("Configuration", ("Parameter " + name + " not defined in Configuration").c_str()); diff --git a/dram/src/controller/core/configuration/Configuration.h b/dram/src/controller/core/configuration/Configuration.h index 5383dbdb..3a5b15d4 100644 --- a/dram/src/controller/core/configuration/Configuration.h +++ b/dram/src/controller/core/configuration/Configuration.h @@ -51,6 +51,11 @@ struct Configuration void setParameter(std::string name, std::string value); void setParameters(std::map parameterMap); + //Configs for Seed, csv file and StorageMode + unsigned int Chipseed; + std::string csvfile ="not defined."; + unsigned int StorMode; + private: Configuration(); unsigned int powerDownTimeoutInClk = 3; diff --git a/dram/src/controller/core/configuration/ConfigurationLoader.cpp b/dram/src/controller/core/configuration/ConfigurationLoader.cpp index aaa4e4aa..897a1b2b 100644 --- a/dram/src/controller/core/configuration/ConfigurationLoader.cpp +++ b/dram/src/controller/core/configuration/ConfigurationLoader.cpp @@ -47,7 +47,6 @@ void ConfigurationLoader::loadConfig(Configuration& config, XMLElement* configNo void ConfigurationLoader::loadMemSpec(Configuration& config, string memspecUri) { tinyxml2::XMLDocument doc; - loadXML(memspecUri, doc); XMLElement* memspec = doc.FirstChildElement("memspec"); loadMemSpec(config, memspec); @@ -114,6 +113,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"); @@ -165,6 +165,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 ddbfc9b6..3412c38c 100644 --- a/dram/src/controller/core/configuration/MemSpec.h +++ b/dram/src/controller/core/configuration/MemSpec.h @@ -53,6 +53,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/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 new file mode 100644 index 00000000..adeeb580 --- /dev/null +++ b/dram/src/error/flip_memory.cpp @@ -0,0 +1,402 @@ +/* + * 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; + +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)); + 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; + + // path of csv file + errormap = new nest_map(Configuration::getInstance().csvfile); + + // 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; //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() +{ + cout << endl << endl << endl << "Bit-Fehler: " << BIT_ERR << endl << endl << endl; +} + +DecodedAddress flip_memory::getUnifiedNode(unsigned int addr) +{ + DecodedAddress n = xmlAddressDecoder::getInstance().decodeAddress(addr); + n.channel = 0; + 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() +{ + unsigned int maxWeakCells = errormap->getMaxWeakCells(); + + 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; 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.column++; + + // Swap around if more columns addressed than exist + if (no.column>(COLS_PER_ROW - 1)) no.column -= BURSTLENGTH*BYTES_PER_COL; + + 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::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 + DecodedAddress no; + no = getUnifiedNode(t_addr); + + + 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.column++; + + // Swap around if more columns addressed than exist + if (no.column>(COLS_PER_ROW - 1)) no.column -= BURSTLENGTH*BYTES_PER_COL; + + unsigned int addr = xmlAddressDecoder::getInstance().encodeAddress(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? + //cout << "TEST=" << refr[row] << endl; + sc_time deltaT = sc_time_stamp() - refr[row]; + + unsigned int n = errormap->getFlipRate(TEMPERATURE, deltaT); + + //cout << sc_time_stamp() << ": deltaT=" << deltaT << " n=" << n << endl; + //cout << "Flip_Memory::refresh" << 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/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: + // Remember to adjust this value by hand when editing in simulation + 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; + 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; + 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; + } + } + +}; +#endif diff --git a/dram/src/error/nest_map.cpp b/dram/src/error/nest_map.cpp new file mode 100644 index 00000000..75fb96a6 --- /dev/null +++ b/dram/src/error/nest_map.cpp @@ -0,0 +1,173 @@ +/* + * Created on: Juli, 2014 + * Author: patrick, peter + */ + +#include "nest_map.h" +#include +#include +#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; + 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)) + { + ++noOfLines; + } + input.clear(); + input.seekg(0, ios::beg); + + // Knowing the size, allocate the errormap + size = noOfLines; + tr = new quadrupel[noOfLines]; + + // Copy entries from CSV to errormap + for (unsigned int i = 0; i < noOfLines; i++) + { + getline(input, line); + + // "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 + tr[i].t = sc_time(atoi(tmp[1].c_str()), SC_MS); + + 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; +} + + +// 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 + tr[i].d; + } + } + } + return noOfWeakCells; +} + + +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 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; +} diff --git a/dram/src/error/nest_map.h b/dram/src/error/nest_map.h new file mode 100644 index 00000000..5b9134f3 --- /dev/null +++ b/dram/src/error/nest_map.h @@ -0,0 +1,56 @@ +/* + * Created on: Juli, 2014 + * Author: patrick, peter + */ + +#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 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 "6 values" with dynamic size + quadrupel *tr; + + // Number of entrys in tr[] + unsigned int size; + + // Largest value of n in tr[] + unsigned int maxWeakCells; + unsigned int maxDependentCells; + + // 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(); + unsigned int getMaxDependentCells(); +}; +#endif diff --git a/dram/src/simulation/Dram.h b/dram/src/simulation/Dram.h index 25510d86..fd0cfc83 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; @@ -49,6 +50,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 + + flip_memory * fmemory; + //Configuration::getInstance().memSpec.NumberOfBanks]; map< unsigned long int, unsigned char[BUSWIDTH/2] > memory; SC_CTOR(Dram) : tSocket("socket") @@ -57,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() @@ -65,7 +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 ); - std::cout << "Simulated Memory Size: " << memory.size() << endl; + if(StorageMode == 2) + { + 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); + 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_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(memory.count(payload.get_address()) == 1) + if (StorageMode == 1) //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 if(StorageMode == 2)// use StorageMode with errormodel { - //SC_REPORT_WARNING ("DRAM", "Reading from an empty memory location."); + 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) { 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) @@ -205,6 +289,4 @@ struct Dram: sc_module }; - - #endif /* DRAM_H_ */ diff --git a/dram/src/simulation/Simulation.cpp b/dram/src/simulation/Simulation.cpp index d04cd5ba..b2688f86 100644 --- a/dram/src/simulation/Simulation.cpp +++ b/dram/src/simulation/Simulation.cpp @@ -16,6 +16,7 @@ #include #include #include "../common/Utils.h" +#include "../error/flip_memory.h" #include "StlPlayer.h" using namespace std; diff --git a/dram/src/simulation/Simulation.h b/dram/src/simulation/Simulation.h index 0f89117a..060803c4 100644 --- a/dram/src/simulation/Simulation.h +++ b/dram/src/simulation/Simulation.h @@ -18,6 +18,7 @@ #include #include "TracePlayerListener.h" #include "../common/third_party/tinyxml2.h" +#include "../error/flip_memory.h" struct DramSetup { diff --git a/dram/src/simulation/StlPlayer.h b/dram/src/simulation/StlPlayer.h index 2bab13e9..8ea07d69 100644 --- a/dram/src/simulation/StlPlayer.h +++ b/dram/src/simulation/StlPlayer.h @@ -35,7 +35,7 @@ public: unsigned long long parsedAdress = std::stoull(address.c_str(), 0, 16); gp* payload = this->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)); diff --git a/dram/src/simulation/TracePlayer.h b/dram/src/simulation/TracePlayer.h index 0fa606ad..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(); } @@ -141,3 +154,4 @@ void TracePlayer::sendToTarget(tlm_generic_payload &payload, const tlm } #endif /* TRACEPLAYER_H_ */ +