commit 48d7daf9d987da1a0b8b22e0973dd6350dfd4f80 Author: Eyck Jentzsch Date: Sun Sep 17 15:06:10 2017 +0200 Initial checkin diff --git a/.cproject b/.cproject new file mode 100644 index 0000000..a3b3b2d --- /dev/null +++ b/.cproject @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..84c048a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..decf55c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "sc-components"] + path = sc-components + url = https://github.com/Minres/SystemC-Components.git + branch = develop diff --git a/.project b/.project new file mode 100644 index 0000000..48a6ba2 --- /dev/null +++ b/.project @@ -0,0 +1,27 @@ + + + sc-components-test + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml new file mode 100644 index 0000000..f6080c7 --- /dev/null +++ b/.settings/language.settings.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.settings/org.eclipse.cdt.core.prefs b/.settings/org.eclipse.cdt.core.prefs new file mode 100644 index 0000000..68901c8 --- /dev/null +++ b/.settings/org.eclipse.cdt.core.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +environment/project/cdt.managedbuild.config.gnu.macosx.exe.debug.133691581/SYSTEMC_HOME/delimiter=\: +environment/project/cdt.managedbuild.config.gnu.macosx.exe.debug.133691581/SYSTEMC_HOME/operation=replace +environment/project/cdt.managedbuild.config.gnu.macosx.exe.debug.133691581/SYSTEMC_HOME/value=/usr/local +environment/project/cdt.managedbuild.config.gnu.macosx.exe.debug.133691581/append=true +environment/project/cdt.managedbuild.config.gnu.macosx.exe.debug.133691581/appendContributed=true diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..46f06b6 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 2.8.12) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + +### set the directory names of the submodules +set(GIT_SUBMODULE_DIR_sc-components .) +### set each submodules's commit or tag that is to be checked out +### (leave empty if you want master) +#set(GIT_SUBMODULE_VERSION_sc-comp 3af6b9836589b082c19d9131c5d0b7afa8ddd7cd) + +include(GNUInstallDirs) +include(cmake/Submodules.cmake) + +#enable_testing() + +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + set(warnings "-Wall -Wextra -Werror") + set(CMAKE_CXX_FLAG_RELEASE "-O2 -DNDEBUG") + set(CMAKE_C_FLAG_RELEASE "-O2 -DNDEBUG") + set(CMAKE_CXX_FLAG_DEBUG "-Og") + set(CMAKE_C_FLAG_DEBUG "-Og") +elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + set(warnings "/W4 /WX /EHsc") +endif() + +add_subdirectory(sc-components) +add_subdirectory(examples) +#add_subdirectory(test) diff --git a/cmake/Common.cmake b/cmake/Common.cmake new file mode 100644 index 0000000..673ec59 --- /dev/null +++ b/cmake/Common.cmake @@ -0,0 +1,20 @@ +# Function to link between sub-projects +function(add_dependent_subproject subproject_name) + #if (NOT TARGET ${subproject_name}) # target unknown + if(NOT PROJECT_${subproject_name}) # var unknown because we build only this subproject + find_package(${subproject_name} CONFIG REQUIRED) + else () # we know the target thus we are doing a build from the top directory + include_directories(../${subproject_name}/incl) + endif () +endfunction(add_dependent_subproject) + +# Make sure we tell the topdir CMakeLists that we exist (if build from topdir) +get_directory_property(hasParent PARENT_DIRECTORY) +if(hasParent) + set(PROJECT_${PROJECT_NAME} true PARENT_SCOPE) +endif() + +# Function to link between sub-projects +function(add_dependent_header subproject_name) + include_directories(../${subproject_name}/incl) +endfunction(add_dependent_header) diff --git a/cmake/DoxygenTarget.cmake b/cmake/DoxygenTarget.cmake new file mode 100644 index 0000000..49d5dd4 --- /dev/null +++ b/cmake/DoxygenTarget.cmake @@ -0,0 +1,24 @@ +function(PrepareDocTarget) + + # Configure the doxygen config file with current settings: + configure_file(documentation-config.doxygen.in ${CMAKE_CURRENT_BINARY_DIR}/documentation-config.doxygen @ONLY) + + # Set the name of the target : "doc" if it doesn't already exist and "doc" if it does. + # This way we make sure to have a single "doc" target. Either it is the one of the top directory or + # it is the one of the subproject that we are compiling alone. + set(DOC_TARGET_NAME "doc") + if(TARGET doc) + set(DOC_TARGET_NAME "doc${PROJECT_NAME}") + endif() + + add_custom_target(${DOC_TARGET_NAME} ${TARGET_ALL} + ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/documentation-config.doxygen + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating API documentation using doxygen for ${PROJECT_NAME}" VERBATIM) + + set(INSTALL_DOC_DIR ${CMAKE_BINARY_DIR}/doc/${PROJECT_NAME}/html) + file(MAKE_DIRECTORY ${INSTALL_DOC_DIR}) # needed for install + + install(DIRECTORY ${INSTALL_DOC_DIR} DESTINATION share/${PROJECT_NAME}-${VERSION_MAJOR} COMPONENT doc) + +endfunction() \ No newline at end of file diff --git a/cmake/FindSystemC.cmake b/cmake/FindSystemC.cmake new file mode 100644 index 0000000..5f55a7c --- /dev/null +++ b/cmake/FindSystemC.cmake @@ -0,0 +1,91 @@ +SET(_SYSTEMC_HINTS + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\SystemC\\2.2;SystemcHome]/include" + ${SYSTEMC_PREFIX}/include + ${SYSTEMC_PREFIX}/lib + ${SYSTEMC_PREFIX}/lib-linux + ${SYSTEMC_PREFIX}/lib-linux64 + ${SYSTEMC_PREFIX}/lib-macos + $ENV{SYSTEMC_PREFIX}/include + $ENV{SYSTEMC_PREFIX}/lib + $ENV{SYSTEMC_PREFIX}/lib-linux + $ENV{SYSTEMC_PREFIX}/lib-linux64 + $ENV{SYSTEMC_PREFIX}/lib-macos + $ENV{SYSTEMC_HOME}/include + $ENV{SYSTEMC_HOME}/lib + $ENV{SYSTEMC_HOME}/lib-linux + $ENV{SYSTEMC_HOME}/lib-linux64 + $ENV{SYSTEMC_HOME}/lib-macos + ${CMAKE_INSTALL_PREFIX}/include + ${CMAKE_INSTALL_PREFIX}/lib + ${CMAKE_INSTALL_PREFIX}/lib-linux + ${CMAKE_INSTALL_PREFIX}/lib-linux64 + ${CMAKE_INSTALL_PREFIX}/lib-macos + ) +SET(_SYSTEMC_PATHS + /usr/include/systemc + /usr/lib + /usr/lib-linux + /usr/lib-linux64 + /usr/lib-macos + /usr/local/include/sysc + /usr/local/lib + /usr/local/lib-linux + /usr/local/lib-linux64 + /usr/local/lib-macos + ) +FIND_FILE(_SYSTEMC_HEADER_FILE + NAMES systemc + HINTS ${_SYSTEMC_HINTS} + PATHS ${_SYSTEMC_PATHS} + PATH_SUFFIXES sysc/kernel +) + +FIND_FILE(_SCV_HEADER_FILE + NAMES scv.h + HINTS ${_SYSTEMC_HINTS} + PATHS ${_SYSTEMC_PATHS} + PATH_SUFFIXES sysc/kernel +) + +if(NOT _SYSTEMC_HEADER_FILE STREQUAL _SYSTEMC_HEADER_FILE-NOTFOUND) + set(SystemC_FOUND TRUE) +endif(NOT _SYSTEMC_HEADER_FILE STREQUAL _SYSTEMC_HEADER_FILE-NOTFOUND) + +if(NOT _SCV_HEADER_FILE STREQUAL _SCV_HEADER_FILE-NOTFOUND) + set(SCV_FOUND TRUE) +endif(NOT _SCV_HEADER_FILE STREQUAL _SCV_HEADER_FILE-NOTFOUND) + +FIND_PATH(SystemC_INCLUDE_DIRS + NAMES systemc.h + HINTS ${_SYSTEMC_HINTS} + PATHS ${_SYSTEMC_PATHS} +) + +FIND_PATH(SystemC_LIBRARY_DIR + NAMES libsystemc.a + HINTS ${_SYSTEMC_HINTS} + PATHS ${_SYSTEMC_PATHS} +) + +FIND_PATH(SCV_INCLUDE_DIRS + NAMES scv.h + HINTS ${_SYSTEMC_HINTS} + PATHS ${_SYSTEMC_PATHS} +) + +FIND_PATH(SCV_LIBRARY_DIRS + NAMES libscv.a + HINTS ${_SYSTEMC_HINTS} + PATHS ${_SYSTEMC_PATHS} +) + +if(SystemC_FOUND) + set(SystemC_LIBRARIES systemc) + message(STATUS "SystemC header files are taken from ${SystemC_INCLUDE_DIRS}") + message(STATUS "SystemC library is taken from ${SystemC_LIBRARY_DIR}") + if(SCV_FOUND) + set(SCV_LIBRARIES scv) + message(STATUS "SCV header files are taken from ${SCV_INCLUDE_DIRS}") + message(STATUS "SCV library is taken from ${SCV_LIBRARY_DIRS}") + endif(SCV_FOUND) +endif(SystemC_FOUND) diff --git a/cmake/GetGitRevisionDescription.cmake b/cmake/GetGitRevisionDescription.cmake new file mode 100644 index 0000000..bcd1d72 --- /dev/null +++ b/cmake/GetGitRevisionDescription.cmake @@ -0,0 +1,130 @@ +# - Returns a version string from Git +# +# These functions force a re-configure on each git commit so that you can +# trust the values of the variables in your build system. +# +# get_git_head_revision( [ ...]) +# +# Returns the refspec and sha hash of the current head revision +# +# git_describe( [ ...]) +# +# Returns the results of git describe on the source tree, and adjusting +# the output so that it tests false if an error occurs. +# +# git_get_exact_tag( [ ...]) +# +# Returns the results of git describe --exact-match on the source tree, +# and adjusting the output so that it tests false if there was no exact +# matching tag. +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +if(__get_git_revision_description) + return() +endif() +set(__get_git_revision_description YES) + +# We must run the following at "include" time, not at function call time, +# to find the path to this module rather than the path to a calling list file +get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) + +function(get_git_head_revision _refspecvar _hashvar) + set(GIT_PARENT_DIR "${CMAKE_CURRENT_LIST_DIR}") + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories + set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") + get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH) + if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT) + # We have reached the root directory, we are not in git + set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + return() + endif() + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + endwhile() + # check if this is a submodule + if(NOT IS_DIRECTORY ${GIT_DIR}) + file(READ ${GIT_DIR} submodule) + string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule}) + get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) + get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE) + endif() + set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") + if(NOT EXISTS "${GIT_DATA}") + file(MAKE_DIRECTORY "${GIT_DATA}") + endif() + + if(NOT EXISTS "${GIT_DIR}/HEAD") + return() + endif() + set(HEAD_FILE "${GIT_DATA}/HEAD") + configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) + + configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" + "${GIT_DATA}/grabRef.cmake" + @ONLY) + include("${GIT_DATA}/grabRef.cmake") + + set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) + set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) +endfunction() + +function(git_describe _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) + return() + endif() + + # TODO sanitize + #if((${ARGN}" MATCHES "&&") OR + # (ARGN MATCHES "||") OR + # (ARGN MATCHES "\\;")) + # message("Please report the following error to the project!") + # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") + #endif() + + #message(STATUS "Arguments to execute_process: ${ARGN}") + + execute_process(COMMAND + "${GIT_EXECUTABLE}" + describe + ${hash} + ${ARGN} + WORKING_DIRECTORY + "${CMAKE_SOURCE_DIR}" + RESULT_VARIABLE + res + OUTPUT_VARIABLE + out + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${_var} "${out}" PARENT_SCOPE) +endfunction() + +function(git_get_exact_tag _var) + git_describe(out --exact-match ${ARGN}) + set(${_var} "${out}" PARENT_SCOPE) +endfunction() diff --git a/cmake/GetGitRevisionDescription.cmake.in b/cmake/GetGitRevisionDescription.cmake.in new file mode 100644 index 0000000..6d8b708 --- /dev/null +++ b/cmake/GetGitRevisionDescription.cmake.in @@ -0,0 +1,41 @@ +# +# Internal file for GetGitRevisionDescription.cmake +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +set(HEAD_HASH) + +file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) + +string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) +if(HEAD_CONTENTS MATCHES "ref") + # named branch + string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") + if(EXISTS "@GIT_DIR@/${HEAD_REF}") + configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + else() + configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY) + file(READ "@GIT_DATA@/packed-refs" PACKED_REFS) + if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}") + set(HEAD_HASH "${CMAKE_MATCH_1}") + endif() + endif() +else() + # detached HEAD + configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) +endif() + +if(NOT HEAD_HASH) + file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) + string(STRIP "${HEAD_HASH}" HEAD_HASH) +endif() diff --git a/cmake/PackageConfigurator.cmake b/cmake/PackageConfigurator.cmake new file mode 100644 index 0000000..b67615d --- /dev/null +++ b/cmake/PackageConfigurator.cmake @@ -0,0 +1,44 @@ +# Create package-config files : +# - ConfigVersion.cmake +# - Config.cmake +# They are installed in lib/cmake/. +# +# Required variables : +# - VERSION +# - PROJECT_NAME +# + +# Include needed for 'write_basic_package_version_file' +include(CMakePackageConfigHelpers) + +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}ConfigVersion.cmake" + VERSION ${VERSION} + COMPATIBILITY AnyNewerVersion +) + +configure_file(cmake/${PROJECT_NAME}Config.cmake + "${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake" + COPYONLY +) + +# Destination +set(config_install_dir lib/cmake/${PROJECT_NAME}) + +# Config installation +# * /lib/cmake//Targets.cmake +install( + EXPORT ${PROJECT_NAME}Targets + DESTINATION ${config_install_dir} +) + +# Config installation +# * /lib/cmake//Config.cmake +# * /lib/cmake//ConfigVersion.cmake +install( + FILES + cmake/${PROJECT_NAME}Config.cmake + "${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}ConfigVersion.cmake" + DESTINATION ${config_install_dir} + COMPONENT devel +) \ No newline at end of file diff --git a/cmake/Submodules.cmake b/cmake/Submodules.cmake new file mode 100644 index 0000000..f2612b8 --- /dev/null +++ b/cmake/Submodules.cmake @@ -0,0 +1,53 @@ +if(EXISTS "${PROJECT_SOURCE_DIR}/.gitmodules") +message(STATUS "Updating submodules to their latest/fixed versions") +message(STATUS "(this can take a while, please be patient)") + +### First, get all submodules in +if(${GIT_SUBMODULES_CHECKOUT_QUIET}) + execute_process( + COMMAND git submodule update --init --recursive + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_QUIET + ERROR_QUIET + ) +else() + execute_process( + COMMAND git submodule update --init --recursive + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + ) +endif() + +### Then, checkout each submodule to the specified commit +# Note: Execute separate processes here, to make sure each one is run, +# should one crash (because of branch not existing, this, that ... whatever) +foreach(GIT_SUBMODULE ${GIT_SUBMODULES}) + + if( "${GIT_SUBMODULE_VERSION_${GIT_SUBMODULE}}" STREQUAL "" ) + message(STATUS "no specific version given for submodule ${GIT_SUBMODULE}, checking out master") + set(GIT_SUBMODULE_VERSION_${GIT_SUBMODULE} "master") + endif() + + if( "${GIT_SUBMODULE_DIR_${GIT_SUBMODULE}}" STREQUAL "" ) + set(GIT_SUBMODULES_DIRECTORY external) + else() + set(GIT_SUBMODULES_DIRECTORY ${GIT_SUBMODULE_DIR_${GIT_SUBMODULE}}) + endif() + + if(${GIT_SUBMODULES_CHECKOUT_QUIET}) + execute_process( + COMMAND git checkout ${GIT_SUBMODULE_VERSION_${GIT_SUBMODULE}} + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/${GIT_SUBMODULES_DIRECTORY}/${GIT_SUBMODULE} + OUTPUT_QUIET + ERROR_QUIET + ) + else() + message(STATUS "checking out ${GIT_SUBMODULE}'s commit/tag ${GIT_SUBMODULE_VERSION_${GIT_SUBMODULE}}") + execute_process( + COMMAND git checkout ${GIT_SUBMODULE_VERSION_${GIT_SUBMODULE}} + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/${GIT_SUBMODULES_DIRECTORY}/${GIT_SUBMODULE} + ) + endif() + +endforeach(${GIT_SUBMODULE}) + +endif() diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..efaa288 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required (VERSION 2.8.12) +# Add executable called "recordingExample" that is built from the source files +# "scv_tr_recording_example.cpp". The extensions are automatically found. +add_executable (recExample scv_tr_recording_example.cpp) +# Link the executable to the Hello library. Since the Hello library has +# public include directories we will use those link directories when building +# recordingExample +target_link_libraries (recExample LINK_PUBLIC sc-components) +target_link_libraries (recExample LINK_PUBLIC ${SystemC_LIBRARIES}) +target_link_libraries (recExample LINK_PUBLIC ${SCV_LIBRARIES}) +target_link_libraries (recExample LINK_PUBLIC ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries (recExample LINK_PUBLIC ${CMAKE_DL_LIBS}) diff --git a/examples/scv_tr_recording_example.cpp b/examples/scv_tr_recording_example.cpp new file mode 100644 index 0000000..02583e8 --- /dev/null +++ b/examples/scv_tr_recording_example.cpp @@ -0,0 +1,383 @@ +// -*- C++ -*- +/***************************************************************************** + + The following code is derived, directly or indirectly, from the SystemC + source code Copyright (c) 1996-2014 by all Contributors. + All Rights reserved. + + The contents of this file are subject to the restrictions and limitations + set forth in the SystemC Open Source License (the "License"); + You may not use this file except in compliance with such restrictions and + limitations. You may obtain instructions on how to receive a copy of the + License at http://www.accellera.org/. Software distributed by Contributors + under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF + ANY KIND, either express or implied. See the License for the specific + language governing rights and limitations under the License. + + *****************************************************************************/ +#include "scv.h" + +// hack to fake a true fifo_mutex +#define fifo_mutex sc_mutex + +const unsigned ram_size = 256; + +class rw_task_if: virtual public sc_interface { +public: + typedef sc_uint<8> addr_t; + typedef sc_uint<8> data_t; + struct write_t { + addr_t addr; + data_t data; + }; + + virtual data_t read(const addr_t*) = 0; + virtual void write(const write_t*) = 0; +}; + +SCV_EXTENSIONS(rw_task_if::write_t){ +public: +scv_extensions addr; +scv_extensions data; +SCV_EXTENSIONS_CTOR(rw_task_if::write_t) { + SCV_FIELD(addr); + SCV_FIELD(data); +} +}; + +class pipelined_bus_ports: public sc_module { +public: + sc_in clk; + sc_inout rw; + sc_inout addr_req; + sc_inout addr_ack; + sc_inout > bus_addr; + sc_inout data_rdy; + sc_inout > bus_data; + + SC_CTOR(pipelined_bus_ports) : + clk("clk"), rw("rw"), addr_req("addr_req"), addr_ack("addr_ack"), bus_addr("bus_addr"), data_rdy("data_rdy"), bus_data( + "bus_data") { + } + virtual void trace( sc_trace_file* tf ) const; +}; + +void pipelined_bus_ports::trace( sc_trace_file* tf ) const { + sc_trace(tf, clk, clk.name()); + sc_trace(tf, rw, rw.name()); + sc_trace(tf, addr_req, addr_req.name()); + sc_trace(tf, addr_ack, addr_ack.name()); + sc_trace(tf, bus_addr, bus_addr.name()); + sc_trace(tf, data_rdy, data_rdy.name()); + sc_trace(tf, bus_data, bus_data.name()); +} + +class rw_pipelined_transactor: public rw_task_if, public pipelined_bus_ports { + + fifo_mutex addr_phase;fifo_mutex data_phase; + + scv_tr_stream pipelined_stream; + scv_tr_stream addr_stream; + scv_tr_stream data_stream; + scv_tr_generator, sc_uint<8> > read_gen; + scv_tr_generator, sc_uint<8> > write_gen; + scv_tr_generator > addr_gen; + scv_tr_generator<_scv_tr_generator_default_data, sc_uint<8> > rdata_gen; + scv_tr_generator > wdata_gen; + +public: + rw_pipelined_transactor(sc_module_name nm) + : pipelined_bus_ports(nm) + , addr_phase("addr_phase") + , data_phase("data_phase") + , pipelined_stream((std::string(name()) +".pipelined_stream").c_str(), "transactor") + , addr_stream( (std::string(name()) +".addr_stream").c_str(), "transactor") + , data_stream((std::string(name()) +".data_stream").c_str(), "transactor") + , read_gen("read", pipelined_stream, "addr", "data") + , write_gen("write", pipelined_stream, "addr", "data") + , addr_gen("addr", addr_stream, "addr") + , rdata_gen("rdata", data_stream, NULL, "data") + , wdata_gen("wdata", data_stream, "data") + { + } + virtual data_t read(const addr_t* p_addr); + virtual void write(const write_t * req); +}; + +rw_task_if::data_t rw_pipelined_transactor::read(const addr_t* addr) { + addr_phase.lock(); + scv_tr_handle h = read_gen.begin_transaction(*addr); + h.record_attribute("data_size", sizeof(data_t)); + scv_tr_handle h1 = addr_gen.begin_transaction(*addr, "addr_phase", h); + wait(clk->posedge_event()); + bus_addr = *addr; + rw=false; + addr_req = 1; + wait(addr_ack->posedge_event()); + wait(clk->negedge_event()); + addr_req = 0; + wait(addr_ack->negedge_event()); + addr_gen.end_transaction(h1); + addr_phase.unlock(); + + data_phase.lock(); + scv_tr_handle h2 = rdata_gen.begin_transaction("data_phase", h); + wait(data_rdy->posedge_event()); + data_t data = bus_data.read(); + wait(data_rdy->negedge_event()); + rdata_gen.end_transaction(h2, data); + read_gen.end_transaction(h, data); + data_phase.unlock(); + + return data; +} + +void rw_pipelined_transactor::write(const write_t * req) { + addr_phase.lock(); + scv_tr_handle h = write_gen.begin_transaction(req->addr); + h.record_attribute("data_size", sizeof(data_t)); + scv_tr_handle h1 = addr_gen.begin_transaction(req->addr, "addr_phase", h); + wait(clk->posedge_event()); + bus_addr = req->addr; + rw=true; + addr_req = 1; + wait(addr_ack->posedge_event()); + wait(clk->negedge_event()); + addr_req = 0; + wait(addr_ack->negedge_event()); + addr_gen.end_transaction(h1); + addr_phase.unlock(); + + data_phase.lock(); + scv_tr_handle h2 = wdata_gen.begin_transaction(req->data, "data_phase", h); + bus_data=req->data; + wait(data_rdy->posedge_event()); + wait(data_rdy->negedge_event()); + wdata_gen.end_transaction(h2); + write_gen.end_transaction(h, req->data); + data_phase.unlock(); +} + +class test: public sc_module { +public: + sc_port transactor; + SC_HAS_PROCESS(test); + test( ::sc_core::sc_module_name ){ + SC_THREAD(main1); + SC_THREAD(main2); + } + void main1(); + void main2(); +}; + +class write_constraint: virtual public scv_constraint_base { +public: + scv_smart_ptr write;SCV_CONSTRAINT_CTOR(write_constraint) { + SCV_CONSTRAINT(write->addr() <= ram_size); + SCV_CONSTRAINT(write->addr() != write->data()); + } +}; + +inline void process(scv_smart_ptr data) { +} + +inline void test::main1() { + // simple sequential tests + for (int i = 0; i < 3; i++) { + rw_task_if::addr_t addr = i; + rw_task_if::data_t data = transactor->read(&addr); + cout << "at time " << sc_time_stamp() << ": "; + cout << "received data : " << data << endl; + } + + scv_smart_ptr addr; + for (int i = 0; i < 3; i++) { + + addr->next(); + rw_task_if::data_t data = transactor->read(addr->get_instance()); + cout << "data for address " << *addr << " is " << data << endl; + } + + scv_smart_ptr write; + for (int i = 0; i < 3; i++) { + write->next(); + transactor->write(write->get_instance()); + cout << "send data : " << write->data << endl; + } + + scv_smart_ptr data; + scv_bag distribution; + distribution.push(1, 40); + distribution.push(2, 60); + data->set_mode(distribution); + for (int i = 0; i < 3; i++) { + data->next(); + process(data); + } +} + +inline void test::main2() { + // simple sequential tests + for (int i = 0; i < 3; i++) { + rw_task_if::addr_t addr = i; + rw_task_if::data_t data = transactor->read(&addr); + cout << "at time " << sc_time_stamp() << ": "; + cout << "received data : " << data << endl; + } + + scv_smart_ptr addr; + for (int i = 0; i < 3; i++) { + + addr->next(); + rw_task_if::data_t data = transactor->read(addr->get_instance()); + cout << "data for address " << *addr << " is " << data << endl; + } + + scv_smart_ptr write; + for (int i = 0; i < 3; i++) { + write->next(); + transactor->write(write->get_instance()); + cout << "send data : " << write->data << endl; + } + + scv_smart_ptr data; + scv_bag distribution; + distribution.push(1, 140); + distribution.push(2, 160); + data->set_mode(distribution); + for (int i = 0; i < 3; i++) { + data->next(); + process(data); + } +} +class design: public pipelined_bus_ports { + std::list > outstandingAddresses; + std::list outstandingType; + sc_uint<8> memory[ram_size]; + +public: + SC_HAS_PROCESS(design); + design(sc_module_name nm) : + pipelined_bus_ports(nm) { + for (unsigned i = 0; i < ram_size; ++i) { + memory[i] = i; + } + SC_THREAD(addr_phase); + SC_THREAD(data_phase); + } + void addr_phase(); + void data_phase(); +}; + +inline void design::addr_phase() { + while (1) { + while (addr_req.read() != 1) { + wait(addr_req->value_changed_event()); + } + sc_uint<8> _addr = bus_addr.read(); + bool _rw = rw.read(); + + int cycle = rand() % 10 + 1; + while (cycle-- > 0) { + wait(clk->posedge_event()); + } + + addr_ack = 1; + wait(clk->posedge_event()); + addr_ack = 0; + + outstandingAddresses.push_back(_addr); + outstandingType.push_back(_rw); + cout << "at time " << sc_time_stamp() << ": "; + cout << "received request for memory address " << _addr << endl; + } +} + +inline void design::data_phase() { + while (1) { + while (outstandingAddresses.empty()) { + wait(clk->posedge_event()); + } + int cycle = rand() % 10 + 1; + while (cycle-- > 0) { + wait(clk->posedge_event()); + } + if (outstandingType.front() == false) { + cout << "reading memory address " << outstandingAddresses.front() << " with value " + << memory[outstandingAddresses.front().to_ulong()] << endl; + bus_data = memory[outstandingAddresses.front().to_ulong()]; + data_rdy = 1; + wait(clk->posedge_event()); + data_rdy = 0; + + } else { + cout << "writing memory address " << outstandingAddresses.front() << " with value " + << bus_data << endl; + memory[outstandingAddresses.front().to_ulong()]=bus_data; + data_rdy = 1; + wait(clk->posedge_event()); + data_rdy = 0; + } + outstandingAddresses.pop_front(); + outstandingType.pop_front(); + } +} +extern void scv_tr_sqlite_init(); + +int sc_main(int argc, char *argv[]) { + scv_startup(); + +#if 0 + scv_tr_text_init(); + const char* fileName = "my_db.txlog"; +#else + scv_tr_sqlite_init(); + const char* fileName = "my_db"; +#endif + scv_tr_db db(fileName); + scv_tr_db::set_default_db(&db); + sc_trace_file* tf = sc_create_vcd_trace_file("my_db"); + // create signals + sc_clock clk("clk", 20.0, SC_NS, 0.5, 0.0, SC_NS, true); + sc_signal rw; + sc_signal addr_req; + sc_signal addr_ack; + sc_signal > bus_addr; + sc_signal data_rdy; + sc_signal > bus_data; + + // create modules/channels + test t("t"); + rw_pipelined_transactor tr("tr"); + design duv("duv"); + + // connect them up + t.transactor(tr); + + tr.clk(clk); + tr.rw(rw); + tr.addr_req(addr_req); + tr.addr_ack(addr_ack); + tr.bus_addr(bus_addr); + tr.data_rdy(data_rdy); + tr.bus_data(bus_data); + tr.trace(tf); + + duv.clk(clk); + duv.rw(rw); + duv.addr_req(addr_req); + duv.addr_ack(addr_ack); + duv.bus_addr(bus_addr); + duv.data_rdy(data_rdy); + duv.bus_data(bus_data); + duv.trace(tf); + + // Accellera SystemC >=2.2 got picky about multiple drivers. + // Disable check for bus simulation. + sc_report_handler::set_actions(SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, SC_DO_NOTHING); + // run the simulation + sc_start(1.0, SC_MS); + sc_close_vcd_trace_file(tf); + return 0; +} + diff --git a/sc-components b/sc-components new file mode 160000 index 0000000..53ccc12 --- /dev/null +++ b/sc-components @@ -0,0 +1 @@ +Subproject commit 53ccc122bb2f6143bde83f915e65b1f5bee9d0c5