#include #include "src/GB/Global_Buffer.h" #include "src/Interposer/Interposer_Interface.h" #include "src/Chiplet/Chiplet_Interface.h" #include "src/Optical_Electrical/O_E_converter.h" #include "src/PE/Processing_Element.h" #include "src/utils/configuration.h" #include "src/utils/token_manager.h" #include "src/utils/noc_logger.h" int sc_main(int argc, char* argv[]) { // Define the number of chiplets and processing elements const int num_chiplets = CHIPLET_NO; const int num_pes = PE_PER_CHIPLET; const int total_pes = PE_NO; setup_logger(); // Create the Global Buffer instance GlobalBuffer gb("GlobalBuffer", num_chiplets, num_pes); //gb.configure(CHIPLET_NO); //std::cout << "Creating global buffer instances" << std::endl; // Create an array of Interposer Interface instances InterposerInterface* interposers[num_chiplets]; ChipletInterface* chiplets[num_chiplets]; O_E_converter* oec[num_chiplets][num_pes]; ProcessingElement* pe[num_chiplets][num_pes]; TokenManager* tokens[num_chiplets]; for (int i = 0; i < num_chiplets; ++i) { //Dynamically Create each Interposer Interface instance std::string name = "InterposerInterface_" + std::to_string(i); interposers[i] = new InterposerInterface(name.c_str()); //std::cout << "Creating interposer instances" << std::endl; interposers[i] -> interposer_id = i; //std::cout << "Before Connecting sockets" << std::endl; // Bind the sockets of Global Buffer to those of the Interposer Interface gb.features_from_GB_sockets[i].bind(interposers[i]->gb_features_receive_socket); gb.weight_from_GB_sockets[i].bind(interposers[i]->gb_weight_receive_socket); interposers[i]->gb_send_socket.bind(gb.receive_to_GB_sockets[i]); //std::cout << "After Connecting sockets" << std::endl; std::string chip_name = "ChipletInterface_" + std::to_string(i); chiplets[i] = new ChipletInterface(chip_name.c_str(), num_pes); chiplets[i] -> chiplet_id = i; // Bind chiplet sockets interposers[i]->chiplet_features_send_socket.bind(chiplets[i]->interposer_features_receive_socket); interposers[i]->chiplet_weight_send_socket.bind(chiplets[i]->interposer_weight_receive_socket); chiplets[i]->interposer_send_socket.bind(interposers[i]->chiplet_receive_socket); std::string token_name = "TokenManager_" + std::to_string(i); tokens[i] = new TokenManager(token_name.c_str()); // Create a token for each chiplet for (int j = 0; j < num_pes; ++j) { std::string oe_name = "O_E_converter_" + std::to_string(i) + "_" + std::to_string(j); oec[i][j] = new O_E_converter(oe_name.c_str()); oec[i][j] -> O_E_converter_id = j; chiplets[i]->oec_features_send_sockets[j].bind(oec[i][j]->ci_features_receive_socket); chiplets[i]->oec_weight_send_sockets[j].bind(oec[i][j]->ci_weight_receive_socket); oec[i][j]->ci_send_socket.bind(chiplets[i]->oec_receive_sockets[j]); std::string pe_name = "ProcessingElement_" + std::to_string(i) + "_" + std::to_string(j); pe[i][j] = new ProcessingElement(pe_name.c_str(), *tokens[i]); oec[i][j]->pe_features_send_socket.bind(pe[i][j] ->oec_features_receive_socket); oec[i][j]->pe_weight_send_socket.bind(pe[i][j] ->oec_weight_receive_socket); pe[i][j] ->oec_send_socket.bind(oec[i][j] ->pe_receive_socket); pe[i][j] ->pe_id = j; pe[i][j] ->pe_chiplet_id = i; //pe[i][j]->set_token_manager[i](&tok_mgr); //std::cout << "Created modules and binded sockets" << std::endl; } } // Start the simulation sc_core::sc_start(1500, SC_NS); // Clean up dynamically allocated Interposer Interfaces for (int i = 0; i < num_chiplets; ++i) { delete interposers[i]; delete chiplets[i]; delete tokens[i]; for (int j = 0; j < num_pes; ++j) { delete oec[i][j]; delete pe[i][j]; } } return 0; }