Compare commits

...

29 Commits

Author SHA1 Message Date
9fcd203f87 updates scc and adds burst packet handling 2024-12-19 17:33:46 +01:00
2c18dd4d17 removes CentOS 7 from Jenkins as OS it not supported anymore 2024-12-19 16:29:21 +01:00
5be69cfa75 cleans up Jenkinsfile 2024-12-19 13:34:55 +01:00
085423620d adds multi-packet CXS test case 2024-12-19 11:59:00 +01:00
1eba464c61 fixes namespace in CXS test 2024-12-18 19:31:09 +01:00
2e4d0efb50 applies clang-tidy fixes 2024-12-18 19:23:05 +01:00
f8f1f2f54c applies clang-format 2024-12-18 17:36:16 +01:00
a0bd767bc9 adds some more CXS channel testing 2024-12-18 17:31:28 +01:00
89920683e9 updates initial CXS test 2024-12-13 20:35:32 +01:00
a8d883475d applies clang-format 2024-12-13 20:34:58 +01:00
82b219f267 updates scc and adapts tests 2024-12-11 11:03:49 +01:00
6df06684bc fixes project setup 2024-12-11 10:52:45 +01:00
56024ae892 applies clang format 2024-12-11 09:18:37 +01:00
bc2ba8161d adds some testing for CXS TLM implementation 2024-12-11 09:16:04 +01:00
2043e43140 updates scc 2024-10-10 20:52:52 +02:00
12f3ecd6f3 adds test for tracing of sc_fixed datatypes 2024-10-10 12:55:43 +02:00
9a41d1ac80 updates SCC to version 2024.07 2024-08-07 11:07:25 +02:00
614b1f9215 adds APB pinlevel adapter 2024-08-06 16:02:03 +02:00
8f8e8f928c updates scc 2024-07-11 20:10:13 +02:00
771f1fea26 updates scc 2024-07-11 07:58:43 +02:00
c22518a1f4 updates SCC 2024-07-11 07:30:09 +02:00
99b0d443d0 updates scc 2024-07-08 22:19:45 +02:00
8c25ce1ddf updates cci 2024-07-08 21:57:29 +02:00
c6e480d134 updates Jenkinsfile 2024-07-06 10:41:41 +02:00
29b8de6c16 updates Jenkinsfile 2024-07-06 10:37:34 +02:00
08c9e36fae removes ubuntu 20.04 form list 2024-07-06 10:25:29 +02:00
7ebfb5897c extends python package list to provide cmake and simplifies Jenkins 2024-07-06 10:22:02 +02:00
78d52ce741 removes generated preset file 2024-07-06 10:17:36 +02:00
e8def0bb86 switches to Conan 2 2024-07-06 10:15:24 +02:00
26 changed files with 860 additions and 226 deletions

View File

@ -14,7 +14,7 @@
</extensions> </extensions>
</storageModule> </storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0"> <storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" description="" id="cmake4eclipse.mbs.toolchain.cmake.134761605" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=" parent="org.eclipse.cdt.build.core.emptycfg"> <configuration artifactName="${ProjName}" buildProperties="" description="" id="cmake4eclipse.mbs.toolchain.cmake.134761605" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="cmake4eclipse.mbs.toolchain.cmake.134761605.1159094612" name="/" resourcePath=""> <folderInfo id="cmake4eclipse.mbs.toolchain.cmake.134761605.1159094612" name="/" resourcePath="">
<toolChain id="cmake4eclipse.mbs.toolchain.cmake.1883503430" name="CMake driven" superClass="cmake4eclipse.mbs.toolchain.cmake"> <toolChain id="cmake4eclipse.mbs.toolchain.cmake.1883503430" name="CMake driven" superClass="cmake4eclipse.mbs.toolchain.cmake">
<targetPlatform id="cmake4eclipse.mbs.targetPlatform.cmake.1279728098" name="Any Platform" superClass="cmake4eclipse.mbs.targetPlatform.cmake"/> <targetPlatform id="cmake4eclipse.mbs.targetPlatform.cmake.1279728098" name="Any Platform" superClass="cmake4eclipse.mbs.targetPlatform.cmake"/>
@ -28,10 +28,9 @@
</configuration> </configuration>
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule buildDir="build/${ConfigName}" dirtyTs="1715065528068" moduleId="de.marw.cmake4eclipse.mbs.settings"> <storageModule buildDir="build/${ConfigName}" dirtyTs="1733906014591" moduleId="de.marw.cmake4eclipse.mbs.settings">
<options/> <options otherArguments="--preset Debug"/>
<defs> <defs>
<def name="CMAKE_BUILD_TYPE" type="STRING" val="Debug"/>
<def name="BUILD_SCC_DOCUMENTATION" type="BOOL" val="OFF"/> <def name="BUILD_SCC_DOCUMENTATION" type="BOOL" val="OFF"/>
<def name="ENABLE_CLANG_TIDY" type="STRING" val="OFF"/> <def name="ENABLE_CLANG_TIDY" type="STRING" val="OFF"/>
</defs> </defs>
@ -64,10 +63,9 @@
</configuration> </configuration>
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule buildDir="build/${ConfigName}" dirtyTs="1673562408113" moduleId="de.marw.cmake4eclipse.mbs.settings"> <storageModule buildDir="build/${ConfigName}" dirtyTs="1720252186652" moduleId="de.marw.cmake4eclipse.mbs.settings">
<options/> <options otherArguments="--preset Release"/>
<defs> <defs>
<def name="CMAKE_BUILD_TYPE" type="STRING" val="Debug"/>
<def name="BUILD_SCC_DOCUMENTATION" type="BOOL" val="OFF"/> <def name="BUILD_SCC_DOCUMENTATION" type="BOOL" val="OFF"/>
</defs> </defs>
</storageModule> </storageModule>
@ -99,12 +97,47 @@
</configuration> </configuration>
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule buildDir="build/${ConfigName}" dirtyTs="1703253448607" moduleId="de.marw.cmake4eclipse.mbs.settings"> <storageModule buildDir="build/${ConfigName}" dirtyTs="1720252426316" moduleId="de.marw.cmake4eclipse.mbs.settings">
<options/> <options otherArguments="--preset Debug"/>
<defs>
<def name="BUILD_SCC_DOCUMENTATION" type="BOOL" val="OFF"/>
<def name="ENABLE_CLANG_TIDY" type="STRING" val="ON"/>
</defs>
</storageModule>
</cconfiguration>
<cconfiguration id="cmake4eclipse.mbs.toolchain.cmake.134761605.974626950">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cmake4eclipse.mbs.toolchain.cmake.134761605.974626950" moduleId="org.eclipse.cdt.core.settings" name="RelWithDebInfo">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.PE64" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" description="" id="cmake4eclipse.mbs.toolchain.cmake.134761605.974626950" name="RelWithDebInfo" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="cmake4eclipse.mbs.toolchain.cmake.134761605.974626950." name="/" resourcePath="">
<toolChain id="cmake4eclipse.mbs.toolchain.cmake.938816325" name="CMake driven" superClass="cmake4eclipse.mbs.toolchain.cmake">
<targetPlatform id="cmake4eclipse.mbs.targetPlatform.cmake.867056485" name="Any Platform" superClass="cmake4eclipse.mbs.targetPlatform.cmake"/>
<builder buildPath="/SystemC-Components-Test/build/Debug" id="cmake4eclipse.mbs.builder.792816315" keepEnvironmentInBuildfile="false" name="CMake Builder" superClass="cmake4eclipse.mbs.builder"/>
<tool id="cmake4eclipse.mbs.toolchain.tool.dummy.112318524" name="CMake" superClass="cmake4eclipse.mbs.toolchain.tool.dummy">
<inputType id="cmake4eclipse.mbs.inputType.c.931591253" superClass="cmake4eclipse.mbs.inputType.c"/>
<inputType id="cmake4eclipse.mbs.inputType.cpp.923601899" superClass="cmake4eclipse.mbs.inputType.cpp"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule buildDir="build/${ConfigName}" dirtyTs="1728554089717" moduleId="de.marw.cmake4eclipse.mbs.settings">
<options otherArguments="--preset Debug"/>
<defs> <defs>
<def name="CMAKE_BUILD_TYPE" type="STRING" val="Debug"/> <def name="CMAKE_BUILD_TYPE" type="STRING" val="Debug"/>
<def name="BUILD_SCC_DOCUMENTATION" type="BOOL" val="OFF"/> <def name="BUILD_SCC_DOCUMENTATION" type="BOOL" val="OFF"/>
<def name="ENABLE_CLANG_TIDY" type="STRING" val="ON"/> <def name="ENABLE_CLANG_TIDY" type="STRING" val="OFF"/>
</defs> </defs>
</storageModule> </storageModule>
</cconfiguration> </cconfiguration>
@ -117,10 +150,12 @@
<configuration configurationName="ClangTidy"> <configuration configurationName="ClangTidy">
<resource resourceType="PROJECT" workspacePath="/SystemC-Components-Test"/> <resource resourceType="PROJECT" workspacePath="/SystemC-Components-Test"/>
</configuration> </configuration>
<configuration configurationName="RelWithDebInfo"/>
<configuration configurationName="Default"> <configuration configurationName="Default">
<resource resourceType="PROJECT" workspacePath="/SystemC-Components-Test"/> <resource resourceType="PROJECT" workspacePath="/SystemC-Components-Test"/>
</configuration> </configuration>
<configuration configurationName="Debug"/> <configuration configurationName="Debug"/>
<configuration configurationName="Release"/>
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/> <storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<storageModule cmakelistsFolder="" moduleId="de.marw.cmake4eclipse.mbs.settings"> <storageModule cmakelistsFolder="" moduleId="de.marw.cmake4eclipse.mbs.settings">

1
.gitignore vendored
View File

@ -47,3 +47,4 @@
/.direnv/ /.direnv/
/.venv/ /.venv/
/.cache /.cache
/CMakeUserPresets.json

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "scc"] [submodule "scc"]
path = scc path = scc
url = https://github.com/Minres/SystemC-Components.git url = https://github.com/Minres/SystemC-Components.git
[submodule "cmake-conan"]
path = cmake-conan
url = https://github.com/conan-io/cmake-conan.git

View File

@ -8,11 +8,9 @@ option(FULL_TEST_SUITE "enable also long-running tests" OFF)
option(ENABLE_SCV "Enable use of SCV" OFF) option(ENABLE_SCV "Enable use of SCV" OFF)
option(ENABLE_CLANG_TIDY "Enable clang-tidy checks" OFF) option(ENABLE_CLANG_TIDY "Enable clang-tidy checks" OFF)
include(ConanInline)
include(GNUInstallDirs) include(GNUInstallDirs)
include(BuildType) include(BuildType)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON)
@ -20,14 +18,6 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-march=native" COMPILER_SUPPORTS_MARCH_NATIVE) CHECK_CXX_COMPILER_FLAG("-march=native" COMPILER_SUPPORTS_MARCH_NATIVE)
if(COMPILER_SUPPORTS_MARCH_NATIVE)
if("${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
elseif(NOT(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo"))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
endif()
endif()
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(warnings "-Wall -Wextra -Werror") set(warnings "-Wall -Wextra -Werror")
set(CMAKE_CXX_FLAG_RELEASE "-O3 -DNDEBUG") set(CMAKE_CXX_FLAG_RELEASE "-O3 -DNDEBUG")
@ -39,11 +29,10 @@ endif()
if(ENABLE_COVERAGE) if(ENABLE_COVERAGE)
include(CodeCoverage) include(CodeCoverage)
append_coverage_compiler_flags() append_coverage_compiler_flags()
set(COVERAGE_EXCLUDES "osci-lib/scc/*" "/engr/dev/tools/*")
endif() endif()
find_program(CLANG_TIDY_EXE NAMES "clang-tidy")
if(ENABLE_CLANG_TIDY) if(ENABLE_CLANG_TIDY)
find_program(CLANG_TIDY_EXE NAMES "clang-tidy")
if(CLANG_TIDY_EXE) if(CLANG_TIDY_EXE)
message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}") message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}")
#set(CLANG_TIDY_CHECKS "-*,modernize-*,-modernize-use-trailing-return-type,clang-analyzer-core.*,clang-analyzer-cplusplus.*") #set(CLANG_TIDY_CHECKS "-*,modernize-*,-modernize-use-trailing-return-type,clang-analyzer-core.*,clang-analyzer-cplusplus.*")
@ -54,17 +43,8 @@ if(ENABLE_CLANG_TIDY)
endif() endif()
endif() endif()
set(CLANG_FORMAT_EXCLUDE_PATTERNS "/third_party/") set(CLANG_FORMAT_EXCLUDE_PATTERNS "/third_party/" "/build/")
find_package(ClangFormat) find_package(ClangFormat)
set(CONAN_CMAKE_SILENT_OUTPUT ON)
conan_check()
conan_configure(REQUIRES jsoncpp/1.9.5 yaml-cpp/0.6.3 spdlog/1.9.2 fmt/8.0.1 boost/1.85.0 gsl-lite/0.37.0 systemc/2.3.4 catch2/3.1.0 zlib/1.2.11 lz4/1.9.4
GENERATORS cmake_find_package
OPTIONS fmt:header_only=True spdlog:header_only=True
)
conan_install()
find_package(ZLIB) find_package(ZLIB)
find_package(lz4) find_package(lz4)
# This line finds the boost lib and headers. # This line finds the boost lib and headers.

40
CMakePresets.json Normal file
View File

@ -0,0 +1,40 @@
{
"version": 3,
"vendor": {
"conan": {}
},
"cmakeMinimumRequired": {
"major": 3,
"minor": 24,
"patch": 0
},
"configurePresets": [
{
"name": "Debug",
"cacheVariables": {
"CMAKE_POLICY_DEFAULT_CMP0091": "NEW",
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_CXX_STANDARD": "17",
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES": "cmake-conan/conan_provider.cmake"
}
},
{
"name": "RelWithDebInfo",
"cacheVariables": {
"CMAKE_POLICY_DEFAULT_CMP0091": "NEW",
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
"CMAKE_CXX_STANDARD": "17",
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES": "cmake-conan/conan_provider.cmake"
}
},
{
"name": "Release",
"cacheVariables": {
"CMAKE_POLICY_DEFAULT_CMP0091": "NEW",
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_CXX_STANDARD": "17",
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES": "cmake-conan/conan_provider.cmake"
}
}
]
}

45
Jenkinsfile vendored
View File

@ -29,18 +29,12 @@ void checkout_project() {
]) ])
} }
void setup_conan() {
sh'''
pip3 install --user "conan<2.0" pyucis
conan profile new default --detect --force
conan remote list | grep minres > /dev/null
[ $? ] || conan remote add minres https://git.minres.com/api/packages/Tooling/conan
'''
}
void build_n_test_project() { void build_n_test_project() {
sh''' sh'''
cmake -S . -B build python3 -mvenv .venv
. .venv/bin/activate
pip3 install -r requirements.txt
cmake -S . -B build --preset Release
cmake --build build -j12 cmake --build build -j12
cmake --build build --target test cmake --build build --target test
''' '''
@ -57,47 +51,30 @@ pipeline {
stages { stages {
stage('SCC test pipeline') { stage('SCC test pipeline') {
parallel { parallel {
stage('U22.04') { stage('ubuntu-22.04') {
agent {docker { image 'ubuntu-22.04' } } agent {docker { image 'ubuntu-22.04' } }
stages { stages {
stage('Checkout') { steps { checkout_project() }} stage('Checkout') { steps { checkout_project() }}
stage('Setup') { steps { setup_conan() }}
stage('Build & test') { steps { build_n_test_project() }} stage('Build & test') { steps { build_n_test_project() }}
} }
} }
stage('U20.04') { stage('rockylinux8') {
agent {docker { image 'ubuntu-20.04' } }
stages {
stage('Checkout') { steps { checkout_project() }}
stage('Setup') { steps { setup_conan() }}
stage('Build & test') { steps { build_n_test_project() }}
}
}
stage('COS7') {
agent {docker { image 'centos7' } }
stages {
stage('Checkout') { steps { checkout_project() }}
stage('Setup') { steps { setup_conan() }}
stage('Build & test') { steps { build_n_test_project() }}
}
}
stage('RCK8') {
agent {docker { image 'rockylinux8' } } agent {docker { image 'rockylinux8' } }
stages { stages {
stage('Checkout') { steps { checkout_project() }} stage('Checkout') { steps { checkout_project() }}
stage('Setup') { steps { setup_conan() }}
stage('Build & test') { steps { build_n_test_project() }} stage('Build & test') { steps { build_n_test_project() }}
} }
} }
//
stage('Format check') { stage('Format check') {
agent {docker { image 'ubuntu-riscv' } } agent {docker { image 'ubuntu-22.04' } }
stages { stages {
stage('Checkout') { steps { checkout_project() }} stage('Checkout') { steps { checkout_project() }}
stage('Setup') { steps { setup_conan() }}
stage('Build & check format') { steps { stage('Build & check format') { steps {
sh''' sh'''
cmake -S . -B build python3 -mvenv .venv
. .venv/bin/activate
pip3 install -r requirements.txt
cmake -S . -B build --preset Release
cmake --build build --target format-check cmake --build build --target format-check
''' '''
}} }}

View File

@ -13,5 +13,5 @@ if { $distro == "CentOS" && ![info exists ::env(PROJECT)] && ![info exists ::env
} }
module load tools/utilities module load tools/utilities
module load tools/cmake module load tools/cmake/3.28
module load tools/clang/14.0 module load tools/clang/14.0

View File

@ -12,9 +12,10 @@ In Console:
module load ./Modulefile module load ./Modulefile
python3 -mvenv .venv python3 -mvenv .venv
. .venv/bin/activate . .venv/bin/activate
pip3 install conan==1.59.0 pip3 install -r requirements.txt
cmake -S . -B build cmake -S . -B build --preset Release
cmake --build build -j30 cmake --build build -j30
cmake --build build --target test

1
cmake-conan Submodule

@ -0,0 +1 @@
Subproject commit c22bbf0af0b73d5f0def24a9cdf4ce503ae79e5d

44
conanfile.txt Normal file
View File

@ -0,0 +1,44 @@
[requires]
jsoncpp/1.9.5
yaml-cpp/0.6.3
spdlog/1.9.2
fmt/8.0.1
boost/1.85.0
gsl-lite/0.37.0
systemc/2.3.4
catch2/3.1.0
zlib/1.2.11
lz4/1.9.4
rapidjson/cci.20230929
[options]
boost/*:fPIC=True
boost/*:header_only=False
boost/*:without_contract=True
boost/*:without_fiber=True
boost/*:without_graph=True
boost/*:without_graph_parallel=True
boost/*:without_iostreams=True
boost/*:without_json=True
boost/*:without_locale=True
boost/*:without_log=True
boost/*:without_math=True
boost/*:without_mpi=True
boost/*:without_nowide=True
boost/*:without_python=True
boost/*:without_random=True
boost/*:without_regex=True
boost/*:without_stacktrace=True
boost/*:without_test=True
boost/*:without_timer=True
boost/*:without_type_erasure=True
boost/*:without_wave=True
systemc/*:shared=False
systemc/*:disable_virtual_bind=False
[generators]
CMakeDeps
CMakeToolchain
[layout]
cmake_layout

View File

@ -1,148 +0,0 @@
#include <ahb/pin/initiator.h>
#include <ahb/pin/target.h>
#include <cci_utils/broker.h>
#include <fstream>
#include <scc/configurable_tracer.h>
#include <scc/configurer.h>
#include <scc/report.h>
#include <scc/traceable.h>
#include <scc/tracer.h>
#include <tlm/scc/initiator_mixin.h>
#include <tlm/scc/target_mixin.h>
using namespace sc_core;
using namespace scc;
class testbench : public sc_module, public scc::traceable {
public:
enum { WIDTH = 64 };
tlm::scc::initiator_mixin<tlm::tlm_initiator_socket<WIDTH>> isck{"isck"};
ahb::pin::initiator<WIDTH> intor{"intor"};
sc_core::sc_clock HCLK{"HCLK", 10_ns};
sc_core::sc_signal<bool> HRESETn{"HRESETn"};
sc_core::sc_signal<sc_dt::sc_uint<32>> HADDR{"HADDR"};
sc_core::sc_signal<sc_dt::sc_uint<3>> HBURST{"HBURST"};
sc_core::sc_signal<bool> HMASTLOCK{"HMASTLOCK"};
sc_core::sc_signal<sc_dt::sc_uint<4>> HPROT{"HPROT"};
sc_core::sc_signal<sc_dt::sc_uint<3>> HSIZE{"HSIZE"};
sc_core::sc_signal<sc_dt::sc_uint<2>> HTRANS{"HTRANS"};
sc_core::sc_signal<sc_dt::sc_uint<WIDTH>> HWDATA{"HWDATA"};
sc_core::sc_signal<bool> HWRITE{"HWRITE"};
sc_core::sc_signal<sc_dt::sc_uint<WIDTH>> HRDATA{"HRDATA"};
sc_core::sc_signal<bool> HREADY{"HREADY"};
sc_core::sc_signal<bool> HRESP{"HRESP"};
sc_core::sc_signal<bool> HSEL{"HSEL"};
ahb::pin::target<WIDTH> target{"target"};
tlm::scc::target_mixin<tlm::tlm_target_socket<WIDTH>> tsck{"tsck"};
testbench(sc_module_name nm)
: sc_module(nm) {
SC_HAS_PROCESS(testbench);
isck(intor.tsckt);
intor.HCLK_i(HCLK);
intor.HRESETn_i(HRESETn);
intor.HADDR_o(HADDR);
intor.HBURST_o(HBURST);
intor.HMASTLOCK_o(HMASTLOCK);
intor.HPROT_o(HPROT);
intor.HSIZE_o(HSIZE);
intor.HTRANS_o(HTRANS);
intor.HWDATA_o(HWDATA);
intor.HWRITE_o(HWRITE);
intor.HRDATA_i(HRDATA);
intor.HREADY_i(HREADY);
intor.HRESP_i(HRESP);
target.HCLK_i(HCLK);
target.HRESETn_i(HRESETn);
target.HADDR_i(HADDR);
target.HBURST_i(HBURST);
target.HMASTLOCK_i(HMASTLOCK);
target.HPROT_i(HPROT);
target.HSIZE_i(HSIZE);
target.HTRANS_i(HTRANS);
target.HWDATA_i(HWDATA);
target.HWRITE_i(HWRITE);
target.HSEL_i(HSEL);
target.HRDATA_o(HRDATA);
target.HREADY_o(HREADY);
target.HRESP_o(HRESP);
target.isckt(tsck);
SC_THREAD(run);
tsck.register_b_transport([this](tlm::tlm_generic_payload& gp, sc_time& delay) {
gp.set_response_status(tlm::TLM_OK_RESPONSE);
if(gp.is_write()) {
SCCINFO(SCMOD) << "Received write access to addr 0x" << std::hex << gp.get_address();
} else {
memset(gp.get_data_ptr(), 0x55, gp.get_data_length());
SCCINFO(SCMOD) << "Received read access from addr 0x" << std::hex << gp.get_address();
}
});
}
void run() {
HRESETn.write(false);
for(size_t i = 0; i < 10; ++i)
wait(HCLK.posedge_event());
HRESETn.write(true);
wait(HCLK.posedge_event());
HSEL.write(true);
tlm::tlm_generic_payload gp;
uint8_t data[8];
data[0] = 2;
data[1] = 4;
gp.set_address(0x1000);
gp.set_data_length(8);
gp.set_data_ptr(data);
gp.set_streaming_width(8);
gp.set_command(tlm::TLM_WRITE_COMMAND);
sc_time delay;
isck->b_transport(gp, delay);
gp.set_address(0x1020);
gp.set_data_length(8);
gp.set_data_ptr(data);
gp.set_streaming_width(8);
gp.set_command(tlm::TLM_READ_COMMAND);
delay = SC_ZERO_TIME;
isck->b_transport(gp, delay);
for(size_t i = 0; i < 10; ++i)
wait(HCLK.posedge_event());
sc_stop();
}
};
int sc_main(int argc, char* argv[]) {
sc_core::sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", sc_core::SC_DO_NOTHING);
sc_report_handler::set_actions(SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, SC_DO_NOTHING);
///////////////////////////////////////////////////////////////////////////
// configure logging
///////////////////////////////////////////////////////////////////////////
scc::init_logging(scc::log::DEBUG);
///////////////////////////////////////////////////////////////////////////
// set up configuration and tracing
///////////////////////////////////////////////////////////////////////////
scc::configurer cfg("ahb_bfm.json");
scc::configurable_tracer trace("ahb_bfm", tracer::TEXT, true, true);
///////////////////////////////////////////////////////////////////////////
// create modules/channels and trace
///////////////////////////////////////////////////////////////////////////
testbench tb("tb");
trace.add_control();
{
std::ofstream of{"ahb_test.default.json"};
if(of.is_open())
cfg.dump_configuration(of);
}
cfg.configure();
///////////////////////////////////////////////////////////////////////////
// run the simulation
///////////////////////////////////////////////////////////////////////////
try {
sc_core::sc_start(1_us);
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);
}
return 0;
}

View File

@ -1 +1,3 @@
conan<2.0 conan>=2.0
cmake
clang-format==14.0

2
scc

@ -1 +1 @@
Subproject commit 803a6bba4d979dad70e797236f8951080648df54 Subproject commit d6f2a80b1b8aa49506fd6e37e21c38149bcc3ba6

View File

@ -25,7 +25,7 @@ public:
add(const std::string& name, Args&&... args); add(const std::string& name, Args&&... args);
}; };
template <typename T> static T& get(const std::string& name = ""); template <typename T> static T& get(const std::string& name = typeid(T).name());
void create(); void create();
@ -50,7 +50,7 @@ private:
std::map<std::string, object> m_objects; std::map<std::string, object> m_objects;
}; };
template <typename T, typename... Args> factory::add<T, Args...>::add(Args&&... args) { add("", args...); } template <typename T, typename... Args> factory::add<T, Args...>::add(Args&&... args) { add(typeid(T).name(), args...); }
template <typename T, typename... Args> factory::add<T, Args...>::add(const std::string& name, Args&&... args) { template <typename T, typename... Args> factory::add<T, Args...>::add(const std::string& name, Args&&... args) {
factory::get_instance().add_object(name, [args...]() -> object { factory::get_instance().add_object(name, [args...]() -> object {

View File

@ -27,8 +27,9 @@ int sc_main(int argc, char* argv[]) {
scc::init_logging(LogConfig().logLevel(getenv("SCC_TEST_VERBOSE") ? log::TRACE : log::FATAL).logAsync(false).msgTypeFieldWidth(35)); scc::init_logging(LogConfig().logLevel(getenv("SCC_TEST_VERBOSE") ? log::TRACE : log::FATAL).logAsync(false).msgTypeFieldWidth(35));
// create tracer if environment variable SCC_TEST_TRACE is defined // create tracer if environment variable SCC_TEST_TRACE is defined
std::unique_ptr<scc::tracer> tracer; std::unique_ptr<scc::tracer> tracer;
if(getenv("SCC_TEST_TRACE")) if(auto* test_trace = getenv("SCC_TEST_TRACE")) {
tracer = std::make_unique<scc::tracer>(my_name, scc::tracer::NONE, scc::tracer::ENABLE); tracer = std::make_unique<scc::tracer>(my_name, scc::tracer::ENABLE, scc::tracer::ENABLE);
}
int result = -1; int result = -1;
if(setjmp(abrt) == 0) { if(setjmp(abrt) == 0) {
// instantiate design(s) // instantiate design(s)
@ -37,6 +38,7 @@ int sc_main(int argc, char* argv[]) {
result = Catch::Session().run(argc, argv); result = Catch::Session().run(argc, argv);
// destroy design(s) // destroy design(s)
sc_stop(); sc_stop();
SCCTRACE() << "Test sequence finished";
factory::get_instance().destroy(); factory::get_instance().destroy();
} }
return result; return result;

View File

@ -1,11 +1,14 @@
add_subdirectory(io-redirector) add_subdirectory(io-redirector)
add_subdirectory(ordered_semaphore) add_subdirectory(ordered_semaphore)
add_subdirectory(cci_param_restricted) add_subdirectory(cci_param_restricted)
add_subdirectory(apb_pin_level)
add_subdirectory(ahb_pin_level) add_subdirectory(ahb_pin_level)
add_subdirectory(axi4_pin_level) add_subdirectory(axi4_pin_level)
add_subdirectory(ace_pin_level) add_subdirectory(ace_pin_level)
add_subdirectory(configuration) add_subdirectory(configuration)
add_subdirectory(configurer) add_subdirectory(configurer)
add_subdirectory(sc_fixed_tracing)
add_subdirectory(cxs_tlm)
if(FULL_TEST_SUITE) if(FULL_TEST_SUITE)
add_subdirectory(sim_performance) add_subdirectory(sim_performance)
endif() endif()

View File

@ -0,0 +1,9 @@
project (apb_pin_level)
add_executable(${PROJECT_NAME}
bus_test.cpp
${test_util_SOURCE_DIR}/sc_main.cpp
)
target_link_libraries (${PROJECT_NAME} PUBLIC test_util)
catch_discover_tests(${PROJECT_NAME})

View File

@ -0,0 +1,255 @@
#include "testbench.h"
#include <factory.h>
#include <tlm/scc/tlm_gp_shared.h>
#undef CHECK
#include <catch2/catch_all.hpp>
#include <unordered_map>
using namespace sc_core;
using namespace ahb;
factory::add<testbench> tb;
bool is_equal(tlm::tlm_generic_payload const& a, tlm::tlm_generic_payload const& b) {
auto ret = true;
ret &= a.get_command() == b.get_command();
ret &= a.get_address() == b.get_address();
ret &= a.get_data_length() == b.get_data_length();
for(auto i = 0u; i < a.get_data_length(); ++i)
ret &= a.get_data_ptr()[i] == b.get_data_ptr()[i];
// if(a.get_byte_enable_ptr() && b.get_byte_enable_ptr()) {
// ret &= a.get_byte_enable_length() == b.get_byte_enable_length();
// for(auto i=0u; i<a.get_byte_enable_length(); ++i)
// ret &= a.get_byte_enable_ptr()[i] == b.get_byte_enable_ptr()[i];
// }
ret &= a.get_command() == b.get_command();
// if(!ret) SCCWARN()<<"Comparison failed: "<<a<<" and "<<b;
return ret;
}
template <unsigned BUSWIDTH> tlm::tlm_generic_payload* prepare_trans(uint64_t start_address, unsigned len, unsigned width) {
static unsigned id{0};
auto trans = tlm::scc::tlm_mm<>::get().allocate<apb::apb_extension>(len);
trans->set_address(start_address);
tlm::scc::setId(*trans, ++id);
auto ext = trans->get_extension<apb::apb_extension>();
trans->set_data_length(len);
trans->set_streaming_width(len);
ext->set_instruction();
return trans;
}
inline void randomize(tlm::tlm_generic_payload& gp) {
static uint8_t req_cnt{0};
for(size_t i = 0; i < gp.get_data_length(); ++i) {
*(gp.get_data_ptr() + i) = i % 2 ? i : req_cnt;
}
req_cnt++;
}
template <typename STATE> unsigned run_scenario(STATE& state, unsigned wait_states = 0) {
auto& dut = factory::get<testbench>();
dut.register_b_transport([&state, wait_states](tlm::tlm_base_protocol_types::tlm_payload_type& trans, sc_core::sc_time& d) {
if(trans.is_read()) {
for(size_t i = 0; i < trans.get_data_length(); ++i) {
*(trans.get_data_ptr() + i) = i % 2 ? i : (state.resp_cnt + 128);
}
state.read_tx.second.emplace_back(&trans);
}
if(trans.is_write())
state.write_tx.second.emplace_back(&trans);
SCCDEBUG(__FUNCTION__) << "RX: " << trans;
for(unsigned i = 0; i < wait_states; ++i)
sc_core::wait(factory::get<testbench>().clk.posedge_event());
state.resp_cnt++;
trans.set_response_status(tlm::TLM_OK_RESPONSE);
});
dut.rst_n.write(false);
sc_start(state.ResetCycles * dut.clk.period());
dut.rst_n.write(true);
sc_start(dut.clk.period());
sc_start(dut.clk.period());
auto run1 = sc_spawn([&dut, &state]() {
unsigned int StartAddr{0x0};
for(int i = 0; i < state.NumberOfIterations; ++i) {
tlm::scc::tlm_gp_shared_ptr trans =
prepare_trans<testbench::DATA_WIDTH>(StartAddr, state.BurstLengthByte, state.BurstSizeBytes);
trans->set_command(tlm::TLM_READ_COMMAND);
SCCDEBUG(__FUNCTION__) << "task run1, iteration " << i << " TX: " << *trans;
sc_core::sc_time d;
dut.isck->b_transport(*trans, d);
state.read_tx.first.emplace_back(trans);
StartAddr += state.BurstSizeBytes;
}
SCCDEBUG(__FUNCTION__) << "task run1 finished";
});
auto run2 = sc_spawn([&dut, &state]() {
unsigned int StartAddr{0x2000};
for(int i = 0; i < state.NumberOfIterations; ++i) {
tlm::scc::tlm_gp_shared_ptr trans =
prepare_trans<testbench::DATA_WIDTH>(StartAddr, state.BurstLengthByte, state.BurstSizeBytes);
trans->set_command(tlm::TLM_WRITE_COMMAND);
randomize(*trans);
SCCDEBUG(__FUNCTION__) << "task run2, iteration " << i << " TX: " << *trans;
sc_core::sc_time d;
dut.isck->b_transport(*trans, d);
state.write_tx.first.emplace_back(trans);
StartAddr += state.BurstSizeBytes;
}
SCCDEBUG(__FUNCTION__) << "task run2 finished";
});
auto run3 = sc_spawn([&dut, &state]() {
unsigned int StartAddr{0x1000};
for(int i = 0; i < state.NumberOfIterations; ++i) {
tlm::scc::tlm_gp_shared_ptr trans =
prepare_trans<testbench::DATA_WIDTH>(StartAddr, state.BurstLengthByte, state.BurstSizeBytes);
trans->set_command(tlm::TLM_READ_COMMAND);
SCCDEBUG(__FUNCTION__) << "task run3, iteration " << i << " TX: " << *trans;
sc_core::sc_time d;
dut.isck->b_transport(*trans, d);
state.read_tx.first.emplace_back(trans);
StartAddr += state.BurstSizeBytes;
}
SCCDEBUG(__FUNCTION__) << "task run3 finished";
});
auto run4 = sc_spawn([&dut, &state]() {
unsigned int StartAddr{0x3000};
for(int i = 0; i < state.NumberOfIterations; ++i) {
tlm::scc::tlm_gp_shared_ptr trans =
prepare_trans<testbench::DATA_WIDTH>(StartAddr, state.BurstLengthByte, state.BurstSizeBytes);
trans->set_command(tlm::TLM_WRITE_COMMAND);
randomize(*trans);
SCCDEBUG(__FUNCTION__) << "task run4, iteration " << i << " TX: " << *trans;
sc_core::sc_time d;
dut.isck->b_transport(*trans, d);
state.write_tx.first.emplace_back(trans);
StartAddr += state.BurstSizeBytes;
}
SCCDEBUG(__FUNCTION__) << "task run4 finished";
});
unsigned cycles{0};
while(cycles < 1000 && !(run1.terminated() && run2.terminated() && run3.terminated() && run4.terminated())) {
sc_start(10 * dut.clk.period());
cycles += 10;
}
return cycles;
}
TEST_CASE("apb_read_write", "[APB][pin-level]") {
struct {
unsigned int ResetCycles{4};
unsigned int BurstLengthByte{4};
unsigned int BurstSizeBytes{4};
unsigned int NumberOfIterations{1};
std::pair<std::vector<tlm::scc::tlm_gp_shared_ptr>, std::vector<tlm::scc::tlm_gp_shared_ptr>> read_tx;
std::pair<std::vector<tlm::scc::tlm_gp_shared_ptr>, std::vector<tlm::scc::tlm_gp_shared_ptr>> write_tx;
unsigned resp_cnt{0};
} state;
auto cycles = run_scenario(state);
REQUIRE(cycles < 1000);
REQUIRE(sc_report_handler::get_count(SC_ERROR) == 0);
REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0);
REQUIRE(state.resp_cnt == 4 * state.NumberOfIterations);
{
auto& e = state.write_tx;
auto const& send_tx = e.first;
auto const& recv_tx = e.second;
REQUIRE(send_tx.size() == recv_tx.size());
for(auto i = 0; i < send_tx.size(); ++i) {
REQUIRE(send_tx[i]->get_response_status() == tlm::TLM_OK_RESPONSE);
CHECK(is_equal(*send_tx[i], *recv_tx[i]));
}
}
{
auto& e = state.read_tx;
auto const& send_tx = e.first;
auto const& recv_tx = e.second;
REQUIRE(send_tx.size() == recv_tx.size());
for(auto i = 0; i < send_tx.size(); ++i) {
REQUIRE(send_tx[i]->get_response_status() == tlm::TLM_OK_RESPONSE);
CHECK(is_equal(*send_tx[i], *recv_tx[i]));
}
}
}
TEST_CASE("apb_narrow_read_write", "[APB][pin-level]") {
struct {
unsigned int ResetCycles{4};
unsigned int BurstLengthByte{1};
unsigned int BurstSizeBytes{1};
unsigned int NumberOfIterations{8};
std::pair<std::vector<tlm::scc::tlm_gp_shared_ptr>, std::vector<tlm::scc::tlm_gp_shared_ptr>> read_tx;
std::pair<std::vector<tlm::scc::tlm_gp_shared_ptr>, std::vector<tlm::scc::tlm_gp_shared_ptr>> write_tx;
unsigned resp_cnt{0};
} state;
auto cycles = run_scenario(state);
REQUIRE(cycles < 1000);
REQUIRE(sc_report_handler::get_count(SC_ERROR) == 0);
REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0);
REQUIRE(state.resp_cnt == 4 * state.NumberOfIterations);
{
auto& e = state.write_tx;
auto const& send_tx = e.first;
auto const& recv_tx = e.second;
REQUIRE(send_tx.size() == recv_tx.size());
for(auto i = 0; i < send_tx.size(); ++i)
CHECK(is_equal(*send_tx[i], *recv_tx[i]));
}
{
auto& e = state.read_tx;
auto const& send_tx = e.first;
auto const& recv_tx = e.second;
REQUIRE(send_tx.size() == recv_tx.size());
// Narrow reads cannot be checked as they arrive a word read at the target
// for(auto i = 0; i < send_tx.size(); ++i)
// CHECK(is_equal(*send_tx[i], *recv_tx[i]));
}
}
TEST_CASE("apb_delayed_read_write", "[APB][pin-level]") {
struct {
unsigned int ResetCycles{4};
unsigned int BurstLengthByte{4};
unsigned int BurstSizeBytes{4};
unsigned int NumberOfIterations{2};
std::pair<std::vector<tlm::scc::tlm_gp_shared_ptr>, std::vector<tlm::scc::tlm_gp_shared_ptr>> read_tx;
std::pair<std::vector<tlm::scc::tlm_gp_shared_ptr>, std::vector<tlm::scc::tlm_gp_shared_ptr>> write_tx;
unsigned resp_cnt{0};
} state;
auto cycles = run_scenario(state, 2);
REQUIRE(cycles < 1000);
REQUIRE(sc_report_handler::get_count(SC_ERROR) == 0);
REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0);
REQUIRE(state.resp_cnt == 4 * state.NumberOfIterations);
{
auto& e = state.write_tx;
auto const& send_tx = e.first;
auto const& recv_tx = e.second;
REQUIRE(send_tx.size() == recv_tx.size());
for(auto i = 0; i < send_tx.size(); ++i) {
REQUIRE(send_tx[i]->get_response_status() == tlm::TLM_OK_RESPONSE);
CHECK(is_equal(*send_tx[i], *recv_tx[i]));
}
}
{
auto& e = state.read_tx;
auto const& send_tx = e.first;
auto const& recv_tx = e.second;
REQUIRE(send_tx.size() == recv_tx.size());
for(auto i = 0; i < send_tx.size(); ++i) {
REQUIRE(send_tx[i]->get_response_status() == tlm::TLM_OK_RESPONSE);
CHECK(is_equal(*send_tx[i], *recv_tx[i]));
}
}
}

View File

@ -0,0 +1,89 @@
#ifndef _TESTBENCH_H_
#define _TESTBENCH_H_
#include <apb/pin/initiator.h>
#include <apb/pin/target.h>
#include <scc.h>
using namespace sc_core;
class testbench : public sc_core::sc_module {
public:
enum { DATA_WIDTH = 32, ADDR_WIDTH = 32 };
using addr_t = typename apb::pin::initiator<DATA_WIDTH, ADDR_WIDTH>::addr_t;
using data_t = apb::pin::initiator<DATA_WIDTH, ADDR_WIDTH>::data_t;
using strb_t = sc_dt::sc_uint<DATA_WIDTH / 8>;
sc_core::sc_time clk_period{10, sc_core::SC_NS};
sc_core::sc_clock clk{"clk", clk_period, 0.5, sc_core::SC_ZERO_TIME, true};
sc_core::sc_signal<bool> rst_n{"rst_n"};
// initiator side
tlm::scc::initiator_mixin<tlm::tlm_initiator_socket<DATA_WIDTH>> isck{"isck"};
apb::pin::initiator<DATA_WIDTH, ADDR_WIDTH> intor_bfm{"intor_bfm"};
// signal accurate bus
sc_core::sc_signal<addr_t> PADDR{"PADDR"};
sc_core::sc_signal<sc_dt::sc_uint<3>> PPROT{"PPROT"};
sc_core::sc_signal<bool> PNSE{"PNSE"};
sc_core::sc_signal<bool> PSELx{"PSELx"};
sc_core::sc_signal<bool> PENABLE{"PENABLE"};
sc_core::sc_signal<bool> PWRITE{"PWRITE"};
sc_core::sc_signal<data_t> PWDATA{"PWDATA"};
sc_core::sc_signal<strb_t> PSTRB{"PSTRB"};
sc_core::sc_signal<bool> PREADY{"PREADY"};
sc_core::sc_signal<data_t> PRDATA{"PRDATA"};
sc_core::sc_signal<bool> PSLVERR{"PSLVERR"};
sc_core::sc_signal<bool> PWAKEUP{"PWAKEUP"};
// target side
apb::pin::target<DATA_WIDTH, ADDR_WIDTH> tgt_bfm{"tgt_bfm"};
tlm::scc::target_mixin<tlm::tlm_target_socket<scc::LT>> tsck{"tsck"};
public:
SC_HAS_PROCESS(testbench);
testbench()
: testbench("testbench") {}
testbench(sc_core::sc_module_name nm)
: sc_core::sc_module(nm) {
intor_bfm.PCLK_i(clk);
tgt_bfm.PCLK_i(clk);
// bfm to signals
isck(intor_bfm.tsckt);
intor_bfm.PRESETn_i(rst_n);
intor_bfm.PADDR_o(PADDR);
intor_bfm.PPROT_o(PPROT);
intor_bfm.PNSE_o(PNSE);
intor_bfm.PSELx_o(PSELx);
intor_bfm.PENABLE_o(PENABLE);
intor_bfm.PWRITE_o(PWRITE);
intor_bfm.PWDATA_o(PWDATA);
intor_bfm.PSTRB_o(PSTRB);
intor_bfm.PREADY_i(PREADY);
intor_bfm.PRDATA_i(PRDATA);
intor_bfm.PSLVERR_i(PSLVERR);
intor_bfm.PWAKEUP_o(PWAKEUP);
tgt_bfm.PRESETn_i(rst_n);
tgt_bfm.PADDR_i(PADDR);
tgt_bfm.PPROT_i(PPROT);
tgt_bfm.PNSE_i(PNSE);
tgt_bfm.PSELx_i(PSELx);
tgt_bfm.PENABLE_i(PENABLE);
tgt_bfm.PWRITE_i(PWRITE);
tgt_bfm.PWDATA_i(PWDATA);
tgt_bfm.PSTRB_i(PSTRB);
tgt_bfm.PREADY_o(PREADY);
tgt_bfm.PRDATA_o(PRDATA);
tgt_bfm.PSLVERR_o(PSLVERR);
tgt_bfm.PWAKEUP_i(PWAKEUP);
tgt_bfm.isckt(tsck);
tsck.register_b_transport([this](tlm::tlm_base_protocol_types::tlm_payload_type& trans, sc_core::sc_time& d) {
if(cb_delegate)
cb_delegate(trans, d);
});
}
void run1() {}
void register_b_transport(std::function<void(tlm::tlm_generic_payload&, sc_core::sc_time&)> cb) { cb_delegate = cb; }
std::function<void(tlm::tlm_generic_payload&, sc_core::sc_time&)> cb_delegate;
};
#endif // _TESTBENCH_H_

View File

@ -150,7 +150,7 @@ void axi4_burst_alignment(bool pipelined_wrreq, bool write_bp) {
auto& dut = factory::get<testbench>(); auto& dut = factory::get<testbench>();
dut.intor_bfm.pipelined_wrreq = pipelined_wrreq; dut.intor_bfm.pipelined_wrreq = pipelined_wrreq;
dut.tgt_pe.wr_data_accept_delay.value = write_bp ? 1 : 0; dut.tgt_pe.wr_data_accept_delay.set_value(write_bp ? 1 : 0);
auto cycles = run_scenario(state); auto cycles = run_scenario(state);
REQUIRE(cycles < 1000); REQUIRE(cycles < 1000);
@ -192,7 +192,7 @@ void axi4_narrow_burst(bool pipelined_wrreq, bool write_bp) {
auto& dut = factory::get<testbench>(); auto& dut = factory::get<testbench>();
dut.intor_bfm.pipelined_wrreq = pipelined_wrreq; dut.intor_bfm.pipelined_wrreq = pipelined_wrreq;
dut.tgt_pe.wr_data_accept_delay.value = write_bp ? 1 : 0; dut.tgt_pe.wr_data_accept_delay.set_value(write_bp ? 1 : 0);
auto cycles = run_scenario(state); auto cycles = run_scenario(state);
REQUIRE(cycles < 1000); REQUIRE(cycles < 1000);

View File

@ -33,7 +33,6 @@
#include "top_module.h" #include "top_module.h"
#include <cci_configuration> #include <cci_configuration>
#include <cci_utils/broker.h>
#include <string> #include <string>
/** /**

View File

@ -0,0 +1,8 @@
project (cxs_tlm)
add_executable(${PROJECT_NAME}
csx_packet_test.cpp
${test_util_SOURCE_DIR}/sc_main.cpp
)
target_link_libraries (${PROJECT_NAME} PUBLIC scc::busses test_util)
catch_discover_tests(${PROJECT_NAME})

View File

@ -0,0 +1,171 @@
#include "testbench.h"
#include <factory.h>
#include <tlm/scc/tlm_gp_shared.h>
#undef CHECK
#include <catch2/catch_all.hpp>
#include <deque>
#include <unordered_map>
using namespace sc_core;
namespace cxs {
factory::add<testbench<256>> tb8;
factory::add<testbench<512>> tb9;
factory::add<testbench<1024>> tb10;
template <unsigned WIDTH, typename STATE> unsigned run_scenario(STATE& state, unsigned burst_factor = 0) {
auto& dut = factory::get<testbench<WIDTH>>();
if(burst_factor)
dut.tx.burst_len.set_value(burst_factor);
dut.rst.write(true);
sc_start(state.reset_cycles * dut.clk.period());
dut.rst.write(false);
sc_start(dut.clk.period());
auto run1 = sc_spawn([&dut, &state]() {
auto burst_cnt{0};
std::deque<cxs_pkt_shared_ptr> expected_pkt;
for(auto size : state.packet_sizes) {
cxs_pkt_shared_ptr tx_pkt = cxs_pkt_mm::get().allocate();
tx_pkt->get_data().resize(size);
SCCDEBUG("run_scenario") << "Transmitting packet with size " << size;
auto phase{tlm::nw::REQUEST};
sc_core::sc_time t = sc_core::SC_ZERO_TIME;
auto status = dut.isck->nb_transport_fw(*tx_pkt, phase, t);
expected_pkt.emplace_back(tx_pkt);
tx_pkt = nullptr;
REQUIRE(status == tlm::TLM_UPDATED);
REQUIRE(phase == tlm::nw::CONFIRM);
if(++burst_cnt == state.granularity) {
auto rec_cnt = 0u;
while(rec_cnt < burst_cnt) {
::sc_core::wait(dut.recv.data_written_event());
while(!dut.recv.empty()) {
auto recv_pkt = dut.recv.front();
dut.recv.pop_front();
tx_pkt = expected_pkt.front();
expected_pkt.pop_front();
REQUIRE(tx_pkt == recv_pkt);
REQUIRE(recv_pkt->get_data().size() == state.packet_sizes[state.resp_cnt]);
state.resp_cnt++;
rec_cnt++;
SCCDEBUG("run_scenario") << "Received packet with size " << recv_pkt->get_data().size()
<< ", total number of packets is " << state.resp_cnt;
}
}
burst_cnt = 0;
}
}
});
unsigned cycles{0};
while(cycles < state.max_cycles && !(run1.terminated())) {
// while(cycles<1000 && !(run5.terminated())){
sc_start(10 * dut.clk.period());
cycles += 10;
}
return cycles;
}
template <typename STATE> unsigned run_scenario(int width, STATE& state, unsigned burst_factor = 0) {
switch(width) {
case 8:
case 256:
return run_scenario<256>(state);
case 9:
case 512:
return run_scenario<512>(state);
case 10:
case 1024:
return run_scenario<1024>(state);
}
return 0;
}
TEST_CASE("single-packet", "[CXS][tlm-level]") {
struct {
unsigned int reset_cycles{4};
unsigned int max_cycles = 5000;
std::vector<unsigned int> packet_sizes;
unsigned granularity{1};
unsigned resp_cnt{0};
} state;
state.packet_sizes.assign({4, 8, 16, 32, 64, 128, 256, 1024});
for(auto width = 8; width < 11; ++width) {
state.resp_cnt = 0;
auto cycles = run_scenario(width, state);
REQUIRE(cycles < state.max_cycles);
REQUIRE(sc_report_handler::get_count(SC_ERROR) == 0);
REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0);
REQUIRE(state.resp_cnt == state.packet_sizes.size());
}
}
TEST_CASE("multi-packet", "[CXS][tlm-level]") {
struct {
unsigned int reset_cycles{4};
unsigned int max_cycles = 5000;
std::vector<unsigned int> packet_sizes;
unsigned granularity{2};
unsigned resp_cnt{0};
} state;
state.packet_sizes.assign({4, 8, 16, 32, 16, 64, 16, 128, 16, 256, 16, 1024});
for(auto width = 8; width < 11; ++width) {
state.resp_cnt = 0;
auto cycles = run_scenario(width, state);
REQUIRE(cycles < state.max_cycles);
REQUIRE(sc_report_handler::get_count(SC_ERROR) == 0);
REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0);
REQUIRE(state.resp_cnt == state.packet_sizes.size());
}
}
TEST_CASE("single-packet-burst2", "[CXS][tlm-level]") {
struct {
unsigned int reset_cycles{4};
unsigned int max_cycles = 5000;
std::vector<unsigned int> packet_sizes;
unsigned granularity{1};
unsigned resp_cnt{0};
} state;
state.packet_sizes.assign({4, 8, 16, 32, 64, 128, 256, 1024});
for(auto width = 8; width < 11; ++width) {
state.resp_cnt = 0;
auto cycles = run_scenario(width, state, 2);
REQUIRE(cycles < state.max_cycles);
REQUIRE(sc_report_handler::get_count(SC_ERROR) == 0);
REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0);
REQUIRE(state.resp_cnt == state.packet_sizes.size());
}
}
TEST_CASE("multi-packet-burst2", "[CXS][tlm-level]") {
struct {
unsigned int reset_cycles{4};
unsigned int max_cycles = 5000;
std::vector<unsigned int> packet_sizes;
unsigned granularity{2};
unsigned resp_cnt{0};
} state;
state.packet_sizes.assign({4, 8, 16, 32, 16, 64, 16, 128, 16, 256, 16, 1024});
for(auto width = 8; width < 11; ++width) {
state.resp_cnt = 0;
auto cycles = run_scenario(width, state, 2);
REQUIRE(cycles < state.max_cycles);
REQUIRE(sc_report_handler::get_count(SC_ERROR) == 0);
REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0);
REQUIRE(state.resp_cnt == state.packet_sizes.size());
}
}
} // namespace cxs

77
tests/cxs_tlm/testbench.h Normal file
View File

@ -0,0 +1,77 @@
#ifndef _TESTBENCH_H_
#define _TESTBENCH_H_
#include <cxs/cxs_tlm.h>
#include <scc/cci_util.h>
#include <scc/configurer.h>
#include <scc/observer.h>
#include <scc/sc_variable.h>
#include <scc/tracer.h>
#include <string>
#include <systemc>
#include <tlm/nw/initiator_mixin.h>
#include <tlm/nw/target_mixin.h>
using namespace sc_core;
using namespace sc_dt;
using namespace std;
namespace cxs {
const char* sc_gen_unique_name(const char*, bool preserve_first);
template <unsigned PHIT_WIDTH> struct testbench : public sc_core::sc_module {
using transaction_type = cxs_packet_types::tlm_payload_type;
using phase_type = cxs_packet_types::tlm_phase_type;
sc_core::sc_clock clk{"clk", 1_ns};
sc_core::sc_signal<bool> rst{"rst"};
tlm::nw::initiator_mixin<cxs_pkt_initiator_socket<>, cxs_packet_types> isck{"isck"};
cxs_transmitter<PHIT_WIDTH> tx{"tx"};
cxs_channel<PHIT_WIDTH> cxs_chan{"cxs_chan"};
cxs_receiver<PHIT_WIDTH> rx{"rx"};
tlm::nw::target_mixin<cxs_pkt_target_socket<>, cxs_packet_types> tsck{"tsck"};
testbench()
: testbench(sc_core::sc_gen_unique_name("testbench", false)) {}
testbench(sc_core::sc_module_name const& nm)
: sc_module(nm) {
isck.register_nb_transport_bw(
[this](transaction_type& trans, phase_type& phase, sc_core::sc_time& t) { return this->nb_transport_fw(trans, phase, t); });
tsck.register_nb_transport_fw(
[this](transaction_type& trans, phase_type& phase, sc_core::sc_time& t) { return this->nb_transport_fw(trans, phase, t); });
isck(tx.tsck);
tx.clk_i(clk);
tx.rst_i(rst);
tx.isck(cxs_chan.tsck);
cxs_chan.isck(rx.tsck);
rx.clk_i(clk);
rx.rst_i(rst);
rx.isck(tsck);
cxs_chan.channel_delay.set_value(100_ns);
rx.max_credit.set_value(15);
}
tlm::tlm_sync_enum nb_transport_fw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) {
if(phase == tlm::nw::REQUEST) {
SCCINFO(SCMOD) << "Received non-blocking transaction with phase " << phase.get_name();
recv.push_back(&trans);
phase = tlm::nw::CONFIRM;
return tlm::TLM_UPDATED;
}
throw std::runtime_error("illegal request in forward path");
}
tlm::tlm_sync_enum nb_transport_bw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) {
if(phase == tlm::nw::CONFIRM) {
confirmation_evt.notify(sc_core::SC_ZERO_TIME);
return tlm::TLM_ACCEPTED;
}
throw std::runtime_error("illegal response in backward path");
}
sc_core::sc_event confirmation_evt;
scc::fifo_w_cb<cxs_pkt_shared_ptr> recv;
};
} // namespace cxs
#endif // _TESTBENCH_H_

View File

@ -0,0 +1,3 @@
add_executable (sc_fixed_tracing sc_main.cpp)
target_link_libraries (sc_fixed_tracing LINK_PUBLIC scc-sysc)
add_test(NAME sc_fixed_tracing_test COMMAND sc_fixed_tracing )

View File

@ -0,0 +1,82 @@
#define SC_INCLUDE_FX
#include <scc/cci_util.h>
#include <scc/configurer.h>
#include <scc/observer.h>
#include <scc/sc_variable.h>
#include <scc/tracer.h>
#include <string>
#include <systemc>
using namespace sc_dt;
using namespace std;
struct testbench : public sc_core::sc_module {
scc::sc_variable<sc_dt::sc_fixed<6, 4>> a{"a", sc_dt::sc_fixed<6, 4>()};
scc::sc_variable<sc_fixed<4, 2, SC_RND, SC_SAT>> b_sc_sat{"b_sc_sat", 0};
scc::sc_variable<sc_fixed<8, 3>> a_qant{"a_qant", 0};
scc::sc_variable<sc_fixed<5, 3, SC_RND>> b_sc_rnd{"b_sc_rnd", 0};
scc::sc_variable<sc_fixed<5, 3, SC_TRN>> b_sc_trn{"b_sc_trn", 0};
sc_fixed<5, 3> a_fixed;
sc_dt::sc_fix a_fix{5, 3};
sc_fxtype_params params{5, 4};
sc_fxtype_context context{params};
// becase we do not specify in b_fix constructor anything
// the parameters are taken form the latest created context
sc_fix b_fix;
sc_fix c_fix{5, 3};
testbench(sc_core::sc_module_name const& nm)
: sc_module(nm) {
SC_HAS_PROCESS(testbench);
SC_THREAD(run);
}
void trace(sc_core::sc_trace_file* trf) const override {
a.trace(trf);
scc::sc_trace(trf, a_fixed, std::string(name()) + ".a_fixed");
scc::sc_trace(trf, a_fix, std::string(name()) + ".a_fix");
scc::sc_trace(trf, b_fix, std::string(name()) + ".b_fix");
scc::sc_trace(trf, c_fix, std::string(name()) + ".c_fix");
}
void run() {
wait(1_ns);
init();
wait(1_ns);
test_overflow_modes();
wait(1_ns);
test_quantization_modes();
wait(1_ns);
this->a = 2;
wait(1_ps);
sc_core::sc_stop();
}
void init() {
a_fixed = 1.75;
a_fix = 1.75;
b_fix = 1.75;
c_fix = 1.75;
}
void test_overflow_modes() {
a = -7;
b_sc_sat = *a;
}
void test_quantization_modes() {
a_qant = -2.3125;
b_sc_rnd = *a_qant;
b_sc_trn = *a_qant;
}
};
int sc_main(int sc_argc, char* sc_argv[]) {
scc::init_logging(scc::log::INFO);
scc::configurer cfg("");
scc::tracer trc("sc_fixed_tracing");
testbench tb("tb");
sc_core::sc_start();
SCCINFO("sc_main") << "End Simulation.";
return sc_core::sc_report_handler::get_count(sc_core::SC_ERROR) + sc_core::sc_report_handler::get_count(sc_core::SC_WARNING);
} // End of 'sc_main'