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>
</storageModule>
<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="">
<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"/>
@ -171,6 +171,23 @@
<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"/>
</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">
<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">
@ -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">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</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">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</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">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</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">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</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>

View File

@ -1,8 +1,17 @@
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(ENABLE_SCV TRUE CACHE BOOL "Enable use of SCV")
include(GitFunctions)
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(GIT_SUBMODULES elfio libGIS sc-components dbt-core)
@ -45,12 +54,58 @@ endif()
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(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)
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(dbt-core)
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**
* you need to have a decent compiler, make, python, and cmake installed
* install LLVM 4.0 according to http://apt.llvm.org/ (if it is not already provided by your distribution e.g by Ubuntu 17.04)
* 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 18.04)
* install conan.io (see also http://docs.conan.io/en/latest/installation.html):
```
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
#******************************************************************************
# 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

View File

@ -7,7 +7,7 @@ project("external")
include(Common)
include_directories( ${PROJECT_SOURCE_DIR}/external/libGIS )
include_directories( ${PROJECT_SOURCE_DIR}/libGIS )
FILE(GLOB ElfioHeaders elfio *.hpp)
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;
$(function() {

View File

@ -79,7 +79,7 @@ span.value_x { background-color: red;}
}
}
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('open', function (m) { log(name, new Date().toISOString()+': ===connection opened==='); });
s.addEventListener('message', function (m) { log(name, m.data); });
@ -99,8 +99,7 @@ span.value_x { background-color: red;}
top.appendChild(div);
open_connection(n);
}
createElem("uart0");
createElem("gpio0");
createElem("terminal");
</script>
</body>
</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 the name of your project here
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})
project("platform")
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})
# check that we have averything we need
if(!SystemC_FOUND)
message( FATAL_ERROR "SystemC library not found." )
endif()
# 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)
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()
if(!CCI_FOUND)
message( FATAL_ERROR "SystemC CCI library not found." )
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.
include_directories(
${PROJECT_SOURCE_DIR}/incl
${LLVM_INCLUDE_DIRS}
)
add_dependent_subproject(dbt-core)
add_dependent_subproject(sc-components)
@ -72,14 +28,11 @@ add_dependent_subproject(riscv)
add_dependent_subproject(riscv.sc)
include_directories(
${PROJECT_SOURCE_DIR}/incl
${PROJECT_SOURCE_DIR}/../riscv/incl
${PROJECT_SOURCE_DIR}/../external/elfio
${PROJECT_SOURCE_DIR}/../external/libGIS
${Boost_INCLUDE_DIRS}
)
# 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_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_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)
#

View File

@ -1,6 +1,7 @@
`include "gpio.rdl"
`include "uart.rdl"
`include "spi.rdl"
`include "pwm.rdl"
`include "plic.rdl"
`include "aon.rdl"
`include "prci.rdl"
@ -15,10 +16,10 @@ addrmap e300_plat_t {
gpio_regs gpio0 @0x10012000;
uart_regs uart0 @0x10013000;
spi_regs qspi0 @0x10014000;
//pwm_regs pwm0 @0x10015000;
pwm_regs pwm0 @0x10015000;
uart_regs uart1 @0x10023000;
spi_regs qspi1 @0x10024000;
//pwm_regs pwm1 @0x10025000;
pwm_regs pwm1 @0x10025000;
spi_regs qspi2 @0x10034000;
//pwm_regs pwm2 @0x10035000;
pwm_regs pwm2 @0x10035000;
} 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
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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.
*
*******************************************************************************/
#ifndef _AON_H_
#define _AON_H_
@ -45,7 +41,7 @@ class aon_regs;
class aon : public sc_core::sc_module, public scc::tlm_target<> {
public:
SC_HAS_PROCESS(aon);
SC_HAS_PROCESS(aon);// NOLINT
sc_core::sc_in<sc_core::sc_time> clk_i;
sc_core::sc_in<bool> erst_n_i;
sc_core::sc_out<sc_core::sc_time> lfclkc_o;

View File

@ -1,38 +1,34 @@
////////////////////////////////////////////////////////////////////////////////
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 _CLINT_H_
#define _CLINT_H_
@ -54,14 +50,14 @@ class core_complex;
class clint : public sc_core::sc_module, public scc::tlm_target<> {
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> lfclk_i;
sc_core::sc_in<bool> rst_i;
sc_core::sc_out<bool> mtime_int_o;
sc_core::sc_out<bool> msip_int_o;
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:
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
// 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.
//
// Created on: Fri Nov 10 18:01:53 CET 2017
// * aon_regs.h Author: <RDL Generator>
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 _AON_REGS_H_
#define _AON_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h>
#include <scc/register.h>
#include <scc/tlm_target.h>
#include <scc/utilities.h>
#include <util/bit_field.h>
namespace sysc {
class aon_regs :
public sc_core::sc_module,
public scc::resetable
{
class aon_regs : public sc_core::sc_module, public scc::resetable {
public:
// storage declarations
uint32_t r_wdogcfg;
uint32_t r_wdogcount;
uint32_t r_wdogs;
uint32_t r_wdogfeed;
uint32_t r_wdogkey;
uint32_t r_wdogcmp;
uint32_t r_rtccfg;
uint32_t r_rtclo;
uint32_t r_rtchi;
uint32_t r_rtcs;
uint32_t r_rtccmp;
uint32_t r_lfrosccfg;
std::array<uint32_t, 32> r_backup;
BEGIN_BF_DECL(pmuwakeupi_t, uint32_t);
BF_FIELD(delay, 0, 4);
BF_FIELD(vddpaden, 5, 1);
BF_FIELD(corerst, 7, 1);
BF_FIELD(hfclkrst, 8, 1);
END_BF_DECL() ;
BF_FIELD(delay, 0, 4);
BF_FIELD(vddpaden, 5, 1);
BF_FIELD(corerst, 7, 1);
BF_FIELD(hfclkrst, 8, 1);
END_BF_DECL();
std::array<pmuwakeupi_t, 8> r_pmuwakeupi;
BEGIN_BF_DECL(pmusleepi_t, uint32_t);
BF_FIELD(delay, 0, 4);
BF_FIELD(vddpaden, 5, 1);
BF_FIELD(corerst, 7, 1);
BF_FIELD(hfclkrst, 8, 1);
END_BF_DECL() ;
BF_FIELD(delay, 0, 4);
BF_FIELD(vddpaden, 5, 1);
BF_FIELD(corerst, 7, 1);
BF_FIELD(hfclkrst, 8, 1);
END_BF_DECL();
std::array<pmusleepi_t, 8> r_pmusleepi;
uint32_t r_pmuie;
uint32_t r_pmucause;
uint32_t r_pmusleep;
uint32_t r_pmukey;
// register declarations
scc::sc_register<uint32_t> wdogcfg;
scc::sc_register<uint32_t> wdogcount;
@ -119,11 +113,10 @@ public:
scc::sc_register<uint32_t> pmucause;
scc::sc_register<uint32_t> pmusleep;
scc::sc_register<uint32_t> pmukey;
aon_regs(sc_core::sc_module_name nm);
template<unsigned BUSWIDTH=32>
void registerResources(scc::tlm_target<BUSWIDTH>& target);
template <unsigned BUSWIDTH = 32> 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(pmucause, r_pmucause, 0, *this)
, NAMED(pmusleep, r_pmusleep, 0, *this)
, NAMED(pmukey, r_pmukey, 0, *this)
{
}
, NAMED(pmukey, r_pmukey, 0, *this) {}
template<unsigned BUSWIDTH>
inline void sysc::aon_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
template <unsigned BUSWIDTH> inline void sysc::aon_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) {
target.addResource(wdogcfg, 0x0UL);
target.addResource(wdogcount, 0x8UL);
target.addResource(wdogs, 0x10UL);

View File

@ -1,71 +1,64 @@
////////////////////////////////////////////////////////////////////////////////
// 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.
//
// Created on: Fri Nov 10 18:01:53 CET 2017
// * clint_regs.h Author: <RDL Generator>
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 _CLINT_REGS_H_
#define _CLINT_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h>
#include <scc/register.h>
#include <scc/tlm_target.h>
#include <scc/utilities.h>
#include <util/bit_field.h>
namespace sysc {
class clint_regs :
public sc_core::sc_module,
public scc::resetable
{
class clint_regs : public sc_core::sc_module, public scc::resetable {
public:
// storage declarations
BEGIN_BF_DECL(msip_t, uint32_t);
BF_FIELD(msip, 0, 1);
BF_FIELD(msip, 0, 1);
END_BF_DECL() r_msip;
uint64_t r_mtimecmp;
uint64_t r_mtime;
// register declarations
scc::sc_register<msip_t> msip;
scc::sc_register<uint64_t> mtimecmp;
scc::sc_register<uint64_t> mtime;
clint_regs(sc_core::sc_module_name nm);
template<unsigned BUSWIDTH=32>
void registerResources(scc::tlm_target<BUSWIDTH>& target);
template <unsigned BUSWIDTH = 32> 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)
, NAMED(msip, r_msip, 0, *this)
, NAMED(mtimecmp, r_mtimecmp, 0, *this)
, NAMED(mtime, r_mtime, 0, *this)
{
}
, NAMED(mtime, r_mtime, 0, *this) {}
template<unsigned BUSWIDTH>
inline void sysc::clint_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
template <unsigned BUSWIDTH> inline void sysc::clint_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) {
target.addResource(msip, 0x0UL);
target.addResource(mtimecmp, 0x4000UL);
target.addResource(mtime, 0xbff8UL);

View File

@ -1,17 +1,21 @@
#ifndef _E300_PLAT_MAP_H_
#define _E300_PLAT_MAP_H_
// need double braces, see https://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list#6894191
const std::array<scc::target_memory_map_entry<32>, 10> e300_plat_map = {{
{&i_clint, 0x2000000, 0xc000},
{&i_plic, 0xc000000, 0x200008},
{&i_aon, 0x10000000, 0x150},
{&i_prci, 0x10008000, 0x14},
{&i_gpio0, 0x10012000, 0x44},
{&i_uart0, 0x10013000, 0x1c},
{&i_qspi0, 0x10014000, 0x78},
{&i_uart1, 0x10023000, 0x1c},
{&i_qspi1, 0x10024000, 0x78},
{&i_qspi2, 0x10034000, 0x78},
#ifndef _E300_PLAT_T_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
const std::array<scc::target_memory_map_entry<32>, 13> e300_plat_t_map = {{
{i_clint->socket, 0x2000000, 0xc000},
{i_plic->socket, 0xc000000, 0x200008},
{i_aon->socket, 0x10000000, 0x150},
{i_prci->socket, 0x10008000, 0x14},
{i_gpio0->socket, 0x10012000, 0x44},
{i_uart0->socket, 0x10013000, 0x1c},
{i_qspi0->socket, 0x10014000, 0x78},
{i_pwm0->socket, 0x10015000, 0x30},
{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
// 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.
//
// Created on: Fri Nov 10 18:01:53 CET 2017
// * gpio_regs.h Author: <RDL Generator>
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 _GPIO_REGS_H_
#define _GPIO_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h>
#include <scc/register.h>
#include <scc/tlm_target.h>
#include <scc/utilities.h>
#include <util/bit_field.h>
namespace sysc {
class gpio_regs :
public sc_core::sc_module,
public scc::resetable
{
class gpio_regs : public sc_core::sc_module, public scc::resetable {
public:
// storage declarations
uint32_t r_value;
uint32_t r_input_en;
uint32_t r_output_en;
uint32_t r_port;
uint32_t r_pue;
uint32_t r_ds;
uint32_t r_rise_ie;
uint32_t r_rise_ip;
uint32_t r_fall_ie;
uint32_t r_fall_ip;
uint32_t r_high_ie;
uint32_t r_high_ip;
uint32_t r_low_ie;
uint32_t r_low_ip;
uint32_t r_iof_en;
uint32_t r_iof_sel;
uint32_t r_out_xor;
// register declarations
scc::sc_register<uint32_t> value;
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_sel;
scc::sc_register<uint32_t> out_xor;
gpio_regs(sc_core::sc_module_name nm);
template<unsigned BUSWIDTH=32>
void registerResources(scc::tlm_target<BUSWIDTH>& target);
template <unsigned BUSWIDTH = 32> 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(iof_en, r_iof_en, 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>
inline void sysc::gpio_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
template <unsigned BUSWIDTH> inline void sysc::gpio_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) {
target.addResource(value, 0x0UL);
target.addResource(input_en, 0x4UL);
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);
}
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_

View File

@ -1,80 +1,73 @@
////////////////////////////////////////////////////////////////////////////////
// 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.
//
// Created on: Fri Nov 10 18:01:53 CET 2017
// * plic_regs.h Author: <RDL Generator>
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 _PLIC_REGS_H_
#define _PLIC_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h>
#include <scc/register.h>
#include <scc/tlm_target.h>
#include <scc/utilities.h>
#include <util/bit_field.h>
namespace sysc {
class plic_regs :
public sc_core::sc_module,
public scc::resetable
{
class plic_regs : public sc_core::sc_module, public scc::resetable {
public:
// storage declarations
BEGIN_BF_DECL(priority_t, uint32_t);
BF_FIELD(priority, 0, 3);
END_BF_DECL() ;
BF_FIELD(priority, 0, 3);
END_BF_DECL();
std::array<priority_t, 256> r_priority;
std::array<uint32_t, 8> r_pending;
std::array<uint32_t, 8> r_enabled;
BEGIN_BF_DECL(threshold_t, uint32_t);
BF_FIELD(threshold, 0, 3);
BF_FIELD(threshold, 0, 3);
END_BF_DECL() r_threshold;
uint32_t r_claim_complete;
// register declarations
scc::sc_register_indexed<priority_t, 256> priority;
scc::sc_register_indexed<uint32_t, 8> pending;
scc::sc_register_indexed<uint32_t, 8> enabled;
scc::sc_register<threshold_t> threshold;
scc::sc_register<uint32_t> claim_complete;
plic_regs(sc_core::sc_module_name nm);
template<unsigned BUSWIDTH=32>
void registerResources(scc::tlm_target<BUSWIDTH>& target);
template <unsigned BUSWIDTH = 32> 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(enabled, r_enabled, 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>
inline void sysc::plic_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
template <unsigned BUSWIDTH> inline void sysc::plic_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) {
target.addResource(priority, 0x0UL);
target.addResource(pending, 0x1000UL);
target.addResource(enabled, 0x2000UL);

View File

@ -1,91 +1,84 @@
////////////////////////////////////////////////////////////////////////////////
// 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.
//
// Created on: Fri Nov 10 18:01:53 CET 2017
// * prci_regs.h Author: <RDL Generator>
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 _PRCI_REGS_H_
#define _PRCI_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h>
#include <scc/register.h>
#include <scc/tlm_target.h>
#include <scc/utilities.h>
#include <util/bit_field.h>
namespace sysc {
class prci_regs :
public sc_core::sc_module,
public scc::resetable
{
class prci_regs : public sc_core::sc_module, public scc::resetable {
public:
// storage declarations
BEGIN_BF_DECL(hfrosccfg_t, uint32_t);
BF_FIELD(hfroscdiv, 0, 6);
BF_FIELD(hfrosctrim, 16, 5);
BF_FIELD(hfroscen, 30, 1);
BF_FIELD(hfroscrdy, 31, 1);
BF_FIELD(hfroscdiv, 0, 6);
BF_FIELD(hfrosctrim, 16, 5);
BF_FIELD(hfroscen, 30, 1);
BF_FIELD(hfroscrdy, 31, 1);
END_BF_DECL() r_hfrosccfg;
BEGIN_BF_DECL(hfxosccfg_t, uint32_t);
BF_FIELD(hfxoscrdy, 31, 1);
BF_FIELD(hfxoscen, 30, 1);
BF_FIELD(hfxoscrdy, 31, 1);
BF_FIELD(hfxoscen, 30, 1);
END_BF_DECL() r_hfxosccfg;
BEGIN_BF_DECL(pllcfg_t, uint32_t);
BF_FIELD(pllr, 0, 3);
BF_FIELD(pllf, 4, 6);
BF_FIELD(pllq, 10, 2);
BF_FIELD(pllsel, 16, 1);
BF_FIELD(pllrefsel, 17, 1);
BF_FIELD(pllbypass, 18, 1);
BF_FIELD(plllock, 31, 1);
BF_FIELD(pllr, 0, 3);
BF_FIELD(pllf, 4, 6);
BF_FIELD(pllq, 10, 2);
BF_FIELD(pllsel, 16, 1);
BF_FIELD(pllrefsel, 17, 1);
BF_FIELD(pllbypass, 18, 1);
BF_FIELD(plllock, 31, 1);
END_BF_DECL() r_pllcfg;
uint32_t r_plloutdiv;
uint32_t r_coreclkcfg;
// register declarations
scc::sc_register<hfrosccfg_t> hfrosccfg;
scc::sc_register<hfxosccfg_t> hfxosccfg;
scc::sc_register<pllcfg_t> pllcfg;
scc::sc_register<uint32_t> plloutdiv;
scc::sc_register<uint32_t> coreclkcfg;
prci_regs(sc_core::sc_module_name nm);
template<unsigned BUSWIDTH=32>
void registerResources(scc::tlm_target<BUSWIDTH>& target);
template <unsigned BUSWIDTH = 32> 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(pllcfg, r_pllcfg, 0, *this)
, NAMED(plloutdiv, r_plloutdiv, 0, *this)
, NAMED(coreclkcfg, r_coreclkcfg, 0, *this)
{
}
, NAMED(coreclkcfg, r_coreclkcfg, 0, *this) {}
template<unsigned BUSWIDTH>
inline void sysc::prci_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
template <unsigned BUSWIDTH> inline void sysc::prci_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) {
target.addResource(hfrosccfg, 0x0UL);
target.addResource(hfxosccfg, 0x4UL);
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
// 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.
//
// Created on: Fri Nov 10 18:01:53 CET 2017
// * spi_regs.h Author: <RDL Generator>
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 _SPI_REGS_H_
#define _SPI_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h>
#include <scc/register.h>
#include <scc/tlm_target.h>
#include <scc/utilities.h>
#include <util/bit_field.h>
namespace sysc {
class spi_regs :
public sc_core::sc_module,
public scc::resetable
{
class spi_regs : public sc_core::sc_module, public scc::resetable {
public:
// storage declarations
BEGIN_BF_DECL(sckdiv_t, uint32_t);
BF_FIELD(div, 0, 12);
BF_FIELD(div, 0, 12);
END_BF_DECL() r_sckdiv;
BEGIN_BF_DECL(sckmode_t, uint32_t);
BF_FIELD(pha, 0, 1);
BF_FIELD(pol, 1, 1);
BF_FIELD(pha, 0, 1);
BF_FIELD(pol, 1, 1);
END_BF_DECL() r_sckmode;
uint32_t r_csid;
uint32_t r_csdef;
BEGIN_BF_DECL(csmode_t, uint32_t);
BF_FIELD(mode, 0, 2);
BF_FIELD(mode, 0, 2);
END_BF_DECL() r_csmode;
BEGIN_BF_DECL(delay0_t, uint32_t);
BF_FIELD(cssck, 0, 8);
BF_FIELD(sckcs, 16, 8);
BF_FIELD(cssck, 0, 8);
BF_FIELD(sckcs, 16, 8);
END_BF_DECL() r_delay0;
BEGIN_BF_DECL(delay1_t, uint32_t);
BF_FIELD(intercs, 0, 16);
BF_FIELD(interxfr, 16, 8);
BF_FIELD(intercs, 0, 16);
BF_FIELD(interxfr, 16, 8);
END_BF_DECL() r_delay1;
BEGIN_BF_DECL(fmt_t, uint32_t);
BF_FIELD(proto, 0, 2);
BF_FIELD(endian, 2, 1);
BF_FIELD(dir, 3, 1);
BF_FIELD(len, 16, 4);
BF_FIELD(proto, 0, 2);
BF_FIELD(endian, 2, 1);
BF_FIELD(dir, 3, 1);
BF_FIELD(len, 16, 4);
END_BF_DECL() r_fmt;
BEGIN_BF_DECL(txdata_t, uint32_t);
BF_FIELD(data, 0, 8);
BF_FIELD(full, 31, 1);
BF_FIELD(data, 0, 8);
BF_FIELD(full, 31, 1);
END_BF_DECL() r_txdata;
BEGIN_BF_DECL(rxdata_t, uint32_t);
BF_FIELD(data, 0, 8);
BF_FIELD(empty, 31, 1);
BF_FIELD(data, 0, 8);
BF_FIELD(empty, 31, 1);
END_BF_DECL() r_rxdata;
BEGIN_BF_DECL(txmark_t, uint32_t);
BF_FIELD(txmark, 0, 3);
BF_FIELD(txmark, 0, 3);
END_BF_DECL() r_txmark;
BEGIN_BF_DECL(rxmark_t, uint32_t);
BF_FIELD(rxmark, 0, 3);
BF_FIELD(rxmark, 0, 3);
END_BF_DECL() r_rxmark;
BEGIN_BF_DECL(fctrl_t, uint32_t);
BF_FIELD(en, 0, 1);
BF_FIELD(en, 0, 1);
END_BF_DECL() r_fctrl;
BEGIN_BF_DECL(ffmt_t, uint32_t);
BF_FIELD(cmd_en, 0, 1);
BF_FIELD(addr_len, 1, 2);
BF_FIELD(pad_cnt, 3, 4);
BF_FIELD(cmd_proto, 7, 2);
BF_FIELD(addr_proto, 9, 2);
BF_FIELD(data_proto, 11, 2);
BF_FIELD(cmd_code, 16, 8);
BF_FIELD(pad_code, 24, 8);
BF_FIELD(cmd_en, 0, 1);
BF_FIELD(addr_len, 1, 2);
BF_FIELD(pad_cnt, 3, 4);
BF_FIELD(cmd_proto, 7, 2);
BF_FIELD(addr_proto, 9, 2);
BF_FIELD(data_proto, 11, 2);
BF_FIELD(cmd_code, 16, 8);
BF_FIELD(pad_code, 24, 8);
END_BF_DECL() r_ffmt;
BEGIN_BF_DECL(ie_t, uint32_t);
BF_FIELD(txwm, 0, 1);
BF_FIELD(rxwm, 1, 1);
BF_FIELD(txwm, 0, 1);
BF_FIELD(rxwm, 1, 1);
END_BF_DECL() r_ie;
BEGIN_BF_DECL(ip_t, uint32_t);
BF_FIELD(txwm, 0, 1);
BF_FIELD(rxwm, 1, 1);
BF_FIELD(txwm, 0, 1);
BF_FIELD(rxwm, 1, 1);
END_BF_DECL() r_ip;
// register declarations
scc::sc_register<sckdiv_t> sckdiv;
scc::sc_register<sckmode_t> sckmode;
@ -143,11 +137,10 @@ public:
scc::sc_register<ffmt_t> ffmt;
scc::sc_register<ie_t> ie;
scc::sc_register<ip_t> ip;
spi_regs(sc_core::sc_module_name nm);
template<unsigned BUSWIDTH=32>
void registerResources(scc::tlm_target<BUSWIDTH>& target);
template <unsigned BUSWIDTH = 32> 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(ffmt, r_ffmt, 0, *this)
, NAMED(ie, r_ie, 0, *this)
, NAMED(ip, r_ip, 0, *this)
{
}
, NAMED(ip, r_ip, 0, *this) {}
template<unsigned BUSWIDTH>
inline void sysc::spi_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
template <unsigned BUSWIDTH> inline void sysc::spi_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) {
target.addResource(sckdiv, 0x0UL);
target.addResource(sckmode, 0x4UL);
target.addResource(csid, 0x10UL);

View File

@ -1,89 +1,83 @@
////////////////////////////////////////////////////////////////////////////////
// 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.
//
// Created on: Fri Nov 10 18:01:53 CET 2017
// * uart_regs.h Author: <RDL Generator>
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 _UART_REGS_H_
#define _UART_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h>
#include <scc/register.h>
#include <scc/tlm_target.h>
#include <scc/utilities.h>
#include <util/bit_field.h>
namespace sysc {
class uart_regs :
public sc_core::sc_module,
public scc::resetable
{
class uart_regs : public sc_core::sc_module, public scc::resetable {
public:
// storage declarations
BEGIN_BF_DECL(txdata_t, uint32_t);
BF_FIELD(data, 0, 8);
BF_FIELD(full, 31, 1);
BF_FIELD(data, 0, 8);
BF_FIELD(full, 31, 1);
END_BF_DECL() r_txdata;
BEGIN_BF_DECL(rxdata_t, uint32_t);
BF_FIELD(data, 0, 8);
BF_FIELD(empty, 31, 1);
BF_FIELD(data, 0, 8);
BF_FIELD(empty, 31, 1);
END_BF_DECL() r_rxdata;
BEGIN_BF_DECL(txctrl_t, uint32_t);
BF_FIELD(txen, 0, 1);
BF_FIELD(nstop, 1, 1);
BF_FIELD(txcnt, 16, 3);
BF_FIELD(txen, 0, 1);
BF_FIELD(nstop, 1, 1);
BF_FIELD(txcnt, 16, 3);
END_BF_DECL() r_txctrl;
BEGIN_BF_DECL(rxctrl_t, uint32_t);
BF_FIELD(rxen, 0, 1);
BF_FIELD(rxcnt, 16, 3);
BF_FIELD(rxen, 0, 1);
BF_FIELD(rxcnt, 16, 3);
END_BF_DECL() r_rxctrl;
BEGIN_BF_DECL(ie_t, uint32_t);
BF_FIELD(txwm, 0, 1);
BF_FIELD(rxwm, 1, 1);
BF_FIELD(txwm, 0, 1);
BF_FIELD(rxwm, 1, 1);
END_BF_DECL() r_ie;
BEGIN_BF_DECL(ip_t, uint32_t);
BF_FIELD(txwm, 0, 1);
BF_FIELD(rxwm, 1, 1);
BF_FIELD(txwm, 0, 1);
BF_FIELD(rxwm, 1, 1);
END_BF_DECL() r_ip;
BEGIN_BF_DECL(div_t, uint32_t);
BF_FIELD(div, 0, 16);
BF_FIELD(div, 0, 16);
END_BF_DECL() r_div;
// register declarations
scc::sc_register<txdata_t> txdata;
scc::sc_register<rxdata_t> rxdata;
@ -92,11 +86,10 @@ public:
scc::sc_register<ie_t> ie;
scc::sc_register<ip_t> ip;
scc::sc_register<div_t> div;
uart_regs(sc_core::sc_module_name nm);
template<unsigned BUSWIDTH=32>
void registerResources(scc::tlm_target<BUSWIDTH>& target);
template <unsigned BUSWIDTH = 32> 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(ie, r_ie, 0, *this)
, NAMED(ip, r_ip, 0, *this)
, NAMED(div, r_div, 0, *this)
{
}
, NAMED(div, r_div, 0, *this) {}
template<unsigned BUSWIDTH>
inline void sysc::uart_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
template <unsigned BUSWIDTH> inline void sysc::uart_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) {
target.addResource(txdata, 0x0UL);
target.addResource(rxdata, 0x4UL);
target.addResource(txctrl, 0x8UL);

View File

@ -1,47 +1,44 @@
////////////////////////////////////////////////////////////////////////////////
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 _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 "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 {
@ -50,18 +47,18 @@ class WsHandler;
class gpio : public sc_core::sc_module, public scc::tlm_target<> {
public:
SC_HAS_PROCESS(gpio);
SC_HAS_PROCESS(gpio);// NOLINT
sc_core::sc_in<sc_core::sc_time> clk_i;
sc_core::sc_in<bool> rst_i;
// 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_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> iof1_o;
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> iof0_i;
sc_core::sc_vector<scc::tlm_signal_bool_opt_in> iof1_i;
gpio(sc_core::sc_module_name nm);
virtual ~gpio() override; // need to keep it in source file because of fwd declaration of gpio_regs
@ -71,19 +68,18 @@ public:
protected:
void clock_cb();
void reset_cb();
void update_pins();
void update_pins(uint32_t changed_bits);
void before_end_of_elaboration();
void pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_logic>& gp, sc_core::sc_time& delay);
void forward_pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_logic>& gp);
void iof_input(unsigned int tag, unsigned iof_idx, tlm::tlm_signal_gp<>& 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_dt::sc_logic> &gp);
void iof_input(unsigned int tag, unsigned iof_idx, tlm::tlm_signal_gp<> &gp, sc_core::sc_time &delay);
sc_core::sc_time clk;
std::array<bool, 32> last_iof0, last_iof1;
std::unique_ptr<gpio_regs> regs;
std::shared_ptr<sysc::WsHandler> handler;
private:
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);
tlm::tlm_phase write_output(tlm::tlm_signal_gp<sc_dt::sc_logic> &gp, size_t i, sc_dt::sc_logic val);
};
} /* 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
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 _PLIC_H_
#define _PLIC_H_
@ -46,7 +42,7 @@ class plic_regs;
class plic : public sc_core::sc_module, public scc::tlm_target<> {
public:
SC_HAS_PROCESS(plic);
SC_HAS_PROCESS(plic);// NOLINT
sc_core::sc_in<sc_core::sc_time> clk_i;
sc_core::sc_in<bool> rst_i;
sc_core::sc_vector<sc_core::sc_in<bool>> global_interrupts_i;
@ -59,7 +55,6 @@ public:
protected:
void clock_cb();
void reset_cb();
void init_callbacks();
void global_int_port_cb();
void handle_pending_int();

View File

@ -1,38 +1,34 @@
////////////////////////////////////////////////////////////////////////////////
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 _PRCI_H_
#define _PRCI_H_
@ -45,8 +41,8 @@ class prci_regs;
class prci : public sc_core::sc_module, public scc::tlm_target<> {
public:
SC_HAS_PROCESS(prci);
sc_core::sc_port<sc_core::sc_signal_in_if<sc_core::sc_time>,1,SC_ZERO_OR_MORE_BOUND> hfxosc_i;
SC_HAS_PROCESS(prci);// NOLINT
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_out<sc_core::sc_time> hfclk_o;
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
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 _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 <tlm/tlm_signal.h>
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:
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<bool> rst_i;
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;
sc_core::sc_in<bool> rst_i;
tlm_out<bool> sck_o;
tlm_out<bool> mosi_o;
tlm_in<bool> miso_i;
sc_core::sc_vector<tlm_out<bool>> scs_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);
virtual ~spi() override;
spi(spi &&other) = delete;
spi &operator=(spi &other) = delete;
spi &operator=(spi &&other) = delete;
~spi() override = default;
protected:
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_time clk;
std::unique_ptr<spi_regs> regs;
sc_core::sc_fifo<uint8_t> rx_fifo, tx_fifo;
spi(sc_core::sc_module_name nm)
: sc_core::sc_module(nm)
, NAMED(clk_i)
, NAMED(rst_i)
, NAMED(sck_o)
, NAMED(mosi_o)
, NAMED(miso_i)
, NAMED(scs_o, 4)
, NAMED(irq_o){};
};
} /* namespace sysc */

View File

@ -1,47 +1,43 @@
////////////////////////////////////////////////////////////////////////////////
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 _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 "scc/signal_initiator_mixin.h"
#include "scc/signal_target_mixin.h"
#include "scc/tlm_target.h"
#include <tlm/tlm_signal.h>
namespace sysc {
class tlm_signal_uart_extension;
@ -50,11 +46,11 @@ class WsHandler;
class uart : public sc_core::sc_module, public scc::tlm_target<> {
public:
SC_HAS_PROCESS(uart);
SC_HAS_PROCESS(uart);// NOLINT
sc_core::sc_in<sc_core::sc_time> clk_i;
sc_core::sc_in<bool> rst_i;
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;
@ -67,9 +63,9 @@ protected:
void clock_cb();
void reset_cb();
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();
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;
sc_core::sc_fifo<uint8_t> rx_fifo, tx_fifo;
};

View File

@ -1,111 +1,112 @@
////////////////////////////////////////////////////////////////////////////////
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 _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/PageHandler.h>
#include <sysc/kernel/sc_module.h>
#include <memory>
#include <thread>
#include <cstring>
#include <functional>
#include <memory>
#include <thread>
namespace sysc {
class WsHandler: public seasocks::WebSocket::Handler {
class WsHandler : public seasocks::WebSocket::Handler {
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:
std::set<seasocks::WebSocket*> _connections;
std::function<void(const char* data)> callback;
std::set<seasocks::WebSocket *> _connections;
std::function<void(const char *data)> callback;
};
class sc_comm_singleton: public sc_core::sc_module {
struct DefaultPageHandler: public seasocks::PageHandler {
DefaultPageHandler(sc_comm_singleton& o):owner(o){}
virtual std::shared_ptr<seasocks::Response> handle(const seasocks::Request& request);
sc_comm_singleton& owner;
};
class sc_comm_singleton : public sc_core::sc_module {
struct DefaultPageHandler : public seasocks::PageHandler {
DefaultPageHandler(sc_comm_singleton &o)
: owner(o) {}
virtual std::shared_ptr<seasocks::Response> handle(const seasocks::Request &request);
sc_comm_singleton &owner;
};
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 i("__sc_singleton");
return i;
}
static sc_comm_singleton &inst() {
static sc_comm_singleton i("__sc_singleton");
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 start_client();
protected:
void start_of_simulation() override;
void end_of_simulation() override;
void start_of_simulation() override;
void end_of_simulation() override;
private:
sc_comm_singleton(sc_core::sc_module_name nm);
std::unique_ptr<seasocks::Server> m_serv;
std::thread t;
void thread_func();
bool needs_client, client_started;
std::vector<std::string> endpoints;
sc_comm_singleton(sc_core::sc_module_name nm);
std::unique_ptr<seasocks::Server> m_serv;
std::thread t;
void thread_func();
bool needs_client, client_started;
std::vector<std::string> endpoints;
};
} /* 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
* Author: eyck
*/
* 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_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 uart_tx {
unsigned data_bits:4;
unsigned stop_bits:2;
bool parity:1;
unsigned baud_rate:24;
unsigned data_bits : 4;
unsigned stop_bits : 2;
bool parity : 1;
unsigned baud_rate : 24;
unsigned data;
} tx;
sc_core::sc_time start_time;
};
struct tlm_signal_spi_extension : public tlm::tlm_unmanaged_extension<tlm_signal_spi_extension> {
struct spi_tx {
unsigned data_bits:5;
bool msb_first:1;
bool s2m_data_valid:1;
unsigned data_bits : 5;
bool msb_first : 1;
bool m2s_data_valid : 1;
bool s2m_data_valid : 1;
unsigned m2s_data, s2m_data;
} tx;
sc_core::sc_time start_time;
void copy_from(tlm_extension_base const & other) override {
auto& o = static_cast<const type&>(other);
this->tx=o.tx;
this->start_time=o.start_time;
void copy_from(tlm_extension_base const &other) override {
auto &o = static_cast<const type &>(other);
this->tx = o.tx;
this->start_time = o.start_time;
}
};
}
#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
* Author: eyck
*/
* 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 BLDC_H_
#define BLDC_H_
@ -11,43 +36,47 @@
#include <boost/numeric/odeint.hpp>
namespace odeint = boost::numeric::odeint;
inline
double norm_angle(double alpha){
double alpha_n = fmod(alpha, M_PI * 2);
if (alpha_n < 0.) alpha_n += (M_PI * 2);
return alpha_n;
inline double norm_angle(double alpha) {
double alpha_n = fmod(alpha, M_PI * 2);
while (alpha_n < 0.) alpha_n += (M_PI * 2);
return alpha_n;
}
class BLDC {
public:
struct Config {
double inertia = 0.0005; /* aka 'J' in kg/(m^2) */
double damping = 0.000089; /* aka 'B' in Nm/(rad/s) */
double static_friction = 0.0; /* in Nm */
//double Kv = 0.0042; /* motor constant in RPM/V */
double Ke = 0.0042; /* back emf constant in V/rad/s*/
double L = 0.0027; /* Coil inductance in H */
double M = -0.000069; /* Mutual coil inductance in H */
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) */
double inertia = 0.0005; /* aka 'J' in kg/(m^2) */
double damping = 0.000089; /* aka 'B' in Nm/(rad/s) */
double static_friction = 0.0; /* in Nm */
// double Kv = 0.0042; /* motor constant in RPM/V */
double Ke = 0.0042; /* back emf constant in V/rad/s*/
double L = 0.0027; /* Coil inductance in H */
double M = -0.000069; /* Mutual coil inductance in H */
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) */
};
using StateVector = std::array<double, 5>;
struct State{
double& theta; /* angle of the rotor */
double& omega; /* angular speed of the rotor */
double& ia; /* phase a current */
double& ib; /* phase b 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]){}
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(){
struct State {
double &theta; /* angle of the rotor */
double &omega; /* angular speed of the rotor */
double &ia; /* phase a current */
double &ib; /* phase b 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]) {}
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;
omega = 0.;
}
@ -57,49 +86,46 @@ public:
virtual ~BLDC();
void set_input(std::array<double, 3> vin){
this->vin=vin;
}
void set_input(std::array<double, 3> vin) { this->vin = vin; }
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(){
return std::tuple<double, double, double>(
voltages[VA]+voltages[EA]+state.ia*config.R,
voltages[VB]+voltages[EB]+state.ib*config.R,
voltages[VC]+voltages[EC]+state.ic*config.R
);
std::array<double, 7> get_voltages() {
return std::array<double, 7>{voltages[VA], voltages[VB], voltages[VC], voltages[VCENTER],
voltages[EA], voltages[EB], voltages[EC]};
}
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:
Config config;
StateVector stateVector;
State state;
std::array<double, 3> vin;
double current_time = 0.0;
double torque_load=0.0;
double etorque=0.0, mtorque=0.0;
const double dt = 0.000001;
double torque_load = 0.0001;
double etorque = 0.0, mtorque = 0.0;
std::array<double, 7> voltages;
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 );
void calc_back_emf(const State& state, double theta_e );
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);
void calc_back_emf(const State &state, double theta_e);
void calc_voltages();
// ODE part
//boost::numeric::odeint::runge_kutta4< 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_cash_karp54< StateVector>;
using stepper_type = odeint::runge_kutta_fehlberg78< StateVector>;
void rotor_dyn( const StateVector& x , StateVector& dxdt , const double t );
// boost::numeric::odeint::runge_kutta4< 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_cash_karp54< StateVector>;
using stepper_type = odeint::runge_kutta_fehlberg78<StateVector>;
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_ */

View File

@ -1,36 +1,66 @@
/*
* dcmotor.h
/*******************************************************************************
* Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Created on: 25.07.2018
* Author: eyck
*/
* 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_DCMOTOR_H_
#define _SYSC_TOP_DCMOTOR_H_
#include "BLDC.h"
#include "cci_configuration"
#include "scc/traceable.h"
#include <systemc>
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:
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_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();
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:
void thread(void);
BLDC bldc_model;
const BLDC::State& bldc_state;
const BLDC::State &bldc_state;
std::array<double, 7> vout;
};
} /* 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
* Author: eyck
*/
* 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 RISCV_SC_INCL_SYSC_TOP_H_BRIDGE_H_
#define RISCV_SC_INCL_SYSC_TOP_H_BRIDGE_H_
@ -13,9 +38,9 @@
namespace sysc {
class h_bridge: public sc_core::sc_module {
class h_bridge : public sc_core::sc_module {
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> hb_i, lb_i;
@ -25,13 +50,15 @@ public:
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();
private:
void ain_cb();
void bin_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 */

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
* Author: eyck
*/
* 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_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 "h_bridge.h"
#include <memory>
#include <systemc>
#include "hifive1.h"
namespace sysc {
class system: sc_core::sc_module {
class system : sc_core::sc_module {
public:
SC_HAS_PROCESS(system);
SC_HAS_PROCESS(system);// NOLINT
system(sc_core::sc_module_name nm);
virtual ~system();
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<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;
sysc::hifive1 i_platform;
sysc::terminal i_terminal;
sysc::mcp3008 i_adc;
sysc::hifive1 i_hifive1;
sysc::h_bridge i_h_bridge;
sysc::dc_motor i_motor;
void gen_por();
};
}
#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
* Author: eyck
*/
* 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_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 <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 <sysc/kernel/sc_module.h>
namespace sysc {
class WsHandler;
class terminal: public sc_core::sc_module {
class terminal : public sc_core::sc_module {
public:
scc::tlm_signal_logic_out tx_o;
scc::tlm_signal_logic_in rx_i;
scc::tlm_signal_logic_in rx_i;
terminal();
terminal(const sc_core::sc_module_name& nm);
terminal(const sc_core::sc_module_name &nm);
virtual ~terminal();
@ -33,11 +58,11 @@ public:
protected:
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::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
FILE(GLOB RiscVSCHeaders *.h */*.h)
FILE(GLOB RiscvSCSources sysc/*.cpp)
FILE(GLOB RiscVSCHeaders ${PROJECT_SOURCE_DIR}/incl/sysc/*.h ${PROJECT_SOURCE_DIR}/incl/sysc/*/*.h)
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)
# 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"
set(APPLICATION_NAME riscv.vp)
include_directories(${PROJECT_SOURCE_DIR}/incl)
include_directories(${CONAN_INCLUDE_DIRS_SEASOCKS})
add_definitions(-DWITH_SYSTEMC) # or -DSC_NO_WRITE_CHECK
include_directories(${SystemC_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})
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
target_link_libraries(${APPLICATION_NAME} ${LIBRARY_NAME})
target_link_libraries(${APPLICATION_NAME} riscv.sc)
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} ${SystemC_LIBRARIES} )
if(SCV_FOUND)
add_definitions(-DWITH_SCV)
include_directories(${SCV_INCLUDE_DIRS})
link_directories(${SCV_LIBRARY_DIRS})
target_link_libraries (${APPLICATION_NAME} ${SCV_LIBRARIES})
endif()

View File

@ -1,49 +1,52 @@
////////////////////////////////////////////////////////////////////////////////
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 "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 <iss/log_categories.h>
#include <fstream>
#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;
namespace po = boost::program_options;
@ -54,69 +57,20 @@ const size_t SUCCESS = 0;
const size_t ERROR_UNHANDLED_EXCEPTION = 2;
} // 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[]) {
// 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"));
///////////////////////////////////////////////////////////////////////////
// CLI argument parsing
// CLI argument parsing & logging setup
///////////////////////////////////////////////////////////////////////////
po::options_description desc("Options");
// 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,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;
}
CLIParser parser(argc, argv);
if (!parser.is_valid()) return ERROR_IN_COMMAND_LINE;
///////////////////////////////////////////////////////////////////////////
// set up infrastructure
///////////////////////////////////////////////////////////////////////////
@ -124,45 +78,48 @@ int sc_main(int argc, char *argv[]) {
///////////////////////////////////////////////////////////////////////////
// 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
///////////////////////////////////////////////////////////////////////////
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>();
scc::tracer trace("simple_system", static_cast<scc::tracer::file_type>(trace_val >> 1), trace_val != 0);
trace.add_control();
///////////////////////////////////////////////////////////////////////////
// dump configuration if requested
///////////////////////////////////////////////////////////////////////////
if(vm["dump-config"].as<std::string>().size()>0){
std::ofstream of{vm["dump-config"].as<std::string>()};
if(of.is_open())
cfg.dump_configuration(of);
if (parser.get<std::string>("dump-config").size() > 0) {
std::ofstream of{parser.get<std::string>("dump-config")};
if (of.is_open()) cfg.dump_configuration(of);
}
cfg.configure();
cfg.configure();
///////////////////////////////////////////////////////////////////////////
// overwrite config with command line settings
///////////////////////////////////////////////////////////////////////////
if (vm["gdb-port"].as<unsigned short>())
cfg.set_value("i_system.i_platform.i_core_complex.gdb_server_port", vm["gdb-port"].as<unsigned short>());
if (vm.count("dump-ir"))
cfg.set_value("i_system.i_platform.i_core_complex.dump_ir", vm.count("dump-ir") != 0);
if (vm.count("elf"))
cfg.set_value("i_system.i_platform.i_core_complex.elf_file", vm["elf"].as<std::string>());
if (vm.count("quantum"))
tlm::tlm_global_quantum::instance().set(sc_core::sc_time(vm["quantum"].as<unsigned>(), sc_core::SC_NS));
if (vm.count("reset")) {
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);
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_hifive1.i_fe310.i_core_complex.dump_ir", parser.is_set("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"));
if (parser.is_set("quantum"))
tlm::tlm_global_quantum::instance().set(sc_core::sc_time(parser.get<unsigned>("quantum"), sc_core::SC_NS));
if (parser.is_set("reset")) {
auto str = parser.get<std::string>("reset");
uint64_t start_address = str.find("0x") == 0 ? std::stoull(str.substr(2), nullptr, 16) : std::stoull(str, nullptr, 10);
cfg.set_value("i_system.i_hifive1.i_fe310.i_core_complex.reset_address", start_address);
}
if (vm.count("disass")) {
cfg.set_value("i_system.i_platform.i_core_complex.enable_disass", true);
if (parser.is_set("disass")) {
cfg.set_value("i_system.i_hifive1.i_fe310.i_core_complex.enable_disass", true);
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) {
LOG_OUTPUT(disass)::stream() = fopen(file_name.c_str(), "w");
LOGGER(disass)::print_time() = false;
@ -173,14 +130,13 @@ int sc_main(int argc, char *argv[]) {
// run simulation
///////////////////////////////////////////////////////////////////////////
try {
if(vm.count("max_time")){
sc_core::sc_time max_time = scc::parse_from_string(vm["max_time"].as<std::string>());
sc_core::sc_start(max_time);
if (parser.is_set("max_time")) {
sc_core::sc_start(scc::parse_from_string(parser.get<std::string>("max_time")));
} else
sc_core::sc_start();
} catch(sc_core::sc_report& rep){
CLOG(FATAL, SystemC)<<"IWEF"[rep.get_severity()]<<"("<<rep.get_id()<<") "<<rep.get_msg_type()<<": "<<rep.get_msg()<<std::endl;
if (!sc_core::sc_end_of_simulation_invoked()) sc_core::sc_stop();
} 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;
}

View File

@ -1,9 +1,34 @@
/*
* BLDC.cpp
/*******************************************************************************
* Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Created on: 26.06.2018
* Author: eyck
*/
* 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/top/BLDC.h"
@ -14,50 +39,48 @@ BLDC::BLDC(const Config config)
, stateVector({{0.0, 0.0, 0.0, 0.0, 0.0}})
, state(stateVector)
, 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();
}
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;
} else if(theta>=2./3.*M_PI && theta < 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 >= 2. / 3. * M_PI && theta < M_PI) {
return 1 - 6 / M_PI * (theta - 2. / 3. * M_PI);
} else if (theta >= M_PI && theta < 5. / 3. * M_PI) {
return -1;
} else if(theta>=5./3. * M_PI && theta < 2. * M_PI){
return -1+6/M_PI*(theta-5./3.*M_PI);
} else if (theta >= 5. / 3. * M_PI && theta <= 2. * M_PI) {
return -1 + 6 / M_PI * (theta - 5. / 3. * M_PI);
} else {
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");
}
}
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;
voltages[EA] = max_bemf*calc_bemf_factor(state, norm_angle(theta_e));
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.)));
theta_e-=M_PI * (1. / 3.);
voltages[EA] = max_bemf * calc_bemf_factor(state, norm_angle(theta_e));
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("");
/* Check which phases are excited. */
bool pa = isnan(vin[0])?false:true;
bool pb = isnan(vin[1])?false:true;
bool pc = isnan(vin[2])?false:true;
bool pa = isnan(vin[0]) ? false : true;
bool pb = isnan(vin[1]) ? false : true;
bool pc = isnan(vin[2]) ? false : true;
if (pa && pb && pc) {
voltages[VA] = vin[0];
voltages[VB] = vin[1];
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) {
voltages[VA] = vin[0];
voltages[VB] = vin[1];
@ -93,19 +116,21 @@ void BLDC::calc_voltages(){
voltages[VB] = voltages[EB];
voltages[VC] = voltages[EC];
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 {
os<<state.omega<<";"<<state.theta<<";"
<<state.ia<<";"<<state.ib<<";"<<state.ic<<";"
<<voltages[VA]<<";"<<voltages[VB]<<";"<<voltages[VC]<<";"
<<voltages[EA]<<";"<<voltages[EB]<<";"<<voltages[EC]<<";"<<voltages[VCENTER]<<";"
<<vin[0]<<";"<<vin[1]<<";"<<vin[2]<<";"<<etorque;
void BLDC::printToStream(std::ostream &os) const {
os << state.omega << ";" << state.theta << ";" << state.ia << ";" << state.ib << ";" << state.ic << ";"
<< voltages[VA] << ";" << voltages[VB] << ";" << voltages[VC] << ";" << voltages[EA] << ";" << voltages[EB]
<< ";" << voltages[EC] << ";" << voltages[VCENTER] << ";" << vin[0] << ";" << vin[1] << ";" << vin[2] << ";"
<< etorque;
}
void BLDC::rotor_dyn(const StateVector& x_, StateVector& dxdt_, const double t) {
const State x(const_cast<StateVector&>(x_));
void BLDC::rotor_dyn(const StateVector &x_, StateVector &dxdt_, const double t) {
const State x(const_cast<StateVector &>(x_));
State dxdt(dxdt_);
double theta_e = state.theta * (config.NbPoles / 2.);
/* Calculate backemf voltages. */
@ -113,18 +138,16 @@ void BLDC::rotor_dyn(const StateVector& x_, StateVector& dxdt_, const double t)
/* Calculate voltages. */
calc_voltages();
/* Electromagnetic torque. */
// if (x.omega == 0) {
// printf("ERROR: input state vector omega equals 0!!!\n");
// throw std::runtime_error("input state vector omega equals 0");
// }
// if (x.omega == 0) {
// printf("ERROR: input state vector omega equals 0!!!\n");
// throw std::runtime_error("input state vector omega equals 0");
// }
/* 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:
etorque = config.Ke*(
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.ic * (calc_bemf_factor(state, norm_angle(theta_e + M_PI * (4. / 3.))))
);
etorque = config.Ke * (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.ic * (calc_bemf_factor(state, norm_angle(theta_e + M_PI * (4. / 3.)))));
/* Mechanical torque. */
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) {
if(dt>incr) throw std::runtime_error("incr needs to be larger than dt");
double next_time = current_time+incr;
odeint::integrate_adaptive(make_controlled( 1.0e-10 , 1.0e-6 , stepper_type() ),
[this]( const StateVector &x , StateVector &dxdt , double t ) {this->rotor_dyn(x, dxdt,t);},
stateVector, current_time, next_time, dt);
current_time=next_time;
state.theta=norm_angle(state.theta);
if (dt > incr) throw std::runtime_error("incr needs to be larger than dt");
double next_time = current_time + incr;
odeint::integrate_adaptive(
make_controlled(1.0e-10, 1.0e-6, stepper_type()),
[this](const StateVector &x, StateVector &dxdt, double t) { this->rotor_dyn(x, dxdt, t); }, stateVector,
current_time, next_time, dt);
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);
return os;
}

View File

@ -1,38 +1,38 @@
////////////////////////////////////////////////////////////////////////////////
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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
*
*
*******************************************************************************/
#include "sysc/SiFive/aon.h"
@ -48,7 +48,7 @@ aon::aon(sc_core::sc_module_name nm)
, NAMED(erst_n_i)
, NAMED(lfclkc_o)
, NAMED(rst_o)
, NAMEDD(aon_regs, regs) {
, NAMEDD(regs, aon_regs) {
regs->registerResources(*this);
SC_METHOD(clock_cb);
sensitive << clk_i;
@ -56,28 +56,23 @@ aon::aon(sc_core::sc_module_name nm)
sensitive << erst_n_i;
}
void aon::start_of_simulation() {
rst_o=true;
}
void aon::start_of_simulation() { rst_o = true; }
void aon::clock_cb() {
this->clk = clk_i.read();
}
void aon::clock_cb() { this->clk = clk_i.read(); }
aon::~aon() {}
aon::~aon() {} // NOLINT
void aon::reset_cb() {
if (!erst_n_i.read()){
if (!erst_n_i.read()) {
regs->reset_start();
rst_o=true;
rst_o = true;
} else {
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 */

View File

@ -1,46 +1,43 @@
////////////////////////////////////////////////////////////////////////////////
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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/clint.h"
#include "scc/utilities.h"
#include "scc/report.h"
#include "scc/utilities.h"
#include "sysc/SiFive/gen/clint_regs.h"
namespace sysc {
using namespace sc_core;
const int lfclk_mutiplier = 1 << 12;
@ -52,28 +49,29 @@ clint::clint(sc_core::sc_module_name nm)
, NAMED(rst_i)
, NAMED(mtime_int_o)
, NAMED(msip_int_o)
, NAMEDD(clint_regs, regs)
, NAMEDD(regs, clint_regs)
, cnt_fraction(0) {
regs->registerResources(*this);
SC_METHOD(clock_cb);
sensitive << tlclk_i<<lfclk_i;
sensitive << tlclk_i << lfclk_i;
SC_METHOD(reset_cb);
sensitive << rst_i;
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()) {
reg.put(data);
this->update_mtime();
}
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();
data = reg.get();
return true;
});
regs->mtime.set_write_cb([this](scc::sc_register<uint64_t> &reg, uint64_t data) -> bool { return false; });
regs->msip.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool {
regs->mtime.set_write_cb(
[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);
msip_int_o.write(regs->r_msip.msip);
return true;
@ -89,7 +87,7 @@ void clint::clock_cb() {
update_mtime();
}
clint::~clint() {}
clint::~clint() = default;
void clint::reset_cb() {
if (rst_i.read()) {
@ -102,16 +100,18 @@ void clint::reset_cb() {
}
void clint::update_mtime() {
if(clk>SC_ZERO_TIME){
uint64_t elapsed_clks = (sc_time_stamp()-last_updt)/clk; // get the number of clock periods since last invocation
last_updt += elapsed_clks*clk; // increment the last_updt timestamp by the number of clocks
if(elapsed_clks){ // update mtime reg if we have more than 0 elapsed clk periods
regs->r_mtime+=elapsed_clks;
if (clk > SC_ZERO_TIME) {
uint64_t elapsed_clks =
(sc_time_stamp() - last_updt) / clk; // get the number of clock periods since last invocation
last_updt += elapsed_clks * clk; // increment the last_updt timestamp by the number of clocks
if (elapsed_clks) { // update mtime reg if we have more than 0 elapsed clk periods
regs->r_mtime += elapsed_clks;
mtime_evt.cancel();
if (regs->r_mtimecmp > 0)
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;
LOG(DEBUG)<<"Timer fires at "<< sc_time_stamp()+next_trigger;
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;
SCTRACE() << "Timer fires at " << sc_time_stamp() + next_trigger;
mtime_evt.notify(next_trigger);
mtime_int_o.write(false);
} else

View File

@ -1,9 +1,34 @@
/*
* dcmotor.cpp
/*******************************************************************************
* Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Created on: 25.07.2018
* Author: eyck
*/
* 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/top/dcmotor.h"
#include "scc/utilities.h"
@ -15,54 +40,74 @@ using namespace sc_core;
auto get_config = []() -> BLDC::Config {
BLDC::Config config{};
config.Ke=1./4000. ,//0.01; // V/rad/s, = 1/Kv
config.R=0.5; // Ohm
config.Ke = 1. / 4000., // 0.01; // V/rad/s, = 1/Kv
config.R = 0.5; // Ohm
config.Ke = 0.01;
config.inertia = 0.0005;
config.NbPoles = 2;
config.damping = 0.00001;
return config;
};
dc_motor::dc_motor(const sc_module_name& nm )
dc_motor::dc_motor(const sc_module_name &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_state(bldc_model.getState())
{
, bldc_state(bldc_model.getState()) {
bldc_model.setLoad(0.0001);
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) {
auto ia=bldc_state.ia; TRACE_VAR(trf, ia);
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) {
void dc_motor::thread() {
const auto divider = 10.0;
wait(SC_ZERO_TIME);
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::tuple<double, double, double> {
auto eval_model = [this](std::array<double, 3> vin, const sc_time step) -> std::array<double, 7> {
bldc_model.set_input(vin);
bldc_model.run(step.to_seconds());
return bldc_model.get_voltages();
};
while(true){
vin[0]=va_i.read();
vin[1]=vb_i.read();
vin[2]=vc_i.read();
// auto sim_res=std::async(std::launch::async, eval_model, vin, step);
wait(step);
// auto vout=sim_res.get();
auto vout = eval_model(vin, step);
va_o=std::get<0>(vout);
vb_o=std::get<1>(vout);
vc_o=std::get<2>(vout);
while (true) {
vin[0] = va_i.read();
vin[1] = vb_i.read();
vin[2] = vc_i.read();
// auto sim_res=std::async(std::launch::async, eval_model, vin, step);
auto start = sc_time_stamp();
wait(max_integ_step, va_i.value_changed_event() | vb_i.value_changed_event() | vc_i.value_changed_event());
auto diff = sc_time_stamp() - start;
if (diff.to_seconds() >= bldc_model.dt) {
vout = eval_model(vin, diff); // sim_res.get();
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
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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/gpio.h"
#include "sysc/sc_comm_singleton.h"
#include "scc/report.h"
#include "scc/utilities.h"
#include "sysc/SiFive/gen/gpio_regs.h"
#include "sysc/sc_comm_singleton.h"
#include <limits>
namespace sysc {
using namespace sc_core;
using namespace sc_dt;
gpio::gpio(sc_core::sc_module_name nm)
: sc_core::sc_module(nm)
@ -53,95 +52,85 @@ gpio::gpio(sc_core::sc_module_name nm)
, NAMED(iof1_o, 32)
, NAMED(iof0_i, 32)
, NAMED(iof1_i, 32)
, NAMEDD(gpio_regs, regs)
, NAMED(write_to_ws, false){
, NAMEDD(regs, gpio_regs)
, NAMED(write_to_ws, false) {
regs->registerResources(*this);
SC_METHOD(clock_cb);
sensitive << clk_i;
SC_METHOD(reset_cb);
sensitive << rst_i;
dont_initialize();
auto pins_i_cb =[this](unsigned int tag, tlm::tlm_signal_gp<sc_logic>& gp,
tlm::tlm_phase& phase, sc_core::sc_time& delay)->tlm::tlm_sync_enum{
auto pins_i_cb = [this](unsigned int tag, tlm::tlm_signal_gp<sc_logic> &gp, tlm::tlm_phase &phase,
sc_core::sc_time &delay) -> tlm::tlm_sync_enum {
this->pin_input(tag, gp, delay);
return tlm::TLM_COMPLETED;
};
auto i=0U;
for(auto& s:pins_i){
auto i = 0U;
for (auto &s : pins_i) {
s.register_nb_transport(pins_i_cb, i);
++i;
}
auto iof0_i_cb =[this](unsigned int tag, tlm::tlm_signal_gp<bool>& gp,
tlm::tlm_phase& phase, sc_core::sc_time& delay)->tlm::tlm_sync_enum{
last_iof0[tag]=gp.get_value();
auto iof0_i_cb = [this](unsigned int tag, tlm::tlm_signal_gp<bool> &gp, tlm::tlm_phase &phase,
sc_core::sc_time &delay) -> tlm::tlm_sync_enum {
last_iof0[tag] = gp.get_value();
this->iof_input(tag, 0, gp, delay);
return tlm::TLM_COMPLETED;
};
i=0;
for(auto& s:iof0_i){
i = 0;
for (auto &s : iof0_i) {
s.register_nb_transport(iof0_i_cb, i);
++i;
}
auto iof1_i_cb =[this](unsigned int tag, tlm::tlm_signal_gp<bool>& gp,
tlm::tlm_phase& phase, sc_core::sc_time& delay)->tlm::tlm_sync_enum{
last_iof1[tag]=gp.get_value();
auto iof1_i_cb = [this](unsigned int tag, tlm::tlm_signal_gp<bool> &gp, tlm::tlm_phase &phase,
sc_core::sc_time &delay) -> tlm::tlm_sync_enum {
last_iof1[tag] = gp.get_value();
this->iof_input(tag, 1, gp, delay);
return tlm::TLM_COMPLETED;
};
i=0;
for(auto& s:iof1_i){
i = 0;
for (auto &s : iof1_i) {
s.register_nb_transport(iof1_i_cb, 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()) {
auto changed_bits = (reg.get() ^ data);
reg.put(data);
// read r_ports and update pins_io
update_pins();
update_pins(changed_bits);
}
return true;
});
regs->iof_en.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool {
if (!this->regs->in_reset()) {
enable_outputs(data, regs->r_iof_sel);
reg.put(data);
}
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;
});
};
regs->port.set_write_cb(update_pins_cb);
regs->output_en.set_write_cb(update_pins_cb);
regs->out_xor.set_write_cb(update_pins_cb);
regs->iof_en.set_write_cb(update_pins_cb);
regs->iof_sel.set_write_cb(update_pins_cb);
}
gpio::~gpio() {}
gpio::~gpio() = default;
void gpio::before_end_of_elaboration() {
if(write_to_ws.get_value()) {
LOG(TRACE)<<"Adding WS handler for "<<(std::string{"/ws/"}+name());
handler=std::make_shared<WsHandler>();
sc_comm_singleton::inst().registerWebSocketHandler((std::string{"/ws/"}+name()).c_str(), handler);
}
if (write_to_ws.get_value()) {
SCTRACE() << "Adding WS handler for " << (std::string{"/ws/"} + name());
handler = std::make_shared<WsHandler>();
sc_comm_singleton::inst().registerWebSocketHandler((std::string{"/ws/"} + name()).c_str(), handler);
}
}
void gpio::reset_cb() {
if (rst_i.read())
if (rst_i.read()) {
regs->reset_start();
else
} else {
regs->reset_stop();
}
update_pins(std::numeric_limits<uint32_t>::max());
}
void gpio::clock_cb() {
this->clk = clk_i.read();
}
void gpio::clock_cb() { 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};
tlm::tlm_phase phase{ tlm::BEGIN_REQ };
tlm::tlm_phase phase{tlm::BEGIN_REQ};
gp.set_command(tlm::TLM_WRITE_COMMAND);
gp.set_response_status(tlm::TLM_OK_RESPONSE);
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;
}
void gpio::update_pins() {
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);
void gpio::update_pins(uint32_t changed_bits) {
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(changed_bits&mask){
if(new_iof_en&mask){
if((regs->r_iof_sel&mask)==0 && iof0_i[i].size()>0){
tlm::tlm_phase phase = write_output(gp, i, last_iof0[i]?sc_dt::Log_1:sc_dt::Log_0);
} else if((regs->r_iof_sel&mask)==1 && iof1_i[i].size()>0)
tlm::tlm_phase phase = write_output(gp, i, last_iof1[i]?sc_dt::Log_1:sc_dt::Log_0);
sc_logic val;
for (size_t i = 0, mask = 1; i < 32; ++i, mask <<= 1) {
if (changed_bits & mask) {
if ((regs->r_iof_en & mask != 0) && (iof0_i[i].size() == 0 || iof1_i[i].size() == 0)) {
if ((regs->r_iof_sel & mask) == 0 && iof0_i[i].size() > 0) {
val = last_iof0[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 {
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);
if (regs->r_output_en & mask)
val = regs->r_port & mask ? sc_dt::Log_1 : sc_dt::Log_0;
else
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) {
if(delay>SC_ZERO_TIME){
wait(delay);
delay=SC_ZERO_TIME;
}
switch(gp.get_value().value()){
case sc_dt::Log_1:
regs->r_value|=1<<tag;
forward_pin_input(tag, gp);
break;
case sc_dt::Log_0:
regs->r_value&=~(1<<tag);
forward_pin_input(tag, gp);
break;
}
void gpio::pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_logic> &gp, sc_core::sc_time &delay) {
if (delay > SC_ZERO_TIME) {
wait(delay);
delay = SC_ZERO_TIME;
}
auto mask = 1u << tag;
switch (gp.get_value().value()) {
case sc_dt::Log_1:
if (regs->r_output_en & mask == 0) regs->r_value |= mask;
forward_pin_input(tag, gp);
break;
case sc_dt::Log_0:
if (regs->r_output_en & mask == 0) regs->r_value &= ~mask;
forward_pin_input(tag, gp);
break;
}
}
void gpio::forward_pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_logic>& gp) {
const auto mask = 1U<<tag;
if(regs->iof_en&mask){
auto& socket = regs->iof_sel&mask?iof1_o[tag]:iof0_o[tag];
void gpio::forward_pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_logic> &gp) {
const auto mask = 1U << tag;
if (regs->iof_en & mask) {
auto &socket = regs->iof_sel & mask ? iof1_o[tag] : iof0_o[tag];
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};
tlm::tlm_phase phase{tlm::BEGIN_REQ};
new_gp.set_command(tlm::TLM_WRITE_COMMAND);
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);
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) {
if(delay>SC_ZERO_TIME){
wait(delay);
delay=SC_ZERO_TIME;
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) {
wait(delay);
delay = SC_ZERO_TIME;
}
const auto mask = 1U<<tag;
if(regs->r_iof_en&mask){
const auto idx = regs->r_iof_sel&mask?1:0;
if(iof_idx == idx){
auto& socket = pins_o[tag];
for(size_t i=0; i<socket.size(); ++i){
const auto mask = 1U << tag;
if (regs->r_iof_en & mask) {
const auto idx = regs->r_iof_sel & mask ? 1 : 0;
if (iof_idx == idx) {
auto &socket = pins_o[tag];
for (size_t i = 0; i < socket.size(); ++i) {
sc_core::sc_time delay{SC_ZERO_TIME};
tlm::tlm_phase phase{tlm::BEGIN_REQ};
tlm::tlm_signal_gp<sc_logic> new_gp;
new_gp.set_command(tlm::TLM_WRITE_COMMAND);
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);
socket->nb_transport_fw(new_gp, phase, delay); // we don't care about phase and sync enum
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 */

View File

@ -1,18 +1,45 @@
/*
* h_bridge.cpp
/*******************************************************************************
* Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Created on: 25.07.2018
* Author: eyck
*/
* 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/top/h_bridge.h"
#include "scc/utilities.h"
#include <cmath>
namespace sysc {
using namespace sc_core;
using namespace sc_dt;
h_bridge::h_bridge(const sc_module_name& nm)
:sc_module(nm)
h_bridge::h_bridge(const sc_module_name &nm)
: sc_module(nm)
, NAMED(ha_i)
, NAMED(la_i)
, NAMED(hb_i)
@ -22,26 +49,55 @@ h_bridge::h_bridge(const sc_module_name& nm)
, NAMED(va_o)
, NAMED(vb_o)
, NAMED(vc_o)
, NAMED(vcc, 48.0)
{
, NAMED(vcc, 48.0) {
SC_METHOD(ain_cb);
sensitive<<ha_i<<la_i;
sensitive << ha_i << la_i;
SC_METHOD(bin_cb);
sensitive<<hb_i<<lb_i;
sensitive << hb_i << lb_i;
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 */

View File

@ -1,145 +1,111 @@
////////////////////////////////////////////////////////////////////////////////
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 "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)
: sc_core::sc_module(nm)
, NAMED(pins_o, 32)
, NAMED(pins_i, 32)
hifive1::hifive1(sc_module_name nm)
: sc_module(nm)
, NAMED(erst_n)
, NAMED(i_core_complex)
, NAMED(i_router, 12, 1)
, NAMED(i_uart0)
, NAMED(i_uart1)
, NAMED(i_qspi0)
, NAMED(i_qspi1)
, NAMED(i_qspi2)
, NAMED(i_gpio0)
, NAMED(i_plic)
, NAMED(i_aon)
, NAMED(i_prci)
, NAMED(i_clint)
, NAMED(i_mem_qspi)
, NAMED(i_mem_ram)
, NAMED(s_tlclk)
, 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)
, NAMED(vref_i)
#define PORT_NAMING(z, n, _) , NAMED(adc_ch##n##_i)
BOOST_PP_REPEAT(8, PORT_NAMING, _)
#undef PORT_NAMING
, NAMED(ha_o)
, NAMED(la_o)
, NAMED(hb_o)
, NAMED(lb_o)
, NAMED(hc_o)
, NAMED(lc_o)
, NAMED(s_gpio, 32)
, NAMED(h_bridge, 6)
, NAMED(i_fe310)
, NAMED(i_terminal)
, NAMED(i_adc)
{
i_core_complex.initiator(i_router.target[0]);
size_t i = 0;
for (const auto &e : e300_plat_map) {
i_router.initiator.at(i)(e.target->socket);
i_router.add_target_range(i, e.start, e.size);
i++;
i_fe310.erst_n(erst_n);
for (auto i = 0U; i < s_gpio.size(); ++i) {
s_gpio[i].in(i_fe310.pins_o[i]);
i_fe310.pins_i[i](s_gpio[i].out);
}
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);
// connect other units
// terminal
i_terminal.tx_o(s_gpio[16].in);
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
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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/plic.h>
#include <scc/utilities.h>
#include <scc/report.h>
#include <scc/utilities.h>
#include <sysc/SiFive/gen/plic_regs.h>
namespace sysc {
@ -49,13 +45,18 @@ plic::plic(sc_core::sc_module_name nm)
, NAMED(rst_i)
, NAMED(global_interrupts_i, 256)
, NAMED(core_interrupt_o)
, NAMEDD(plic_regs, regs)
, NAMEDD(regs, plic_regs)
{
regs->registerResources(*this);
// register callbacks
init_callbacks();
regs->claim_complete.set_write_cb(m_claim_complete_write_cb);
regs->claim_complete.set_write_cb([this](scc::sc_register<uint32_t> reg, uint32_t v, sc_core::sc_time d) -> 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;
});
// port callbacks
SC_METHOD(global_int_port_cb);
@ -72,21 +73,9 @@ plic::plic(sc_core::sc_module_name nm)
dont_initialize();
}
plic::~plic() {}
plic::~plic() {}// NOLINT
void plic::init_callbacks() {
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::clock_cb() { this->clk = clk_i.read(); }
void plic::reset_cb() {
if (rst_i.read())
@ -112,67 +101,67 @@ void plic::reset_cb() {
// - complete-reg write register content
void plic::global_int_port_cb() {
auto handle_pending = false;
// set related pending bit if enable is set for incoming global_interrupt
for (uint32_t i = 1; i < 256; i++) {
auto reg_idx = i>>5;
auto bit_ofs = i & 0x1F;
auto reg_idx = i >> 5;
auto bit_ofs = i & 0x1F;
bool enable = regs->r_enabled[reg_idx] & (0x1 << bit_ofs); // read enable bit
if (enable && global_interrupts_i[i].read() == 1) {
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() {
// identify high-prio pending interrupt and raise a core-interrupt
uint32_t claim_int = 0; // claim interrupt
uint32_t claim_prio = 0; // related priority (highest prio interrupt wins the race)
bool raise_int = 0;
uint32_t thold = regs->r_threshold.threshold; // threshold value
auto claim_int = 0U; // claim interrupt
auto claim_prio = 0U; // related priority (highest prio interrupt wins the race)
auto raise_int = false;
auto thold = regs->r_threshold.threshold; // threshold value
for (uint32_t i = 1; i < 255; i++) {
auto reg_idx = i>>5;
auto bit_ofs = i & 0x1F;
for (size_t i = 1; i < 255; i++) {
auto reg_idx = i >> 5;
auto bit_ofs = i & 0x1F;
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) {
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
// priority-interrupts
if (prio > claim_prio) {
claim_prio = prio;
claim_int = i;
raise_int = 1;
LOG(DEBUG) << "pending interrupt activated: " << i;
raise_int = true;
SCDEBUG(this->name()) << "pending interrupt activated: " << i;
}
}
}
if (raise_int) {
regs->r_claim_complete = claim_int;
core_interrupt_o.write(1);
core_interrupt_o.write(true);
// todo: evluate clock period
} else {
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) {
// todo: evaluate enable register (see 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
auto reg_idx = irq>>5;
auto bit_ofs = irq & 0x1F;
auto reg_idx = irq >> 5;
auto bit_ofs = irq & 0x1F;
regs->r_pending[reg_idx] &= ~(0x1 << bit_ofs);
core_interrupt_o.write(0);
core_interrupt_o.write(false);
// evaluate next pending interrupt
handle_pending_int();

View File

@ -1,38 +1,34 @@
////////////////////////////////////////////////////////////////////////////////
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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/prci.h"
@ -40,13 +36,14 @@
#include "sysc/SiFive/gen/prci_regs.h"
namespace sysc {
using namespace sc_core;
prci::prci(sc_core::sc_module_name nm)
: sc_core::sc_module(nm)
, tlm_target<>(hfclk)
, NAMED(rst_i)
, NAMED(hfclk_o)
, NAMEDD(prci_regs, regs) {
, NAMEDD(regs, prci_regs) {
regs->registerResources(*this);
SC_METHOD(reset_cb);
sensitive << rst_i;
@ -57,25 +54,25 @@ prci::prci(sc_core::sc_module_name nm)
sensitive << hfrosc_en_evt;
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);
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);
} else {
this->hfxosc_en_evt.notify(SC_ZERO_TIME);
}
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);
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);
} else {
this->hfrosc_en_evt.notify(SC_ZERO_TIME);
}
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);
auto &pllcfg = this->regs->r_pllcfg;
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();
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);
update_hfclk();
return true;
});
hfxosc_clk=62.5_ns;
hfxosc_clk = 62.5_ns;
}
prci::~prci() {}
prci::~prci() = default;
void prci::reset_cb() {
if (rst_i.read())
@ -104,41 +101,42 @@ void prci::reset_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);
}
void prci::hfxosc_en_cb() {
update_hfclk();
if(regs->r_hfxosccfg.hfxoscen==1)// set rosc_rdy
regs->r_hfxosccfg.hfxoscrdy =1;
if (regs->r_hfxosccfg.hfxoscen == 1) // set rosc_rdy
regs->r_hfxosccfg.hfxoscrdy = 1;
else
regs->r_hfxosccfg.hfxoscrdy =0;
regs->r_hfxosccfg.hfxoscrdy = 0;
}
void prci::hfrosc_en_cb() {
update_hfclk();
auto& hfrosccfg=regs->r_hfrosccfg;
if(regs->r_hfrosccfg.hfroscen==1) {// set rosc_rdy
regs->r_hfrosccfg.hfroscrdy =1;
auto &hfrosccfg = regs->r_hfrosccfg;
if (regs->r_hfrosccfg.hfroscen == 1) { // set rosc_rdy
regs->r_hfrosccfg.hfroscrdy = 1;
} else {
regs->r_hfrosccfg.hfroscrdy =0;
regs->r_hfrosccfg.hfroscrdy = 0;
}
}
void prci::update_hfclk() {
auto& hfrosccfg=regs->r_hfrosccfg;
auto& pllcfg=regs->r_pllcfg;
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);
auto pll_ref = pllcfg.pllrefsel==1?hfxosc_clk:hfrosc_clk;
auto r = pllcfg.pllr+1;
auto f = 2*(pllcfg.pllf+1);
auto q = 1<<pllcfg.pllq;
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;
auto &hfrosccfg = regs->r_hfrosccfg;
auto &pllcfg = regs->r_pllcfg;
auto &plldiv = regs->r_plloutdiv;
uint32_t trim = hfrosccfg.hfrosctrim;
uint32_t div = hfrosccfg.hfroscdiv;
hfrosc_clk = sc_core::sc_time(((div + 1) * 1.0) / (70000000 + 12000.0 * trim), sc_core::SC_SEC);
auto pll_ref = pllcfg.pllrefsel == 1 ? hfxosc_clk : hfrosc_clk;
auto r = pllcfg.pllr + 1;
auto f = 2 * (pllcfg.pllf + 1);
auto q = 1 << pllcfg.pllq;
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);
}

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
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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/sc_comm_singleton.h"
#include "seasocks/PrintfLogger.h"
#include "seasocks/ResponseWriter.h"
#include "seasocks/Server.h"
#include "seasocks/StringUtil.h"
#include "seasocks/util/Json.h"
#include "seasocks/ResponseWriter.h"
#include "seasocks/util/RootPageHandler.h"
#include "seasocks/util/CrackedUriPageHandler.h"
#include "seasocks/util/Json.h"
#include "seasocks/util/RootPageHandler.h"
#include "seasocks/util/StaticResponseHandler.h"
#include <cstdio>
#include <csignal>
#include <sys/stat.h>
#include <cerrno>
#include <csignal>
#include <cstdio>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
namespace sysc {
@ -58,127 +54,116 @@ using namespace seasocks;
using namespace std;
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_core::sc_module(nm)
, m_serv(new Server(std::make_shared<PrintfLogger>(Logger::Level::WARNING)))
, needs_client(false)
, client_started(false){
m_serv->addPageHandler(std::make_shared<DefaultPageHandler>(*this));
, client_started(false) {
m_serv->addPageHandler(std::make_shared<DefaultPageHandler>(*this));
}
sc_comm_singleton::~sc_comm_singleton() {
//Join the thread with the main thread
t.join();
// Join the thread with the main thread
t.join();
}
void sc_comm_singleton::start_of_simulation() {
//Launch a thread
t=std::thread(&sc_comm_singleton::thread_func, this);
if(needs_client) start_client();
// Launch a thread
t = std::thread(&sc_comm_singleton::thread_func, this);
if (needs_client) start_client();
}
void sc_comm_singleton::end_of_simulation() {
get_server().terminate();
}
void sc_comm_singleton::end_of_simulation() { get_server().terminate(); }
void sc_comm_singleton::start_client() {
if(client_started) return;
std::stringstream ss;
if (client_started) return;
std::stringstream ss;
#ifndef WIN32
if(fork()==0){
// 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.
pid_t pid = fork();
if (pid == -1) {
die();
} else if (pid != 0) {
_exit(0);
}
// Start a new session for the daemon.
if (setsid()==-1) die();
// Fork again, allowing the parent process to terminate.
signal(SIGHUP,SIG_IGN);
pid=fork();
if (pid == -1) {
die();
} else if (pid != 0) {
_exit(0);
}
// Set the current working directory to the root directory.
if (chdir("/") == -1) die();
// Set the user file creation mask to zero.
umask(0);
if (fork() == 0) {
// 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.
pid_t pid = fork();
if (pid == -1) {
die();
} else if (pid != 0) {
_exit(0);
}
// Start a new session for the daemon.
if (setsid() == -1) die();
// Fork again, allowing the parent process to terminate.
signal(SIGHUP, SIG_IGN);
pid = fork();
if (pid == -1) {
die();
} else if (pid != 0) {
_exit(0);
}
// Set the current working directory to the root directory.
if (chdir("/") == -1) die();
// Set the user file creation mask to zero.
umask(0);
// Close then reopen standard file descriptors.
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
if (open("/dev/null",O_RDONLY) == -1) die();
if (open("/dev/null",O_WRONLY) == -1) die();
if (open("/dev/null",O_RDWR) == -1) die();
// now do what is needed
ss<<"x-www-browser http://localhost:9090/ws.html"; //Linux
auto res = system (ss.str().c_str());
if(res==0) exit(0);
ss.str("");
ss<<"xdg-open http://localhost:9090/ws.html"; // Linux
res=system (ss.str().c_str());
if(res==0) exit(0);
ss.str("");
ss<<"open http://localhost:9090/ws.html"; // MacOS
res=system (ss.str().c_str());
exit(0);
}
// #else
// on windows should be open, see https://www.experts-exchange.com/articles/1595/Execute-a-Program-with-C.html
// Close then reopen standard file descriptors.
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
if (open("/dev/null", O_RDONLY) == -1) die();
if (open("/dev/null", O_WRONLY) == -1) die();
if (open("/dev/null", O_RDWR) == -1) die();
// now do what is needed
ss << "x-www-browser http://localhost:9090/ws.html"; // Linux
auto res = system(ss.str().c_str());
if (res == 0) exit(0);
ss.str("");
ss << "xdg-open http://localhost:9090/ws.html"; // Linux
res = system(ss.str().c_str());
if (res == 0) exit(0);
ss.str("");
ss << "open http://localhost:9090/ws.html"; // MacOS
res = system(ss.str().c_str());
exit(0);
}
// #else
// on windows should be open, see https://www.experts-exchange.com/articles/1595/Execute-a-Program-with-C.html
#endif
client_started=true;
client_started = true;
}
void sc_comm_singleton::registerWebSocketHandler(const char* endpoint,
std::shared_ptr<WebSocket::Handler> handler,
bool allowCrossOriginRequests) {
get_server().addWebSocketHandler(endpoint, handler, allowCrossOriginRequests);
endpoints.push_back(endpoint);
needs_client=true;
void sc_comm_singleton::registerWebSocketHandler(const char *endpoint, std::shared_ptr<WebSocket::Handler> handler,
bool allowCrossOriginRequests) {
get_server().addWebSocketHandler(endpoint, handler, allowCrossOriginRequests);
endpoints.emplace_back(endpoint);
needs_client = true;
}
void sc_comm_singleton::execute(std::function<void()> f) {
get_server().execute(f);
void sc_comm_singleton::execute(std::function<void()> 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() {
get_server().serve("./html", 9090);
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);
}
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 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);
}
void WsHandler::onDisconnect(WebSocket *connection) { _connections.erase(connection); }
} /* namespace sysc */

View File

@ -1,60 +1,93 @@
////////////////////////////////////////////////////////////////////////////////
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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/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 "sysc/SiFive/gen/spi_regs.h"
#include "sysc/tlm_extensions.h"
#include <util/ities.h>
namespace sysc {
namespace spi_impl {
using namespace sc_core;
spi::spi(sc_core::sc_module_name nm)
: sc_core::sc_module(nm)
class beh : public sysc::spi, public scc::tlm_target<> {
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)
, NAMED(clk_i)
, NAMED(rst_i)
, NAMED(sck_o)
, NAMED(mosi_o)
, NAMED(miso_i)
, NAMED(scs_o, 4)
, NAMED(irq_o)
, NAMED(_sck_o)
, NAMED(_mosi_o)
, NAMED(_miso_i)
, NAMED(_scs_o, 4)
, 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);
SC_METHOD(clock_cb);
sensitive << clk_i;
@ -62,158 +95,177 @@ spi::spi(sc_core::sc_module_name nm)
sensitive << rst_i;
dont_initialize();
SC_THREAD(transmit_data);
miso_i.register_nb_transport([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);
return tlm::TLM_COMPLETED;
});
regs->txdata.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool {
_miso_i.register_nb_transport(
[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);
return tlm::TLM_COMPLETED;
});
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()) {
reg.put(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;
});
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()) {
uint8_t val;
if(rx_fifo.nb_read(val)){
regs->r_rxdata.empty=0;
regs->r_rxdata.data=val;
if(regs->r_rxmark.rxmark<=rx_fifo.num_available()){
regs->r_ip.rxwm=1;
if (rx_fifo.nb_read(val)) {
regs->r_rxdata.empty = 0;
regs->r_rxdata.data = val;
if (regs->r_rxmark.rxmark <= rx_fifo.num_available()) {
regs->r_ip.rxwm = 1;
update_irq();
}
} else
regs->r_rxdata.empty=1;
data = reg.get()&reg.rdmask;
regs->r_rxdata.empty = 1;
data = reg.get() & reg.rdmask;
}
return true;
});
regs->csmode.set_write_cb([this](const scc::sc_register<uint32_t> &reg, uint32_t& data) -> bool {
if(regs->r_csmode.mode==2 && regs->r_csmode.mode != bit_sub<0, 2>(data) && regs->r_csid<4){
regs->csmode.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->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);
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);
_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) -> 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 {
regs->csdef.set_write_cb([this](const scc::sc_register<uint32_t> &reg, uint32_t &data, sc_core::sc_time d) -> bool {
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);
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);
_scs_o[regs->r_csid]->nb_transport_fw(gp, phase, delay);
}
reg.put(data);
return true;
});
regs->ie.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool {
update_irq();
regs->ie.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data, sc_core::sc_time d) -> bool {
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 {
update_irq();
regs->ip.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data, sc_core::sc_time d) -> bool {
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() {
this->clk = clk_i.read();
}
void beh::clock_cb() { this->clk = clk_i.read(); }
void spi::reset_cb() {
void beh::reset_cb() {
if (rst_i.read())
regs->reset_start();
else
regs->reset_stop();
}
void spi::transmit_data() {
void beh::transmit_data() {
uint8_t txdata;
sysc::tlm_signal_spi_extension ext;
tlm::tlm_phase phase(tlm::BEGIN_REQ);
tlm::tlm_signal_gp<> gp;
sc_core::sc_time delay(SC_ZERO_TIME);
sc_core::sc_time bit_duration(SC_ZERO_TIME);
sc_core::sc_time start_time;
gp.set_extension(&ext);
ext.tx.data_bits=8;
auto set_bit = [&](bool val, scc::tlm_signal_bool_opt_out& socket){
if(socket.get_interface()==nullptr) return;
gp.set_command(tlm::TLM_WRITE_COMMAND);
gp.set_value(val);
auto set_bit = [&](bool val, scc::tlm_signal_bool_opt_out &socket,
bool data_valid = false) -> std::pair<bool, uint32_t> {
if (socket.get_interface() == nullptr) return std::pair<bool, uint32_t>{false, 0};
auto *gp = tlm::tlm_signal_gp<>::create();
auto *ext = new sysc::tlm_signal_spi_extension();
ext->tx.data_bits = 8;
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);
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;
while(true){
wait(delay); // intentionally 0ns;
while (true) {
wait(tx_fifo.data_written_event());
if(regs->r_csmode.mode != 3 && regs->r_csid<4) // not in OFF mode
set_bit(false, scs_o[regs->r_csid]);
set_bit(regs->r_sckmode.pol, sck_o);
while(tx_fifo.nb_read(txdata)){
regs->r_txdata.full=tx_fifo.num_free()==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;
ext.start_time = sc_core::sc_time_stamp();
ext.tx.m2s_data=txdata;
ext.tx.s2m_data_valid=false;
set_bit(txdata&0x80, mosi_o); // 8 data bits, MSB first
set_bit(1-regs->r_sckmode.pol, sck_o);
wait(bit_duration/2);
set_bit(regs->r_sckmode.pol, sck_o);
wait(bit_duration/2);
if(bit_true_transfer.get_value()){
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(1-regs->r_sckmode.pol, sck_o);
wait(bit_duration/2);
set_bit(regs->r_sckmode.pol, sck_o);
wait(bit_duration/2);
if (regs->r_csmode.mode != 3 && regs->r_csid < 4) // not in OFF mode
set_bit(false, _scs_o[regs->r_csid]);
set_bit(regs->r_sckmode.pol, _sck_o);
while (tx_fifo.nb_read(txdata)) {
regs->r_txdata.full = tx_fifo.num_free() == 0;
regs->r_ip.txwm = regs->r_txmark.txmark <= (7 - tx_fifo.num_free()) ? 1 : 0;
update_irq_evt.notify();
bit_duration = 2 * (regs->r_sckdiv.div + 1) * clk;
start_time = sc_core::sc_time_stamp();
set_bit(txdata & 0x80, _mosi_o); // 8 data bits, MSB first
auto s2m = set_bit(1 - regs->r_sckmode.pol, _sck_o, true);
wait(bit_duration / 2);
set_bit(regs->r_sckmode.pol, _sck_o, true);
wait(bit_duration / 2);
if (bit_true_transfer.get_value()) {
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(1 - regs->r_sckmode.pol, _sck_o);
wait(bit_duration / 2);
set_bit(regs->r_sckmode.pol, _sck_o);
wait(bit_duration / 2);
}
} else
wait(7*bit_duration);
rx_fifo.nb_write(ext.tx.s2m_data&0xff);
if(regs->r_rxmark.rxmark<=rx_fifo.num_available()){
regs->r_ip.rxwm=1;
update_irq();
}
wait(7 * bit_duration);
if (s2m.first) rx_fifo.nb_write(s2m.second & 0xff);
update_irq_evt.notify();
}
if(regs->r_csmode.mode == 0 && regs->r_csid<4) // in AUTO mode
set_bit(false, scs_o[regs->r_csid]);
if (regs->r_csmode.mode == 0 && regs->r_csid < 4) // in AUTO mode
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 */

View File

@ -1,88 +1,115 @@
/*
* system.cpp
/*******************************************************************************
* Copyright (C) 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Created on: 11.07.2018
* Author: eyck
*/
* 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/top/system.h"
using namespace sysc;
using namespace sc_core;
system::system(sc_core::sc_module_name nm)
system::system(sc_module_name 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_vref)
, NAMED(s_va)
, NAMED(s_vb)
, NAMED(s_vc)
, NAMED(s_ana, 5)
, NAMED(i_platform)
, NAMED(i_terminal)
, NAMED(i_adc)
, NAMED(s_vasens)
, NAMED(s_vbsens)
, NAMED(s_vcsens)
, NAMED(s_vcentersens)
, NAMED(s_ana, 4)
, NAMED(i_hifive1)
, NAMED(i_h_bridge)
, NAMED(i_motor)
{
, NAMED(i_motor) {
// connect platform
i_platform.erst_n(s_rst_n);
for(auto i=0U; i<s_gpio.size(); ++i){
s_gpio[i].in(i_platform.pins_o[i]);
i_platform.pins_i[i](s_gpio[i].out);
}
// connect other units
// terminal
i_terminal.tx_o(s_gpio[16].in);
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(s_vref);
i_adc.ch_i[0](s_vasens);
i_adc.ch_i[1](s_vbsens);
i_adc.ch_i[2](s_vcsens);
i_adc.ch_i[3](s_ana[0]);
i_adc.ch_i[4](s_ana[1]);
i_adc.ch_i[5](s_ana[2]);
i_adc.ch_i[6](s_ana[3]);
i_adc.ch_i[7](s_ana[4]);
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_hifive1.erst_n(s_rst_n);
// HiFive1 digital out
i_hifive1.ha_o(s_ha);
i_hifive1.la_o(s_la);
i_hifive1.hb_o(s_hb);
i_hifive1.lb_o(s_lb);
i_hifive1.hc_o(s_hc);
i_hifive1.lc_o(s_lc);
// HiFive1 analog in
i_hifive1.vref_i(s_vref);
i_hifive1.adc_ch0_i(s_vasens);
i_hifive1.adc_ch1_i(s_vbsens);
i_hifive1.adc_ch2_i(s_vcsens);
i_hifive1.adc_ch3_i(s_vcentersens);
i_hifive1.adc_ch4_i(s_ana[0]);
i_hifive1.adc_ch5_i(s_ana[1]);
i_hifive1.adc_ch6_i(s_ana[2]);
i_hifive1.adc_ch7_i(s_ana[3]);
// H-bridge digital in
i_h_bridge.ha_i(s_ha);
i_h_bridge.la_i(s_la);
i_h_bridge.hb_i(s_hb);
i_h_bridge.lb_i(s_lb);
i_h_bridge.hc_i(s_hc);
i_h_bridge.lc_i(s_lc);
// H-bridge analog out
i_h_bridge.va_o(s_va);
i_h_bridge.vb_o(s_vb);
i_h_bridge.vc_o(s_vc);
// motor analog in
i_motor.va_i(s_va);
i_motor.vb_i(s_vb);
i_motor.vc_i(s_vc);
// motor analog out
i_motor.va_o(s_vasens);
i_motor.vb_o(s_vbsens);
i_motor.vc_o(s_vcsens);
i_motor.vcenter_o(s_vcentersens);
SC_THREAD(gen_por);
}
system::~system() {
}
system::~system() = default;
void sysc::system::gen_por() {
// single shot
s_rst_n = false;
wait(10_ns);
wait(1_us);
s_rst_n = true;
s_vref=1.024;
double val=0.1;
for(auto& sig:s_ana){
sig=val;
val+=0.12;
s_vref = 4.8;
double val = 0.1;
for (auto &sig : s_ana) {
sig = val;
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
* Author: eyck
*/
* 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/top/terminal.h"
#include "scc/report.h"
#include "sysc/sc_comm_singleton.h"
#include "sysc/tlm_extensions.h"
#include "scc/report.h"
using namespace sysc;
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)
, NAMED(tx_o)
, NAMED(rx_i)
, NAMED(write_to_ws, false)
{
rx_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{
, NAMED(write_to_ws, false) {
rx_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 {
this->receive(gp, delay);
return tlm::TLM_COMPLETED;
});
}
terminal::~terminal() {
}
terminal::~terminal() = default;
void terminal::before_end_of_elaboration() {
if(write_to_ws.get_value()) {
LOG(TRACE)<<"Adding WS handler for "<<(std::string{"/ws/"}+name());
handler=std::make_shared<WsHandler>();
sc_comm_singleton::inst().registerWebSocketHandler((std::string{"/ws/"}+name()).c_str(), handler);
if (write_to_ws.get_value()) {
SCTRACE() << "Adding WS handler for " << (std::string{"/ws/"} + name());
handler = std::make_shared<WsHandler>();
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) {
sysc::tlm_signal_uart_extension* ext;
void terminal::receive(tlm::tlm_signal_gp<sc_dt::sc_logic> &gp, sc_core::sc_time &delay) {
sysc::tlm_signal_uart_extension *ext;
gp.get_extension(ext);
if(ext && ext->start_time!=last_tx_start){
uint8_t txdata = static_cast<uint8_t>(ext->tx.data);
if (ext && ext->start_time != last_tx_start) {
auto txdata = static_cast<uint8_t>(ext->tx.data);
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)) {
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();
if(handler)
sysc::sc_comm_singleton::inst().execute([this, msg, now](){
if (handler)
sysc::sc_comm_singleton::inst().execute([this, msg, now]() {
std::stringstream os;
os << "{\"time\":\"" << now << "\",\"message\":\""<<msg<<"\"}";
os << R"({"time":")" << now << R"(","message":")" << msg << R"("})";
this->handler->send(os.str());
});
else
LOG(INFO) << this->name() << " receive: '" << msg << "'";
SCINFO(this->name()) << " receive: '" << msg << "'";
queue.clear();
}
}

View File

@ -1,50 +1,46 @@
////////////////////////////////////////////////////////////////////////////////
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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/uart.h"
#include "sysc/tlm_extensions.h"
#include "scc/report.h"
#include "scc/utilities.h"
#include "sysc/SiFive/gen/uart_regs.h"
#include "sysc/tlm_extensions.h"
using namespace std;
namespace sysc {
using namespace sc_core;
uart::uart(sc_core::sc_module_name nm)
: sc_core::sc_module(nm)
@ -55,10 +51,9 @@ uart::uart(sc_core::sc_module_name nm)
, NAMED(rx_i)
, NAMED(irq_o)
, NAMED(bit_true_transfer, false)
, NAMEDD(uart_regs, regs)
, NAMEDD(regs, uart_regs)
, NAMED(rx_fifo, 8)
, NAMED(tx_fifo, 8)
{
, NAMED(tx_fifo, 8) {
regs->registerResources(*this);
SC_METHOD(clock_cb);
sensitive << clk_i;
@ -66,52 +61,52 @@ uart::uart(sc_core::sc_module_name nm)
sensitive << rst_i;
dont_initialize();
SC_THREAD(transmit_data);
rx_i.register_nb_transport([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);
return tlm::TLM_COMPLETED;
});
regs->txdata.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool {
rx_i.register_nb_transport(
[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);
return tlm::TLM_COMPLETED;
});
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()) {
reg.put(data);
tx_fifo.nb_write(static_cast<uint8_t>(regs->r_txdata.data));
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_txdata.full = tx_fifo.num_free() == 0;
regs->r_ip.txwm = regs->r_txctrl.txcnt <= (7 - tx_fifo.num_free()) ? 1 : 0;
update_irq();
}
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()) {
uint8_t val;
if(rx_fifo.nb_read(val)){
regs->r_rxdata.data=val;
if(regs->r_rxctrl.rxcnt<=rx_fifo.num_available()){
regs->r_ip.rxwm=1;
if (rx_fifo.nb_read(val)) {
regs->r_rxdata.data = val;
if (regs->r_rxctrl.rxcnt <= rx_fifo.num_available()) {
regs->r_ip.rxwm = 1;
update_irq();
}
}
data = reg.get()&reg.rdmask;
data = reg.get() & reg.rdmask;
}
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();
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();
return true;
});
}
uart::~uart() {}
uart::~uart() = default;
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() {
this->clk = clk_i.read();
}
void uart::clock_cb() { this->clk = clk_i.read(); }
void uart::reset_cb() {
if (rst_i.read())
@ -122,62 +117,64 @@ void uart::reset_cb() {
void uart::transmit_data() {
uint8_t txdata;
sysc::tlm_signal_uart_extension ext;
tlm::tlm_phase phase(tlm::BEGIN_REQ);
tlm::tlm_signal_gp<> gp;
sc_core::sc_time delay(SC_ZERO_TIME);
sc_core::sc_time bit_duration(SC_ZERO_TIME);
sc_core::sc_time start_time;
gp.set_extension(&ext);
ext.tx.data_bits=8;
ext.tx.parity=false;
auto set_bit = [&](bool val){
gp.set_command(tlm::TLM_WRITE_COMMAND);
gp.set_value(val);
tlm::tlm_phase phase(tlm::BEGIN_REQ);
tx_o->nb_transport_fw(gp, phase, delay);
if(delay<bit_duration) wait(bit_duration-delay);
auto set_bit = [&](bool val) {
auto *gp = tlm::tlm_signal_gp<>::create();
auto *ext = new sysc::tlm_signal_uart_extension();
ext->tx.data_bits = 8;
ext->tx.parity = false;
ext->start_time = start_time;
ext->tx.baud_rate = static_cast<unsigned>(1 / bit_duration.to_seconds());
ext->tx.stop_bits = 1 + regs->r_txctrl.nstop;
ext->tx.data = txdata;
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);
while(true){
while (true) {
set_bit(true);
wait(tx_fifo.data_written_event());
while(tx_fifo.nb_read(txdata)){
regs->r_txdata.full=tx_fifo.num_free()==0;
regs->r_ip.txwm=regs->r_txctrl.txcnt<=(7-tx_fifo.num_free())?1:0;
bit_duration = (regs->r_div.div+1)*clk;
ext.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;
while (tx_fifo.nb_read(txdata)) {
regs->r_txdata.full = tx_fifo.num_free() == 0;
regs->r_ip.txwm = regs->r_txctrl.txcnt <= (7 - tx_fifo.num_free()) ? 1 : 0;
bit_duration = (regs->r_div.div + 1) * clk;
start_time = sc_core::sc_time_stamp();
set_bit(false); // start bit
if(bit_true_transfer.get_value()){
for(int i = 8; i>0; --i)
set_bit(txdata&(1<<(i-1))); // 8 data bits, MSB first
if(regs->r_txctrl.nstop) set_bit(true); // stop bit 1
if (bit_true_transfer.get_value()) {
for (int i = 8; i > 0; --i) set_bit(txdata & (1 << (i - 1))); // 8 data bits, MSB first
if (regs->r_txctrl.nstop) set_bit(true); // stop bit 1
} else
wait(8*bit_duration);
wait(8 * bit_duration);
set_bit(true); // stop bit 1/2
}
}
}
void uart::receive_data(tlm::tlm_signal_gp<>& gp, sc_core::sc_time& delay) {
sysc::tlm_signal_uart_extension* ext{nullptr};
void uart::receive_data(tlm::tlm_signal_gp<> &gp, sc_core::sc_time &delay) {
sysc::tlm_signal_uart_extension *ext{nullptr};
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);
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);
if(regs->r_rxctrl.rxcnt<=rx_fifo.num_available()){
regs->r_ip.rxwm=1;
if (regs->r_rxctrl.rxcnt <= rx_fifo.num_available()) {
regs->r_ip.rxwm = 1;
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);
}
} /* namespace sysc */

View File

@ -1,6 +1,5 @@
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) # project specific cmake dir
# CMake useful variables
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
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)
## 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})
# check that we have averything we need
if(!SystemC_FOUND)
message( FATAL_ERROR "SystemC library not found." )
endif()
# 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)
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()
if(!CCI_FOUND)
message( FATAL_ERROR "SystemC CCI library not found." )
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)
add_definitions(-DWITH_SCV)
include_directories(${SCV_INCLUDE_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.
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_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
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.
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
add_library(${LIBRARY_NAME} ${LIB_SOURCES})

View File

@ -1,55 +1,51 @@
////////////////////////////////////////////////////////////////////////////////
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 _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/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_stream;
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 {
class vm_if;
@ -78,7 +74,7 @@ class core_wrapper;
class core_complex : public sc_core::sc_module, public scc::traceable {
public:
SC_HAS_PROCESS(core_complex);
SC_HAS_PROCESS(core_complex);// NOLINT
scc::initiator_mixin<scv4tlm::tlm_rec_initiator_socket<32>> initiator;
@ -109,13 +105,13 @@ public:
~core_complex();
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);
if (quantum_keeper.need_sync()) {
wait(quantum_keeper.get_local_time());
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);
@ -126,9 +122,10 @@ public:
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);
protected:
void before_end_of_elaboration();
void start_of_simulation();
@ -145,18 +142,17 @@ protected:
std::unique_ptr<core_wrapper> cpu;
std::unique_ptr<iss::vm_if> vm;
sc_core::sc_time curr_clk;
iss::debugger::target_adapter_if* tgt_adapter;
iss::debugger::target_adapter_if *tgt_adapter;
#ifdef WITH_SCV
//! transaction recording database
scv_tr_db *m_db;
//! blocking transaction recording stream handle
scv_tr_stream *stream_handle;
//! 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<uint64_t,_scv_tr_generator_default_data> *fetch_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_handle tr_handle;
#endif
};
} /* namespace SiFive */

View File

@ -1,70 +1,67 @@
////////////////////////////////////////////////////////////////////////////////
// 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
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 "scc/report.h"
#include "sysc/core_complex.h"
#include "iss/arch/riscv_hart_msu_vp.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/vm_types.h"
#include "iss/debugger/server.h"
#include "iss/debugger/gdb_session.h"
#include "iss/debugger/target_adapter_if.h"
#include "iss/debugger/encoderdecoder.h"
#include "sysc/core_complex.h"
#include "scc/report.h"
#include <sstream>
#include <iostream>
#ifdef WITH_SCV
#include <scv.h>
#include <array>
#include <scv.h>
#endif
namespace sysc {
namespace SiFive {
using namespace std;
using namespace iss;
using namespace logging;
using namespace sc_core;
namespace {
iss::debugger::encoder_decoder encdec;
}
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 = { {
"Instruction address misaligned",
@ -96,121 +93,126 @@ public:
using base_type = arch::riscv_hart_msu_vp<arch::rv32imac>;
using phys_addr_t = typename arch::traits<arch::rv32imac>::phys_addr_t;
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
void set_interrupt_execution(bool v){ this->interrupt_sim=v;}
inline void set_interrupt_execution(bool v) { this->interrupt_sim = v; }
inline
bool get_interrupt_execution(){ return this->interrupt_sim;}
inline 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 {
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; }
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()){
std::stringstream s;
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 << "]";
scc::Log<logging::Output2FILE<logging::disass>>().get(logging::INFO, "disass")
<< "0x"<<std::setw(16)<<std::setfill('0')<<std::hex<<pc<<"\t\t"<<std::setw(40)<<std::setfill(' ')<<std::left<<instr<<s.str();
}
owner->disass_output(pc,instr);
if (INFO <= Log<Output2FILE<disass>>::reporting_level() && Output2FILE<disass>::stream()) {
std::stringstream s;
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 << "]";
Log<Output2FILE<disass>>().get(INFO, "disass")
<< "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);
};
status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data) {
if (addr.access && access_type::DEBUG)
return owner->read_mem_dbg(addr.val, length, data) ? Ok : Err;
else {
return owner->read_mem(addr.val, length, data,addr.access && access_type::FETCH) ? Ok : Err;
}
status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data) override {
if (addr.access && access_type::DEBUG)
return owner->read_mem_dbg(addr.val, length, data) ? Ok : Err;
else {
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) {
if (addr.access && access_type::DEBUG)
return owner->write_mem_dbg(addr.val, length, data) ? Ok : Err;
else{
auto res = owner->write_mem(addr.val, length, data) ? Ok : Err;
// clear MTIP on mtimecmp write
if(addr.val==0x2004000){
reg_t val;
this->read_csr(arch::mip, val);
this->write_csr(arch::mip, val & ~(1ULL<<7));
}
return res;
}
status write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data) override {
if (addr.access && access_type::DEBUG)
return owner->write_mem_dbg(addr.val, length, data) ? Ok : Err;
else {
auto res = owner->write_mem(addr.val, length, data) ? Ok : Err;
// clear MTIP on mtimecmp write
if (addr.val == 0x2004000) {
reg_t val;
this->read_csr(arch::mip, val);
if (val & (1ULL << 7)) this->write_csr(arch::mip, val & ~(1ULL << 7));
}
return res;
}
}
void wait_until(uint64_t flags) {
do{
wait(wfi_evt);
this->check_interrupt();
} while(this->reg.pending_trap==0);
base_type::wait_until(flags);
void wait_until(uint64_t flags) override {
SCDEBUG(owner->name()) << "Sleeping until interrupt";
do {
wait(wfi_evt);
} while (this->reg.pending_trap == 0);
base_type::wait_until(flags);
}
void local_irq(short id){
switch(id){
case 16: // SW
this->csr[arch::mip] |= 1<<3;
break;
case 17: // timer
this->csr[arch::mip] |= 1<<7;
break;
case 18: //external
this->csr[arch::mip] |= 1<<11;
break;
default:
/* do nothing*/
break;
}
wfi_evt.notify();
void local_irq(short id, bool value) {
base_type::reg_t mask = 0;
switch (id) {
case 16: // SW
mask = 1 << 3;
break;
case 17: // timer
mask = 1 << 7;
break;
case 18: // external
mask = 1 << 11;
break;
default:
/* do nothing*/
break;
}
if (value) {
this->csr[arch::mip] |= mask;
wfi_evt.notify();
} else
this->csr[arch::mip] &= ~mask;
this->check_interrupt();
}
private:
core_complex *const owner;
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){
if(argc>1) {
if(strcasecmp(argv[1], "print_time")==0){
std::string t = sc_core::sc_time_stamp().to_string();
int cmd_sysc(int argc, char *argv[], debugger::out_func of, debugger::data_func df,
debugger::target_adapter_if *tgt_adapter) {
if (argc > 1) {
if (strcasecmp(argv[1], "print_time") == 0) {
std::string t = sc_time_stamp().to_string();
of(t.c_str());
std::array<char, 64> buf;
encdec.enc_string(t.c_str(), buf.data(), 63);
df(buf.data());
std::array<char, 64> buf;
encdec.enc_string(t.c_str(), buf.data(), 63);
df(buf.data());
return Ok;
} else if(strcasecmp(argv[1], "break")==0){
sc_core::sc_time t;
if(argc==4){
t= scc::parse_from_string(argv[2], argv[3]);
} else if(argc==3){
t= scc::parse_from_string(argv[2]);
} else if (strcasecmp(argv[1], "break") == 0) {
sc_time t;
if (argc == 4) {
t = scc::parse_from_string(argv[2], argv[3]);
} else if (argc == 3) {
t = scc::parse_from_string(argv[2]);
} else
return Err;
// no check needed as it is only called if debug server is active
tgt_adapter->add_break_condition([t]()->unsigned{
LOG(TRACE)<<"Checking condition at "<<sc_core::sc_time_stamp();
return sc_core::sc_time_stamp()>=t?std::numeric_limits<unsigned>::max():0;
tgt_adapter->add_break_condition([t]() -> unsigned {
SCTRACE() << "Checking condition at " << sc_time_stamp();
return sc_time_stamp() >= t ? std::numeric_limits<unsigned>::max() : 0;
});
return Ok;
}
return Err;
}
return Err;
}
core_complex::core_complex(sc_core::sc_module_name name)
: sc_core::sc_module(name)
core_complex::core_complex(sc_module_name name)
: sc_module(name)
, NAMED(initiator)
, NAMED(clk_i)
, NAMED(rst_i)
@ -250,100 +252,96 @@ core_complex::core_complex(sc_core::sc_module_name name)
SC_METHOD(rst_cb);
sensitive << rst_i;
SC_METHOD(sw_irq_cb);
sensitive<<sw_irq_i;
sensitive << sw_irq_i;
SC_METHOD(timer_irq_cb);
sensitive<<timer_irq_i;
sensitive << timer_irq_i;
SC_METHOD(global_irq_cb);
sensitive<<global_irq_i;
sensitive << global_irq_i;
}
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() {
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());
#ifdef WITH_SCV
vm->setDisassEnabled(enable_disass.get_value() || m_db!=nullptr);
vm->setDisassEnabled(enable_disass.get_value() || m_db != nullptr);
#else
vm->setDisassEnabled(enable_disass.get_value());
#endif
auto* srv = debugger::server<debugger::gdb_session>::get();
if(srv) tgt_adapter = srv->get_target();
if(tgt_adapter)
tgt_adapter->add_custom_command({
"sysc",
[this](int argc, char* argv[], debugger::out_func of, debugger::data_func df)-> int {
return cmd_sysc(argc, argv, of, df, tgt_adapter);
},
"SystemC sub-commands: break <time>, print_time"});
auto *srv = debugger::server<debugger::gdb_session>::get();
if (srv) tgt_adapter = srv->get_target();
if (tgt_adapter)
tgt_adapter->add_custom_command(
{"sysc", [this](int argc, char *argv[], debugger::out_func of,
debugger::data_func df) -> int { return cmd_sysc(argc, argv, of, df, tgt_adapter); },
"SystemC sub-commands: break <time>, print_time"});
}
void core_complex::start_of_simulation() {
quantum_keeper.reset();
if (elf_file.get_value().size() > 0){
std::pair<uint64_t,bool> start_addr=cpu->load_file(elf_file.get_value());
if(reset_address.is_default_value() && start_addr.second==true) reset_address.set_value(start_addr.first);
if (elf_file.get_value().size() > 0) {
istringstream is(elf_file.get_value());
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
if (m_db!=nullptr && stream_handle == nullptr) {
string basename(this->name());
stream_handle = new scv_tr_stream((basename + ".instr").c_str(), "TRANSACTOR", m_db);
instr_tr_handle = new scv_tr_generator<>("execute", *stream_handle);
fetch_tr_handle = new scv_tr_generator<uint64_t>("fetch", *stream_handle);
}
if (m_db != nullptr && stream_handle == nullptr) {
string basename(this->name());
stream_handle = new scv_tr_stream((basename + ".instr").c_str(), "TRANSACTOR", m_db);
instr_tr_handle = new scv_tr_generator<>("execute", *stream_handle);
fetch_tr_handle = new scv_tr_generator<uint64_t>("fetch", *stream_handle);
}
#endif
}
void core_complex::disass_output(uint64_t pc, const std::string instr_str) {
#ifdef WITH_SCV
if (m_db==nullptr) return;
if(tr_handle.is_active()) tr_handle.end_transaction();
if (m_db == nullptr) return;
if (tr_handle.is_active()) tr_handle.end_transaction();
tr_handle = instr_tr_handle->begin_transaction();
tr_handle.record_attribute("PC", pc);
tr_handle.record_attribute("INSTR", instr_str);
tr_handle.record_attribute("MODE", lvl[cpu->get_mode()]);
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
}
void core_complex::clk_cb() {
curr_clk = clk_i.read();
if(curr_clk==SC_ZERO_TIME) cpu->set_interrupt_execution(true);
curr_clk = clk_i.read();
if (curr_clk == SC_ZERO_TIME) cpu->set_interrupt_execution(true);
}
void core_complex::rst_cb() {
if(rst_i.read())
cpu->set_interrupt_execution(true);
if (rst_i.read()) cpu->set_interrupt_execution(true);
}
void core_complex::sw_irq_cb(){
if(sw_irq_i.read()) cpu->local_irq(16);
}
void core_complex::sw_irq_cb() { cpu->local_irq(16, sw_irq_i.read()); }
void core_complex::timer_irq_cb(){
if(timer_irq_i.read()) cpu->local_irq(17);
}
void core_complex::timer_irq_cb() { cpu->local_irq(17, timer_irq_i.read()); }
void core_complex::global_irq_cb(){
if(timer_irq_i.read()) cpu->local_irq(18);
}
void core_complex::global_irq_cb() { cpu->local_irq(18, global_irq_i.read()); }
void core_complex::run() {
wait(SC_ZERO_TIME); // separate from elaboration phase
do{
if(rst_i.read()){
do {
if (rst_i.read()) {
cpu->reset(reset_address.get_value());
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());
}
cpu->set_interrupt_execution(false);
vm->start();
} while(cpu->get_interrupt_execution());
} while (cpu->get_interrupt_execution());
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_length(length);
gp.set_streaming_width(length);
auto delay{quantum_keeper.get_local_time()};
sc_time delay{quantum_keeper.get_local_time()};
#ifdef WITH_SCV
if(m_db!=nullptr && tr_handle.is_valid()){
if(is_fetch && tr_handle.is_active()){
if (m_db != nullptr && tr_handle.is_valid()) {
if (is_fetch && tr_handle.is_active()) {
tr_handle.end_transaction();
}
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
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) {
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_length(length);
gp.set_streaming_width(length);
auto delay{quantum_keeper.get_local_time()};
sc_time delay{quantum_keeper.get_local_time()};
#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);
gp.set_extension(preExt);
}
#endif
initiator->b_transport(gp, 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) {
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
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)
## 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()
# 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.
include_directories(
${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);
}
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%";
if(rd != 0) X[rd] <= X[rs1] ^ imm;
if(rd != 0) X[rd] <= X[rs1]s ^ imm;
}
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%";
if(rd != 0) X[rd] <= X[rs1] | imm;
if(rd != 0) X[rd] <= X[rs1]s | imm;
}
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%";
if(rd != 0) X[rd] <= X[rs1] & imm;
if(rd != 0) X[rd] <= X[rs1]s & imm;
}
SLLI {
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
// 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 API and implementation
//
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 <iss/arch/CORE_DEF_NAME.h>
#include <iss/arch/riscv_hart_msu_vp.h>
@ -44,8 +40,8 @@
#include <boost/format.hpp>
#include <iss/debugger/riscv_target_adapter.h>
#include <array>
#include <iss/debugger/riscv_target_adapter.h>
namespace iss {
namespace CORE_DEF_NAME {
@ -101,14 +97,13 @@ protected:
void gen_trap_check(llvm::BasicBlock *bb);
inline llvm::Value *gen_reg_load(unsigned i, unsigned level = 0) {
return this->builder.CreateLoad(get_reg_ptr(i), false);
}
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),
this->get_type(traits<ARCH>::XLEN));
this->get_type(traits<ARCH>::XLEN));
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> 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[],
compile_func f) {
@ -180,23 +175,23 @@ private:
};
/* «start generated code» */
std::array<InstructionDesriptor, 0> instr_descr = { { } };
std::array<InstructionDesriptor, 0> instr_descr = {{}};
/* «end generated code» */
/****************************************************************************
* end opcode definitions
****************************************************************************/
std::tuple<vm::continuation_e, llvm::BasicBlock *> illegal_intruction(virt_addr_t &pc, code_word_t instr,
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),
get_reg_ptr(traits<ARCH>::PC), true);
get_reg_ptr(traits<ARCH>::PC), true);
this->builder.CreateStore(
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);
pc = pc + ((instr & 3) == 3 ? 4 : 2);
this->gen_raise_trap(0, 2); // illegal instruction trap
this->gen_sync(iss::POST_SYNC, instr_descr.size());
this->gen_raise_trap(0, 2); // illegal instruction trap
this->gen_sync(iss::POST_SYNC, instr_descr.size());
this->gen_trap_check(this->leave_blk);
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) {
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
typename vm_impl<ARCH>::processing_pc_entry addr(*this, pc, paddr);
++inst_cnt;

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (C) 2017, MINRES Technologies GmbH
* Copyright (C) 2017, 2018, MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -37,21 +37,26 @@
#include "iss/arch/traits.h"
#include "iss/arch_if.h"
#include "iss/instrumentation_if.h"
#include "iss/log_categories.h"
#include "iss/vm_if.h"
#include "iss/instrumentation_if.h"
#include <array>
#include <elfio/elfio.hpp>
#include <iomanip>
#include <sstream>
#include <type_traits>
#include <unordered_map>
#include <util/bit_field.h>
#include <util/ities.h>
#include <util/sparse_array.h>
#include <util/bit_field.h>
#include <array>
#include <type_traits>
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#if defined(__GNUC__)
#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 arch {
@ -165,29 +170,29 @@ enum riscv_csr {
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 = { { ""
"Instruction address misaligned", //0
"Instruction access fault", //1
"Illegal instruction", //2
"Breakpoint", //3
"Load address misaligned", //4
"Load access fault", //5
"Store/AMO address misaligned", //6
"Store/AMO access fault", //7
"Environment call from U-mode", //8
"Environment call from S-mode", //9
"Reserved", //a
"Environment call from M-mode", //b
"Instruction page fault", //c
"Load page fault", //d
"Reserved", //e
"Store/AMO page fault" } };
std::array<const char*, 12> irq_str = { {
"User software interrupt", "Supervisor software interrupt", "Reserved", "Machine software interrupt",
"User timer interrupt", "Supervisor timer interrupt", "Reserved", "Machine timer interrupt", "User external interrupt",
"Supervisor external interrupt", "Reserved", "Machine external interrupt" } };
std::array<const char *, 16> trap_str = {{""
"Instruction address misaligned", // 0
"Instruction access fault", // 1
"Illegal instruction", // 2
"Breakpoint", // 3
"Load address misaligned", // 4
"Load access fault", // 5
"Store/AMO address misaligned", // 6
"Store/AMO access fault", // 7
"Environment call from U-mode", // 8
"Environment call from S-mode", // 9
"Reserved", // a
"Environment call from M-mode", // b
"Instruction page fault", // c
"Load page fault", // d
"Reserved", // e
"Store/AMO page fault"}};
std::array<const char *, 12> irq_str = {
{"User software interrupt", "Supervisor software interrupt", "Reserved", "Machine software interrupt",
"User timer interrupt", "Supervisor timer interrupt", "Reserved", "Machine timer interrupt",
"User external interrupt", "Supervisor external interrupt", "Reserved", "Machine external interrupt"}};
enum {
PGSHIFT = 12,
@ -229,7 +234,7 @@ struct vm_info {
int idxbits;
int ptesize;
uint64_t ptbase;
bool is_active() { return levels;}
bool is_active() { return levels; }
};
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);
// primary template
template<class T, class Enable = void> struct hart_state { };
template <class T, class Enable = void> struct hart_state {};
// specialization 32bit
template <typename T>
class hart_state<T, typename std::enable_if<std::is_same<T, uint32_t>::value>::type> {
template <typename T> class hart_state<T, typename std::enable_if<std::is_same<T, uint32_t>::value>::type> {
public:
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)))
@ -318,10 +322,10 @@ public:
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 new_val = (mstatus.st.value & ~mask) | (val & mask);
mstatus=new_val;
mstatus = new_val;
}
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 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) {
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
default: return 0x807ff9ddUL; // 0b1000 0000 0111 1111 1111 1001 1011 1011
}
#endif
}
static inline vm_info decode_vm_info(uint32_t state, T sptbr) {
@ -349,8 +357,7 @@ public:
}
};
// specialization 64bit
template <typename T>
class hart_state<T, typename std::enable_if<std::is_same<T, uint64_t>::value>::type> {
template <typename T> class hart_state<T, typename std::enable_if<std::is_same<T, uint64_t>::value>::type> {
public:
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)))
@ -397,17 +404,17 @@ public:
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;
auto mask = get_mask(priv_lvl);
auto new_val = (old_val & ~mask) | (val & mask);
if((new_val&mstatus.SXL.Mask)==0){
new_val |= old_val&mstatus.SXL.Mask;
if ((new_val & mstatus.SXL.Mask) == 0) {
new_val |= old_val & mstatus.SXL.Mask;
}
if((new_val&mstatus.UXL.Mask)==0){
new_val |= old_val&mstatus.UXL.Mask;
if ((new_val & mstatus.UXL.Mask) == 0) {
new_val |= old_val & mstatus.UXL.Mask;
}
mstatus=new_val;
mstatus = new_val;
}
T satp;
@ -426,9 +433,9 @@ public:
if (state == PRIV_M) return {0, 0, 0, 0};
if (state <= PRIV_S)
switch (bit_sub<60, 4>(sptbr)) {
case 0: return {0, 0, 0, 0}; // off
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 0: return {0, 0, 0, 0}; // off
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 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
default: abort();
@ -442,12 +449,12 @@ public:
const typename super::reg_t PGMASK = PGSIZE - 1;
constexpr reg_t get_irq_mask(size_t mode) {
std::array<const reg_t,4> m = { {
0b000100010001,// U mode
0b001100110011,// S mode
0,
0b101110111011 // M mode
}};
std::array<const reg_t, 4> m = {{
0b000100010001, // U mode
0b001100110011, // S mode
0,
0b101110111011 // M mode
}};
return m[mode];
}
@ -456,7 +463,7 @@ public:
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;
@ -468,40 +475,39 @@ public:
virtual uint64_t leave_trap(uint64_t flags) override;
void wait_until(uint64_t flags) override;
void disass_output(uint64_t pc, const std::string instr) override {
std::stringstream s;
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 << "]";
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:
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
*
* @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;
addr_t get_pc(){return this->reg.PC;}
addr_t get_next_pc(){return this->reg.NEXT_PC;}
addr_t get_pc() { return this->reg.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 write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data);
@ -512,7 +518,7 @@ protected:
hart_state<reg_t> state;
uint64_t cycle_offset;
reg_t fault_data;
std::array<vm_info,2> vm;
std::array<vm_info, 2> vm;
uint64_t tohost = tohost_dflt;
uint64_t fromhost = fromhost_dflt;
unsigned to_host_wr_cnt = 0;
@ -541,15 +547,18 @@ private:
iss::status write_ip(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 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);
protected:
void check_interrupt();
};
template <typename BASE>
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();
uart_buf.str("");
// 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_rd_cb[frm] = &riscv_hart_msu_vp<BASE>::read_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");
if (fp) {
std::array<char, 5> buf;
auto n = fread(buf.data(), 1, 4, fp);
std::array<char, 5> buf;
auto n = fread(buf.data(), 1, 4, fp);
if (n != 4) throw std::runtime_error("input file has insufficient size");
buf[4] = 0;
if (strcmp(buf.data() + 1, "ELF") == 0) {
if (strcmp(buf.data() + 1, "ELF") == 0) {
fclose(fp);
// Create elfio reader
ELFIO::elfio reader;
// Load ELF data
if (!reader.load(name)) throw std::runtime_error("could not process elf file");
// check elf properties
if ( reader.get_class() != ELFCLASS32 )
if(sizeof(reg_t) == 4) throw std::runtime_error("wrong elf class in file");
if (reader.get_class() != ELFCLASS32)
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_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) {
const auto fsize = pseg->get_file_size(); // 0x42c/0x0
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) {
#ifndef NDEBUG
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 {
LOG(DEBUG) << "read of " << length << " bytes @addr " << addr;
LOG(TRACE) << "read of " << length << " bytes @addr " << addr;
}
#endif
try {
@ -716,26 +724,26 @@ iss::status riscv_hart_msu_vp<BASE>::read(const iss::addr_t &addr, unsigned leng
template <typename BASE>
iss::status riscv_hart_msu_vp<BASE>::write(const iss::addr_t &addr, unsigned length, const uint8_t *const data) {
#ifndef NDEBUG
const char *prefix = (addr.access && iss::access_type::DEBUG)? "debug " : "";
const char *prefix = (addr.access && iss::access_type::DEBUG) ? "debug " : "";
switch (length) {
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;
break;
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;
break;
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;
break;
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;
break;
default:
LOG(DEBUG) << prefix << "write of " << length << " bytes @addr " << addr;
LOG(TRACE) << prefix << "write of " << length << " bytes @addr " << addr;
}
#endif
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);
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;
} catch (trap_access &ta) {
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) {
auto cycle_val= this->reg.icount + cycle_offset;
auto cycle_val = this->reg.icount + cycle_offset;
if (addr == mcycle) {
val = static_cast<reg_t>(cycle_val);
} 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) {
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) {
val = static_cast<reg_t>(time_val);
} 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;
if (this->reg.machine_state < req_priv_lvl) throw illegal_instruction_fault(this->fault_data);
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);
check_interrupt();
return iss::Ok;
@ -953,16 +962,16 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_satp(unsigne
update_vm_info();
return iss::Ok;
}
template<typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_fcsr(unsigned addr, reg_t& val) {
switch(addr){
case 1: //fflags, 4:0
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_fcsr(unsigned addr, reg_t &val) {
switch (addr) {
case 1: // fflags, 4:0
val = bit_sub<0, 5>(this->get_fcsr());
break;
case 2: // frm, 7:5
val = bit_sub<5, 3>(this->get_fcsr());
break;
break;
case 3: // fcsr
val=this->get_fcsr();
val = this->get_fcsr();
break;
default:
return iss::Err;
@ -970,16 +979,16 @@ template<typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_fcsr(unsigned
return iss::Ok;
}
template<typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_fcsr(unsigned addr, reg_t val) {
switch(addr){
case 1: //fflags, 4:0
this->set_fcsr( (this->get_fcsr() & 0xffffffe0) | (val&0x1f));
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_fcsr(unsigned addr, reg_t val) {
switch (addr) {
case 1: // fflags, 4:0
this->set_fcsr((this->get_fcsr() & 0xffffffe0) | (val & 0x1f));
break;
case 2: // frm, 7:5
this->set_fcsr( (this->get_fcsr() & 0xffffff1f) | ((val&0x7)<<5));
break;
this->set_fcsr((this->get_fcsr() & 0xffffff1f) | ((val & 0x7) << 5));
break;
case 3: // fcsr
this->set_fcsr(val&0xff);
this->set_fcsr(val & 0xff);
break;
default:
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;
switch (paddr.val) {
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;
this->read_csr(time, time_val);
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)) {
switch (hostvar >> 48) {
case 0:
if (hostvar != 0x1){
if (hostvar != 0x1) {
LOG(FATAL) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
<< "), stopping simulation";
}else{
} else {
LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
<< "), stopping simulation";
}
@ -1087,22 +1096,20 @@ iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t paddr, unsigned lengt
return iss::Ok;
}
template<typename BASE>
inline void riscv_hart_msu_vp<BASE>::reset(uint64_t address) {
template <typename BASE> inline void riscv_hart_msu_vp<BASE>::reset(uint64_t address) {
BASE::reset(address);
state.mstatus = hart_state<reg_t>::mstatus_reset_val;
update_vm_info();
}
template<typename BASE>
inline void riscv_hart_msu_vp<BASE>::update_vm_info() {
template <typename BASE> 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);
BASE::addr_mode[3]=BASE::addr_mode[2]=vm[1].is_active()?iss::address_type::VIRTUAL:iss::address_type::PHYSICAL;
if(state.mstatus.MPRV)
BASE::addr_mode[3]=BASE::addr_mode[2] = vm[1].is_active()? iss::address_type::VIRTUAL : iss::address_type::PHYSICAL;
if (state.mstatus.MPRV)
vm[0] = hart_state<reg_t>::decode_vm_info(state.mstatus.MPP, state.satp);
else
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();
}
@ -1117,7 +1124,7 @@ template <typename BASE> void riscv_hart_msu_vp<BASE>::check_interrupt() {
// any synchronous traps.
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 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
} else {
uint32_t mode = type != iss::access_type::FETCH && state.mstatus.MPRV ? // MPRV
state.mstatus.MPP:
state.mstatus.MPP :
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 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
reg_t pte = 0;
const uint8_t res =
this->read(phys_addr_t{addr.access, traits<BASE>::MEM, base + idx * vm.ptesize}, vm.ptesize, (uint8_t *)&pte);
const uint8_t res = this->read(phys_addr_t{addr.access, traits<BASE>::MEM, base + idx * vm.ptesize},
vm.ptesize, (uint8_t *)&pte);
if (res != 0) throw trap_load_access_fault(addr.val);
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;
} else if (!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) {
break;
} else if (type == iss::access_type::FETCH ? !(pte & PTE_X)
: type == iss::access_type::READ ? !(pte & PTE_R) && !(mxr && (pte & PTE_X))
: !((pte & PTE_R) && (pte & PTE_W))) {
} else if (type == iss::access_type::FETCH
? !(pte & PTE_X)
: type == iss::access_type::READ ? !(pte & PTE_R) && !(mxr && (pte & PTE_X))
: !((pte & PTE_R) && (pte & PTE_W))) {
break;
} else if ((ppn & ((reg_t(1) << ptshift) - 1)) != 0) {
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
this->reg.pending_trap = 0;
}
size_t adr=ucause | (new_priv << 8);
csr[adr] = (trap_id<<31)+cause;
size_t adr = ucause | (new_priv << 8);
csr[adr] = (trap_id << 31) + cause;
// update mstatus
// xPP field of mstatus is written with the active privilege mode at the time
// 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
switch (new_priv) {
case PRIV_M:
state.mstatus.MPP=cur_priv;
state.mstatus.MPIE=state.mstatus.MIE;
state.mstatus.MPP = cur_priv;
state.mstatus.MPIE = state.mstatus.MIE;
state.mstatus.MIE = false;
break;
case PRIV_S:
state.mstatus.SPP = cur_priv;
state.mstatus.SPIE=state.mstatus.SIE;
state.mstatus.SPIE = state.mstatus.SIE;
state.mstatus.SIE = false;
break;
case PRIV_U:
state.mstatus.UPIE=state.mstatus.UIE;
state.mstatus.UPIE = state.mstatus.UIE;
state.mstatus.UIE = false;
break;
default:
break;
@ -1288,11 +1299,12 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
// reset trap state
this->reg.machine_state = new_priv;
this->reg.trap_state = 0;
std::array<char, 32> buffer;
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<<")"
<< " at address " << buffer.data() << " occurred, changing privilege level from " << lvl[cur_priv]
<< " to " << lvl[new_priv];
std::array<char, 32> buffer;
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 << ")"
<< " at address " << buffer.data() << " occurred, changing privilege level from "
<< lvl[cur_priv] << " to " << lvl[new_priv];
update_vm_info();
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) {
case PRIV_M:
this->reg.machine_state = state.mstatus.MPP;
state.mstatus.MPP=0; // clear mpp to U mode
state.mstatus.MIE=state.mstatus.MPIE;
state.mstatus.MPP = 0; // clear mpp to U mode
state.mstatus.MIE = state.mstatus.MPIE;
break;
case PRIV_S:
this->reg.machine_state = state.mstatus.SPP;
state.mstatus.SPP= 0; // clear spp to U mode
state.mstatus.SIE=state.mstatus.SPIE;
state.mstatus.SPP = 0; // clear spp to U mode
state.mstatus.SIE = state.mstatus.SPIE;
break;
case PRIV_U:
this->reg.machine_state = 0;
state.mstatus.UIE=state.mstatus.UPIE;
state.mstatus.UIE = state.mstatus.UPIE;
break;
}
// sets the pc to the value stored in the x epc register.
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();
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_ */

View File

@ -179,7 +179,7 @@ struct rv32gc: public arch_if {
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){
if(addr.space != traits<rv32gc>::MEM ||
@ -272,6 +272,7 @@ protected:
std::array<address_type, 4> addr_mode;
bool interrupt_sim=false;
uint32_t get_fcsr(){return reg.FCSR;}
void set_fcsr(uint32_t val){reg.FCSR = val;}

View File

@ -1,54 +1,59 @@
////////////////////////////////////////////////////////////////////////////////
// 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.
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 _RV32IMAC_H_
#define _RV32IMAC_H_
#include <array>
#include <iss/arch/traits.h>
#include <iss/arch_if.h>
#include <iss/vm_if.h>
#include <iss/arch/traits.h>
#include <array>
namespace iss {
namespace arch {
struct rv32imac;
template<>
struct traits<rv32imac> {
template <> struct traits<rv32imac> {
constexpr static char const* const core_type = "RV32IMAC";
enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b1000000000101000001000100000101, PGSIZE=0x1000, PGMASK=0xfff};
constexpr static char const *const core_type = "RV32IMAC";
enum constants {
XLEN = 32,
PCLEN = 32,
MISA_VAL = 0b1000000000101000001000100000101,
PGSIZE = 0x1000,
PGMASK = 0xfff
};
constexpr static unsigned FP_REGS_SIZE = 0;
@ -87,7 +92,7 @@ struct traits<rv32imac> {
X31,
PC,
NUM_REGS,
NEXT_PC=NUM_REGS,
NEXT_PC = NUM_REGS,
TRAP_STATE,
PENDING_TRAP,
MACHINE_STATE,
@ -99,72 +104,70 @@ struct traits<rv32imac> {
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 phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
constexpr static unsigned reg_bit_width(unsigned r) {
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}};
return RV32IMAC_reg_size[r];
}
static 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}};
constexpr static unsigned reg_byte_offset(unsigned 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];
}
constexpr static unsigned reg_bit_width(unsigned r) { return RV32IMAC_reg_size[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);
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 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;
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
void get_reg(short idx, std::vector<uint8_t>& value) override {}
void set_reg(short idx, const 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 {}
/// deprecated
bool get_flag(int flag) override {return false;}
void set_flag(int, bool value) override {};
bool get_flag(int flag) override { return false; }
void set_flag(int, bool value) override{};
/// 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
uint64_t get_icount() { return reg.icount;}
inline uint64_t get_icount() { return reg.icount; }
inline
bool should_stop() { return interrupt_sim;}
inline bool should_stop() { return interrupt_sim; }
inline phys_addr_t v2p(const iss::addr_t& addr){
if(addr.space != traits<rv32imac>::MEM ||
addr.type == iss::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);
inline phys_addr_t v2p(const iss::addr_t &addr) {
if (addr.space != traits<rv32imac>::MEM || addr.type == iss::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);
} else
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; }
inline
uint32_t get_last_branch(){return reg.last_branch;}
inline uint32_t get_last_branch() { return reg.last_branch; }
protected:
struct RV32IMAC_regs {
@ -207,14 +210,12 @@ protected:
} reg;
std::array<address_type, 4> addr_mode;
bool interrupt_sim=false;
uint32_t get_fcsr(){return 0;}
void set_fcsr(uint32_t val){}
bool interrupt_sim = false;
uint32_t get_fcsr() { return 0; }
void set_fcsr(uint32_t val) {}
};
}
}
}
#endif /* _RV32IMAC_H_ */

View File

@ -144,9 +144,9 @@ struct rv64ia: public arch_if {
/// deprecated
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){
if(addr.space != traits<rv64ia>::MEM ||
@ -206,6 +206,7 @@ protected:
std::array<address_type, 4> addr_mode;
bool interrupt_sim=false;
uint32_t get_fcsr(){return 0;}
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
* Author: eyck
*/
* 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 _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/iss.h>
#include <array>
#include <memory>
#include <util/logging.h>
#include <array>
namespace iss {
namespace debugger {
@ -95,9 +120,10 @@ public:
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:
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));
avail.push_back(0xff);
}
// if(arch::traits<ARCH>::XLEN < 64)
// for(unsigned j=0; j<4; ++j){
// data.push_back(0);
// avail.push_back(0xff);
// }
// if(arch::traits<ARCH>::XLEN < 64)
// for(unsigned j=0; j<4; ++j){
// data.push_back(0);
// avail.push_back(0xff);
// }
}
// work around fill with F type registers
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);
avail.push_back(0x00);
}
// if(arch::traits<ARCH>::XLEN < 64)
// for(unsigned j=0; j<4; ++j){
// data.push_back(0x0);
// avail.push_back(0x00);
// }
// if(arch::traits<ARCH>::XLEN < 64)
// for(unsigned j=0; j<4; ++j){
// data.push_back(0x0);
// avail.push_back(0x00);
// }
}
}
return Ok;
@ -280,10 +306,10 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::threadinfo_query(int
template <typename ARCH>
status riscv_target_adapter<ARCH>::threadextrainfo_query(const rp_thread_ref &thread, std::string &out_buf) {
std::array<char, 20> buf;
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);
out_buf = buf.data();
std::array<char, 20> buf;
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);
out_buf = buf.data();
return Ok;
}
@ -317,56 +343,56 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::remove_break(int typ
return Err;
}
template <typename ARCH> status riscv_target_adapter<ARCH>::resume_from_addr(bool step, int sig, uint64_t addr, rp_thread_ref thread,
std::function<void(unsigned)> stop_callback) {
auto* reg_base = core->get_regs_base_ptr();
template <typename ARCH>
status riscv_target_adapter<ARCH>::resume_from_addr(bool step, int sig, uint64_t addr, rp_thread_ref thread,
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 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);
return resume_from_current(step, sig, thread, stop_callback);
}
template <typename ARCH> status riscv_target_adapter<ARCH>::target_xml_query(std::string& out_buf) {
const std::string res{
"<?xml version=\"1.0\"?><!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
"<target><architecture>riscv:rv32</architecture>"
//" <feature name=\"org.gnu.gdb.riscv.rv32i\">\n"
//" <reg name=\"x0\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x1\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x2\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x3\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x4\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x5\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x6\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x7\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x8\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x9\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x10\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x11\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x12\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x13\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x14\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x15\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x16\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x17\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x18\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x19\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x20\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x21\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x22\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x23\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x24\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x25\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x26\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x27\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x28\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x29\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x30\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x31\" bitsize=\"32\" group=\"general\"/>\n"
//" </feature>\n"
"</target>"};
out_buf=res;
template <typename ARCH> status riscv_target_adapter<ARCH>::target_xml_query(std::string &out_buf) {
const std::string res{"<?xml version=\"1.0\"?><!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
"<target><architecture>riscv:rv32</architecture>"
//" <feature name=\"org.gnu.gdb.riscv.rv32i\">\n"
//" <reg name=\"x0\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x1\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x2\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x3\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x4\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x5\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x6\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x7\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x8\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x9\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x10\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x11\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x12\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x13\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x14\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x15\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x16\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x17\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x18\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x19\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x20\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x21\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x22\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x23\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x24\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x25\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x26\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x27\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x28\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x29\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x30\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x31\" bitsize=\"32\" group=\"general\"/>\n"
//" </feature>\n"
"</target>"};
out_buf = res;
return Ok;
}

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (C) 2017, MINRES Technologies GmbH
* Copyright (C) 2017, 2018, MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -35,8 +35,8 @@
#ifndef _ISS_PLUGIN_CYCLE_ESTIMATE_H_
#define _ISS_PLUGIN_CYCLE_ESTIMATE_H_
#include "iss/vm_plugin.h"
#include "iss/instrumentation_if.h"
#include "iss/vm_plugin.h"
#include <json/json.h>
#include <string>
#include <unordered_map>
@ -58,38 +58,38 @@ class cycle_estimate: public iss::vm_plugin {
END_BF_DECL();
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:
iss::instrumentation_if* arch_instr;
iss::instrumentation_if *arch_instr;
std::vector<instr_desc> delays;
struct pair_hash {
size_t operator()(const std::pair<uint64_t, uint64_t>& p) const{
std::hash<uint64_t> hash;
return hash(p.first)+hash(p.second);
}
size_t operator()(const std::pair<uint64_t, uint64_t> &p) const {
std::hash<uint64_t> hash;
return hash(p.first) + hash(p.second);
}
};
std::unordered_map<std::pair<uint64_t, uint64_t>, uint64_t, pair_hash> blocks;
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.
*
* Redistribution and use in source and binary forms, with or without
@ -42,39 +42,40 @@
namespace iss {
namespace plugin {
class instruction_count: public iss::vm_plugin {
struct instr_delay {
std::string instr_name;
size_t size;
size_t not_taken_delay;
size_t taken_delay;
};
class instruction_count : public iss::vm_plugin {
struct instr_delay {
std::string instr_name;
size_t size;
size_t not_taken_delay;
size_t taken_delay;
};
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:
Json::Value root;
std::vector<instr_delay> delays;
std::vector<uint64_t> rep_counts;
};
}
}

View File

@ -1,14 +1,16 @@
# library files
FILE(GLOB RiscVHeaders *.h)
FILE(GLOB IssSources iss/*.cpp internal/*.cpp)
set(LIB_HEADERS ${RiscVHeaders} )
set(LIB_SOURCES
${IssSources}
FILE(GLOB RiscVSCHeaders ${PROJECT_SOURCE_DIR}/incl/sysc/*.h ${PROJECT_SOURCE_DIR}/incl/sysc/*/*.h)
set(LIB_HEADERS ${RiscVSCHeaders} )
set(LIB_SOURCES
iss/rv32gc.cpp
iss/rv32imac.cpp
iss/rv64ia.cpp
internal/fp_functions.cpp
internal/vm_rv32gc.cpp
internal/vm_rv32imac.cpp
internal/vm_rv64ia.cpp
plugin/instruction_count.cpp
plugin/cycle_estimate.cpp
)
plugin/cycle_estimate.cpp)
set(APP_HEADERS )
@ -18,7 +20,6 @@ set(APP_SOURCES main.cpp)
set(LIBRARY_NAME riscv)
# Define the library
#add_library(${LIBRARY_NAME} SHARED ${LIB_SOURCES})
add_library(${LIBRARY_NAME} ${LIB_SOURCES})
SET(${LIBRARY_NAME} -Wl,-whole-archive -l${LIBRARY_NAME} -Wl,-no-whole-archive)
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
// 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.
//
// Created on: Tue Aug 29 16:45:20 CEST 2017
// * rv32imac.cpp Author: <CoreDSL Generator>
//
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 "util/ities.h"
#include <util/logging.h>
@ -52,9 +49,15 @@ extern "C" {
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) {
for (size_t i = 0; i < traits<rv32imac>::NUM_REGS; ++i)

View File

@ -1,36 +1,34 @@
////////////////////////////////////////////////////////////////////////////////
// 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
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* 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 <iostream>
#include <iss/iss.h>
@ -43,8 +41,8 @@
#include <iss/arch/rv64ia.h>
#include <iss/jit/jit_helper.h>
#include <iss/log_categories.h>
#include <iss/plugin/instruction_count.h>
#include <iss/plugin/cycle_estimate.h>
#include <iss/plugin/instruction_count.h>
namespace po = boost::program_options;
@ -98,8 +96,8 @@ int main(int argc, char *argv[]) {
LOG_OUTPUT(connection)::stream() = f;
}
std::vector<iss::vm_plugin*> plugin_list;
auto res=0;
std::vector<iss::vm_plugin *> plugin_list;
auto res = 0;
try {
// application code comes here //
iss::init_jit(argc, argv);
@ -125,24 +123,24 @@ int main(int argc, char *argv[]) {
return 127;
}
if (clim.count("plugin")) {
for (std::string opt_val : clim["plugin"].as<std::vector<std::string>>()){
auto plugin_name{opt_val};
std::string filename{"cycles.txt"};
std::size_t found = opt_val.find('=');
if (found!=std::string::npos){
plugin_name=opt_val.substr(0, found);
filename=opt_val.substr(found+1, opt_val.size());
}
if(plugin_name=="ic"){
auto* ic_plugin= new iss::plugin::instruction_count(filename);
for (std::string opt_val : clim["plugin"].as<std::vector<std::string>>()) {
std::string plugin_name{opt_val};
std::string filename{"cycles.txt"};
std::size_t found = opt_val.find('=');
if (found != std::string::npos) {
plugin_name = opt_val.substr(0, found);
filename = opt_val.substr(found + 1, opt_val.size());
}
if (plugin_name == "ic") {
auto *ic_plugin = new iss::plugin::instruction_count(filename);
vm->register_plugin(*ic_plugin);
plugin_list.push_back(ic_plugin);
} else if(plugin_name=="ce"){
auto* ce_plugin= new iss::plugin::cycle_estimate(filename);
} else if (plugin_name == "ce") {
auto *ce_plugin = new iss::plugin::cycle_estimate(filename);
vm->register_plugin(*ce_plugin);
plugin_list.push_back(ce_plugin);
} 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;
}
}
@ -157,33 +155,32 @@ int main(int argc, char *argv[]) {
LOGGER(disass)::print_severity() = false;
}
}
uint64_t start_address=0;
uint64_t start_address = 0;
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"))
for (std::string input : clim["elf"].as<std::vector<std::string>>()){
auto start_addr = vm->get_arch()->load_file(input);
if(start_addr.second)
start_address=start_addr.first;
for (std::string input : clim["elf"].as<std::vector<std::string>>()) {
auto start_addr = vm->get_arch()->load_file(input);
if (start_addr.second) start_address = start_addr.first;
}
for (std::string input : args){
auto start_addr = vm->get_arch()->load_file(input);// treat remaining arguments as elf files
if(start_addr.second)
start_address=start_addr.first;
for (std::string input : args) {
auto start_addr = vm->get_arch()->load_file(input); // treat remaining arguments as elf files
if (start_addr.second) start_address = start_addr.first;
}
if (clim.count("reset")) {
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>();
res = vm->start(cycles, dump);
} catch (std::exception &e) {
LOG(ERROR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit" << std::endl;
res=2;
LOG(ERROR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit"
<< std::endl;
res = 2;
}
// cleanup to let plugins report of needed
for(auto* p:plugin_list){
for (auto *p : plugin_list) {
delete p;
}
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")
# 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")
include(Common)