add test case focusing on simulation kernel performance
This commit is contained in:
		| @@ -9,6 +9,7 @@ set(ENABLE_SHARED TRUE CACHE BOOL "Build shared libraries") | ||||
|  | ||||
| set(NO_SUBMODULE_CHECK FALSE CACHE BOOL "Disable the submodule check") | ||||
|  | ||||
| set(ENABLE_CLANG_TIDY FALSE CACHE BOOL "Enable clang-tidy checks") | ||||
| include(GitFunctions) | ||||
| get_branch_from_git() | ||||
|  | ||||
| @@ -60,7 +61,8 @@ if(ENABLE_COVERAGE) | ||||
| endif() | ||||
|  | ||||
| find_program(CLANG_TIDY_EXE NAMES "clang-tidy-9") | ||||
| if (CLANG_TIDY_EXE) | ||||
| if(ENABLE_CLANG_TIDY) | ||||
| if(CLANG_TIDY_EXE) | ||||
|   	message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}") | ||||
|   	set(CLANG_TIDY_CHECKS "-*,modernize-*,-modernize-use-trailing-return-type,clang-analyzer-core.*,clang-analyzer-cplusplus.*") | ||||
|   	set(CMAKE_CXX_CLANG_TIDY  | ||||
| @@ -71,6 +73,7 @@ else() | ||||
|   	message(AUTHOR_WARNING "clang-tidy not found!") | ||||
|   	set(CMAKE_CXX_CLANG_TIDY "" CACHE STRING "" FORCE) # delete it | ||||
| endif() | ||||
| endif() | ||||
|  | ||||
| setup_conan() | ||||
|  | ||||
|   | ||||
| @@ -1,45 +0,0 @@ | ||||
| macro(setup_conan) | ||||
|   find_program(conan conan PATHS /usr/bin /usr/local/bin) | ||||
|   if(NOT EXISTS ${conan}) | ||||
|     message(FATAL_ERROR "Conan is required. Please see README.md") | ||||
|     return() | ||||
|   endif() | ||||
|  | ||||
|   if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL Darwin) | ||||
|     set(os Macos) | ||||
|   else() | ||||
|     set(os ${CMAKE_HOST_SYSTEM_NAME}) | ||||
|   endif() | ||||
|  | ||||
|   if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU) | ||||
|     set(compiler gcc) | ||||
|   elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL AppleClang) | ||||
|     set(compiler apple-clang) | ||||
|   else() | ||||
|     message(FATAL_ERROR "Unknown compiler: ${CMAKE_CXX_COMPILER_ID}") | ||||
|   endif() | ||||
|  | ||||
|   string(SUBSTRING ${CMAKE_CXX_COMPILER_VERSION} 0 3 compiler_version) | ||||
|  | ||||
|   set(conanfile ${CMAKE_SOURCE_DIR}/conanfile.txt) | ||||
|   set(conanfile_cmake ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) | ||||
|   set(compiler_libcxx libstdc++11) | ||||
|  | ||||
|   if("${CMAKE_BUILD_TYPE}" STREQUAL "") | ||||
| 	set(CONAN_BUILD_TYPE Debug) | ||||
|   elseif("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo") | ||||
| 	set(CONAN_BUILD_TYPE Release) | ||||
|   else() | ||||
| 	set(CONAN_BUILD_TYPE ${CMAKE_BUILD_TYPE}) | ||||
|   endif() | ||||
|  | ||||
|   execute_process(COMMAND ${conan} install --build=missing | ||||
| 	  -s build_type=${CONAN_BUILD_TYPE} -s compiler.libcxx=${compiler_libcxx} | ||||
| 	           ${CMAKE_SOURCE_DIR} RESULT_VARIABLE return_code) | ||||
|   if(NOT ${return_code} EQUAL 0) | ||||
|     message(FATAL_ERROR "conan install command failed.") | ||||
|   endif() | ||||
|  | ||||
|   include(${conanfile_cmake}) | ||||
|   conan_basic_setup() | ||||
| endmacro() | ||||
 Submodule sc-components updated: ffa9b526d7...3192c9cc21
									
								
							| @@ -1,3 +1,3 @@ | ||||
| add_subdirectory(io-redirector) | ||||
| #add_subdirectory(sim_performance) | ||||
| add_subdirectory(sim_performance) | ||||
| add_subdirectory(ordered_semaphore) | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| cmake_minimum_required(VERSION 3.12) | ||||
| add_executable (sim_performance  | ||||
|     sc_main.cpp | ||||
| 	blocks.cpp | ||||
| 	pkt_sender.cpp | ||||
| 	pkt_switch.cpp | ||||
| 	top.cpp | ||||
| ) | ||||
| target_link_libraries (sim_performance LINK_PUBLIC scc) | ||||
|   | ||||
							
								
								
									
										34
									
								
								tests/sim_performance/packet.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								tests/sim_performance/packet.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| /* | ||||
|  * packet.h | ||||
|  * | ||||
|  *  Created on: 04.05.2020 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #ifndef _SIM_PERFORMANCE_PACKET_H_ | ||||
| #define _SIM_PERFORMANCE_PACKET_H_ | ||||
|  | ||||
| #include <tlm> | ||||
|  | ||||
| struct packet { | ||||
|     std::vector<uint8_t> routing; | ||||
| }; | ||||
|  | ||||
| struct packet_ext: public tlm::tlm_extension<packet_ext>, public packet { | ||||
|  | ||||
|     packet_ext() = default; | ||||
|  | ||||
|     packet_ext& operator=(packet_ext const& o) = default; | ||||
|  | ||||
|     tlm_extension_base* clone() const override { | ||||
|         return new packet_ext(*this); | ||||
|     } | ||||
|  | ||||
|     void copy_from(tlm_extension_base const & o) override { | ||||
|         auto* ext = dynamic_cast<packet_ext const*>(&o); | ||||
|         if(ext) | ||||
|             this->routing=ext->routing; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| #endif /* _SIM_PERFORMANCE_PACKET_H_ */ | ||||
							
								
								
									
										99
									
								
								tests/sim_performance/pkt_sender.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								tests/sim_performance/pkt_sender.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| /* | ||||
|  * blocks.cpp | ||||
|  * | ||||
|  *  Created on: 04.05.2020 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #include "pkt_sender.h" | ||||
| #include "types.h" | ||||
| #include <scc/report.h> | ||||
| #include <tlm/tlm_mm.h> | ||||
|  | ||||
| using namespace sc_core; | ||||
|  | ||||
| pkt_sender::pkt_sender(const sc_core::sc_module_name &nm, unsigned dim, unsigned pos_x, unsigned pos_y) | ||||
| : sc_module(nm) | ||||
| , bw_peq("bw_peq") | ||||
| , fw_peq("fw_peq") | ||||
| , my_pos{pos_x,pos_y} | ||||
| , dim{dim} | ||||
| { | ||||
|     SCCDEBUG(SCMOD)<<"instantiating sender "<<pos_x<<"/"<<pos_y; | ||||
|     SC_HAS_PROCESS(pkt_sender); | ||||
|     isck.register_nb_transport_bw([this](tlm::tlm_generic_payload &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay)->tlm::tlm_sync_enum{ | ||||
|         return this->nb_bw(gp, phase, delay); | ||||
|     }); | ||||
|     tsck.register_nb_transport_fw([this](tlm::tlm_generic_payload &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay)->tlm::tlm_sync_enum{ | ||||
|         return this->nb_fw(gp, phase, delay); | ||||
|     }); | ||||
|     SC_METHOD(received); | ||||
|     sensitive<<fw_peq.get_event(); | ||||
|     dont_initialize(); | ||||
|     SC_THREAD(run); | ||||
| } | ||||
|  | ||||
| void pkt_sender::gen_routing(std::vector<uint8_t> &route_vec) { | ||||
|     if(std::get<0>(my_pos)==0){ | ||||
|         for(auto i=0; i<dim; ++i) | ||||
|             route_vec.push_back(RIGHT); | ||||
|     } else if(std::get<0>(my_pos)==dim+1){ | ||||
|         for(auto i=0; i<dim; ++i) | ||||
|             route_vec.push_back(LEFT); | ||||
|     } else if(std::get<1>(my_pos)==0){ | ||||
|         for(auto i=0; i<dim; ++i) | ||||
|             route_vec.push_back(BOTTOM); | ||||
|     } else if(std::get<1>(my_pos)==dim+1){ | ||||
|         for(auto i=0; i<dim; ++i) | ||||
|             route_vec.push_back(TOP); | ||||
|     } else | ||||
|         SCCERR(SCMOD)<<"WTF!?!"; | ||||
| } | ||||
|  | ||||
| void pkt_sender::run() { | ||||
|     wait(clk_i.posedge_event()); | ||||
|     for(auto i=0U; i<1000; i++){ | ||||
|         tlm::tlm_generic_payload* gp = tlm::tlm_mm<>::get().allocate<packet_ext>(); | ||||
|         gen_routing(gp->get_extension<packet_ext>()->routing); | ||||
|         tlm::tlm_phase phase{tlm::BEGIN_REQ}; | ||||
|         sc_time delay; | ||||
|         gp->acquire(); | ||||
|         auto sync = isck->nb_transport_fw(*gp, phase, delay); | ||||
|         sc_assert(sync==tlm::TLM_UPDATED && phase==tlm::END_REQ); | ||||
|         tlm::tlm_generic_payload* ret{nullptr}; | ||||
|         while(!(ret=bw_peq.get_next_transaction())){ | ||||
|             wait(bw_peq.get_event()); | ||||
|         } | ||||
|         sc_assert(gp==ret); | ||||
|         ret->release(); | ||||
|         wait(clk_i.posedge_event()); | ||||
|     } | ||||
|     finish_evt.notify(SC_ZERO_TIME); | ||||
| } | ||||
|  | ||||
| tlm::tlm_sync_enum pkt_sender::nb_bw(tlm::tlm_generic_payload &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay) { | ||||
|     sc_assert(phase==tlm::BEGIN_RESP); | ||||
|     bw_peq.notify(gp, delay); | ||||
|     phase=tlm::END_RESP; | ||||
|     return tlm::TLM_COMPLETED; | ||||
| } | ||||
|  | ||||
| tlm::tlm_sync_enum pkt_sender::nb_fw(tlm::tlm_generic_payload &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay) { | ||||
|     sc_assert(phase==tlm::BEGIN_REQ); | ||||
|     auto ext = gp.get_extension<packet_ext>(); | ||||
|     sc_assert(ext->routing.size()==0); | ||||
|     gp.acquire(); | ||||
|     fw_peq.notify(gp, delay); | ||||
|     phase=tlm::END_REQ; | ||||
|     return tlm::TLM_UPDATED; | ||||
| } | ||||
|  | ||||
| void pkt_sender::received() { | ||||
|     if(auto gp = fw_peq.get_next_transaction()){ | ||||
|         tlm::tlm_phase phase{tlm::BEGIN_RESP}; | ||||
|         sc_time delay; | ||||
|         auto sync = tsck->nb_transport_bw(*gp, phase, delay); | ||||
|         sc_assert(sync==tlm::TLM_COMPLETED && phase==tlm::END_RESP); | ||||
|         gp->release(); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										37
									
								
								tests/sim_performance/pkt_sender.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								tests/sim_performance/pkt_sender.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| /* | ||||
|  * blocks.h | ||||
|  * | ||||
|  *  Created on: 04.05.2020 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #ifndef _SIM_PERFORMANCE_PKT_SENDER_H_ | ||||
| #define _SIM_PERFORMANCE_PKT_SENDER_H_ | ||||
|  | ||||
| #include <systemc> | ||||
| #include "packet.h" | ||||
| #include <scc/initiator_mixin.h> | ||||
| #include <scc/target_mixin.h> | ||||
|  | ||||
|  | ||||
| class pkt_sender : sc_core::sc_module { | ||||
| public: | ||||
|     sc_core::sc_in<bool> clk_i{"clk_i"}; | ||||
|     scc::initiator_mixin<tlm::tlm_initiator_socket<32>> isck; | ||||
|     scc::target_mixin<tlm::tlm_target_socket<32>> tsck; | ||||
|     pkt_sender(sc_core::sc_module_name const&, unsigned dim, unsigned pos_x, unsigned pos_y); | ||||
|     virtual ~pkt_sender() = default; | ||||
|     sc_core::sc_event const& get_finish_event(){return finish_evt;} | ||||
| private: | ||||
|     void run(); | ||||
|     void gen_routing(std::vector<uint8_t>& route_vec); | ||||
|     void received(); | ||||
|     tlm_utils::peq_with_get<tlm::tlm_generic_payload> bw_peq, fw_peq; | ||||
|     tlm::tlm_sync_enum nb_fw(tlm::tlm_generic_payload&, tlm::tlm_phase&, sc_core::sc_time&); | ||||
|     tlm::tlm_sync_enum nb_bw(tlm::tlm_generic_payload&, tlm::tlm_phase&, sc_core::sc_time&); | ||||
|     sc_core::sc_event finish_evt; | ||||
|     std::pair<unsigned, unsigned> my_pos; | ||||
|     const unsigned dim; | ||||
| }; | ||||
|  | ||||
| #endif /* _SIM_PERFORMANCE_PKT_SENDER_H_ */ | ||||
							
								
								
									
										97
									
								
								tests/sim_performance/pkt_switch.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								tests/sim_performance/pkt_switch.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| /* | ||||
|  * blocks.cpp | ||||
|  * | ||||
|  *  Created on: 04.05.2020 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #ifndef SC_INCLUDE_DYNAMIC_PROCESSES // needed for sc_spawn | ||||
| #define SC_INCLUDE_DYNAMIC_PROCESSES | ||||
| #endif | ||||
| #include "pkt_switch.h" | ||||
| #include "types.h" | ||||
| #include <tlm/tlm_mm.h> | ||||
| #include <scc/report.h> | ||||
|  | ||||
| using namespace sc_core; | ||||
|  | ||||
| pkt_switch::pkt_switch(const sc_core::sc_module_name &nm):sc_module(nm) { | ||||
|     SC_HAS_PROCESS(pkt_switch); | ||||
|     auto index = 0U; | ||||
|     for(auto& s:isck){ | ||||
|         s.register_nb_transport_bw([this](unsigned id, tlm::tlm_generic_payload &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay)->tlm::tlm_sync_enum{ | ||||
|         return this->nb_bw(id, gp, phase, delay); | ||||
|         }, index++); | ||||
|     } | ||||
|     index = 0U; | ||||
|     for(auto& s:tsck){ | ||||
|         s.register_nb_transport_fw([this](unsigned id, tlm::tlm_generic_payload &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay)->tlm::tlm_sync_enum{ | ||||
|         return this->nb_fw(id, gp, phase, delay); | ||||
|         }, index++); | ||||
|     } | ||||
|     SC_METHOD(clock_cb); | ||||
|     sensitive<<clk_i.pos(); | ||||
|     dont_initialize(); | ||||
|     for(auto i=0U; i<SIDES; ++i){ | ||||
|         sc_core::sc_spawn_options opts; | ||||
|         opts.spawn_method(); | ||||
|         opts.set_sensitivity(&out_fifo[i].data_written_event()); | ||||
|         sc_core::sc_spawn([this, i]()->void {this->output_cb(i);}, sc_core::sc_gen_unique_name("out_peq"), &opts); | ||||
|     } | ||||
| } | ||||
|  | ||||
| tlm::tlm_sync_enum pkt_switch::nb_fw(unsigned id, tlm::tlm_generic_payload &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay) { | ||||
|     in_tx[id].write(&gp); | ||||
|     if(phase==tlm::BEGIN_REQ) phase=tlm::END_REQ; | ||||
|     else SCCERR(SCMOD)<<"WTF!?!"; | ||||
|     return tlm::TLM_UPDATED; | ||||
| } | ||||
|  | ||||
| void pkt_switch::clock_cb() { | ||||
|     std::array<std::vector<unsigned>, SIDES> routing{}; | ||||
|     bool nothing_todo=true; | ||||
|     for(auto i=0U; i<SIDES; ++i){ | ||||
|         if(auto gp = in_tx[i].read()){ | ||||
|             auto ext = gp->get_extension<packet_ext>(); | ||||
|             sc_assert(ext); | ||||
|             routing[ext->routing.back()].push_back(i); | ||||
|             nothing_todo = false; | ||||
|         } | ||||
|     } | ||||
|     if(nothing_todo) return; | ||||
|     for(auto i=0U; i<SIDES; ++i){ | ||||
|         if(routing[i].size()){ | ||||
|             auto selected_input=routing[i].front(); | ||||
|             auto* gp = in_tx[selected_input].read(); | ||||
|             if(out_fifo[i].nb_write(gp)){ | ||||
|                 auto ext = gp->get_extension<packet_ext>(); | ||||
|                 ext->routing.pop_back(); | ||||
|                 gp->acquire(); | ||||
|                 tlm::tlm_phase phase{tlm::BEGIN_RESP}; | ||||
|                 sc_core::sc_time delay; | ||||
|                 auto res = tsck[selected_input]->nb_transport_bw(*gp, phase, delay); | ||||
|                 if(res!=tlm::TLM_COMPLETED && !(res==tlm::TLM_UPDATED && phase==tlm::END_RESP)) | ||||
|                     SCCERR(SCMOD)<<"WTF!?!"; | ||||
|                 in_tx[selected_input].clear(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void pkt_switch::output_cb(unsigned id) { | ||||
|  | ||||
|     if(out_fifo[id].num_available()){ | ||||
|         auto* gp = out_fifo[id].read(); | ||||
|         tlm::tlm_phase phase{tlm::BEGIN_REQ}; | ||||
|         sc_time delay; | ||||
|         auto sync = isck[id]->nb_transport_fw(*gp, phase, delay); | ||||
|         sc_assert(sync==tlm::TLM_UPDATED && phase==tlm::END_REQ); | ||||
|     } | ||||
| } | ||||
|  | ||||
| tlm::tlm_sync_enum pkt_switch::nb_bw(unsigned id, tlm::tlm_generic_payload &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay) { | ||||
|     gp.release(); | ||||
|     sc_assert(phase==tlm::BEGIN_RESP); | ||||
|     phase=tlm::END_RESP; | ||||
|     return tlm::TLM_COMPLETED; | ||||
| } | ||||
							
								
								
									
										37
									
								
								tests/sim_performance/pkt_switch.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								tests/sim_performance/pkt_switch.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| /* | ||||
|  * blocks.h | ||||
|  * | ||||
|  *  Created on: 04.05.2020 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #ifndef _SIM_PERFORMANCE_PKT_SWITCH_H_ | ||||
| #define _SIM_PERFORMANCE_PKT_SWITCH_H_ | ||||
|  | ||||
| #include <systemc> | ||||
| #include "packet.h" | ||||
| #include <scc/tagged_initiator_mixin.h> | ||||
| #include <scc/tagged_target_mixin.h> | ||||
| #include <scc/sc_owning_signal.h> | ||||
| #include <array> | ||||
|  | ||||
|  | ||||
| class pkt_switch : sc_core::sc_module { | ||||
| public: | ||||
|     enum {NONE=std::numeric_limits<unsigned>::max()}; | ||||
|     sc_core::sc_in<bool> clk_i{"clk_i"}; | ||||
|     sc_core::sc_vector<scc::tagged_target_mixin<tlm::tlm_target_socket<32>>> tsck{"tsck",4}; | ||||
|     sc_core::sc_vector<scc::tagged_initiator_mixin<tlm::tlm_initiator_socket<32>>> isck{"isck",4}; | ||||
|     pkt_switch(sc_core::sc_module_name const&); | ||||
|     virtual ~pkt_switch() = default; | ||||
| private: | ||||
|     void clock_cb(); | ||||
|     void output_cb(unsigned); | ||||
|     tlm::tlm_sync_enum nb_fw(unsigned, tlm::tlm_generic_payload&, tlm::tlm_phase&, sc_core::sc_time&); | ||||
|     tlm::tlm_sync_enum nb_bw(unsigned, tlm::tlm_generic_payload&, tlm::tlm_phase&, sc_core::sc_time&); | ||||
|     sc_core::sc_vector<scc::sc_owning_signal<tlm::tlm_generic_payload>> in_tx{"in_sig", 4}; | ||||
|     sc_core::sc_vector<sc_core::sc_fifo<tlm::tlm_generic_payload*>> out_fifo{"out_peq", 4}; | ||||
|     std::array<unsigned, 4> last_sel_inp{NONE, NONE, NONE, NONE}; | ||||
| }; | ||||
|  | ||||
| #endif /* _SIM_PERFORMANCE_PKT_SWITCH_H_ */ | ||||
							
								
								
									
										102
									
								
								tests/sim_performance/sc_main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								tests/sim_performance/sc_main.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // Copyright 2017 eyck@minres.com | ||||
| // | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||||
| // use this file except in compliance with the License.  You may obtain a copy | ||||
| // of the License at | ||||
| // | ||||
| //   http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
| // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the | ||||
| // License for the specific language governing permissions and limitations under | ||||
| // the License. | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| /* | ||||
|  * sc_main.cpp | ||||
|  * | ||||
|  *  Created on: 17.09.2017 | ||||
|  *      Author: eyck@minres.com | ||||
|  */ | ||||
|  | ||||
| #include "top.h" | ||||
| #include <scc/perf_estimator.h> | ||||
| #include <scc/report.h> | ||||
| #include <scc/scv_tr_db.h> | ||||
| #include <scc/tracer.h> | ||||
| #include <boost/program_options.hpp> | ||||
|  | ||||
| using namespace scc; | ||||
| namespace po = boost::program_options; | ||||
|  | ||||
| namespace { | ||||
| const size_t ERROR_IN_COMMAND_LINE = 1; | ||||
| const size_t SUCCESS = 0; | ||||
| const size_t ERROR_UNHANDLED_EXCEPTION = 2; | ||||
| } // namespace | ||||
|  | ||||
| int sc_main(int argc, char *argv[]) { | ||||
|     sc_core::sc_report_handler::set_actions( "/IEEE_Std_1666/deprecated", sc_core::SC_DO_NOTHING ); | ||||
|     sc_core::sc_report_handler::set_actions(sc_core::SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, sc_core::SC_DO_NOTHING); | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|     // CLI argument parsing | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|     po::options_description desc("Options"); | ||||
|     // clang-format off | ||||
|     desc.add_options() | ||||
|     		("help,h",  "Print help message") | ||||
| 			("debug,d", "set debug level") | ||||
| 			("trace,t", "trace SystemC signals"); | ||||
|     // clang-format on | ||||
|     po::variables_map vm; | ||||
|     try { | ||||
|         po::store(po::parse_command_line(argc, argv, desc), vm); // can throw | ||||
|         // --help option | ||||
|         if (vm.count("help")) { | ||||
|             std::cout << "JIT-ISS simulator for AVR" << std::endl << desc << std::endl; | ||||
|             return SUCCESS; | ||||
|         } | ||||
|         po::notify(vm); // throws on error, so do after help in case | ||||
|         // there are any problems | ||||
|     } catch (po::error &e) { | ||||
|         std::cerr << "ERROR: " << e.what() << std::endl << std::endl; | ||||
|         std::cerr << desc << std::endl; | ||||
|         return ERROR_IN_COMMAND_LINE; | ||||
|     } | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|     // configure logging | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|     scc::init_logging(vm.count("debug")?scc::log::DEBUG:scc::log::INFO); | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|     // set up tracing & transaction recording | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|     //tracer trace("simple_system", tracer::TEXT, vm.count("trace")); | ||||
|     // todo: fix displayed clock period in VCD | ||||
|     try { | ||||
|         /////////////////////////////////////////////////////////////////////////// | ||||
|         // instantiate top level | ||||
|         /////////////////////////////////////////////////////////////////////////// | ||||
|         perf_estimator estimator; | ||||
|         top i_top("i_top", 89); | ||||
|         /////////////////////////////////////////////////////////////////////////// | ||||
|         // run simulation | ||||
|         /////////////////////////////////////////////////////////////////////////// | ||||
|         sc_start(sc_core::sc_time(1, sc_core::SC_MS)); | ||||
|         if(sc_is_running()) { | ||||
|             SCCERR() << "simulation timed out"; // calls sc_stop | ||||
|             sc_core::sc_stop(); | ||||
|         } | ||||
|     } catch(sc_report& e) { | ||||
|         SCCERR() << "Caught sc_report exception during simulation: " << e.what() << ":" << e.get_msg(); | ||||
|     } catch(std::exception& e) { | ||||
|         SCCERR() << "Caught exception during simulation: " << e.what(); | ||||
|     } catch(...) { | ||||
|         SCCERR() << "Caught unspecified exception during simulation"; | ||||
|     } | ||||
|     auto errcnt = sc_report_handler::get_count(SC_ERROR); | ||||
|     auto warncnt = sc_report_handler::get_count(SC_WARNING); | ||||
|     SCCINFO() << "simulation finished, " << errcnt << " error" << (errcnt == 1 ? "" : "s") << " and " << warncnt << " warning" | ||||
|               << (warncnt == 1 ? "" : "s"); | ||||
|     return errcnt + warncnt; | ||||
| } | ||||
							
								
								
									
										96
									
								
								tests/sim_performance/top.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								tests/sim_performance/top.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| /* | ||||
|  * top.cpp | ||||
|  * | ||||
|  *  Created on: 04.05.2020 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #include "top.h" | ||||
| #include <scc/utilities.h> | ||||
| #include <scc/report.h> | ||||
| #include <fmt/format.h> | ||||
|  | ||||
| using namespace sc_core; | ||||
| using namespace fmt; | ||||
|  | ||||
| top::top(sc_core::sc_module_name const& nm, unsigned dimension) :sc_module(nm){ | ||||
|     sc_assert(dimension>0); | ||||
|     SC_HAS_PROCESS(top); | ||||
|     for(auto yidx=0U; yidx<dimension; ++yidx){ | ||||
|         for(auto xidx=0U; xidx<dimension; ++xidx){ | ||||
|             auto name = format("sw_{}_{}", xidx, yidx); | ||||
|             SCCDEBUG(SCMOD)<<"instantiating switch "<<xidx<<"/"<<yidx; | ||||
|             switches.push_back(scc::make_unique<pkt_switch>(sc_module_name(name.c_str()))); | ||||
|             switches.back()->clk_i(clk); | ||||
|         } | ||||
|     } | ||||
|     for(auto yidx=0U; yidx<dimension; ++yidx){ | ||||
|         for(auto xidx=0U; xidx<dimension; ++xidx){ | ||||
|             auto& sw = switches[yidx*dimension+xidx]; | ||||
|             if(xidx<dimension-1) { | ||||
|                 auto& swr = switches[yidx*dimension+(xidx+1)]; | ||||
|                 sw->isck[RIGHT](swr->tsck[LEFT]); | ||||
|                 swr->isck[LEFT](sw->tsck[RIGHT]); | ||||
|             } | ||||
|             if(yidx<dimension-1){ | ||||
|                 auto& swb = switches[(yidx+1)*dimension+xidx]; | ||||
|                 sw->isck[BOTTOM](swb->tsck[TOP]); | ||||
|                 swb->isck[TOP](sw->tsck[BOTTOM]); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     auto yidx = 0U; | ||||
|     auto xidx = 0U; | ||||
|     for(xidx=0U; xidx<dimension; ++xidx){ | ||||
|         auto name = format("snd_{}_{}", xidx+1, 0); | ||||
|         senders[TOP].push_back(scc::make_unique<pkt_sender>(sc_module_name(name.c_str()), dimension, xidx+1, 0)); | ||||
|         auto& snd = senders[TOP].back(); | ||||
|         snd->clk_i(clk); | ||||
|         auto& sw = switches[yidx*dimension+xidx]; | ||||
|         snd->isck(sw->tsck[TOP]); | ||||
|         sw->isck[TOP](snd->tsck); | ||||
|     } | ||||
|     yidx=dimension-1; | ||||
|     for(xidx=0U; xidx<dimension; ++xidx){ | ||||
|         auto name = format("snd_{}_{}", xidx+1, dimension+1); | ||||
|         senders[BOTTOM].push_back(scc::make_unique<pkt_sender>(sc_module_name(name.c_str()), dimension, xidx+1, dimension+1)); | ||||
|         auto& snd = senders[BOTTOM].back(); | ||||
|         snd->clk_i(clk); | ||||
|         auto& sw = switches[yidx*dimension+xidx]; | ||||
|         snd->isck(sw->tsck[BOTTOM]); | ||||
|         sw->isck[BOTTOM](snd->tsck); | ||||
|     } | ||||
|     xidx=0U; | ||||
|     for(yidx=0U; yidx<dimension; ++yidx){ | ||||
|         auto name = format("snd_{}_{}", 0, yidx+1); | ||||
|         senders[LEFT].push_back(scc::make_unique<pkt_sender>(sc_module_name(name.c_str()), dimension, 0, yidx+1)); | ||||
|         auto& snd = senders[LEFT].back(); | ||||
|         snd->clk_i(clk); | ||||
|         auto& sw = switches[yidx*dimension+xidx]; | ||||
|         snd->isck(sw->tsck[LEFT]); | ||||
|         sw->isck[LEFT](snd->tsck); | ||||
|     } | ||||
|     xidx=dimension-1; | ||||
|     for(yidx=0U; yidx<dimension; ++yidx){ | ||||
|         auto name = format("snd_{}_{}", dimension+1, yidx+1); | ||||
|         senders[RIGHT].push_back(scc::make_unique<pkt_sender>(sc_module_name(name.c_str()), dimension, dimension+1, yidx+1)); | ||||
|         auto& snd = senders[RIGHT].back(); | ||||
|         snd->clk_i(clk); | ||||
|         auto& sw = switches[yidx*dimension+xidx]; | ||||
|         snd->isck(sw->tsck[RIGHT]); | ||||
|         sw->isck[RIGHT](snd->tsck); | ||||
|     } | ||||
|     SC_THREAD(run); | ||||
| } | ||||
|  | ||||
| void top::run() { | ||||
|     sc_event_and_list evt_list; | ||||
|     for(auto& sides:senders) { | ||||
|         for(auto& sender:sides){ | ||||
|             evt_list&=sender->get_finish_event(); | ||||
|         } | ||||
|     } | ||||
|     wait(evt_list); | ||||
|     sc_stop(); | ||||
| } | ||||
|  | ||||
							
								
								
									
										29
									
								
								tests/sim_performance/top.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								tests/sim_performance/top.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| /* | ||||
|  * top.h | ||||
|  * | ||||
|  *  Created on: 04.05.2020 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #ifndef _SIM_PERFORMANCE_TOP_H_ | ||||
| #define _SIM_PERFORMANCE_TOP_H_ | ||||
|  | ||||
| #include <systemc> | ||||
| #include <memory> | ||||
| #include <vector> | ||||
| #include "pkt_sender.h" | ||||
| #include "pkt_switch.h" | ||||
| #include "types.h" | ||||
|  | ||||
| class top: public sc_core::sc_module { | ||||
| public: | ||||
|     top(sc_core::sc_module_name const&, unsigned); | ||||
|     virtual ~top() = default; | ||||
| private: | ||||
|     void run(); | ||||
|     sc_core::sc_clock clk; | ||||
|     std::array<std::vector<std::unique_ptr<pkt_sender>>, SIDES> senders; | ||||
|     std::vector<std::unique_ptr<pkt_switch>> switches; | ||||
| }; | ||||
|  | ||||
| #endif /* TESTS_SIM_PERFORMANCE_TOP_H_ */ | ||||
							
								
								
									
										13
									
								
								tests/sim_performance/types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								tests/sim_performance/types.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| /* | ||||
|  * types.h | ||||
|  * | ||||
|  *  Created on: 12.07.2020 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #ifndef TESTS_SIM_PERFORMANCE_TYPES_H_ | ||||
| #define TESTS_SIM_PERFORMANCE_TYPES_H_ | ||||
|  | ||||
| enum {TOP=0, RIGHT=1, BOTTOM=2, LEFT=3, SIDES=4}; | ||||
|  | ||||
| #endif /* TESTS_SIM_PERFORMANCE_TYPES_H_ */ | ||||
		Reference in New Issue
	
	Block a user