/* * $Id: Parameters.cpp 81 2008-04-15 18:40:01Z rosiere $ * * [ Description ] * */ #include "Behavioural/Core/Multi_Execute_loop/Execute_loop/include/Parameters.h" namespace morpheo { namespace behavioural { namespace core { namespace multi_execute_loop { namespace execute_loop { #undef FUNCTION #define FUNCTION "Execute_loop::Parameters" Parameters::Parameters (uint32_t nb_read_unit , uint32_t nb_functionnal_unit , uint32_t nb_load_store_unit , uint32_t nb_write_unit , uint32_t nb_context , uint32_t nb_front_end , uint32_t nb_ooo_engine , uint32_t nb_packet , uint32_t size_general_data , uint32_t size_special_data , uint32_t * size_read_queue , uint32_t * size_reservation_station , uint32_t * nb_inst_retire , execute_timing_t *** timing , morpheo::behavioural::custom::custom_information_t (*get_custom_information) (uint32_t), uint32_t * size_store_queue , uint32_t * size_load_queue , uint32_t * size_speculative_access_queue , uint32_t * nb_port_check , Tspeculative_load_t * speculative_load , uint32_t * nb_bypass_memory , uint32_t * size_write_queue , uint32_t * size_execute_queue , uint32_t * nb_bypass_write , uint32_t nb_gpr_bank , uint32_t nb_gpr_port_read_by_bank , uint32_t nb_gpr_port_write_by_bank , uint32_t nb_spr_bank , uint32_t nb_spr_port_read_by_bank , uint32_t nb_spr_port_write_by_bank , uint32_t * nb_general_register , uint32_t * nb_special_register , uint32_t * nb_inst_insert_rob , uint32_t * nb_inst_retire_rob , Tpriority_t execution_unit_to_write_unit_priority , bool ** execution_unit_to_write_unit_table_routing, bool ** execution_unit_to_write_unit_table_thread , Tpriority_t read_unit_to_execution_unit_priority , bool ** read_unit_to_execution_unit_table_routing , bool ** read_unit_to_execution_unit_table_thread ) { log_printf(FUNC,Execute_loop,FUNCTION,"Begin"); _nb_read_unit = nb_read_unit ; _nb_functionnal_unit = nb_functionnal_unit ; _nb_load_store_unit = nb_load_store_unit ; _nb_write_unit = nb_write_unit ; _nb_context = nb_context ; _nb_front_end = nb_front_end ; _nb_ooo_engine = nb_ooo_engine ; _nb_packet = nb_packet ; _size_general_data = size_general_data ; _size_special_data = size_special_data ; _size_read_queue = size_read_queue ; _size_reservation_station = size_reservation_station ; _nb_inst_retire = nb_inst_retire ; _timing = timing ; _get_custom_information = get_custom_information ; _size_store_queue = size_store_queue ; _size_load_queue = size_load_queue ; _size_speculative_access_queue = size_speculative_access_queue ; _nb_port_check = nb_port_check ; _speculative_load = speculative_load ; _nb_bypass_memory = nb_bypass_memory ; _size_write_queue = size_write_queue ; _size_execute_queue = size_execute_queue ; _nb_bypass_write = nb_bypass_write ; _nb_gpr_bank = nb_gpr_bank ; _nb_gpr_port_read_by_bank = nb_gpr_port_read_by_bank ; _nb_gpr_port_write_by_bank = nb_gpr_port_write_by_bank ; _nb_spr_bank = nb_spr_bank ; _nb_spr_port_read_by_bank = nb_spr_port_read_by_bank ; _nb_spr_port_write_by_bank = nb_spr_port_write_by_bank ; _nb_general_register = nb_general_register ; _nb_special_register = nb_special_register ; _nb_inst_insert_rob = nb_inst_insert_rob ; _nb_inst_retire_rob = nb_inst_retire_rob ; _execution_unit_to_write_unit_priority = execution_unit_to_write_unit_priority; _execution_unit_to_write_unit_table_routing = execution_unit_to_write_unit_table_routing; _execution_unit_to_write_unit_table_thread = execution_unit_to_write_unit_table_thread ; _read_unit_to_execution_unit_priority = read_unit_to_execution_unit_priority ; _read_unit_to_execution_unit_table_routing = read_unit_to_execution_unit_table_routing ; _read_unit_to_execution_unit_table_thread = read_unit_to_execution_unit_table_thread ; _nb_execute_unit = _nb_functionnal_unit + _nb_load_store_unit; _size_context_id = log2(nb_context ); _size_front_end_id = log2(nb_front_end ); _size_ooo_engine_id = log2(nb_ooo_engine ); _size_packet_id = log2(nb_packet ); _have_port_context_id = _size_context_id >= 1; _have_port_front_end_id = _size_front_end_id >= 1; _have_port_ooo_engine_id = _size_ooo_engine_id >= 1; _have_port_packet_id = _size_packet_id >= 1; _is_load_store_unit = new bool [_nb_execute_unit]; _translate_num_execute_unit = new uint32_t [_nb_execute_unit]; _read_unit_to_execution_unit_table_execute_type = new bool * [_nb_execute_unit]; for (uint32_t i=0; i<_nb_execute_unit; i++) { _is_load_store_unit [i] = false; _read_unit_to_execution_unit_table_execute_type [i] = new bool [_nb_type]; for (uint32_t j=0; j<_nb_type; j++) _read_unit_to_execution_unit_table_execute_type [i][j] = false; } // Fill execute_type for (uint32_t i=0; i<_nb_execute_unit; i++) for (uint32_t j=0; j<_nb_type; j++) for (uint32_t k=0; k<_nb_operation; k++) // Test if operation is implemnted if (timing[i][j][k]._latence > 0) { _read_unit_to_execution_unit_table_execute_type [i][j] = true; _is_load_store_unit [i] = (j == TYPE_MEMORY); break; } for (uint32_t i=0; i<_nb_execute_unit; i++) if (_is_load_store_unit [i]) log_printf(TRACE,Execute_loop,FUNCTION,"Execute unit '%d' is a Load Store unit",i); else log_printf(TRACE,Execute_loop,FUNCTION,"Execute unit '%d' is a Functionnal unit",i); _nb_gpr_read = 2*_nb_read_unit; _nb_spr_read = 1*_nb_read_unit; _nb_gpr_write = 1*_nb_write_unit; _nb_spr_write = 1*_nb_write_unit; _max_nb_general_register = 0; _max_nb_special_register = 0; for (uint32_t i=0; i _max_nb_general_register) _max_nb_general_register = _nb_general_register[i]; if (_nb_special_register[i] > _max_nb_special_register) _max_nb_special_register = _nb_special_register[i]; } _max_size_store_queue = 0; _max_size_load_queue = 0; for (uint32_t i=0; i _max_size_store_queue) _max_size_store_queue = _size_store_queue[i]; if (_size_load_queue [i] > _max_size_load_queue ) _max_size_load_queue = _size_load_queue [i]; } _have_port_load_queue_ptr= _max_size_load_queue >= 2; _size_general_register = log2(_max_nb_general_register); _size_special_register = log2(_max_nb_special_register); uint32_t _nb_thread = get_nb_thread(_nb_context, _nb_front_end, _nb_ooo_engine); _set_read_unit_source_register_write = new std::set [_nb_read_unit]; _set_read_unit_source_bypass_write = new std::set [_nb_read_unit]; _set_read_unit_source_bypass_memory = new std::set [_nb_read_unit]; _read_unit_nb_register_write = new uint32_t [_nb_read_unit]; _read_unit_nb_bypass_write = new uint32_t [_nb_read_unit]; _read_unit_nb_bypass_memory = new uint32_t [_nb_read_unit]; _link_read_unit_with_load_store_unit = new bool * [nb_read_unit]; _link_read_unit_with_write_unit = new bool * [nb_read_unit]; _link_read_unit_with_thread = new bool * [nb_read_unit]; for (uint32_t i=0; i<_nb_read_unit; i++) { _read_unit_nb_register_write [i] = 0; _read_unit_nb_bypass_write [i] = 0; _read_unit_nb_bypass_memory [i] = 0; _link_read_unit_with_load_store_unit [i] = new bool [_nb_execute_unit]; _link_read_unit_with_write_unit [i] = new bool [_nb_write_unit]; _link_read_unit_with_thread [i] = new bool [_nb_thread]; for (uint32_t j=0; j<_nb_execute_unit; j++) _link_read_unit_with_load_store_unit [i][j] = false; for (uint32_t j=0; j<_nb_write_unit; j++) _link_read_unit_with_write_unit [i][j] = false; for (uint32_t j=0; j<_nb_thread; j++) _link_read_unit_with_thread [i][j] = false; // fill link array for (uint32_t j=0; j<_nb_execute_unit; j++) { // Test if this read unit can send operation at this execute_unit if (_read_unit_to_execution_unit_table_routing [i][j]) { if (_is_load_store_unit [j]) { _link_read_unit_with_load_store_unit [i][j] = true; } for (uint32_t k=0; k<_nb_thread; k++) { if (_read_unit_to_execution_unit_table_thread [j][k]) { _link_read_unit_with_thread [i][k] = true; } } // Scearch associed write_unit for (uint32_t k=0; k<_nb_write_unit; k++) { // Test if this execute_unit can send operation at this write_unit // Test if have not a previous link ! (a same read_unit can send operation à two execute_unit and each execute_unit send at the same write_unit) if (_execution_unit_to_write_unit_table_routing [j][k] and not _link_read_unit_with_write_unit [i][k]) // if yes : this write_unit can have operation sended by this read_unit { _link_read_unit_with_write_unit [i][k] = true; } } } } } // Compute the gpr_write and spr_write port for the read_unit : // * Max : 2*nb_write_unit gpr_write_port. // * a specific read_unit and a specific write_unit can execute a null intersection of thread operation. Also it's unnecessarry to send the gpr_write at the read_unit. std::cout << "_link_......." << std::endl; std::cout << "_link_read_unit_with_load_store_unit" << std::endl; for (uint32_t i=0; i<_nb_read_unit; i++) { std::cout << "\t" << std::endl; for (uint32_t j=0; j<_nb_execute_unit; j++) std::cout << _link_read_unit_with_load_store_unit [i][j] << " "; std::cout << std::endl; } std::cout << "_link_read_unit_with_write_unit" << std::endl; for (uint32_t i=0; i<_nb_read_unit; i++) { std::cout << "\t" << std::endl; for (uint32_t j=0; j<_nb_write_unit; j++) std::cout << _link_read_unit_with_write_unit [i][j] << " "; std::cout << std::endl; } std::cout << "_link_read_unit_with_thread" << std::endl; for (uint32_t i=0; i<_nb_read_unit; i++) { std::cout << "\t" << std::endl; for (uint32_t j=0; j<_nb_thread; j++) std::cout << _link_read_unit_with_thread [i][j] << " "; std::cout << std::endl; } std::cout << "_set_......." << std::endl; for (uint32_t i=0; i<_nb_read_unit; i++) { std::cout << " * Read_unit[" << i << "]" << std::endl; for (uint32_t j=0; j<_nb_write_unit; j++) { std::cout << " * Write_unit[" << j << "]" << std::endl; // Test the thread executed on this write_unit for (uint32_t k=0; k<_nb_thread; k++) { std::cout << " * Thread[" << k << "]" << std::endl; if ( (_execution_unit_to_write_unit_table_thread [j][k]) and (_link_read_unit_with_thread [i][k])) { std::cout << " * Find !!!!" << std::endl; std::cout << " * Read_unit "+toString(i)+" must take the gpr_write with write_unit "+toString(j)+"." << std::endl; _set_read_unit_source_register_write[i].insert(j); _read_unit_nb_register_write [i] ++; std::cout << " * bypass_write : " << _nb_bypass_write [j] << std::endl; std::cout << " * Read_unit "+toString(i)+" must take the bypass_write with write_unit "+toString(j)+"." << std::endl; _set_read_unit_source_bypass_write [i].insert(j); _read_unit_nb_bypass_write [i] += _nb_bypass_write [j]; break; } } } } for (uint32_t i=0; i<_nb_read_unit; i++) { std::cout << " * Read_unit[" << i << "]" << std::endl; for (uint32_t j=0; j<_nb_execute_unit; j++) { std::cout << " * Execute_unit[" << j << "]" << std::endl; // Test the thread executed on this execute_unit for (uint32_t k=0; k<_nb_thread; k++) { std::cout << " * Thread[" << k << "]" << std::endl; if ((_read_unit_to_execution_unit_table_thread [j][k]) and (_link_read_unit_with_thread [i][k]) and (_is_load_store_unit [j])) { std::cout << " * Find !!!!" << std::endl; std::cout << " * Bypass_memory !!!!" << std::endl; std::cout << " * Read_unit "+toString(i)+" must take the bypass_memory with load_store_unit "+toString(j)+"." << std::endl; _set_read_unit_source_bypass_memory [i].insert(j); _read_unit_nb_bypass_memory [i] += _nb_bypass_memory [j]; break; } } } } test(); _param_read_unit = new morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_read_unit::read_unit::Parameters * [_nb_read_unit]; for (uint32_t i=0; i<_nb_read_unit; i++) _param_read_unit [i] = new morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_read_unit::read_unit::Parameters (_size_read_queue [i], _size_reservation_station [i], _nb_context , _nb_front_end , _nb_ooo_engine , _nb_packet , _size_general_data , _size_special_data , _max_nb_general_register , _max_nb_special_register , 1*_read_unit_nb_register_write [i], 1*_read_unit_nb_register_write [i], _max_size_store_queue , _max_size_load_queue , _nb_inst_retire [i], _read_unit_nb_bypass_write [i], _read_unit_nb_bypass_memory [i]); _param_functionnal_unit = new morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_execute_unit::execute_unit::functionnal_unit::Parameters * [_nb_functionnal_unit]; _param_load_store_unit = new morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_execute_unit::execute_unit::load_store_unit::Parameters * [_nb_load_store_unit]; uint32_t x=0; uint32_t y=0; for (uint32_t i=0; i<_nb_execute_unit; i++) if (_is_load_store_unit [i] == false) { _translate_num_execute_unit [i] = x; _param_functionnal_unit [x] = new morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_execute_unit::execute_unit::functionnal_unit::Parameters (_nb_context , _nb_front_end , _nb_ooo_engine , _nb_packet , _size_general_data , _max_nb_general_register , _size_special_data , _max_nb_special_register , _max_size_store_queue , _max_size_load_queue , _timing [i], _get_custom_information ); x++; } else { _translate_num_execute_unit [i] = y; _param_load_store_unit [y] = new morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_execute_unit::execute_unit::load_store_unit::Parameters (_size_store_queue [y], _size_load_queue [y], _size_speculative_access_queue [y], _nb_port_check [y], _speculative_load [y], _nb_bypass_memory [y], _nb_context , _nb_front_end , _nb_ooo_engine , _nb_packet , _size_general_data , _size_special_data , _max_nb_special_register , _max_nb_general_register ); y ++; } for (uint32_t i=0; i<_nb_load_store_unit; i++) _param_write_unit = new morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_write_unit::write_unit::Parameters * [_nb_write_unit]; for (uint32_t i=0; i<_nb_write_unit; i++) _param_write_unit [i] = new morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_write_unit::write_unit::Parameters (_size_write_queue [i], _size_execute_queue [i], _nb_context , _nb_front_end , _nb_ooo_engine , _nb_packet , _size_general_data , _max_nb_general_register , _size_special_data , _max_nb_special_register , _nb_bypass_write [i]); _param_read_unit_to_execution_unit = new morpheo::behavioural::core::multi_execute_loop::execute_loop::network::read_unit_to_execution_unit::Parameters (_nb_read_unit , _nb_execute_unit , _nb_context , _nb_front_end , _nb_ooo_engine , _nb_packet , _size_general_data , _size_special_data , _max_nb_general_register , _max_nb_special_register , _max_size_store_queue , _max_size_load_queue , _read_unit_to_execution_unit_priority , _read_unit_to_execution_unit_table_routing , _read_unit_to_execution_unit_table_execute_type, _read_unit_to_execution_unit_table_thread ); _param_execution_unit_to_write_unit = new morpheo::behavioural::core::multi_execute_loop::execute_loop::network::execution_unit_to_write_unit::Parameters (_nb_execute_unit , _nb_write_unit , _nb_context , _nb_front_end , _nb_ooo_engine , _nb_packet , _size_general_data , _size_special_data , _max_nb_general_register , _max_nb_special_register , _execution_unit_to_write_unit_priority , _execution_unit_to_write_unit_table_routing, _execution_unit_to_write_unit_table_thread ); _param_register_unit = new morpheo::behavioural::core::multi_execute_loop::execute_loop::register_unit::Parameters (_nb_ooo_engine , _size_general_data , _size_special_data , _nb_gpr_read , _nb_gpr_write , _nb_gpr_bank , _nb_gpr_port_read_by_bank , _nb_gpr_port_write_by_bank , _nb_spr_read , _nb_spr_write , _nb_spr_bank , _nb_spr_port_read_by_bank , _nb_spr_port_write_by_bank , _nb_general_register , _nb_special_register , _nb_inst_insert_rob , _nb_inst_retire_rob ); _max_size_dcache_context_id = 0; _max_size_dcache_packet_id = 0; for (uint32_t i=0; i<_nb_load_store_unit; i++) { if (_param_load_store_unit [i]->_size_dcache_context_id > _max_size_dcache_context_id) _max_size_dcache_context_id = _param_load_store_unit [i]->_size_dcache_context_id; if (_param_load_store_unit [i]->_size_dcache_packet_id > _max_size_dcache_packet_id) _max_size_dcache_packet_id = _param_load_store_unit [i]->_size_dcache_packet_id; } _have_port_dcache_context_id = (_max_size_dcache_context_id>1); log_printf(FUNC,Execute_loop,FUNCTION,"End"); }; // #undef FUNCTION // #define FUNCTION "Execute_loop::Parameters (copy)" // Parameters::Parameters (Parameters & param) // { // log_printf(FUNC,Execute_loop,FUNCTION,"Begin"); // test(); // log_printf(FUNC,Execute_loop,FUNCTION,"End"); // }; #undef FUNCTION #define FUNCTION "Execute_loop::~Parameters" Parameters::~Parameters () { log_printf(FUNC,Execute_loop,FUNCTION,"Begin"); delete [] _param_read_unit; delete [] _param_functionnal_unit; delete [] _param_load_store_unit; delete [] _param_write_unit; delete _param_read_unit_to_execution_unit; delete _param_execution_unit_to_write_unit; delete _param_register_unit; delete [] _read_unit_to_execution_unit_table_execute_type; delete [] _read_unit_nb_register_write; delete [] _read_unit_nb_bypass_write; delete [] _read_unit_nb_bypass_memory; delete [] _set_read_unit_source_register_write ; delete [] _set_read_unit_source_bypass_write ; delete [] _set_read_unit_source_bypass_memory ; delete [] _link_read_unit_with_load_store_unit; delete [] _link_read_unit_with_write_unit; delete [] _link_read_unit_with_thread; delete [] _is_load_store_unit; delete [] _translate_num_execute_unit; log_printf(FUNC,Execute_loop,FUNCTION,"End"); }; }; // end namespace execute_loop }; // end namespace multi_execute_loop }; // end namespace core }; // end namespace behavioural }; // end namespace morpheo