diff --git a/CMakeLists.txt b/CMakeLists.txt index 04e6dd5..b3d3a69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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() diff --git a/cmake/Conan.cmake b/cmake/Conan.cmake deleted file mode 100644 index 946ccb9..0000000 --- a/cmake/Conan.cmake +++ /dev/null @@ -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() diff --git a/sc-components b/sc-components index ffa9b52..3192c9c 160000 --- a/sc-components +++ b/sc-components @@ -1 +1 @@ -Subproject commit ffa9b526d7f64f7233720d139e7202aaba61895c +Subproject commit 3192c9cc2169b18ee7e1cd2c9fbb92d04887e7ac diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 919cf09..dc55372 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,3 +1,3 @@ add_subdirectory(io-redirector) -#add_subdirectory(sim_performance) +add_subdirectory(sim_performance) add_subdirectory(ordered_semaphore) diff --git a/tests/sim_performance/CMakeLists.txt b/tests/sim_performance/CMakeLists.txt index 9bfb17d..b907dc9 100644 --- a/tests/sim_performance/CMakeLists.txt +++ b/tests/sim_performance/CMakeLists.txt @@ -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) diff --git a/tests/sim_performance/packet.h b/tests/sim_performance/packet.h new file mode 100644 index 0000000..0d047e2 --- /dev/null +++ b/tests/sim_performance/packet.h @@ -0,0 +1,34 @@ +/* + * packet.h + * + * Created on: 04.05.2020 + * Author: eyck + */ + +#ifndef _SIM_PERFORMANCE_PACKET_H_ +#define _SIM_PERFORMANCE_PACKET_H_ + +#include + +struct packet { + std::vector routing; +}; + +struct packet_ext: public tlm::tlm_extension, 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(&o); + if(ext) + this->routing=ext->routing; + } +}; + +#endif /* _SIM_PERFORMANCE_PACKET_H_ */ diff --git a/tests/sim_performance/pkt_sender.cpp b/tests/sim_performance/pkt_sender.cpp new file mode 100644 index 0000000..a7b060d --- /dev/null +++ b/tests/sim_performance/pkt_sender.cpp @@ -0,0 +1,99 @@ +/* + * blocks.cpp + * + * Created on: 04.05.2020 + * Author: eyck + */ + +#include "pkt_sender.h" +#include "types.h" +#include +#include + +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 "<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< &route_vec) { + if(std::get<0>(my_pos)==0){ + for(auto i=0; i(my_pos)==dim+1){ + for(auto i=0; i(my_pos)==0){ + for(auto i=0; i(my_pos)==dim+1){ + for(auto i=0; i::get().allocate(); + gen_routing(gp->get_extension()->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(); + 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(); + } +} diff --git a/tests/sim_performance/pkt_sender.h b/tests/sim_performance/pkt_sender.h new file mode 100644 index 0000000..b6728af --- /dev/null +++ b/tests/sim_performance/pkt_sender.h @@ -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 +#include "packet.h" +#include +#include + + +class pkt_sender : sc_core::sc_module { +public: + sc_core::sc_in clk_i{"clk_i"}; + scc::initiator_mixin> isck; + scc::target_mixin> 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& route_vec); + void received(); + tlm_utils::peq_with_get 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 my_pos; + const unsigned dim; +}; + +#endif /* _SIM_PERFORMANCE_PKT_SENDER_H_ */ diff --git a/tests/sim_performance/pkt_switch.cpp b/tests/sim_performance/pkt_switch.cpp new file mode 100644 index 0000000..57943f6 --- /dev/null +++ b/tests/sim_performance/pkt_switch.cpp @@ -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 +#include + +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<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, SIDES> routing{}; + bool nothing_todo=true; + for(auto i=0U; iget_extension(); + sc_assert(ext); + routing[ext->routing.back()].push_back(i); + nothing_todo = false; + } + } + if(nothing_todo) return; + for(auto i=0U; iget_extension(); + 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; +} diff --git a/tests/sim_performance/pkt_switch.h b/tests/sim_performance/pkt_switch.h new file mode 100644 index 0000000..732acc5 --- /dev/null +++ b/tests/sim_performance/pkt_switch.h @@ -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 +#include "packet.h" +#include +#include +#include +#include + + +class pkt_switch : sc_core::sc_module { +public: + enum {NONE=std::numeric_limits::max()}; + sc_core::sc_in clk_i{"clk_i"}; + sc_core::sc_vector>> tsck{"tsck",4}; + sc_core::sc_vector>> 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> in_tx{"in_sig", 4}; + sc_core::sc_vector> out_fifo{"out_peq", 4}; + std::array last_sel_inp{NONE, NONE, NONE, NONE}; +}; + +#endif /* _SIM_PERFORMANCE_PKT_SWITCH_H_ */ diff --git a/tests/sim_performance/sc_main.cpp b/tests/sim_performance/sc_main.cpp new file mode 100644 index 0000000..fac05d7 --- /dev/null +++ b/tests/sim_performance/sc_main.cpp @@ -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 +#include +#include +#include +#include + +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; +} diff --git a/tests/sim_performance/top.cpp b/tests/sim_performance/top.cpp new file mode 100644 index 0000000..da8cc68 --- /dev/null +++ b/tests/sim_performance/top.cpp @@ -0,0 +1,96 @@ +/* + * top.cpp + * + * Created on: 04.05.2020 + * Author: eyck + */ + +#include "top.h" +#include +#include +#include + +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(sc_module_name(name.c_str()))); + switches.back()->clk_i(clk); + } + } + for(auto yidx=0U; yidxisck[RIGHT](swr->tsck[LEFT]); + swr->isck[LEFT](sw->tsck[RIGHT]); + } + if(yidxisck[BOTTOM](swb->tsck[TOP]); + swb->isck[TOP](sw->tsck[BOTTOM]); + } + } + } + auto yidx = 0U; + auto xidx = 0U; + for(xidx=0U; xidx(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(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(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(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(); +} + diff --git a/tests/sim_performance/top.h b/tests/sim_performance/top.h new file mode 100644 index 0000000..15627f5 --- /dev/null +++ b/tests/sim_performance/top.h @@ -0,0 +1,29 @@ +/* + * top.h + * + * Created on: 04.05.2020 + * Author: eyck + */ + +#ifndef _SIM_PERFORMANCE_TOP_H_ +#define _SIM_PERFORMANCE_TOP_H_ + +#include +#include +#include +#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>, SIDES> senders; + std::vector> switches; +}; + +#endif /* TESTS_SIM_PERFORMANCE_TOP_H_ */ diff --git a/tests/sim_performance/types.h b/tests/sim_performance/types.h new file mode 100644 index 0000000..059b0c6 --- /dev/null +++ b/tests/sim_performance/types.h @@ -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_ */