#ifndef MEMORY_H #define MEMORY_H #include #include "systemc.h" #include "Common/include/BitManipulation.h" #include "Common/include/Debug.h" #include "Common/include/Log2.h" #include "Common/include/Test.h" #include "Behavioural/include/Constants.h" #include "Behavioural/include/Types.h" //================================================================{Memory_t} typedef struct { double _cycle ; uint32_t _context ; morpheo::behavioural::Tdcache_address_t _address ; morpheo::behavioural::Tdcache_type_t _type ; morpheo::behavioural::Tdcache_data_t _data_old; morpheo::behavioural::Tdcache_data_t _data_new; } trace_memory_t; class Memory_t { private : const uint32_t _nb_context; private : const uint32_t _nb_word ; private : const uint32_t _size_word ; private : const uint32_t _shift_addr; private : const morpheo::behavioural::Tdcache_address_t _mask_addr ; private : morpheo::behavioural::Tdcache_data_t ** _data ; private : std::list _trace_memory; public : Memory_t (uint32_t nb_context, uint32_t nb_word, uint32_t size_word): _nb_context (nb_context), _nb_word (nb_word ), _size_word (size_word ), _shift_addr (morpheo::log2(size_word/8)), _mask_addr (morpheo::gen_mask(_shift_addr)) { _data = new morpheo::behavioural::Tdcache_data_t * [nb_context]; for (uint32_t i=0; i(rand()); } std::cout << "=====[ Memory's information ]" << std::endl << " * _nb_context : " << _nb_context << std::endl << " * _nb_word : " << _nb_word << std::endl << " * _size_word : " << _size_word << std::endl << " * _shift_addr : " << _shift_addr << std::endl << " * _mask_addr : " << std::hex << _mask_addr << std::dec << std::endl; } public : ~Memory_t (void) { delete [] _data; } public : morpheo::behavioural::Tdcache_data_t access (uint32_t context, morpheo::behavioural::Tdcache_address_t address, morpheo::behavioural::Tdcache_type_t type, morpheo::behavioural::Tdcache_data_t data) { std::cout << "" << std::endl << " * context : " << context << std::endl << " * address : " << std::hex << address << std::dec << std::endl << " * type : " << type << std::endl << " * wdata : " << std::hex << data << std::dec << std::endl; morpheo::behavioural::Tdcache_data_t rdata; if ((type == DCACHE_TYPE_LOAD_8 ) or (type == DCACHE_TYPE_LOAD_16) or (type == DCACHE_TYPE_LOAD_32) or (type == DCACHE_TYPE_LOAD_64) ) rdata = read (context, address, type); else if ((type == DCACHE_TYPE_STORE_8 ) or (type == DCACHE_TYPE_STORE_16) or (type == DCACHE_TYPE_STORE_32) or (type == DCACHE_TYPE_STORE_64) ) rdata = write (context, address, type, data); else rdata = other (context, address, type); std::cout << " * rdata : " << std::hex << rdata << std::dec << std::endl; return rdata; } public : morpheo::behavioural::Tdcache_data_t read_lsq (uint32_t context, morpheo::behavioural::Tdcache_address_t address, morpheo::behavioural::Tdcache_type_t type) { if (context>_nb_context) TEST_KO(" nb context is too high"); morpheo::behavioural::Tdcache_address_t LSB = address & _mask_addr; morpheo::behavioural::Tdcache_address_t MSB = address >> _shift_addr; if (MSB >_nb_word) TEST_KO(" address is too high : %8.x", address); morpheo::behavioural::Tdcache_data_t data = _data [context][MSB] >> (LSB<<3); switch (type) { case OPERATION_MEMORY_LOAD_8_Z : case OPERATION_MEMORY_LOAD_16_Z : case OPERATION_MEMORY_LOAD_32_Z : case OPERATION_MEMORY_LOAD_64_Z : case OPERATION_MEMORY_LOAD_8_S : case OPERATION_MEMORY_LOAD_16_S : case OPERATION_MEMORY_LOAD_32_S : case OPERATION_MEMORY_LOAD_64_S : return morpheo::extend(_size_word,data, is_operation_memory_load_signed(type),memory_size(type)); default : TEST_KO(" invalide type"); return data; } } private : morpheo::behavioural::Tdcache_data_t read (uint32_t context, morpheo::behavioural::Tdcache_address_t address, morpheo::behavioural::Tdcache_type_t type) { // Address's Read must be aligned if ((address & _mask_addr) != 0) TEST_KO(" Address is not aligned"); if (context>_nb_context) TEST_KO(" nb context is too high"); morpheo::behavioural::Tdcache_address_t MSB = address >> _shift_addr; if (MSB >_nb_word) TEST_KO(" address is too high"); morpheo::behavioural::Tdcache_data_t rdata = _data [context][MSB]; trace_memory_t trace; trace._cycle = sc_simulation_time(); trace._context = context; trace._address = address; trace._type = type; trace._data_old = rdata; trace._data_new = rdata; _trace_memory.push_back(trace); return rdata; } private : morpheo::behavioural::Tdcache_data_t write (uint32_t context, morpheo::behavioural::Tdcache_address_t address, morpheo::behavioural::Tdcache_type_t type, morpheo::behavioural::Tdcache_data_t data) { std::cout << " * write" << std::endl; if (context>_nb_context) TEST_KO(" nb context is too high"); if (address>_nb_word) TEST_KO(" address is too high"); morpheo::behavioural::Tdcache_address_t LSB = address & _mask_addr; morpheo::behavioural::Tdcache_address_t MSB = address >> _shift_addr; std::cout << std::hex << " * LSB : " << LSB << std::endl << " * MSB : " << MSB << std::endl << std::dec; morpheo::behavioural::Tdcache_data_t data_old = _data [context][MSB]; // exemple to size_word = 32b // LSB index_min // 0 0 // 1 8 // 2 16 // 3 24 uint32_t memory_size = ((type==DCACHE_TYPE_STORE_16)?MEMORY_SIZE_16: ((type==DCACHE_TYPE_STORE_32)?MEMORY_SIZE_32: ((type==DCACHE_TYPE_STORE_64 )?MEMORY_SIZE_64:MEMORY_SIZE_8))); uint32_t index_min = LSB<<3; // *8 uint32_t index_max = index_min+memory_size; std::cout << " * type : " << type << std::endl << " * memory_size : " << memory_size << std::endl << " * index_min : " << index_min << std::endl << " * index_max : " << index_max << std::endl; morpheo::behavioural::Tdcache_data_t data_insert = data< _size_word) TEST_KO(" illegal value of index_max : %d, size_word is %d.",index_max,_size_word); morpheo::behavioural::Tdcache_data_t data_new = morpheo::insert(data_old, data_insert, index_max-1, index_min); _data [context][MSB] = data_new; std::cout << std::hex << " * data_old : " << data_old << std::endl << " * data_new : " << data_new << std::endl << std::dec; trace_memory_t trace; trace._cycle = sc_simulation_time(); trace._context = context; trace._address = address; trace._type = type; trace._data_old = data_old; trace._data_new = data_new; _trace_memory.push_back(trace); return data_old; } private : morpheo::behavioural::Tdcache_data_t other (uint32_t context, morpheo::behavioural::Tdcache_address_t address, morpheo::behavioural::Tdcache_type_t type) { trace_memory_t trace; trace._cycle = sc_simulation_time(); trace._context = context; trace._address = address; trace._type = type; trace._data_old = 0; trace._data_new = 0; _trace_memory.push_back(trace); return 0; } public : void trace (void) { for (std::list::iterator i=_trace_memory.begin(); i!= _trace_memory.end(); i++) { std::cout << "{" << i->_cycle << "}\t" << i->_context << " - "; switch(i->_type) { case DCACHE_TYPE_LOCK : std::cout << "DCACHE_TYPE_LOCK "; break; case DCACHE_TYPE_INVALIDATE : std::cout << "DCACHE_TYPE_INVALIDATE "; break; case DCACHE_TYPE_PREFETCH : std::cout << "DCACHE_TYPE_PREFETCH "; break; case DCACHE_TYPE_FLUSH : std::cout << "DCACHE_TYPE_FLUSH "; break; case DCACHE_TYPE_SYNCHRONIZATION : std::cout << "DCACHE_TYPE_SYNCHRONIZATION"; break; case DCACHE_TYPE_LOAD_8 : std::cout << "DCACHE_TYPE_LOAD_8 "; break; case DCACHE_TYPE_LOAD_16 : std::cout << "DCACHE_TYPE_LOAD_16 "; break; case DCACHE_TYPE_LOAD_32 : std::cout << "DCACHE_TYPE_LOAD_32 "; break; case DCACHE_TYPE_LOAD_64 : std::cout << "DCACHE_TYPE_LOAD_64 "; break; case DCACHE_TYPE_STORE_8 : std::cout << "DCACHE_TYPE_STORE_8 "; break; case DCACHE_TYPE_STORE_16 : std::cout << "DCACHE_TYPE_STORE_16 "; break; case DCACHE_TYPE_STORE_32 : std::cout << "DCACHE_TYPE_STORE_32 "; break; case DCACHE_TYPE_STORE_64 : std::cout << "DCACHE_TYPE_STORE_64 "; break; } std::cout << " - " << std::hex << i->_address << " : " << i->_data_old << " -> " << i->_data_new << std::endl << std::dec; } } }; inline void test_Memory_t (void) { const uint32_t _nb_context = 4; const uint32_t _size_word = 32; const uint32_t _nb_word = 100; Memory_t * memory = new Memory_t (_nb_context, _nb_word, _size_word); memory -> access (2, 0x10, DCACHE_TYPE_STORE_32, 0xdeadbeef); memory -> access (2, 0x14, DCACHE_TYPE_STORE_16, 0xdada5678); memory -> access (2, 0x16, DCACHE_TYPE_STORE_16, 0xbead1234); memory -> access (2, 0x18, DCACHE_TYPE_STORE_8 , 0x45675681); memory -> access (2, 0x19, DCACHE_TYPE_STORE_8 , 0x1f311219); memory -> access (2, 0x1a, DCACHE_TYPE_STORE_8 , 0x2e075607); memory -> access (2, 0x1b, DCACHE_TYPE_STORE_8 , 0x19811221); TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x10, DCACHE_TYPE_LOAD_32, 0), 0xdeadbeef); TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x14, DCACHE_TYPE_LOAD_32, 0), 0x12345678); TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x18, DCACHE_TYPE_LOAD_32, 0), 0x21071981); TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x10, DCACHE_TYPE_LOAD_32, 0), 0xdeadbeef); TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x10, DCACHE_TYPE_LOAD_16, 0), 0xbeef); TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x12, DCACHE_TYPE_LOAD_16, 0), 0xdead); TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x10, DCACHE_TYPE_LOAD_8 , 0), 0xef); TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x11, DCACHE_TYPE_LOAD_8 , 0), 0xbe); TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x12, DCACHE_TYPE_LOAD_8 , 0), 0xad); TEST(morpheo::behavioural::Tdcache_data_t, memory -> access (2, 0x13, DCACHE_TYPE_LOAD_8 , 0), 0xde); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x10, OPERATION_MEMORY_LOAD_8_Z ), 0x000000ef); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x10, OPERATION_MEMORY_LOAD_8_S ), 0xffffffef); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x10, OPERATION_MEMORY_LOAD_16_Z), 0x0000beef); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x10, OPERATION_MEMORY_LOAD_16_S), 0xffffbeef); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x10, OPERATION_MEMORY_LOAD_32_Z), 0xdeadbeef); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x10, OPERATION_MEMORY_LOAD_32_S), 0xdeadbeef); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x12, OPERATION_MEMORY_LOAD_8_Z ), 0x000000ad); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x12, OPERATION_MEMORY_LOAD_8_S ), 0xffffffad); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x12, OPERATION_MEMORY_LOAD_16_Z), 0x0000dead); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x12, OPERATION_MEMORY_LOAD_16_S), 0xffffdead); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x14, OPERATION_MEMORY_LOAD_8_Z ), 0x00000078); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x14, OPERATION_MEMORY_LOAD_8_S ), 0x00000078); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x18, OPERATION_MEMORY_LOAD_16_Z), 0x00001981); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x18, OPERATION_MEMORY_LOAD_16_S), 0x00001981); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x18, OPERATION_MEMORY_LOAD_32_Z), 0x21071981); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x18, OPERATION_MEMORY_LOAD_32_S), 0x21071981); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x1a, OPERATION_MEMORY_LOAD_8_Z ), 0x00000007); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x1a, OPERATION_MEMORY_LOAD_8_S ), 0x00000007); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x1a, OPERATION_MEMORY_LOAD_16_Z), 0x00002107); TEST(morpheo::behavioural::Tdcache_data_t, memory -> read_lsq (2, 0x1a, OPERATION_MEMORY_LOAD_16_S), 0x00002107); delete memory; } #endif