diff --git a/CMakeLists.txt b/CMakeLists.txt index 71d4723..d110f03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.3) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_CURRENT_SOURCE_DIR}/sc-components/cmake) include(cmake/GitFunctions.cmake) @@ -16,19 +16,26 @@ set(GIT_SUBMODULE_BRANCH_dbt-core ${GIT_BRANCH}) include(GNUInstallDirs) include(Submodules) +include(Conan) #enable_testing() +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(warnings "-Wall -Wextra -Werror") - set(CMAKE_CXX_FLAG_RELEASE "-O3 -DNDEBUG") + set(CMAKE_CXX_FLAG_RELEASE "-O3 -DNDEBUG -D_GLIBCXX_USE_CXX11_ABI=0") set(CMAKE_C_FLAG_RELEASE "-O3 -DNDEBUG") - set(CMAKE_CXX_FLAG_DEBUG "-Og") + set(CMAKE_CXX_FLAG_DEBUG "-Og -D_GLIBCXX_USE_CXX11_ABI=0") set(CMAKE_C_FLAG_DEBUG "-Og") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set(warnings "/W4 /WX /EHsc") endif() +setup_conan() + find_package(Threads) find_package(Tcmalloc) @@ -40,3 +47,5 @@ add_subdirectory(dbt-core) add_subdirectory(sc-components) add_subdirectory(riscv) add_subdirectory(riscv.sc) + +message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}") \ No newline at end of file diff --git a/README.md b/README.md index fc41e1a..26f7fc8 100644 --- a/README.md +++ b/README.md @@ -25,20 +25,32 @@ DBT-RISE-RiscV uses libGIS (https://github.com/vsergeev/libGIS) as well as ELFIO **Quick start** -* you need to have a decent compiler, make and cmake installed -* install LLVM 4.0 according to http://apt.llvm.org/ -* download and install SystemC from http://accellera.org/downloads/standards/systemc +* you need to have a decent compiler, make, python, and cmake installed +* install LLVM 4.0 according to http://apt.llvm.org/ (if it is not already provided by your distribution) +* install conan.io (see also http://docs.conan.io/en/latest/installation.html) +``` + pip install conan +``` +* download and install SystemC from http://accellera.org/downloads/standards/systemc (this is going to be replaced with a conan.io integration) * optionally download and install SystemC Verification Library (SCV) from Accelera into the same location +* setup conan to use the minres repo +``` + conan add remote minres https://dl.bintray.com/minres/conan-repo +``` * checkout source from git -* start an out-of-source build like so (e.g. when using LLVM 3.9 and bash) -``` +* start an out-of-source build like so (e.g. when using bash) +``` cd DBT-RISE-RiscV mkdir build cd build cmake .. - make + cmake --build . ``` * if the SystemC installation is not found by cmake you can optionally specify the location by either setting the following environment variables pointing to the installation - SYSTEMC_HOME - SYSTEMC_PREFIX - \ No newline at end of file +* if you encounter issues when linking wrt. c++11 symbols you might have run into GCC ABI incompatibility introduced from GCC 5.0 onwards. You can fix this by adding '-s compiler.libcxx=libstdc++11' to the conan call or changing compiler.libcxx to +``` +compiler.libcxx=libstdc++11 +``` +in $HOME/.conan/profiles/default \ No newline at end of file diff --git a/cmake/Conan.cmake b/cmake/Conan.cmake new file mode 100644 index 0000000..42e5ce1 --- /dev/null +++ b/cmake/Conan.cmake @@ -0,0 +1,42 @@ +macro(setup_conan) + find_program(conan conan) + 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) + + if(${CMAKE_BUILD_TYPE} STREQUAL RelWithDebInfo) + execute_process(COMMAND ${conan} install --build=missing + -s build_type=Release + ${CMAKE_SOURCE_DIR} RESULT_VARIABLE return_code) + else() + execute_process(COMMAND ${conan} install --build=missing + -s build_type=${CMAKE_BUILD_TYPE} + ${CMAKE_SOURCE_DIR} RESULT_VARIABLE return_code) + endif() + if(NOT ${return_code} EQUAL 0) + message(FATAL_ERROR "conan install command failed.") + endif() + + include(${conanfile_cmake}) + conan_basic_setup(TARGETS) +endmacro() \ No newline at end of file diff --git a/conanfile.txt b/conanfile.txt new file mode 100644 index 0000000..9505687 --- /dev/null +++ b/conanfile.txt @@ -0,0 +1,10 @@ +[requires] +Poco/1.7.8p3@pocoproject/stable +Seasocks/1.3.2@seasocks/stable + +[generators] +cmake + +[options] +Poco:shared=True +Seasocks:shared=False \ No newline at end of file diff --git a/riscv.sc/incl/sysc/sc_singleton.h b/riscv.sc/incl/sysc/sc_singleton.h new file mode 100644 index 0000000..26f5dff --- /dev/null +++ b/riscv.sc/incl/sysc/sc_singleton.h @@ -0,0 +1,49 @@ +/* + * sc_singleton.h + * + * Created on: 09.10.2017 + * Author: eyck + */ + +#ifndef RISCV_SC_INCL_SYSC_SC_SINGLETON_H_ +#define RISCV_SC_INCL_SYSC_SC_SINGLETON_H_ + +#include +#include +#include + +namespace seasocks { +class Server; +} + +namespace sysc { + +class sc_singleton: public sc_core::sc_module { +public: + sc_singleton() = delete; + + sc_singleton(const sc_singleton&) = delete; + + sc_singleton& operator=(sc_singleton& o) = delete; + + virtual ~sc_singleton(); + + static sc_singleton& inst(){ + static sc_singleton i("__sc_singleton"); + return i; + } + + seasocks::Server& get_server(); +protected: + void start_of_simulation(); + +private: + sc_singleton(sc_core::sc_module_name nm); + std::unique_ptr m_serv; + std::thread t; + void thread_func(); +}; + +} /* namespace sysc */ + +#endif /* RISCV_SC_INCL_SYSC_SC_SINGLETON_H_ */ diff --git a/riscv.sc/src/CMakeLists.txt b/riscv.sc/src/CMakeLists.txt index 982cec2..ef3a5df 100644 --- a/riscv.sc/src/CMakeLists.txt +++ b/riscv.sc/src/CMakeLists.txt @@ -36,6 +36,7 @@ target_link_libraries(${APPLICATION_NAME} ${LIBRARY_NAME}) target_link_libraries(${APPLICATION_NAME} risc-v) target_link_libraries(${APPLICATION_NAME} dbt-core) target_link_libraries(${APPLICATION_NAME} sc-components) +target_link_libraries(${APPLICATION_NAME} CONAN_PKG::Seasocks) target_link_libraries(${APPLICATION_NAME} external) target_link_libraries(${APPLICATION_NAME} ${llvm_libs}) target_link_libraries(${APPLICATION_NAME} ${SystemC_LIBRARIES} ) diff --git a/riscv.sc/src/sysc/sc_singleton.cpp b/riscv.sc/src/sysc/sc_singleton.cpp new file mode 100644 index 0000000..4f997b6 --- /dev/null +++ b/riscv.sc/src/sysc/sc_singleton.cpp @@ -0,0 +1,57 @@ +/* + * sc_singleton.cpp + * + * Created on: 09.10.2017 + * Author: eyck + */ + +#include "sysc/sc_singleton.h" + +#include "seasocks/PrintfLogger.h" +#include "seasocks/Server.h" +#include "seasocks/StringUtil.h" +#include "seasocks/util/Json.h" +#include "seasocks/ResponseWriter.h" +#include "seasocks/util/RootPageHandler.h" +#include "seasocks/util/CrackedUriPageHandler.h" +#include "seasocks/util/StaticResponseHandler.h" + +namespace sysc { + +using namespace seasocks; +using namespace std; + +namespace { +const std::string MSG_TXT { "Hello World"}; +} + +void sc_singleton::start_of_simulation() { + //Launch a thread + t=std::thread(&sc_singleton::thread_func, this); + +} + +sc_singleton::sc_singleton(sc_core::sc_module_name nm) +: sc_core::sc_module(nm) +, m_serv(new seasocks::Server(std::make_shared(Logger::Level::DEBUG))){ + auto rootHandler = make_shared(); + rootHandler->add(std::shared_ptr(new StaticResponseHandler("/", Response::textResponse(MSG_TXT)))); + m_serv->addPageHandler(rootHandler); +} + +sc_singleton::~sc_singleton() { + //Join the thread with the main thread + t.join(); +} + +void sc_singleton::thread_func() { + get_server().serve(".", 9090); +} + +seasocks::Server& sc_singleton::get_server() { + return *m_serv.get(); +} + + +} /* namespace sysc */ + diff --git a/riscv.sc/src/sysc/uart.cpp b/riscv.sc/src/sysc/uart.cpp index c0f77c3..0f7887d 100644 --- a/riscv.sc/src/sysc/uart.cpp +++ b/riscv.sc/src/sysc/uart.cpp @@ -19,9 +19,75 @@ #include "scc/report.h" #include "scc/utilities.h" #include "sysc/SiFive/gen/uart_regs.h" +#include "sysc/sc_singleton.h" + +#include "seasocks/PrintfLogger.h" +#include "seasocks/Server.h" +#include "seasocks/StringUtil.h" +#include "seasocks/WebSocket.h" +#include "seasocks/util/Json.h" namespace sysc { +namespace { +using namespace seasocks; + +class MyHandler: public WebSocket::Handler { +public: + explicit MyHandler(Server* server) : _server(server), _currentValue(0) { + setValue(1); + } + + virtual void onConnect(WebSocket* connection) { + _connections.insert(connection); + connection->send(_currentSetValue.c_str()); + cout << "Connected: " << connection->getRequestUri() + << " : " << formatAddress(connection->getRemoteAddress()) + << endl; + cout << "Credentials: " << *(connection->credentials()) << endl; + } + + virtual void onData(WebSocket* connection, const char* data) { + if (0 == strcmp("die", data)) { + _server->terminate(); + return; + } + if (0 == strcmp("close", data)) { + cout << "Closing.." << endl; + connection->close(); + cout << "Closed." << endl; + return; + } + + int value = atoi(data) + 1; + if (value > _currentValue) { + setValue(value); + for (auto c : _connections) { + c->send(_currentSetValue.c_str()); + } + } + } + + virtual void onDisconnect(WebSocket* connection) { + _connections.erase(connection); + cout << "Disconnected: " << connection->getRequestUri() + << " : " << formatAddress(connection->getRemoteAddress()) + << endl; + } + +private: + set _connections; + Server* _server; + int _currentValue; + string _currentSetValue; + + void setValue(int value) { + _currentValue = value; + _currentSetValue = makeExecString("set", _currentValue); + } +}; + +} uart::uart(sc_core::sc_module_name nm) : sc_core::sc_module(nm) , tlm_target<>(clk) @@ -41,6 +107,10 @@ uart::uart(sc_core::sc_module_name nm) } return true; }); + auto& server = sc_singleton::inst().get_server(); + auto handler = std::make_shared(&server); + server.addWebSocketHandler((std::string{"/ws/"}+name()).c_str(), handler); + } uart::~uart() {} diff --git a/sc-components b/sc-components index ba65d9f..d5abb72 160000 --- a/sc-components +++ b/sc-components @@ -1 +1 @@ -Subproject commit ba65d9f172246d6735a40fd6259ec13467e43419 +Subproject commit d5abb72bf3e9030e4a7800195cb6ea5e1bb218cc