#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(); }