Back-ported DVCon turorial changes

This commit is contained in:
Eyck Jentzsch 2018-11-08 13:31:28 +01:00
parent 124a308ffa
commit 20b3665003
86 changed files with 429488 additions and 4424 deletions

View File

@ -70,7 +70,7 @@
</extensions> </extensions>
</storageModule> </storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0"> <storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.1745230171" name="Release" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=" parent="cdt.managedbuild.config.gnu.exe.release"> <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.1745230171" name="Release" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="cdt.managedbuild.config.gnu.exe.release">
<folderInfo id="cdt.managedbuild.config.gnu.exe.release.1745230171." name="/" resourcePath=""> <folderInfo id="cdt.managedbuild.config.gnu.exe.release.1745230171." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.2006835092" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release"> <toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.2006835092" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
<targetPlatform binaryParser="org.eclipse.cdt.core.GNU_ELF;org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.exe.release.1630517313" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/> <targetPlatform binaryParser="org.eclipse.cdt.core.GNU_ELF;org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.exe.release.1630517313" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
@ -171,6 +171,23 @@
<storageModule moduleId="cdtBuildSystem" version="4.0.0"> <storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="DBT-RISE-RISCV.cdt.managedbuild.target.gnu.exe.1695631616" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/> <project id="DBT-RISE-RISCV.cdt.managedbuild.target.gnu.exe.1695631616" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="RelWithDebInfo">
<resource resourceType="PROJECT" workspacePath="/DBT-RISE-RISCV"/>
</configuration>
<configuration configurationName="Default">
<resource resourceType="PROJECT" workspacePath="/DBT-RISE-RISCV"/>
</configuration>
<configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/DBT-RISE-RISCV"/>
</configuration>
<configuration configurationName="Release">
<resource resourceType="PROJECT" workspacePath="/DBT-RISE-RISCV"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<storageModule moduleId="scannerConfiguration"> <storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.119132886.1995486963;cdt.managedbuild.config.gnu.exe.debug.119132886.1995486963.;cdt.managedbuild.tool.gnu.cpp.compiler.base.64491626;cdt.managedbuild.tool.gnu.cpp.compiler.input.550087631"> <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.119132886.1995486963;cdt.managedbuild.config.gnu.exe.debug.119132886.1995486963.;cdt.managedbuild.tool.gnu.cpp.compiler.base.64491626;cdt.managedbuild.tool.gnu.cpp.compiler.input.550087631">
@ -215,6 +232,9 @@
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.1745230171;cdt.managedbuild.config.gnu.exe.release.1745230171.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.187095968;cdt.managedbuild.tool.gnu.cpp.compiler.input.1317114938"> <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.1745230171;cdt.managedbuild.config.gnu.exe.release.1745230171.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.187095968;cdt.managedbuild.tool.gnu.cpp.compiler.input.1317114938">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo> </scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404;cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1556984395;cdt.managedbuild.tool.gnu.cpp.compiler.input.228859511">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.119132886.1763523931;cdt.managedbuild.config.gnu.exe.debug.119132886.1763523931.;cdt.managedbuild.tool.gnu.c.compiler.base.1252259913;cdt.managedbuild.tool.gnu.c.compiler.input.1578289923"> <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.119132886.1763523931;cdt.managedbuild.config.gnu.exe.debug.119132886.1763523931.;cdt.managedbuild.tool.gnu.c.compiler.base.1252259913;cdt.managedbuild.tool.gnu.c.compiler.input.1578289923">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo> </scannerConfigBuildInfo>
@ -224,25 +244,11 @@
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.446935686;cdt.managedbuild.config.gnu.exe.release.446935686.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1265053613;cdt.managedbuild.tool.gnu.cpp.compiler.input.1842530130"> <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.446935686;cdt.managedbuild.config.gnu.exe.release.446935686.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1265053613;cdt.managedbuild.tool.gnu.cpp.compiler.input.1842530130">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo> </scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404;cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.1020243188;cdt.managedbuild.tool.gnu.c.compiler.input.693742822">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1751741082;cdt.managedbuild.config.gnu.exe.debug.1751741082.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.1306991179;cdt.managedbuild.tool.gnu.c.compiler.input.140891728"> <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1751741082;cdt.managedbuild.config.gnu.exe.debug.1751741082.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.1306991179;cdt.managedbuild.tool.gnu.c.compiler.input.140891728">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo> </scannerConfigBuildInfo>
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="RelWithDebInfo">
<resource resourceType="PROJECT" workspacePath="/DBT-RISE-RISCV"/>
</configuration>
<configuration configurationName="Default">
<resource resourceType="PROJECT" workspacePath="/DBT-RISE-RISCV"/>
</configuration>
<configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/DBT-RISE-RISCV"/>
</configuration>
<configuration configurationName="Release">
<resource resourceType="PROJECT" workspacePath="/DBT-RISE-RISCV"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
</cproject> </cproject>

View File

@ -1,8 +1,17 @@
cmake_minimum_required(VERSION 3.3) 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) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_CURRENT_SOURCE_DIR}/sc-components/cmake)
set(ENABLE_SCV TRUE CACHE BOOL "Enable use of SCV")
include(GitFunctions) include(GitFunctions)
get_branch_from_git() get_branch_from_git()
# if we are not on master or develop set the submodules to develop
IF(NOT ${GIT_BRANCH} MATCHES "master")
IF(NOT ${GIT_BRANCH} MATCHES "develop")
message(STATUS "main branch is '${GIT_BRANCH}', setting submodules to 'develop'")
set(GIT_BRANCH develop)
endif()
endif()
### set the directory names of the submodules ### set the directory names of the submodules
set(GIT_SUBMODULES elfio libGIS sc-components dbt-core) set(GIT_SUBMODULES elfio libGIS sc-components dbt-core)
@ -45,12 +54,58 @@ endif()
setup_conan() setup_conan()
# This line finds the boost lib and headers.
set(Boost_NO_BOOST_CMAKE ON) # Don't do a find_package in config mode before searching for a regular boost install.
find_package(Boost COMPONENTS program_options system thread filesystem REQUIRED)
if(DEFINED ENV{LLVM_HOME})
find_path (LLVM_DIR LLVM-Config.cmake $ENV{LLVM_HOME}/lib/cmake/llvm)
endif(DEFINED ENV{LLVM_HOME})
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
llvm_map_components_to_libnames(llvm_libs support core mcjit x86codegen x86asmparser)
find_package(Threads) find_package(Threads)
find_package(Tcmalloc) find_package(Tcmalloc)
find_package(ZLIB)
find_package(SystemC)
if(SystemC_FOUND)
message(STATUS "SystemC headers at ${SystemC_INCLUDE_DIRS}")
message(STATUS "SystemC library at ${SystemC_LIBRARY_DIRS}")
if(SCV_FOUND)
message(STATUS "SCV headers at ${SCV_INCLUDE_DIRS}")
message(STATUS "SCV library at ${SCV_LIBRARY_DIRS}")
endif(SCV_FOUND)
if(CCI_FOUND)
message(STATUS "CCI headers at ${CCI_INCLUDE_DIRS}")
message(STATUS "CCI library at ${CCI_LIBRARY_DIRS}")
endif()
endif(SystemC_FOUND)
set(PROJECT_3PARTY_DIRS external) set(PROJECT_3PARTY_DIRS external)
include(clang-format) include(clang-format)
set(ENABLE_CLANG_TIDY OFF CACHE BOOL "Add clang-tidy automatically to builds")
if (ENABLE_CLANG_TIDY)
find_program (CLANG_TIDY_EXE NAMES "clang-tidy" PATHS /usr/local/opt/llvm/bin )
if (CLANG_TIDY_EXE)
message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}")
set(CLANG_TIDY_CHECKS "-*,modernize-*")
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_EXE};-checks=${CLANG_TIDY_CHECKS};-header-filter='${CMAKE_SOURCE_DIR}/*';-fix"
CACHE STRING "" FORCE)
else()
message(AUTHOR_WARNING "clang-tidy not found!")
set(CMAKE_CXX_CLANG_TIDY "" CACHE STRING "" FORCE) # delete it
endif()
endif()
# Set the version number of your project here (format is MAJOR.MINOR.PATCHLEVEL - e.g. 1.0.0)
set(VERSION_MAJOR "1")
set(VERSION_MINOR "0")
set(VERSION_PATCH "0")
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
add_subdirectory(external) add_subdirectory(external)
add_subdirectory(dbt-core) add_subdirectory(dbt-core)
add_subdirectory(sc-components) add_subdirectory(sc-components)

View File

@ -25,8 +25,8 @@ DBT-RISE-RISCV uses libGIS (https://github.com/vsergeev/libGIS) as well as ELFIO
**Quick start** **Quick start**
* you need to have a decent compiler, make, python, and cmake installed * you need to have a C++11 capable 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 e.g by Ubuntu 17.04) * install LLVM >= 4.0 according to http://apt.llvm.org/ (if it is not already provided by your distribution e.g by Ubuntu 18.04)
* install conan.io (see also http://docs.conan.io/en/latest/installation.html): * install conan.io (see also http://docs.conan.io/en/latest/installation.html):
``` ```
pip install conan pip install conan

423701
callgrind.out.2141 Normal file

File diff suppressed because it is too large Load Diff

@ -1 +1 @@
Subproject commit 31263d4aaa6a7f01914c2decead091dc968f30d3 Subproject commit 54cf894c3f3897a57f366905345514f5e94a5166

View File

@ -1,4 +1,35 @@
#!/bin/sh #!/bin/sh
#******************************************************************************
# Copyright (C) 2018 MINRES Technologies GmbH
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
#******************************************************************************/
## ##
if [ -n "$1" ]; then if [ -n "$1" ]; then

View File

@ -7,7 +7,7 @@ project("external")
include(Common) include(Common)
include_directories( ${PROJECT_SOURCE_DIR}/external/libGIS ) include_directories( ${PROJECT_SOURCE_DIR}/libGIS )
FILE(GLOB ElfioHeaders elfio *.hpp) FILE(GLOB ElfioHeaders elfio *.hpp)
FILE(GLOB GISHeaders libGis *.h) FILE(GLOB GISHeaders libGis *.h)

View File

@ -1,3 +1,34 @@
/*******************************************************************************
* Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
var ws; var ws;
$(function() { $(function() {

View File

@ -79,7 +79,7 @@ span.value_x { background-color: red;}
} }
} }
var open_connection = function(name){ var open_connection = function(name){
var s = new WebSocket('ws://'+window.location.host+'/ws/i_simple_system.i_'+name); var s = new WebSocket('ws://'+window.location.host+'/ws/i_system.i_hifive1.i_'+name);
s.addEventListener('error', function (m) { log(name, new Date().toISOString()+': ===connection error ==='); }); s.addEventListener('error', function (m) { log(name, new Date().toISOString()+': ===connection error ==='); });
s.addEventListener('open', function (m) { log(name, new Date().toISOString()+': ===connection opened==='); }); s.addEventListener('open', function (m) { log(name, new Date().toISOString()+': ===connection opened==='); });
s.addEventListener('message', function (m) { log(name, m.data); }); s.addEventListener('message', function (m) { log(name, m.data); });
@ -99,8 +99,7 @@ span.value_x { background-color: red;}
top.appendChild(div); top.appendChild(div);
open_connection(n); open_connection(n);
} }
createElem("uart0"); createElem("terminal");
createElem("gpio0");
</script> </script>
</body> </body>
</html> </html>

View File

@ -8,63 +8,19 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
# Set the name of your project here # Set the name of your project here
project("riscv.sc") project("platform")
# Set the version number of your project here (format is MAJOR.MINOR.PATCHLEVEL - e.g. 1.0.0)
set(VERSION_MAJOR "0")
set(VERSION_MINOR "0")
set(VERSION_PATCH "1")
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
include(Common) include(Common)
# check that we have averything we need
## Git (and its revision) if(!SystemC_FOUND)
find_package(Git QUIET) # if we don't find git or FindGit.cmake is not on the system we ignore it. message( FATAL_ERROR "SystemC library not found." )
## The Git module will trigger a reconfiguration for each pull that will bring a new revision on the local repository
set (VCS_REVISION "-1")
if(GIT_FOUND)
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REFSPEC GIT_SHA1)
message(STATUS "GIT branch ${GIT_REFSPEC}")
message(STATUS "GIT revision ${GIT_SHA1}")
set (VCS_REVISION ${GIT_SHA1})
endif() endif()
# This line finds the boost lib and headers. if(!CCI_FOUND)
set(Boost_NO_BOOST_CMAKE ON) # Don't do a find_package in config mode before searching for a regular boost install.
find_package(Boost COMPONENTS program_options system thread REQUIRED)
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
llvm_map_components_to_libnames(llvm_libs support core mcjit x86codegen x86asmparser)
find_package(SystemC)
if(SystemC_FOUND)
add_definitions(-DWITH_SYSTEMC)
include_directories(${SystemC_INCLUDE_DIRS})
link_directories(${SystemC_LIBRARY_DIRS})
else(SystemC_FOUND)
message( FATAL_ERROR "SystemC library not found." )
endif(SystemC_FOUND)
if(CCI_FOUND)
include_directories(${CCI_INCLUDE_DIRS})
link_directories(${CCI_LIBRARY_DIRS})
else()
message( FATAL_ERROR "SystemC CCI library not found." ) message( FATAL_ERROR "SystemC CCI library not found." )
endif() endif()
if(SCV_FOUND)
add_definitions(-DWITH_SCV)
link_directories(${SCV_LIBRARY_DIRS})
endif(SCV_FOUND)
# This sets the include directory for the reference project. This is the -I flag in gcc. # This sets the include directory for the reference project. This is the -I flag in gcc.
include_directories(
${PROJECT_SOURCE_DIR}/incl
${LLVM_INCLUDE_DIRS}
)
add_dependent_subproject(dbt-core) add_dependent_subproject(dbt-core)
add_dependent_subproject(sc-components) add_dependent_subproject(sc-components)
@ -72,14 +28,11 @@ add_dependent_subproject(riscv)
add_dependent_subproject(riscv.sc) add_dependent_subproject(riscv.sc)
include_directories( include_directories(
${PROJECT_SOURCE_DIR}/incl
${PROJECT_SOURCE_DIR}/../riscv/incl
${PROJECT_SOURCE_DIR}/../external/elfio ${PROJECT_SOURCE_DIR}/../external/elfio
${PROJECT_SOURCE_DIR}/../external/libGIS ${PROJECT_SOURCE_DIR}/../external/libGIS
${Boost_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
) )
# Mac needed variables (adapt for your needs - http://www.cmake.org/Wiki/CMake_RPATH_handling#Mac_OS_X_and_the_RPATH) # Mac needed variables (adapt for your needs - http://www.cmake.org/Wiki/CMake_RPATH_handling#Mac_OS_X_and_the_RPATH)
set(CMAKE_MACOSX_RPATH ON) set(CMAKE_MACOSX_RPATH ON)
set(CMAKE_SKIP_BUILD_RPATH FALSE) set(CMAKE_SKIP_BUILD_RPATH FALSE)
@ -87,6 +40,9 @@ set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
## the following setting needs to be consistent with the library
#add_definitions(-DSC_DEFAULT_WRITER_POLICY=SC_MANY_WRITERS)
add_subdirectory(src) add_subdirectory(src)
# #

View File

@ -1,6 +1,7 @@
`include "gpio.rdl" `include "gpio.rdl"
`include "uart.rdl" `include "uart.rdl"
`include "spi.rdl" `include "spi.rdl"
`include "pwm.rdl"
`include "plic.rdl" `include "plic.rdl"
`include "aon.rdl" `include "aon.rdl"
`include "prci.rdl" `include "prci.rdl"
@ -15,10 +16,10 @@ addrmap e300_plat_t {
gpio_regs gpio0 @0x10012000; gpio_regs gpio0 @0x10012000;
uart_regs uart0 @0x10013000; uart_regs uart0 @0x10013000;
spi_regs qspi0 @0x10014000; spi_regs qspi0 @0x10014000;
//pwm_regs pwm0 @0x10015000; pwm_regs pwm0 @0x10015000;
uart_regs uart1 @0x10023000; uart_regs uart1 @0x10023000;
spi_regs qspi1 @0x10024000; spi_regs qspi1 @0x10024000;
//pwm_regs pwm1 @0x10025000; pwm_regs pwm1 @0x10025000;
spi_regs qspi2 @0x10034000; spi_regs qspi2 @0x10034000;
//pwm_regs pwm2 @0x10035000; pwm_regs pwm2 @0x10035000;
} e300_plat; } e300_plat;

View File

@ -0,0 +1,96 @@
regfile pwm_regs {
reg {
name="pwmcfg";
desc="pin value";
field {
name = "pwmscale";
} pwmscale[3:0];
field {
name = "pwmsticky";
} pwmsticky[8:8];
field {
name = "pwmzerocmp";
} pwmsticky[9:9];
field {
name = "pwmdeglitch";
} pwmsticky[10:10];
field {
name = "pwmenalways";
} pwmenalways[12:12];
field {
name = "pwmenoneshot";
} pwmenalways[13:13];
field {
name = "pwmcmp0center";
} pwmcmp0center[16:16];
field {
name = "pwmcmp1center";
} pwmcmp1center[17:17];
field {
name = "pwmcmp2center";
} pwmcmp2center[18:18];
field {
name = "pwmcmp3center";
} pwmcmp3center[19:19];
field {
name = "pwmcmp0gang";
} pwmcmp0gang[24:24];
field {
name = "pwmcmp1gang";
} pwmcmp1gang[25:25];
field {
name = "pwmcmp2gang";
} pwmcmp2gang[26:26];
field {
name = "pwmcmp3gang";
} pwmcmp3gang[27:27];
field {
name = "pwmcmp0ip";
} pwmcmp0ip[28:28];
field {
name = "pwmcmp1ip";
} pwmcmp1ip[29:29];
field {
name = "pwmcmp2ip";
} pwmcmp2ip[30:30];
field {
name = "pwmcmp3ip";
} pwmcmp3ip[31:31];
} pwmcfg @0x000;
reg {
name="pwmcount";
field {
name = "pwmcount";
} pwmcount[31:0];
} pwmcount @0x008;
reg {
name="pwms";
field {
name = "pwms";
}pwms[15:0];
} pwms @0x010;
reg {
name="pwmcmp0";
field {
name = "pwmcmp0";
} pwmcmp0[15:0];
} pwmcmp0 @0x020;
reg {
name="pwmcmp1";
field {
name = "pwmcmp0";
} pwmcmp0[15:0];
} pwmcmp1 @0x024;
reg {
name="pwmcmp2";
field {
name = "pwmcmp0";
} pwmcmp0[15:0];
} pwmcmp2 @0x028;
reg {
name="pwmcmp3";
field {
name = "pwmcmp0";
} pwmcmp0[15:0];
} pwmcmp3 @0x02C;
};

View File

@ -1,38 +1,34 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _AON_H_ #ifndef _AON_H_
#define _AON_H_ #define _AON_H_
@ -45,7 +41,7 @@ class aon_regs;
class aon : public sc_core::sc_module, public scc::tlm_target<> { class aon : public sc_core::sc_module, public scc::tlm_target<> {
public: public:
SC_HAS_PROCESS(aon); SC_HAS_PROCESS(aon);// NOLINT
sc_core::sc_in<sc_core::sc_time> clk_i; sc_core::sc_in<sc_core::sc_time> clk_i;
sc_core::sc_in<bool> erst_n_i; sc_core::sc_in<bool> erst_n_i;
sc_core::sc_out<sc_core::sc_time> lfclkc_o; sc_core::sc_out<sc_core::sc_time> lfclkc_o;

View File

@ -1,38 +1,34 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _CLINT_H_ #ifndef _CLINT_H_
#define _CLINT_H_ #define _CLINT_H_
@ -54,14 +50,14 @@ class core_complex;
class clint : public sc_core::sc_module, public scc::tlm_target<> { class clint : public sc_core::sc_module, public scc::tlm_target<> {
public: public:
SC_HAS_PROCESS(clint); SC_HAS_PROCESS(clint);// NOLINT
sc_core::sc_in<sc_core::sc_time> tlclk_i; sc_core::sc_in<sc_core::sc_time> tlclk_i;
sc_core::sc_in<sc_core::sc_time> lfclk_i; sc_core::sc_in<sc_core::sc_time> lfclk_i;
sc_core::sc_in<bool> rst_i; sc_core::sc_in<bool> rst_i;
sc_core::sc_out<bool> mtime_int_o; sc_core::sc_out<bool> mtime_int_o;
sc_core::sc_out<bool> msip_int_o; sc_core::sc_out<bool> msip_int_o;
clint(sc_core::sc_module_name nm); clint(sc_core::sc_module_name nm);
virtual ~clint() override; // need to keep it in source file because of fwd declaration of clint_regs virtual ~clint() override; // NOLINT // need to keep it in source file because of fwd declaration of clint_regs
protected: protected:
void clock_cb(); void clock_cb();

View File

@ -0,0 +1,106 @@
/*******************************************************************************
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef _PLATFORM_H_
#define _PLATFORM_H_
#include "aon.h"
#include "clint.h"
#include "gpio.h"
#include "plic.h"
#include "prci.h"
#include "pwm.h"
#include "spi.h"
#include "sysc/core_complex.h"
#include "uart.h"
#include "cci_configuration"
#include "scc/memory.h"
#include "scc/router.h"
#include "scc/utilities.h"
#include "tlm/tlm_signal_sockets.h"
#include <array>
#include <memory>
#include <sysc/kernel/sc_module.h>
namespace sysc {
class fe310 : public sc_core::sc_module {
public:
SC_HAS_PROCESS(fe310);// NOLINT
sc_core::sc_vector<tlm::tlm_signal_initiator_socket<sc_dt::sc_logic>> pins_o;
sc_core::sc_vector<tlm::tlm_signal_target_socket<sc_dt::sc_logic>> pins_i;
sc_core::sc_in<bool> erst_n;
fe310(sc_core::sc_module_name nm);
cci::cci_param<bool> use_rtl;
private:
std::unique_ptr<SiFive::core_complex> i_core_complex;
std::unique_ptr<scc::router<>> i_router;
std::unique_ptr<uart> i_uart0, i_uart1;
std::unique_ptr<spi> i_qspi0, i_qspi1, i_qspi2;
std::unique_ptr<pwm> i_pwm0, i_pwm1, i_pwm2;
std::unique_ptr<gpio> i_gpio0;
std::unique_ptr<plic> i_plic;
std::unique_ptr<aon> i_aon;
std::unique_ptr<prci> i_prci;
std::unique_ptr<clint> i_clint;
using mem_qspi_t = scc::memory<512_MB, 32>;
std::unique_ptr<mem_qspi_t> i_mem_qspi;
using mem_ram_t = scc::memory<128_kB, 32>;
std::unique_ptr<mem_ram_t> i_mem_ram;
sc_core::sc_signal<sc_core::sc_time, sc_core::SC_MANY_WRITERS> s_tlclk;
sc_core::sc_signal<sc_core::sc_time, sc_core::SC_MANY_WRITERS> s_lfclk;
sc_core::sc_signal<bool, sc_core::SC_MANY_WRITERS> s_rst, s_mtime_int, s_msie_int;
sc_core::sc_vector<sc_core::sc_signal<bool, sc_core::SC_MANY_WRITERS>> s_global_int, s_local_int;
sc_core::sc_signal<bool, sc_core::SC_MANY_WRITERS> s_core_int;
sc_core::sc_vector<scc::tlm_signal_bool_opt_in> s_dummy_sck_i;
sc_core::sc_vector<scc::tlm_signal_bool_opt_out> s_dummy_sck_o;
protected:
void gen_reset();
#include "gen/e300_plat_t.h"
};
} /* namespace sysc */
#endif /* _PLATFORM_H_ */

View File

@ -1,104 +1,98 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Created on: Fri Nov 10 18:01:53 CET 2017 *******************************************************************************/
// * aon_regs.h Author: <RDL Generator>
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _AON_REGS_H_ #ifndef _AON_REGS_H_
#define _AON_REGS_H_ #define _AON_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h>
#include <scc/register.h> #include <scc/register.h>
#include <scc/tlm_target.h> #include <scc/tlm_target.h>
#include <scc/utilities.h>
#include <util/bit_field.h>
namespace sysc { namespace sysc {
class aon_regs : class aon_regs : public sc_core::sc_module, public scc::resetable {
public sc_core::sc_module,
public scc::resetable
{
public: public:
// storage declarations // storage declarations
uint32_t r_wdogcfg; uint32_t r_wdogcfg;
uint32_t r_wdogcount; uint32_t r_wdogcount;
uint32_t r_wdogs; uint32_t r_wdogs;
uint32_t r_wdogfeed; uint32_t r_wdogfeed;
uint32_t r_wdogkey; uint32_t r_wdogkey;
uint32_t r_wdogcmp; uint32_t r_wdogcmp;
uint32_t r_rtccfg; uint32_t r_rtccfg;
uint32_t r_rtclo; uint32_t r_rtclo;
uint32_t r_rtchi; uint32_t r_rtchi;
uint32_t r_rtcs; uint32_t r_rtcs;
uint32_t r_rtccmp; uint32_t r_rtccmp;
uint32_t r_lfrosccfg; uint32_t r_lfrosccfg;
std::array<uint32_t, 32> r_backup; std::array<uint32_t, 32> r_backup;
BEGIN_BF_DECL(pmuwakeupi_t, uint32_t); BEGIN_BF_DECL(pmuwakeupi_t, uint32_t);
BF_FIELD(delay, 0, 4); BF_FIELD(delay, 0, 4);
BF_FIELD(vddpaden, 5, 1); BF_FIELD(vddpaden, 5, 1);
BF_FIELD(corerst, 7, 1); BF_FIELD(corerst, 7, 1);
BF_FIELD(hfclkrst, 8, 1); BF_FIELD(hfclkrst, 8, 1);
END_BF_DECL() ; END_BF_DECL();
std::array<pmuwakeupi_t, 8> r_pmuwakeupi; std::array<pmuwakeupi_t, 8> r_pmuwakeupi;
BEGIN_BF_DECL(pmusleepi_t, uint32_t); BEGIN_BF_DECL(pmusleepi_t, uint32_t);
BF_FIELD(delay, 0, 4); BF_FIELD(delay, 0, 4);
BF_FIELD(vddpaden, 5, 1); BF_FIELD(vddpaden, 5, 1);
BF_FIELD(corerst, 7, 1); BF_FIELD(corerst, 7, 1);
BF_FIELD(hfclkrst, 8, 1); BF_FIELD(hfclkrst, 8, 1);
END_BF_DECL() ; END_BF_DECL();
std::array<pmusleepi_t, 8> r_pmusleepi; std::array<pmusleepi_t, 8> r_pmusleepi;
uint32_t r_pmuie; uint32_t r_pmuie;
uint32_t r_pmucause; uint32_t r_pmucause;
uint32_t r_pmusleep; uint32_t r_pmusleep;
uint32_t r_pmukey; uint32_t r_pmukey;
// register declarations // register declarations
scc::sc_register<uint32_t> wdogcfg; scc::sc_register<uint32_t> wdogcfg;
scc::sc_register<uint32_t> wdogcount; scc::sc_register<uint32_t> wdogcount;
@ -119,11 +113,10 @@ public:
scc::sc_register<uint32_t> pmucause; scc::sc_register<uint32_t> pmucause;
scc::sc_register<uint32_t> pmusleep; scc::sc_register<uint32_t> pmusleep;
scc::sc_register<uint32_t> pmukey; scc::sc_register<uint32_t> pmukey;
aon_regs(sc_core::sc_module_name nm); aon_regs(sc_core::sc_module_name nm);
template<unsigned BUSWIDTH=32> template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target);
void registerResources(scc::tlm_target<BUSWIDTH>& target);
}; };
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -150,12 +143,9 @@ inline sysc::aon_regs::aon_regs(sc_core::sc_module_name nm)
, NAMED(pmuie, r_pmuie, 0, *this) , NAMED(pmuie, r_pmuie, 0, *this)
, NAMED(pmucause, r_pmucause, 0, *this) , NAMED(pmucause, r_pmucause, 0, *this)
, NAMED(pmusleep, r_pmusleep, 0, *this) , NAMED(pmusleep, r_pmusleep, 0, *this)
, NAMED(pmukey, r_pmukey, 0, *this) , NAMED(pmukey, r_pmukey, 0, *this) {}
{
}
template<unsigned BUSWIDTH> template <unsigned BUSWIDTH> inline void sysc::aon_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) {
inline void sysc::aon_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
target.addResource(wdogcfg, 0x0UL); target.addResource(wdogcfg, 0x0UL);
target.addResource(wdogcount, 0x8UL); target.addResource(wdogcount, 0x8UL);
target.addResource(wdogs, 0x10UL); target.addResource(wdogs, 0x10UL);

View File

@ -1,71 +1,64 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Created on: Fri Nov 10 18:01:53 CET 2017 *******************************************************************************/
// * clint_regs.h Author: <RDL Generator>
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _CLINT_REGS_H_ #ifndef _CLINT_REGS_H_
#define _CLINT_REGS_H_ #define _CLINT_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h>
#include <scc/register.h> #include <scc/register.h>
#include <scc/tlm_target.h> #include <scc/tlm_target.h>
#include <scc/utilities.h>
#include <util/bit_field.h>
namespace sysc { namespace sysc {
class clint_regs : class clint_regs : public sc_core::sc_module, public scc::resetable {
public sc_core::sc_module,
public scc::resetable
{
public: public:
// storage declarations // storage declarations
BEGIN_BF_DECL(msip_t, uint32_t); BEGIN_BF_DECL(msip_t, uint32_t);
BF_FIELD(msip, 0, 1); BF_FIELD(msip, 0, 1);
END_BF_DECL() r_msip; END_BF_DECL() r_msip;
uint64_t r_mtimecmp; uint64_t r_mtimecmp;
uint64_t r_mtime; uint64_t r_mtime;
// register declarations // register declarations
scc::sc_register<msip_t> msip; scc::sc_register<msip_t> msip;
scc::sc_register<uint64_t> mtimecmp; scc::sc_register<uint64_t> mtimecmp;
scc::sc_register<uint64_t> mtime; scc::sc_register<uint64_t> mtime;
clint_regs(sc_core::sc_module_name nm); clint_regs(sc_core::sc_module_name nm);
template<unsigned BUSWIDTH=32> template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target);
void registerResources(scc::tlm_target<BUSWIDTH>& target);
}; };
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -76,12 +69,9 @@ inline sysc::clint_regs::clint_regs(sc_core::sc_module_name nm)
: sc_core::sc_module(nm) : sc_core::sc_module(nm)
, NAMED(msip, r_msip, 0, *this) , NAMED(msip, r_msip, 0, *this)
, NAMED(mtimecmp, r_mtimecmp, 0, *this) , NAMED(mtimecmp, r_mtimecmp, 0, *this)
, NAMED(mtime, r_mtime, 0, *this) , NAMED(mtime, r_mtime, 0, *this) {}
{
}
template<unsigned BUSWIDTH> template <unsigned BUSWIDTH> inline void sysc::clint_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) {
inline void sysc::clint_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
target.addResource(msip, 0x0UL); target.addResource(msip, 0x0UL);
target.addResource(mtimecmp, 0x4000UL); target.addResource(mtimecmp, 0x4000UL);
target.addResource(mtime, 0xbff8UL); target.addResource(mtime, 0xbff8UL);

View File

@ -1,17 +1,21 @@
#ifndef _E300_PLAT_MAP_H_ #ifndef _E300_PLAT_T_MAP_H_
#define _E300_PLAT_MAP_H_ #define _E300_PLAT_T_MAP_H_
// need double braces, see https://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list#6894191 // need double braces, see
const std::array<scc::target_memory_map_entry<32>, 10> e300_plat_map = {{ // https://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list#6894191
{&i_clint, 0x2000000, 0xc000}, const std::array<scc::target_memory_map_entry<32>, 13> e300_plat_t_map = {{
{&i_plic, 0xc000000, 0x200008}, {i_clint->socket, 0x2000000, 0xc000},
{&i_aon, 0x10000000, 0x150}, {i_plic->socket, 0xc000000, 0x200008},
{&i_prci, 0x10008000, 0x14}, {i_aon->socket, 0x10000000, 0x150},
{&i_gpio0, 0x10012000, 0x44}, {i_prci->socket, 0x10008000, 0x14},
{&i_uart0, 0x10013000, 0x1c}, {i_gpio0->socket, 0x10012000, 0x44},
{&i_qspi0, 0x10014000, 0x78}, {i_uart0->socket, 0x10013000, 0x1c},
{&i_uart1, 0x10023000, 0x1c}, {i_qspi0->socket, 0x10014000, 0x78},
{&i_qspi1, 0x10024000, 0x78}, {i_pwm0->socket, 0x10015000, 0x30},
{&i_qspi2, 0x10034000, 0x78}, {i_uart1->socket, 0x10023000, 0x1c},
{i_qspi1->socket, 0x10024000, 0x78},
{i_pwm1->socket, 0x10025000, 0x30},
{i_qspi2->socket, 0x10034000, 0x78},
{i_pwm2->socket, 0x10035000, 0x30},
}}; }};
#endif /* _E300_PLAT_MAP_H_ */ #endif /* _E300_PLAT_T_MAP_H_ */

View File

@ -1,88 +1,82 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Created on: Fri Nov 10 18:01:53 CET 2017 *******************************************************************************/
// * gpio_regs.h Author: <RDL Generator>
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _GPIO_REGS_H_ #ifndef _GPIO_REGS_H_
#define _GPIO_REGS_H_ #define _GPIO_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h>
#include <scc/register.h> #include <scc/register.h>
#include <scc/tlm_target.h> #include <scc/tlm_target.h>
#include <scc/utilities.h>
#include <util/bit_field.h>
namespace sysc { namespace sysc {
class gpio_regs : class gpio_regs : public sc_core::sc_module, public scc::resetable {
public sc_core::sc_module,
public scc::resetable
{
public: public:
// storage declarations // storage declarations
uint32_t r_value; uint32_t r_value;
uint32_t r_input_en; uint32_t r_input_en;
uint32_t r_output_en; uint32_t r_output_en;
uint32_t r_port; uint32_t r_port;
uint32_t r_pue; uint32_t r_pue;
uint32_t r_ds; uint32_t r_ds;
uint32_t r_rise_ie; uint32_t r_rise_ie;
uint32_t r_rise_ip; uint32_t r_rise_ip;
uint32_t r_fall_ie; uint32_t r_fall_ie;
uint32_t r_fall_ip; uint32_t r_fall_ip;
uint32_t r_high_ie; uint32_t r_high_ie;
uint32_t r_high_ip; uint32_t r_high_ip;
uint32_t r_low_ie; uint32_t r_low_ie;
uint32_t r_low_ip; uint32_t r_low_ip;
uint32_t r_iof_en; uint32_t r_iof_en;
uint32_t r_iof_sel; uint32_t r_iof_sel;
uint32_t r_out_xor; uint32_t r_out_xor;
// register declarations // register declarations
scc::sc_register<uint32_t> value; scc::sc_register<uint32_t> value;
scc::sc_register<uint32_t> input_en; scc::sc_register<uint32_t> input_en;
@ -101,11 +95,11 @@ public:
scc::sc_register<uint32_t> iof_en; scc::sc_register<uint32_t> iof_en;
scc::sc_register<uint32_t> iof_sel; scc::sc_register<uint32_t> iof_sel;
scc::sc_register<uint32_t> out_xor; scc::sc_register<uint32_t> out_xor;
gpio_regs(sc_core::sc_module_name nm); gpio_regs(sc_core::sc_module_name nm);
template<unsigned BUSWIDTH=32> template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target);
void registerResources(scc::tlm_target<BUSWIDTH>& target); void trace(sc_core::sc_trace_file *tf) const override;
}; };
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -130,12 +124,9 @@ inline sysc::gpio_regs::gpio_regs(sc_core::sc_module_name nm)
, NAMED(low_ip, r_low_ip, 0, *this) , NAMED(low_ip, r_low_ip, 0, *this)
, NAMED(iof_en, r_iof_en, 0, *this) , NAMED(iof_en, r_iof_en, 0, *this)
, NAMED(iof_sel, r_iof_sel, 0, *this) , NAMED(iof_sel, r_iof_sel, 0, *this)
, NAMED(out_xor, r_out_xor, 0, *this) , NAMED(out_xor, r_out_xor, 0, *this) {}
{
}
template<unsigned BUSWIDTH> template <unsigned BUSWIDTH> inline void sysc::gpio_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) {
inline void sysc::gpio_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
target.addResource(value, 0x0UL); target.addResource(value, 0x0UL);
target.addResource(input_en, 0x4UL); target.addResource(input_en, 0x4UL);
target.addResource(output_en, 0x8UL); target.addResource(output_en, 0x8UL);
@ -155,4 +146,24 @@ inline void sysc::gpio_regs::registerResources(scc::tlm_target<BUSWIDTH>& target
target.addResource(out_xor, 0x40UL); target.addResource(out_xor, 0x40UL);
} }
inline void sysc::gpio_regs::trace(sc_core::sc_trace_file *tf) const {
value.trace(tf);
input_en.trace(tf);
output_en.trace(tf);
port.trace(tf);
pue.trace(tf);
ds.trace(tf);
rise_ie.trace(tf);
rise_ip.trace(tf);
fall_ie.trace(tf);
fall_ip.trace(tf);
high_ie.trace(tf);
high_ip.trace(tf);
low_ie.trace(tf);
low_ip.trace(tf);
iof_en.trace(tf);
iof_sel.trace(tf);
out_xor.trace(tf);
}
#endif // _GPIO_REGS_H_ #endif // _GPIO_REGS_H_

View File

@ -1,80 +1,73 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Created on: Fri Nov 10 18:01:53 CET 2017 *******************************************************************************/
// * plic_regs.h Author: <RDL Generator>
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _PLIC_REGS_H_ #ifndef _PLIC_REGS_H_
#define _PLIC_REGS_H_ #define _PLIC_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h>
#include <scc/register.h> #include <scc/register.h>
#include <scc/tlm_target.h> #include <scc/tlm_target.h>
#include <scc/utilities.h>
#include <util/bit_field.h>
namespace sysc { namespace sysc {
class plic_regs : class plic_regs : public sc_core::sc_module, public scc::resetable {
public sc_core::sc_module,
public scc::resetable
{
public: public:
// storage declarations // storage declarations
BEGIN_BF_DECL(priority_t, uint32_t); BEGIN_BF_DECL(priority_t, uint32_t);
BF_FIELD(priority, 0, 3); BF_FIELD(priority, 0, 3);
END_BF_DECL() ; END_BF_DECL();
std::array<priority_t, 256> r_priority; std::array<priority_t, 256> r_priority;
std::array<uint32_t, 8> r_pending; std::array<uint32_t, 8> r_pending;
std::array<uint32_t, 8> r_enabled; std::array<uint32_t, 8> r_enabled;
BEGIN_BF_DECL(threshold_t, uint32_t); BEGIN_BF_DECL(threshold_t, uint32_t);
BF_FIELD(threshold, 0, 3); BF_FIELD(threshold, 0, 3);
END_BF_DECL() r_threshold; END_BF_DECL() r_threshold;
uint32_t r_claim_complete; uint32_t r_claim_complete;
// register declarations // register declarations
scc::sc_register_indexed<priority_t, 256> priority; scc::sc_register_indexed<priority_t, 256> priority;
scc::sc_register_indexed<uint32_t, 8> pending; scc::sc_register_indexed<uint32_t, 8> pending;
scc::sc_register_indexed<uint32_t, 8> enabled; scc::sc_register_indexed<uint32_t, 8> enabled;
scc::sc_register<threshold_t> threshold; scc::sc_register<threshold_t> threshold;
scc::sc_register<uint32_t> claim_complete; scc::sc_register<uint32_t> claim_complete;
plic_regs(sc_core::sc_module_name nm); plic_regs(sc_core::sc_module_name nm);
template<unsigned BUSWIDTH=32> template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target);
void registerResources(scc::tlm_target<BUSWIDTH>& target);
}; };
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -87,12 +80,9 @@ inline sysc::plic_regs::plic_regs(sc_core::sc_module_name nm)
, NAMED(pending, r_pending, 0, *this) , NAMED(pending, r_pending, 0, *this)
, NAMED(enabled, r_enabled, 0, *this) , NAMED(enabled, r_enabled, 0, *this)
, NAMED(threshold, r_threshold, 0, *this) , NAMED(threshold, r_threshold, 0, *this)
, NAMED(claim_complete, r_claim_complete, 0, *this) , NAMED(claim_complete, r_claim_complete, 0, *this) {}
{
}
template<unsigned BUSWIDTH> template <unsigned BUSWIDTH> inline void sysc::plic_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) {
inline void sysc::plic_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
target.addResource(priority, 0x0UL); target.addResource(priority, 0x0UL);
target.addResource(pending, 0x1000UL); target.addResource(pending, 0x1000UL);
target.addResource(enabled, 0x2000UL); target.addResource(enabled, 0x2000UL);

View File

@ -1,91 +1,84 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Created on: Fri Nov 10 18:01:53 CET 2017 *******************************************************************************/
// * prci_regs.h Author: <RDL Generator>
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _PRCI_REGS_H_ #ifndef _PRCI_REGS_H_
#define _PRCI_REGS_H_ #define _PRCI_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h>
#include <scc/register.h> #include <scc/register.h>
#include <scc/tlm_target.h> #include <scc/tlm_target.h>
#include <scc/utilities.h>
#include <util/bit_field.h>
namespace sysc { namespace sysc {
class prci_regs : class prci_regs : public sc_core::sc_module, public scc::resetable {
public sc_core::sc_module,
public scc::resetable
{
public: public:
// storage declarations // storage declarations
BEGIN_BF_DECL(hfrosccfg_t, uint32_t); BEGIN_BF_DECL(hfrosccfg_t, uint32_t);
BF_FIELD(hfroscdiv, 0, 6); BF_FIELD(hfroscdiv, 0, 6);
BF_FIELD(hfrosctrim, 16, 5); BF_FIELD(hfrosctrim, 16, 5);
BF_FIELD(hfroscen, 30, 1); BF_FIELD(hfroscen, 30, 1);
BF_FIELD(hfroscrdy, 31, 1); BF_FIELD(hfroscrdy, 31, 1);
END_BF_DECL() r_hfrosccfg; END_BF_DECL() r_hfrosccfg;
BEGIN_BF_DECL(hfxosccfg_t, uint32_t); BEGIN_BF_DECL(hfxosccfg_t, uint32_t);
BF_FIELD(hfxoscrdy, 31, 1); BF_FIELD(hfxoscrdy, 31, 1);
BF_FIELD(hfxoscen, 30, 1); BF_FIELD(hfxoscen, 30, 1);
END_BF_DECL() r_hfxosccfg; END_BF_DECL() r_hfxosccfg;
BEGIN_BF_DECL(pllcfg_t, uint32_t); BEGIN_BF_DECL(pllcfg_t, uint32_t);
BF_FIELD(pllr, 0, 3); BF_FIELD(pllr, 0, 3);
BF_FIELD(pllf, 4, 6); BF_FIELD(pllf, 4, 6);
BF_FIELD(pllq, 10, 2); BF_FIELD(pllq, 10, 2);
BF_FIELD(pllsel, 16, 1); BF_FIELD(pllsel, 16, 1);
BF_FIELD(pllrefsel, 17, 1); BF_FIELD(pllrefsel, 17, 1);
BF_FIELD(pllbypass, 18, 1); BF_FIELD(pllbypass, 18, 1);
BF_FIELD(plllock, 31, 1); BF_FIELD(plllock, 31, 1);
END_BF_DECL() r_pllcfg; END_BF_DECL() r_pllcfg;
uint32_t r_plloutdiv; uint32_t r_plloutdiv;
uint32_t r_coreclkcfg; uint32_t r_coreclkcfg;
// register declarations // register declarations
scc::sc_register<hfrosccfg_t> hfrosccfg; scc::sc_register<hfrosccfg_t> hfrosccfg;
scc::sc_register<hfxosccfg_t> hfxosccfg; scc::sc_register<hfxosccfg_t> hfxosccfg;
scc::sc_register<pllcfg_t> pllcfg; scc::sc_register<pllcfg_t> pllcfg;
scc::sc_register<uint32_t> plloutdiv; scc::sc_register<uint32_t> plloutdiv;
scc::sc_register<uint32_t> coreclkcfg; scc::sc_register<uint32_t> coreclkcfg;
prci_regs(sc_core::sc_module_name nm); prci_regs(sc_core::sc_module_name nm);
template<unsigned BUSWIDTH=32> template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target);
void registerResources(scc::tlm_target<BUSWIDTH>& target);
}; };
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -98,12 +91,9 @@ inline sysc::prci_regs::prci_regs(sc_core::sc_module_name nm)
, NAMED(hfxosccfg, r_hfxosccfg, 0x40000000, *this) , NAMED(hfxosccfg, r_hfxosccfg, 0x40000000, *this)
, NAMED(pllcfg, r_pllcfg, 0, *this) , NAMED(pllcfg, r_pllcfg, 0, *this)
, NAMED(plloutdiv, r_plloutdiv, 0, *this) , NAMED(plloutdiv, r_plloutdiv, 0, *this)
, NAMED(coreclkcfg, r_coreclkcfg, 0, *this) , NAMED(coreclkcfg, r_coreclkcfg, 0, *this) {}
{
}
template<unsigned BUSWIDTH> template <unsigned BUSWIDTH> inline void sysc::prci_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) {
inline void sysc::prci_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
target.addResource(hfrosccfg, 0x0UL); target.addResource(hfrosccfg, 0x0UL);
target.addResource(hfxosccfg, 0x4UL); target.addResource(hfxosccfg, 0x4UL);
target.addResource(pllcfg, 0x8UL); target.addResource(pllcfg, 0x8UL);

View File

@ -0,0 +1,129 @@
/*******************************************************************************
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef _PWM_REGS_H_
#define _PWM_REGS_H_
#include <scc/register.h>
#include <scc/tlm_target.h>
#include <scc/utilities.h>
#include <util/bit_field.h>
namespace sysc {
class pwm_regs : public sc_core::sc_module, public scc::resetable {
public:
// storage declarations
BEGIN_BF_DECL(pwmcfg_t, uint32_t);
BF_FIELD(pwmscale, 0, 4);
BF_FIELD(pwmsticky, 8, 1);
BF_FIELD(pwmzerocmp, 9, 1);
BF_FIELD(pwmdeglitch, 10, 1);
BF_FIELD(pwmenalways, 12, 1);
BF_FIELD(pwmenoneshot, 13, 1);
BF_FIELD(pwmcmp0center, 16, 1);
BF_FIELD(pwmcmp1center, 17, 1);
BF_FIELD(pwmcmp2center, 18, 1);
BF_FIELD(pwmcmp3center, 19, 1);
BF_FIELD(pwmcmp0gang, 24, 1);
BF_FIELD(pwmcmp1gang, 25, 1);
BF_FIELD(pwmcmp2gang, 26, 1);
BF_FIELD(pwmcmp3gang, 27, 1);
BF_FIELD(pwmcmp0ip, 28, 1);
BF_FIELD(pwmcmp1ip, 29, 1);
BF_FIELD(pwmcmp2ip, 30, 1);
BF_FIELD(pwmcmp3ip, 31, 1);
END_BF_DECL() r_pwmcfg;
BEGIN_BF_DECL(pwmcount_t, uint32_t);
BF_FIELD(pwmcount, 0, 31);
END_BF_DECL() r_pwmcount;
BEGIN_BF_DECL(pwms_t, uint32_t);
BF_FIELD(pwms, 0, 16);
END_BF_DECL() r_pwms;
BEGIN_BF_DECL(pwmcmp0_t, uint32_t);
BF_FIELD(pwmcmp0, 0, 16);
END_BF_DECL() r_pwmcmp0;
BEGIN_BF_DECL(pwmcmp1_t, uint32_t);
BF_FIELD(pwmcmp0, 0, 16);
END_BF_DECL() r_pwmcmp1;
BEGIN_BF_DECL(pwmcmp2_t, uint32_t);
BF_FIELD(pwmcmp0, 0, 16);
END_BF_DECL() r_pwmcmp2;
BEGIN_BF_DECL(pwmcmp3_t, uint32_t);
BF_FIELD(pwmcmp0, 0, 16);
END_BF_DECL() r_pwmcmp3;
// register declarations
scc::sc_register<pwmcfg_t> pwmcfg;
scc::sc_register<pwmcount_t> pwmcount;
scc::sc_register<pwms_t> pwms;
scc::sc_register<pwmcmp0_t> pwmcmp0;
scc::sc_register<pwmcmp1_t> pwmcmp1;
scc::sc_register<pwmcmp2_t> pwmcmp2;
scc::sc_register<pwmcmp3_t> pwmcmp3;
pwm_regs(sc_core::sc_module_name nm);
template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target);
};
}
//////////////////////////////////////////////////////////////////////////////
// member functions
//////////////////////////////////////////////////////////////////////////////
inline sysc::pwm_regs::pwm_regs(sc_core::sc_module_name nm)
: sc_core::sc_module(nm)
, NAMED(pwmcfg, r_pwmcfg, 0, *this)
, NAMED(pwmcount, r_pwmcount, 0, *this)
, NAMED(pwms, r_pwms, 0, *this)
, NAMED(pwmcmp0, r_pwmcmp0, 0, *this)
, NAMED(pwmcmp1, r_pwmcmp1, 0, *this)
, NAMED(pwmcmp2, r_pwmcmp2, 0, *this)
, NAMED(pwmcmp3, r_pwmcmp3, 0, *this) {}
template <unsigned BUSWIDTH> inline void sysc::pwm_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) {
target.addResource(pwmcfg, 0x0UL);
target.addResource(pwmcount, 0x8UL);
target.addResource(pwms, 0x10UL);
target.addResource(pwmcmp0, 0x20UL);
target.addResource(pwmcmp1, 0x24UL);
target.addResource(pwmcmp2, 0x28UL);
target.addResource(pwmcmp3, 0x2cUL);
}
#endif // _PWM_REGS_H_

View File

@ -1,131 +1,125 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Created on: Fri Nov 10 18:01:53 CET 2017 *******************************************************************************/
// * spi_regs.h Author: <RDL Generator>
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _SPI_REGS_H_ #ifndef _SPI_REGS_H_
#define _SPI_REGS_H_ #define _SPI_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h>
#include <scc/register.h> #include <scc/register.h>
#include <scc/tlm_target.h> #include <scc/tlm_target.h>
#include <scc/utilities.h>
#include <util/bit_field.h>
namespace sysc { namespace sysc {
class spi_regs : class spi_regs : public sc_core::sc_module, public scc::resetable {
public sc_core::sc_module,
public scc::resetable
{
public: public:
// storage declarations // storage declarations
BEGIN_BF_DECL(sckdiv_t, uint32_t); BEGIN_BF_DECL(sckdiv_t, uint32_t);
BF_FIELD(div, 0, 12); BF_FIELD(div, 0, 12);
END_BF_DECL() r_sckdiv; END_BF_DECL() r_sckdiv;
BEGIN_BF_DECL(sckmode_t, uint32_t); BEGIN_BF_DECL(sckmode_t, uint32_t);
BF_FIELD(pha, 0, 1); BF_FIELD(pha, 0, 1);
BF_FIELD(pol, 1, 1); BF_FIELD(pol, 1, 1);
END_BF_DECL() r_sckmode; END_BF_DECL() r_sckmode;
uint32_t r_csid; uint32_t r_csid;
uint32_t r_csdef; uint32_t r_csdef;
BEGIN_BF_DECL(csmode_t, uint32_t); BEGIN_BF_DECL(csmode_t, uint32_t);
BF_FIELD(mode, 0, 2); BF_FIELD(mode, 0, 2);
END_BF_DECL() r_csmode; END_BF_DECL() r_csmode;
BEGIN_BF_DECL(delay0_t, uint32_t); BEGIN_BF_DECL(delay0_t, uint32_t);
BF_FIELD(cssck, 0, 8); BF_FIELD(cssck, 0, 8);
BF_FIELD(sckcs, 16, 8); BF_FIELD(sckcs, 16, 8);
END_BF_DECL() r_delay0; END_BF_DECL() r_delay0;
BEGIN_BF_DECL(delay1_t, uint32_t); BEGIN_BF_DECL(delay1_t, uint32_t);
BF_FIELD(intercs, 0, 16); BF_FIELD(intercs, 0, 16);
BF_FIELD(interxfr, 16, 8); BF_FIELD(interxfr, 16, 8);
END_BF_DECL() r_delay1; END_BF_DECL() r_delay1;
BEGIN_BF_DECL(fmt_t, uint32_t); BEGIN_BF_DECL(fmt_t, uint32_t);
BF_FIELD(proto, 0, 2); BF_FIELD(proto, 0, 2);
BF_FIELD(endian, 2, 1); BF_FIELD(endian, 2, 1);
BF_FIELD(dir, 3, 1); BF_FIELD(dir, 3, 1);
BF_FIELD(len, 16, 4); BF_FIELD(len, 16, 4);
END_BF_DECL() r_fmt; END_BF_DECL() r_fmt;
BEGIN_BF_DECL(txdata_t, uint32_t); BEGIN_BF_DECL(txdata_t, uint32_t);
BF_FIELD(data, 0, 8); BF_FIELD(data, 0, 8);
BF_FIELD(full, 31, 1); BF_FIELD(full, 31, 1);
END_BF_DECL() r_txdata; END_BF_DECL() r_txdata;
BEGIN_BF_DECL(rxdata_t, uint32_t); BEGIN_BF_DECL(rxdata_t, uint32_t);
BF_FIELD(data, 0, 8); BF_FIELD(data, 0, 8);
BF_FIELD(empty, 31, 1); BF_FIELD(empty, 31, 1);
END_BF_DECL() r_rxdata; END_BF_DECL() r_rxdata;
BEGIN_BF_DECL(txmark_t, uint32_t); BEGIN_BF_DECL(txmark_t, uint32_t);
BF_FIELD(txmark, 0, 3); BF_FIELD(txmark, 0, 3);
END_BF_DECL() r_txmark; END_BF_DECL() r_txmark;
BEGIN_BF_DECL(rxmark_t, uint32_t); BEGIN_BF_DECL(rxmark_t, uint32_t);
BF_FIELD(rxmark, 0, 3); BF_FIELD(rxmark, 0, 3);
END_BF_DECL() r_rxmark; END_BF_DECL() r_rxmark;
BEGIN_BF_DECL(fctrl_t, uint32_t); BEGIN_BF_DECL(fctrl_t, uint32_t);
BF_FIELD(en, 0, 1); BF_FIELD(en, 0, 1);
END_BF_DECL() r_fctrl; END_BF_DECL() r_fctrl;
BEGIN_BF_DECL(ffmt_t, uint32_t); BEGIN_BF_DECL(ffmt_t, uint32_t);
BF_FIELD(cmd_en, 0, 1); BF_FIELD(cmd_en, 0, 1);
BF_FIELD(addr_len, 1, 2); BF_FIELD(addr_len, 1, 2);
BF_FIELD(pad_cnt, 3, 4); BF_FIELD(pad_cnt, 3, 4);
BF_FIELD(cmd_proto, 7, 2); BF_FIELD(cmd_proto, 7, 2);
BF_FIELD(addr_proto, 9, 2); BF_FIELD(addr_proto, 9, 2);
BF_FIELD(data_proto, 11, 2); BF_FIELD(data_proto, 11, 2);
BF_FIELD(cmd_code, 16, 8); BF_FIELD(cmd_code, 16, 8);
BF_FIELD(pad_code, 24, 8); BF_FIELD(pad_code, 24, 8);
END_BF_DECL() r_ffmt; END_BF_DECL() r_ffmt;
BEGIN_BF_DECL(ie_t, uint32_t); BEGIN_BF_DECL(ie_t, uint32_t);
BF_FIELD(txwm, 0, 1); BF_FIELD(txwm, 0, 1);
BF_FIELD(rxwm, 1, 1); BF_FIELD(rxwm, 1, 1);
END_BF_DECL() r_ie; END_BF_DECL() r_ie;
BEGIN_BF_DECL(ip_t, uint32_t); BEGIN_BF_DECL(ip_t, uint32_t);
BF_FIELD(txwm, 0, 1); BF_FIELD(txwm, 0, 1);
BF_FIELD(rxwm, 1, 1); BF_FIELD(rxwm, 1, 1);
END_BF_DECL() r_ip; END_BF_DECL() r_ip;
// register declarations // register declarations
scc::sc_register<sckdiv_t> sckdiv; scc::sc_register<sckdiv_t> sckdiv;
scc::sc_register<sckmode_t> sckmode; scc::sc_register<sckmode_t> sckmode;
@ -143,11 +137,10 @@ public:
scc::sc_register<ffmt_t> ffmt; scc::sc_register<ffmt_t> ffmt;
scc::sc_register<ie_t> ie; scc::sc_register<ie_t> ie;
scc::sc_register<ip_t> ip; scc::sc_register<ip_t> ip;
spi_regs(sc_core::sc_module_name nm); spi_regs(sc_core::sc_module_name nm);
template<unsigned BUSWIDTH=32> template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target);
void registerResources(scc::tlm_target<BUSWIDTH>& target);
}; };
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -171,12 +164,9 @@ inline sysc::spi_regs::spi_regs(sc_core::sc_module_name nm)
, NAMED(fctrl, r_fctrl, 0, *this) , NAMED(fctrl, r_fctrl, 0, *this)
, NAMED(ffmt, r_ffmt, 0, *this) , NAMED(ffmt, r_ffmt, 0, *this)
, NAMED(ie, r_ie, 0, *this) , NAMED(ie, r_ie, 0, *this)
, NAMED(ip, r_ip, 0, *this) , NAMED(ip, r_ip, 0, *this) {}
{
}
template<unsigned BUSWIDTH> template <unsigned BUSWIDTH> inline void sysc::spi_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) {
inline void sysc::spi_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
target.addResource(sckdiv, 0x0UL); target.addResource(sckdiv, 0x0UL);
target.addResource(sckmode, 0x4UL); target.addResource(sckmode, 0x4UL);
target.addResource(csid, 0x10UL); target.addResource(csid, 0x10UL);

View File

@ -1,89 +1,83 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Created on: Fri Nov 10 18:01:53 CET 2017 *******************************************************************************/
// * uart_regs.h Author: <RDL Generator>
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _UART_REGS_H_ #ifndef _UART_REGS_H_
#define _UART_REGS_H_ #define _UART_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h>
#include <scc/register.h> #include <scc/register.h>
#include <scc/tlm_target.h> #include <scc/tlm_target.h>
#include <scc/utilities.h>
#include <util/bit_field.h>
namespace sysc { namespace sysc {
class uart_regs : class uart_regs : public sc_core::sc_module, public scc::resetable {
public sc_core::sc_module,
public scc::resetable
{
public: public:
// storage declarations // storage declarations
BEGIN_BF_DECL(txdata_t, uint32_t); BEGIN_BF_DECL(txdata_t, uint32_t);
BF_FIELD(data, 0, 8); BF_FIELD(data, 0, 8);
BF_FIELD(full, 31, 1); BF_FIELD(full, 31, 1);
END_BF_DECL() r_txdata; END_BF_DECL() r_txdata;
BEGIN_BF_DECL(rxdata_t, uint32_t); BEGIN_BF_DECL(rxdata_t, uint32_t);
BF_FIELD(data, 0, 8); BF_FIELD(data, 0, 8);
BF_FIELD(empty, 31, 1); BF_FIELD(empty, 31, 1);
END_BF_DECL() r_rxdata; END_BF_DECL() r_rxdata;
BEGIN_BF_DECL(txctrl_t, uint32_t); BEGIN_BF_DECL(txctrl_t, uint32_t);
BF_FIELD(txen, 0, 1); BF_FIELD(txen, 0, 1);
BF_FIELD(nstop, 1, 1); BF_FIELD(nstop, 1, 1);
BF_FIELD(txcnt, 16, 3); BF_FIELD(txcnt, 16, 3);
END_BF_DECL() r_txctrl; END_BF_DECL() r_txctrl;
BEGIN_BF_DECL(rxctrl_t, uint32_t); BEGIN_BF_DECL(rxctrl_t, uint32_t);
BF_FIELD(rxen, 0, 1); BF_FIELD(rxen, 0, 1);
BF_FIELD(rxcnt, 16, 3); BF_FIELD(rxcnt, 16, 3);
END_BF_DECL() r_rxctrl; END_BF_DECL() r_rxctrl;
BEGIN_BF_DECL(ie_t, uint32_t); BEGIN_BF_DECL(ie_t, uint32_t);
BF_FIELD(txwm, 0, 1); BF_FIELD(txwm, 0, 1);
BF_FIELD(rxwm, 1, 1); BF_FIELD(rxwm, 1, 1);
END_BF_DECL() r_ie; END_BF_DECL() r_ie;
BEGIN_BF_DECL(ip_t, uint32_t); BEGIN_BF_DECL(ip_t, uint32_t);
BF_FIELD(txwm, 0, 1); BF_FIELD(txwm, 0, 1);
BF_FIELD(rxwm, 1, 1); BF_FIELD(rxwm, 1, 1);
END_BF_DECL() r_ip; END_BF_DECL() r_ip;
BEGIN_BF_DECL(div_t, uint32_t); BEGIN_BF_DECL(div_t, uint32_t);
BF_FIELD(div, 0, 16); BF_FIELD(div, 0, 16);
END_BF_DECL() r_div; END_BF_DECL() r_div;
// register declarations // register declarations
scc::sc_register<txdata_t> txdata; scc::sc_register<txdata_t> txdata;
scc::sc_register<rxdata_t> rxdata; scc::sc_register<rxdata_t> rxdata;
@ -92,11 +86,10 @@ public:
scc::sc_register<ie_t> ie; scc::sc_register<ie_t> ie;
scc::sc_register<ip_t> ip; scc::sc_register<ip_t> ip;
scc::sc_register<div_t> div; scc::sc_register<div_t> div;
uart_regs(sc_core::sc_module_name nm); uart_regs(sc_core::sc_module_name nm);
template<unsigned BUSWIDTH=32> template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target);
void registerResources(scc::tlm_target<BUSWIDTH>& target);
}; };
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -111,12 +104,9 @@ inline sysc::uart_regs::uart_regs(sc_core::sc_module_name nm)
, NAMED(rxctrl, r_rxctrl, 0, *this) , NAMED(rxctrl, r_rxctrl, 0, *this)
, NAMED(ie, r_ie, 0, *this) , NAMED(ie, r_ie, 0, *this)
, NAMED(ip, r_ip, 0, *this) , NAMED(ip, r_ip, 0, *this)
, NAMED(div, r_div, 0, *this) , NAMED(div, r_div, 0, *this) {}
{
}
template<unsigned BUSWIDTH> template <unsigned BUSWIDTH> inline void sysc::uart_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) {
inline void sysc::uart_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
target.addResource(txdata, 0x0UL); target.addResource(txdata, 0x0UL);
target.addResource(rxdata, 0x4UL); target.addResource(rxdata, 0x4UL);
target.addResource(txctrl, 0x8UL); target.addResource(txctrl, 0x8UL);

View File

@ -1,47 +1,44 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _GPIO_H_ #ifndef _GPIO_H_
#define _GPIO_H_ #define _GPIO_H_
#include "scc/tlm_target.h"
#include "scc/signal_target_mixin.h"
#include "scc/signal_initiator_mixin.h"
#include <tlm/tlm_signal.h>
#include "cci_configuration" #include "cci_configuration"
#include "scc/signal_initiator_mixin.h"
#include "scc/signal_target_mixin.h"
#include "scc/tlm_target.h"
#include <memory>
#include <tlm/tlm_signal.h>
namespace sysc { namespace sysc {
@ -50,18 +47,18 @@ class WsHandler;
class gpio : public sc_core::sc_module, public scc::tlm_target<> { class gpio : public sc_core::sc_module, public scc::tlm_target<> {
public: public:
SC_HAS_PROCESS(gpio); SC_HAS_PROCESS(gpio);// NOLINT
sc_core::sc_in<sc_core::sc_time> clk_i; sc_core::sc_in<sc_core::sc_time> clk_i;
sc_core::sc_in<bool> rst_i; sc_core::sc_in<bool> rst_i;
// sc_core::sc_inout_rv<32> pins_io; // sc_core::sc_inout_rv<32> pins_io;
sc_core::sc_vector<scc::tlm_signal_logic_out> pins_o; sc_core::sc_vector<scc::tlm_signal_logic_out> pins_o;
sc_core::sc_vector<scc::tlm_signal_logic_in> pins_i; sc_core::sc_vector<scc::tlm_signal_logic_in> pins_i;
sc_core::sc_vector<scc::tlm_signal_bool_opt_out> iof0_o; sc_core::sc_vector<scc::tlm_signal_bool_opt_out> iof0_o;
sc_core::sc_vector<scc::tlm_signal_bool_opt_out> iof1_o; sc_core::sc_vector<scc::tlm_signal_bool_opt_out> iof1_o;
sc_core::sc_vector<scc::tlm_signal_bool_opt_in> iof0_i; sc_core::sc_vector<scc::tlm_signal_bool_opt_in> iof0_i;
sc_core::sc_vector<scc::tlm_signal_bool_opt_in> iof1_i; sc_core::sc_vector<scc::tlm_signal_bool_opt_in> iof1_i;
gpio(sc_core::sc_module_name nm); gpio(sc_core::sc_module_name nm);
virtual ~gpio() override; // need to keep it in source file because of fwd declaration of gpio_regs virtual ~gpio() override; // need to keep it in source file because of fwd declaration of gpio_regs
@ -71,19 +68,18 @@ public:
protected: protected:
void clock_cb(); void clock_cb();
void reset_cb(); void reset_cb();
void update_pins(); void update_pins(uint32_t changed_bits);
void before_end_of_elaboration(); void before_end_of_elaboration();
void pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_logic>& gp, sc_core::sc_time& delay); void pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_dt::sc_logic> &gp, sc_core::sc_time &delay);
void forward_pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_logic>& gp); void forward_pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_dt::sc_logic> &gp);
void iof_input(unsigned int tag, unsigned iof_idx, tlm::tlm_signal_gp<>& gp, sc_core::sc_time& delay); void iof_input(unsigned int tag, unsigned iof_idx, tlm::tlm_signal_gp<> &gp, sc_core::sc_time &delay);
sc_core::sc_time clk; sc_core::sc_time clk;
std::array<bool, 32> last_iof0, last_iof1; std::array<bool, 32> last_iof0, last_iof1;
std::unique_ptr<gpio_regs> regs; std::unique_ptr<gpio_regs> regs;
std::shared_ptr<sysc::WsHandler> handler; std::shared_ptr<sysc::WsHandler> handler;
private: private:
tlm::tlm_phase write_output(tlm::tlm_signal_gp<sc_dt::sc_logic>& gp, size_t i, sc_dt::sc_logic val); tlm::tlm_phase write_output(tlm::tlm_signal_gp<sc_dt::sc_logic> &gp, size_t i, sc_dt::sc_logic val);
void enable_outputs(uint32_t new_iof_en, uint32_t new_iof_sel);
}; };
} /* namespace sysc */ } /* namespace sysc */

View File

@ -1,101 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2017, MINRES Technologies GmbH
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Contributors:
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _PLATFORM_H_
#define _PLATFORM_H_
#include "aon.h"
#include "clint.h"
#include "gpio.h"
#include "plic.h"
#include "prci.h"
#include "spi.h"
#include "uart.h"
#include "sysc/core_complex.h"
#include "scc/memory.h"
#include "scc/router.h"
#include "scc/utilities.h"
#include "tlm/tlm_signal_sockets.h"
#include <sysc/kernel/sc_module.h>
#include <array>
namespace sysc {
class hifive1 : public sc_core::sc_module {
public:
SC_HAS_PROCESS(hifive1);
sc_core::sc_vector<tlm::tlm_signal_initiator_socket<sc_dt::sc_logic>> pins_o;
sc_core::sc_vector<tlm::tlm_signal_target_socket<sc_dt::sc_logic>> pins_i;
sc_core::sc_in<bool> erst_n;
hifive1(sc_core::sc_module_name nm);
private:
SiFive::core_complex i_core_complex;
scc::router<> i_router;
uart i_uart0, i_uart1;
spi i_qspi0, i_qspi1, i_qspi2;
gpio i_gpio0;
plic i_plic;
aon i_aon;
prci i_prci;
clint i_clint;
scc::memory<512_MB, 32> i_mem_qspi;
scc::memory<128_kB, 32> i_mem_ram;
sc_core::sc_signal<sc_core::sc_time> s_tlclk;
sc_core::sc_signal<sc_core::sc_time> s_lfclk;
sc_core::sc_signal<bool> s_rst, s_mtime_int, s_msie_int;
sc_core::sc_vector<sc_core::sc_signal<bool, SC_MANY_WRITERS>> s_global_int, s_local_int;
sc_core::sc_signal<bool> s_core_int;
sc_core::sc_vector<sc_core::sc_signal<bool>> s_dummy;
sc_core::sc_vector<scc::tlm_signal_bool_opt_in> s_dummy_sck_i;
sc_core::sc_vector<scc::tlm_signal_bool_opt_out> s_dummy_sck_o;
protected:
void gen_reset();
#include "gen/e300_plat_t.h"
};
} /* namespace sysc */
#endif /* _PLATFORM_H_ */

View File

@ -1,38 +1,34 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _PLIC_H_ #ifndef _PLIC_H_
#define _PLIC_H_ #define _PLIC_H_
@ -46,7 +42,7 @@ class plic_regs;
class plic : public sc_core::sc_module, public scc::tlm_target<> { class plic : public sc_core::sc_module, public scc::tlm_target<> {
public: public:
SC_HAS_PROCESS(plic); SC_HAS_PROCESS(plic);// NOLINT
sc_core::sc_in<sc_core::sc_time> clk_i; sc_core::sc_in<sc_core::sc_time> clk_i;
sc_core::sc_in<bool> rst_i; sc_core::sc_in<bool> rst_i;
sc_core::sc_vector<sc_core::sc_in<bool>> global_interrupts_i; sc_core::sc_vector<sc_core::sc_in<bool>> global_interrupts_i;
@ -59,7 +55,6 @@ public:
protected: protected:
void clock_cb(); void clock_cb();
void reset_cb(); void reset_cb();
void init_callbacks();
void global_int_port_cb(); void global_int_port_cb();
void handle_pending_int(); void handle_pending_int();

View File

@ -1,38 +1,34 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _PRCI_H_ #ifndef _PRCI_H_
#define _PRCI_H_ #define _PRCI_H_
@ -45,8 +41,8 @@ class prci_regs;
class prci : public sc_core::sc_module, public scc::tlm_target<> { class prci : public sc_core::sc_module, public scc::tlm_target<> {
public: public:
SC_HAS_PROCESS(prci); SC_HAS_PROCESS(prci);// NOLINT
sc_core::sc_port<sc_core::sc_signal_in_if<sc_core::sc_time>,1,SC_ZERO_OR_MORE_BOUND> hfxosc_i; sc_core::sc_port<sc_core::sc_signal_in_if<sc_core::sc_time>, 1, sc_core::SC_ZERO_OR_MORE_BOUND> hfxosc_i;
sc_core::sc_in<bool> rst_i; sc_core::sc_in<bool> rst_i;
sc_core::sc_out<sc_core::sc_time> hfclk_o; sc_core::sc_out<sc_core::sc_time> hfclk_o;
prci(sc_core::sc_module_name nm); prci(sc_core::sc_module_name nm);

View File

@ -0,0 +1,79 @@
/*******************************************************************************
* Copyright (C) 2017,2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef _PWM_H_
#define _PWM_H_
#include "cci_configuration"
#include "scc/signal_initiator_mixin.h"
#include "scc/signal_target_mixin.h"
#include "scc/tlm_target.h"
#include <tlm/tlm_signal.h>
namespace sysc {
class pwm_regs;
class pwm : public sc_core::sc_module, public scc::tlm_target<> {
public:
SC_HAS_PROCESS(pwm);// NOLINT
sc_core::sc_in<sc_core::sc_time> clk_i;
sc_core::sc_in<bool> rst_i;
sc_core::sc_vector<scc::tlm_signal_bool_opt_out> cmpgpio_o;
sc_core::sc_vector<sc_core::sc_out<bool>> cmpip_o;
pwm(sc_core::sc_module_name nm);
virtual ~pwm() override; // need to keep it in source file because of fwd declaration of gpio_regs
protected:
sc_core::sc_time clk, last_clk;
void clock_cb();
void reset_cb();
inline double get_pulses(sc_core::sc_time d) {
auto t = sc_core::sc_time_stamp() + d;
return last_clk > sc_core::SC_ZERO_TIME ? (t - last_cnt_update) / last_clk : 0.;
}
void update_counter();
void write_cmpgpio(size_t, bool);
std::unique_ptr<pwm_regs> regs;
uint64_t current_cnt;
sc_core::sc_time last_cnt_update;
double clk_remainder = 0.0;
bool last_enable = false, reset_cnt = false;
sc_core::sc_event update_counter_evt;
std::array<bool, 4> pwmcmp_ip;
};
} /* namespace sysc */
#endif /* _GPIO_H_ */

View File

@ -1,79 +1,86 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _SPI_H_ #ifndef _SPI_H_
#define _SPI_H_ #define _SPI_H_
#include "scc/tlm_target.h"
#include "scc/signal_target_mixin.h"
#include "scc/signal_initiator_mixin.h"
#include <tlm/tlm_signal.h>
#include "cci_configuration"
#include <sysc/utils/sc_vector.h> #include <sysc/utils/sc_vector.h>
#include <tlm/tlm_signal.h>
namespace sysc { namespace sysc {
class spi_regs; namespace spi_impl {
class beh;
class rtl;
}
class spi : public sc_core::sc_module, public scc::tlm_target<> { class spi : public sc_core::sc_module {
public: public:
SC_HAS_PROCESS(spi); template <typename TYPE>
static std::unique_ptr<spi> create(sc_core::sc_module_name nm);
template <typename T> using tlm_in = tlm::tlm_signal_opt_target_socket<T>;
template <typename T> using tlm_out = tlm::tlm_signal_opt_initiator_socket<T>;
tlm::tlm_target_socket<> socket;
sc_core::sc_in<sc_core::sc_time> clk_i; sc_core::sc_in<sc_core::sc_time> clk_i;
sc_core::sc_in<bool> rst_i; sc_core::sc_in<bool> rst_i;
scc::tlm_signal_bool_opt_out sck_o; tlm_out<bool> sck_o;
scc::tlm_signal_bool_opt_out mosi_o; tlm_out<bool> mosi_o;
scc::tlm_signal_bool_opt_in miso_i; tlm_in<bool> miso_i;
sc_core::sc_vector<scc::tlm_signal_bool_opt_out> scs_o; sc_core::sc_vector<tlm_out<bool>> scs_o;
sc_core::sc_out<bool> irq_o; sc_core::sc_out<bool> irq_o;
cci::cci_param<bool> bit_true_transfer; spi(spi &other) = delete;
spi(sc_core::sc_module_name nm); spi(spi &&other) = delete;
virtual ~spi() override;
spi &operator=(spi &other) = delete;
spi &operator=(spi &&other) = delete;
~spi() override = default;
protected: protected:
void clock_cb(); spi(sc_core::sc_module_name nm)
void reset_cb(); : sc_core::sc_module(nm)
void transmit_data(); , NAMED(clk_i)
void receive_data(tlm::tlm_signal_gp<>& gp, sc_core::sc_time& delay); , NAMED(rst_i)
void update_irq(); , NAMED(sck_o)
sc_core::sc_time clk; , NAMED(mosi_o)
std::unique_ptr<spi_regs> regs; , NAMED(miso_i)
sc_core::sc_fifo<uint8_t> rx_fifo, tx_fifo; , NAMED(scs_o, 4)
, NAMED(irq_o){};
}; };
} /* namespace sysc */ } /* namespace sysc */

View File

@ -1,47 +1,43 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _UART_H_ #ifndef _UART_H_
#define _UART_H_ #define _UART_H_
#include "scc/tlm_target.h"
#include "scc/signal_target_mixin.h"
#include "scc/signal_initiator_mixin.h"
#include <tlm/tlm_signal.h>
#include "cci_configuration" #include "cci_configuration"
#include "scc/signal_initiator_mixin.h"
#include "scc/signal_target_mixin.h"
#include "scc/tlm_target.h"
#include <tlm/tlm_signal.h>
namespace sysc { namespace sysc {
class tlm_signal_uart_extension; class tlm_signal_uart_extension;
@ -50,11 +46,11 @@ class WsHandler;
class uart : public sc_core::sc_module, public scc::tlm_target<> { class uart : public sc_core::sc_module, public scc::tlm_target<> {
public: public:
SC_HAS_PROCESS(uart); SC_HAS_PROCESS(uart);// NOLINT
sc_core::sc_in<sc_core::sc_time> clk_i; sc_core::sc_in<sc_core::sc_time> clk_i;
sc_core::sc_in<bool> rst_i; sc_core::sc_in<bool> rst_i;
scc::tlm_signal_bool_out tx_o; scc::tlm_signal_bool_out tx_o;
scc::tlm_signal_bool_in rx_i; scc::tlm_signal_bool_in rx_i;
sc_core::sc_out<bool> irq_o; sc_core::sc_out<bool> irq_o;
@ -67,9 +63,9 @@ protected:
void clock_cb(); void clock_cb();
void reset_cb(); void reset_cb();
void transmit_data(); void transmit_data();
void receive_data(tlm::tlm_signal_gp<>& gp, sc_core::sc_time& delay); void receive_data(tlm::tlm_signal_gp<> &gp, sc_core::sc_time &delay);
void update_irq(); void update_irq();
sc_core::sc_time clk{SC_ZERO_TIME},rx_last_start{SC_ZERO_TIME}; sc_core::sc_time clk{sc_core::SC_ZERO_TIME}, rx_last_start{sc_core::SC_ZERO_TIME};
std::unique_ptr<uart_regs> regs; std::unique_ptr<uart_regs> regs;
sc_core::sc_fifo<uint8_t> rx_fifo, tx_fifo; sc_core::sc_fifo<uint8_t> rx_fifo, tx_fifo;
}; };

View File

@ -1,111 +1,112 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _SYSC_SC_COMM_SINGLETON_H_ #ifndef _SYSC_SC_COMM_SINGLETON_H_
#define _SYSC_SC_COMM_SINGLETON_H_ #define _SYSC_SC_COMM_SINGLETON_H_
#include <sysc/kernel/sc_module.h>
#include <seasocks/PageHandler.h>
#include "seasocks/WebSocket.h" #include "seasocks/WebSocket.h"
#include <seasocks/PageHandler.h>
#include <sysc/kernel/sc_module.h>
#include <memory>
#include <thread>
#include <cstring> #include <cstring>
#include <functional> #include <functional>
#include <memory>
#include <thread>
namespace sysc { namespace sysc {
class WsHandler: public seasocks::WebSocket::Handler { class WsHandler : public seasocks::WebSocket::Handler {
public: public:
explicit WsHandler() { } explicit WsHandler() {}
void onConnect(seasocks::WebSocket* connection) override; void onConnect(seasocks::WebSocket *connection) override;
void onData(seasocks::WebSocket* connection, const char* data) override; void onData(seasocks::WebSocket *connection, const char *data) override;
void onDisconnect(seasocks::WebSocket* connection) override; void onDisconnect(seasocks::WebSocket *connection) override;
void send(std::string msg) { for (auto *con : _connections) con->send(msg); } void send(std::string msg) {
for (auto *con : _connections) con->send(msg);
}
void set_receive_callback(std::function<void(const char* data)> cb){callback=cb;} void set_receive_callback(std::function<void(const char *data)> cb) { callback = cb; }
private: private:
std::set<seasocks::WebSocket*> _connections; std::set<seasocks::WebSocket *> _connections;
std::function<void(const char* data)> callback; std::function<void(const char *data)> callback;
}; };
class sc_comm_singleton: public sc_core::sc_module { class sc_comm_singleton : public sc_core::sc_module {
struct DefaultPageHandler: public seasocks::PageHandler { struct DefaultPageHandler : public seasocks::PageHandler {
DefaultPageHandler(sc_comm_singleton& o):owner(o){} DefaultPageHandler(sc_comm_singleton &o)
virtual std::shared_ptr<seasocks::Response> handle(const seasocks::Request& request); : owner(o) {}
sc_comm_singleton& owner; virtual std::shared_ptr<seasocks::Response> handle(const seasocks::Request &request);
}; sc_comm_singleton &owner;
};
public: public:
sc_comm_singleton() = delete; sc_comm_singleton() = delete;
sc_comm_singleton(const sc_comm_singleton&) = delete; sc_comm_singleton(const sc_comm_singleton &) = delete;
sc_comm_singleton& operator=(sc_comm_singleton& o) = delete; sc_comm_singleton &operator=(sc_comm_singleton &o) = delete;
virtual ~sc_comm_singleton(); virtual ~sc_comm_singleton();
static sc_comm_singleton& inst(){ static sc_comm_singleton &inst() {
static sc_comm_singleton i("__sc_singleton"); static sc_comm_singleton i("__sc_singleton");
return i; return i;
} }
seasocks::Server& get_server(); seasocks::Server &get_server();
void registerWebSocketHandler(const char* endpoint, std::shared_ptr<seasocks::WebSocket::Handler> handler, bool allowCrossOriginRequests = false); void registerWebSocketHandler(const char *endpoint, std::shared_ptr<seasocks::WebSocket::Handler> handler,
bool allowCrossOriginRequests = false);
void execute(std::function<void()> f); void execute(std::function<void()> f);
void start_client(); void start_client();
protected: protected:
void start_of_simulation() override; void start_of_simulation() override;
void end_of_simulation() override; void end_of_simulation() override;
private: private:
sc_comm_singleton(sc_core::sc_module_name nm); sc_comm_singleton(sc_core::sc_module_name nm);
std::unique_ptr<seasocks::Server> m_serv; std::unique_ptr<seasocks::Server> m_serv;
std::thread t; std::thread t;
void thread_func(); void thread_func();
bool needs_client, client_started; bool needs_client, client_started;
std::vector<std::string> endpoints; std::vector<std::string> endpoints;
}; };
} /* namespace sysc */ } /* namespace sysc */

View File

@ -1,9 +1,34 @@
/* /*******************************************************************************
* tlm_extensions.h * Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
* *
* Created on: 12.07.2018 * Redistribution and use in source and binary forms, with or without
* Author: eyck * modification, are permitted provided that the following conditions are met:
*/ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef _SYSC_TLM_EXTENSIONS_H_ #ifndef _SYSC_TLM_EXTENSIONS_H_
#define _SYSC_TLM_EXTENSIONS_H_ #define _SYSC_TLM_EXTENSIONS_H_
@ -14,35 +39,32 @@ namespace sysc {
struct tlm_signal_uart_extension : public tlm::tlm_unmanaged_extension<tlm_signal_uart_extension> { struct tlm_signal_uart_extension : public tlm::tlm_unmanaged_extension<tlm_signal_uart_extension> {
struct uart_tx { struct uart_tx {
unsigned data_bits:4; unsigned data_bits : 4;
unsigned stop_bits:2; unsigned stop_bits : 2;
bool parity:1; bool parity : 1;
unsigned baud_rate:24; unsigned baud_rate : 24;
unsigned data; unsigned data;
} tx; } tx;
sc_core::sc_time start_time; sc_core::sc_time start_time;
}; };
struct tlm_signal_spi_extension : public tlm::tlm_unmanaged_extension<tlm_signal_spi_extension> { struct tlm_signal_spi_extension : public tlm::tlm_unmanaged_extension<tlm_signal_spi_extension> {
struct spi_tx { struct spi_tx {
unsigned data_bits:5; unsigned data_bits : 5;
bool msb_first:1; bool msb_first : 1;
bool s2m_data_valid:1; bool m2s_data_valid : 1;
bool s2m_data_valid : 1;
unsigned m2s_data, s2m_data; unsigned m2s_data, s2m_data;
} tx; } tx;
sc_core::sc_time start_time; sc_core::sc_time start_time;
void copy_from(tlm_extension_base const & other) override { void copy_from(tlm_extension_base const &other) override {
auto& o = static_cast<const type&>(other); auto &o = static_cast<const type &>(other);
this->tx=o.tx; this->tx = o.tx;
this->start_time=o.start_time; this->start_time = o.start_time;
} }
}; };
} }
#endif /* _SYSC_TLM_EXTENSIONS_H_ */ #endif /* _SYSC_TLM_EXTENSIONS_H_ */

View File

@ -1,9 +1,34 @@
/* /*******************************************************************************
* BLDC.h * Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
* *
* Created on: 26.06.2018 * Redistribution and use in source and binary forms, with or without
* Author: eyck * modification, are permitted provided that the following conditions are met:
*/ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef BLDC_H_ #ifndef BLDC_H_
#define BLDC_H_ #define BLDC_H_
@ -11,43 +36,47 @@
#include <boost/numeric/odeint.hpp> #include <boost/numeric/odeint.hpp>
namespace odeint = boost::numeric::odeint; namespace odeint = boost::numeric::odeint;
inline inline double norm_angle(double alpha) {
double norm_angle(double alpha){ double alpha_n = fmod(alpha, M_PI * 2);
double alpha_n = fmod(alpha, M_PI * 2); while (alpha_n < 0.) alpha_n += (M_PI * 2);
if (alpha_n < 0.) alpha_n += (M_PI * 2); return alpha_n;
return alpha_n;
} }
class BLDC { class BLDC {
public: public:
struct Config { struct Config {
double inertia = 0.0005; /* aka 'J' in kg/(m^2) */ double inertia = 0.0005; /* aka 'J' in kg/(m^2) */
double damping = 0.000089; /* aka 'B' in Nm/(rad/s) */ double damping = 0.000089; /* aka 'B' in Nm/(rad/s) */
double static_friction = 0.0; /* in Nm */ double static_friction = 0.0; /* in Nm */
//double Kv = 0.0042; /* motor constant in RPM/V */ // double Kv = 0.0042; /* motor constant in RPM/V */
double Ke = 0.0042; /* back emf constant in V/rad/s*/ double Ke = 0.0042; /* back emf constant in V/rad/s*/
double L = 0.0027; /* Coil inductance in H */ double L = 0.0027; /* Coil inductance in H */
double M = -0.000069; /* Mutual coil inductance in H */ double M = -0.000069; /* Mutual coil inductance in H */
double R = 2.875; /* Coil resistence in Ohm */ double R = 2.875; /* Coil resistence in Ohm */
int NbPoles = 2; /* NbPoles / 2 = Number of pole pairs (you count the permanent magnets on the rotor to get NbPoles) */ int NbPoles =
2; /* NbPoles / 2 = Number of pole pairs (you count the permanent magnets on the rotor to get NbPoles) */
}; };
using StateVector = std::array<double, 5>; using StateVector = std::array<double, 5>;
struct State{ struct State {
double& theta; /* angle of the rotor */ double &theta; /* angle of the rotor */
double& omega; /* angular speed of the rotor */ double &omega; /* angular speed of the rotor */
double& ia; /* phase a current */ double &ia; /* phase a current */
double& ib; /* phase b current */ double &ib; /* phase b current */
double& ic; /* phase c current */ double &ic; /* phase c current */
explicit State(StateVector& v):theta(v[0]), omega(v[1]), ia(v[2]), ib(v[3]), ic(v[4]){} explicit State(StateVector &v)
State(State&&) = delete; : theta(v[0])
State(const State&) = delete; , omega(v[1])
State& operator=(const State&) = delete; // Copy assignment operator , ia(v[2])
State& operator=(const State&&) = delete; // Move assignment operator , ib(v[3])
~State(){} , ic(v[4]) {}
void init(){ State(State &&) = delete;
State(const State &) = delete;
State &operator=(const State &) = delete; // Copy assignment operator
State &operator=(const State &&) = delete; // Move assignment operator
~State() {}
void init() {
theta = ia = ib = ic = 0; theta = ia = ib = ic = 0;
omega = 0.; omega = 0.;
} }
@ -57,49 +86,46 @@ public:
virtual ~BLDC(); virtual ~BLDC();
void set_input(std::array<double, 3> vin){ void set_input(std::array<double, 3> vin) { this->vin = vin; }
this->vin=vin;
}
void run(double dt); void run(double dt);
void printToStream(std::ostream&) const; void printToStream(std::ostream &) const;
double get_current_time(){return current_time;} double get_current_time() { return current_time; }
std::tuple<double, double, double> get_voltages(){ std::array<double, 7> get_voltages() {
return std::tuple<double, double, double>( return std::array<double, 7>{voltages[VA], voltages[VB], voltages[VC], voltages[VCENTER],
voltages[VA]+voltages[EA]+state.ia*config.R, voltages[EA], voltages[EB], voltages[EC]};
voltages[VB]+voltages[EB]+state.ib*config.R,
voltages[VC]+voltages[EC]+state.ic*config.R
);
} }
const State& getState(){ return state;} const State &getState() { return state; }
void setLoad(double torque) { torque_load = torque; }
const double dt = 0.00000001;
void setLoad(double torque){torque_load=torque;}
protected: protected:
Config config; Config config;
StateVector stateVector; StateVector stateVector;
State state; State state;
std::array<double, 3> vin; std::array<double, 3> vin;
double current_time = 0.0; double current_time = 0.0;
double torque_load=0.0; double torque_load = 0.0001;
double etorque=0.0, mtorque=0.0; double etorque = 0.0, mtorque = 0.0;
const double dt = 0.000001;
std::array<double, 7> voltages; std::array<double, 7> voltages;
enum VoltageNames {EA=0, EB=1, EC=2, VA=3, VB=4, VC=5, VCENTER=6}; enum VoltageNames { EA = 0, EB = 1, EC = 2, VA = 3, VB = 4, VC = 5, VCENTER = 6 };
double calc_bemf_factor(const State& state, double theta ); double calc_bemf_factor(const State &state, double theta);
void calc_back_emf(const State& state, double theta_e ); void calc_back_emf(const State &state, double theta_e);
void calc_voltages(); void calc_voltages();
// ODE part // ODE part
//boost::numeric::odeint::runge_kutta4< StateVector > stepper; // boost::numeric::odeint::runge_kutta4< StateVector > stepper;
//boost::numeric::odeint::runge_kutta_cash_karp54<StateVector > stepper; // boost::numeric::odeint::runge_kutta_cash_karp54<StateVector > stepper;
//using stepper_type = odeint::runge_kutta_dopri5<StateVector>; // using stepper_type = odeint::runge_kutta_dopri5<StateVector>;
//using stepper_type = odeint::runge_kutta_cash_karp54< StateVector>; // using stepper_type = odeint::runge_kutta_cash_karp54< StateVector>;
using stepper_type = odeint::runge_kutta_fehlberg78< StateVector>; using stepper_type = odeint::runge_kutta_fehlberg78<StateVector>;
void rotor_dyn( const StateVector& x , StateVector& dxdt , const double t ); void rotor_dyn(const StateVector &x, StateVector &dxdt, const double t);
}; };
std::ostream& operator<<(std::ostream& os, const BLDC& bldc); std::ostream &operator<<(std::ostream &os, const BLDC &bldc);
#endif /* BLDC_H_ */ #endif /* BLDC_H_ */

View File

@ -1,36 +1,66 @@
/* /*******************************************************************************
* dcmotor.h * Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
* *
* Created on: 25.07.2018 * Redistribution and use in source and binary forms, with or without
* Author: eyck * modification, are permitted provided that the following conditions are met:
*/ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef _SYSC_TOP_DCMOTOR_H_ #ifndef _SYSC_TOP_DCMOTOR_H_
#define _SYSC_TOP_DCMOTOR_H_ #define _SYSC_TOP_DCMOTOR_H_
#include "BLDC.h" #include "BLDC.h"
#include "cci_configuration"
#include "scc/traceable.h" #include "scc/traceable.h"
#include <systemc> #include <systemc>
namespace sysc { namespace sysc {
class dc_motor: public sc_core::sc_module, public scc::traceable { class dc_motor : public sc_core::sc_module, public scc::traceable {
public: public:
SC_HAS_PROCESS(dc_motor); SC_HAS_PROCESS(dc_motor);// NOLINT
sc_core::sc_in<double> va_i, vb_i, vc_i; sc_core::sc_in<double> va_i, vb_i, vc_i;
sc_core::sc_out<double> va_o, vb_o, vc_o; sc_core::sc_out<double> va_o, vb_o, vc_o, vcenter_o;
dc_motor(const sc_core::sc_module_name& nm ); dc_motor(const sc_core::sc_module_name &nm);
virtual ~dc_motor(); virtual ~dc_motor();
void trace(sc_core::sc_trace_file *trf) override; void trace(sc_core::sc_trace_file *trf) const override;
cci::cci_param<sc_core::sc_time> max_integ_step;
cci::cci_param<double> load;
private: private:
void thread(void); void thread(void);
BLDC bldc_model; BLDC bldc_model;
const BLDC::State& bldc_state; const BLDC::State &bldc_state;
std::array<double, 7> vout;
}; };
} /* namespace sysc */ } /* namespace sysc */

View File

@ -1,9 +1,34 @@
/* /*******************************************************************************
* h_bridge.h * Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
* *
* Created on: 25.07.2018 * Redistribution and use in source and binary forms, with or without
* Author: eyck * modification, are permitted provided that the following conditions are met:
*/ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef RISCV_SC_INCL_SYSC_TOP_H_BRIDGE_H_ #ifndef RISCV_SC_INCL_SYSC_TOP_H_BRIDGE_H_
#define RISCV_SC_INCL_SYSC_TOP_H_BRIDGE_H_ #define RISCV_SC_INCL_SYSC_TOP_H_BRIDGE_H_
@ -13,9 +38,9 @@
namespace sysc { namespace sysc {
class h_bridge: public sc_core::sc_module { class h_bridge : public sc_core::sc_module {
public: public:
SC_HAS_PROCESS(h_bridge); SC_HAS_PROCESS(h_bridge);// NOLINT
sc_core::sc_in<sc_dt::sc_logic> ha_i, la_i; sc_core::sc_in<sc_dt::sc_logic> ha_i, la_i;
sc_core::sc_in<sc_dt::sc_logic> hb_i, lb_i; sc_core::sc_in<sc_dt::sc_logic> hb_i, lb_i;
@ -25,13 +50,15 @@ public:
cci::cci_param<double> vcc; cci::cci_param<double> vcc;
h_bridge(const sc_core::sc_module_name& nm); h_bridge(const sc_core::sc_module_name &nm);
virtual ~h_bridge(); virtual ~h_bridge();
private: private:
void ain_cb(); void ain_cb();
void bin_cb(); void bin_cb();
void cin_cb(); void cin_cb();
void write_output(sc_dt::sc_logic h_i, sc_dt::sc_logic l_i, sc_core::sc_out<double> &v_o);
}; };
} /* namespace sysc */ } /* namespace sysc */

View File

@ -0,0 +1,68 @@
/*******************************************************************************
* Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef _SIFIVE_HIFIVE1_H_
#define _SIFIVE_HIFIVE1_H_
#include <sysc/top/terminal.h>
#include <sysc/top/mcp_adc.h>
#include "tlm/tlm_signal_sockets.h"
#include <boost/preprocessor.hpp>
#include <systemc>
#include <sysc/SiFive/fe310.h>
namespace sysc {
struct hifive1 : public sc_core::sc_module {
SC_HAS_PROCESS(hifive1);
sc_core::sc_in<bool> erst_n;
sc_core::sc_in<double> vref_i;
#define PORT_DECL(z, n, _) sc_core::sc_in<double> adc_ch##n##_i;
BOOST_PP_REPEAT(8, PORT_DECL, _);
#undef PORT_DECL
sc_core::sc_out<sc_dt::sc_logic> ha_o, la_o, hb_o, lb_o,hc_o, lc_o;
hifive1(sc_core::sc_module_name nm);
protected:
sc_core::sc_vector<tlm::tlm_signal<sc_dt::sc_logic>> s_gpio;
sc_core::sc_vector<scc::tlm_signal_logic_in> h_bridge;
fe310 i_fe310;
terminal i_terminal;
mcp_3208 i_adc;
};
}
#endif /* _SYSC_SIFIVE_HIFIVE1_H_ */

View File

@ -1,47 +0,0 @@
/*
* mcp3008.h
*
* Created on: 17.07.2018
* Author: eyck
*/
#ifndef _SYSC_TOP_MCP3008_H_
#define _SYSC_TOP_MCP3008_H_
#include "scc/signal_target_mixin.h"
#include "scc/signal_initiator_mixin.h"
#include "sysc/tlm_extensions.h"
#include <tlm/tlm_signal.h>
#include "cci_configuration"
#include <sysc/utils/sc_vector.h>
#include <sysc/kernel/sc_module.h>
namespace sysc {
class mcp3008: public sc_core::sc_module {
public:
SC_HAS_PROCESS(mcp3008);
scc::tlm_signal_logic_in sck_i;
scc::tlm_signal_logic_out miso_o;
scc::tlm_signal_logic_in mosi_i;
scc::tlm_signal_logic_in cs_i;
sc_core::sc_in<double> vref_i;
sc_core::sc_vector<sc_core::sc_in<double>> ch_i;
mcp3008(sc_core::sc_module_name nm);
virtual ~mcp3008();
private:
tlm::tlm_sync_enum receive(tlm::tlm_signal_gp<sc_dt::sc_logic> &, tlm::tlm_phase &, sc_core::sc_time &);
void do_conversion();
unsigned idx, rx_bits;
std::array<uint8_t, 3> rx_bytes, tx_bytes;
sc_dt::sc_logic mosi_v, miso_v, cs_v;
sysc::tlm_signal_spi_extension* ext, tx_ext;
sc_core::sc_time last_tx_start;
};
} /* namespace sysc */
#endif /* _SYSC_TOP_MCP3008_H_ */

View File

@ -0,0 +1,120 @@
/*******************************************************************************
* Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef _SYSC_TOP_MCP3008_H_
#define _SYSC_TOP_MCP3008_H_
#include "cci_configuration"
#include "scc/signal_initiator_mixin.h"
#include "scc/signal_target_mixin.h"
#include "sysc/tlm_extensions.h"
#include <sysc/kernel/sc_module.h>
#include <sysc/utils/sc_vector.h>
#include <tlm/tlm_signal.h>
namespace sysc {
class mcp_adc : public sc_core::sc_module {
public:
template <typename TYPE>
static std::unique_ptr<mcp_adc> create(sc_core::sc_module_name nm);
scc::tlm_signal_logic_in sck_i;
scc::tlm_signal_logic_out miso_o;
scc::tlm_signal_logic_in mosi_i;
scc::tlm_signal_logic_in cs_i;
sc_core::sc_in<double> vref_i;
sc_core::sc_vector<sc_core::sc_in<double>> ch_i;
mcp_adc(mcp_adc &other) = delete;
mcp_adc(mcp_adc &&other) = delete;
mcp_adc &operator=(mcp_adc &other) = delete;
mcp_adc &operator=(mcp_adc &&other) = delete;
~mcp_adc() override = default;
protected:
mcp_adc(sc_core::sc_module_name nm, size_t channel_no)
: sc_core::sc_module(nm)
, NAMED(sck_i)
, NAMED(miso_o)
, NAMED(mosi_i)
, NAMED(cs_i)
, NAMED(vref_i)
, NAMED(ch_i, channel_no) {}
};
class mcp_3008 : public mcp_adc {
public:
SC_HAS_PROCESS(mcp_3008);// NOLINT
mcp_3008(sc_core::sc_module_name nm);
~mcp_3008() override = default;
private:
tlm::tlm_sync_enum receive(tlm::tlm_signal_gp<sc_dt::sc_logic> &, tlm::tlm_phase &, sc_core::sc_time &);
void do_conversion();
unsigned idx, rx_bits;
std::array<uint8_t, 3> rx_bytes, tx_bytes;
sc_dt::sc_logic mosi_v, miso_v, cs_v;
sysc::tlm_signal_spi_extension *ext, tx_ext;
sc_core::sc_time last_tx_start;
};
class mcp_3208 : public mcp_adc {
public:
SC_HAS_PROCESS(mcp_3208);// NOLINT
mcp_3208(sc_core::sc_module_name nm);
~mcp_3208() override = default;
private:
tlm::tlm_sync_enum receive(tlm::tlm_signal_gp<sc_dt::sc_logic> &, tlm::tlm_phase &, sc_core::sc_time &);
void sample_inputs();
void do_conversion();
unsigned idx, rx_bits, byte_offs, bit_offs;
std::array<uint8_t, 3> rx_bytes, tx_bytes;
sc_dt::sc_logic mosi_v, sck_v, cs_v;
sysc::tlm_signal_spi_extension *ext, tx_ext;
sc_core::sc_time last_tx_start;
sc_core::sc_event clk_sample_evt;
};
} /* namespace sysc */
#endif /* _SYSC_TOP_MCP3008_H_ */

View File

@ -1,42 +1,62 @@
/* /*******************************************************************************
* system.h * Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
* *
* Created on: 11.07.2018 * Redistribution and use in source and binary forms, with or without
* Author: eyck * modification, are permitted provided that the following conditions are met:
*/ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef __SYSC_GENERAL_SYSTEM_H_ #ifndef __SYSC_GENERAL_SYSTEM_H_
#define __SYSC_GENERAL_SYSTEM_H_ #define __SYSC_GENERAL_SYSTEM_H_
#include <systemc>
#include "sysc/SiFive/hifive1.h"
#include "mcp3008.h"
#include "terminal.h"
#include "h_bridge.h"
#include "dcmotor.h" #include "dcmotor.h"
#include "h_bridge.h"
#include <memory>
#include <systemc>
#include "hifive1.h"
namespace sysc { namespace sysc {
class system: sc_core::sc_module { class system : sc_core::sc_module {
public: public:
SC_HAS_PROCESS(system); SC_HAS_PROCESS(system);// NOLINT
system(sc_core::sc_module_name nm); system(sc_core::sc_module_name nm);
virtual ~system(); virtual ~system();
private: private:
sc_core::sc_vector<tlm::tlm_signal<sc_dt::sc_logic>> s_gpio; sc_core::sc_signal<sc_dt::sc_logic> s_ha, s_la, s_hb, s_lb, s_hc, s_lc;
sc_core::sc_signal<bool> s_rst_n; sc_core::sc_signal<bool> s_rst_n;
sc_core::sc_signal<double> s_vref, s_va, s_vb, s_vc, s_vasens, s_vbsens, s_vcsens; sc_core::sc_signal<double> s_vref, s_va, s_vb, s_vc, s_vasens, s_vbsens, s_vcsens, s_vcentersens;
sc_core::sc_vector<sc_core::sc_signal<double>> s_ana; sc_core::sc_vector<sc_core::sc_signal<double>> s_ana;
sysc::hifive1 i_platform; sysc::hifive1 i_hifive1;
sysc::terminal i_terminal;
sysc::mcp3008 i_adc;
sysc::h_bridge i_h_bridge; sysc::h_bridge i_h_bridge;
sysc::dc_motor i_motor; sysc::dc_motor i_motor;
void gen_por(); void gen_por();
}; };
} }
#endif /* __SYSC_GENERAL_SYSTEM_H_ */ #endif /* __SYSC_GENERAL_SYSTEM_H_ */

View File

@ -1,31 +1,56 @@
/* /*******************************************************************************
* terminal.h * Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
* *
* Created on: 07.07.2018 * Redistribution and use in source and binary forms, with or without
* Author: eyck * modification, are permitted provided that the following conditions are met:
*/ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef _SYSC_TOP_TERMINAL_H_ #ifndef _SYSC_TOP_TERMINAL_H_
#define _SYSC_TOP_TERMINAL_H_ #define _SYSC_TOP_TERMINAL_H_
#include "scc/signal_target_mixin.h"
#include "scc/signal_initiator_mixin.h"
#include "tlm/tlm_signal.h"
#include "cci_configuration" #include "cci_configuration"
#include <sysc/kernel/sc_module.h> #include "scc/signal_initiator_mixin.h"
#include "scc/signal_target_mixin.h"
#include "tlm/tlm_signal.h"
#include <memory> #include <memory>
#include <sysc/kernel/sc_module.h>
namespace sysc { namespace sysc {
class WsHandler; class WsHandler;
class terminal: public sc_core::sc_module { class terminal : public sc_core::sc_module {
public: public:
scc::tlm_signal_logic_out tx_o; scc::tlm_signal_logic_out tx_o;
scc::tlm_signal_logic_in rx_i; scc::tlm_signal_logic_in rx_i;
terminal(); terminal();
terminal(const sc_core::sc_module_name& nm); terminal(const sc_core::sc_module_name &nm);
virtual ~terminal(); virtual ~terminal();
@ -33,11 +58,11 @@ public:
protected: protected:
void before_end_of_elaboration(); void before_end_of_elaboration();
void receive(tlm::tlm_signal_gp<sc_dt::sc_logic>& gp, sc_core::sc_time& delay); void receive(tlm::tlm_signal_gp<sc_dt::sc_logic> &gp, sc_core::sc_time &delay);
std::vector<uint8_t> queue; std::vector<uint8_t> queue;
std::shared_ptr<sysc::WsHandler> handler; std::shared_ptr<sysc::WsHandler> handler;
sc_core::sc_time last_tx_start=sc_core::SC_ZERO_TIME; sc_core::sc_time last_tx_start = sc_core::SC_ZERO_TIME;
}; };
} }

112
platform/src/CLIParser.cpp Normal file
View File

@ -0,0 +1,112 @@
/*******************************************************************************
* Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#include "CLIParser.h"
#include <scc/report.h>
#include <iostream>
#include <iss/log_categories.h>
#include <stdexcept>
namespace po = boost::program_options;
using namespace sc_core;
CLIParser::CLIParser(int argc, char *argv[])
: desc("Options")
, valid(false) {
scc::init_logging();
LOGGER(DEFAULT)::reporting_level() = logging::WARNING;
LOGGER(connection)::reporting_level() = logging::WARNING;
LOGGER(SystemC)::reporting_level() = logging::WARNING;
build();
try {
po::store(po::parse_command_line(argc, argv, desc), vm_); // can throw
// --help option
if (vm_.count("help")) {
std::cout << "DBT-RISE-RiscV simulator for RISC-V" << std::endl << desc << std::endl;
}
po::notify(vm_); // throws on error, so do after help in case there are any problems
valid = true;
} catch (po::error &e) {
std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
std::cerr << desc << std::endl;
}
if (vm_.count("verbose")) { // NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE
const std::array<int, 8> verbosity = {SC_NONE, // Logging::NONE
SC_LOW, // Logging::FATAL
SC_LOW, // Logging::ERROR
SC_LOW, // Logging::WARNING
SC_MEDIUM, // Logging::INFO
SC_HIGH, // logging::DEBUG
SC_FULL, // logging::TRACE
SC_DEBUG}; // logging::TRACE+1
auto log_level = vm_["verbose"].as<int>();
auto l = logging::as_log_level(log_level > 6 ? 6 : log_level);
LOGGER(DEFAULT)::reporting_level() = l;
LOGGER(DEFAULT)::print_time() = false;
LOGGER(connection)::reporting_level() = l;
LOGGER(connection)::print_time() = false;
LOGGER(SystemC)::reporting_level() = l;
LOGGER(SystemC)::print_time() = false;
sc_report_handler::set_verbosity_level(verbosity[log_level]);
}
if (vm_.count("log-file")) {
// configure the connection logger
auto f = fopen(vm_["log-file"].as<std::string>().c_str(), "w");
LOG_OUTPUT(DEFAULT)::stream() = f;
LOG_OUTPUT(connection)::stream() = f;
LOG_OUTPUT(SystemC)::stream() = f;
}
}
void CLIParser::build() {
// clang-format off
desc.add_options()
("help,h", "Print help message")
("verbose,v", po::value<int>()->implicit_value(3), "Sets logging verbosity")
("log-file", po::value<std::string>(), "Sets default log file.")
("disass,d", po::value<std::string>()->implicit_value(""), "Enables disassembly")
("elf,l", po::value<std::string>(), "ELF file to load")
("gdb-port,g", po::value<unsigned short>()->default_value(0), "enable gdb server and specify port to use")
("dump-ir", "dump the intermediate representation")
("quantum", po::value<unsigned>(), "SystemC quantum time in ns")
("reset,r", po::value<std::string>(), "reset address")
("trace-level,t", po::value<unsigned>()->default_value(0), "enable tracing, or combination of 1=signals and 2=TX text, 4=TX compressed text, 6=TX in SQLite")
("trace-default-on", "enables tracing for all unspecified modules")
("trace-file", po::value<std::string>()->default_value("system"), "set th ename of the trace file")
("max_time,m", po::value<std::string>(), "maximum time to run")
("config-file,c", po::value<std::string>()->default_value(""), "read configuration from file")
("dump-config,dc", po::value<std::string>()->default_value(""), "dump configuration to file file");
// clang-format on
}
CLIParser::~CLIParser() = default;

60
platform/src/CLIParser.h Normal file
View File

@ -0,0 +1,60 @@
/*******************************************************************************
* Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef PLATFORM_SRC_CLIPARSER_H_
#define PLATFORM_SRC_CLIPARSER_H_
#include <boost/program_options.hpp>
#include <memory>
class CLIParser {
public:
CLIParser(int argc, char *argv[]);
virtual ~CLIParser();
bool is_valid() { return valid; }
const boost::program_options::variables_map &vm() { return vm_; }
bool is_set(const char *option) { return vm_.count(option) != 0; }
template <typename T> const T &get(const char *option) { return vm_[option].as<T>(); }
private:
void build();
bool valid;
boost::program_options::variables_map vm_;
boost::program_options::options_description desc;
};
#endif /* PLATFORM_SRC_CLIPARSER_H_ */

View File

@ -1,11 +1,26 @@
# library files # library files
FILE(GLOB RiscVSCHeaders *.h */*.h) FILE(GLOB RiscVSCHeaders ${PROJECT_SOURCE_DIR}/incl/sysc/*.h ${PROJECT_SOURCE_DIR}/incl/sysc/*/*.h)
FILE(GLOB RiscvSCSources sysc/*.cpp)
set(LIB_HEADERS ${RiscVSCHeaders} ) set(LIB_HEADERS ${RiscVSCHeaders} )
set(LIB_SOURCES ${RiscvSCSources} ) set(LIB_SOURCES
sysc/aon.cpp
sysc/BLDC.cpp
sysc/clint.cpp
sysc/dcmotor.cpp
sysc/gpio.cpp
sysc/h_bridge.cpp
sysc/hifive1.cpp
sysc/fe310.cpp
sysc/mcp_adc.cpp
sysc/plic.cpp
sysc/prci.cpp
sysc/pwm.cpp
sysc/sc_comm_singleton.cpp
sysc/spi.cpp
sysc/system.cpp
sysc/terminal.cpp
sysc/uart.cpp
CLIParser.cpp )
set(APP_HEADERS )
set(APP_SOURCES sc_main.cpp) set(APP_SOURCES sc_main.cpp)
# Define two variables in order not to repeat ourselves. # Define two variables in order not to repeat ourselves.
@ -26,18 +41,25 @@ set_target_properties(${LIBRARY_NAME} PROPERTIES
# This is a make target, so you can do a "make riscv-sc" # This is a make target, so you can do a "make riscv-sc"
set(APPLICATION_NAME riscv.vp) set(APPLICATION_NAME riscv.vp)
include_directories(${PROJECT_SOURCE_DIR}/incl)
include_directories(${CONAN_INCLUDE_DIRS_SEASOCKS}) include_directories(${CONAN_INCLUDE_DIRS_SEASOCKS})
add_definitions(-DWITH_SYSTEMC) # or -DSC_NO_WRITE_CHECK
include_directories(${SystemC_INCLUDE_DIRS}) include_directories(${SystemC_INCLUDE_DIRS})
include_directories(${CCI_INCLUDE_DIRS}) include_directories(${CCI_INCLUDE_DIRS})
if(SCV_FOUND)
add_definitions(-DWITH_SCV)
include_directories(${SCV_INCLUDE_DIRS})
endif()
link_directories(${SystemC_LIBRARY_DIR})
link_directories(${CCI_LIBRARY_DIR}) link_directories(${SystemC_LIBRARY_DIRS})
link_directories(${CCI_LIBRARY_DIRS})
link_directories(${CONAN_LIB_DIRS_SEASOCKS}) link_directories(${CONAN_LIB_DIRS_SEASOCKS})
add_executable(${APPLICATION_NAME} ${APP_SOURCES}) add_executable(${APPLICATION_NAME} ${APP_SOURCES})
# include files for this application
target_include_directories(${APPLICATION_NAME} SYSTEM PRIVATE ${LLVM_INCLUDE_DIRS})
# Links the target exe against the libraries # Links the target exe against the libraries
target_link_libraries(${APPLICATION_NAME} ${LIBRARY_NAME}) target_link_libraries(${APPLICATION_NAME} ${LIBRARY_NAME})
target_link_libraries(${APPLICATION_NAME} riscv.sc) target_link_libraries(${APPLICATION_NAME} riscv.sc)
target_link_libraries(${APPLICATION_NAME} riscv) target_link_libraries(${APPLICATION_NAME} riscv)
@ -50,8 +72,6 @@ target_link_libraries(${APPLICATION_NAME} ${llvm_libs})
target_link_libraries(${APPLICATION_NAME} ${CCI_LIBRARIES} ) target_link_libraries(${APPLICATION_NAME} ${CCI_LIBRARIES} )
target_link_libraries(${APPLICATION_NAME} ${SystemC_LIBRARIES} ) target_link_libraries(${APPLICATION_NAME} ${SystemC_LIBRARIES} )
if(SCV_FOUND) if(SCV_FOUND)
add_definitions(-DWITH_SCV)
include_directories(${SCV_INCLUDE_DIRS})
link_directories(${SCV_LIBRARY_DIRS}) link_directories(${SCV_LIBRARY_DIRS})
target_link_libraries (${APPLICATION_NAME} ${SCV_LIBRARIES}) target_link_libraries (${APPLICATION_NAME} ${SCV_LIBRARIES})
endif() endif()

View File

@ -1,49 +1,52 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
// #include "CLIParser.h"
// #include <sysc/top/system.h>
//////////////////////////////////////////////////////////////////////////////// #include <iss/jit/jit_helper.h>
#include <iss/log_categories.h>
#include <scc/configurable_tracer.h>
#include <scc/configurer.h>
#include <scc/report.h>
#include <scc/scv_tr_db.h>
#include <scc/tracer.h>
#include <scc/perf_estimator.h>
#include <cci_utils/broker.h>
#include <boost/program_options.hpp> #include <boost/program_options.hpp>
#include <iss/log_categories.h> #include <fstream>
#include <sstream> #include <sstream>
#include "scc/configurer.h"
#include "scc/report.h"
#include "scc/scv_tr_db.h"
#include "scc/tracer.h"
#include <cci_utils/broker.h>
#include <iss/jit/jit_helper.h>
#include "../incl/sysc/top/system.h"
using namespace sysc; using namespace sysc;
namespace po = boost::program_options; namespace po = boost::program_options;
@ -54,69 +57,20 @@ const size_t SUCCESS = 0;
const size_t ERROR_UNHANDLED_EXCEPTION = 2; const size_t ERROR_UNHANDLED_EXCEPTION = 2;
} // namespace } // namespace
#include "sysc/kernel/sc_externs.h"
int
main( int argc, char* argv[]){
#ifdef _POSIX_SOURCE
putenv(const_cast<char*>("SC_SIGNAL_WRITE_CHECK=DISABLE"));
putenv(const_cast<char*>("SC_VCD_SCOPES=ENABLE"));
#endif
return sc_core::sc_elab_and_sim( argc, argv );
}
int sc_main(int argc, char *argv[]) { int sc_main(int argc, char *argv[]) {
// sc_report_handler::set_handler(my_report_handler); ///////////////////////////////////////////////////////////////////////////
scc::Logger<>::reporting_level() = logging::ERROR; // SystemC >=2.2 got picky about multiple drivers so disable check
///////////////////////////////////////////////////////////////////////////
sc_report_handler::set_actions(SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, SC_DO_NOTHING);
///////////////////////////////////////////////////////////////////////////
// create global CCI broker
///////////////////////////////////////////////////////////////////////////
cci::cci_register_broker(new cci_utils::broker("Global Broker")); cci::cci_register_broker(new cci_utils::broker("Global Broker"));
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// CLI argument parsing // CLI argument parsing & logging setup
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
po::options_description desc("Options"); CLIParser parser(argc, argv);
// clang-format off if (!parser.is_valid()) return ERROR_IN_COMMAND_LINE;
desc.add_options()
("help,h", "Print help message")
("verbose,v", po::value<int>()->implicit_value(3), "Sets logging verbosity")
("log-file", po::value<std::string>(), "Sets default log file.")
("disass,d", po::value<std::string>()->implicit_value(""), "Enables disassembly")
("elf,l", po::value<std::string>(), "ELF file to load")
("gdb-port,g", po::value<unsigned short>()->default_value(0), "enable gdb server and specify port to use")
("dump-ir", "dump the intermediate representation")
("quantum", po::value<unsigned>(), "SystemC quantum time in ns")
("reset,r", po::value<std::string>(), "reset address")
("trace,t", po::value<unsigned>()->default_value(0), "enable tracing, or combintation of 1=signals and 2=TX text, 4=TX compressed text, 6=TX in SQLite")
("max_time,m", po::value<std::string>(), "maximum time to run")
("config-file,c", po::value<std::string>()->default_value(""), "read configuration from file")
("dump-config", po::value<std::string>()->default_value(""), "dump configuration to file file");
// 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 << "DBT-RISE-RiscV simulator for RISC-V" << 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;
}
if (vm.count("verbose")) {
auto l = logging::as_log_level(vm["verbose"].as<int>());
LOGGER(DEFAULT)::reporting_level() = l;
LOGGER(connection)::reporting_level() = l;
LOGGER(SystemC)::reporting_level() = l;
scc::Logger<>::reporting_level() = l;
}
if (vm.count("log-file")) {
// configure the connection logger
auto f = fopen(vm["log-file"].as<std::string>().c_str(), "w");
LOG_OUTPUT(DEFAULT)::stream() = f;
LOG_OUTPUT(connection)::stream() = f;
LOG_OUTPUT(SystemC)::stream() = f;
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// set up infrastructure // set up infrastructure
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -124,45 +78,48 @@ int sc_main(int argc, char *argv[]) {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// set up configuration // set up configuration
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
scc::configurer cfg(vm["config-file"].as<std::string>()); scc::configurer cfg(parser.get<std::string>("config-file"));
///////////////////////////////////////////////////////////////////////////
// set up tracing & transaction recording
///////////////////////////////////////////////////////////////////////////
auto trace_level = parser.get<unsigned>("trace-level");
scc::configurable_tracer trace(parser.get<std::string>("trace-file"),
static_cast<scc::tracer::file_type>(trace_level >> 1), // bit3-bit1 define the kind of transaction trace
(trace_level&0x1) != 0, // bit0 enables vcd
parser.is_set("trace-default-on"));
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// instantiate top level // instantiate top level
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
auto i_system = std::make_unique<sysc::system>("i_system"); auto i_system = std::make_unique<sysc::system>("i_system");
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// set up tracing & transaction recording // add non-implemented 'enableTracing' properties
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
auto trace_val = vm["trace"].as<unsigned>(); trace.add_control();
scc::tracer trace("simple_system", static_cast<scc::tracer::file_type>(trace_val >> 1), trace_val != 0);
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// dump configuration if requested // dump configuration if requested
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
if(vm["dump-config"].as<std::string>().size()>0){ if (parser.get<std::string>("dump-config").size() > 0) {
std::ofstream of{vm["dump-config"].as<std::string>()}; std::ofstream of{parser.get<std::string>("dump-config")};
if(of.is_open()) if (of.is_open()) cfg.dump_configuration(of);
cfg.dump_configuration(of);
} }
cfg.configure(); cfg.configure();
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// overwrite config with command line settings // overwrite config with command line settings
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
if (vm["gdb-port"].as<unsigned short>()) cfg.set_value("i_system.i_hifive1.i_fe310.i_core_complex.gdb_server_port", parser.get<unsigned short>("gdb-port"));
cfg.set_value("i_system.i_platform.i_core_complex.gdb_server_port", vm["gdb-port"].as<unsigned short>()); cfg.set_value("i_system.i_hifive1.i_fe310.i_core_complex.dump_ir", parser.is_set("dump-ir"));
if (vm.count("dump-ir")) if (parser.is_set("elf")) cfg.set_value("i_system.i_hifive1.i_fe310.i_core_complex.elf_file", parser.get<std::string>("elf"));
cfg.set_value("i_system.i_platform.i_core_complex.dump_ir", vm.count("dump-ir") != 0); if (parser.is_set("quantum"))
if (vm.count("elf")) tlm::tlm_global_quantum::instance().set(sc_core::sc_time(parser.get<unsigned>("quantum"), sc_core::SC_NS));
cfg.set_value("i_system.i_platform.i_core_complex.elf_file", vm["elf"].as<std::string>()); if (parser.is_set("reset")) {
if (vm.count("quantum")) auto str = parser.get<std::string>("reset");
tlm::tlm_global_quantum::instance().set(sc_core::sc_time(vm["quantum"].as<unsigned>(), sc_core::SC_NS)); uint64_t start_address = str.find("0x") == 0 ? std::stoull(str.substr(2), nullptr, 16) : std::stoull(str, nullptr, 10);
if (vm.count("reset")) { cfg.set_value("i_system.i_hifive1.i_fe310.i_core_complex.reset_address", start_address);
auto str = vm["reset"].as<std::string>();
uint64_t start_address = str.find("0x") == 0 ? std::stoull(str.substr(2), 0, 16) : std::stoull(str, 0, 10);
cfg.set_value("i_system.i_platform.i_core_complex.reset_address", start_address);
} }
if (vm.count("disass")) { if (parser.is_set("disass")) {
cfg.set_value("i_system.i_platform.i_core_complex.enable_disass", true); cfg.set_value("i_system.i_hifive1.i_fe310.i_core_complex.enable_disass", true);
LOGGER(disass)::reporting_level() = logging::INFO; LOGGER(disass)::reporting_level() = logging::INFO;
auto file_name = vm["disass"].as<std::string>(); auto file_name = parser.get<std::string>("disass");
if (file_name.length() > 0) { if (file_name.length() > 0) {
LOG_OUTPUT(disass)::stream() = fopen(file_name.c_str(), "w"); LOG_OUTPUT(disass)::stream() = fopen(file_name.c_str(), "w");
LOGGER(disass)::print_time() = false; LOGGER(disass)::print_time() = false;
@ -173,14 +130,13 @@ int sc_main(int argc, char *argv[]) {
// run simulation // run simulation
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
try { try {
if(vm.count("max_time")){ if (parser.is_set("max_time")) {
sc_core::sc_time max_time = scc::parse_from_string(vm["max_time"].as<std::string>()); sc_core::sc_start(scc::parse_from_string(parser.get<std::string>("max_time")));
sc_core::sc_start(max_time);
} else } else
sc_core::sc_start(); sc_core::sc_start();
} catch(sc_core::sc_report& rep){ if (!sc_core::sc_end_of_simulation_invoked()) sc_core::sc_stop();
CLOG(FATAL, SystemC)<<"IWEF"[rep.get_severity()]<<"("<<rep.get_id()<<") "<<rep.get_msg_type()<<": "<<rep.get_msg()<<std::endl; } catch (sc_core::sc_report &rep) {
sc_core::sc_report_handler::get_handler()(rep, sc_core::SC_DISPLAY | sc_core::SC_STOP);
} }
if (!sc_core::sc_end_of_simulation_invoked()) sc_core::sc_stop();
return 0; return 0;
} }

View File

@ -1,9 +1,34 @@
/* /*******************************************************************************
* BLDC.cpp * Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
* *
* Created on: 26.06.2018 * Redistribution and use in source and binary forms, with or without
* Author: eyck * modification, are permitted provided that the following conditions are met:
*/ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#include "sysc/top/BLDC.h" #include "sysc/top/BLDC.h"
@ -14,50 +39,48 @@ BLDC::BLDC(const Config config)
, stateVector({{0.0, 0.0, 0.0, 0.0, 0.0}}) , stateVector({{0.0, 0.0, 0.0, 0.0, 0.0}})
, state(stateVector) , state(stateVector)
, vin({{0.0, 0.0, 0.0}}) , vin({{0.0, 0.0, 0.0}})
, voltages({{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}) , voltages({{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}) {
{
state.init(); state.init();
} }
BLDC::~BLDC() { BLDC::~BLDC() = default;
} double BLDC::calc_bemf_factor(const State &x, double theta) {
if (theta >= 0 && theta < 2. / 3. * M_PI) {
double BLDC::calc_bemf_factor(const State& x, double theta){
if(theta>=0 && theta < 2./3.*M_PI){
return 1; return 1;
} else if(theta>=2./3.*M_PI && theta < M_PI){ } else if (theta >= 2. / 3. * M_PI && theta < M_PI) {
return 1-6/M_PI*(theta-2./3.*M_PI); return 1 - 6 / M_PI * (theta - 2. / 3. * M_PI);
} else if(theta>=M_PI && theta < 5./3. * M_PI){ } else if (theta >= M_PI && theta < 5. / 3. * M_PI) {
return -1; return -1;
} else if(theta>=5./3. * M_PI && theta < 2. * M_PI){ } else if (theta >= 5. / 3. * M_PI && theta <= 2. * M_PI) {
return -1+6/M_PI*(theta-5./3.*M_PI); return -1 + 6 / M_PI * (theta - 5. / 3. * M_PI);
} else { } else {
fprintf(stderr, "ERROR: angle out of bounds can not calculate bemf %f\n", theta); fprintf(stderr, "ERROR: angle out of bounds can not calculate bemf %f\n", theta);
throw std::runtime_error("angle out of bounds can not calculate bemf"); throw std::runtime_error("angle out of bounds can not calculate bemf");
} }
} }
void BLDC::calc_back_emf(const State& state, double theta_e) { void BLDC::calc_back_emf(const State &state, double theta_e) {
double max_bemf = config.Ke * state.omega; double max_bemf = config.Ke * state.omega;
voltages[EA] = max_bemf*calc_bemf_factor(state, norm_angle(theta_e)); theta_e-=M_PI * (1. / 3.);
voltages[EB] = max_bemf*calc_bemf_factor(state, norm_angle(theta_e + M_PI * (2. / 3.))); voltages[EA] = max_bemf * calc_bemf_factor(state, norm_angle(theta_e));
voltages[EC] = max_bemf*calc_bemf_factor(state, norm_angle(theta_e + M_PI * (4. / 3.))); voltages[EB] = max_bemf * calc_bemf_factor(state, norm_angle(theta_e + M_PI * (2. / 3.)));
voltages[EC] = max_bemf * calc_bemf_factor(state, norm_angle(theta_e + M_PI * (4. / 3.)));
} }
void BLDC::calc_voltages() {
void BLDC::calc_voltages(){
const double NaN = nan(""); const double NaN = nan("");
/* Check which phases are excited. */ /* Check which phases are excited. */
bool pa = isnan(vin[0])?false:true; bool pa = isnan(vin[0]) ? false : true;
bool pb = isnan(vin[1])?false:true; bool pb = isnan(vin[1]) ? false : true;
bool pc = isnan(vin[2])?false:true; bool pc = isnan(vin[2]) ? false : true;
if (pa && pb && pc) { if (pa && pb && pc) {
voltages[VA] = vin[0]; voltages[VA] = vin[0];
voltages[VB] = vin[1]; voltages[VB] = vin[1];
voltages[VC] = vin[2]; voltages[VC] = vin[2];
voltages[VCENTER] = (voltages[VA] + voltages[VB] + voltages[VC] - voltages[EA] - voltages[EB] - voltages[EC]) / 3.; voltages[VCENTER] =
(voltages[VA] + voltages[VB] + voltages[VC] - voltages[EA] - voltages[EB] - voltages[EC]) / 3.;
} else if (pa && pb) { } else if (pa && pb) {
voltages[VA] = vin[0]; voltages[VA] = vin[0];
voltages[VB] = vin[1]; voltages[VB] = vin[1];
@ -93,19 +116,21 @@ void BLDC::calc_voltages(){
voltages[VB] = voltages[EB]; voltages[VB] = voltages[EB];
voltages[VC] = voltages[EC]; voltages[VC] = voltages[EC];
voltages[VCENTER] = 0; voltages[VCENTER] = 0;
// return;
} }
auto vmax = std::max({pa ? vin[0] : 0, pb ? vin[1] : 0, pc ? vin[2] : 0});
voltages[VCENTER] = vmax / 2;
} }
void BLDC::printToStream(std::ostream& os) const { void BLDC::printToStream(std::ostream &os) const {
os<<state.omega<<";"<<state.theta<<";" os << state.omega << ";" << state.theta << ";" << state.ia << ";" << state.ib << ";" << state.ic << ";"
<<state.ia<<";"<<state.ib<<";"<<state.ic<<";" << voltages[VA] << ";" << voltages[VB] << ";" << voltages[VC] << ";" << voltages[EA] << ";" << voltages[EB]
<<voltages[VA]<<";"<<voltages[VB]<<";"<<voltages[VC]<<";" << ";" << voltages[EC] << ";" << voltages[VCENTER] << ";" << vin[0] << ";" << vin[1] << ";" << vin[2] << ";"
<<voltages[EA]<<";"<<voltages[EB]<<";"<<voltages[EC]<<";"<<voltages[VCENTER]<<";" << etorque;
<<vin[0]<<";"<<vin[1]<<";"<<vin[2]<<";"<<etorque;
} }
void BLDC::rotor_dyn(const StateVector& x_, StateVector& dxdt_, const double t) { void BLDC::rotor_dyn(const StateVector &x_, StateVector &dxdt_, const double t) {
const State x(const_cast<StateVector&>(x_)); const State x(const_cast<StateVector &>(x_));
State dxdt(dxdt_); State dxdt(dxdt_);
double theta_e = state.theta * (config.NbPoles / 2.); double theta_e = state.theta * (config.NbPoles / 2.);
/* Calculate backemf voltages. */ /* Calculate backemf voltages. */
@ -113,18 +138,16 @@ void BLDC::rotor_dyn(const StateVector& x_, StateVector& dxdt_, const double t)
/* Calculate voltages. */ /* Calculate voltages. */
calc_voltages(); calc_voltages();
/* Electromagnetic torque. */ /* Electromagnetic torque. */
// if (x.omega == 0) { // if (x.omega == 0) {
// printf("ERROR: input state vector omega equals 0!!!\n"); // printf("ERROR: input state vector omega equals 0!!!\n");
// throw std::runtime_error("input state vector omega equals 0"); // throw std::runtime_error("input state vector omega equals 0");
// } // }
/* electrical torque */ /* electrical torque */
//etorque = ((voltages[EA] * x.ia) + (voltages[EB] * x.ib) + (voltages[EC] * x.ic)) / x.omega; // etorque = ((voltages[EA] * x.ia) + (voltages[EB] * x.ib) + (voltages[EC] * x.ic)) / x.omega;
// which is equivalent to: // which is equivalent to:
etorque = config.Ke*( etorque = config.Ke * (x.ia * (calc_bemf_factor(state, norm_angle(theta_e))) +
x.ia * (calc_bemf_factor(state, norm_angle(theta_e))) + x.ib * (calc_bemf_factor(state, norm_angle(theta_e + M_PI * (2. / 3.)))) +
x.ib * (calc_bemf_factor(state, norm_angle(theta_e + M_PI * (2. / 3.)))) + x.ic * (calc_bemf_factor(state, norm_angle(theta_e + M_PI * (4. / 3.)))));
x.ic * (calc_bemf_factor(state, norm_angle(theta_e + M_PI * (4. / 3.))))
);
/* Mechanical torque. */ /* Mechanical torque. */
mtorque = ((etorque * (config.NbPoles / 2)) - (config.damping * x.omega) - torque_load); mtorque = ((etorque * (config.NbPoles / 2)) - (config.damping * x.omega) - torque_load);
@ -149,16 +172,17 @@ void BLDC::rotor_dyn(const StateVector& x_, StateVector& dxdt_, const double t)
} }
void BLDC::run(double incr) { void BLDC::run(double incr) {
if(dt>incr) throw std::runtime_error("incr needs to be larger than dt"); if (dt > incr) throw std::runtime_error("incr needs to be larger than dt");
double next_time = current_time+incr; double next_time = current_time + incr;
odeint::integrate_adaptive(make_controlled( 1.0e-10 , 1.0e-6 , stepper_type() ), odeint::integrate_adaptive(
[this]( const StateVector &x , StateVector &dxdt , double t ) {this->rotor_dyn(x, dxdt,t);}, make_controlled(1.0e-10, 1.0e-6, stepper_type()),
stateVector, current_time, next_time, dt); [this](const StateVector &x, StateVector &dxdt, double t) { this->rotor_dyn(x, dxdt, t); }, stateVector,
current_time=next_time; current_time, next_time, dt);
state.theta=norm_angle(state.theta); current_time = next_time;
state.theta = norm_angle(state.theta);
} }
std::ostream& operator <<(std::ostream& os, const BLDC& bldc) { std::ostream &operator<<(std::ostream &os, const BLDC &bldc) {
bldc.printToStream(os); bldc.printToStream(os);
return os; return os;
} }

View File

@ -1,38 +1,38 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: * Contributors:
// eyck@minres.com - initial implementation * eyck@minres.com - initial implementation
// *
// *
//////////////////////////////////////////////////////////////////////////////// *******************************************************************************/
#include "sysc/SiFive/aon.h" #include "sysc/SiFive/aon.h"
@ -48,7 +48,7 @@ aon::aon(sc_core::sc_module_name nm)
, NAMED(erst_n_i) , NAMED(erst_n_i)
, NAMED(lfclkc_o) , NAMED(lfclkc_o)
, NAMED(rst_o) , NAMED(rst_o)
, NAMEDD(aon_regs, regs) { , NAMEDD(regs, aon_regs) {
regs->registerResources(*this); regs->registerResources(*this);
SC_METHOD(clock_cb); SC_METHOD(clock_cb);
sensitive << clk_i; sensitive << clk_i;
@ -56,28 +56,23 @@ aon::aon(sc_core::sc_module_name nm)
sensitive << erst_n_i; sensitive << erst_n_i;
} }
void aon::start_of_simulation() { void aon::start_of_simulation() { rst_o = true; }
rst_o=true;
}
void aon::clock_cb() { void aon::clock_cb() { this->clk = clk_i.read(); }
this->clk = clk_i.read();
}
aon::~aon() {} aon::~aon() {} // NOLINT
void aon::reset_cb() { void aon::reset_cb() {
if (!erst_n_i.read()){ if (!erst_n_i.read()) {
regs->reset_start(); regs->reset_start();
rst_o=true; rst_o = true;
} else { } else {
regs->reset_stop(); regs->reset_stop();
rst_o=false; rst_o = false;
} }
lfclkc_o.write(sc_core::sc_time(1/32768., sc_core::SC_SEC)); lfclkc_o.write(sc_core::sc_time(1 / 32768., sc_core::SC_SEC));
} }
void aon::reset_internal_cb() { void aon::reset_internal_cb() {}
}
} /* namespace sysc */ } /* namespace sysc */

View File

@ -1,46 +1,43 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#include "sysc/SiFive/clint.h" #include "sysc/SiFive/clint.h"
#include "scc/utilities.h"
#include "scc/report.h" #include "scc/report.h"
#include "scc/utilities.h"
#include "sysc/SiFive/gen/clint_regs.h" #include "sysc/SiFive/gen/clint_regs.h"
namespace sysc { namespace sysc {
using namespace sc_core;
const int lfclk_mutiplier = 1 << 12; const int lfclk_mutiplier = 1 << 12;
@ -52,28 +49,29 @@ clint::clint(sc_core::sc_module_name nm)
, NAMED(rst_i) , NAMED(rst_i)
, NAMED(mtime_int_o) , NAMED(mtime_int_o)
, NAMED(msip_int_o) , NAMED(msip_int_o)
, NAMEDD(clint_regs, regs) , NAMEDD(regs, clint_regs)
, cnt_fraction(0) { , cnt_fraction(0) {
regs->registerResources(*this); regs->registerResources(*this);
SC_METHOD(clock_cb); SC_METHOD(clock_cb);
sensitive << tlclk_i<<lfclk_i; sensitive << tlclk_i << lfclk_i;
SC_METHOD(reset_cb); SC_METHOD(reset_cb);
sensitive << rst_i; sensitive << rst_i;
dont_initialize(); dont_initialize();
regs->mtimecmp.set_write_cb([this](scc::sc_register<uint64_t> &reg, uint64_t data) -> bool { regs->mtimecmp.set_write_cb([this](scc::sc_register<uint64_t> &reg, uint64_t data, sc_core::sc_time d) -> bool {
if (!regs->in_reset()) { if (!regs->in_reset()) {
reg.put(data); reg.put(data);
this->update_mtime(); this->update_mtime();
} }
return true; return true;
}); });
regs->mtime.set_read_cb([this](const scc::sc_register<uint64_t> &reg, uint64_t &data) -> bool { regs->mtime.set_read_cb([this](const scc::sc_register<uint64_t> &reg, uint64_t &data, sc_core::sc_time d) -> bool {
this->update_mtime(); this->update_mtime();
data = reg.get(); data = reg.get();
return true; return true;
}); });
regs->mtime.set_write_cb([this](scc::sc_register<uint64_t> &reg, uint64_t data) -> bool { return false; }); regs->mtime.set_write_cb(
regs->msip.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool { [this](scc::sc_register<uint64_t> &reg, uint64_t data, sc_core::sc_time d) -> bool { return false; });
regs->msip.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data, sc_core::sc_time d) -> bool {
reg.put(data); reg.put(data);
msip_int_o.write(regs->r_msip.msip); msip_int_o.write(regs->r_msip.msip);
return true; return true;
@ -89,7 +87,7 @@ void clint::clock_cb() {
update_mtime(); update_mtime();
} }
clint::~clint() {} clint::~clint() = default;
void clint::reset_cb() { void clint::reset_cb() {
if (rst_i.read()) { if (rst_i.read()) {
@ -102,16 +100,18 @@ void clint::reset_cb() {
} }
void clint::update_mtime() { void clint::update_mtime() {
if(clk>SC_ZERO_TIME){ if (clk > SC_ZERO_TIME) {
uint64_t elapsed_clks = (sc_time_stamp()-last_updt)/clk; // get the number of clock periods since last invocation uint64_t elapsed_clks =
last_updt += elapsed_clks*clk; // increment the last_updt timestamp by the number of clocks (sc_time_stamp() - last_updt) / clk; // get the number of clock periods since last invocation
if(elapsed_clks){ // update mtime reg if we have more than 0 elapsed clk periods last_updt += elapsed_clks * clk; // increment the last_updt timestamp by the number of clocks
regs->r_mtime+=elapsed_clks; if (elapsed_clks) { // update mtime reg if we have more than 0 elapsed clk periods
regs->r_mtime += elapsed_clks;
mtime_evt.cancel(); mtime_evt.cancel();
if (regs->r_mtimecmp > 0) if (regs->r_mtimecmp > 0)
if(regs->r_mtimecmp > regs->r_mtime && clk > sc_core::SC_ZERO_TIME) { if (regs->r_mtimecmp > regs->r_mtime && clk > sc_core::SC_ZERO_TIME) {
sc_core::sc_time next_trigger = (clk * lfclk_mutiplier) * (regs->r_mtimecmp - regs->mtime) - cnt_fraction * clk; sc_core::sc_time next_trigger =
LOG(DEBUG)<<"Timer fires at "<< sc_time_stamp()+next_trigger; (clk * lfclk_mutiplier) * (regs->r_mtimecmp - regs->mtime) - cnt_fraction * clk;
SCTRACE() << "Timer fires at " << sc_time_stamp() + next_trigger;
mtime_evt.notify(next_trigger); mtime_evt.notify(next_trigger);
mtime_int_o.write(false); mtime_int_o.write(false);
} else } else

View File

@ -1,9 +1,34 @@
/* /*******************************************************************************
* dcmotor.cpp * Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
* *
* Created on: 25.07.2018 * Redistribution and use in source and binary forms, with or without
* Author: eyck * modification, are permitted provided that the following conditions are met:
*/ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#include "sysc/top/dcmotor.h" #include "sysc/top/dcmotor.h"
#include "scc/utilities.h" #include "scc/utilities.h"
@ -15,54 +40,74 @@ using namespace sc_core;
auto get_config = []() -> BLDC::Config { auto get_config = []() -> BLDC::Config {
BLDC::Config config{}; BLDC::Config config{};
config.Ke=1./4000. ,//0.01; // V/rad/s, = 1/Kv config.Ke = 1. / 4000., // 0.01; // V/rad/s, = 1/Kv
config.R=0.5; // Ohm config.R = 0.5; // Ohm
config.Ke = 0.01;
config.inertia = 0.0005; config.inertia = 0.0005;
config.NbPoles = 2; config.NbPoles = 2;
config.damping = 0.00001; config.damping = 0.00001;
return config; return config;
}; };
dc_motor::dc_motor(const sc_module_name& nm ) dc_motor::dc_motor(const sc_module_name &nm)
: sc_module(nm) : sc_module(nm)
, NAMED(va_i)
, NAMED(vb_i)
, NAMED(vc_i)
, NAMED(va_o)
, NAMED(vb_o)
, NAMED(vc_o)
, NAMED(vcenter_o)
, NAMED(max_integ_step, sc_time(10, SC_US))
, NAMED(load, 0.1)
, bldc_model(get_config()) , bldc_model(get_config())
, bldc_state(bldc_model.getState()) , bldc_state(bldc_model.getState()) {
{
bldc_model.setLoad(0.0001); bldc_model.setLoad(0.0001);
SC_THREAD(thread); SC_THREAD(thread);
} }
dc_motor::~dc_motor() { dc_motor::~dc_motor() = default;
void dc_motor::trace(sc_trace_file *trf) const {
auto &ia = bldc_state.ia;
sc_core::sc_trace(trf, bldc_state.ia, std::string(this->name()) +"." "ia");
sc_core::sc_trace(trf, bldc_state.ib, std::string(this->name()) +"." "ib");
sc_core::sc_trace(trf, bldc_state.ic, std::string(this->name()) +"." "ic");
sc_core::sc_trace(trf, bldc_state.theta, std::string(this->name()) +"." "theta");
sc_core::sc_trace(trf, bldc_state.omega, std::string(this->name()) +"." "omega");
sc_core::sc_trace(trf, vout[0], std::string(this->name()) + "." "va");
sc_core::sc_trace(trf, vout[1], std::string(this->name()) + "." "vb");
sc_core::sc_trace(trf, vout[2], std::string(this->name()) + "." "vc");
sc_core::sc_trace(trf, vout[3], std::string(this->name()) + "." "vcenter");
sc_core::sc_trace(trf, vout[4], std::string(this->name()) + "." "ea");
sc_core::sc_trace(trf, vout[5], std::string(this->name()) + "." "eb");
sc_core::sc_trace(trf, vout[6], std::string(this->name()) + "." "ec");
} }
void dc_motor::trace(sc_trace_file* trf) { void dc_motor::thread() {
auto ia=bldc_state.ia; TRACE_VAR(trf, ia); const auto divider = 10.0;
auto ib=bldc_state.ib; TRACE_VAR(trf, ib);
auto ic=bldc_state.ic; TRACE_VAR(trf, ic);
auto theta=bldc_state.theta; TRACE_VAR(trf, theta);
auto omega=bldc_state.omega; TRACE_VAR(trf, omega);
}
void dc_motor::thread(void) {
wait(SC_ZERO_TIME); wait(SC_ZERO_TIME);
std::array<double, 3> vin{0., 0., 0.}; std::array<double, 3> vin{0., 0., 0.};
const sc_time step(1, SC_US); auto eval_model = [this](std::array<double, 3> vin, const sc_time step) -> std::array<double, 7> {
auto eval_model = [this](std::array<double, 3> vin, const sc_time step)->std::tuple<double, double, double> {
bldc_model.set_input(vin); bldc_model.set_input(vin);
bldc_model.run(step.to_seconds()); bldc_model.run(step.to_seconds());
return bldc_model.get_voltages(); return bldc_model.get_voltages();
}; };
while(true){ while (true) {
vin[0]=va_i.read(); vin[0] = va_i.read();
vin[1]=vb_i.read(); vin[1] = vb_i.read();
vin[2]=vc_i.read(); vin[2] = vc_i.read();
// auto sim_res=std::async(std::launch::async, eval_model, vin, step); // auto sim_res=std::async(std::launch::async, eval_model, vin, step);
wait(step); auto start = sc_time_stamp();
// auto vout=sim_res.get(); wait(max_integ_step, va_i.value_changed_event() | vb_i.value_changed_event() | vc_i.value_changed_event());
auto vout = eval_model(vin, step); auto diff = sc_time_stamp() - start;
va_o=std::get<0>(vout); if (diff.to_seconds() >= bldc_model.dt) {
vb_o=std::get<1>(vout); vout = eval_model(vin, diff); // sim_res.get();
vc_o=std::get<2>(vout); va_o = vout[0] / divider;
vb_o = vout[1] / divider;
vc_o = vout[2] / divider;
vcenter_o = vout[3] / divider;
}
} }
} }

194
platform/src/sysc/fe310.cpp Normal file
View File

@ -0,0 +1,194 @@
/*******************************************************************************
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#include "sysc/SiFive/fe310.h"
namespace sysc {
using namespace sc_core;
using namespace SiFive;
#ifdef HAS_VERILATOR
inline std::unique_ptr<spi> create_spi(sc_module_name nm, bool use_rtl) {
return use_rtl ? spi::create<spi_impl::rtl>("i_qspi1") : spi::create<spi_impl::beh>("i_qspi1");
}
#else
inline std::unique_ptr<spi> create_spi(sc_module_name nm, bool use_rtl) {
return spi::create<spi_impl::beh>("i_qspi1");
}
#endif
fe310::fe310(sc_core::sc_module_name nm)
: sc_core::sc_module(nm)
, NAMED(pins_o, 32)
, NAMED(pins_i, 32)
, NAMED(erst_n)
, NAMED(use_rtl, false)
, NAMEDD(i_core_complex, core_complex)
, NAMEDD(i_router, scc::router<>, e300_plat_t_map.size() + 2, 1)
, NAMEDD(i_uart0, uart)
, NAMEDD(i_uart1, uart)
, NAMEDC(i_qspi0, spi, spi_impl::beh)
, i_qspi1(create_spi("i_qspi1", use_rtl))
, NAMEDC(i_qspi2, spi, spi_impl::beh)
, NAMEDD(i_pwm0, pwm)
, NAMEDD(i_pwm1, pwm)
, NAMEDD(i_pwm2, pwm)
, NAMEDD(i_gpio0, gpio)
, NAMEDD(i_plic, plic)
, NAMEDD(i_aon, aon)
, NAMEDD(i_prci, prci)
, NAMEDD(i_clint, clint)
, NAMEDD(i_mem_qspi, mem_qspi_t)
, NAMEDD(i_mem_ram, mem_ram_t)
, NAMED(s_tlclk)
, NAMED(s_lfclk)
, NAMED(s_rst)
, NAMED(s_mtime_int)
, NAMED(s_msie_int)
, NAMED(s_global_int, 256)
, NAMED(s_local_int, 16)
, NAMED(s_core_int)
, NAMED(s_dummy_sck_i, 16)
, NAMED(s_dummy_sck_o, 16) {
i_core_complex->initiator(i_router->target[0]);
size_t i = 0;
for (const auto &e : e300_plat_t_map) {
i_router->initiator.at(i)(e.target);
i_router->add_target_range(i, e.start, e.size);
i++;
}
i_router->initiator.at(i)(i_mem_qspi->target);
i_router->add_target_range(i, 0x20000000, 512_MB);
i_router->initiator.at(++i)(i_mem_ram->target);
i_router->add_target_range(i, 0x80000000, 128_kB);
i_uart0->clk_i(s_tlclk);
i_uart1->clk_i(s_tlclk);
i_qspi0->clk_i(s_tlclk);
i_qspi1->clk_i(s_tlclk);
i_qspi2->clk_i(s_tlclk);
i_pwm0->clk_i(s_tlclk);
i_pwm1->clk_i(s_tlclk);
i_pwm2->clk_i(s_tlclk);
i_gpio0->clk_i(s_tlclk);
i_plic->clk_i(s_tlclk);
i_aon->clk_i(s_tlclk);
i_aon->lfclkc_o(s_lfclk);
i_prci->hfclk_o(s_tlclk); // clock driver
i_clint->tlclk_i(s_tlclk);
i_clint->lfclk_i(s_lfclk);
i_core_complex->clk_i(s_tlclk);
i_uart0->rst_i(s_rst);
i_uart1->rst_i(s_rst);
i_qspi0->rst_i(s_rst);
i_qspi1->rst_i(s_rst);
i_qspi2->rst_i(s_rst);
i_pwm0->rst_i(s_rst);
i_pwm1->rst_i(s_rst);
i_pwm2->rst_i(s_rst);
i_gpio0->rst_i(s_rst);
i_plic->rst_i(s_rst);
i_aon->rst_o(s_rst);
i_prci->rst_i(s_rst);
i_clint->rst_i(s_rst);
i_core_complex->rst_i(s_rst);
i_aon->erst_n_i(erst_n);
i_clint->mtime_int_o(s_mtime_int);
i_clint->msip_int_o(s_msie_int);
i_plic->global_interrupts_i(s_global_int);
i_plic->core_interrupt_o(s_core_int);
i_core_complex->sw_irq_i(s_msie_int);
i_core_complex->timer_irq_i(s_mtime_int);
i_core_complex->global_irq_i(s_core_int);
i_core_complex->local_irq_i(s_local_int);
pins_i(i_gpio0->pins_i);
i_gpio0->pins_o(pins_o);
i_gpio0->iof0_i[17](i_uart0->tx_o);
i_uart0->rx_i(i_gpio0->iof0_o[16]);
i_uart0->irq_o(s_global_int[3]);
i_gpio0->iof0_i[5](i_qspi1->sck_o);
i_gpio0->iof0_i[3](i_qspi1->mosi_o);
i_qspi1->miso_i(i_gpio0->iof0_o[4]);
i_gpio0->iof0_i[2](i_qspi1->scs_o[0]);
i_gpio0->iof0_i[9](i_qspi1->scs_o[2]);
i_gpio0->iof0_i[10](i_qspi1->scs_o[3]);
i_qspi0->irq_o(s_global_int[5]);
i_qspi1->irq_o(s_global_int[6]);
i_qspi2->irq_o(s_global_int[7]);
s_dummy_sck_i[0](i_uart1->tx_o);
i_uart1->rx_i(s_dummy_sck_o[0]);
i_uart1->irq_o(s_global_int[4]);
i_gpio0->iof1_i[0](i_pwm0->cmpgpio_o[0]);
i_gpio0->iof1_i[1](i_pwm0->cmpgpio_o[1]);
i_gpio0->iof1_i[2](i_pwm0->cmpgpio_o[2]);
i_gpio0->iof1_i[3](i_pwm0->cmpgpio_o[3]);
i_gpio0->iof1_i[10](i_pwm2->cmpgpio_o[0]);
i_gpio0->iof1_i[11](i_pwm2->cmpgpio_o[1]);
i_gpio0->iof1_i[12](i_pwm2->cmpgpio_o[2]);
i_gpio0->iof1_i[13](i_pwm2->cmpgpio_o[3]);
i_gpio0->iof1_i[19](i_pwm1->cmpgpio_o[0]);
i_gpio0->iof1_i[20](i_pwm1->cmpgpio_o[1]);
i_gpio0->iof1_i[21](i_pwm1->cmpgpio_o[2]);
i_gpio0->iof1_i[22](i_pwm1->cmpgpio_o[3]);
i_pwm0->cmpip_o[0](s_global_int[40]);
i_pwm0->cmpip_o[1](s_global_int[41]);
i_pwm0->cmpip_o[2](s_global_int[42]);
i_pwm0->cmpip_o[3](s_global_int[43]);
i_pwm1->cmpip_o[0](s_global_int[44]);
i_pwm1->cmpip_o[1](s_global_int[45]);
i_pwm1->cmpip_o[2](s_global_int[46]);
i_pwm1->cmpip_o[3](s_global_int[47]);
i_pwm2->cmpip_o[0](s_global_int[48]);
i_pwm2->cmpip_o[1](s_global_int[49]);
i_pwm2->cmpip_o[2](s_global_int[50]);
i_pwm2->cmpip_o[3](s_global_int[51]);
for (auto &sock : s_dummy_sck_i) sock.error_if_no_callback = false;
}
} /* namespace sysc */

View File

@ -1,46 +1,45 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#include "sysc/SiFive/gpio.h" #include "sysc/SiFive/gpio.h"
#include "sysc/sc_comm_singleton.h"
#include "scc/report.h" #include "scc/report.h"
#include "scc/utilities.h" #include "scc/utilities.h"
#include "sysc/SiFive/gen/gpio_regs.h" #include "sysc/SiFive/gen/gpio_regs.h"
#include "sysc/sc_comm_singleton.h"
#include <limits>
namespace sysc { namespace sysc {
using namespace sc_core;
using namespace sc_dt;
gpio::gpio(sc_core::sc_module_name nm) gpio::gpio(sc_core::sc_module_name nm)
: sc_core::sc_module(nm) : sc_core::sc_module(nm)
@ -53,95 +52,85 @@ gpio::gpio(sc_core::sc_module_name nm)
, NAMED(iof1_o, 32) , NAMED(iof1_o, 32)
, NAMED(iof0_i, 32) , NAMED(iof0_i, 32)
, NAMED(iof1_i, 32) , NAMED(iof1_i, 32)
, NAMEDD(gpio_regs, regs) , NAMEDD(regs, gpio_regs)
, NAMED(write_to_ws, false){ , NAMED(write_to_ws, false) {
regs->registerResources(*this); regs->registerResources(*this);
SC_METHOD(clock_cb); SC_METHOD(clock_cb);
sensitive << clk_i; sensitive << clk_i;
SC_METHOD(reset_cb); SC_METHOD(reset_cb);
sensitive << rst_i; sensitive << rst_i;
dont_initialize(); dont_initialize();
auto pins_i_cb =[this](unsigned int tag, tlm::tlm_signal_gp<sc_logic>& gp, auto pins_i_cb = [this](unsigned int tag, tlm::tlm_signal_gp<sc_logic> &gp, tlm::tlm_phase &phase,
tlm::tlm_phase& phase, sc_core::sc_time& delay)->tlm::tlm_sync_enum{ sc_core::sc_time &delay) -> tlm::tlm_sync_enum {
this->pin_input(tag, gp, delay); this->pin_input(tag, gp, delay);
return tlm::TLM_COMPLETED; return tlm::TLM_COMPLETED;
}; };
auto i=0U; auto i = 0U;
for(auto& s:pins_i){ for (auto &s : pins_i) {
s.register_nb_transport(pins_i_cb, i); s.register_nb_transport(pins_i_cb, i);
++i; ++i;
} }
auto iof0_i_cb =[this](unsigned int tag, tlm::tlm_signal_gp<bool>& gp, auto iof0_i_cb = [this](unsigned int tag, tlm::tlm_signal_gp<bool> &gp, tlm::tlm_phase &phase,
tlm::tlm_phase& phase, sc_core::sc_time& delay)->tlm::tlm_sync_enum{ sc_core::sc_time &delay) -> tlm::tlm_sync_enum {
last_iof0[tag]=gp.get_value(); last_iof0[tag] = gp.get_value();
this->iof_input(tag, 0, gp, delay); this->iof_input(tag, 0, gp, delay);
return tlm::TLM_COMPLETED; return tlm::TLM_COMPLETED;
}; };
i=0; i = 0;
for(auto& s:iof0_i){ for (auto &s : iof0_i) {
s.register_nb_transport(iof0_i_cb, i); s.register_nb_transport(iof0_i_cb, i);
++i; ++i;
} }
auto iof1_i_cb =[this](unsigned int tag, tlm::tlm_signal_gp<bool>& gp, auto iof1_i_cb = [this](unsigned int tag, tlm::tlm_signal_gp<bool> &gp, tlm::tlm_phase &phase,
tlm::tlm_phase& phase, sc_core::sc_time& delay)->tlm::tlm_sync_enum{ sc_core::sc_time &delay) -> tlm::tlm_sync_enum {
last_iof1[tag]=gp.get_value(); last_iof1[tag] = gp.get_value();
this->iof_input(tag, 1, gp, delay); this->iof_input(tag, 1, gp, delay);
return tlm::TLM_COMPLETED; return tlm::TLM_COMPLETED;
}; };
i=0; i = 0;
for(auto& s:iof1_i){ for (auto &s : iof1_i) {
s.register_nb_transport(iof1_i_cb, i); s.register_nb_transport(iof1_i_cb, i);
++i; ++i;
} }
regs->port.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool { auto update_pins_cb = [this](scc::sc_register<uint32_t> &reg, uint32_t data, sc_core::sc_time d) -> bool {
if (!this->regs->in_reset()) { if (!this->regs->in_reset()) {
auto changed_bits = (reg.get() ^ data);
reg.put(data); reg.put(data);
// read r_ports and update pins_io update_pins(changed_bits);
update_pins();
} }
return true; return true;
}); };
regs->iof_en.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool { regs->port.set_write_cb(update_pins_cb);
if (!this->regs->in_reset()) { regs->output_en.set_write_cb(update_pins_cb);
enable_outputs(data, regs->r_iof_sel); regs->out_xor.set_write_cb(update_pins_cb);
reg.put(data); regs->iof_en.set_write_cb(update_pins_cb);
} regs->iof_sel.set_write_cb(update_pins_cb);
return true;
});
regs->iof_sel.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool {
if (!this->regs->in_reset()) {
enable_outputs(regs->r_iof_en, data);
reg.put(data);
}
return true;
});
} }
gpio::~gpio() {} gpio::~gpio() = default;
void gpio::before_end_of_elaboration() { void gpio::before_end_of_elaboration() {
if(write_to_ws.get_value()) { if (write_to_ws.get_value()) {
LOG(TRACE)<<"Adding WS handler for "<<(std::string{"/ws/"}+name()); SCTRACE() << "Adding WS handler for " << (std::string{"/ws/"} + name());
handler=std::make_shared<WsHandler>(); handler = std::make_shared<WsHandler>();
sc_comm_singleton::inst().registerWebSocketHandler((std::string{"/ws/"}+name()).c_str(), handler); sc_comm_singleton::inst().registerWebSocketHandler((std::string{"/ws/"} + name()).c_str(), handler);
} }
} }
void gpio::reset_cb() { void gpio::reset_cb() {
if (rst_i.read()) if (rst_i.read()) {
regs->reset_start(); regs->reset_start();
else } else {
regs->reset_stop(); regs->reset_stop();
}
update_pins(std::numeric_limits<uint32_t>::max());
} }
void gpio::clock_cb() { void gpio::clock_cb() { this->clk = clk_i.read(); }
this->clk = clk_i.read();
}
tlm::tlm_phase gpio::write_output(tlm::tlm_signal_gp<sc_dt::sc_logic>& gp, size_t i, sc_dt::sc_logic val) { tlm::tlm_phase gpio::write_output(tlm::tlm_signal_gp<sc_dt::sc_logic> &gp, size_t i, sc_dt::sc_logic val) {
sc_core::sc_time delay{SC_ZERO_TIME}; sc_core::sc_time delay{SC_ZERO_TIME};
tlm::tlm_phase phase{ tlm::BEGIN_REQ }; tlm::tlm_phase phase{tlm::BEGIN_REQ};
gp.set_command(tlm::TLM_WRITE_COMMAND); gp.set_command(tlm::TLM_WRITE_COMMAND);
gp.set_response_status(tlm::TLM_OK_RESPONSE); gp.set_response_status(tlm::TLM_OK_RESPONSE);
gp.set_value(val); gp.set_value(val);
@ -149,92 +138,81 @@ tlm::tlm_phase gpio::write_output(tlm::tlm_signal_gp<sc_dt::sc_logic>& gp, size_
return phase; return phase;
} }
void gpio::update_pins() { void gpio::update_pins(uint32_t changed_bits) {
sc_core::sc_inout_rv<32>::data_type out_val; sc_core::sc_inout_rv<32>::data_type out_val;
tlm::tlm_signal_gp<sc_dt::sc_logic> gp;
for(size_t i=0, mask = 1; i<32; ++i, mask<<=1){
if((regs->iof_en&mask == 0) || (iof0_i[i].size()==0 && iof1_i[i].size()==0)){
auto val = regs->r_output_en&mask?
regs->r_port&mask?
sc_dt::Log_1:
sc_dt::Log_0:
sc_dt::Log_Z;
tlm::tlm_phase phase = write_output(gp, i, val);
}
}
}
void gpio::enable_outputs(uint32_t new_iof_en, uint32_t new_iof_sel) {
auto changed_bits = (regs->r_iof_en^new_iof_en) | (regs->r_iof_sel^new_iof_sel);
tlm::tlm_signal_gp<sc_dt::sc_logic> gp; tlm::tlm_signal_gp<sc_dt::sc_logic> gp;
for(size_t i=0, mask=1; i<32; ++i, mask<<=1){ sc_logic val;
if(changed_bits&mask){ for (size_t i = 0, mask = 1; i < 32; ++i, mask <<= 1) {
if(new_iof_en&mask){ if (changed_bits & mask) {
if((regs->r_iof_sel&mask)==0 && iof0_i[i].size()>0){ if ((regs->r_iof_en & mask != 0) && (iof0_i[i].size() == 0 || iof1_i[i].size() == 0)) {
tlm::tlm_phase phase = write_output(gp, i, last_iof0[i]?sc_dt::Log_1:sc_dt::Log_0); if ((regs->r_iof_sel & mask) == 0 && iof0_i[i].size() > 0) {
} else if((regs->r_iof_sel&mask)==1 && iof1_i[i].size()>0) val = last_iof0[i] ? sc_dt::Log_1 : sc_dt::Log_0;
tlm::tlm_phase phase = write_output(gp, i, last_iof1[i]?sc_dt::Log_1:sc_dt::Log_0); } else if ((regs->r_iof_sel & mask) == 1 && iof1_i[i].size() > 0)
val = last_iof1[i] ? sc_dt::Log_1 : sc_dt::Log_0;
} else { } else {
auto val = regs->r_output_en&mask? if (regs->r_output_en & mask)
regs->r_port&mask?sc_dt::Log_1:sc_dt::Log_0: val = regs->r_port & mask ? sc_dt::Log_1 : sc_dt::Log_0;
sc_dt::Log_Z; else
tlm::tlm_phase phase = write_output(gp, i, val); val = sc_dt::Log_Z;
if (regs->r_out_xor & mask) val = ~val;
} }
tlm::tlm_phase phase = write_output(gp, i, val);
} }
} }
} }
void gpio::pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_logic>& gp, sc_core::sc_time& delay) { void gpio::pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_logic> &gp, sc_core::sc_time &delay) {
if(delay>SC_ZERO_TIME){ if (delay > SC_ZERO_TIME) {
wait(delay); wait(delay);
delay=SC_ZERO_TIME; delay = SC_ZERO_TIME;
} }
switch(gp.get_value().value()){ auto mask = 1u << tag;
case sc_dt::Log_1: switch (gp.get_value().value()) {
regs->r_value|=1<<tag; case sc_dt::Log_1:
forward_pin_input(tag, gp); if (regs->r_output_en & mask == 0) regs->r_value |= mask;
break; forward_pin_input(tag, gp);
case sc_dt::Log_0: break;
regs->r_value&=~(1<<tag); case sc_dt::Log_0:
forward_pin_input(tag, gp); if (regs->r_output_en & mask == 0) regs->r_value &= ~mask;
break; forward_pin_input(tag, gp);
} break;
}
} }
void gpio::forward_pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_logic>& gp) { void gpio::forward_pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_logic> &gp) {
const auto mask = 1U<<tag; const auto mask = 1U << tag;
if(regs->iof_en&mask){ if (regs->iof_en & mask) {
auto& socket = regs->iof_sel&mask?iof1_o[tag]:iof0_o[tag]; auto &socket = regs->iof_sel & mask ? iof1_o[tag] : iof0_o[tag];
tlm::tlm_signal_gp<> new_gp; tlm::tlm_signal_gp<> new_gp;
for(size_t i=0; i<socket.size(); ++i){ for (size_t i = 0; i < socket.size(); ++i) {
sc_core::sc_time delay{SC_ZERO_TIME}; sc_core::sc_time delay{SC_ZERO_TIME};
tlm::tlm_phase phase{tlm::BEGIN_REQ}; tlm::tlm_phase phase{tlm::BEGIN_REQ};
new_gp.set_command(tlm::TLM_WRITE_COMMAND); new_gp.set_command(tlm::TLM_WRITE_COMMAND);
new_gp.set_response_status(tlm::TLM_OK_RESPONSE); new_gp.set_response_status(tlm::TLM_OK_RESPONSE);
new_gp.set_value(gp.get_value().value()==sc_dt::Log_1); new_gp.set_value(gp.get_value().value() == sc_dt::Log_1);
new_gp.update_extensions_from(gp); new_gp.update_extensions_from(gp);
socket->nb_transport_fw(new_gp, phase, delay); // we don't care about phase and sync enum socket->nb_transport_fw(new_gp, phase, delay); // we don't care about phase and sync enum
} }
} }
} }
void gpio::iof_input(unsigned int tag, unsigned iof_idx, tlm::tlm_signal_gp<>& gp, sc_core::sc_time& delay) { void gpio::iof_input(unsigned int tag, unsigned iof_idx, tlm::tlm_signal_gp<> &gp, sc_core::sc_time &delay) {
if(delay>SC_ZERO_TIME){ if (delay > SC_ZERO_TIME) {
wait(delay); wait(delay);
delay=SC_ZERO_TIME; delay = SC_ZERO_TIME;
} }
const auto mask = 1U<<tag; const auto mask = 1U << tag;
if(regs->r_iof_en&mask){ if (regs->r_iof_en & mask) {
const auto idx = regs->r_iof_sel&mask?1:0; const auto idx = regs->r_iof_sel & mask ? 1 : 0;
if(iof_idx == idx){ if (iof_idx == idx) {
auto& socket = pins_o[tag]; auto &socket = pins_o[tag];
for(size_t i=0; i<socket.size(); ++i){ for (size_t i = 0; i < socket.size(); ++i) {
sc_core::sc_time delay{SC_ZERO_TIME}; sc_core::sc_time delay{SC_ZERO_TIME};
tlm::tlm_phase phase{tlm::BEGIN_REQ}; tlm::tlm_phase phase{tlm::BEGIN_REQ};
tlm::tlm_signal_gp<sc_logic> new_gp; tlm::tlm_signal_gp<sc_logic> new_gp;
new_gp.set_command(tlm::TLM_WRITE_COMMAND); new_gp.set_command(tlm::TLM_WRITE_COMMAND);
auto val = gp.get_value(); auto val = gp.get_value();
new_gp.set_value(val?sc_dt::Log_1:sc_dt::Log_0); new_gp.set_value(val ? sc_dt::Log_1 : sc_dt::Log_0);
new_gp.copy_extensions_from(gp); new_gp.copy_extensions_from(gp);
socket->nb_transport_fw(new_gp, phase, delay); // we don't care about phase and sync enum socket->nb_transport_fw(new_gp, phase, delay); // we don't care about phase and sync enum
gp.update_extensions_from(new_gp); gp.update_extensions_from(new_gp);
@ -244,4 +222,3 @@ void gpio::iof_input(unsigned int tag, unsigned iof_idx, tlm::tlm_signal_gp<>& g
} }
} /* namespace sysc */ } /* namespace sysc */

View File

@ -1,18 +1,45 @@
/* /*******************************************************************************
* h_bridge.cpp * Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
* *
* Created on: 25.07.2018 * Redistribution and use in source and binary forms, with or without
* Author: eyck * modification, are permitted provided that the following conditions are met:
*/ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#include "sysc/top/h_bridge.h" #include "sysc/top/h_bridge.h"
#include "scc/utilities.h" #include "scc/utilities.h"
#include <cmath>
namespace sysc { namespace sysc {
using namespace sc_core; using namespace sc_core;
using namespace sc_dt;
h_bridge::h_bridge(const sc_module_name& nm) h_bridge::h_bridge(const sc_module_name &nm)
:sc_module(nm) : sc_module(nm)
, NAMED(ha_i) , NAMED(ha_i)
, NAMED(la_i) , NAMED(la_i)
, NAMED(hb_i) , NAMED(hb_i)
@ -22,26 +49,55 @@ h_bridge::h_bridge(const sc_module_name& nm)
, NAMED(va_o) , NAMED(va_o)
, NAMED(vb_o) , NAMED(vb_o)
, NAMED(vc_o) , NAMED(vc_o)
, NAMED(vcc, 48.0) , NAMED(vcc, 48.0) {
{
SC_METHOD(ain_cb); SC_METHOD(ain_cb);
sensitive<<ha_i<<la_i; sensitive << ha_i << la_i;
SC_METHOD(bin_cb); SC_METHOD(bin_cb);
sensitive<<hb_i<<lb_i; sensitive << hb_i << lb_i;
SC_METHOD(cin_cb); SC_METHOD(cin_cb);
sensitive<<hc_i<<lc_i; sensitive << hc_i << lc_i;
} }
h_bridge::~h_bridge() { h_bridge::~h_bridge() = default;
}
void h_bridge::ain_cb() { void h_bridge::ain_cb() { write_output(ha_i.read(), la_i.read(), va_o); }
}
void h_bridge::bin_cb() { void h_bridge::bin_cb() { write_output(hb_i.read(), lb_i.read(), vb_o); }
}
void h_bridge::cin_cb() { void h_bridge::cin_cb() { write_output(hc_i.read(), lc_i.read(), vc_o); }
void h_bridge::write_output(sc_logic h_i, sc_logic l_i, sc_out<double> &v_o) {
if (h_i == sc_dt::Log_1 && l_i == sc_dt::Log_0)
v_o.write(vcc);
else if (h_i == sc_dt::Log_0 && l_i == sc_dt::Log_1)
v_o.write(0.0);
else
v_o.write(nan(""));
/*
auto v = v_o.read();
if(h_i==Log_1 && l_i==Log_0){
if(isnan(v)){
v_o.write(0.75*vcc);
next_trigger(2, SC_US);
} else
v_o.write(vcc);
} else if(h_i==Log_0 && l_i==Log_1){
if(isnan(v)){
v_o.write(0.25*vcc);
next_trigger(2, SC_US);
} else
v_o.write(0.0);
} else {
if(v_o.read()>0.8*vcc) {
v_o.write(0.75*vcc);
next_trigger(2, SC_US);
} else if(v_o.read()>0.8*vcc) {
v_o.write(0.25*vcc);
next_trigger(2, SC_US);
} else
v_o.write(nan(""));
}
*/
} }
} /* namespace sysc */ } /* namespace sysc */

View File

@ -1,145 +1,111 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#include "sysc/SiFive/hifive1.h" #include <sysc/top/hifive1.h>
namespace sysc { using namespace sc_core;
using namespace sc_dt;
using namespace sysc;
hifive1::hifive1(sc_core::sc_module_name nm) hifive1::hifive1(sc_module_name nm)
: sc_core::sc_module(nm) : sc_module(nm)
, NAMED(pins_o, 32)
, NAMED(pins_i, 32)
, NAMED(erst_n) , NAMED(erst_n)
, NAMED(i_core_complex) , NAMED(vref_i)
, NAMED(i_router, 12, 1) #define PORT_NAMING(z, n, _) , NAMED(adc_ch##n##_i)
, NAMED(i_uart0) BOOST_PP_REPEAT(8, PORT_NAMING, _)
, NAMED(i_uart1) #undef PORT_NAMING
, NAMED(i_qspi0) , NAMED(ha_o)
, NAMED(i_qspi1) , NAMED(la_o)
, NAMED(i_qspi2) , NAMED(hb_o)
, NAMED(i_gpio0) , NAMED(lb_o)
, NAMED(i_plic) , NAMED(hc_o)
, NAMED(i_aon) , NAMED(lc_o)
, NAMED(i_prci) , NAMED(s_gpio, 32)
, NAMED(i_clint) , NAMED(h_bridge, 6)
, NAMED(i_mem_qspi) , NAMED(i_fe310)
, NAMED(i_mem_ram) , NAMED(i_terminal)
, NAMED(s_tlclk) , NAMED(i_adc)
, NAMED(s_rst)
, NAMED(s_global_int, 256)
, NAMED(s_local_int, 16)
, NAMED(s_core_int)
, NAMED(s_dummy, 16)
, NAMED(s_dummy_sck_i, 16)
, NAMED(s_dummy_sck_o, 16)
{ {
i_core_complex.initiator(i_router.target[0]); i_fe310.erst_n(erst_n);
size_t i = 0; for (auto i = 0U; i < s_gpio.size(); ++i) {
for (const auto &e : e300_plat_map) { s_gpio[i].in(i_fe310.pins_o[i]);
i_router.initiator.at(i)(e.target->socket); i_fe310.pins_i[i](s_gpio[i].out);
i_router.add_target_range(i, e.start, e.size);
i++;
} }
i_router.initiator.at(i)(i_mem_qspi.target); // connect other units
i_router.add_target_range(i, 0x20000000, 512_MB); // terminal
i_router.initiator.at(++i)(i_mem_ram.target); i_terminal.tx_o(s_gpio[16].in);
i_router.add_target_range(i, 0x80000000, 128_kB); s_gpio[17].out(i_terminal.rx_i);
// adc digital io
s_gpio[2].out(i_adc.cs_i);
s_gpio[3].out(i_adc.mosi_i);
i_adc.miso_o(s_gpio[4].in);
s_gpio[5].out(i_adc.sck_i);
// adc analog inputs
i_adc.vref_i(vref_i);
i_adc.ch_i[0](adc_ch0_i);
i_adc.ch_i[1](adc_ch1_i);
i_adc.ch_i[2](adc_ch2_i);
i_adc.ch_i[3](adc_ch3_i);
i_adc.ch_i[4](adc_ch4_i);
i_adc.ch_i[5](adc_ch5_i);
i_adc.ch_i[6](adc_ch6_i);
i_adc.ch_i[7](adc_ch7_i);
// H-Bridge signal proxies
s_gpio[0].out(h_bridge[0]);
s_gpio[1].out(h_bridge[1]);
s_gpio[10].out(h_bridge[2]);
s_gpio[11].out(h_bridge[3]);
s_gpio[20].out(h_bridge[4]);
s_gpio[19].out(h_bridge[5]);
// proxy callbacks
h_bridge[0].register_nb_transport([this](tlm::tlm_signal_gp<sc_logic> &gp, tlm::tlm_phase &phase, sc_time &delay) -> tlm::tlm_sync_enum {
ha_o.write(gp.get_value());
});
h_bridge[1].register_nb_transport([this](tlm::tlm_signal_gp<sc_logic> &gp, tlm::tlm_phase &phase, sc_time &delay) -> tlm::tlm_sync_enum {
la_o.write(gp.get_value());
});
h_bridge[2].register_nb_transport([this](tlm::tlm_signal_gp<sc_logic> &gp, tlm::tlm_phase &phase, sc_time &delay) -> tlm::tlm_sync_enum {
hb_o.write(gp.get_value());
});
h_bridge[3].register_nb_transport([this](tlm::tlm_signal_gp<sc_logic> &gp, tlm::tlm_phase &phase, sc_time &delay) -> tlm::tlm_sync_enum {
lb_o.write(gp.get_value());
});
h_bridge[4].register_nb_transport([this](tlm::tlm_signal_gp<sc_logic> &gp, tlm::tlm_phase &phase, sc_time &delay) -> tlm::tlm_sync_enum {
hc_o.write(gp.get_value());
});
h_bridge[5].register_nb_transport([this](tlm::tlm_signal_gp<sc_logic> &gp, tlm::tlm_phase &phase, sc_time &delay) -> tlm::tlm_sync_enum {
lc_o.write(gp.get_value());
});
i_uart0.clk_i(s_tlclk);
i_uart1.clk_i(s_tlclk);
i_qspi0.clk_i(s_tlclk);
i_qspi1.clk_i(s_tlclk);
i_qspi2.clk_i(s_tlclk);
i_gpio0.clk_i(s_tlclk);
i_plic.clk_i(s_tlclk);
i_aon.clk_i(s_tlclk);
i_aon.lfclkc_o(s_lfclk);
i_prci.hfclk_o(s_tlclk); // clock driver
i_clint.tlclk_i(s_tlclk);
i_clint.lfclk_i(s_lfclk);
i_core_complex.clk_i(s_tlclk);
i_uart0.rst_i(s_rst);
i_uart1.rst_i(s_rst);
i_qspi0.rst_i(s_rst);
i_qspi1.rst_i(s_rst);
i_qspi2.rst_i(s_rst);
i_gpio0.rst_i(s_rst);
i_plic.rst_i(s_rst);
i_aon.rst_o(s_rst);
i_prci.rst_i(s_rst);
i_clint.rst_i(s_rst);
i_core_complex.rst_i(s_rst);
i_aon.erst_n_i(erst_n);
i_clint.mtime_int_o(s_mtime_int);
i_clint.msip_int_o(s_msie_int);
i_plic.global_interrupts_i(s_global_int);
i_plic.core_interrupt_o(s_core_int);
i_core_complex.sw_irq_i(s_msie_int);
i_core_complex.timer_irq_i(s_mtime_int);
i_core_complex.global_irq_i(s_core_int);
i_core_complex.local_irq_i(s_local_int);
pins_i(i_gpio0.pins_i);
i_gpio0.pins_o(pins_o);
i_gpio0.iof0_i[17](i_uart0.tx_o);
i_uart0.rx_i(i_gpio0.iof0_o[16]);
i_uart0.irq_o(s_global_int[3]);
i_gpio0.iof0_i[2](i_qspi1.scs_o[0]);
i_gpio0.iof0_i[3](i_qspi1.mosi_o);
i_qspi1.miso_i(i_gpio0.iof0_o[4]);
i_gpio0.iof0_i[5](i_qspi1.sck_o);
i_gpio0.iof0_i[9](i_qspi1.scs_o[2]);
i_gpio0.iof0_i[10](i_qspi1.scs_o[3]);
i_qspi0.irq_o(s_global_int[5]);
i_qspi1.irq_o(s_global_int[6]);
i_qspi2.irq_o(s_global_int[7]);
s_dummy_sck_i[0](i_uart1.tx_o);
i_uart1.rx_i(s_dummy_sck_o[0]);
i_uart1.irq_o(s_global_int[4]);
for(auto& sock:s_dummy_sck_i) sock.error_if_no_callback=false;
} }
} /* namespace sysc */

View File

@ -1,86 +0,0 @@
/*
* mcp3008.cpp
*
* Created on: 17.07.2018
* Author: eyck
*/
#include "sysc/top/mcp3008.h"
#include <scc/report.h>
#include <util/ities.h>
namespace sysc {
mcp3008::mcp3008(sc_core::sc_module_name nm)
: sc_core::sc_module(nm)
, NAMED(sck_i)
, NAMED(miso_o)
, NAMED(mosi_i)
, NAMED(cs_i)
, NAMED(vref_i)
, NAMED(ch_i, 8)
, last_tx_start(sc_core::SC_ZERO_TIME)
{
sck_i.register_nb_transport([this](tlm::tlm_signal_gp<sc_dt::sc_logic>& gp, tlm::tlm_phase& phase, sc_core::sc_time& delay)
-> tlm::tlm_sync_enum{
return tlm::TLM_COMPLETED;
});
mosi_i.register_nb_transport([this](tlm::tlm_signal_gp<sc_dt::sc_logic>& gp, tlm::tlm_phase& phase, sc_core::sc_time& delay)
-> tlm::tlm_sync_enum{
if(cs_v==sc_dt::Log_0)
return receive(gp, phase, delay);
});
cs_i.register_nb_transport([this](tlm::tlm_signal_gp<sc_dt::sc_logic>& gp, tlm::tlm_phase& phase, sc_core::sc_time& delay)
-> tlm::tlm_sync_enum{
if(cs_v!=sc_dt::Log_0 && gp.get_value()==sc_dt::Log_0){
idx=0; // falling edge
rx_bits=0;
}
cs_v=gp.get_value();
return tlm::TLM_COMPLETED;
});
}
mcp3008::~mcp3008() {
}
tlm::tlm_sync_enum mcp3008::receive(tlm::tlm_signal_gp<sc_dt::sc_logic>& gp, tlm::tlm_phase& phase, sc_core::sc_time& delay) {
gp.get_extension(ext);
if(ext){
if( ext->start_time!=last_tx_start){
assert(ext->tx.data_bits==8);
rx_bytes[idx]=bit_sub<0,8>(ext->tx.m2s_data);
if(idx==1)
do_conversion();
ext->tx.s2m_data=tx_bytes[idx];
ext->tx.s2m_data_valid=true;
idx++;
last_tx_start=ext->start_time;
}
}
return tlm::TLM_COMPLETED;
}
void mcp3008::do_conversion() {
if(rx_bytes[0]==0x1){
auto mode = bit_sub<7,1>(rx_bytes[1]);
auto channel = bit_sub<4,3>(rx_bytes[1]);
auto vref=vref_i.read();
if(mode){ // single ended
auto inp = ch_i[channel].read();
auto norm = inp/vref*1024.0;
auto res = static_cast<int>(norm);
CLOG(DEBUG, SystemC)<<"Converting "<<inp<<" to "<<norm<<" as int "<<res;
tx_bytes[1]=bit_sub<8,2>(res);
tx_bytes[2]=bit_sub<0,8>(res);
} else {
tx_bytes[1]=0;
tx_bytes[2]=0;
}
}
}
} /* namespace sysc */

View File

@ -0,0 +1,202 @@
/*******************************************************************************
* Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#include <scc/report.h>
#include <sysc/top/mcp_adc.h>
#include <util/ities.h>
namespace sysc {
mcp_3008::mcp_3008(sc_core::sc_module_name nm)
: sysc::mcp_adc(nm, 8)
, last_tx_start(sc_core::SC_ZERO_TIME) {
sck_i.register_nb_transport([this](tlm::tlm_signal_gp<sc_dt::sc_logic> &gp, tlm::tlm_phase &phase,
sc_core::sc_time &delay) -> tlm::tlm_sync_enum { return tlm::TLM_COMPLETED; });
mosi_i.register_nb_transport([this](tlm::tlm_signal_gp<sc_dt::sc_logic> &gp, tlm::tlm_phase &phase,
sc_core::sc_time &delay) -> tlm::tlm_sync_enum {
if (cs_v == sc_dt::Log_0) return receive(gp, phase, delay);
return tlm::TLM_COMPLETED;
});
cs_i.register_nb_transport([this](tlm::tlm_signal_gp<sc_dt::sc_logic> &gp, tlm::tlm_phase &phase,
sc_core::sc_time &delay) -> tlm::tlm_sync_enum {
if (cs_v != sc_dt::Log_0 && gp.get_value() == sc_dt::Log_0) {
idx = 0; // falling edge
rx_bits = 0;
}
cs_v = gp.get_value();
return tlm::TLM_COMPLETED;
});
}
tlm::tlm_sync_enum mcp_3008::receive(tlm::tlm_signal_gp<sc_dt::sc_logic> &gp, tlm::tlm_phase &phase,
sc_core::sc_time &delay) {
gp.get_extension(ext);
if (ext) {
if (ext->start_time != last_tx_start) {
assert(ext->tx.data_bits == 8);
rx_bytes[idx] = bit_sub<0, 8>(ext->tx.m2s_data);
if (idx == 1) do_conversion();
ext->tx.s2m_data = tx_bytes[idx];
ext->tx.s2m_data_valid = true;
idx++;
last_tx_start = ext->start_time;
}
}
return tlm::TLM_COMPLETED;
}
void mcp_3008::do_conversion() {
if (rx_bytes[0] == 0x1) {
auto mode = bit_sub<7, 1>(rx_bytes[1]);
auto channel = bit_sub<4, 3>(rx_bytes[1]);
auto vref = vref_i.read();
if (mode) { // single ended
auto inp = ch_i[channel].read();
auto norm = 1024.0 * inp / vref;
auto res = static_cast<int>(norm);
SCDEBUG(this->name()) << "Converting " << inp << " to " << norm << " as int " << res;
tx_bytes[1] = bit_sub<8, 2>(res);
tx_bytes[2] = bit_sub<0, 8>(res);
} else {
tx_bytes[1] = 0;
tx_bytes[2] = 0;
}
}
}
mcp_3208::mcp_3208(sc_core::sc_module_name nm)
: sysc::mcp_adc(nm, 8)
, ext(nullptr)
, last_tx_start(sc_core::SC_ZERO_TIME) {
sck_i.register_nb_transport([this](tlm::tlm_signal_gp<sc_dt::sc_logic> &gp, tlm::tlm_phase &phase,
sc_core::sc_time &delay) -> tlm::tlm_sync_enum {
auto ret = tlm::TLM_COMPLETED;
if (cs_v == sc_dt::Log_0) ret = receive(gp, phase, delay);
sck_v = gp.get_value();
return ret;
});
mosi_i.register_nb_transport([this](tlm::tlm_signal_gp<sc_dt::sc_logic> &gp, tlm::tlm_phase &phase,
sc_core::sc_time &delay) -> tlm::tlm_sync_enum {
mosi_v = gp.get_value();
return tlm::TLM_COMPLETED;
});
cs_i.register_nb_transport([this](tlm::tlm_signal_gp<sc_dt::sc_logic> &gp, tlm::tlm_phase &phase,
sc_core::sc_time &delay) -> tlm::tlm_sync_enum {
if (cs_v != sc_dt::Log_0 && gp.get_value() == sc_dt::Log_0) { // falling edge of CS
idx = 0;
rx_bits = byte_offs = 0;
bit_offs = 7;
}
cs_v = gp.get_value();
return tlm::TLM_COMPLETED;
});
SC_METHOD(sample_inputs);
sensitive << clk_sample_evt;
}
tlm::tlm_sync_enum mcp_3208::receive(tlm::tlm_signal_gp<sc_dt::sc_logic> &gp, tlm::tlm_phase &phase,
sc_core::sc_time &delay) {
gp.get_extension(ext);
if (ext) {
if (ext->start_time != last_tx_start) {
assert(ext->tx.data_bits == 8);
if (ext->tx.m2s_data_valid) {
rx_bytes[idx] = bit_sub<0, 8>(ext->tx.m2s_data);
if (idx == 1) do_conversion();
ext->tx.s2m_data = tx_bytes[idx];
ext->tx.s2m_data_valid = true;
last_tx_start = ext->start_time;
idx++;
}
}
} else if (gp.get_value() == sc_dt::SC_LOGIC_1 && sck_v == sc_dt::SC_LOGIC_0) // sample an rising edge
clk_sample_evt.notify(sc_core::SC_ZERO_TIME);
return tlm::TLM_COMPLETED;
}
void mcp_3208::sample_inputs() {
if (byte_offs >= 3) return;
if (bit_offs == 7) {
rx_bytes[byte_offs] = 0;
if (byte_offs == 0) tx_bytes[0] = tx_bytes[1] = tx_bytes[2] = 0;
}
auto mask = 1 << bit_offs;
if (mosi_v == sc_dt::SC_LOGIC_1) rx_bytes[byte_offs] |= mask;
miso_o.write_now(tx_bytes[byte_offs] & mask ? sc_dt::SC_LOGIC_1 : sc_dt::SC_LOGIC_0);
// increment counters
if (bit_offs == 0) {
bit_offs = 7;
byte_offs++;
} else
bit_offs--;
// sample if in the middle of second byte
if (byte_offs == 1 && bit_offs == 4) do_conversion();
}
void mcp_3208::do_conversion() {
if (rx_bytes[0] & 0x4) {
auto mode = bit_sub<1, 1>(rx_bytes[0]);
auto channel = bit_sub<0, 1>(rx_bytes[0]) * 4 + bit_sub<6, 2>(rx_bytes[1]);
auto vref = vref_i.read();
if (mode) { // single ended
auto inp = ch_i[channel].read();
auto norm = 4096.0 * inp / vref;
auto res = static_cast<int>(norm);
SCDEBUG(this->name()) << "Converting channel " << channel << " " << inp << "V to " << norm << " as int "
<< res;
tx_bytes[1] = bit_sub<8, 4>(res);
tx_bytes[2] = bit_sub<0, 8>(res);
} else {
tx_bytes[1] = 0;
tx_bytes[2] = 0;
}
}
}
template <>
std::unique_ptr<mcp_adc> mcp_adc::create<mcp_3008>(sc_core::sc_module_name nm) {
auto *res = new mcp_3008(nm);
return std::unique_ptr<mcp_adc>(res);
}
template <>
std::unique_ptr<mcp_adc> mcp_adc::create<mcp_3208>(sc_core::sc_module_name nm) {
auto *res = new mcp_3208(nm);
return std::unique_ptr<mcp_adc>(res);
}
} /* namespace sysc */

View File

@ -1,43 +1,39 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#include <sysc/SiFive/plic.h> #include <sysc/SiFive/plic.h>
#include <scc/utilities.h>
#include <scc/report.h> #include <scc/report.h>
#include <scc/utilities.h>
#include <sysc/SiFive/gen/plic_regs.h> #include <sysc/SiFive/gen/plic_regs.h>
namespace sysc { namespace sysc {
@ -49,13 +45,18 @@ plic::plic(sc_core::sc_module_name nm)
, NAMED(rst_i) , NAMED(rst_i)
, NAMED(global_interrupts_i, 256) , NAMED(global_interrupts_i, 256)
, NAMED(core_interrupt_o) , NAMED(core_interrupt_o)
, NAMEDD(plic_regs, regs) , NAMEDD(regs, plic_regs)
{ {
regs->registerResources(*this); regs->registerResources(*this);
// register callbacks // register callbacks
init_callbacks(); regs->claim_complete.set_write_cb([this](scc::sc_register<uint32_t> reg, uint32_t v, sc_core::sc_time d) -> bool {
regs->claim_complete.set_write_cb(m_claim_complete_write_cb); reg.put(v);
reset_pending_int(v);
// std::cout << "Value of register: 0x" << std::hex << reg << std::endl;
// todo: reset related interrupt and find next high-prio interrupt
return true;
});
// port callbacks // port callbacks
SC_METHOD(global_int_port_cb); SC_METHOD(global_int_port_cb);
@ -72,21 +73,9 @@ plic::plic(sc_core::sc_module_name nm)
dont_initialize(); dont_initialize();
} }
plic::~plic() {} plic::~plic() {}// NOLINT
void plic::init_callbacks() { void plic::clock_cb() { this->clk = clk_i.read(); }
m_claim_complete_write_cb = [=](scc::sc_register<uint32_t> reg, uint32_t v) -> bool {
reg.put(v);
reset_pending_int(v);
// std::cout << "Value of register: 0x" << std::hex << reg << std::endl;
// todo: reset related interrupt and find next high-prio interrupt
return true;
};
}
void plic::clock_cb() {
this->clk = clk_i.read();
}
void plic::reset_cb() { void plic::reset_cb() {
if (rst_i.read()) if (rst_i.read())
@ -112,67 +101,67 @@ void plic::reset_cb() {
// - complete-reg write register content // - complete-reg write register content
void plic::global_int_port_cb() { void plic::global_int_port_cb() {
auto handle_pending = false;
// set related pending bit if enable is set for incoming global_interrupt // set related pending bit if enable is set for incoming global_interrupt
for (uint32_t i = 1; i < 256; i++) { for (uint32_t i = 1; i < 256; i++) {
auto reg_idx = i>>5; auto reg_idx = i >> 5;
auto bit_ofs = i & 0x1F; auto bit_ofs = i & 0x1F;
bool enable = regs->r_enabled[reg_idx] & (0x1 << bit_ofs); // read enable bit bool enable = regs->r_enabled[reg_idx] & (0x1 << bit_ofs); // read enable bit
if (enable && global_interrupts_i[i].read() == 1) { if (enable && global_interrupts_i[i].read() == 1) {
regs->r_pending[reg_idx] = regs->r_pending[reg_idx] | (0x1 << bit_ofs); regs->r_pending[reg_idx] = regs->r_pending[reg_idx] | (0x1 << bit_ofs);
LOG(DEBUG) << "pending interrupt identified: " << i; handle_pending = true;
SCDEBUG(this->name()) << "pending interrupt identified: " << i;
} }
} }
handle_pending_int(); if (handle_pending) handle_pending_int();
} }
void plic::handle_pending_int() { void plic::handle_pending_int() {
// identify high-prio pending interrupt and raise a core-interrupt // identify high-prio pending interrupt and raise a core-interrupt
uint32_t claim_int = 0; // claim interrupt auto claim_int = 0U; // claim interrupt
uint32_t claim_prio = 0; // related priority (highest prio interrupt wins the race) auto claim_prio = 0U; // related priority (highest prio interrupt wins the race)
bool raise_int = 0; auto raise_int = false;
uint32_t thold = regs->r_threshold.threshold; // threshold value auto thold = regs->r_threshold.threshold; // threshold value
for (uint32_t i = 1; i < 255; i++) { for (size_t i = 1; i < 255; i++) {
auto reg_idx = i>>5; auto reg_idx = i >> 5;
auto bit_ofs = i & 0x1F; auto bit_ofs = i & 0x1F;
bool pending = (regs->r_pending[reg_idx] & (0x1 << bit_ofs)) ? true : false; bool pending = (regs->r_pending[reg_idx] & (0x1 << bit_ofs)) ? true : false;
uint32_t prio = regs->r_priority[i - 1].priority; // read priority value auto prio = regs->r_priority[i].priority; // read priority value
if (pending && thold < prio) { if (pending && thold < prio) {
regs->r_pending[reg_idx] = regs->r_pending[reg_idx] | (0x1 << bit_ofs);
// below condition ensures implicitly that lowest id is selected in case of multiple identical // below condition ensures implicitly that lowest id is selected in case of multiple identical
// priority-interrupts // priority-interrupts
if (prio > claim_prio) { if (prio > claim_prio) {
claim_prio = prio; claim_prio = prio;
claim_int = i; claim_int = i;
raise_int = 1; raise_int = true;
LOG(DEBUG) << "pending interrupt activated: " << i; SCDEBUG(this->name()) << "pending interrupt activated: " << i;
} }
} }
} }
if (raise_int) { if (raise_int) {
regs->r_claim_complete = claim_int; regs->r_claim_complete = claim_int;
core_interrupt_o.write(1); core_interrupt_o.write(true);
// todo: evluate clock period // todo: evluate clock period
} else { } else {
regs->r_claim_complete = 0; regs->r_claim_complete = 0;
LOG(DEBUG) << "no further pending interrupt."; SCDEBUG(this->name()) << "no further pending interrupt.";
} }
} }
void plic::reset_pending_int(uint32_t irq) { void plic::reset_pending_int(uint32_t irq) {
// todo: evaluate enable register (see spec) // todo: evaluate enable register (see spec)
// todo: make sure that pending is set, otherwise don't reset irq ... read spec. // todo: make sure that pending is set, otherwise don't reset irq ... read spec.
LOG(TRACE) << "reset pending interrupt: " << irq; SCTRACE(this->name()) << "reset pending interrupt: " << irq;
// reset related pending bit // reset related pending bit
auto reg_idx = irq>>5; auto reg_idx = irq >> 5;
auto bit_ofs = irq & 0x1F; auto bit_ofs = irq & 0x1F;
regs->r_pending[reg_idx] &= ~(0x1 << bit_ofs); regs->r_pending[reg_idx] &= ~(0x1 << bit_ofs);
core_interrupt_o.write(0); core_interrupt_o.write(false);
// evaluate next pending interrupt // evaluate next pending interrupt
handle_pending_int(); handle_pending_int();

View File

@ -1,38 +1,34 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#include "sysc/SiFive/prci.h" #include "sysc/SiFive/prci.h"
@ -40,13 +36,14 @@
#include "sysc/SiFive/gen/prci_regs.h" #include "sysc/SiFive/gen/prci_regs.h"
namespace sysc { namespace sysc {
using namespace sc_core;
prci::prci(sc_core::sc_module_name nm) prci::prci(sc_core::sc_module_name nm)
: sc_core::sc_module(nm) : sc_core::sc_module(nm)
, tlm_target<>(hfclk) , tlm_target<>(hfclk)
, NAMED(rst_i) , NAMED(rst_i)
, NAMED(hfclk_o) , NAMED(hfclk_o)
, NAMEDD(prci_regs, regs) { , NAMEDD(regs, prci_regs) {
regs->registerResources(*this); regs->registerResources(*this);
SC_METHOD(reset_cb); SC_METHOD(reset_cb);
sensitive << rst_i; sensitive << rst_i;
@ -57,25 +54,25 @@ prci::prci(sc_core::sc_module_name nm)
sensitive << hfrosc_en_evt; sensitive << hfrosc_en_evt;
dont_initialize(); dont_initialize();
regs->hfxosccfg.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool { regs->hfxosccfg.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data, sc_core::sc_time d) -> bool {
reg.put(data); reg.put(data);
if (this->regs->r_hfxosccfg.hfxoscen==1) { // check rosc_en if (this->regs->r_hfxosccfg.hfxoscen == 1) { // check rosc_en
this->hfxosc_en_evt.notify(1, sc_core::SC_US); this->hfxosc_en_evt.notify(1, sc_core::SC_US);
} else { } else {
this->hfxosc_en_evt.notify(SC_ZERO_TIME); this->hfxosc_en_evt.notify(SC_ZERO_TIME);
} }
return true; return true;
}); });
regs->hfrosccfg.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool { regs->hfrosccfg.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data, sc_core::sc_time d) -> bool {
reg.put(data); reg.put(data);
if (this->regs->r_hfrosccfg.hfroscen==1) { // check rosc_en if (this->regs->r_hfrosccfg.hfroscen == 1) { // check rosc_en
this->hfrosc_en_evt.notify(1, sc_core::SC_US); this->hfrosc_en_evt.notify(1, sc_core::SC_US);
} else { } else {
this->hfrosc_en_evt.notify(SC_ZERO_TIME); this->hfrosc_en_evt.notify(SC_ZERO_TIME);
} }
return true; return true;
}); });
regs->pllcfg.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool { regs->pllcfg.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data, sc_core::sc_time d) -> bool {
reg.put(data); reg.put(data);
auto &pllcfg = this->regs->r_pllcfg; auto &pllcfg = this->regs->r_pllcfg;
if (pllcfg.pllbypass == 0 && pllcfg.pllq != 0) { // set pll_lock if pll is selected if (pllcfg.pllbypass == 0 && pllcfg.pllq != 0) { // set pll_lock if pll is selected
@ -84,15 +81,15 @@ prci::prci(sc_core::sc_module_name nm)
update_hfclk(); update_hfclk();
return true; return true;
}); });
regs->plloutdiv.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool { regs->plloutdiv.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data, sc_core::sc_time d) -> bool {
reg.put(data); reg.put(data);
update_hfclk(); update_hfclk();
return true; return true;
}); });
hfxosc_clk=62.5_ns; hfxosc_clk = 62.5_ns;
} }
prci::~prci() {} prci::~prci() = default;
void prci::reset_cb() { void prci::reset_cb() {
if (rst_i.read()) if (rst_i.read())
@ -104,41 +101,42 @@ void prci::reset_cb() {
} }
void prci::hfxosc_cb() { void prci::hfxosc_cb() {
this->regs->r_hfxosccfg.hfxoscrdy=0; this->regs->r_hfxosccfg.hfxoscrdy = 0;
this->hfxosc_en_evt.notify(1, sc_core::SC_US); this->hfxosc_en_evt.notify(1, sc_core::SC_US);
} }
void prci::hfxosc_en_cb() { void prci::hfxosc_en_cb() {
update_hfclk(); update_hfclk();
if(regs->r_hfxosccfg.hfxoscen==1)// set rosc_rdy if (regs->r_hfxosccfg.hfxoscen == 1) // set rosc_rdy
regs->r_hfxosccfg.hfxoscrdy =1; regs->r_hfxosccfg.hfxoscrdy = 1;
else else
regs->r_hfxosccfg.hfxoscrdy =0; regs->r_hfxosccfg.hfxoscrdy = 0;
} }
void prci::hfrosc_en_cb() { void prci::hfrosc_en_cb() {
update_hfclk(); update_hfclk();
auto& hfrosccfg=regs->r_hfrosccfg; auto &hfrosccfg = regs->r_hfrosccfg;
if(regs->r_hfrosccfg.hfroscen==1) {// set rosc_rdy if (regs->r_hfrosccfg.hfroscen == 1) { // set rosc_rdy
regs->r_hfrosccfg.hfroscrdy =1; regs->r_hfrosccfg.hfroscrdy = 1;
} else { } else {
regs->r_hfrosccfg.hfroscrdy =0; regs->r_hfrosccfg.hfroscrdy = 0;
} }
} }
void prci::update_hfclk() { void prci::update_hfclk() {
auto& hfrosccfg=regs->r_hfrosccfg; auto &hfrosccfg = regs->r_hfrosccfg;
auto& pllcfg=regs->r_pllcfg; auto &pllcfg = regs->r_pllcfg;
auto& plldiv=regs->r_plloutdiv; auto &plldiv = regs->r_plloutdiv;
hfrosc_clk = sc_core::sc_time(((hfrosccfg.hfroscdiv+1)*1.0)/(1125000.0*(hfrosccfg.hfrosctrim+1)), sc_core::SC_SEC); uint32_t trim = hfrosccfg.hfrosctrim;
auto pll_ref = pllcfg.pllrefsel==1?hfxosc_clk:hfrosc_clk; uint32_t div = hfrosccfg.hfroscdiv;
auto r = pllcfg.pllr+1; hfrosc_clk = sc_core::sc_time(((div + 1) * 1.0) / (70000000 + 12000.0 * trim), sc_core::SC_SEC);
auto f = 2*(pllcfg.pllf+1); auto pll_ref = pllcfg.pllrefsel == 1 ? hfxosc_clk : hfrosc_clk;
auto q = 1<<pllcfg.pllq; auto r = pllcfg.pllr + 1;
auto pll_out = pllcfg.pllbypass==1 || pllcfg.plllock==0?pll_ref:((pll_ref*r)/f)*q; auto f = 2 * (pllcfg.pllf + 1);
auto pll_res = plldiv&0x100?pll_out:2*pll_out*((plldiv&0x3f)+1); auto q = 1 << pllcfg.pllq;
hfclk = pllcfg.pllsel?pll_res:hfrosc_clk; auto pll_out = pllcfg.pllbypass == 1 || pllcfg.plllock == 0 ? pll_ref : ((pll_ref * r) / f) * q;
auto pll_res = plldiv & 0x100 ? pll_out : 2 * pll_out * ((plldiv & 0x3f) + 1);
hfclk = pllcfg.pllsel ? pll_res : hfrosc_clk;
hfclk_o.write(hfclk); hfclk_o.write(hfclk);
} }

231
platform/src/sysc/pwm.cpp Normal file
View File

@ -0,0 +1,231 @@
/*******************************************************************************
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#include "sysc/SiFive/pwm.h"
#include "scc/utilities.h"
#include "sysc/SiFive/gen/pwm_regs.h"
using namespace sysc;
using namespace sc_core;
pwm::pwm(sc_core::sc_module_name nm)
: sc_core::sc_module(nm)
, tlm_target<>(clk)
, NAMED(clk_i)
, NAMED(rst_i)
, NAMED(cmpgpio_o, 4)
, NAMED(cmpip_o, 4)
, NAMEDD(regs, pwm_regs)
, current_cnt(0)
, last_cnt_update() {
regs->registerResources(*this);
regs->pwmcfg.set_write_cb(
[this](const scc::sc_register<uint32_t> &reg, uint32_t &data, sc_core::sc_time d) -> bool {
if (d.value()) wait(d);
reg.put(data);
update_counter();
return true;
});
regs->pwmcount.set_write_cb(
[this](const scc::sc_register<uint32_t> &reg, uint32_t &data, sc_core::sc_time d) -> bool {
if (d.value()) wait(d);
reg.put(data);
update_counter();
current_cnt = data;
clk_remainder = 0.;
return true;
});
regs->pwmcount.set_read_cb([this](const scc::sc_register<uint32_t> &reg, uint32_t &data,
sc_core::sc_time d) -> bool {
auto offset = regs->r_pwmcfg.pwmenalways || regs->r_pwmcfg.pwmenoneshot ? static_cast<int>(get_pulses(d)) : 0;
data = current_cnt + offset;
regs->r_pwmcount.pwmcount = data;
return true;
});
regs->pwms.set_write_cb(
[this](scc::sc_register<uint32_t> &reg, uint32_t data, sc_core::sc_time d) -> bool { return false; });
regs->pwms.set_read_cb([this](const scc::sc_register<uint32_t> &reg, uint32_t &data, sc_core::sc_time d) -> bool {
auto offset = regs->r_pwmcfg.pwmenalways || regs->r_pwmcfg.pwmenoneshot ? static_cast<int>(get_pulses(d)) : 0;
auto cnt = current_cnt + offset;
data = (cnt >> regs->r_pwmcfg.pwmscale) & 0xffff;
regs->r_pwms.pwms = static_cast<uint16_t>(data);
return true;
});
regs->pwmcmp0.set_write_cb(
[this](const scc::sc_register<uint32_t> &reg, uint32_t &data, sc_core::sc_time d) -> bool {
reg.put(data);
update_counter();
return true;
});
regs->pwmcmp1.set_write_cb(
[this](const scc::sc_register<uint32_t> &reg, uint32_t &data, sc_core::sc_time d) -> bool {
reg.put(data);
update_counter();
return true;
});
regs->pwmcmp2.set_write_cb(
[this](const scc::sc_register<uint32_t> &reg, uint32_t &data, sc_core::sc_time d) -> bool {
reg.put(data);
update_counter();
return true;
});
regs->pwmcmp3.set_write_cb(
[this](const scc::sc_register<uint32_t> &reg, uint32_t &data, sc_core::sc_time d) -> bool {
reg.put(data);
update_counter();
return true;
});
SC_METHOD(clock_cb);
sensitive << clk_i;
SC_METHOD(reset_cb);
sensitive << rst_i;
SC_METHOD(update_counter);
sensitive << update_counter_evt;
dont_initialize();
}
void pwm::clock_cb() {
update_counter();
clk = clk_i.read();
}
pwm::~pwm() = default;
void pwm::reset_cb() {
if (rst_i.read()) {
regs->reset_start();
} else {
regs->reset_stop();
}
}
void pwm::update_counter() {
auto now = sc_time_stamp();
if (now == SC_ZERO_TIME) return;
update_counter_evt.cancel();
if (regs->r_pwmcfg.pwmenalways || regs->r_pwmcfg.pwmenoneshot) {
std::array<bool, 4> pwmcmp_new_ip{false, false, false, false};
auto dpulses = get_pulses(SC_ZERO_TIME);
auto pulses = static_cast<int>(dpulses);
clk_remainder += dpulses - pulses;
if (clk_remainder > 1) {
pulses++;
clk_remainder -= 1.0;
}
if (reset_cnt) {
current_cnt = 0;
reset_cnt = false;
} else if (last_enable)
current_cnt += pulses;
auto pwms = (current_cnt >> regs->r_pwmcfg.pwmscale) & 0xffff;
auto next_trigger_time =
(0xffff - pwms) * (1 << regs->r_pwmcfg.pwmscale) * clk; // next trigger based on wrap around
if (pwms == 0xffff) { // wrap around calculation
reset_cnt = true;
next_trigger_time = clk;
regs->r_pwmcfg.pwmenoneshot = 0;
}
auto pwms0 = (regs->r_pwmcfg.pwmcmp0center && (pwms & 0x8000) == 1) ? pwms ^ 0xffff : pwms;
if (pwms0 >= regs->r_pwmcmp0.pwmcmp0) {
pwmcmp_new_ip[0] = true;
regs->r_pwmcfg.pwmenoneshot = 0;
if (regs->r_pwmcfg.pwmzerocmp) {
reset_cnt = true;
next_trigger_time = clk;
}
} else {
pwmcmp_new_ip[0] = false;
// TODO: add correct calculation for regs->r_pwmcfg.pwmcmpXcenter==1
auto nt = (regs->r_pwmcmp0.pwmcmp0 - pwms0) * (1 << regs->r_pwmcfg.pwmscale) * clk;
next_trigger_time = nt < next_trigger_time ? nt : next_trigger_time;
}
auto pwms1 = (regs->r_pwmcfg.pwmcmp0center && (pwms & 0x8000) == 1) ? pwms ^ 0xffff : pwms;
if (pwms1 >= regs->r_pwmcmp1.pwmcmp0) {
pwmcmp_new_ip[1] = true;
} else {
pwmcmp_new_ip[1] = false;
// TODO: add correct calculation for regs->r_pwmcfg.pwmcmpXcenter==1
auto nt = (regs->r_pwmcmp0.pwmcmp0 - pwms0) * (1 << regs->r_pwmcfg.pwmscale) * clk;
next_trigger_time = nt < next_trigger_time ? nt : next_trigger_time;
}
auto pwms2 = (regs->r_pwmcfg.pwmcmp0center && (pwms & 0x8000) == 1) ? pwms ^ 0xffff : pwms;
if (pwms2 >= regs->r_pwmcmp2.pwmcmp0) {
pwmcmp_new_ip[2] = true;
} else {
pwmcmp_new_ip[2] = false;
// TODO: add correct calculation for regs->r_pwmcfg.pwmcmpXcenter==1
auto nt = (regs->r_pwmcmp0.pwmcmp0 - pwms0) * regs->r_pwmcfg.pwmscale * clk;
next_trigger_time = nt < next_trigger_time ? nt : next_trigger_time;
}
auto pwms3 = (regs->r_pwmcfg.pwmcmp0center && (pwms & 0x8000) == 1) ? pwms ^ 0xffff : pwms;
if (pwms3 >= regs->r_pwmcmp3.pwmcmp0) {
pwmcmp_new_ip[3] = true;
} else {
pwmcmp_new_ip[3] = false;
// TODO: add correct calculation for regs->r_pwmcfg.pwmcmpXcenter==1
auto nt = (regs->r_pwmcmp0.pwmcmp0 - pwms0) * (1 << regs->r_pwmcfg.pwmscale) * clk;
next_trigger_time = nt < next_trigger_time ? nt : next_trigger_time;
}
for (size_t i = 0; i < 4; ++i) {
// write gpio bits depending of gang bit
if (regs->r_pwmcfg & (1 < (24 + i)))
write_cmpgpio(i, pwmcmp_new_ip[i] && !pwmcmp_new_ip[(i + 1) % 4]);
else
write_cmpgpio(i, pwmcmp_new_ip[i]);
// detect rising edge and set ip bit if found
if (!pwmcmp_ip[i] && pwmcmp_new_ip[i]) regs->r_pwmcfg |= 1 << (28 + i);
pwmcmp_ip[i] = pwmcmp_new_ip[i];
}
last_enable = true;
update_counter_evt.notify(next_trigger_time);
} else
last_enable = false;
cmpip_o[0].write(regs->r_pwmcfg.pwmcmp0ip != 0);
cmpip_o[1].write(regs->r_pwmcfg.pwmcmp1ip != 0);
cmpip_o[2].write(regs->r_pwmcfg.pwmcmp2ip != 0);
cmpip_o[3].write(regs->r_pwmcfg.pwmcmp3ip != 0);
last_cnt_update = now;
last_clk = clk;
}
void pwm::write_cmpgpio(size_t index, bool val) {
if (cmpgpio_o[index].get_interface()) {
tlm::tlm_phase phase(tlm::BEGIN_REQ);
tlm::tlm_signal_gp<> gp;
sc_core::sc_time delay(SC_ZERO_TIME);
gp.set_value(val);
cmpgpio_o[index]->nb_transport_fw(gp, phase, delay);
}
}

View File

@ -1,55 +1,51 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#include "sysc/sc_comm_singleton.h" #include "sysc/sc_comm_singleton.h"
#include "seasocks/PrintfLogger.h" #include "seasocks/PrintfLogger.h"
#include "seasocks/ResponseWriter.h"
#include "seasocks/Server.h" #include "seasocks/Server.h"
#include "seasocks/StringUtil.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/CrackedUriPageHandler.h"
#include "seasocks/util/Json.h"
#include "seasocks/util/RootPageHandler.h"
#include "seasocks/util/StaticResponseHandler.h" #include "seasocks/util/StaticResponseHandler.h"
#include <cstdio>
#include <csignal>
#include <sys/stat.h>
#include <cerrno> #include <cerrno>
#include <csignal>
#include <cstdio>
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
namespace sysc { namespace sysc {
@ -58,127 +54,116 @@ using namespace seasocks;
using namespace std; using namespace std;
namespace { namespace {
inline void die(){perror(nullptr);exit(errno);} inline void die() {
perror(nullptr);
exit(errno);
}
} }
sc_comm_singleton::sc_comm_singleton(sc_core::sc_module_name nm) sc_comm_singleton::sc_comm_singleton(sc_core::sc_module_name nm)
: sc_core::sc_module(nm) : sc_core::sc_module(nm)
, m_serv(new Server(std::make_shared<PrintfLogger>(Logger::Level::WARNING))) , m_serv(new Server(std::make_shared<PrintfLogger>(Logger::Level::WARNING)))
, needs_client(false) , needs_client(false)
, client_started(false){ , client_started(false) {
m_serv->addPageHandler(std::make_shared<DefaultPageHandler>(*this)); m_serv->addPageHandler(std::make_shared<DefaultPageHandler>(*this));
} }
sc_comm_singleton::~sc_comm_singleton() { sc_comm_singleton::~sc_comm_singleton() {
//Join the thread with the main thread // Join the thread with the main thread
t.join(); t.join();
} }
void sc_comm_singleton::start_of_simulation() { void sc_comm_singleton::start_of_simulation() {
//Launch a thread // Launch a thread
t=std::thread(&sc_comm_singleton::thread_func, this); t = std::thread(&sc_comm_singleton::thread_func, this);
if(needs_client) start_client(); if (needs_client) start_client();
} }
void sc_comm_singleton::end_of_simulation() { void sc_comm_singleton::end_of_simulation() { get_server().terminate(); }
get_server().terminate();
}
void sc_comm_singleton::start_client() { void sc_comm_singleton::start_client() {
if(client_started) return; if (client_started) return;
std::stringstream ss; std::stringstream ss;
#ifndef WIN32 #ifndef WIN32
if(fork()==0){ if (fork() == 0) {
// daemonizing, see http://www.microhowto.info/howto/cause_a_process_to_become_a_daemon_in_c.html#id2407077 // daemonizing, see http://www.microhowto.info/howto/cause_a_process_to_become_a_daemon_in_c.html#id2407077
// Fork, allowing the parent process to terminate. // Fork, allowing the parent process to terminate.
pid_t pid = fork(); pid_t pid = fork();
if (pid == -1) { if (pid == -1) {
die(); die();
} else if (pid != 0) { } else if (pid != 0) {
_exit(0); _exit(0);
} }
// Start a new session for the daemon. // Start a new session for the daemon.
if (setsid()==-1) die(); if (setsid() == -1) die();
// Fork again, allowing the parent process to terminate. // Fork again, allowing the parent process to terminate.
signal(SIGHUP,SIG_IGN); signal(SIGHUP, SIG_IGN);
pid=fork(); pid = fork();
if (pid == -1) { if (pid == -1) {
die(); die();
} else if (pid != 0) { } else if (pid != 0) {
_exit(0); _exit(0);
} }
// Set the current working directory to the root directory. // Set the current working directory to the root directory.
if (chdir("/") == -1) die(); if (chdir("/") == -1) die();
// Set the user file creation mask to zero. // Set the user file creation mask to zero.
umask(0); umask(0);
// Close then reopen standard file descriptors. // Close then reopen standard file descriptors.
close(STDIN_FILENO); close(STDIN_FILENO);
close(STDOUT_FILENO); close(STDOUT_FILENO);
close(STDERR_FILENO); close(STDERR_FILENO);
if (open("/dev/null",O_RDONLY) == -1) die(); if (open("/dev/null", O_RDONLY) == -1) die();
if (open("/dev/null",O_WRONLY) == -1) die(); if (open("/dev/null", O_WRONLY) == -1) die();
if (open("/dev/null",O_RDWR) == -1) die(); if (open("/dev/null", O_RDWR) == -1) die();
// now do what is needed // now do what is needed
ss<<"x-www-browser http://localhost:9090/ws.html"; //Linux ss << "x-www-browser http://localhost:9090/ws.html"; // Linux
auto res = system (ss.str().c_str()); auto res = system(ss.str().c_str());
if(res==0) exit(0); if (res == 0) exit(0);
ss.str(""); ss.str("");
ss<<"xdg-open http://localhost:9090/ws.html"; // Linux ss << "xdg-open http://localhost:9090/ws.html"; // Linux
res=system (ss.str().c_str()); res = system(ss.str().c_str());
if(res==0) exit(0); if (res == 0) exit(0);
ss.str(""); ss.str("");
ss<<"open http://localhost:9090/ws.html"; // MacOS ss << "open http://localhost:9090/ws.html"; // MacOS
res=system (ss.str().c_str()); res = system(ss.str().c_str());
exit(0); exit(0);
} }
// #else // #else
// on windows should be open, see https://www.experts-exchange.com/articles/1595/Execute-a-Program-with-C.html // on windows should be open, see https://www.experts-exchange.com/articles/1595/Execute-a-Program-with-C.html
#endif #endif
client_started=true; client_started = true;
} }
void sc_comm_singleton::registerWebSocketHandler(const char* endpoint, void sc_comm_singleton::registerWebSocketHandler(const char *endpoint, std::shared_ptr<WebSocket::Handler> handler,
std::shared_ptr<WebSocket::Handler> handler, bool allowCrossOriginRequests) {
bool allowCrossOriginRequests) { get_server().addWebSocketHandler(endpoint, handler, allowCrossOriginRequests);
get_server().addWebSocketHandler(endpoint, handler, allowCrossOriginRequests); endpoints.emplace_back(endpoint);
endpoints.push_back(endpoint); needs_client = true;
needs_client=true;
} }
void sc_comm_singleton::execute(std::function<void()> f) { void sc_comm_singleton::execute(std::function<void()> f) { get_server().execute(f); }
get_server().execute(f);
void sc_comm_singleton::thread_func() { get_server().serve("./html", 9090); }
Server &sc_comm_singleton::get_server() { return *m_serv.get(); }
std::shared_ptr<Response> sc_comm_singleton::DefaultPageHandler::handle(const Request &request) {
if (request.verb() == Request::Verb::Get && request.getRequestUri() == "conf.json") {
return Response::htmlResponse("{}");
}
return Response::unhandled();
} }
void sc_comm_singleton::thread_func() { void WsHandler::onConnect(WebSocket *connection) { _connections.insert(connection); }
get_server().serve("./html", 9090);
void WsHandler::onData(WebSocket *connection, const char *data) {
if (0 == strcmp("close", data)) {
connection->close();
} else if (callback)
callback(data);
} }
Server& sc_comm_singleton::get_server() { void WsHandler::onDisconnect(WebSocket *connection) { _connections.erase(connection); }
return *m_serv.get();
}
std::shared_ptr<Response> sc_comm_singleton::DefaultPageHandler::handle(const Request& request) {
if(request.verb() == Request::Verb::Get && request.getRequestUri()=="conf.json"){
return Response::htmlResponse("{}");
}
return Response::unhandled();
}
void WsHandler::onConnect(WebSocket* connection) {
_connections.insert(connection);
}
void WsHandler::onData(WebSocket* connection, const char* data) {
if (0 == strcmp("close", data)) {
connection->close();
} else if(callback)
callback(data);
}
void WsHandler::onDisconnect(WebSocket* connection) {
_connections.erase(connection);
}
} /* namespace sysc */ } /* namespace sysc */

View File

@ -1,60 +1,93 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#include "sysc/SiFive/spi.h" #include "sysc/SiFive/spi.h"
#include "cci_configuration"
#include "scc/signal_initiator_mixin.h"
#include "scc/signal_target_mixin.h"
#include "scc/tlm_target.h"
#include "sysc/tlm_extensions.h"
#include "scc/utilities.h" #include "scc/utilities.h"
#include "sysc/SiFive/gen/spi_regs.h" #include "sysc/SiFive/gen/spi_regs.h"
#include "sysc/tlm_extensions.h"
#include <util/ities.h> #include <util/ities.h>
namespace sysc { namespace sysc {
namespace spi_impl {
using namespace sc_core;
spi::spi(sc_core::sc_module_name nm) class beh : public sysc::spi, public scc::tlm_target<> {
: sc_core::sc_module(nm) public:
SC_HAS_PROCESS(beh); // NOLINT
cci::cci_param<bool> bit_true_transfer;
beh(sc_core::sc_module_name nm);
~beh() override;
protected:
scc::tlm_signal_bool_opt_out _sck_o;
scc::tlm_signal_bool_opt_out _mosi_o;
scc::tlm_signal_bool_opt_in _miso_i;
sc_core::sc_vector<scc::tlm_signal_bool_opt_out> _scs_o;
void clock_cb();
void reset_cb();
void transmit_data();
void receive_data(tlm::tlm_signal_gp<> &gp, sc_core::sc_time &delay);
void update_irq();
sc_core::sc_event update_irq_evt;
sc_core::sc_time clk;
std::unique_ptr<spi_regs> regs;
sc_core::sc_fifo<uint8_t> rx_fifo, tx_fifo;
};
beh::beh(sc_core::sc_module_name nm)
: sysc::spi(nm)
, tlm_target<>(clk) , tlm_target<>(clk)
, NAMED(clk_i) , NAMED(_sck_o)
, NAMED(rst_i) , NAMED(_mosi_o)
, NAMED(sck_o) , NAMED(_miso_i)
, NAMED(mosi_o) , NAMED(_scs_o, 4)
, NAMED(miso_i)
, NAMED(scs_o, 4)
, NAMED(irq_o)
, NAMED(bit_true_transfer, false) , NAMED(bit_true_transfer, false)
, NAMEDD(spi_regs, regs) { , NAMEDD(regs, spi_regs)
, rx_fifo(8)
, tx_fifo(8) {
spi::socket(scc::tlm_target<>::socket);
_sck_o(sck_o);
_mosi_o(mosi_o);
miso_i(_miso_i);
_scs_o(scs_o);
regs->registerResources(*this); regs->registerResources(*this);
SC_METHOD(clock_cb); SC_METHOD(clock_cb);
sensitive << clk_i; sensitive << clk_i;
@ -62,158 +95,177 @@ spi::spi(sc_core::sc_module_name nm)
sensitive << rst_i; sensitive << rst_i;
dont_initialize(); dont_initialize();
SC_THREAD(transmit_data); SC_THREAD(transmit_data);
miso_i.register_nb_transport([this](tlm::tlm_signal_gp<bool>& gp, _miso_i.register_nb_transport(
tlm::tlm_phase& phase, sc_core::sc_time& delay)->tlm::tlm_sync_enum{ [this](tlm::tlm_signal_gp<bool> &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay) -> tlm::tlm_sync_enum {
this->receive_data(gp, delay); this->receive_data(gp, delay);
return tlm::TLM_COMPLETED; return tlm::TLM_COMPLETED;
}); });
regs->txdata.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool { regs->txdata.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data, sc_core::sc_time d) -> bool {
if (!this->regs->in_reset()) { if (!this->regs->in_reset()) {
reg.put(data); reg.put(data);
tx_fifo.nb_write(static_cast<uint8_t>(regs->r_txdata.data)); tx_fifo.nb_write(static_cast<uint8_t>(regs->r_txdata.data));
regs->r_txdata.full=tx_fifo.num_free()==0;
update_irq();
} }
return true; return true;
}); });
regs->rxdata.set_read_cb([this](const scc::sc_register<uint32_t> &reg, uint32_t& data) -> bool { regs->rxdata.set_read_cb([this](const scc::sc_register<uint32_t> &reg, uint32_t &data, sc_core::sc_time d) -> bool {
if (!this->regs->in_reset()) { if (!this->regs->in_reset()) {
uint8_t val; uint8_t val;
if(rx_fifo.nb_read(val)){ if (rx_fifo.nb_read(val)) {
regs->r_rxdata.empty=0; regs->r_rxdata.empty = 0;
regs->r_rxdata.data=val; regs->r_rxdata.data = val;
if(regs->r_rxmark.rxmark<=rx_fifo.num_available()){ if (regs->r_rxmark.rxmark <= rx_fifo.num_available()) {
regs->r_ip.rxwm=1; regs->r_ip.rxwm = 1;
update_irq(); update_irq();
} }
} else } else
regs->r_rxdata.empty=1; regs->r_rxdata.empty = 1;
data = reg.get()&reg.rdmask; data = reg.get() & reg.rdmask;
} }
return true; return true;
}); });
regs->csmode.set_write_cb([this](const scc::sc_register<uint32_t> &reg, uint32_t& data) -> bool { regs->csmode.set_write_cb(
if(regs->r_csmode.mode==2 && regs->r_csmode.mode != bit_sub<0, 2>(data) && regs->r_csid<4){ [this](const scc::sc_register<uint32_t> &reg, uint32_t &data, sc_core::sc_time d) -> bool {
if (regs->r_csmode.mode == 2 && regs->r_csmode.mode != bit_sub<0, 2>(data) && regs->r_csid < 4) {
tlm::tlm_phase phase(tlm::BEGIN_REQ);
sc_core::sc_time delay(SC_ZERO_TIME);
tlm::tlm_signal_gp<> gp;
gp.set_command(tlm::TLM_WRITE_COMMAND);
gp.set_value(true);
_scs_o[regs->r_csid]->nb_transport_fw(gp, phase, delay);
}
reg.put(data);
return true;
});
regs->csid.set_write_cb([this](const scc::sc_register<uint32_t> &reg, uint32_t &data, sc_core::sc_time d) -> bool {
if (regs->r_csmode.mode == 2 && regs->csid != data && regs->r_csid < 4) {
tlm::tlm_phase phase(tlm::BEGIN_REQ); tlm::tlm_phase phase(tlm::BEGIN_REQ);
sc_core::sc_time delay(SC_ZERO_TIME); sc_core::sc_time delay(SC_ZERO_TIME);
tlm::tlm_signal_gp<> gp; tlm::tlm_signal_gp<> gp;
gp.set_command(tlm::TLM_WRITE_COMMAND); gp.set_command(tlm::TLM_WRITE_COMMAND);
gp.set_value(true); gp.set_value(true);
scs_o[regs->r_csid]->nb_transport_fw(gp, phase, delay); _scs_o[regs->r_csid]->nb_transport_fw(gp, phase, delay);
} }
reg.put(data); reg.put(data);
return true; return true;
}); });
regs->csid.set_write_cb([this](const scc::sc_register<uint32_t> &reg, uint32_t& data) -> bool { regs->csdef.set_write_cb([this](const scc::sc_register<uint32_t> &reg, uint32_t &data, sc_core::sc_time d) -> bool {
if(regs->r_csmode.mode==2 && regs->csid != data && regs->r_csid<4){
tlm::tlm_phase phase(tlm::BEGIN_REQ);
sc_core::sc_time delay(SC_ZERO_TIME);
tlm::tlm_signal_gp<> gp;
gp.set_command(tlm::TLM_WRITE_COMMAND);
gp.set_value(true);
scs_o[regs->r_csid]->nb_transport_fw(gp, phase, delay);
}
reg.put(data);
return true;
});
regs->csdef.set_write_cb([this](const scc::sc_register<uint32_t> &reg, uint32_t& data) -> bool {
auto diff = regs->csdef ^ data; auto diff = regs->csdef ^ data;
if(regs->r_csmode.mode==2 && diff!=0 && (regs->r_csid<4) && (diff & (1<<regs->r_csid))!=0){ if (regs->r_csmode.mode == 2 && diff != 0 && (regs->r_csid < 4) && (diff & (1 << regs->r_csid)) != 0) {
tlm::tlm_phase phase(tlm::BEGIN_REQ); tlm::tlm_phase phase(tlm::BEGIN_REQ);
sc_core::sc_time delay(SC_ZERO_TIME); sc_core::sc_time delay(SC_ZERO_TIME);
tlm::tlm_signal_gp<> gp; tlm::tlm_signal_gp<> gp;
gp.set_command(tlm::TLM_WRITE_COMMAND); gp.set_command(tlm::TLM_WRITE_COMMAND);
gp.set_value(true); gp.set_value(true);
scs_o[regs->r_csid]->nb_transport_fw(gp, phase, delay); _scs_o[regs->r_csid]->nb_transport_fw(gp, phase, delay);
} }
reg.put(data); reg.put(data);
return true; return true;
}); });
regs->ie.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool { regs->ie.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data, sc_core::sc_time d) -> bool {
update_irq(); reg.put(data);
update_irq_evt.notify();
return true;
}); });
regs->ip.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool { regs->ip.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data, sc_core::sc_time d) -> bool {
update_irq(); reg.put(data);
update_irq_evt.notify();
return true;
}); });
SC_METHOD(update_irq);
sensitive << update_irq_evt << rx_fifo.data_written_event() << rx_fifo.data_read_event()
<< tx_fifo.data_written_event() << tx_fifo.data_read_event();
} }
spi::~spi() {} beh::~beh() = default;
void spi::clock_cb() { void beh::clock_cb() { this->clk = clk_i.read(); }
this->clk = clk_i.read();
}
void spi::reset_cb() { void beh::reset_cb() {
if (rst_i.read()) if (rst_i.read())
regs->reset_start(); regs->reset_start();
else else
regs->reset_stop(); regs->reset_stop();
} }
void spi::transmit_data() { void beh::transmit_data() {
uint8_t txdata; uint8_t txdata;
sysc::tlm_signal_spi_extension ext;
tlm::tlm_phase phase(tlm::BEGIN_REQ); tlm::tlm_phase phase(tlm::BEGIN_REQ);
tlm::tlm_signal_gp<> gp;
sc_core::sc_time delay(SC_ZERO_TIME); sc_core::sc_time delay(SC_ZERO_TIME);
sc_core::sc_time bit_duration(SC_ZERO_TIME); sc_core::sc_time bit_duration(SC_ZERO_TIME);
sc_core::sc_time start_time;
gp.set_extension(&ext); auto set_bit = [&](bool val, scc::tlm_signal_bool_opt_out &socket,
ext.tx.data_bits=8; bool data_valid = false) -> std::pair<bool, uint32_t> {
if (socket.get_interface() == nullptr) return std::pair<bool, uint32_t>{false, 0};
auto set_bit = [&](bool val, scc::tlm_signal_bool_opt_out& socket){ auto *gp = tlm::tlm_signal_gp<>::create();
if(socket.get_interface()==nullptr) return; auto *ext = new sysc::tlm_signal_spi_extension();
gp.set_command(tlm::TLM_WRITE_COMMAND); ext->tx.data_bits = 8;
gp.set_value(val); ext->start_time = start_time;
ext->tx.m2s_data = txdata;
ext->tx.m2s_data_valid = data_valid;
ext->tx.s2m_data_valid = false;
gp->set_extension(ext);
gp->set_command(tlm::TLM_WRITE_COMMAND);
gp->set_value(val);
tlm::tlm_phase phase(tlm::BEGIN_REQ); tlm::tlm_phase phase(tlm::BEGIN_REQ);
socket->nb_transport_fw(gp, phase, delay); gp->acquire();
phase = tlm::BEGIN_REQ;
delay = SC_ZERO_TIME;
socket->nb_transport_fw(*gp, phase, delay);
std::pair<bool, uint32_t> ret{ext->tx.s2m_data_valid != 0, ext->tx.s2m_data};
gp->release();
return ret;
}; };
wait(delay); //intentionally 0ns; wait(delay); // intentionally 0ns;
while(true){ while (true) {
wait(tx_fifo.data_written_event()); wait(tx_fifo.data_written_event());
if(regs->r_csmode.mode != 3 && regs->r_csid<4) // not in OFF mode if (regs->r_csmode.mode != 3 && regs->r_csid < 4) // not in OFF mode
set_bit(false, scs_o[regs->r_csid]); set_bit(false, _scs_o[regs->r_csid]);
set_bit(regs->r_sckmode.pol, sck_o); set_bit(regs->r_sckmode.pol, _sck_o);
while(tx_fifo.nb_read(txdata)){ while (tx_fifo.nb_read(txdata)) {
regs->r_txdata.full=tx_fifo.num_free()==0; regs->r_txdata.full = tx_fifo.num_free() == 0;
regs->r_ip.txwm=regs->r_txmark.txmark<=(7-tx_fifo.num_free())?1:0; regs->r_ip.txwm = regs->r_txmark.txmark <= (7 - tx_fifo.num_free()) ? 1 : 0;
bit_duration = 2*(regs->r_sckdiv.div+1)*clk; update_irq_evt.notify();
ext.start_time = sc_core::sc_time_stamp(); bit_duration = 2 * (regs->r_sckdiv.div + 1) * clk;
ext.tx.m2s_data=txdata; start_time = sc_core::sc_time_stamp();
ext.tx.s2m_data_valid=false; set_bit(txdata & 0x80, _mosi_o); // 8 data bits, MSB first
set_bit(txdata&0x80, mosi_o); // 8 data bits, MSB first auto s2m = set_bit(1 - regs->r_sckmode.pol, _sck_o, true);
set_bit(1-regs->r_sckmode.pol, sck_o); wait(bit_duration / 2);
wait(bit_duration/2); set_bit(regs->r_sckmode.pol, _sck_o, true);
set_bit(regs->r_sckmode.pol, sck_o); wait(bit_duration / 2);
wait(bit_duration/2); if (bit_true_transfer.get_value()) {
if(bit_true_transfer.get_value()){ for (size_t i = 0, mask = 0x40; i < 7; ++i, mask >= 1) {
for(size_t i = 0, mask=0x40; i<7; ++i, mask>=1){ set_bit(txdata & mask, _mosi_o); // 8 data bits, MSB first
set_bit(txdata&mask, mosi_o); // 8 data bits, MSB first set_bit(1 - regs->r_sckmode.pol, _sck_o);
set_bit(1-regs->r_sckmode.pol, sck_o); wait(bit_duration / 2);
wait(bit_duration/2); set_bit(regs->r_sckmode.pol, _sck_o);
set_bit(regs->r_sckmode.pol, sck_o); wait(bit_duration / 2);
wait(bit_duration/2);
} }
} else } else
wait(7*bit_duration); wait(7 * bit_duration);
rx_fifo.nb_write(ext.tx.s2m_data&0xff); if (s2m.first) rx_fifo.nb_write(s2m.second & 0xff);
if(regs->r_rxmark.rxmark<=rx_fifo.num_available()){ update_irq_evt.notify();
regs->r_ip.rxwm=1;
update_irq();
}
} }
if(regs->r_csmode.mode == 0 && regs->r_csid<4) // in AUTO mode if (regs->r_csmode.mode == 0 && regs->r_csid < 4) // in AUTO mode
set_bit(false, scs_o[regs->r_csid]); set_bit(false, _scs_o[regs->r_csid]);
} }
} }
void spi::receive_data(tlm::tlm_signal_gp<>& gp, sc_core::sc_time& delay) { void beh::receive_data(tlm::tlm_signal_gp<> &gp, sc_core::sc_time &delay) {}
}
void spi::update_irq() { void beh::update_irq() {
regs->r_ip.rxwm = regs->r_rxmark.rxmark < rx_fifo.num_available();
regs->r_ip.txwm = regs->r_txmark.txmark <= tx_fifo.num_available();
regs->r_txdata.full = tx_fifo.num_free() == 0;
irq_o.write((regs->r_ie.rxwm > 0 && regs->r_ip.rxwm > 0) || (regs->r_ie.txwm > 0 && regs->r_ip.txwm > 0));
}
} /* namespace spi:impl */
template <> std::unique_ptr<spi> spi::create<sysc::spi_impl::beh>(sc_core::sc_module_name nm) {
auto *res = new sysc::spi_impl::beh(nm);
return std::unique_ptr<spi>(res);
} }
} /* namespace sysc */ } /* namespace sysc */

View File

@ -1,88 +1,115 @@
/* /*******************************************************************************
* system.cpp * Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
* *
* Created on: 11.07.2018 * Redistribution and use in source and binary forms, with or without
* Author: eyck * modification, are permitted provided that the following conditions are met:
*/ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#include "sysc/top/system.h" #include "sysc/top/system.h"
using namespace sysc; using namespace sysc;
using namespace sc_core;
system::system(sc_core::sc_module_name nm) system::system(sc_module_name nm)
: sc_module(nm) : sc_module(nm)
, NAMED(s_gpio, 32) , NAMED(s_ha)
, NAMED(s_la)
, NAMED(s_hb)
, NAMED(s_lb)
, NAMED(s_hc)
, NAMED(s_lc)
, NAMED(s_rst_n) , NAMED(s_rst_n)
, NAMED(s_vref) , NAMED(s_vref)
, NAMED(s_va) , NAMED(s_va)
, NAMED(s_vb) , NAMED(s_vb)
, NAMED(s_vc) , NAMED(s_vc)
, NAMED(s_ana, 5) , NAMED(s_vasens)
, NAMED(i_platform) , NAMED(s_vbsens)
, NAMED(i_terminal) , NAMED(s_vcsens)
, NAMED(i_adc) , NAMED(s_vcentersens)
, NAMED(s_ana, 4)
, NAMED(i_hifive1)
, NAMED(i_h_bridge) , NAMED(i_h_bridge)
, NAMED(i_motor) , NAMED(i_motor) {
{
// connect platform // connect platform
i_platform.erst_n(s_rst_n); i_hifive1.erst_n(s_rst_n);
// HiFive1 digital out
for(auto i=0U; i<s_gpio.size(); ++i){ i_hifive1.ha_o(s_ha);
s_gpio[i].in(i_platform.pins_o[i]); i_hifive1.la_o(s_la);
i_platform.pins_i[i](s_gpio[i].out); i_hifive1.hb_o(s_hb);
} i_hifive1.lb_o(s_lb);
// connect other units i_hifive1.hc_o(s_hc);
// terminal i_hifive1.lc_o(s_lc);
i_terminal.tx_o(s_gpio[16].in); // HiFive1 analog in
s_gpio[17].out(i_terminal.rx_i); i_hifive1.vref_i(s_vref);
// adc digital io i_hifive1.adc_ch0_i(s_vasens);
s_gpio[2].out(i_adc.cs_i); i_hifive1.adc_ch1_i(s_vbsens);
s_gpio[3].out(i_adc.mosi_i); i_hifive1.adc_ch2_i(s_vcsens);
i_adc.miso_o(s_gpio[4].in); i_hifive1.adc_ch3_i(s_vcentersens);
s_gpio[5].out(i_adc.sck_i); i_hifive1.adc_ch4_i(s_ana[0]);
// adc analog inputs i_hifive1.adc_ch5_i(s_ana[1]);
i_adc.vref_i(s_vref); i_hifive1.adc_ch6_i(s_ana[2]);
i_adc.ch_i[0](s_vasens); i_hifive1.adc_ch7_i(s_ana[3]);
i_adc.ch_i[1](s_vbsens); // H-bridge digital in
i_adc.ch_i[2](s_vcsens); i_h_bridge.ha_i(s_ha);
i_adc.ch_i[3](s_ana[0]); i_h_bridge.la_i(s_la);
i_adc.ch_i[4](s_ana[1]); i_h_bridge.hb_i(s_hb);
i_adc.ch_i[5](s_ana[2]); i_h_bridge.lb_i(s_lb);
i_adc.ch_i[6](s_ana[3]); i_h_bridge.hc_i(s_hc);
i_adc.ch_i[7](s_ana[4]); i_h_bridge.lc_i(s_lc);
// H-bridge analog out
i_h_bridge.ha_i(s_gpio[0]);
i_h_bridge.la_i(s_gpio[1]);
i_h_bridge.hb_i(s_gpio[10]);
i_h_bridge.lb_i(s_gpio[11]);
i_h_bridge.hc_i(s_gpio[19]);
i_h_bridge.lc_i(s_gpio[20]);
i_h_bridge.va_o(s_va); i_h_bridge.va_o(s_va);
i_h_bridge.vb_o(s_vb); i_h_bridge.vb_o(s_vb);
i_h_bridge.vc_o(s_vc); i_h_bridge.vc_o(s_vc);
// motor analog in
i_motor.va_i(s_va); i_motor.va_i(s_va);
i_motor.vb_i(s_vb); i_motor.vb_i(s_vb);
i_motor.vc_i(s_vc); i_motor.vc_i(s_vc);
// motor analog out
i_motor.va_o(s_vasens); i_motor.va_o(s_vasens);
i_motor.vb_o(s_vbsens); i_motor.vb_o(s_vbsens);
i_motor.vc_o(s_vcsens); i_motor.vc_o(s_vcsens);
i_motor.vcenter_o(s_vcentersens);
SC_THREAD(gen_por); SC_THREAD(gen_por);
} }
system::~system() { system::~system() = default;
}
void sysc::system::gen_por() { void sysc::system::gen_por() {
// single shot // single shot
s_rst_n = false; s_rst_n = false;
wait(10_ns); wait(1_us);
s_rst_n = true; s_rst_n = true;
s_vref=1.024; s_vref = 4.8;
double val=0.1; double val = 0.1;
for(auto& sig:s_ana){ for (auto &sig : s_ana) {
sig=val; sig = val;
val+=0.12; val += 0.12;
} }
} }

View File

@ -1,68 +1,86 @@
/* /*******************************************************************************
* terminal.cpp * Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
* *
* Created on: 07.07.2018 * Redistribution and use in source and binary forms, with or without
* Author: eyck * modification, are permitted provided that the following conditions are met:
*/ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#include "sysc/top/terminal.h" #include "sysc/top/terminal.h"
#include "scc/report.h"
#include "sysc/sc_comm_singleton.h" #include "sysc/sc_comm_singleton.h"
#include "sysc/tlm_extensions.h" #include "sysc/tlm_extensions.h"
#include "scc/report.h"
using namespace sysc; using namespace sysc;
terminal::terminal() terminal::terminal()
: terminal(sc_core::sc_gen_unique_name("terminal")) : terminal(sc_core::sc_gen_unique_name("terminal")) {}
{
}
terminal::terminal(const sc_core::sc_module_name& nm) terminal::terminal(const sc_core::sc_module_name &nm)
: sc_core::sc_module(nm) : sc_core::sc_module(nm)
, NAMED(tx_o) , NAMED(tx_o)
, NAMED(rx_i) , NAMED(rx_i)
, NAMED(write_to_ws, false) , NAMED(write_to_ws, false) {
{ rx_i.register_nb_transport([this](tlm::tlm_signal_gp<sc_dt::sc_logic> &gp, tlm::tlm_phase &phase,
rx_i.register_nb_transport([this]( sc_core::sc_time &delay) -> tlm::tlm_sync_enum {
tlm::tlm_signal_gp<sc_dt::sc_logic>& gp,
tlm::tlm_phase& phase,
sc_core::sc_time& delay)->tlm::tlm_sync_enum{
this->receive(gp, delay); this->receive(gp, delay);
return tlm::TLM_COMPLETED; return tlm::TLM_COMPLETED;
}); });
} }
terminal::~terminal() { terminal::~terminal() = default;
}
void terminal::before_end_of_elaboration() { void terminal::before_end_of_elaboration() {
if(write_to_ws.get_value()) { if (write_to_ws.get_value()) {
LOG(TRACE)<<"Adding WS handler for "<<(std::string{"/ws/"}+name()); SCTRACE() << "Adding WS handler for " << (std::string{"/ws/"} + name());
handler=std::make_shared<WsHandler>(); handler = std::make_shared<WsHandler>();
sc_comm_singleton::inst().registerWebSocketHandler((std::string{"/ws/"}+name()).c_str(), handler); sc_comm_singleton::inst().registerWebSocketHandler((std::string{"/ws/"} + name()).c_str(), handler);
} }
} }
void terminal::receive(tlm::tlm_signal_gp<sc_dt::sc_logic> &gp, sc_core::sc_time &delay) {
void terminal::receive(tlm::tlm_signal_gp<sc_dt::sc_logic>& gp, sc_core::sc_time& delay) { sysc::tlm_signal_uart_extension *ext;
sysc::tlm_signal_uart_extension* ext;
gp.get_extension(ext); gp.get_extension(ext);
if(ext && ext->start_time!=last_tx_start){ if (ext && ext->start_time != last_tx_start) {
uint8_t txdata = static_cast<uint8_t>(ext->tx.data); auto txdata = static_cast<uint8_t>(ext->tx.data);
last_tx_start = ext->start_time; last_tx_start = ext->start_time;
if(txdata != '\r') queue.push_back(txdata); if (txdata != '\r') queue.push_back(txdata);
if (queue.size() >> 0 && (txdata == '\n' || txdata == 0)) { if (queue.size() >> 0 && (txdata == '\n' || txdata == 0)) {
std::string msg(queue.begin(), queue.end()-1); std::string msg(queue.begin(), queue.end() - 1);
sc_core::sc_time now = sc_core::sc_time_stamp(); sc_core::sc_time now = sc_core::sc_time_stamp();
if(handler) if (handler)
sysc::sc_comm_singleton::inst().execute([this, msg, now](){ sysc::sc_comm_singleton::inst().execute([this, msg, now]() {
std::stringstream os; std::stringstream os;
os << "{\"time\":\"" << now << "\",\"message\":\""<<msg<<"\"}"; os << R"({"time":")" << now << R"(","message":")" << msg << R"("})";
this->handler->send(os.str()); this->handler->send(os.str());
}); });
else else
LOG(INFO) << this->name() << " receive: '" << msg << "'"; SCINFO(this->name()) << " receive: '" << msg << "'";
queue.clear(); queue.clear();
} }
} }

View File

@ -1,50 +1,46 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#include "sysc/SiFive/uart.h" #include "sysc/SiFive/uart.h"
#include "sysc/tlm_extensions.h"
#include "scc/report.h" #include "scc/report.h"
#include "scc/utilities.h" #include "scc/utilities.h"
#include "sysc/SiFive/gen/uart_regs.h" #include "sysc/SiFive/gen/uart_regs.h"
#include "sysc/tlm_extensions.h"
using namespace std; using namespace std;
namespace sysc { namespace sysc {
using namespace sc_core;
uart::uart(sc_core::sc_module_name nm) uart::uart(sc_core::sc_module_name nm)
: sc_core::sc_module(nm) : sc_core::sc_module(nm)
@ -55,10 +51,9 @@ uart::uart(sc_core::sc_module_name nm)
, NAMED(rx_i) , NAMED(rx_i)
, NAMED(irq_o) , NAMED(irq_o)
, NAMED(bit_true_transfer, false) , NAMED(bit_true_transfer, false)
, NAMEDD(uart_regs, regs) , NAMEDD(regs, uart_regs)
, NAMED(rx_fifo, 8) , NAMED(rx_fifo, 8)
, NAMED(tx_fifo, 8) , NAMED(tx_fifo, 8) {
{
regs->registerResources(*this); regs->registerResources(*this);
SC_METHOD(clock_cb); SC_METHOD(clock_cb);
sensitive << clk_i; sensitive << clk_i;
@ -66,52 +61,52 @@ uart::uart(sc_core::sc_module_name nm)
sensitive << rst_i; sensitive << rst_i;
dont_initialize(); dont_initialize();
SC_THREAD(transmit_data); SC_THREAD(transmit_data);
rx_i.register_nb_transport([this](tlm::tlm_signal_gp<bool>& gp, rx_i.register_nb_transport(
tlm::tlm_phase& phase, sc_core::sc_time& delay)->tlm::tlm_sync_enum{ [this](tlm::tlm_signal_gp<bool> &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay) -> tlm::tlm_sync_enum {
this->receive_data(gp, delay); this->receive_data(gp, delay);
return tlm::TLM_COMPLETED; return tlm::TLM_COMPLETED;
}); });
regs->txdata.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool { regs->txdata.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data, sc_core::sc_time d) -> bool {
if (!this->regs->in_reset()) { if (!this->regs->in_reset()) {
reg.put(data); reg.put(data);
tx_fifo.nb_write(static_cast<uint8_t>(regs->r_txdata.data)); tx_fifo.nb_write(static_cast<uint8_t>(regs->r_txdata.data));
regs->r_txdata.full=tx_fifo.num_free()==0; regs->r_txdata.full = tx_fifo.num_free() == 0;
regs->r_ip.txwm=regs->r_txctrl.txcnt<=(7-tx_fifo.num_free())?1:0; regs->r_ip.txwm = regs->r_txctrl.txcnt <= (7 - tx_fifo.num_free()) ? 1 : 0;
update_irq(); update_irq();
} }
return true; return true;
}); });
regs->rxdata.set_read_cb([this](const scc::sc_register<uint32_t> &reg, uint32_t& data) -> bool { regs->rxdata.set_read_cb([this](const scc::sc_register<uint32_t> &reg, uint32_t &data, sc_core::sc_time d) -> bool {
if (!this->regs->in_reset()) { if (!this->regs->in_reset()) {
uint8_t val; uint8_t val;
if(rx_fifo.nb_read(val)){ if (rx_fifo.nb_read(val)) {
regs->r_rxdata.data=val; regs->r_rxdata.data = val;
if(regs->r_rxctrl.rxcnt<=rx_fifo.num_available()){ if (regs->r_rxctrl.rxcnt <= rx_fifo.num_available()) {
regs->r_ip.rxwm=1; regs->r_ip.rxwm = 1;
update_irq(); update_irq();
} }
} }
data = reg.get()&reg.rdmask; data = reg.get() & reg.rdmask;
} }
return true; return true;
}); });
regs->ie.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool { regs->ie.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data, sc_core::sc_time d) -> bool {
update_irq(); update_irq();
return true;
}); });
regs->ip.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool { regs->ip.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data, sc_core::sc_time d) -> bool {
update_irq(); update_irq();
return true;
}); });
} }
uart::~uart() {} uart::~uart() = default;
void uart::update_irq() { void uart::update_irq() {
irq_o=(regs->r_ip.rxwm==1 && regs->r_ie.rxwm==1) || (regs->r_ip.txwm==1 && regs->r_ie.txwm==1); irq_o = (regs->r_ip.rxwm == 1 && regs->r_ie.rxwm == 1) || (regs->r_ip.txwm == 1 && regs->r_ie.txwm == 1);
} }
void uart::clock_cb() { void uart::clock_cb() { this->clk = clk_i.read(); }
this->clk = clk_i.read();
}
void uart::reset_cb() { void uart::reset_cb() {
if (rst_i.read()) if (rst_i.read())
@ -122,62 +117,64 @@ void uart::reset_cb() {
void uart::transmit_data() { void uart::transmit_data() {
uint8_t txdata; uint8_t txdata;
sysc::tlm_signal_uart_extension ext;
tlm::tlm_phase phase(tlm::BEGIN_REQ); tlm::tlm_phase phase(tlm::BEGIN_REQ);
tlm::tlm_signal_gp<> gp;
sc_core::sc_time delay(SC_ZERO_TIME); sc_core::sc_time delay(SC_ZERO_TIME);
sc_core::sc_time bit_duration(SC_ZERO_TIME); sc_core::sc_time bit_duration(SC_ZERO_TIME);
sc_core::sc_time start_time;
gp.set_extension(&ext); auto set_bit = [&](bool val) {
ext.tx.data_bits=8; auto *gp = tlm::tlm_signal_gp<>::create();
ext.tx.parity=false; auto *ext = new sysc::tlm_signal_uart_extension();
ext->tx.data_bits = 8;
auto set_bit = [&](bool val){ ext->tx.parity = false;
gp.set_command(tlm::TLM_WRITE_COMMAND); ext->start_time = start_time;
gp.set_value(val); ext->tx.baud_rate = static_cast<unsigned>(1 / bit_duration.to_seconds());
tlm::tlm_phase phase(tlm::BEGIN_REQ); ext->tx.stop_bits = 1 + regs->r_txctrl.nstop;
tx_o->nb_transport_fw(gp, phase, delay); ext->tx.data = txdata;
if(delay<bit_duration) wait(bit_duration-delay); gp->set_extension(ext);
gp->set_command(tlm::TLM_WRITE_COMMAND);
gp->set_value(val);
gp->acquire();
phase = tlm::BEGIN_REQ;
delay = SC_ZERO_TIME;
tx_o->nb_transport_fw(*gp, phase, delay);
gp->release();
if (delay < bit_duration) wait(bit_duration - delay);
}; };
wait(delay); wait(delay);
while(true){ while (true) {
set_bit(true); set_bit(true);
wait(tx_fifo.data_written_event()); wait(tx_fifo.data_written_event());
while(tx_fifo.nb_read(txdata)){ while (tx_fifo.nb_read(txdata)) {
regs->r_txdata.full=tx_fifo.num_free()==0; regs->r_txdata.full = tx_fifo.num_free() == 0;
regs->r_ip.txwm=regs->r_txctrl.txcnt<=(7-tx_fifo.num_free())?1:0; regs->r_ip.txwm = regs->r_txctrl.txcnt <= (7 - tx_fifo.num_free()) ? 1 : 0;
bit_duration = (regs->r_div.div+1)*clk; bit_duration = (regs->r_div.div + 1) * clk;
ext.start_time = sc_core::sc_time_stamp(); start_time = sc_core::sc_time_stamp();
ext.tx.stop_bits=1+regs->r_txctrl.nstop;
ext.tx.baud_rate=static_cast<unsigned>(1/bit_duration.to_seconds());
ext.tx.data=txdata;
set_bit(false); // start bit set_bit(false); // start bit
if(bit_true_transfer.get_value()){ if (bit_true_transfer.get_value()) {
for(int i = 8; i>0; --i) for (int i = 8; i > 0; --i) set_bit(txdata & (1 << (i - 1))); // 8 data bits, MSB first
set_bit(txdata&(1<<(i-1))); // 8 data bits, MSB first if (regs->r_txctrl.nstop) set_bit(true); // stop bit 1
if(regs->r_txctrl.nstop) set_bit(true); // stop bit 1
} else } else
wait(8*bit_duration); wait(8 * bit_duration);
set_bit(true); // stop bit 1/2 set_bit(true); // stop bit 1/2
} }
} }
} }
void uart::receive_data(tlm::tlm_signal_gp<>& gp, sc_core::sc_time& delay) { void uart::receive_data(tlm::tlm_signal_gp<> &gp, sc_core::sc_time &delay) {
sysc::tlm_signal_uart_extension* ext{nullptr}; sysc::tlm_signal_uart_extension *ext{nullptr};
gp.get_extension(ext); gp.get_extension(ext);
if(ext && ext->start_time != rx_last_start){ if (ext && ext->start_time != rx_last_start) {
auto data = static_cast<uint8_t>(ext->tx.data); auto data = static_cast<uint8_t>(ext->tx.data);
if(ext->tx.parity || ext->tx.data_bits!=8) data = rand(); // random value if wrong config if (ext->tx.parity || ext->tx.data_bits != 8) data = rand(); // random value if wrong config
rx_fifo.write(data); rx_fifo.write(data);
if(regs->r_rxctrl.rxcnt<=rx_fifo.num_available()){ if (regs->r_rxctrl.rxcnt <= rx_fifo.num_available()) {
regs->r_ip.rxwm=1; regs->r_ip.rxwm = 1;
update_irq(); update_irq();
} }
rx_last_start=ext->start_time; // omit repeated handling of signal changes rx_last_start = ext->start_time; // omit repeated handling of signal changes
} }
gp.set_response_status(tlm::TLM_OK_RESPONSE); gp.set_response_status(tlm::TLM_OK_RESPONSE);
} }
} /* namespace sysc */ } /* namespace sysc */

View File

@ -1,6 +1,5 @@
cmake_minimum_required(VERSION 3.3) cmake_minimum_required(VERSION 3.3)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) # main (top) cmake dir set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) # main (top) cmake dir
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # project specific cmake dir
# CMake useful variables # CMake useful variables
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
@ -10,55 +9,29 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
# Set the name of your project here # Set the name of your project here
project("riscv.sc") project("riscv.sc")
# Set the version number of your project here (format is MAJOR.MINOR.PATCHLEVEL - e.g. 1.0.0)
set(VERSION_MAJOR "0")
set(VERSION_MINOR "0")
set(VERSION_PATCH "1")
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
include(Common) include(Common)
## Git (and its revision) # check that we have averything we need
find_package(Git QUIET) # if we don't find git or FindGit.cmake is not on the system we ignore it. if(!SystemC_FOUND)
## The Git module will trigger a reconfiguration for each pull that will bring a new revision on the local repository message( FATAL_ERROR "SystemC library not found." )
set (VCS_REVISION "-1")
if(GIT_FOUND)
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REFSPEC GIT_SHA1)
message(STATUS "GIT branch ${GIT_REFSPEC}")
message(STATUS "GIT revision ${GIT_SHA1}")
set (VCS_REVISION ${GIT_SHA1})
endif() endif()
# This line finds the boost lib and headers. if(!CCI_FOUND)
set(Boost_NO_BOOST_CMAKE ON) # Don't do a find_package in config mode before searching for a regular boost install.
find_package(Boost COMPONENTS program_options system thread REQUIRED)
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
llvm_map_components_to_libnames(llvm_libs support core mcjit x86codegen x86asmparser)
find_package(SystemC)
if(SystemC_FOUND)
add_definitions(-DWITH_SYSTEMC)
include_directories(${SystemC_INCLUDE_DIRS})
link_directories(${SystemC_LIBRARY_DIRS})
else(SystemC_FOUND)
message( FATAL_ERROR "SystemC library not found." )
endif(SystemC_FOUND)
if(CCI_FOUND)
include_directories(${CCI_INCLUDE_DIRS})
link_directories(${CCI_LIBRARY_DIRS})
else()
message( FATAL_ERROR "SystemC CCI library not found." ) message( FATAL_ERROR "SystemC CCI library not found." )
endif() endif()
add_definitions(-DWITH_SYSTEMC)
include_directories(${SystemC_INCLUDE_DIRS})
link_directories(${SystemC_LIBRARY_DIRS})
include_directories(${CCI_INCLUDE_DIRS})
link_directories(${CCI_LIBRARY_DIRS})
if(SCV_FOUND) if(SCV_FOUND)
add_definitions(-DWITH_SCV) add_definitions(-DWITH_SCV)
include_directories(${SCV_INCLUDE_DIRS})
link_directories(${SCV_LIBRARY_DIRS}) link_directories(${SCV_LIBRARY_DIRS})
endif(SCV_FOUND) endif()
# This sets the include directory for the reference project. This is the -I flag in gcc. # This sets the include directory for the reference project. This is the -I flag in gcc.
include_directories( include_directories(
@ -86,6 +59,9 @@ set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
## the following setting needs to be consistent with the library
#add_definitions(-DSC_DEFAULT_WRITER_POLICY=SC_MANY_WRITERS)
# library files # library files
FILE(GLOB RiscVSCHeaders *.h */*.h) FILE(GLOB RiscVSCHeaders *.h */*.h)
@ -95,9 +71,6 @@ set(LIB_SOURCES src/core_complex.cpp )
# Define two variables in order not to repeat ourselves. # Define two variables in order not to repeat ourselves.
set(LIBRARY_NAME riscv.sc) set(LIBRARY_NAME riscv.sc)
## the following setting needs to be consistent with the library
#add_definitions(-DSC_DEFAULT_WRITER_POLICY=SC_MANY_WRITERS)
# Define the library # Define the library
add_library(${LIBRARY_NAME} ${LIB_SOURCES}) add_library(${LIBRARY_NAME} ${LIB_SOURCES})

View File

@ -1,55 +1,51 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _SYSC_SIFIVE_FE310_H_ #ifndef _SYSC_SIFIVE_FE310_H_
#define _SYSC_SIFIVE_FE310_H_ #define _SYSC_SIFIVE_FE310_H_
#include "scc/utilities.h"
#include <tlm>
#include <tlm_utils/tlm_quantumkeeper.h>
#include <cci_configuration>
#include <util/range_lut.h>
#include "scv4tlm/tlm_rec_initiator_socket.h"
#include "scc/initiator_mixin.h" #include "scc/initiator_mixin.h"
#include "scc/traceable.h" #include "scc/traceable.h"
#include "scc/utilities.h"
#include "scv4tlm/tlm_rec_initiator_socket.h"
#include <cci_configuration>
#include <tlm>
#include <tlm_utils/tlm_quantumkeeper.h>
#include <util/range_lut.h>
class scv_tr_db; class scv_tr_db;
class scv_tr_stream; class scv_tr_stream;
struct _scv_tr_generator_default_data; struct _scv_tr_generator_default_data;
template < class T_begin, class T_end> class scv_tr_generator; template <class T_begin, class T_end> class scv_tr_generator;
namespace iss { namespace iss {
class vm_if; class vm_if;
@ -78,7 +74,7 @@ class core_wrapper;
class core_complex : public sc_core::sc_module, public scc::traceable { class core_complex : public sc_core::sc_module, public scc::traceable {
public: public:
SC_HAS_PROCESS(core_complex); SC_HAS_PROCESS(core_complex);// NOLINT
scc::initiator_mixin<scv4tlm::tlm_rec_initiator_socket<32>> initiator; scc::initiator_mixin<scv4tlm::tlm_rec_initiator_socket<32>> initiator;
@ -109,13 +105,13 @@ public:
~core_complex(); ~core_complex();
inline void sync(uint64_t cycle) { inline void sync(uint64_t cycle) {
auto time = curr_clk*(cycle-last_sync_cycle); auto time = curr_clk * (cycle - last_sync_cycle);
quantum_keeper.inc(time); quantum_keeper.inc(time);
if (quantum_keeper.need_sync()) { if (quantum_keeper.need_sync()) {
wait(quantum_keeper.get_local_time()); wait(quantum_keeper.get_local_time());
quantum_keeper.reset(); quantum_keeper.reset();
} }
last_sync_cycle=cycle; last_sync_cycle = cycle;
} }
bool read_mem(uint64_t addr, unsigned length, uint8_t *const data, bool is_fetch); bool read_mem(uint64_t addr, unsigned length, uint8_t *const data, bool is_fetch);
@ -126,9 +122,10 @@ public:
bool write_mem_dbg(uint64_t addr, unsigned length, const uint8_t *const data); bool write_mem_dbg(uint64_t addr, unsigned length, const uint8_t *const data);
void trace(sc_core::sc_trace_file *trf) override; void trace(sc_core::sc_trace_file *trf) const override;
void disass_output(uint64_t pc, const std::string instr); void disass_output(uint64_t pc, const std::string instr);
protected: protected:
void before_end_of_elaboration(); void before_end_of_elaboration();
void start_of_simulation(); void start_of_simulation();
@ -145,18 +142,17 @@ protected:
std::unique_ptr<core_wrapper> cpu; std::unique_ptr<core_wrapper> cpu;
std::unique_ptr<iss::vm_if> vm; std::unique_ptr<iss::vm_if> vm;
sc_core::sc_time curr_clk; sc_core::sc_time curr_clk;
iss::debugger::target_adapter_if* tgt_adapter; iss::debugger::target_adapter_if *tgt_adapter;
#ifdef WITH_SCV #ifdef WITH_SCV
//! transaction recording database //! transaction recording database
scv_tr_db *m_db; scv_tr_db *m_db;
//! blocking transaction recording stream handle //! blocking transaction recording stream handle
scv_tr_stream *stream_handle; scv_tr_stream *stream_handle;
//! transaction generator handle for blocking transactions //! transaction generator handle for blocking transactions
scv_tr_generator<_scv_tr_generator_default_data,_scv_tr_generator_default_data> *instr_tr_handle; scv_tr_generator<_scv_tr_generator_default_data, _scv_tr_generator_default_data> *instr_tr_handle;
scv_tr_generator<uint64_t,_scv_tr_generator_default_data> *fetch_tr_handle; scv_tr_generator<uint64_t, _scv_tr_generator_default_data> *fetch_tr_handle;
scv_tr_handle tr_handle; scv_tr_handle tr_handle;
#endif #endif
}; };
} /* namespace SiFive */ } /* namespace SiFive */

View File

@ -1,70 +1,67 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#include "scc/report.h" #include "sysc/core_complex.h"
#include "iss/arch/riscv_hart_msu_vp.h" #include "iss/arch/riscv_hart_msu_vp.h"
#include "iss/arch/rv32imac.h" #include "iss/arch/rv32imac.h"
#include "iss/debugger/encoderdecoder.h"
#include "iss/debugger/gdb_session.h"
#include "iss/debugger/server.h"
#include "iss/debugger/target_adapter_if.h"
#include "iss/iss.h" #include "iss/iss.h"
#include "iss/vm_types.h" #include "iss/vm_types.h"
#include "iss/debugger/server.h" #include "scc/report.h"
#include "iss/debugger/gdb_session.h" #include <sstream>
#include "iss/debugger/target_adapter_if.h" #include <iostream>
#include "iss/debugger/encoderdecoder.h"
#include "sysc/core_complex.h"
#ifdef WITH_SCV #ifdef WITH_SCV
#include <scv.h>
#include <array> #include <array>
#include <scv.h>
#endif #endif
namespace sysc { namespace sysc {
namespace SiFive { namespace SiFive {
using namespace std; using namespace std;
using namespace iss; using namespace iss;
using namespace logging;
using namespace sc_core;
namespace { namespace {
iss::debugger::encoder_decoder encdec; iss::debugger::encoder_decoder encdec;
} }
namespace { namespace {
std::array<const char, 4> lvl = { { 'U', 'S', 'H', 'M' } }; std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
std::array<const char*, 16> trap_str = { { std::array<const char*, 16> trap_str = { {
"Instruction address misaligned", "Instruction address misaligned",
@ -96,121 +93,126 @@ public:
using base_type = arch::riscv_hart_msu_vp<arch::rv32imac>; using base_type = arch::riscv_hart_msu_vp<arch::rv32imac>;
using phys_addr_t = typename arch::traits<arch::rv32imac>::phys_addr_t; using phys_addr_t = typename arch::traits<arch::rv32imac>::phys_addr_t;
core_wrapper(core_complex *owner) core_wrapper(core_complex *owner)
: owner(owner) : owner(owner) {}
{}
uint32_t get_mode(){ return this->reg.machine_state; } uint32_t get_mode() { return this->reg.machine_state; }
inline inline void set_interrupt_execution(bool v) { this->interrupt_sim = v; }
void set_interrupt_execution(bool v){ this->interrupt_sim=v;}
inline inline bool get_interrupt_execution() { return this->interrupt_sim; }
bool get_interrupt_execution(){ return this->interrupt_sim;}
base_type::hart_state<base_type::reg_t>& get_state() { return this->state; } base_type::hart_state<base_type::reg_t> &get_state() { return this->state; }
void notify_phase(exec_phase p) override { void notify_phase(exec_phase p) override {
if(p == ISTART) owner->sync(this->reg.icount+cycle_offset); if (p == ISTART) owner->sync(this->reg.icount + cycle_offset);
} }
sync_type needed_sync() const override { return PRE_SYNC; } sync_type needed_sync() const override { return PRE_SYNC; }
void disass_output(uint64_t pc, const std::string instr) override { void disass_output(uint64_t pc, const std::string instr) override {
if (logging::INFO <= logging::Log<logging::Output2FILE<logging::disass>>::reporting_level() && logging::Output2FILE<logging::disass>::stream()){ if (INFO <= Log<Output2FILE<disass>>::reporting_level() && Output2FILE<disass>::stream()) {
std::stringstream s; std::stringstream s;
s << "[p:" << lvl[this->reg.machine_state] << ";s:0x" << std::hex << std::setfill('0') s << "[p:" << lvl[this->reg.machine_state] << ";s:0x" << std::hex << std::setfill('0')
<< std::setw(sizeof(reg_t) * 2) << (reg_t)state.mstatus << std::dec << ";c:" << this->reg.icount << "]"; << std::setw(sizeof(reg_t) * 2) << (reg_t)state.mstatus << std::dec << ";c:" << this->reg.icount << "]";
scc::Log<logging::Output2FILE<logging::disass>>().get(logging::INFO, "disass") Log<Output2FILE<disass>>().get(INFO, "disass")
<< "0x"<<std::setw(16)<<std::setfill('0')<<std::hex<<pc<<"\t\t"<<std::setw(40)<<std::setfill(' ')<<std::left<<instr<<s.str(); << "0x" << std::setw(16) << std::right << std::setfill('0') << std::hex << pc << "\t\t" << std::setw(40)
} << std::setfill(' ') << std::left << instr << s.str();
owner->disass_output(pc,instr); }
owner->disass_output(pc, instr);
}; };
status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data) { status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data) override {
if (addr.access && access_type::DEBUG) if (addr.access && access_type::DEBUG)
return owner->read_mem_dbg(addr.val, length, data) ? Ok : Err; return owner->read_mem_dbg(addr.val, length, data) ? Ok : Err;
else { else {
return owner->read_mem(addr.val, length, data,addr.access && access_type::FETCH) ? Ok : Err; return owner->read_mem(addr.val, length, data, addr.access && access_type::FETCH) ? Ok : Err;
} }
} }
status write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data) { status write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data) override {
if (addr.access && access_type::DEBUG) if (addr.access && access_type::DEBUG)
return owner->write_mem_dbg(addr.val, length, data) ? Ok : Err; return owner->write_mem_dbg(addr.val, length, data) ? Ok : Err;
else{ else {
auto res = owner->write_mem(addr.val, length, data) ? Ok : Err; auto res = owner->write_mem(addr.val, length, data) ? Ok : Err;
// clear MTIP on mtimecmp write // clear MTIP on mtimecmp write
if(addr.val==0x2004000){ if (addr.val == 0x2004000) {
reg_t val; reg_t val;
this->read_csr(arch::mip, val); this->read_csr(arch::mip, val);
this->write_csr(arch::mip, val & ~(1ULL<<7)); if (val & (1ULL << 7)) this->write_csr(arch::mip, val & ~(1ULL << 7));
} }
return res; return res;
} }
} }
void wait_until(uint64_t flags) { void wait_until(uint64_t flags) override {
do{ SCDEBUG(owner->name()) << "Sleeping until interrupt";
wait(wfi_evt); do {
this->check_interrupt(); wait(wfi_evt);
} while(this->reg.pending_trap==0); } while (this->reg.pending_trap == 0);
base_type::wait_until(flags); base_type::wait_until(flags);
} }
void local_irq(short id){ void local_irq(short id, bool value) {
switch(id){ base_type::reg_t mask = 0;
case 16: // SW switch (id) {
this->csr[arch::mip] |= 1<<3; case 16: // SW
break; mask = 1 << 3;
case 17: // timer break;
this->csr[arch::mip] |= 1<<7; case 17: // timer
break; mask = 1 << 7;
case 18: //external break;
this->csr[arch::mip] |= 1<<11; case 18: // external
break; mask = 1 << 11;
default: break;
/* do nothing*/ default:
break; /* do nothing*/
} break;
wfi_evt.notify(); }
if (value) {
this->csr[arch::mip] |= mask;
wfi_evt.notify();
} else
this->csr[arch::mip] &= ~mask;
this->check_interrupt();
} }
private: private:
core_complex *const owner; core_complex *const owner;
sc_event wfi_evt; sc_event wfi_evt;
}; };
int cmd_sysc(int argc, char* argv[], debugger::out_func of, debugger::data_func df, debugger::target_adapter_if* tgt_adapter){ int cmd_sysc(int argc, char *argv[], debugger::out_func of, debugger::data_func df,
if(argc>1) { debugger::target_adapter_if *tgt_adapter) {
if(strcasecmp(argv[1], "print_time")==0){ if (argc > 1) {
std::string t = sc_core::sc_time_stamp().to_string(); if (strcasecmp(argv[1], "print_time") == 0) {
std::string t = sc_time_stamp().to_string();
of(t.c_str()); of(t.c_str());
std::array<char, 64> buf; std::array<char, 64> buf;
encdec.enc_string(t.c_str(), buf.data(), 63); encdec.enc_string(t.c_str(), buf.data(), 63);
df(buf.data()); df(buf.data());
return Ok; return Ok;
} else if(strcasecmp(argv[1], "break")==0){ } else if (strcasecmp(argv[1], "break") == 0) {
sc_core::sc_time t; sc_time t;
if(argc==4){ if (argc == 4) {
t= scc::parse_from_string(argv[2], argv[3]); t = scc::parse_from_string(argv[2], argv[3]);
} else if(argc==3){ } else if (argc == 3) {
t= scc::parse_from_string(argv[2]); t = scc::parse_from_string(argv[2]);
} else } else
return Err; return Err;
// no check needed as it is only called if debug server is active // no check needed as it is only called if debug server is active
tgt_adapter->add_break_condition([t]()->unsigned{ tgt_adapter->add_break_condition([t]() -> unsigned {
LOG(TRACE)<<"Checking condition at "<<sc_core::sc_time_stamp(); SCTRACE() << "Checking condition at " << sc_time_stamp();
return sc_core::sc_time_stamp()>=t?std::numeric_limits<unsigned>::max():0; return sc_time_stamp() >= t ? std::numeric_limits<unsigned>::max() : 0;
}); });
return Ok; return Ok;
} }
return Err; return Err;
} }
return Err; return Err;
} }
core_complex::core_complex(sc_core::sc_module_name name) core_complex::core_complex(sc_module_name name)
: sc_core::sc_module(name) : sc_module(name)
, NAMED(initiator) , NAMED(initiator)
, NAMED(clk_i) , NAMED(clk_i)
, NAMED(rst_i) , NAMED(rst_i)
@ -250,100 +252,96 @@ core_complex::core_complex(sc_core::sc_module_name name)
SC_METHOD(rst_cb); SC_METHOD(rst_cb);
sensitive << rst_i; sensitive << rst_i;
SC_METHOD(sw_irq_cb); SC_METHOD(sw_irq_cb);
sensitive<<sw_irq_i; sensitive << sw_irq_i;
SC_METHOD(timer_irq_cb); SC_METHOD(timer_irq_cb);
sensitive<<timer_irq_i; sensitive << timer_irq_i;
SC_METHOD(global_irq_cb); SC_METHOD(global_irq_cb);
sensitive<<global_irq_i; sensitive << global_irq_i;
} }
core_complex::~core_complex() = default; core_complex::~core_complex() = default;
void core_complex::trace(sc_core::sc_trace_file *trf) {} void core_complex::trace(sc_trace_file *trf) const {}
void core_complex::before_end_of_elaboration() { void core_complex::before_end_of_elaboration() {
cpu = make_unique<core_wrapper>(this); cpu = std::make_unique<core_wrapper>(this);
vm = create<arch::rv32imac>(cpu.get(), gdb_server_port.get_value(), dump_ir.get_value()); vm = create<arch::rv32imac>(cpu.get(), gdb_server_port.get_value(), dump_ir.get_value());
#ifdef WITH_SCV #ifdef WITH_SCV
vm->setDisassEnabled(enable_disass.get_value() || m_db!=nullptr); vm->setDisassEnabled(enable_disass.get_value() || m_db != nullptr);
#else #else
vm->setDisassEnabled(enable_disass.get_value()); vm->setDisassEnabled(enable_disass.get_value());
#endif #endif
auto* srv = debugger::server<debugger::gdb_session>::get(); auto *srv = debugger::server<debugger::gdb_session>::get();
if(srv) tgt_adapter = srv->get_target(); if (srv) tgt_adapter = srv->get_target();
if(tgt_adapter) if (tgt_adapter)
tgt_adapter->add_custom_command({ tgt_adapter->add_custom_command(
"sysc", {"sysc", [this](int argc, char *argv[], debugger::out_func of,
[this](int argc, char* argv[], debugger::out_func of, debugger::data_func df)-> int { debugger::data_func df) -> int { return cmd_sysc(argc, argv, of, df, tgt_adapter); },
return cmd_sysc(argc, argv, of, df, tgt_adapter); "SystemC sub-commands: break <time>, print_time"});
},
"SystemC sub-commands: break <time>, print_time"});
} }
void core_complex::start_of_simulation() { void core_complex::start_of_simulation() {
quantum_keeper.reset(); quantum_keeper.reset();
if (elf_file.get_value().size() > 0){ if (elf_file.get_value().size() > 0) {
std::pair<uint64_t,bool> start_addr=cpu->load_file(elf_file.get_value()); istringstream is(elf_file.get_value());
if(reset_address.is_default_value() && start_addr.second==true) reset_address.set_value(start_addr.first); string s;
while (getline(is, s, ',')) {
std::pair<uint64_t, bool> start_addr = cpu->load_file(s);
if (reset_address.is_default_value() && start_addr.second == true)
reset_address.set_value(start_addr.first);
}
} }
#ifdef WITH_SCV #ifdef WITH_SCV
if (m_db!=nullptr && stream_handle == nullptr) { if (m_db != nullptr && stream_handle == nullptr) {
string basename(this->name()); string basename(this->name());
stream_handle = new scv_tr_stream((basename + ".instr").c_str(), "TRANSACTOR", m_db); stream_handle = new scv_tr_stream((basename + ".instr").c_str(), "TRANSACTOR", m_db);
instr_tr_handle = new scv_tr_generator<>("execute", *stream_handle); instr_tr_handle = new scv_tr_generator<>("execute", *stream_handle);
fetch_tr_handle = new scv_tr_generator<uint64_t>("fetch", *stream_handle); fetch_tr_handle = new scv_tr_generator<uint64_t>("fetch", *stream_handle);
} }
#endif #endif
} }
void core_complex::disass_output(uint64_t pc, const std::string instr_str) { void core_complex::disass_output(uint64_t pc, const std::string instr_str) {
#ifdef WITH_SCV #ifdef WITH_SCV
if (m_db==nullptr) return; if (m_db == nullptr) return;
if(tr_handle.is_active()) tr_handle.end_transaction(); if (tr_handle.is_active()) tr_handle.end_transaction();
tr_handle = instr_tr_handle->begin_transaction(); tr_handle = instr_tr_handle->begin_transaction();
tr_handle.record_attribute("PC", pc); tr_handle.record_attribute("PC", pc);
tr_handle.record_attribute("INSTR", instr_str); tr_handle.record_attribute("INSTR", instr_str);
tr_handle.record_attribute("MODE", lvl[cpu->get_mode()]); tr_handle.record_attribute("MODE", lvl[cpu->get_mode()]);
tr_handle.record_attribute("MSTATUS", cpu->get_state().mstatus.st.value); tr_handle.record_attribute("MSTATUS", cpu->get_state().mstatus.st.value);
tr_handle.record_attribute("LTIME_START", quantum_keeper.get_current_time().value()/1000); tr_handle.record_attribute("LTIME_START", quantum_keeper.get_current_time().value() / 1000);
#endif #endif
} }
void core_complex::clk_cb() { void core_complex::clk_cb() {
curr_clk = clk_i.read(); curr_clk = clk_i.read();
if(curr_clk==SC_ZERO_TIME) cpu->set_interrupt_execution(true); if (curr_clk == SC_ZERO_TIME) cpu->set_interrupt_execution(true);
} }
void core_complex::rst_cb() { void core_complex::rst_cb() {
if(rst_i.read()) if (rst_i.read()) cpu->set_interrupt_execution(true);
cpu->set_interrupt_execution(true);
} }
void core_complex::sw_irq_cb(){ void core_complex::sw_irq_cb() { cpu->local_irq(16, sw_irq_i.read()); }
if(sw_irq_i.read()) cpu->local_irq(16);
}
void core_complex::timer_irq_cb(){ void core_complex::timer_irq_cb() { cpu->local_irq(17, timer_irq_i.read()); }
if(timer_irq_i.read()) cpu->local_irq(17);
}
void core_complex::global_irq_cb(){ void core_complex::global_irq_cb() { cpu->local_irq(18, global_irq_i.read()); }
if(timer_irq_i.read()) cpu->local_irq(18);
}
void core_complex::run() { void core_complex::run() {
wait(SC_ZERO_TIME); // separate from elaboration phase wait(SC_ZERO_TIME); // separate from elaboration phase
do{ do {
if(rst_i.read()){ if (rst_i.read()) {
cpu->reset(reset_address.get_value()); cpu->reset(reset_address.get_value());
wait(rst_i.negedge_event()); wait(rst_i.negedge_event());
} }
while(clk_i.read()==SC_ZERO_TIME){ while (clk_i.read() == SC_ZERO_TIME) {
wait(clk_i.value_changed_event()); wait(clk_i.value_changed_event());
} }
cpu->set_interrupt_execution(false); cpu->set_interrupt_execution(false);
vm->start(); vm->start();
} while(cpu->get_interrupt_execution()); } while (cpu->get_interrupt_execution());
sc_stop(); sc_stop();
} }
@ -362,10 +360,10 @@ bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t *const data,
gp.set_data_ptr(data); gp.set_data_ptr(data);
gp.set_data_length(length); gp.set_data_length(length);
gp.set_streaming_width(length); gp.set_streaming_width(length);
auto delay{quantum_keeper.get_local_time()}; sc_time delay{quantum_keeper.get_local_time()};
#ifdef WITH_SCV #ifdef WITH_SCV
if(m_db!=nullptr && tr_handle.is_valid()){ if (m_db != nullptr && tr_handle.is_valid()) {
if(is_fetch && tr_handle.is_active()){ if (is_fetch && tr_handle.is_active()) {
tr_handle.end_transaction(); tr_handle.end_transaction();
} }
auto preExt = new scv4tlm::tlm_recording_extension(tr_handle, this); auto preExt = new scv4tlm::tlm_recording_extension(tr_handle, this);
@ -373,7 +371,7 @@ bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t *const data,
} }
#endif #endif
initiator->b_transport(gp, delay); initiator->b_transport(gp, delay);
LOG(TRACE) << "read_mem(0x" << std::hex << addr << ") : " << data; SCTRACE(this->name()) << "read_mem(0x" << std::hex << addr << ") : " << data;
if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) { if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) {
return false; return false;
} }
@ -411,16 +409,16 @@ bool core_complex::write_mem(uint64_t addr, unsigned length, const uint8_t *cons
gp.set_data_ptr(write_buf.data()); gp.set_data_ptr(write_buf.data());
gp.set_data_length(length); gp.set_data_length(length);
gp.set_streaming_width(length); gp.set_streaming_width(length);
auto delay{quantum_keeper.get_local_time()}; sc_time delay{quantum_keeper.get_local_time()};
#ifdef WITH_SCV #ifdef WITH_SCV
if(m_db!=nullptr && tr_handle.is_valid()){ if (m_db != nullptr && tr_handle.is_valid()) {
auto preExt = new scv4tlm::tlm_recording_extension(tr_handle, this); auto preExt = new scv4tlm::tlm_recording_extension(tr_handle, this);
gp.set_extension(preExt); gp.set_extension(preExt);
} }
#endif #endif
initiator->b_transport(gp, delay); initiator->b_transport(gp, delay);
quantum_keeper.set(delay); quantum_keeper.set(delay);
LOG(TRACE) << "write_mem(0x" << std::hex << addr << ") : " << data; SCTRACE() << "write_mem(0x" << std::hex << addr << ") : " << data;
if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) { if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) {
return false; return false;
} }

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>riscv</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
</natures>
</projectDescription>

View File

@ -1 +0,0 @@
/com.minres.coredsl.CoreDsl.prefs

View File

@ -10,37 +10,10 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
# Set the name of your project here # Set the name of your project here
project("riscv") project("riscv")
# Set the version number of your project here (format is MAJOR.MINOR.PATCHLEVEL - e.g. 1.0.0)
set(VERSION_MAJOR "0")
set(VERSION_MINOR "0")
set(VERSION_PATCH "1")
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
include(Common) include(Common)
## Git (and its revision)
find_package(Git QUIET) # if we don't find git or FindGit.cmake is not on the system we ignore it.
## The Git module will trigger a reconfiguration for each pull that will bring a new revision on the local repository
set (VCS_REVISION "-1")
if(GIT_FOUND)
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REFSPEC GIT_SHA1)
message(STATUS "GIT branch ${GIT_REFSPEC}")
message(STATUS "GIT revision ${GIT_SHA1}")
set (VCS_REVISION ${GIT_SHA1})
endif()
conan_basic_setup() conan_basic_setup()
# This line finds the boost lib and headers.
set(Boost_NO_BOOST_CMAKE ON) # Don't do a find_package in config mode before searching for a regular boost install.
find_package(Boost COMPONENTS program_options system thread REQUIRED)
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
llvm_map_components_to_libnames(llvm_libs support core mcjit x86codegen x86asmparser)
# This sets the include directory for the reference project. This is the -I flag in gcc. # This sets the include directory for the reference project. This is the -I flag in gcc.
include_directories( include_directories(
${PROJECT_SOURCE_DIR}/incl ${PROJECT_SOURCE_DIR}/incl

View File

@ -143,19 +143,19 @@ InsructionSet RV32IBase {
if (rd != 0) X[rd] <= choose(X[rs1]'u < full_imm'u, 1, 0); if (rd != 0) X[rd] <= choose(X[rs1]'u < full_imm'u, 1, 0);
} }
XORI { XORI {
encoding: imm[11:0] | rs1[4:0] | b100 | rd[4:0] | b0010011; encoding: imm[11:0]s | rs1[4:0] | b100 | rd[4:0] | b0010011;
args_disass:"x%rd$d, x%rs1$d, %imm%"; args_disass:"x%rd$d, x%rs1$d, %imm%";
if(rd != 0) X[rd] <= X[rs1] ^ imm; if(rd != 0) X[rd] <= X[rs1]s ^ imm;
} }
ORI { ORI {
encoding: imm[11:0] | rs1[4:0] | b110 | rd[4:0] | b0010011; encoding: imm[11:0]s | rs1[4:0] | b110 | rd[4:0] | b0010011;
args_disass:"x%rd$d, x%rs1$d, %imm%"; args_disass:"x%rd$d, x%rs1$d, %imm%";
if(rd != 0) X[rd] <= X[rs1] | imm; if(rd != 0) X[rd] <= X[rs1]s | imm;
} }
ANDI { ANDI {
encoding: imm[11:0] | rs1[4:0] | b111 | rd[4:0] | b0010011; encoding: imm[11:0]s | rs1[4:0] | b111 | rd[4:0] | b0010011;
args_disass:"x%rd$d, x%rs1$d, %imm%"; args_disass:"x%rd$d, x%rs1$d, %imm%";
if(rd != 0) X[rd] <= X[rs1] & imm; if(rd != 0) X[rd] <= X[rs1]s & imm;
} }
SLLI { SLLI {
encoding: b0000000 | shamt[4:0] | rs1[4:0] | b001 | rd[4:0] | b0010011; encoding: b0000000 | shamt[4:0] | rs1[4:0] | b001 | rd[4:0] | b0010011;

View File

@ -1,38 +1,34 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial API and implementation
//
//
////////////////////////////////////////////////////////////////////////////////
#include <iss/arch/CORE_DEF_NAME.h> #include <iss/arch/CORE_DEF_NAME.h>
#include <iss/arch/riscv_hart_msu_vp.h> #include <iss/arch/riscv_hart_msu_vp.h>
@ -44,8 +40,8 @@
#include <boost/format.hpp> #include <boost/format.hpp>
#include <iss/debugger/riscv_target_adapter.h>
#include <array> #include <array>
#include <iss/debugger/riscv_target_adapter.h>
namespace iss { namespace iss {
namespace CORE_DEF_NAME { namespace CORE_DEF_NAME {
@ -101,14 +97,13 @@ protected:
void gen_trap_check(llvm::BasicBlock *bb); void gen_trap_check(llvm::BasicBlock *bb);
inline llvm::Value *gen_reg_load(unsigned i, unsigned level = 0) { inline llvm::Value *gen_reg_load(unsigned i, unsigned level = 0) {
return this->builder.CreateLoad(get_reg_ptr(i), false); return this->builder.CreateLoad(get_reg_ptr(i), false);
} }
inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) { inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) {
llvm::Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits<ARCH>::XLEN, pc.val), llvm::Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits<ARCH>::XLEN, pc.val),
this->get_type(traits<ARCH>::XLEN)); this->get_type(traits<ARCH>::XLEN));
this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true); this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true);
} }
@ -127,9 +122,9 @@ protected:
std::array<compile_func, LUT_SIZE_C> lut_00, lut_01, lut_10; std::array<compile_func, LUT_SIZE_C> lut_00, lut_01, lut_10;
std::array<compile_func, LUT_SIZE> lut_11; std::array<compile_func, LUT_SIZE> lut_11;
std::array<compile_func*, 4> qlut; std::array<compile_func *, 4> qlut;
std::array<const uint32_t, 4> lutmasks = { { EXTR_MASK16, EXTR_MASK16, EXTR_MASK16, EXTR_MASK32 } }; std::array<const uint32_t, 4> lutmasks = {{EXTR_MASK16, EXTR_MASK16, EXTR_MASK16, EXTR_MASK32}};
void expand_bit_mask(int pos, uint32_t mask, uint32_t value, uint32_t valid, uint32_t idx, compile_func lut[], void expand_bit_mask(int pos, uint32_t mask, uint32_t value, uint32_t valid, uint32_t idx, compile_func lut[],
compile_func f) { compile_func f) {
@ -180,23 +175,23 @@ private:
}; };
/* «start generated code» */ /* «start generated code» */
std::array<InstructionDesriptor, 0> instr_descr = { { } }; std::array<InstructionDesriptor, 0> instr_descr = {{}};
/* «end generated code» */ /* «end generated code» */
/**************************************************************************** /****************************************************************************
* end opcode definitions * end opcode definitions
****************************************************************************/ ****************************************************************************/
std::tuple<vm::continuation_e, llvm::BasicBlock *> illegal_intruction(virt_addr_t &pc, code_word_t instr, std::tuple<vm::continuation_e, llvm::BasicBlock *> illegal_intruction(virt_addr_t &pc, code_word_t instr,
llvm::BasicBlock *bb) { llvm::BasicBlock *bb) {
this->gen_sync(iss::PRE_SYNC, instr_descr.size()); this->gen_sync(iss::PRE_SYNC, instr_descr.size());
this->builder.CreateStore(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::NEXT_PC), true), this->builder.CreateStore(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::NEXT_PC), true),
get_reg_ptr(traits<ARCH>::PC), true); get_reg_ptr(traits<ARCH>::PC), true);
this->builder.CreateStore( this->builder.CreateStore(
this->builder.CreateAdd(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::ICOUNT), true), this->builder.CreateAdd(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::ICOUNT), true),
this->gen_const(64U, 1)), this->gen_const(64U, 1)),
get_reg_ptr(traits<ARCH>::ICOUNT), true); get_reg_ptr(traits<ARCH>::ICOUNT), true);
pc = pc + ((instr & 3) == 3 ? 4 : 2); pc = pc + ((instr & 3) == 3 ? 4 : 2);
this->gen_raise_trap(0, 2); // illegal instruction trap this->gen_raise_trap(0, 2); // illegal instruction trap
this->gen_sync(iss::POST_SYNC, instr_descr.size()); this->gen_sync(iss::POST_SYNC, instr_descr.size());
this->gen_trap_check(this->leave_blk); this->gen_trap_check(this->leave_blk);
return std::make_tuple(iss::vm::BRANCH, nullptr); return std::make_tuple(iss::vm::BRANCH, nullptr);
} }
@ -245,7 +240,7 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
} catch (trap_access &ta) { } catch (trap_access &ta) {
throw trap_access(ta.id, pc.val); throw trap_access(ta.id, pc.val);
} }
if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' if (insn == 0x0000006f || (insn & 0xffff) == 0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
// curr pc on stack // curr pc on stack
typename vm_impl<ARCH>::processing_pc_entry addr(*this, pc, paddr); typename vm_impl<ARCH>::processing_pc_entry addr(*this, pc, paddr);
++inst_cnt; ++inst_cnt;

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018, MINRES Technologies GmbH
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -37,21 +37,26 @@
#include "iss/arch/traits.h" #include "iss/arch/traits.h"
#include "iss/arch_if.h" #include "iss/arch_if.h"
#include "iss/instrumentation_if.h"
#include "iss/log_categories.h" #include "iss/log_categories.h"
#include "iss/vm_if.h" #include "iss/vm_if.h"
#include "iss/instrumentation_if.h" #include <array>
#include <elfio/elfio.hpp> #include <elfio/elfio.hpp>
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
#include <type_traits>
#include <unordered_map> #include <unordered_map>
#include <util/bit_field.h>
#include <util/ities.h> #include <util/ities.h>
#include <util/sparse_array.h> #include <util/sparse_array.h>
#include <util/bit_field.h>
#include <array>
#include <type_traits>
#define likely(x) __builtin_expect(!!(x), 1) #if defined(__GNUC__)
#define unlikely(x) __builtin_expect(!!(x), 0) #define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#else
#define likely(x) x
#define unlikely(x) x
#endif
namespace iss { namespace iss {
namespace arch { namespace arch {
@ -165,29 +170,29 @@ enum riscv_csr {
namespace { namespace {
std::array<const char, 4> lvl = { { 'U', 'S', 'H', 'M' } }; std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
std::array<const char*, 16> trap_str = { { "" std::array<const char *, 16> trap_str = {{""
"Instruction address misaligned", //0 "Instruction address misaligned", // 0
"Instruction access fault", //1 "Instruction access fault", // 1
"Illegal instruction", //2 "Illegal instruction", // 2
"Breakpoint", //3 "Breakpoint", // 3
"Load address misaligned", //4 "Load address misaligned", // 4
"Load access fault", //5 "Load access fault", // 5
"Store/AMO address misaligned", //6 "Store/AMO address misaligned", // 6
"Store/AMO access fault", //7 "Store/AMO access fault", // 7
"Environment call from U-mode", //8 "Environment call from U-mode", // 8
"Environment call from S-mode", //9 "Environment call from S-mode", // 9
"Reserved", //a "Reserved", // a
"Environment call from M-mode", //b "Environment call from M-mode", // b
"Instruction page fault", //c "Instruction page fault", // c
"Load page fault", //d "Load page fault", // d
"Reserved", //e "Reserved", // e
"Store/AMO page fault" } }; "Store/AMO page fault"}};
std::array<const char*, 12> irq_str = { { std::array<const char *, 12> irq_str = {
"User software interrupt", "Supervisor software interrupt", "Reserved", "Machine software interrupt", {"User software interrupt", "Supervisor software interrupt", "Reserved", "Machine software interrupt",
"User timer interrupt", "Supervisor timer interrupt", "Reserved", "Machine timer interrupt", "User external interrupt", "User timer interrupt", "Supervisor timer interrupt", "Reserved", "Machine timer interrupt",
"Supervisor external interrupt", "Reserved", "Machine external interrupt" } }; "User external interrupt", "Supervisor external interrupt", "Reserved", "Machine external interrupt"}};
enum { enum {
PGSHIFT = 12, PGSHIFT = 12,
@ -229,7 +234,7 @@ struct vm_info {
int idxbits; int idxbits;
int ptesize; int ptesize;
uint64_t ptbase; uint64_t ptbase;
bool is_active() { return levels;} bool is_active() { return levels; }
}; };
class trap_load_access_fault : public trap_access { class trap_load_access_fault : public trap_access {
@ -272,10 +277,9 @@ public:
using wr_csr_f = iss::status (this_class::*)(unsigned addr, reg_t); using wr_csr_f = iss::status (this_class::*)(unsigned addr, reg_t);
// primary template // primary template
template<class T, class Enable = void> struct hart_state { }; template <class T, class Enable = void> struct hart_state {};
// specialization 32bit // specialization 32bit
template <typename T> template <typename T> class hart_state<T, typename std::enable_if<std::is_same<T, uint32_t>::value>::type> {
class hart_state<T, typename std::enable_if<std::is_same<T, uint32_t>::value>::type> {
public: public:
BEGIN_BF_DECL(mstatus_t, T); BEGIN_BF_DECL(mstatus_t, T);
// SD bit is read-only and is set when either the FS or XS bits encode a Dirty state (i.e., SD=((FS==11) OR XS==11))) // SD bit is read-only and is set when either the FS or XS bits encode a Dirty state (i.e., SD=((FS==11) OR XS==11)))
@ -318,10 +322,10 @@ public:
static const reg_t mstatus_reset_val = 0; static const reg_t mstatus_reset_val = 0;
void write_mstatus(T val, unsigned priv_lvl){ void write_mstatus(T val, unsigned priv_lvl) {
auto mask = get_mask(priv_lvl); auto mask = get_mask(priv_lvl);
auto new_val = (mstatus.st.value & ~mask) | (val & mask); auto new_val = (mstatus.st.value & ~mask) | (val & mask);
mstatus=new_val; mstatus = new_val;
} }
T satp; T satp;
@ -329,11 +333,15 @@ public:
static constexpr T get_misa() { return (1UL << 30) | ISA_I | ISA_M | ISA_A | ISA_U | ISA_S | ISA_M; } static constexpr T get_misa() { return (1UL << 30) | ISA_I | ISA_M | ISA_A | ISA_U | ISA_S | ISA_M; }
static constexpr uint32_t get_mask(unsigned priv_lvl) { static constexpr uint32_t get_mask(unsigned priv_lvl) {
#if __cplusplus < 201402L
return priv_lvl == PRIV_U ? 0x80000011UL : priv_lvl == PRIV_S ? 0x800de133UL : 0x807ff9ddUL;
#else
switch (priv_lvl) { switch (priv_lvl) {
case PRIV_U: return 0x80000011UL; // 0b1000 0000 0000 0000 0000 0000 0001 0001 case PRIV_U: return 0x80000011UL; // 0b1000 0000 0000 0000 0000 0000 0001 0001
case PRIV_S: return 0x800de133UL; // 0b1000 0000 0000 1101 1110 0001 0011 0011 case PRIV_S: return 0x800de133UL; // 0b1000 0000 0000 1101 1110 0001 0011 0011
default: return 0x807ff9ddUL; // 0b1000 0000 0111 1111 1111 1001 1011 1011 default: return 0x807ff9ddUL; // 0b1000 0000 0111 1111 1111 1001 1011 1011
} }
#endif
} }
static inline vm_info decode_vm_info(uint32_t state, T sptbr) { static inline vm_info decode_vm_info(uint32_t state, T sptbr) {
@ -349,8 +357,7 @@ public:
} }
}; };
// specialization 64bit // specialization 64bit
template <typename T> template <typename T> class hart_state<T, typename std::enable_if<std::is_same<T, uint64_t>::value>::type> {
class hart_state<T, typename std::enable_if<std::is_same<T, uint64_t>::value>::type> {
public: public:
BEGIN_BF_DECL(mstatus_t, T); BEGIN_BF_DECL(mstatus_t, T);
// SD bit is read-only and is set when either the FS or XS bits encode a Dirty state (i.e., SD=((FS==11) OR XS==11))) // SD bit is read-only and is set when either the FS or XS bits encode a Dirty state (i.e., SD=((FS==11) OR XS==11)))
@ -397,17 +404,17 @@ public:
static const reg_t mstatus_reset_val = 0xa00000000; static const reg_t mstatus_reset_val = 0xa00000000;
void write_mstatus(T val, unsigned priv_lvl){ void write_mstatus(T val, unsigned priv_lvl) {
T old_val = mstatus; T old_val = mstatus;
auto mask = get_mask(priv_lvl); auto mask = get_mask(priv_lvl);
auto new_val = (old_val & ~mask) | (val & mask); auto new_val = (old_val & ~mask) | (val & mask);
if((new_val&mstatus.SXL.Mask)==0){ if ((new_val & mstatus.SXL.Mask) == 0) {
new_val |= old_val&mstatus.SXL.Mask; new_val |= old_val & mstatus.SXL.Mask;
} }
if((new_val&mstatus.UXL.Mask)==0){ if ((new_val & mstatus.UXL.Mask) == 0) {
new_val |= old_val&mstatus.UXL.Mask; new_val |= old_val & mstatus.UXL.Mask;
} }
mstatus=new_val; mstatus = new_val;
} }
T satp; T satp;
@ -426,9 +433,9 @@ public:
if (state == PRIV_M) return {0, 0, 0, 0}; if (state == PRIV_M) return {0, 0, 0, 0};
if (state <= PRIV_S) if (state <= PRIV_S)
switch (bit_sub<60, 4>(sptbr)) { switch (bit_sub<60, 4>(sptbr)) {
case 0: return {0, 0, 0, 0}; // off case 0: return {0, 0, 0, 0}; // off
case 8: return {3, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT};// SV39 case 8: return {3, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT};// SV39
case 9: return {4, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT};// SV48 case 9: return {4, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT};// SV48
case 10: return {5, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT};// SV57 case 10: return {5, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT};// SV57
case 11: return {6, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT};// SV64 case 11: return {6, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT};// SV64
default: abort(); default: abort();
@ -442,12 +449,12 @@ public:
const typename super::reg_t PGMASK = PGSIZE - 1; const typename super::reg_t PGMASK = PGSIZE - 1;
constexpr reg_t get_irq_mask(size_t mode) { constexpr reg_t get_irq_mask(size_t mode) {
std::array<const reg_t,4> m = { { std::array<const reg_t, 4> m = {{
0b000100010001,// U mode 0b000100010001, // U mode
0b001100110011,// S mode 0b001100110011, // S mode
0, 0,
0b101110111011 // M mode 0b101110111011 // M mode
}}; }};
return m[mode]; return m[mode];
} }
@ -456,7 +463,7 @@ public:
void reset(uint64_t address) override; void reset(uint64_t address) override;
std::pair<uint64_t,bool> load_file(std::string name, int type = -1) override; std::pair<uint64_t, bool> load_file(std::string name, int type = -1) override;
virtual phys_addr_t virt2phys(const iss::addr_t &addr) override; virtual phys_addr_t virt2phys(const iss::addr_t &addr) override;
@ -468,40 +475,39 @@ public:
virtual uint64_t leave_trap(uint64_t flags) override; virtual uint64_t leave_trap(uint64_t flags) override;
void wait_until(uint64_t flags) override; void wait_until(uint64_t flags) override;
void disass_output(uint64_t pc, const std::string instr) override { void disass_output(uint64_t pc, const std::string instr) override {
std::stringstream s; std::stringstream s;
s << "[p:" << lvl[this->reg.machine_state] << ";s:0x" << std::hex << std::setfill('0') s << "[p:" << lvl[this->reg.machine_state] << ";s:0x" << std::hex << std::setfill('0')
<< std::setw(sizeof(reg_t) * 2) << (reg_t)state.mstatus << std::dec << ";c:" << this->reg.icount << "]"; << std::setw(sizeof(reg_t) * 2) << (reg_t)state.mstatus << std::dec << ";c:" << this->reg.icount << "]";
CLOG(INFO, disass) << "0x"<<std::setw(16)<<std::setfill('0')<<std::hex<<pc<<"\t\t"<<instr<<"\t"<<s.str(); CLOG(INFO, disass) << "0x" << std::setw(16) << std::setfill('0') << std::hex << pc << "\t\t" << instr << "\t" << s.str();
}; };
iss::instrumentation_if* get_instrumentation_if() override {return &instr_if;} iss::instrumentation_if *get_instrumentation_if() override { return &instr_if; }
protected: protected:
struct riscv_instrumentation_if : public iss::instrumentation_if{ struct riscv_instrumentation_if : public iss::instrumentation_if {
riscv_instrumentation_if(riscv_hart_msu_vp<BASE>& arch):arch(arch){} riscv_instrumentation_if(riscv_hart_msu_vp<BASE> &arch)
: arch(arch) {}
/** /**
* get the name of this architecture * get the name of this architecture
* *
* @return the name of this architecture * @return the name of this architecture
*/ */
const std::string core_type_name() const override {return traits<BASE>::core_type;} const std::string core_type_name() const override { return traits<BASE>::core_type; }
virtual uint64_t get_pc(){ return arch.get_pc(); }; virtual uint64_t get_pc() { return arch.get_pc(); };
virtual uint64_t get_next_pc(){ return arch.get_next_pc(); }; virtual uint64_t get_next_pc() { return arch.get_next_pc(); };
virtual void set_curr_instr_cycles(unsigned cycles){ arch.cycle_offset+=cycles-1; }; virtual void set_curr_instr_cycles(unsigned cycles) { arch.cycle_offset += cycles - 1; };
riscv_hart_msu_vp<BASE>& arch; riscv_hart_msu_vp<BASE> &arch;
}; };
friend struct riscv_instrumentation_if; friend struct riscv_instrumentation_if;
addr_t get_pc(){return this->reg.PC;} addr_t get_pc() { return this->reg.PC; }
addr_t get_next_pc(){return this->reg.NEXT_PC;} addr_t get_next_pc() { return this->reg.NEXT_PC; }
virtual iss::status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data); virtual iss::status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data);
virtual iss::status write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data); virtual iss::status write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data);
@ -512,7 +518,7 @@ protected:
hart_state<reg_t> state; hart_state<reg_t> state;
uint64_t cycle_offset; uint64_t cycle_offset;
reg_t fault_data; reg_t fault_data;
std::array<vm_info,2> vm; std::array<vm_info, 2> vm;
uint64_t tohost = tohost_dflt; uint64_t tohost = tohost_dflt;
uint64_t fromhost = fromhost_dflt; uint64_t fromhost = fromhost_dflt;
unsigned to_host_wr_cnt = 0; unsigned to_host_wr_cnt = 0;
@ -541,15 +547,18 @@ private:
iss::status write_ip(unsigned addr, reg_t val); iss::status write_ip(unsigned addr, reg_t val);
iss::status read_satp(unsigned addr, reg_t &val); iss::status read_satp(unsigned addr, reg_t &val);
iss::status write_satp(unsigned addr, reg_t val); iss::status write_satp(unsigned addr, reg_t val);
iss::status read_fcsr(unsigned addr, reg_t& val); iss::status read_fcsr(unsigned addr, reg_t &val);
iss::status write_fcsr(unsigned addr, reg_t val); iss::status write_fcsr(unsigned addr, reg_t val);
protected: protected:
void check_interrupt(); void check_interrupt();
}; };
template <typename BASE> template <typename BASE>
riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp() riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp()
: state(), cycle_offset(0), instr_if(*this) { : state()
, cycle_offset(0)
, instr_if(*this) {
csr[misa] = hart_state<reg_t>::get_misa(); csr[misa] = hart_state<reg_t>::get_misa();
uart_buf.str(""); uart_buf.str("");
// read-only registers // read-only registers
@ -591,27 +600,26 @@ riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp()
csr_wr_cb[fflags] = &riscv_hart_msu_vp<BASE>::write_fcsr; csr_wr_cb[fflags] = &riscv_hart_msu_vp<BASE>::write_fcsr;
csr_rd_cb[frm] = &riscv_hart_msu_vp<BASE>::read_fcsr; csr_rd_cb[frm] = &riscv_hart_msu_vp<BASE>::read_fcsr;
csr_wr_cb[frm] = &riscv_hart_msu_vp<BASE>::write_fcsr; csr_wr_cb[frm] = &riscv_hart_msu_vp<BASE>::write_fcsr;
} }
template <typename BASE> std::pair<uint64_t,bool> riscv_hart_msu_vp<BASE>::load_file(std::string name, int type) { template <typename BASE> std::pair<uint64_t, bool> riscv_hart_msu_vp<BASE>::load_file(std::string name, int type) {
FILE *fp = fopen(name.c_str(), "r"); FILE *fp = fopen(name.c_str(), "r");
if (fp) { if (fp) {
std::array<char, 5> buf; std::array<char, 5> buf;
auto n = fread(buf.data(), 1, 4, fp); auto n = fread(buf.data(), 1, 4, fp);
if (n != 4) throw std::runtime_error("input file has insufficient size"); if (n != 4) throw std::runtime_error("input file has insufficient size");
buf[4] = 0; buf[4] = 0;
if (strcmp(buf.data() + 1, "ELF") == 0) { if (strcmp(buf.data() + 1, "ELF") == 0) {
fclose(fp); fclose(fp);
// Create elfio reader // Create elfio reader
ELFIO::elfio reader; ELFIO::elfio reader;
// Load ELF data // Load ELF data
if (!reader.load(name)) throw std::runtime_error("could not process elf file"); if (!reader.load(name)) throw std::runtime_error("could not process elf file");
// check elf properties // check elf properties
if ( reader.get_class() != ELFCLASS32 ) if (reader.get_class() != ELFCLASS32)
if(sizeof(reg_t) == 4) throw std::runtime_error("wrong elf class in file"); if (sizeof(reg_t) == 4) throw std::runtime_error("wrong elf class in file");
if (reader.get_type() != ET_EXEC) throw std::runtime_error("wrong elf type in file"); if (reader.get_type() != ET_EXEC) throw std::runtime_error("wrong elf type in file");
if ( reader.get_machine() != EM_RISCV ) throw std::runtime_error("wrong elf machine in file"); if (reader.get_machine() != EM_RISCV) throw std::runtime_error("wrong elf machine in file");
for (const auto pseg : reader.segments) { for (const auto pseg : reader.segments) {
const auto fsize = pseg->get_file_size(); // 0x42c/0x0 const auto fsize = pseg->get_file_size(); // 0x42c/0x0
const auto seg_data = pseg->get_data(); const auto seg_data = pseg->get_data();
@ -642,9 +650,9 @@ template <typename BASE>
iss::status riscv_hart_msu_vp<BASE>::read(const iss::addr_t &addr, unsigned length, uint8_t *const data) { iss::status riscv_hart_msu_vp<BASE>::read(const iss::addr_t &addr, unsigned length, uint8_t *const data) {
#ifndef NDEBUG #ifndef NDEBUG
if (addr.access && iss::access_type::DEBUG) { if (addr.access && iss::access_type::DEBUG) {
LOG(DEBUG) << "debug read of " << length << " bytes @addr " << addr; LOG(TRACE) << "debug read of " << length << " bytes @addr " << addr;
} else { } else {
LOG(DEBUG) << "read of " << length << " bytes @addr " << addr; LOG(TRACE) << "read of " << length << " bytes @addr " << addr;
} }
#endif #endif
try { try {
@ -716,26 +724,26 @@ iss::status riscv_hart_msu_vp<BASE>::read(const iss::addr_t &addr, unsigned leng
template <typename BASE> template <typename BASE>
iss::status riscv_hart_msu_vp<BASE>::write(const iss::addr_t &addr, unsigned length, const uint8_t *const data) { iss::status riscv_hart_msu_vp<BASE>::write(const iss::addr_t &addr, unsigned length, const uint8_t *const data) {
#ifndef NDEBUG #ifndef NDEBUG
const char *prefix = (addr.access && iss::access_type::DEBUG)? "debug " : ""; const char *prefix = (addr.access && iss::access_type::DEBUG) ? "debug " : "";
switch (length) { switch (length) {
case 8: case 8:
LOG(DEBUG) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint64_t *)&data[0] << std::dec LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint64_t *)&data[0] << std::dec
<< ") @addr " << addr; << ") @addr " << addr;
break; break;
case 4: case 4:
LOG(DEBUG) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint32_t *)&data[0] << std::dec LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint32_t *)&data[0] << std::dec
<< ") @addr " << addr; << ") @addr " << addr;
break; break;
case 2: case 2:
LOG(DEBUG) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint16_t *)&data[0] << std::dec LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint16_t *)&data[0] << std::dec
<< ") @addr " << addr; << ") @addr " << addr;
break; break;
case 1: case 1:
LOG(DEBUG) << prefix << "write of " << length << " bytes (0x" << std::hex << (uint16_t)data[0] << std::dec LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << (uint16_t)data[0] << std::dec
<< ") @addr " << addr; << ") @addr " << addr;
break; break;
default: default:
LOG(DEBUG) << prefix << "write of " << length << " bytes @addr " << addr; LOG(TRACE) << prefix << "write of " << length << " bytes @addr " << addr;
} }
#endif #endif
try { try {
@ -760,7 +768,8 @@ iss::status riscv_hart_msu_vp<BASE>::write(const iss::addr_t &addr, unsigned len
} }
} }
auto res = write_mem(BASE::v2p(addr), length, data); auto res = write_mem(BASE::v2p(addr), length, data);
if (unlikely(res != iss::Ok)) this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 7 (Store/AMO access fault) if (unlikely(res != iss::Ok))
this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 7 (Store/AMO access fault)
return res; return res;
} catch (trap_access &ta) { } catch (trap_access &ta) {
this->reg.trap_state = (1 << 31) | ta.id; this->reg.trap_state = (1 << 31) | ta.id;
@ -857,7 +866,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_csr(unsigned
} }
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_cycle(unsigned addr, reg_t &val) { template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_cycle(unsigned addr, reg_t &val) {
auto cycle_val= this->reg.icount + cycle_offset; auto cycle_val = this->reg.icount + cycle_offset;
if (addr == mcycle) { if (addr == mcycle) {
val = static_cast<reg_t>(cycle_val); val = static_cast<reg_t>(cycle_val);
} else if (addr == mcycleh) { } else if (addr == mcycleh) {
@ -868,7 +877,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_cycle(unsigne
} }
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_time(unsigned addr, reg_t &val) { template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_time(unsigned addr, reg_t &val) {
uint64_t time_val=(this->reg.icount + cycle_offset) / (100000000/32768-1); //-> ~3052; uint64_t time_val = (this->reg.icount + cycle_offset) / (100000000 / 32768 - 1); //-> ~3052;
if (addr == time) { if (addr == time) {
val = static_cast<reg_t>(time_val); val = static_cast<reg_t>(time_val);
} else if (addr == timeh) { } else if (addr == timeh) {
@ -925,7 +934,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_ip(unsigned
auto req_priv_lvl = addr >> 8; auto req_priv_lvl = addr >> 8;
if (this->reg.machine_state < req_priv_lvl) throw illegal_instruction_fault(this->fault_data); if (this->reg.machine_state < req_priv_lvl) throw illegal_instruction_fault(this->fault_data);
auto mask = get_irq_mask(req_priv_lvl); auto mask = get_irq_mask(req_priv_lvl);
mask &= ~(1<<7); // MTIP is read only mask &= ~(1 << 7); // MTIP is read only
csr[mip] = (csr[mip] & ~mask) | (val & mask); csr[mip] = (csr[mip] & ~mask) | (val & mask);
check_interrupt(); check_interrupt();
return iss::Ok; return iss::Ok;
@ -953,16 +962,16 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_satp(unsigne
update_vm_info(); update_vm_info();
return iss::Ok; return iss::Ok;
} }
template<typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_fcsr(unsigned addr, reg_t& val) { template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_fcsr(unsigned addr, reg_t &val) {
switch(addr){ switch (addr) {
case 1: //fflags, 4:0 case 1: // fflags, 4:0
val = bit_sub<0, 5>(this->get_fcsr()); val = bit_sub<0, 5>(this->get_fcsr());
break; break;
case 2: // frm, 7:5 case 2: // frm, 7:5
val = bit_sub<5, 3>(this->get_fcsr()); val = bit_sub<5, 3>(this->get_fcsr());
break; break;
case 3: // fcsr case 3: // fcsr
val=this->get_fcsr(); val = this->get_fcsr();
break; break;
default: default:
return iss::Err; return iss::Err;
@ -970,16 +979,16 @@ template<typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_fcsr(unsigned
return iss::Ok; return iss::Ok;
} }
template<typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_fcsr(unsigned addr, reg_t val) { template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_fcsr(unsigned addr, reg_t val) {
switch(addr){ switch (addr) {
case 1: //fflags, 4:0 case 1: // fflags, 4:0
this->set_fcsr( (this->get_fcsr() & 0xffffffe0) | (val&0x1f)); this->set_fcsr((this->get_fcsr() & 0xffffffe0) | (val & 0x1f));
break; break;
case 2: // frm, 7:5 case 2: // frm, 7:5
this->set_fcsr( (this->get_fcsr() & 0xffffff1f) | ((val&0x7)<<5)); this->set_fcsr((this->get_fcsr() & 0xffffff1f) | ((val & 0x7) << 5));
break; break;
case 3: // fcsr case 3: // fcsr
this->set_fcsr(val&0xff); this->set_fcsr(val & 0xff);
break; break;
default: default:
return iss::Err; return iss::Err;
@ -992,7 +1001,7 @@ iss::status riscv_hart_msu_vp<BASE>::read_mem(phys_addr_t paddr, unsigned length
if ((paddr.val + length) > mem.size()) return iss::Err; if ((paddr.val + length) > mem.size()) return iss::Err;
switch (paddr.val) { switch (paddr.val) {
case 0x0200BFF8: { // CLINT base, mtime reg case 0x0200BFF8: { // CLINT base, mtime reg
if(sizeof(reg_t)<length) return iss::Err; if (sizeof(reg_t) < length) return iss::Err;
reg_t time_val; reg_t time_val;
this->read_csr(time, time_val); this->read_csr(time, time_val);
std::copy((uint8_t *)&time_val, ((uint8_t *)&time_val) + length, data); std::copy((uint8_t *)&time_val, ((uint8_t *)&time_val) + length, data);
@ -1054,10 +1063,10 @@ iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t paddr, unsigned lengt
if (tohost_upper || (tohost_lower && to_host_wr_cnt > 0)) { if (tohost_upper || (tohost_lower && to_host_wr_cnt > 0)) {
switch (hostvar >> 48) { switch (hostvar >> 48) {
case 0: case 0:
if (hostvar != 0x1){ if (hostvar != 0x1) {
LOG(FATAL) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar LOG(FATAL) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
<< "), stopping simulation"; << "), stopping simulation";
}else{ } else {
LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
<< "), stopping simulation"; << "), stopping simulation";
} }
@ -1087,22 +1096,20 @@ iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t paddr, unsigned lengt
return iss::Ok; return iss::Ok;
} }
template<typename BASE> template <typename BASE> inline void riscv_hart_msu_vp<BASE>::reset(uint64_t address) {
inline void riscv_hart_msu_vp<BASE>::reset(uint64_t address) {
BASE::reset(address); BASE::reset(address);
state.mstatus = hart_state<reg_t>::mstatus_reset_val; state.mstatus = hart_state<reg_t>::mstatus_reset_val;
update_vm_info(); update_vm_info();
} }
template<typename BASE> template <typename BASE> inline void riscv_hart_msu_vp<BASE>::update_vm_info() {
inline void riscv_hart_msu_vp<BASE>::update_vm_info() {
vm[1] = hart_state<reg_t>::decode_vm_info(this->reg.machine_state, state.satp); vm[1] = hart_state<reg_t>::decode_vm_info(this->reg.machine_state, state.satp);
BASE::addr_mode[3]=BASE::addr_mode[2]=vm[1].is_active()?iss::address_type::VIRTUAL:iss::address_type::PHYSICAL; BASE::addr_mode[3]=BASE::addr_mode[2] = vm[1].is_active()? iss::address_type::VIRTUAL : iss::address_type::PHYSICAL;
if(state.mstatus.MPRV) if (state.mstatus.MPRV)
vm[0] = hart_state<reg_t>::decode_vm_info(state.mstatus.MPP, state.satp); vm[0] = hart_state<reg_t>::decode_vm_info(state.mstatus.MPP, state.satp);
else else
vm[0] = vm[1]; vm[0] = vm[1];
BASE::addr_mode[1]=BASE::addr_mode[0]=vm[0].is_active()?iss::address_type::VIRTUAL:iss::address_type::PHYSICAL; BASE::addr_mode[1] = BASE::addr_mode[0]=vm[0].is_active() ? iss::address_type::VIRTUAL : iss::address_type::PHYSICAL;
ptw.clear(); ptw.clear();
} }
@ -1117,7 +1124,7 @@ template <typename BASE> void riscv_hart_msu_vp<BASE>::check_interrupt() {
// any synchronous traps. // any synchronous traps.
auto ena_irq = ip & ie; auto ena_irq = ip & ie;
auto mie = state.mstatus.MIE; bool mie = state.mstatus.MIE;
auto m_enabled = this->reg.machine_state < PRIV_M || (this->reg.machine_state == PRIV_M && mie); auto m_enabled = this->reg.machine_state < PRIV_M || (this->reg.machine_state == PRIV_M && mie);
auto enabled_interrupts = m_enabled ? ena_irq & ~ideleg : 0; auto enabled_interrupts = m_enabled ? ena_irq & ~ideleg : 0;
@ -1153,10 +1160,10 @@ typename riscv_hart_msu_vp<BASE>::phys_addr_t riscv_hart_msu_vp<BASE>::virt2phys
#endif #endif
} else { } else {
uint32_t mode = type != iss::access_type::FETCH && state.mstatus.MPRV ? // MPRV uint32_t mode = type != iss::access_type::FETCH && state.mstatus.MPRV ? // MPRV
state.mstatus.MPP: state.mstatus.MPP :
this->reg.machine_state; this->reg.machine_state;
const vm_info& vm = this->vm[static_cast<uint16_t>(type)/2]; const vm_info &vm = this->vm[static_cast<uint16_t>(type) / 2];
const bool s_mode = mode == PRIV_S; const bool s_mode = mode == PRIV_S;
const bool sum = state.mstatus.SUM; const bool sum = state.mstatus.SUM;
@ -1175,8 +1182,8 @@ typename riscv_hart_msu_vp<BASE>::phys_addr_t riscv_hart_msu_vp<BASE>::virt2phys
// check that physical address of PTE is legal // check that physical address of PTE is legal
reg_t pte = 0; reg_t pte = 0;
const uint8_t res = const uint8_t res = this->read(phys_addr_t{addr.access, traits<BASE>::MEM, base + idx * vm.ptesize},
this->read(phys_addr_t{addr.access, traits<BASE>::MEM, base + idx * vm.ptesize}, vm.ptesize, (uint8_t *)&pte); vm.ptesize, (uint8_t *)&pte);
if (res != 0) throw trap_load_access_fault(addr.val); if (res != 0) throw trap_load_access_fault(addr.val);
const reg_t ppn = pte >> PTE_PPN_SHIFT; const reg_t ppn = pte >> PTE_PPN_SHIFT;
@ -1186,9 +1193,10 @@ typename riscv_hart_msu_vp<BASE>::phys_addr_t riscv_hart_msu_vp<BASE>::virt2phys
break; break;
} else if (!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) { } else if (!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) {
break; break;
} else if (type == iss::access_type::FETCH ? !(pte & PTE_X) } else if (type == iss::access_type::FETCH
: type == iss::access_type::READ ? !(pte & PTE_R) && !(mxr && (pte & PTE_X)) ? !(pte & PTE_X)
: !((pte & PTE_R) && (pte & PTE_W))) { : type == iss::access_type::READ ? !(pte & PTE_R) && !(mxr && (pte & PTE_X))
: !((pte & PTE_R) && (pte & PTE_W))) {
break; break;
} else if ((ppn & ((reg_t(1) << ptshift) - 1)) != 0) { } else if ((ppn & ((reg_t(1) << ptshift) - 1)) != 0) {
break; break;
@ -1254,8 +1262,8 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
csr[uepc | (new_priv << 8)] = this->reg.NEXT_PC; // store next address if interrupt csr[uepc | (new_priv << 8)] = this->reg.NEXT_PC; // store next address if interrupt
this->reg.pending_trap = 0; this->reg.pending_trap = 0;
} }
size_t adr=ucause | (new_priv << 8); size_t adr = ucause | (new_priv << 8);
csr[adr] = (trap_id<<31)+cause; csr[adr] = (trap_id << 31) + cause;
// update mstatus // update mstatus
// xPP field of mstatus is written with the active privilege mode at the time // xPP field of mstatus is written with the active privilege mode at the time
// of the trap; the x PIE field of mstatus // of the trap; the x PIE field of mstatus
@ -1265,15 +1273,18 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
// store the actual privilege level in yPP and store interrupt enable flags // store the actual privilege level in yPP and store interrupt enable flags
switch (new_priv) { switch (new_priv) {
case PRIV_M: case PRIV_M:
state.mstatus.MPP=cur_priv; state.mstatus.MPP = cur_priv;
state.mstatus.MPIE=state.mstatus.MIE; state.mstatus.MPIE = state.mstatus.MIE;
state.mstatus.MIE = false;
break; break;
case PRIV_S: case PRIV_S:
state.mstatus.SPP = cur_priv; state.mstatus.SPP = cur_priv;
state.mstatus.SPIE=state.mstatus.SIE; state.mstatus.SPIE = state.mstatus.SIE;
state.mstatus.SIE = false;
break; break;
case PRIV_U: case PRIV_U:
state.mstatus.UPIE=state.mstatus.UIE; state.mstatus.UPIE = state.mstatus.UIE;
state.mstatus.UIE = false;
break; break;
default: default:
break; break;
@ -1288,11 +1299,12 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
// reset trap state // reset trap state
this->reg.machine_state = new_priv; this->reg.machine_state = new_priv;
this->reg.trap_state = 0; this->reg.trap_state = 0;
std::array<char, 32> buffer; std::array<char, 32> buffer;
sprintf(buffer.data(), "0x%016lx", addr); sprintf(buffer.data(), "0x%016lx", addr);
CLOG(INFO, disass) << (trap_id ? "Interrupt" : "Trap") << " with cause '" << (trap_id ? irq_str[cause] : trap_str[cause])<<"' ("<<trap_id<<")" CLOG(INFO, disass) << (trap_id ? "Interrupt" : "Trap") << " with cause '"
<< " at address " << buffer.data() << " occurred, changing privilege level from " << lvl[cur_priv] << (trap_id ? irq_str[cause] : trap_str[cause]) << "' (" << trap_id << ")"
<< " to " << lvl[new_priv]; << " at address " << buffer.data() << " occurred, changing privilege level from "
<< lvl[cur_priv] << " to " << lvl[new_priv];
update_vm_info(); update_vm_info();
return this->reg.NEXT_PC; return this->reg.NEXT_PC;
} }
@ -1314,22 +1326,23 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::leave_trap(uint64_t f
switch (inst_priv) { switch (inst_priv) {
case PRIV_M: case PRIV_M:
this->reg.machine_state = state.mstatus.MPP; this->reg.machine_state = state.mstatus.MPP;
state.mstatus.MPP=0; // clear mpp to U mode state.mstatus.MPP = 0; // clear mpp to U mode
state.mstatus.MIE=state.mstatus.MPIE; state.mstatus.MIE = state.mstatus.MPIE;
break; break;
case PRIV_S: case PRIV_S:
this->reg.machine_state = state.mstatus.SPP; this->reg.machine_state = state.mstatus.SPP;
state.mstatus.SPP= 0; // clear spp to U mode state.mstatus.SPP = 0; // clear spp to U mode
state.mstatus.SIE=state.mstatus.SPIE; state.mstatus.SIE = state.mstatus.SPIE;
break; break;
case PRIV_U: case PRIV_U:
this->reg.machine_state = 0; this->reg.machine_state = 0;
state.mstatus.UIE=state.mstatus.UPIE; state.mstatus.UIE = state.mstatus.UPIE;
break; break;
} }
// sets the pc to the value stored in the x epc register. // sets the pc to the value stored in the x epc register.
this->reg.NEXT_PC = csr[uepc | inst_priv << 8]; this->reg.NEXT_PC = csr[uepc | inst_priv << 8];
CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to " << lvl[this->reg.machine_state]; CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to "
<< lvl[this->reg.machine_state];
update_vm_info(); update_vm_info();
return this->reg.NEXT_PC; return this->reg.NEXT_PC;
} }
@ -1345,5 +1358,4 @@ template <typename BASE> void riscv_hart_msu_vp<BASE>::wait_until(uint64_t flags
} }
} }
#endif /* _RISCV_CORE_H_ */ #endif /* _RISCV_CORE_H_ */

View File

@ -179,7 +179,7 @@ struct rv32gc: public arch_if {
uint64_t get_icount() { return reg.icount;} uint64_t get_icount() { return reg.icount;}
bool should_stop(){return false;} inline bool should_stop() { return interrupt_sim; }
inline phys_addr_t v2p(const iss::addr_t& addr){ inline phys_addr_t v2p(const iss::addr_t& addr){
if(addr.space != traits<rv32gc>::MEM || if(addr.space != traits<rv32gc>::MEM ||
@ -272,6 +272,7 @@ protected:
std::array<address_type, 4> addr_mode; std::array<address_type, 4> addr_mode;
bool interrupt_sim=false;
uint32_t get_fcsr(){return reg.FCSR;} uint32_t get_fcsr(){return reg.FCSR;}
void set_fcsr(uint32_t val){reg.FCSR = val;} void set_fcsr(uint32_t val){reg.FCSR = val;}

View File

@ -1,54 +1,59 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
//////////////////////////////////////////////////////////////////////////////// *******************************************************************************/
#ifndef _RV32IMAC_H_ #ifndef _RV32IMAC_H_
#define _RV32IMAC_H_ #define _RV32IMAC_H_
#include <array>
#include <iss/arch/traits.h>
#include <iss/arch_if.h> #include <iss/arch_if.h>
#include <iss/vm_if.h> #include <iss/vm_if.h>
#include <iss/arch/traits.h>
#include <array>
namespace iss { namespace iss {
namespace arch { namespace arch {
struct rv32imac; struct rv32imac;
template<> template <> struct traits<rv32imac> {
struct traits<rv32imac> {
constexpr static char const* const core_type = "RV32IMAC"; constexpr static char const *const core_type = "RV32IMAC";
enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b1000000000101000001000100000101, PGSIZE=0x1000, PGMASK=0xfff}; enum constants {
XLEN = 32,
PCLEN = 32,
MISA_VAL = 0b1000000000101000001000100000101,
PGSIZE = 0x1000,
PGMASK = 0xfff
};
constexpr static unsigned FP_REGS_SIZE = 0; constexpr static unsigned FP_REGS_SIZE = 0;
@ -87,7 +92,7 @@ struct traits<rv32imac> {
X31, X31,
PC, PC,
NUM_REGS, NUM_REGS,
NEXT_PC=NUM_REGS, NEXT_PC = NUM_REGS,
TRAP_STATE, TRAP_STATE,
PENDING_TRAP, PENDING_TRAP,
MACHINE_STATE, MACHINE_STATE,
@ -99,72 +104,70 @@ struct traits<rv32imac> {
using addr_t = uint32_t; using addr_t = uint32_t;
using code_word_t = uint32_t; //TODO: check removal using code_word_t = uint32_t; // TODO: check removal
using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>; using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>;
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>; using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
constexpr static unsigned reg_bit_width(unsigned r) { static constexpr std::array<const uint32_t, 39> RV32IMAC_reg_size{
constexpr std::array<const uint32_t, 39> RV32IMAC_reg_size{{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64}}; {32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
return RV32IMAC_reg_size[r]; 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 64}};
}
constexpr static unsigned reg_byte_offset(unsigned r) { constexpr static unsigned reg_bit_width(unsigned r) { return RV32IMAC_reg_size[r]; }
constexpr std::array<const uint32_t, 40> RV32IMAC_reg_byte_offset{{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,160}};
return RV32IMAC_reg_byte_offset[r]; static constexpr std::array<const uint32_t, 40> RV32IMAC_reg_byte_offset{
} {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76,
80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 160}};
constexpr static unsigned reg_byte_offset(unsigned r) { return RV32IMAC_reg_byte_offset[r]; }
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
enum sreg_flag_e {FLAGS}; enum sreg_flag_e { FLAGS };
enum mem_type_e {MEM, CSR, FENCE, RES}; enum mem_type_e { MEM, CSR, FENCE, RES };
}; };
struct rv32imac: public arch_if { struct rv32imac : public arch_if {
using virt_addr_t = typename traits<rv32imac>::virt_addr_t; using virt_addr_t = typename traits<rv32imac>::virt_addr_t;
using phys_addr_t = typename traits<rv32imac>::phys_addr_t; using phys_addr_t = typename traits<rv32imac>::phys_addr_t;
using reg_t = typename traits<rv32imac>::reg_t; using reg_t = typename traits<rv32imac>::reg_t;
using addr_t = typename traits<rv32imac>::addr_t; using addr_t = typename traits<rv32imac>::addr_t;
rv32imac(); rv32imac();
~rv32imac(); ~rv32imac();
void reset(uint64_t address=0) override; void reset(uint64_t address = 0) override;
uint8_t* get_regs_base_ptr() override; uint8_t *get_regs_base_ptr() override;
/// deprecated /// deprecated
void get_reg(short idx, std::vector<uint8_t>& value) override {} void get_reg(short idx, std::vector<uint8_t> &value) override {}
void set_reg(short idx, const std::vector<uint8_t>& value) override {} void set_reg(short idx, const std::vector<uint8_t> &value) override {}
/// deprecated /// deprecated
bool get_flag(int flag) override {return false;} bool get_flag(int flag) override { return false; }
void set_flag(int, bool value) override {}; void set_flag(int, bool value) override{};
/// deprecated /// deprecated
void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {}; void update_flags(operations op, uint64_t opr1, uint64_t opr2) override{};
inline inline uint64_t get_icount() { return reg.icount; }
uint64_t get_icount() { return reg.icount;}
inline inline bool should_stop() { return interrupt_sim; }
bool should_stop() { return interrupt_sim;}
inline phys_addr_t v2p(const iss::addr_t& addr){ inline phys_addr_t v2p(const iss::addr_t &addr) {
if(addr.space != traits<rv32imac>::MEM || if (addr.space != traits<rv32imac>::MEM || addr.type == iss::address_type::PHYSICAL ||
addr.type == iss::address_type::PHYSICAL || addr_mode[static_cast<uint16_t>(addr.access) & 0x3] == address_type::PHYSICAL) {
addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL){ return phys_addr_t(addr.access, addr.space, addr.val & traits<rv32imac>::addr_mask);
return phys_addr_t(addr.access, addr.space, addr.val&traits<rv32imac>::addr_mask);
} else } else
return virt2phys(addr); return virt2phys(addr);
} }
virtual phys_addr_t virt2phys(const iss::addr_t& addr); virtual phys_addr_t virt2phys(const iss::addr_t &addr);
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
inline inline uint32_t get_last_branch() { return reg.last_branch; }
uint32_t get_last_branch(){return reg.last_branch;}
protected: protected:
struct RV32IMAC_regs { struct RV32IMAC_regs {
@ -207,14 +210,12 @@ protected:
} reg; } reg;
std::array<address_type, 4> addr_mode; std::array<address_type, 4> addr_mode;
bool interrupt_sim=false;
uint32_t get_fcsr(){return 0;} bool interrupt_sim = false;
void set_fcsr(uint32_t val){}
uint32_t get_fcsr() { return 0; }
void set_fcsr(uint32_t val) {}
}; };
} }
} }
#endif /* _RV32IMAC_H_ */ #endif /* _RV32IMAC_H_ */

View File

@ -144,9 +144,9 @@ struct rv64ia: public arch_if {
/// deprecated /// deprecated
void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {}; void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {};
uint64_t get_icount() { return reg.icount;} inline uint64_t get_icount() { return reg.icount; }
bool should_stop(){return false;} inline bool should_stop() { return interrupt_sim; }
inline phys_addr_t v2p(const iss::addr_t& addr){ inline phys_addr_t v2p(const iss::addr_t& addr){
if(addr.space != traits<rv64ia>::MEM || if(addr.space != traits<rv64ia>::MEM ||
@ -206,6 +206,7 @@ protected:
std::array<address_type, 4> addr_mode; std::array<address_type, 4> addr_mode;
bool interrupt_sim=false;
uint32_t get_fcsr(){return 0;} uint32_t get_fcsr(){return 0;}
void set_fcsr(uint32_t val){} void set_fcsr(uint32_t val){}

View File

@ -1,9 +1,34 @@
/* /*******************************************************************************
* riscv_target_adapter.h * Copyright (C) 2017, 2018 MINRES Technologies GmbH
* All rights reserved.
* *
* Created on: 26.09.2017 * Redistribution and use in source and binary forms, with or without
* Author: eyck * modification, are permitted provided that the following conditions are met:
*/ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef _ISS_DEBUGGER_RISCV_TARGET_ADAPTER_H_ #ifndef _ISS_DEBUGGER_RISCV_TARGET_ADAPTER_H_
#define _ISS_DEBUGGER_RISCV_TARGET_ADAPTER_H_ #define _ISS_DEBUGGER_RISCV_TARGET_ADAPTER_H_
@ -13,9 +38,9 @@
#include <iss/debugger/target_adapter_base.h> #include <iss/debugger/target_adapter_base.h>
#include <iss/iss.h> #include <iss/iss.h>
#include <array>
#include <memory> #include <memory>
#include <util/logging.h> #include <util/logging.h>
#include <array>
namespace iss { namespace iss {
namespace debugger { namespace debugger {
@ -95,9 +120,10 @@ public:
status remove_break(int type, uint64_t addr, unsigned int length) override; status remove_break(int type, uint64_t addr, unsigned int length) override;
status resume_from_addr(bool step, int sig, uint64_t addr, rp_thread_ref thread, std::function<void(unsigned)> stop_callback) override; status resume_from_addr(bool step, int sig, uint64_t addr, rp_thread_ref thread,
std::function<void(unsigned)> stop_callback) override;
status target_xml_query(std::string& out_buf) override; status target_xml_query(std::string &out_buf) override;
protected: protected:
static inline constexpr addr_t map_addr(const addr_t &i) { return i; } static inline constexpr addr_t map_addr(const addr_t &i) { return i; }
@ -160,11 +186,11 @@ status riscv_target_adapter<ARCH>::read_registers(std::vector<uint8_t> &data, st
data.push_back(*(reg_base + offset + j)); data.push_back(*(reg_base + offset + j));
avail.push_back(0xff); avail.push_back(0xff);
} }
// if(arch::traits<ARCH>::XLEN < 64) // if(arch::traits<ARCH>::XLEN < 64)
// for(unsigned j=0; j<4; ++j){ // for(unsigned j=0; j<4; ++j){
// data.push_back(0); // data.push_back(0);
// avail.push_back(0xff); // avail.push_back(0xff);
// } // }
} }
// work around fill with F type registers // work around fill with F type registers
if (arch::traits<ARCH>::NUM_REGS < 65) { if (arch::traits<ARCH>::NUM_REGS < 65) {
@ -174,11 +200,11 @@ status riscv_target_adapter<ARCH>::read_registers(std::vector<uint8_t> &data, st
data.push_back(0x0); data.push_back(0x0);
avail.push_back(0x00); avail.push_back(0x00);
} }
// if(arch::traits<ARCH>::XLEN < 64) // if(arch::traits<ARCH>::XLEN < 64)
// for(unsigned j=0; j<4; ++j){ // for(unsigned j=0; j<4; ++j){
// data.push_back(0x0); // data.push_back(0x0);
// avail.push_back(0x00); // avail.push_back(0x00);
// } // }
} }
} }
return Ok; return Ok;
@ -280,10 +306,10 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::threadinfo_query(int
template <typename ARCH> template <typename ARCH>
status riscv_target_adapter<ARCH>::threadextrainfo_query(const rp_thread_ref &thread, std::string &out_buf) { status riscv_target_adapter<ARCH>::threadextrainfo_query(const rp_thread_ref &thread, std::string &out_buf) {
std::array<char, 20> buf; std::array<char, 20> buf;
memset(buf.data(), 0, 20); memset(buf.data(), 0, 20);
sprintf(buf.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x", 'R', 'u', 'n', 'n', 'a', 'b', 'l', 'e', 0); sprintf(buf.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x", 'R', 'u', 'n', 'n', 'a', 'b', 'l', 'e', 0);
out_buf = buf.data(); out_buf = buf.data();
return Ok; return Ok;
} }
@ -317,56 +343,56 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::remove_break(int typ
return Err; return Err;
} }
template <typename ARCH> status riscv_target_adapter<ARCH>::resume_from_addr(bool step, int sig, uint64_t addr, rp_thread_ref thread, template <typename ARCH>
std::function<void(unsigned)> stop_callback) { status riscv_target_adapter<ARCH>::resume_from_addr(bool step, int sig, uint64_t addr, rp_thread_ref thread,
auto* reg_base = core->get_regs_base_ptr(); std::function<void(unsigned)> stop_callback) {
auto *reg_base = core->get_regs_base_ptr();
auto reg_width = arch::traits<ARCH>::reg_bit_width(arch::traits<ARCH>::PC) / 8; auto reg_width = arch::traits<ARCH>::reg_bit_width(arch::traits<ARCH>::PC) / 8;
auto offset = traits<ARCH>::reg_byte_offset(arch::traits<ARCH>::PC); auto offset = traits<ARCH>::reg_byte_offset(arch::traits<ARCH>::PC);
const uint8_t* iter = reinterpret_cast<const uint8_t*>(&addr); const uint8_t *iter = reinterpret_cast<const uint8_t *>(&addr);
std::copy(iter, iter + reg_width, reg_base); std::copy(iter, iter + reg_width, reg_base);
return resume_from_current(step, sig, thread, stop_callback); return resume_from_current(step, sig, thread, stop_callback);
} }
template <typename ARCH> status riscv_target_adapter<ARCH>::target_xml_query(std::string& out_buf) { template <typename ARCH> status riscv_target_adapter<ARCH>::target_xml_query(std::string &out_buf) {
const std::string res{ const std::string res{"<?xml version=\"1.0\"?><!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
"<?xml version=\"1.0\"?><!DOCTYPE target SYSTEM \"gdb-target.dtd\">" "<target><architecture>riscv:rv32</architecture>"
"<target><architecture>riscv:rv32</architecture>" //" <feature name=\"org.gnu.gdb.riscv.rv32i\">\n"
//" <feature name=\"org.gnu.gdb.riscv.rv32i\">\n" //" <reg name=\"x0\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x0\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x1\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x1\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x2\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x2\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x3\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x3\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x4\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x4\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x5\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x5\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x6\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x6\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x7\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x7\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x8\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x8\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x9\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x9\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x10\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x10\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x11\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x11\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x12\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x12\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x13\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x13\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x14\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x14\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x15\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x15\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x16\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x16\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x17\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x17\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x18\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x18\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x19\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x19\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x20\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x20\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x21\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x21\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x22\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x22\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x23\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x23\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x24\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x24\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x25\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x25\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x26\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x26\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x27\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x27\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x28\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x28\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x29\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x29\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x30\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x30\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x31\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x31\" bitsize=\"32\" group=\"general\"/>\n" //" </feature>\n"
//" </feature>\n" "</target>"};
"</target>"}; out_buf = res;
out_buf=res;
return Ok; return Ok;
} }

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018, MINRES Technologies GmbH
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -35,8 +35,8 @@
#ifndef _ISS_PLUGIN_CYCLE_ESTIMATE_H_ #ifndef _ISS_PLUGIN_CYCLE_ESTIMATE_H_
#define _ISS_PLUGIN_CYCLE_ESTIMATE_H_ #define _ISS_PLUGIN_CYCLE_ESTIMATE_H_
#include "iss/vm_plugin.h"
#include "iss/instrumentation_if.h" #include "iss/instrumentation_if.h"
#include "iss/vm_plugin.h"
#include <json/json.h> #include <json/json.h>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
@ -58,38 +58,38 @@ class cycle_estimate: public iss::vm_plugin {
END_BF_DECL(); END_BF_DECL();
public: public:
cycle_estimate() = delete; cycle_estimate() = delete;
cycle_estimate(const cycle_estimate& ) = delete; cycle_estimate(const cycle_estimate &) = delete;
cycle_estimate(const cycle_estimate&&) = delete; cycle_estimate(const cycle_estimate &&) = delete;
cycle_estimate(std::string config_file_name); cycle_estimate(std::string config_file_name);
virtual ~cycle_estimate(); virtual ~cycle_estimate();
cycle_estimate& operator=(const cycle_estimate& ) = delete; cycle_estimate &operator=(const cycle_estimate &) = delete;
cycle_estimate& operator=(const cycle_estimate&& ) = delete; cycle_estimate &operator=(const cycle_estimate &&) = delete;
bool registration(const char* const version, vm_if& arch) override; bool registration(const char *const version, vm_if &arch) override;
sync_type get_sync() override {return POST_SYNC;}; sync_type get_sync() override { return POST_SYNC; };
void callback(instr_info_t instr_info) override;
void callback(instr_info_t instr_info) override;
private: private:
iss::instrumentation_if* arch_instr; iss::instrumentation_if *arch_instr;
std::vector<instr_desc> delays; std::vector<instr_desc> delays;
struct pair_hash { struct pair_hash {
size_t operator()(const std::pair<uint64_t, uint64_t>& p) const{ size_t operator()(const std::pair<uint64_t, uint64_t> &p) const {
std::hash<uint64_t> hash; std::hash<uint64_t> hash;
return hash(p.first)+hash(p.second); return hash(p.first) + hash(p.second);
} }
}; };
std::unordered_map<std::pair<uint64_t, uint64_t>, uint64_t, pair_hash> blocks; std::unordered_map<std::pair<uint64_t, uint64_t>, uint64_t, pair_hash> blocks;
Json::Value root; Json::Value root;
}; };
} }
} }

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018, MINRES Technologies GmbH
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -42,39 +42,40 @@
namespace iss { namespace iss {
namespace plugin { namespace plugin {
class instruction_count: public iss::vm_plugin { class instruction_count : public iss::vm_plugin {
struct instr_delay { struct instr_delay {
std::string instr_name; std::string instr_name;
size_t size; size_t size;
size_t not_taken_delay; size_t not_taken_delay;
size_t taken_delay; size_t taken_delay;
}; };
public: public:
instruction_count() = delete; instruction_count() = delete;
instruction_count(const instruction_count& ) = delete; instruction_count(const instruction_count &) = delete;
instruction_count(const instruction_count&&) = delete; instruction_count(const instruction_count &&) = delete;
instruction_count(std::string config_file_name); instruction_count(std::string config_file_name);
virtual ~instruction_count(); virtual ~instruction_count();
instruction_count& operator=(const instruction_count& ) = delete; instruction_count &operator=(const instruction_count &) = delete;
instruction_count& operator=(const instruction_count&& ) = delete; instruction_count &operator=(const instruction_count &&) = delete;
bool registration(const char* const version, vm_if& arch) override; bool registration(const char *const version, vm_if &arch) override;
sync_type get_sync() override {return POST_SYNC;}; sync_type get_sync() override { return POST_SYNC; };
void callback(instr_info_t instr_info) override;
void callback(instr_info_t instr_info) override;
private: private:
Json::Value root; Json::Value root;
std::vector<instr_delay> delays; std::vector<instr_delay> delays;
std::vector<uint64_t> rep_counts; std::vector<uint64_t> rep_counts;
}; };
} }
} }

View File

@ -1,14 +1,16 @@
# library files # library files
FILE(GLOB RiscVHeaders *.h) FILE(GLOB RiscVSCHeaders ${PROJECT_SOURCE_DIR}/incl/sysc/*.h ${PROJECT_SOURCE_DIR}/incl/sysc/*/*.h)
FILE(GLOB IssSources iss/*.cpp internal/*.cpp) set(LIB_HEADERS ${RiscVSCHeaders} )
set(LIB_SOURCES
iss/rv32gc.cpp
set(LIB_HEADERS ${RiscVHeaders} ) iss/rv32imac.cpp
set(LIB_SOURCES iss/rv64ia.cpp
${IssSources} internal/fp_functions.cpp
internal/vm_rv32gc.cpp
internal/vm_rv32imac.cpp
internal/vm_rv64ia.cpp
plugin/instruction_count.cpp plugin/instruction_count.cpp
plugin/cycle_estimate.cpp plugin/cycle_estimate.cpp)
)
set(APP_HEADERS ) set(APP_HEADERS )
@ -18,7 +20,6 @@ set(APP_SOURCES main.cpp)
set(LIBRARY_NAME riscv) set(LIBRARY_NAME riscv)
# Define the library # Define the library
#add_library(${LIBRARY_NAME} SHARED ${LIB_SOURCES})
add_library(${LIBRARY_NAME} ${LIB_SOURCES}) add_library(${LIBRARY_NAME} ${LIB_SOURCES})
SET(${LIBRARY_NAME} -Wl,-whole-archive -l${LIBRARY_NAME} -Wl,-no-whole-archive) SET(${LIBRARY_NAME} -Wl,-whole-archive -l${LIBRARY_NAME} -Wl,-no-whole-archive)
set_target_properties(${LIBRARY_NAME} PROPERTIES set_target_properties(${LIBRARY_NAME} PROPERTIES

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +1,34 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Created on: Tue Aug 29 16:45:20 CEST 2017 *******************************************************************************/
// * rv32imac.cpp Author: <CoreDSL Generator>
//
////////////////////////////////////////////////////////////////////////////////
#include "util/ities.h" #include "util/ities.h"
#include <util/logging.h> #include <util/logging.h>
@ -52,9 +49,15 @@ extern "C" {
using namespace iss::arch; using namespace iss::arch;
rv32imac::rv32imac() { reg.icount = 0; reg.machine_state = 0x3;} constexpr std::array<const uint32_t, 39> iss::arch::traits<iss::arch::rv32imac>::RV32IMAC_reg_size;
constexpr std::array<const uint32_t, 40> iss::arch::traits<iss::arch::rv32imac>::RV32IMAC_reg_byte_offset;
rv32imac::~rv32imac(){} rv32imac::rv32imac() {
reg.icount = 0;
reg.machine_state = 0x3;
}
rv32imac::~rv32imac() = default;
void rv32imac::reset(uint64_t address) { void rv32imac::reset(uint64_t address) {
for (size_t i = 0; i < traits<rv32imac>::NUM_REGS; ++i) for (size_t i = 0; i < traits<rv32imac>::NUM_REGS; ++i)

View File

@ -1,36 +1,34 @@
//////////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// Copyright (C) 2017, MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// *
// 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// *
// 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
// *
// Contributors: *******************************************************************************/
// eyck@minres.com - initial implementation
////////////////////////////////////////////////////////////////////////////////
#include <iostream> #include <iostream>
#include <iss/iss.h> #include <iss/iss.h>
@ -43,8 +41,8 @@
#include <iss/arch/rv64ia.h> #include <iss/arch/rv64ia.h>
#include <iss/jit/jit_helper.h> #include <iss/jit/jit_helper.h>
#include <iss/log_categories.h> #include <iss/log_categories.h>
#include <iss/plugin/instruction_count.h>
#include <iss/plugin/cycle_estimate.h> #include <iss/plugin/cycle_estimate.h>
#include <iss/plugin/instruction_count.h>
namespace po = boost::program_options; namespace po = boost::program_options;
@ -98,8 +96,8 @@ int main(int argc, char *argv[]) {
LOG_OUTPUT(connection)::stream() = f; LOG_OUTPUT(connection)::stream() = f;
} }
std::vector<iss::vm_plugin*> plugin_list; std::vector<iss::vm_plugin *> plugin_list;
auto res=0; auto res = 0;
try { try {
// application code comes here // // application code comes here //
iss::init_jit(argc, argv); iss::init_jit(argc, argv);
@ -125,24 +123,24 @@ int main(int argc, char *argv[]) {
return 127; return 127;
} }
if (clim.count("plugin")) { if (clim.count("plugin")) {
for (std::string opt_val : clim["plugin"].as<std::vector<std::string>>()){ for (std::string opt_val : clim["plugin"].as<std::vector<std::string>>()) {
auto plugin_name{opt_val}; std::string plugin_name{opt_val};
std::string filename{"cycles.txt"}; std::string filename{"cycles.txt"};
std::size_t found = opt_val.find('='); std::size_t found = opt_val.find('=');
if (found!=std::string::npos){ if (found != std::string::npos) {
plugin_name=opt_val.substr(0, found); plugin_name = opt_val.substr(0, found);
filename=opt_val.substr(found+1, opt_val.size()); filename = opt_val.substr(found + 1, opt_val.size());
} }
if(plugin_name=="ic"){ if (plugin_name == "ic") {
auto* ic_plugin= new iss::plugin::instruction_count(filename); auto *ic_plugin = new iss::plugin::instruction_count(filename);
vm->register_plugin(*ic_plugin); vm->register_plugin(*ic_plugin);
plugin_list.push_back(ic_plugin); plugin_list.push_back(ic_plugin);
} else if(plugin_name=="ce"){ } else if (plugin_name == "ce") {
auto* ce_plugin= new iss::plugin::cycle_estimate(filename); auto *ce_plugin = new iss::plugin::cycle_estimate(filename);
vm->register_plugin(*ce_plugin); vm->register_plugin(*ce_plugin);
plugin_list.push_back(ce_plugin); plugin_list.push_back(ce_plugin);
} else { } else {
LOG(ERROR) << "Unknown plugin name: " << plugin_name << ", valid names are 'ce', 'ic'"<<std::endl; LOG(ERROR) << "Unknown plugin name: " << plugin_name << ", valid names are 'ce', 'ic'" << std::endl;
return 127; return 127;
} }
} }
@ -157,33 +155,32 @@ int main(int argc, char *argv[]) {
LOGGER(disass)::print_severity() = false; LOGGER(disass)::print_severity() = false;
} }
} }
uint64_t start_address=0; uint64_t start_address = 0;
if (clim.count("mem")) if (clim.count("mem"))
vm->get_arch()->load_file(clim["mem"].as<std::string>(), iss::arch::traits<iss::arch::rv32imac>::MEM); vm->get_arch()->load_file(clim["mem"].as<std::string>(), iss::arch::traits<iss::arch::rv32imac>::MEM);
if (clim.count("elf")) if (clim.count("elf"))
for (std::string input : clim["elf"].as<std::vector<std::string>>()){ for (std::string input : clim["elf"].as<std::vector<std::string>>()) {
auto start_addr = vm->get_arch()->load_file(input); auto start_addr = vm->get_arch()->load_file(input);
if(start_addr.second) if (start_addr.second) start_address = start_addr.first;
start_address=start_addr.first;
} }
for (std::string input : args){ for (std::string input : args) {
auto start_addr = vm->get_arch()->load_file(input);// treat remaining arguments as elf files auto start_addr = vm->get_arch()->load_file(input); // treat remaining arguments as elf files
if(start_addr.second) if (start_addr.second) start_address = start_addr.first;
start_address=start_addr.first;
} }
if (clim.count("reset")) { if (clim.count("reset")) {
auto str = clim["reset"].as<std::string>(); auto str = clim["reset"].as<std::string>();
start_address = str.find("0x") == 0 ? std::stoull(str.substr(2), 0, 16) : std::stoull(str, 0, 10); start_address = str.find("0x") == 0 ? std::stoull(str.substr(2), nullptr, 16) : std::stoull(str, nullptr, 10);
} }
vm->reset(start_address); vm->reset(start_address);
auto cycles = clim["instructions"].as<uint64_t>(); auto cycles = clim["instructions"].as<uint64_t>();
res = vm->start(cycles, dump); res = vm->start(cycles, dump);
} catch (std::exception &e) { } catch (std::exception &e) {
LOG(ERROR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit" << std::endl; LOG(ERROR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit"
res=2; << std::endl;
res = 2;
} }
// cleanup to let plugins report of needed // cleanup to let plugins report of needed
for(auto* p:plugin_list){ for (auto *p : plugin_list) {
delete p; delete p;
} }
return res; return res;

@ -1 +1 @@
Subproject commit 0e5cf3fb3ac199a47f073f2bcee0abd4b3951896 Subproject commit 0f5b5f68e7d5d481b4f8da2620df633495c989d9

View File

@ -11,9 +11,6 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
project("sotfloat") project("sotfloat")
# Set the version number of your project here (format is MAJOR.MINOR.PATCHLEVEL - e.g. 1.0.0) # Set the version number of your project here (format is MAJOR.MINOR.PATCHLEVEL - e.g. 1.0.0)
#set(VERSION_MAJOR "3")
#set(VERSION_MINOR "0")
#set(VERSION_PATCH "0")
set(VERSION "3e") set(VERSION "3e")
include(Common) include(Common)