#ifndef HIERARCHY_MEMORY_H #define HIERARCHY_MEMORY_H #include #include #include #include #include "shared/soclib_segment_table.h" #include "shared/soclib_caches_interfaces.h" #include "hierarchy_memory/data/data.h" #include "hierarchy_memory/file/sort_file.h" #include "hierarchy_memory/file/entry.h" #include "hierarchy_memory/cache/cache.h" #include "hierarchy_memory/ramlock/ramlock.h" #include "hierarchy_memory/tty/tty.h" #include "hierarchy_memory/sim2os/sim2os.h" #include "hierarchy_memory/cache/type_req_cache.h" using namespace std; using namespace hierarchy_memory::data; using namespace hierarchy_memory::sort_file; using namespace hierarchy_memory::cache; using namespace hierarchy_memory::ramlock; using namespace hierarchy_memory::tty; using namespace hierarchy_memory::sim2os; namespace hierarchy_memory { template class param_entity_t { public : uint32_t address ; public : uint32_t size ; public : T param ; public : param_entity_t () {}; public : param_entity_t (uint32_t address , uint32_t size , T param ) { this->address = address ; this->size = size ; this->param = param ; } };//end param_entity_t class param_t { public : uint32_t nb_entity_tty; public : param_entity_t * param_tty; public : uint32_t nb_entity_ramlock; public : param_entity_t * param_ramlock; public : param_entity_t param_sim2os; public : cache::param_t param_cache; public : param_t () {}; public : param_t (uint32_t nb_entity_tty , param_entity_t * param_tty , uint32_t nb_entity_ramlock , param_entity_t * param_ramlock , param_entity_t param_sim2os , cache::param_t param_cache) { this->nb_entity_tty = nb_entity_tty; this->param_tty = param_tty; this->nb_entity_ramlock = nb_entity_ramlock; this->param_ramlock = param_ramlock; this->param_sim2os = param_sim2os; this->param_cache = param_cache; } };//end param_t template class HIERARCHY_MEMORY : sc_module { //--------------------------------------------------------------------------------------------- //-----[ PORT ]-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- public : sc_in_clk CLK; public : sc_in NRESET; public : ICACHE_CACHE_PORTS ** ICACHE; public : DCACHE_CACHE_PORTS ** DCACHE; //--------------------------------------------------------------------------------------------- //-----[ INTERNAL SIGNAL ]--------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- private: bool ** irsp_val; private: bool ** drsp_val; private: bool ** ireq_ack; private: bool ** dreq_ack; //--------------------------------------------------------------------------------------------- //-----[ COMPONENT ]--------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- private: Data * component_data; private: Sort_File ** component_buffer_irsp; private: Sort_File ** component_buffer_drsp; private: Sim2os * component_sim2os; private: Tty ** component_tty; private: Ramlock ** component_ramlock; private: Cache * component_cache; //--------------------------------------------------------------------------------------------- //-----[ VARIABLE ] --------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- private: char * NAME; // instance name private: uint32_t * nb_iport; private: uint32_t * nb_dport; private: const uint32_t nb_context; private: const uint32_t nb_entity; private: const uint32_t nb_entity_tty; private: const uint32_t nb_entity_ramlock; private: char ** read_iram; private: char * read_dram; private: char * write_dram; private: bool * context_stop; // to determine which context have send the signal stop (a same thread can send many signal) private: uint32_t nb_context_stop; // stop the simulation when all context have send the stop signal //--------------------------------------------------------------------------------------------- //-----[ CONSTRUCTOR ]------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- SC_HAS_PROCESS(HIERARCHY_MEMORY); public : HIERARCHY_MEMORY (// Fixe parameter sc_module_name insname , uint32_t globalIndex , // VCI target index uint32_t localIndex , SOCLIB_SEGMENT_TABLE * segtab , // segment table pointer // variable parameter uint32_t nb_entity , uint32_t nb_context , //*****[ buffer respons ]***** uint32_t size_buffer_irsp , uint32_t size_buffer_drsp , //*****[ entity_param ]***** param_t param ): nb_context (nb_context ), nb_entity (nb_entity ), nb_entity_tty (param.nb_entity_tty ), nb_entity_ramlock (param.nb_entity_ramlock) { uint32_t size_name = strlen(insname)+1; NAME = new char [size_name]; strncpy(NAME,insname,size_name); // *****[ Signal creation ]***** ICACHE = new ICACHE_CACHE_PORTS * [nb_entity]; DCACHE = new DCACHE_CACHE_PORTS * [nb_entity]; nb_iport = new uint32_t [nb_entity]; nb_dport = new uint32_t [nb_entity]; irsp_val = new bool * [nb_entity]; drsp_val = new bool * [nb_entity]; ireq_ack = new bool * [nb_entity]; dreq_ack = new bool * [nb_entity]; for (uint32_t it = 0; it < nb_entity; it++) { nb_iport [it] = param.param_cache.param_icache_dedicated [it].nb_port; nb_dport [it] = param.param_cache.param_dcache_dedicated [it].nb_port; irsp_val [it] = new bool [nb_iport[it]]; drsp_val [it] = new bool [nb_dport[it]]; ireq_ack [it] = new bool [nb_iport[it]]; dreq_ack [it] = new bool [nb_dport[it]]; ICACHE [it] = new ICACHE_CACHE_PORTS [nb_iport [it]]; DCACHE [it] = new DCACHE_CACHE_PORTS [nb_dport [it]]; } read_iram = new char * [NB_IWORD]; for (unsigned int num_word = 0; num_word < NB_IWORD; num_word ++) read_iram [num_word] = new char [SIZE_IDATA/8]; read_dram = new char [SIZE_DDATA/8]; write_dram = new char [SIZE_DDATA/8]; // *****[ Create internal structure ]***** component_data = new Data (data::param_t("component_data", 16, globalIndex, localIndex, segtab)); component_buffer_irsp = new Sort_File * [nb_entity]; component_buffer_drsp = new Sort_File * [nb_entity]; for (uint32_t it = 0; it < nb_entity; it++) { char name [100]; sprintf(name,"component_buffer_irsp[%d]",it); component_buffer_irsp [it] = new Sort_File (sort_file::param_t(name,size_buffer_irsp)); sprintf(name,"component_buffer_drsp[%d]",it); component_buffer_drsp [it] = new Sort_File (sort_file::param_t(name,size_buffer_drsp)); } component_cache = new Cache (param.param_cache); component_tty = new Tty * [nb_entity_tty ]; component_ramlock = new Ramlock * [nb_entity_ramlock]; for (uint32_t it = 0; it < nb_entity_tty ; it++) { component_tty [it] = new Tty (param.param_tty[it] .param); entity_t entity = component_data->entity(param.param_tty[it].address, param.param_tty[it].size); if (entity.present == false) { cerr << " the tty [" << it << "] have not a segment in the segment table" << endl; exit (1); } entity.segment->define_target(TYPE_TTY,it); } for (uint32_t it = 0; it < nb_entity_ramlock; it++) { component_ramlock [it] = new Ramlock (param.param_ramlock[it].param); entity_t entity = component_data->entity(param.param_ramlock[it].address, param.param_ramlock[it].size); if (entity.present == false) { cerr << " the ramlock [" << it << "] have not a segment in the segment table" << endl; exit (1); } entity.segment->define_target(TYPE_RAMLOCK,it); } component_sim2os = new Sim2os (param.param_sim2os.param); entity_t entity = component_data->entity(param.param_sim2os.address, param.param_sim2os.size); if (entity.present == false) { cerr << " the sim2os have not a segment in the segment table" << endl; exit (1); } entity.segment->define_target(TYPE_SIM2OS,0); nb_context_stop = 0; context_stop = new bool [1< Successful Instanciation" << endl; }; //--------------------------------------------------------------------------------------------- //-----[ DESTRUCTOR ]-------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- public : ~HIERARCHY_MEMORY () { for (uint32_t it = 0; it < nb_entity_ramlock; it++) delete component_ramlock [it]; for (uint32_t it = 0; it < nb_entity_tty ; it++) delete component_tty [it]; for (uint32_t it = 0; it < nb_entity ; it++) { delete component_buffer_drsp [it]; delete component_buffer_irsp [it]; } delete component_cache ; delete component_data ; delete component_sim2os ; } //--------------------------------------------------------------------------------------------- //-----[ req_type2cache_type ]----------------------------------------------------------------- //--------------------------------------------------------------------------------------------- class req_type2cache_type_t { public : type_req_cache_t type ; public : direction_req_cache_t direction ; public : req_type2cache_type_t () {}; public : req_type2cache_type_t (type_req_cache_t type , direction_req_cache_t direction ) { this->type = type ; this->direction = direction; }; }; req_type2cache_type_t ireq_type2cache_type (uint32_t ireq_type, bool uncached) { type_req_cache_t type ; direction_req_cache_t direction; switch (ireq_type) { case ITYPE_READ : direction=READ ; type=CACHED ; break; case ITYPE_INVALIDATE : direction=NONE ; type=INVALIDATE; break; case ITYPE_PREFETCH : direction=NONE ; type=PREFETCH ; break; default : cerr << " Unkown type (" << type << ")" << endl; exit(1); } return req_type2cache_type_t (type,direction); } req_type2cache_type_t dreq_type2cache_type (uint32_t dreq_type, bool uncached) { type_req_cache_t type ; direction_req_cache_t direction; switch (dreq_type) { case DTYPE_READ : direction=READ ; type=((uncached==true)?UNCACHED:CACHED); break; case DTYPE_INVALIDATE : direction=NONE ; type=INVALIDATE ; break; case DTYPE_WRITE : direction=WRITE; type=((uncached==true)?UNCACHED:CACHED); break; case DTYPE_WRITE_ACK : direction=WRITE; type=((uncached==true)?UNCACHED:CACHED); break; case DTYPE_FLUSH : direction=NONE ; type=FLUSH ; break; case DTYPE_PREFETCH : direction=NONE ; type=INVALIDATE ; break; default : cerr << " Unkown type (" << type << ")" << endl; exit(1); } return req_type2cache_type_t (type,direction); } //--------------------------------------------------------------------------------------------- //-----[ init ]-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- public : bool init (char * section, const char * filename, const char ** list_section) { return component_data->init(section,filename,list_section); } //--------------------------------------------------------------------------------------------- //-----[ reset ]------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- public : void reset () { component_cache -> reset(); // Reset buffer of respons for (uint32_t it = 0; it < nb_entity; it++) { component_buffer_irsp [it] ->reset(); component_buffer_drsp [it] ->reset(); } for (uint32_t it = 0; it < nb_entity_ramlock; it++) component_ramlock [it] ->reset(); for (uint32_t it = 0; it < nb_entity_tty ; it++) component_tty [it] ->reset(); }//end reset //--------------------------------------------------------------------------------------------- //-----[ itoa ]-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- private :char * itoa (uint32_t int_src, char * string_dest, uint32_t size) { for (unsigned int it_size = 0; it_size < size; it_size ++) { string_dest [it_size] = (int_src & 0xFF); //string_dest [size-it_size-1] = (int_src & 0xFF); int_src >>= 8; } return string_dest; } //--------------------------------------------------------------------------------------------- //-----[ stop ]-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- public : bool stop () { return (nb_context_stop >= nb_context); } //--------------------------------------------------------------------------------------------- //-----[ transition ]-------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- public : void transition() { if (NRESET.read() == false) { reset (); return; } //~~~~~[ respons ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // POP All buffer of respons for (uint32_t num_entity = 0; num_entity < nb_entity; num_entity++) { for (uint32_t num_port = nb_iport [num_entity]; num_port > 0 ; num_port --) if ((irsp_val[num_entity][num_port-1] && ICACHE [num_entity][num_port-1].RSP_ACK.read())==true) component_buffer_irsp [num_entity]->pop(num_port-1); for (uint32_t num_port = nb_dport [num_entity]; num_port > 0 ; num_port --) if ((drsp_val[num_entity][num_port-1] && DCACHE [num_entity][num_port-1].RSP_ACK.read())==true) component_buffer_drsp [num_entity]->pop(num_port-1); } //~~~~~[ request ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // cout << "" << endl; for (uint32_t num_entity = 0; num_entity < nb_entity; num_entity++) { // ****************** // ***** ICACHE ***** // ****************** for (uint32_t num_port = 0; num_port < nb_iport [num_entity]; num_port ++) { // Test if transaction if ( (ICACHE [num_entity][num_port].REQ_VAL.read() && ireq_ack [num_entity][num_port]) == false) continue; entity_t entity = component_data->entity((uint32_t)ICACHE [num_entity][num_port].REQ_ADDR.read(), SIZE_IDATA/8); bool uncached = false; bool bus_error = false; sc_uint<2> type = ICACHE[num_entity][num_port].REQ_TYPE .read(); // A lot of flag bool must_read = ((type == DTYPE_READ ) ); bool must_ack = ((type == DTYPE_READ ) ); // Test the type of the address : if != MEMORY -> error if ((entity.present == true) && (entity.segment->getType() == TYPE_MEMORY)) { if (must_read == true) // Test if must read the ram for (unsigned int num_word = 0; num_word < NB_IWORD; num_word ++) { uint32_t addr = (uint32_t) ICACHE [num_entity][num_port].REQ_ADDR.read()+num_word*(SIZE_IDATA/8); bus_error |= !component_data->read(addr , SIZE_IDATA/8 , read_iram[num_word]); if (isSameEndianness((uint32_t)ICACHE[num_entity][num_port].REQ_TRDID.read()) == false) read_iram[num_word] = swapBytes(read_iram[num_word],SIZE_IDATA/8,4); } uncached = entity.segment->getUncached(); } else { // Have a bus error bus_error = true; uncached = true; } req_type2cache_type_t cache_type = ireq_type2cache_type ((uint32_t)type,uncached); // Simplification : the size of a line is a multiple of size_iword (no test) uint32_t latence = component_cache->latence(INSTRUCTION_CACHE , num_entity , num_port , (uint32_t)ICACHE [num_entity][num_port].REQ_ADDR .read() , (uint32_t)ICACHE [num_entity][num_port].REQ_TRDID.read() , cache_type.type , cache_type.direction ); // If is a respons -> compute the latence and push in the write_buffer if (must_ack == true) { if (bus_error == true) cout << "Icache : have a bus error" << endl << " * num_entity : " << num_entity << endl << " * num_port : " << num_port << endl << hex << " * req_addr : " << (uint32_t)ICACHE [num_entity][num_port].REQ_ADDR .read() << endl << dec << " * req_trdid : " << (uint32_t)ICACHE [num_entity][num_port].REQ_TRDID.read() << endl << " * req_pktid : " << (uint32_t)ICACHE [num_entity][num_port].REQ_PKTID.read() << endl; component_buffer_irsp [num_entity]->push(latence, Entry((uint32_t)ICACHE [num_entity][num_port].REQ_TRDID.read() , (uint32_t)ICACHE [num_entity][num_port].REQ_PKTID.read() , NB_IWORD , SIZE_IDATA/8 , read_iram , (bus_error==true)?ERR_BUS:ERR_NO ) ); } }//num_port // ****************** // ***** DCACHE ***** // ****************** for (uint32_t num_port = 0; num_port < nb_dport [num_entity]; num_port ++) { // Test if transaction // cout << "[" << num_entity << "]" // << "[" << num_port << "] " // << "dreq_val : " << DCACHE [num_entity][num_port].REQ_VAL.read() << " " // << "dreq_ack : " << dreq_ack [num_entity][num_port] << endl; if ( (DCACHE [num_entity][num_port].REQ_VAL.read() && dreq_ack [num_entity][num_port]) == false) continue; entity_t entity = component_data->entity((uint32_t)DCACHE [num_entity][num_port].REQ_ADDR.read(), SIZE_DDATA/8); bool uncached = DCACHE [num_entity][num_port].REQ_UNC.read(); bool bus_error = false; uint32_t addr = (uint32_t) DCACHE [num_entity][num_port].REQ_ADDR.read(); sc_uint wdata = DCACHE[num_entity][num_port].REQ_WDATA .read(); sc_uint<3> type = DCACHE[num_entity][num_port].REQ_TYPE .read(); uint32_t nb_bytes = access_nb_bytes(DCACHE[num_entity][num_port].REQ_ACCESS.read()); // A lot of flag bool must_read = ((type == DTYPE_READ )); bool must_write = ((type == DTYPE_WRITE ) || (type == DTYPE_WRITE_ACK ) ); bool must_ack = ((type == DTYPE_READ ) || (type == DTYPE_WRITE_ACK ) ); // Test the type of the address if (entity.present == true) { switch (entity.segment->getType()) { // ACCESS AT A RAM case TYPE_MEMORY : { if (must_read == true) { // Read bus_error |= !component_data->read(addr , SIZE_DDATA/8 , // always read a complete word read_dram ); for (unsigned int it_size_data = nb_bytes; it_size_data < SIZE_DDATA/8; it_size_data+=nb_bytes) memcpy(&(read_dram[it_size_data]),&(read_dram[0]),nb_bytes); // Permutation if problem of endianness if (isSameEndianness((uint32_t)DCACHE[num_entity][num_port].REQ_TRDID.read()) == false) read_dram = swapBytes(read_dram , SIZE_DDATA/8, nb_bytes); } if (must_write == true) { // Write for (unsigned int it_nb_bytes = 0; it_nb_bytes < SIZE_DDATA / 8; it_nb_bytes ++) write_dram [it_nb_bytes] = wdata.range(8*(it_nb_bytes+1)-1,8*it_nb_bytes); } break; } //ACCESS AT THE TTY case TYPE_TTY : { if (must_write == false) { bus_error = true; break; } uint32_t num_tty = (addr - entity.segment->getBase())>>4; uint32_t num_print = ((addr>>2) & 0x3); switch (num_print) { case 0 : // Write TTY { uint32_t num_component_tty = entity.segment->getIndex(); char char_write = (char)wdata.range( 7, 0); bus_error |= !component_tty [num_component_tty]->write(num_tty,char_write); break; } case 1 : // STOP { printf("\n\t***** [ stop ] Time : %.10d - Address : %.8x - Wdata[31:0] : %.2x%.2x%.2x%.2x *****\n" ,(unsigned int)sc_simulation_time() ,(unsigned int)addr ,(unsigned int)wdata.range(31,24) ,(unsigned int)wdata.range(23,16) ,(unsigned int)wdata.range(15, 8) ,(unsigned int)wdata.range( 7, 0) ); uint32_t trdid = (uint32_t) DCACHE[num_entity][num_port].REQ_TRDID.read(); if (context_stop [trdid] == false) { context_stop [trdid] = true; nb_context_stop ++; if (nb_context_stop >= nb_context) sc_stop(); } break; } case 2 : // PRINT { printf("\n\t----- [ print ] Time : %.10d - Address : %.8x - Wdata[31:0] : %.2x%.2x%.2x%.2x -----\n" ,(unsigned int)sc_simulation_time() ,(unsigned int)addr ,(unsigned int)wdata.range(31,24) ,(unsigned int)wdata.range(23,16) ,(unsigned int)wdata.range(15, 8) ,(unsigned int)wdata.range( 7, 0) ); break; } default : { printf("<%s> : [address : %.8x] tty %d, reg %d don't exist\n",NAME,(unsigned int)addr,num_tty,num_print); exit(1); } } break; } case TYPE_RAMLOCK : { // Access is on a byte, else error if (nb_bytes != 1) { bus_error = true; break; } uint32_t num_ramlock = (addr - entity.segment->getBase()); // Char access uint32_t num_component_ramlock = entity.segment->getIndex(); bus_error |= !component_ramlock [num_component_ramlock]->test(num_ramlock); if (bus_error == true) break; memset (read_dram,0,SIZE_DDATA/8); if (must_read == true) read_dram [0] = (char)component_ramlock [num_component_ramlock]->read (num_ramlock); if (must_write == true) read_dram [0] = (char)component_ramlock [num_component_ramlock]->write(num_ramlock); /* printf("Access ramlock ( %d )\n" ,(uint32_t)sc_simulation_time()); printf(" * addr : %.8x\n" ,(uint32_t)addr); printf(" * trdid : %d\n" ,(uint32_t)DCACHE[num_entity][num_port].REQ_TRDID.read()); printf(" * r/w : %d/%d\n",must_read,must_write); printf(" * val : %d\n" ,(uint32_t)read_dram[0]); */ break; } case TYPE_SIM2OS : { // Mapping : // [0] number of service - Wonly - A write in this register lunch the execution of service // [1] result - Ronly - Content the result of the service // [2] error - Ronly - Content the code of errno // [3+] argument - Wonly - it's all argument to execute the service uint32_t num_reg = (addr - entity.segment->getBase())>>2; switch (num_reg) { case 0 : // ---> number of service { if (must_write == false) { cerr << "<" << NAME << "> {ERROR} : SIM2OS[0] is not accessible in Read" << endl; bus_error = true; } else { printf(" service : %.8x\n",(uint32_t)wdata); component_sim2os->execute(int2service((uint32_t)wdata)); } break; } case 1 : // ---> result { if (must_read == false) { cerr << "<" << NAME << "> {ERROR} : SIM2OS[1] is not accessible in Write" << endl; bus_error = true; } else { // Decomposition en groupe octect uint32_t result = (uint32_t) component_sim2os->result; printf(" result : %.8x (%d)\n",result,result); read_dram = itoa(result,read_dram,SIZE_DDATA/8); } break; } case 2 : // ---> error { if (must_read == false) { cerr << "<" << NAME << "> {ERROR} : SIM2OS[2] is not accessible in Write" << endl; bus_error = true; } else { // Decomposition en groupe octect uint32_t error = (uint32_t) component_sim2os->error; printf(" error : %.8x\n",error); read_dram = itoa(error ,read_dram,SIZE_DDATA/8); } break; } default : // ---> argument { if (must_write == false) { cerr << "<" << NAME << "> {ERROR} : SIM2OS[" << num_reg << "] is not accessible in Write" << endl; bus_error = true; } else { uint32_t data = (uint32_t)wdata; printf(" argument[%d] : %.8x\n",num_reg-1,data); component_sim2os->parameter(num_reg-2,(void *)data); } break; } }//end switch num_reg break; } default : { // Have a bus error bus_error = true; break; } }// switch uncached |= entity.segment->getUncached(); } else uncached = true; // If segment don't exist : it's the system bus that determine if the segment exist if ((must_write == true) && (bus_error == false)) { // Permutation if problem of endianness if (isSameEndianness((uint32_t)DCACHE[num_entity][num_port].REQ_TRDID.read()) == false) write_dram = swapBytes(write_dram, SIZE_DDATA/8, nb_bytes); bus_error |= !component_data->write(addr , nb_bytes, // take the good access write_dram ); } // Acces at the cache !!! req_type2cache_type_t cache_type = dreq_type2cache_type (type, uncached); uint32_t latence = component_cache->latence(DATA_CACHE , num_entity , num_port , (uint32_t)DCACHE [num_entity][num_port].REQ_ADDR .read() , (uint32_t)DCACHE [num_entity][num_port].REQ_TRDID.read() , cache_type.type , cache_type.direction ); // If is a respons -> compute the latence and push in the write_buffer if ( must_ack == true) { if (bus_error == true) cout << "Dcache : have a bus error" << endl; component_buffer_drsp [num_entity]->push(latence, Entry((uint32_t)DCACHE [num_entity][num_port].REQ_TRDID.read() , (uint32_t)DCACHE [num_entity][num_port].REQ_PKTID.read() , 1 , SIZE_DDATA/8 , &read_dram , (bus_error==true)?ERR_BUS:ERR_NO ) ); } }// dnb_port }//num_entity // Transition for each component component_cache -> transition(); // Transition buffer of respons for (uint32_t it = 0; it < nb_entity; it++) { component_buffer_irsp [it] ->transition(); component_buffer_drsp [it] ->transition(); } component_sim2os->transition(); }//end transition //--------------------------------------------------------------------------------------------- //-----[ genMoore ]---------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- public : void genMoore() { //Scan all entity and for each entity scan all port for (uint32_t num_entity = 0; num_entity < nb_entity; num_entity++) { //##### REQUEST ##### uint32_t nb_slot_free = component_buffer_irsp [num_entity]->nb_slot_free (); for (uint32_t num_port = 0; num_port < nb_iport [num_entity]; num_port ++) { ireq_ack [num_entity][num_port] = (num_port < nb_slot_free); ICACHE [num_entity][num_port].REQ_ACK.write (ireq_ack [num_entity][num_port]); } nb_slot_free = component_buffer_drsp [num_entity]->nb_slot_free (); for (uint32_t num_port = 0; num_port < nb_dport [num_entity]; num_port ++) { dreq_ack [num_entity][num_port] = (num_port < nb_slot_free ); DCACHE [num_entity][num_port].REQ_ACK.write (dreq_ack [num_entity][num_port]); } //##### RESPONS ##### // ~~~~~> ICACHE <~~~~~ for (uint32_t num_port = 0; num_port < nb_iport [num_entity]; num_port ++) { // Test the number of element in the respons's buffer if (num_port >= component_buffer_irsp [num_entity]->nb_slot_use()) { irsp_val[num_entity][num_port] = 0; // No respons } else { slot_t slot = component_buffer_irsp [num_entity]->read(num_port); irsp_val[num_entity][num_port] = (slot.delay == 0); // respons if have a result ICACHE [num_entity][num_port].RSP_TRDID.write((sc_uint )slot.data.trdid); ICACHE [num_entity][num_port].RSP_PKTID.write((sc_uint)slot.data.pktid); ICACHE [num_entity][num_port].RSP_ERR .write((sc_uint<2> )slot.data.error); for (uint32_t num_word = 0; num_word < NB_IWORD; num_word ++) { sc_uint data; for (unsigned int it_nb_bytes = 0; it_nb_bytes < SIZE_IDATA / 8; it_nb_bytes ++) { #if defined(systemcass) RANGE_SET_VAL(SIZE_IDATA , data , 8*(it_nb_bytes+1)-1, 8*it_nb_bytes , slot.data.data [num_word][it_nb_bytes]); #else //#elif defined(systemc) data.range(8*(it_nb_bytes+1)-1,8*it_nb_bytes) = slot.data.data [num_word][it_nb_bytes]; #endif } ICACHE [num_entity][num_port].RSP_INS [num_word].write(data); } } ICACHE [num_entity][num_port].RSP_VAL.write(irsp_val[num_entity][num_port]); }//end nb_iport // ~~~~~> DCACHE <~~~~~ for (uint32_t num_port = 0; num_port < nb_dport [num_entity]; num_port ++) { if (num_port >= component_buffer_drsp [num_entity]->nb_slot_use()) { drsp_val[num_entity][num_port] = 0; // No respons } else { slot_t slot = component_buffer_drsp [num_entity]->read(num_port); drsp_val[num_entity][num_port] = (slot.delay == 0); DCACHE [num_entity][num_port].RSP_TRDID = (sc_uint )slot.data.trdid; DCACHE [num_entity][num_port].RSP_PKTID = (sc_uint)slot.data.pktid; DCACHE [num_entity][num_port].RSP_ERR = (sc_uint<2> )slot.data.error; sc_uint data; for (unsigned int it_nb_bytes = 0; it_nb_bytes < SIZE_DDATA / 8; it_nb_bytes ++) { #if defined(systemcass) RANGE_SET_VAL(SIZE_DDATA , data , 8*(it_nb_bytes+1)-1, 8*it_nb_bytes , slot.data.data [0][it_nb_bytes]); #else //#elif defined(systemc) data.range(8*(it_nb_bytes+1)-1,8*it_nb_bytes) = slot.data.data [0][it_nb_bytes]; #endif } DCACHE [num_entity][num_port].RSP_RDATA.write(data); } DCACHE [num_entity][num_port].RSP_VAL = drsp_val[num_entity][num_port]; }//nb_dport }//nb_entity }//end genMoore //--------------------------------------------------------------------------------------------- //-----[ operator<< ]-------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- friend ostream& operator<< (ostream& output_stream, const HIERARCHY_MEMORY &x) { output_stream << "<" << x.NAME << ">" << endl << " * nb_entity : " << x.nb_entity << endl; output_stream << " -----[ component_data ]-----------------------------------" << endl; output_stream << *x.component_data << endl; output_stream << " -----[ component_cache ]----------------------------------" << endl; output_stream << *x.component_cache; output_stream << " -----[ component_buffer_irsp ]----------------------------" << endl; for (uint32_t num_entity = 0; num_entity < x.nb_entity; num_entity++) { output_stream << " * nb_iport [" << num_entity << "] : " << x.nb_iport [num_entity] << endl; output_stream << *x.component_buffer_irsp [num_entity]; } output_stream << " -----[ component_buffer_drsp ]----------------------------" << endl; for (uint32_t num_entity = 0; num_entity < x.nb_entity; num_entity++) { output_stream << " * nb_dport [" << num_entity << "] : " << x.nb_dport [num_entity] << endl; output_stream << *x.component_buffer_drsp [num_entity]; } // output_stream << " -----[ component_ramlock ]--------------------------------" << endl; // output_stream << " * nb_entity_ramlock : " << x.nb_entity_ramlock << endl; // for (uint32_t it = 0; it < x.nb_entity_ramlock; it++) // output_stream << *x.component_ramlock [it]; // output_stream << " -----[ component_tty ]------------------------------------" << endl; // output_stream << " * nb_entity_tty : " << x.nb_entity_tty << endl; // for (uint32_t it = 0; it < x.nb_entity_tty ; it++) // output_stream << *x.component_tty [it]; // output_stream << *x.component_sim2os; return output_stream; } };//class }; #endif //!HIERARCHY_MEMORY_H