add test case focusing on simulation kernel performance
This commit is contained in:
parent
954bbed352
commit
61c33fdcc3
|
@ -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()
|
|
@ -1 +1 @@
|
|||
Subproject commit ffa9b526d7f64f7233720d139e7202aaba61895c
|
||||
Subproject commit 3192c9cc2169b18ee7e1cd2c9fbb92d04887e7ac
|
|
@ -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)
|
||||
|
|
|
@ -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_ */
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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_ */
|
|
@ -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;
|
||||
}
|
|
@ -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_ */
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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_ */
|
|
@ -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_ */
|
Loading…
Reference in New Issue