#ifndef CACHE_MULTILEVEL_H #define CACHE_MULTILEVEL_H #include #include #include #include "cache_onelevel.h" #include "type_req_cache.h" #include "type_rsp_cache.h" using namespace std; using namespace hierarchy_memory::cache::cache_multilevel::cache_onelevel; namespace hierarchy_memory { namespace cache { namespace cache_multilevel { class param_t { public : const char * name ; public : uint32_t nb_level ; public : uint32_t nb_port ; public : param_cache_t * param_cache ; public : param_t () {}; public : param_t (const char * name , uint32_t nb_level , uint32_t nb_port , param_cache_t * param_cache ) : name (name) { //this->name = name ; this->nb_level = nb_level ; this->nb_port = nb_port ; this->param_cache = param_cache ; } friend ostream& operator<< (ostream& output_stream, const param_t & x) { output_stream << "<" << x.name << "> " << x.nb_level << " " << x.nb_port; for (uint32_t it = 0; it < x.nb_level; it ++) output_stream << endl << x.param_cache [it]; return output_stream; } };//end param_t class access_t { public : uint32_t num_port ; public : type_rsp_cache_t hit ; // result of access public : uint32_t latence ; // Latence of access public : uint32_t last_nb_level; // if access is not a hit : last level of cache before a error public : access_t (uint32_t num_port , type_rsp_cache_t hit , uint32_t latence , uint32_t last_nb_level) { this->num_port = num_port ; this->hit = hit ; this->latence = latence ; this->last_nb_level = last_nb_level; } friend ostream& operator<< (ostream& output_stream, const access_t & x) { output_stream << "[" << x.num_port << "] " << x.hit << " " << x.latence << " " << x.last_nb_level; return output_stream; } };//access_t class Cache_Multilevel { private : char * name; protected : Cache_OneLevel ** hierarchy_cache; public : const uint32_t nb_level; public : const uint32_t nb_port ; //*****[ constructor ]***** public : Cache_Multilevel (param_t param) : nb_level (param.nb_level), nb_port (param.nb_port ) { uint32_t size_name = strlen(param.name)+1; name = new char [size_name]; strncpy(name,param.name,size_name); hierarchy_cache = new Cache_OneLevel * [nb_level]; // Creation of Cache hierarchy for (uint32_t it = 0; it < nb_level; it ++) hierarchy_cache [it] = new Cache_OneLevel (cache_onelevel::param_t(param.nb_port , param.param_cache [it])); } //*****[ destructor ]***** public : ~Cache_Multilevel () { for (uint32_t it = 0; it < nb_level; it ++) delete hierarchy_cache [it]; }; //*****[ reset ]***** public : void reset () { for (uint32_t it = 0; it < nb_level; it ++) hierarchy_cache [it]->reset(); } //*****[ transition ]***** public : void transition () { for (uint32_t it = 0; it < nb_level; it ++) hierarchy_cache [it]->transition(); } //*****[ access ]***** public : access_t access (uint32_t num_port, uint32_t address, uint32_t trdid, type_req_cache_t type, direction_req_cache_t dir) { uint32_t time = 0; uint32_t last_nb_level = (nb_level==0)?0:(nb_level-1); type_rsp_cache_t hit = MISS; for (uint32_t it_nb_level = 0; it_nb_level < nb_level; it_nb_level ++) { hit = hierarchy_cache[it_nb_level]->access(num_port,address,trdid,type,dir); time += hierarchy_cache [it_nb_level]->latence (num_port); if ( (hit == HIT_CACHE) || (hit == HIT_WRITE_BUFFER) || (hit == HIT_BYPASS) ) { last_nb_level = it_nb_level; break; } } return access_t (num_port,hit,time,last_nb_level); } //*****[ update_access ]***** public : uint32_t update_access (access_t cur_access) { for (uint32_t it = 0; it < cur_access.last_nb_level; it ++) hierarchy_cache [it]->update_latence (cur_access.num_port,cur_access.latence); return cur_access.latence; } //*****[ latence ]***** // Return the time to have the data // latence is call on the same port in a single cycle, only the last access is save public : uint32_t latence (uint32_t num_port, uint32_t address, uint32_t trdid, type_req_cache_t type, direction_req_cache_t dir) { return update_access (access (num_port, address, trdid, type, dir)); } //*****[ information ]***** public : void information (void) { cout << "<" << name << ">" << endl; for (uint32_t it = 0; it < nb_level; it ++) hierarchy_cache [it]->information(); } friend ostream& operator<< (ostream& output_stream, const Cache_Multilevel & x) { output_stream << "<" << x.name << ">" << endl; for (uint32_t it = 0; it < x.nb_level; it ++) output_stream << *x.hierarchy_cache [it] << endl; return output_stream; } }; };};}; #endif //!CACHE_MULTILEVEL_H