Compare commits

83 Commits

Author SHA1 Message Date
c684bbf891 Merge branch 'develop' 2025-01-10 07:59:24 +01:00
ea802247da adds AXI4/ACEL unaligned addr burst tests 2025-01-09 10:34:32 +01:00
5490f0203f updates scc 2025-01-06 12:40:29 +01:00
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
e91e5de6ab Merge branch 'develop' into main 2024-06-04 10:20:31 +02:00
53ed979fa3 updates scc 2024-06-04 10:19:42 +02:00
c30656841c Merge branch 'develop' into main 2024-06-04 10:14:01 +02:00
1e7f9cfc22 updates boost, Rocky8 setup and scc 2024-06-04 10:09:24 +02:00
892554f1f3 updates scc 2024-05-08 21:03:18 +02:00
c929dcb5ea adds pipelining of wr req to AXI/ACE pinlevel adapters 2024-05-08 17:20:38 +02:00
f8bd40cd60 adds error catching code to close databases properly 2024-05-08 17:19:37 +02:00
f82c3ce229 adds namespaced CCI enum test 2024-05-07 12:29:07 +02:00
904d897773 adds test for CCI enum macro 2024-05-07 11:02:40 +02:00
aff456d6f4 adds missed format fix 2024-05-03 22:46:53 +02:00
f639576ac0 adds simple configurer test 2024-05-03 22:14:29 +02:00
0992cefeb8 changes Jenkins step name 2024-04-06 12:50:52 +02:00
3a8a675bfd updates scc 2024-04-06 12:45:28 +02:00
775cacf2b5 extends cci_param_restricted tests 2024-04-06 10:45:08 +02:00
c6167118d5 adds additional tests 2024-04-05 08:42:10 +02:00
f4506a064b adds vscode setup 2024-04-05 08:41:47 +02:00
90002786a4 fixes wrong expectation 2024-04-04 22:41:37 +02:00
d7ce4b9a8e update scc 2024-04-04 22:34:42 +02:00
e27b33947b adds test for restricted cci_params 2024-04-04 22:19:43 +02:00
7f508b1006 adds build status 2023-12-23 14:03:24 +01:00
c0a95d0a57 adds format-check to Jenkins 2023-12-22 22:54:40 +01:00
1a7d7829ed removes ubuntu 18.04 test 2023-12-22 22:35:08 +01:00
7bad0c3381 fixes Jenkins setup 2023-12-22 22:30:19 +01:00
1d8120b43b adds missing jenkins function 2023-12-22 22:23:40 +01:00
cd6100bd47 Merge remote-tracking branch 'origin/main' into develop 2023-12-22 22:20:27 +01:00
5b5feb51f5 adds Jenkinsfile 2023-12-22 21:43:12 +01:00
b9c9e15166 applies cklang-tidy fixes 2023-12-22 20:42:21 +01:00
288f0577f1 updates setup and scc 2023-12-22 13:48:46 +01:00
1f37801f05 adds AHB pin level adapter tests 2023-12-22 09:52:50 +01:00
6ecd234c2c Merge branch 'develop' of https://git.minres.com/SystemC/SystemC-Components-Test into develop 2023-11-10 19:42:55 +01:00
6c07dd99ff extends .cproject settings 2023-11-10 19:42:49 +01:00
f83e61aa1f updates ace_pin_level testcase with cacheline and scc 2023-10-05 15:36:33 +02:00
e30a569cfa updates ace_pin_level testcase with snoop and updates scc 2023-10-04 22:17:38 +02:00
50bd12b4ec add ace_pin_level testcase and update scc 2023-09-29 12:31:00 +02:00
3f97fcc28c update submodule scc 2023-09-26 22:13:36 +02:00
972eb6b001 updates README 2023-09-07 17:43:30 +02:00
c445c1cda1 updating the tests to the latest scc 2022-08-23 08:56:05 +02:00
19580227a9 update scc lib 2022-08-19 12:12:24 +02:00
af670d7004 update scc and eclipse settings 2022-08-19 12:05:30 +02:00
56be3388a3 Merge branch 'master' of https://git.minres.com/SystemC/SystemC-Components-Test 2021-11-21 18:11:19 +01:00
1e71d4c9d2 added tests for further performance increasing analysis 2021-11-21 18:07:27 +01:00
95faedd3d0 b2 and ZLIB libs from conan for CentOS7 2021-11-16 16:15:51 +01:00
8895fa0c26 Check if SystemC_INCLUDE_DIR is already set 2021-11-16 13:40:35 +01:00
238bb2f23c Conan integration in CMake 2021-11-16 13:03:15 +01:00
ecf44871b7 changed tests for benchmark this is the baseline version 2021-07-27 20:25:54 +02:00
f58a58d465 correction of sim_performance names 2021-07-23 13:57:42 +02:00
27ecf48ac0 Merge branch 'develop' 2021-07-23 13:49:10 +02:00
66ca4222e0 Correction of readme.md 2021-07-05 12:30:39 +02:00
c0d0dce683 centos8 conan stdc++11 2021-06-02 12:13:59 +02:00
0535f2e353 link scc-utils 2021-06-02 11:35:34 +02:00
c72b02f99f create Jenkins pipeline 2021-06-02 11:13:19 +02:00
63 changed files with 2887 additions and 630 deletions

View File

@ -1,4 +1,3 @@
---
Language: Cpp
# BasedOnStyle: LLVM
# should be in line with IndentWidth
@ -13,8 +12,8 @@ AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
@ -39,8 +38,8 @@ BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
ColumnLimit: 140
CommentPragmas: '^( IWYU pragma:| @suppress)'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 0
ContinuationIndentWidth: 4
@ -76,13 +75,13 @@ PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceBeforeParens: Never
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false

3
.clang-tidy Normal file
View File

@ -0,0 +1,3 @@
---
Checks: 'clang-diagnostic-*,clang-analyzer-*,clang-diagnostic-*,clang-analyzer-*'
WarningsAsErrors: ''

152
.cproject
View File

@ -10,12 +10,11 @@
<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.CWDLocator" 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" 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">
<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">
<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">
<targetPlatform id="cmake4eclipse.mbs.targetPlatform.cmake.1279728098" name="Any Platform" superClass="cmake4eclipse.mbs.targetPlatform.cmake"/>
@ -29,11 +28,116 @@
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule buildDir="build/${ConfigName}" dirtyTs="1673562408113" moduleId="de.marw.cmake4eclipse.mbs.settings">
<options/>
<storageModule buildDir="build/${ConfigName}" dirtyTs="1733906014591" moduleId="de.marw.cmake4eclipse.mbs.settings">
<options otherArguments="--preset Debug"/>
<defs>
<def name="BUILD_SCC_DOCUMENTATION" type="BOOL" val="OFF"/>
<def name="ENABLE_CLANG_TIDY" type="STRING" val="OFF"/>
</defs>
</storageModule>
</cconfiguration>
<cconfiguration id="cmake4eclipse.mbs.toolchain.cmake.134761605.1785168986">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cmake4eclipse.mbs.toolchain.cmake.134761605.1785168986" moduleId="org.eclipse.cdt.core.settings" name="Release">
<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.1785168986" name="Release" 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.1785168986." name="/" resourcePath="">
<toolChain id="cmake4eclipse.mbs.toolchain.cmake.16485475" name="CMake driven" superClass="cmake4eclipse.mbs.toolchain.cmake">
<targetPlatform id="cmake4eclipse.mbs.targetPlatform.cmake.1713261153" name="Any Platform" superClass="cmake4eclipse.mbs.targetPlatform.cmake"/>
<builder buildPath="/SystemC-Components-Test/build/Debug" id="cmake4eclipse.mbs.builder.322228822" keepEnvironmentInBuildfile="false" name="CMake Builder" superClass="cmake4eclipse.mbs.builder"/>
<tool id="cmake4eclipse.mbs.toolchain.tool.dummy.944613359" name="CMake" superClass="cmake4eclipse.mbs.toolchain.tool.dummy">
<inputType id="cmake4eclipse.mbs.inputType.c.1854920030" superClass="cmake4eclipse.mbs.inputType.c"/>
<inputType id="cmake4eclipse.mbs.inputType.cpp.525905746" superClass="cmake4eclipse.mbs.inputType.cpp"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule buildDir="build/${ConfigName}" dirtyTs="1720252186652" moduleId="de.marw.cmake4eclipse.mbs.settings">
<options otherArguments="--preset Release"/>
<defs>
<def name="BUILD_SCC_DOCUMENTATION" type="BOOL" val="OFF"/>
</defs>
</storageModule>
</cconfiguration>
<cconfiguration id="cmake4eclipse.mbs.toolchain.cmake.134761605.1198783022">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cmake4eclipse.mbs.toolchain.cmake.134761605.1198783022" moduleId="org.eclipse.cdt.core.settings" name="ClangTidy">
<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.1198783022" name="ClangTidy" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.dockerdpath=,org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.connection=ssh://eyck@kraftwerk02:22" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="cmake4eclipse.mbs.toolchain.cmake.134761605.1198783022." name="/" resourcePath="">
<toolChain id="cmake4eclipse.mbs.toolchain.cmake.1529597056" name="CMake driven" superClass="cmake4eclipse.mbs.toolchain.cmake">
<targetPlatform id="cmake4eclipse.mbs.targetPlatform.cmake.157305521" name="Any Platform" superClass="cmake4eclipse.mbs.targetPlatform.cmake"/>
<builder buildPath="/SystemC-Components-Test/build/Debug" id="cmake4eclipse.mbs.builder.407860995" keepEnvironmentInBuildfile="false" name="CMake Builder" superClass="cmake4eclipse.mbs.builder"/>
<tool id="cmake4eclipse.mbs.toolchain.tool.dummy.1269675407" name="CMake" superClass="cmake4eclipse.mbs.toolchain.tool.dummy">
<inputType id="cmake4eclipse.mbs.inputType.c.2145364949" superClass="cmake4eclipse.mbs.inputType.c"/>
<inputType id="cmake4eclipse.mbs.inputType.cpp.143816444" superClass="cmake4eclipse.mbs.inputType.cpp"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule buildDir="build/${ConfigName}" dirtyTs="1720252426316" moduleId="de.marw.cmake4eclipse.mbs.settings">
<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>
<def name="CMAKE_BUILD_TYPE" type="STRING" val="Debug"/>
<def name="BUILD_SCC_DOCUMENTATION" type="BOOL" val="OFF"/>
<def name="ENABLE_CLANG_TIDY" type="STRING" val="OFF"/>
</defs>
</storageModule>
</cconfiguration>
@ -43,21 +147,37 @@
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="ClangTidy">
<resource resourceType="PROJECT" workspacePath="/SystemC-Components-Test"/>
</configuration>
<configuration configurationName="RelWithDebInfo"/>
<configuration configurationName="Default">
<resource resourceType="PROJECT" workspacePath="/SystemC-Components-Test"/>
</configuration>
<configuration configurationName="Debug"/>
<configuration configurationName="Release"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<storageModule cmakelistsFolder="" moduleId="de.marw.cmake4eclipse.mbs.settings">
<targets>
<target name=""/>
</targets>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cmake4eclipse.mbs.toolchain.cmake.134761605;cmake4eclipse.mbs.toolchain.cmake.134761605.1159094612;cmake4eclipse.mbs.toolchain.tool.dummy.326050058;cmake4eclipse.mbs.inputType.cpp.459033018">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cmake4eclipse.mbs.toolchain.cmake.134761605;cmake4eclipse.mbs.toolchain.cmake.134761605.1159094612;cmake4eclipse.mbs.toolchain.tool.dummy.326050058;cmake4eclipse.mbs.inputType.c.1524512146">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cmake4eclipse.mbs.toolchain.cmake.134761605.1198783022;cmake4eclipse.mbs.toolchain.cmake.134761605.1198783022.;cmake4eclipse.mbs.toolchain.tool.dummy.1269675407;cmake4eclipse.mbs.inputType.c.2145364949">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cmake4eclipse.mbs.toolchain.cmake.134761605;cmake4eclipse.mbs.toolchain.cmake.134761605.1159094612;cmake4eclipse.mbs.toolchain.tool.dummy.326050058;cmake4eclipse.mbs.inputType.cpp.459033018">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cmake4eclipse.mbs.toolchain.cmake.134761605.1198783022;cmake4eclipse.mbs.toolchain.cmake.134761605.1198783022.;cmake4eclipse.mbs.toolchain.tool.dummy.1269675407;cmake4eclipse.mbs.inputType.cpp.143816444">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
<buildTargets>
<target name="test" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
@ -68,6 +188,22 @@
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="format" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>$&lt;cmake4eclipse_dyn&gt;</buildArguments>
<buildTarget>format</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="format-check" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>$&lt;cmake4eclipse_dyn&gt;</buildArguments>
<buildTarget>format-check</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
</buildTargets>
</storageModule>
</cproject>

10
.envrc Normal file
View File

@ -0,0 +1,10 @@
module load ./Modulefile
distro=`/bin/lsb_release -i -s`
if [ $distro == "CentOS" ]; then
. /opt/rh/devtoolset-8/enable
. /opt/rh/rh-python38/enable
elif [ $distro == "Rocky" ]; then
. /opt/rh/gcc-toolset-11/enable
fi
layout python3
[ -f .envrc.$USER ] && . .envrc.$USER

8
.gitignore vendored
View File

@ -40,3 +40,11 @@
/*.vcd
/.venv/
/.pydevproject
/*.fst
/*.ftr
/*.gtkw
/.envrc.*
/.direnv/
/.venv/
/.cache
/CMakeUserPresets.json

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "scc"]
path = scc
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

@ -28,6 +28,5 @@
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
<nature>org.python.pydev.pythonNature</nature>
</natures>
</projectDescription>

25
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,25 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [{
"name": "cci_param_restricted",
"type": "cppdbg",
"request": "launch",
"cwd": "${workspaceRoot}",
"program": "${workspaceRoot}/build/tests/cci_param_restricted/cci_param_restricted",
"linux": {
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb"
},
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "CMake: build"
}]
}

16
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,16 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "cmake",
"label": "CMake: build",
"command": "build",
"targets": [
"all"
],
"group": "build",
"problemMatcher": ["$gcc"],
"detail": "CMake template build task",
}
]
}

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_CLANG_TIDY "Enable clang-tidy checks" OFF)
include(ConanInline)
include(GNUInstallDirs)
include(BuildType)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
@ -20,14 +18,6 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
include(CheckCXXCompilerFlag)
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")
set(warnings "-Wall -Wextra -Werror")
set(CMAKE_CXX_FLAG_RELEASE "-O3 -DNDEBUG")
@ -39,32 +29,22 @@ endif()
if(ENABLE_COVERAGE)
include(CodeCoverage)
append_coverage_compiler_flags()
set(COVERAGE_EXCLUDES "osci-lib/scc/*" "/engr/dev/tools/*")
endif()
find_program(CLANG_TIDY_EXE NAMES "clang-tidy-9")
if(ENABLE_CLANG_TIDY)
if(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(CMAKE_CXX_CLANG_TIDY
${CLANG_TIDY_EXE};
-checks=${CLANG_TIDY_CHECKS};
-fix;)
else()
message(AUTHOR_WARNING "clang-tidy not found!")
set(CMAKE_CXX_CLANG_TIDY "" CACHE STRING "" FORCE) # delete it
endif()
find_program(CLANG_TIDY_EXE NAMES "clang-tidy")
if(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(CMAKE_CXX_CLANG_TIDY ${CLANG_TIDY_EXE};-fix)
else()
message(AUTHOR_WARNING "clang-tidy not found!")
set(CMAKE_CXX_CLANG_TIDY "" CACHE STRING "" FORCE) # delete it
endif()
endif()
set(CONAN_CMAKE_SILENT_OUTPUT ON)
conan_check()
conan_configure(REQUIRES fmt/8.0.1 spdlog/1.9.2 boost/1.75.0 gsl-lite/0.37.0 systemc/2.3.3 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()
set(CLANG_FORMAT_EXCLUDE_PATTERNS "/third_party/" "/build/")
find_package(ClangFormat)
find_package(ZLIB)
find_package(lz4)
# 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"
}
}
]
}

101
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,101 @@
def getBranch() {
if (env.BRANCH_NAME != null && !env.BRANCH_NAME.isEmpty() ) {
return env.BRANCH_NAME
} else {
return 'develop'
}
}
void checkout_project() {
checkout([
$class: 'GitSCM',
branches: [
[name: 'refs/heads/' + getBranch()]
],
extensions: [
[$class: 'CleanBeforeCheckout'],
[$class: 'SubmoduleOption',
disableSubmodules: false,
recursiveSubmodules: true,
trackingSubmodules: false,
parentCredentials: true,
shallow: true
]
],
submoduleCfg: [],
userRemoteConfigs: [
[credentialsId: 'gitea-jenkins', url: 'https://git.minres.com/SystemC/SystemC-Components-Test.git']
]
])
}
void build_n_test_project() {
sh'''
python3 -mvenv .venv
. .venv/bin/activate
pip3 install -r requirements.txt
cmake -S . -B build --preset Release
cmake --build build -j12
cmake --build build --target test
'''
}
pipeline {
agent none
options {
// using the Timestamper plugin we can add timestamps to the console log
timestamps()
skipStagesAfterUnstable()
}
stages {
stage('SCC test pipeline') {
parallel {
stage('ubuntu-22.04') {
agent {docker { image 'ubuntu-22.04' } }
stages {
stage('Checkout') { steps { checkout_project() }}
stage('Build & test') { steps { build_n_test_project() }}
}
}
stage('rockylinux8') {
agent {docker { image 'rockylinux8' } }
stages {
stage('Checkout') { steps { checkout_project() }}
stage('Build & test') { steps { build_n_test_project() }}
}
}
stage('Format check') {
agent {docker { image 'ubuntu-22.04' } }
stages {
stage('Checkout') { steps { checkout_project() }}
stage('Build & check format') { steps {
sh'''
python3 -mvenv .venv
. .venv/bin/activate
pip3 install -r requirements.txt
cmake -S . -B build --preset Release
cmake --build build --target format-check
'''
}}
}
}
}
}
}
post {
success {
rocketSend ":thumbsup: SCC test run passed, results at ${env.RUN_DISPLAY_URL} "
}
failure {
rocketSend ":thumbsdown: SCC test failed, please check ${env.RUN_DISPLAY_URL} "
emailext recipientProviders: [culprits(), requestor()],
subject: "SCC Test Pipeline Failed: ${currentBuild.fullDisplayName}",
body: """
<p>Build Status: ${currentBuild.currentResult}</p>
<p> Check logs at <a href='${env.BUILD_URL}console'> Build Console Logs </a> or at <a href='${env.RUN_DISPLAY_URL}'> Overview </a></p>
"""
}
}
}

View File

@ -7,10 +7,11 @@ proc ModulesHelp { } {
puts stderr "\tThis module loads PATHs and variables for SCC tests."
}
set distro [exec /bin/lsb_release -i -s]
set distro [exec /usr/bin/lsb_release -i -s]
if { $distro == "CentOS" && ![info exists ::env(PROJECT)] && ![info exists ::env(PCP_DIR)] } {
puts stderr "Don't forget to execute 'scl enable devtoolset-7 llvm-toolset-7 bash'"
}
module load tools/cmake
module load tools/utilities
module load tools/cmake/3.28
module load tools/clang/14.0

View File

@ -1,50 +1,21 @@
[![Build Status](https://jenkins.minres.com/view/SystemC/job/SCC%20Test/job/develop/badge/icon)](https://jenkins.minres.com/view/SystemC/job/SCC%20Test/job/develop/)
# SystemC-Components-Test
Examples and tests for the SystemC-Components
#Prerequisites:
## Prerequisites:
In Console:
-Check for needed modules in ~/.bashrc
they should be available directly in the linux installation or in the Modulefile top level file in the Project. If not, install it and add it to $PATH with:
export PATH="needed-path:$PATH"
-Edit bashrc and add:
./opt/shared/modules/4.4.1/init/bash
module use /opt/shared/modules/modulefiles
at end of file.
-Load the Modules from the top level file in the Project:
module load ./Modulefile
-Install conan with:
pip install conan
-and run this comands to run conan with the C++11 library:
conan profile new default --detect --force
conan profile update settings.compiler.libcxx=libstdc++11 default
-Add conan to $PATH
#Build:
-Create folder "build" in SystemC-Components-Test project folder.
-Build the project with:
cmake ..
-compile
make -j4 #4 means number of cores where it is compiled.
#Run:
-from build folder run:
./bin/"binary-name" #binary name: zb. "sim_performance"
git clone --recursive -b develop https://git.minres.com/SystemC/SystemC-Components-Test.git
cd SystemC-Components-Test/
module load ./Modulefile
python3 -mvenv .venv
. .venv/bin/activate
pip3 install -r requirements.txt
cmake -S . -B build --preset Release
cmake --build build -j30
cmake --build build --target test

1
cmake-conan Submodule

Submodule cmake-conan added at c22bbf0af0

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

3
requirements.txt Normal file
View File

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

2
scc

Submodule scc updated: e510457db9...bccc9269ff

View File

@ -7,39 +7,33 @@ auto factory::get_instance() -> factory& {
return instance;
}
factory::factory() :
m_constructors{},
m_objects{}
{ }
factory::factory()
: m_constructors{}
, m_objects{} {}
void factory::create() {
for (const auto& item : m_constructors) {
for(const auto& item : m_constructors) {
m_objects[item.first] = item.second();
}
}
void factory::destroy() {
m_objects.clear();
}
void factory::destroy() { m_objects.clear(); }
void factory::add_object(const std::string& name, constructor create) {
auto it = m_constructors.find(name);
if (it == m_constructors.cend()) {
if(it == m_constructors.cend()) {
m_constructors[name] = create;
}
else {
throw std::runtime_error("factory::add(): "
+ name + " object already exist in factory");
} else {
throw std::runtime_error("factory::add(): " + name + " object already exist in factory");
}
}
auto factory::get_object(const std::string& name) -> void* {
auto it = m_objects.find(name);
if (it == m_objects.cend()) {
throw std::runtime_error("factory::get(): "
+ name + " object doesn't exist in factory");
if(it == m_objects.cend()) {
throw std::runtime_error("factory::get(): " + name + " object doesn't exist in factory");
}
return it->second.get();

View File

@ -9,29 +9,28 @@
#ifndef SRC_FACTORY_H_
#define SRC_FACTORY_H_
#include <map>
#include <string>
#include <memory>
#include <functional>
#include <map>
#include <memory>
#include <string>
class factory {
public:
static factory& get_instance();
template<typename T, typename ...Args>
class add {
template <typename T, typename... Args> class add {
public:
add(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 destroy();
private:
using destructor = std::function<void(void*)>;
using object = std::unique_ptr<void, destructor>;
@ -51,27 +50,15 @@ private:
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) {
factory::get_instance().add_object(name, [args...]() -> object {
return object{new T(std::forward<Args>(args)...), [](void* obj) { delete static_cast<T*>(obj); }};
});
}
template<typename T, typename ...Args>
factory::add<T, Args...>::add(const std::string& name, Args&&... args) {
factory::get_instance().add_object(name,
[args...] () -> object {
return object{
new T(std::forward<Args>(args)...),
[] (void* obj) {
delete static_cast<T*>(obj);
}
};
}
);
}
template<typename T> auto
factory::get(const std::string& name) -> T& {
template <typename T> auto factory::get(const std::string& name) -> T& {
return *static_cast<T*>(factory::get_instance().get_object(name));
}

View File

@ -7,28 +7,41 @@
#include "factory.h"
#include <catch2/catch_session.hpp>
#include <csetjmp>
#include <csignal>
#include <cstdlib>
#include <scc/report.h>
#include <scc/trace.h>
#include <scc/tracer.h>
#include <util/ities.h>
#include <cstdlib>
using namespace scc;
using namespace sc_core;
jmp_buf abrt;
void ABRThandler(int sig) { longjmp(abrt, 1); }
int sc_main(int argc, char* argv[]) {
signal(SIGABRT, ABRThandler);
auto my_name = util::split(argv[0], '/').back();
scc::init_logging(LogConfig().logLevel(getenv("SCC_TEST_VERBOSE")?log::DEBUG:log::FATAL).logAsync(false));
auto level = getenv("SCC_TEST_VERBOSE");
auto log_lvl = level ? static_cast<scc::log>(std::min(strtoul(level, nullptr, 10) + 4, 7UL)) : log::FATAL;
scc::init_logging(LogConfig().logLevel(log_lvl).logAsync(false).msgTypeFieldWidth(35));
// create tracer if environment variable SCC_TEST_TRACE is defined
std::unique_ptr<scc::tracer> tracer;
if(getenv("SCC_TEST_TRACE"))
tracer=std::make_unique<scc::tracer>(my_name, scc::tracer::file_type::TEXT, true);
// instantiate design(s)
factory::get_instance().create();
// run tests
int result = Catch::Session().run( argc, argv );
// destroy design(s)
sc_stop();
factory::get_instance().destroy();
if(auto* test_trace = getenv("SCC_TEST_TRACE")) {
tracer = std::make_unique<scc::tracer>(my_name, scc::tracer::ENABLE, scc::tracer::ENABLE);
}
int result = -1;
if(setjmp(abrt) == 0) {
// instantiate design(s)
factory::get_instance().create();
// run tests
result = Catch::Session().run(argc, argv);
// destroy design(s)
sc_stop();
SCCTRACE() << "Test sequence finished";
factory::get_instance().destroy();
}
return result;
}

View File

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

View File

@ -0,0 +1,9 @@
project (ace_pin_level)
add_executable(${PROJECT_NAME}
ace_narrow_burst_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,275 @@
#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;
factory::add<testbench> tb;
int snoop_id = 0;
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 <typename bus_cfg>
tlm::tlm_generic_payload* prepare_trans_ace(uint64_t start_address, unsigned addr_incr, unsigned len, unsigned width, unsigned id) {
auto trans = tlm::scc::tlm_mm<>::get().allocate<axi::ace_extension>(len);
trans->set_address(start_address);
tlm::scc::setId(*trans, id);
auto ext = trans->get_extension<axi::ace_extension>();
trans->set_data_length(len);
trans->set_streaming_width(len);
ext->set_size(scc::ilog2(width));
sc_assert(len < (bus_cfg::BUSWIDTH / 8) || len % (bus_cfg::BUSWIDTH / 8) == 0);
auto length = (len * 8 - 1) / (8 * width);
if(width == (bus_cfg::BUSWIDTH / 8) && start_address % (bus_cfg::BUSWIDTH / 8))
length++;
ext->set_length(length);
// ext->set_burst(len * 8 > bus_cfg::buswidth ? axi::burst_e::INCR : axi::burst_e::FIXED);
// here len is CachelineSizeBytes
// here burtst for read/write_trans and snoop_trans are different
ext->set_burst(axi::burst_e::INCR); // TBD???
// ext->set_burst(len*8 > bus_cfg::BUSWIDTH ? axi::burst_e::WRAP : axi::burst_e::INCR);
ext->set_id(id);
ext->set_snoop(axi::snoop_e::READ_SHARED); // set it so that is_data_less return true???
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) {
auto& dut = factory::get<testbench>();
dut.axi_tgt_pe.set_operation_cb([&state](axi::axi_protocol_types::tlm_payload_type& trans) -> unsigned {
auto id = axi::get_axi_id(trans);
if(trans.is_read()) {
for(size_t i = 0; i < trans.get_data_length(); ++i) {
*(trans.get_data_ptr() + i) = i % 2 ? 123 : (state.resp_cnt + 128);
}
state.read_tx[id].second.emplace_back(&trans);
}
if(trans.is_write())
state.write_tx[id].second.emplace_back(&trans);
SCCDEBUG(__FUNCTION__) << "RX: " << trans;
state.resp_cnt++;
return 0;
});
dut.transport_cb = [&state](tlm::tlm_generic_payload& trans) -> unsigned {
SCCDEBUG(__FUNCTION__) << " update snoop trans, with snoop_id = " << snoop_id;
// extracting address and snoop_e from ac_trans and pack them into cache data trans
auto ac_address = trans.get_address();
auto ext = trans.get_extension<ace_extension>();
auto ac_snoop = ext->get_snoop();
for(size_t i = 0; i < trans.get_data_length(); ++i) {
*(trans.get_data_ptr() + i) = i % 2 ? i : 128;
}
state.snoop_tx[snoop_id].second.emplace_back(&trans);
return 1;
};
dut.rst.write(false);
sc_start(state.ResetCycles * dut.clk.period());
dut.rst.write(true);
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::bus_cfg>(StartAddr, 4,
// state.BurstLengthByte, state.BurstSizeBytes, 1);
tlm::scc::tlm_gp_shared_ptr trans =
prepare_trans_ace<testbench::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 1);
trans->set_command(tlm::TLM_READ_COMMAND);
SCCDEBUG(__FUNCTION__) << "run1, iteration " << i << " TX: " << *trans;
dut.intor_pe.transport(*trans, false);
state.read_tx[axi::get_axi_id(*trans)].first.emplace_back(trans);
StartAddr += state.BurstSizeBytes;
}
});
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_ace<testbench::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 2);
trans->set_command(tlm::TLM_WRITE_COMMAND);
randomize(*trans);
SCCDEBUG(__FUNCTION__) << "run2, iteration " << i << " TX: " << *trans;
dut.intor_pe.transport(*trans, false);
state.write_tx[axi::get_axi_id(*trans)].first.emplace_back(trans);
StartAddr += state.BurstSizeBytes;
}
});
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_ace<testbench::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 3);
trans->set_command(tlm::TLM_READ_COMMAND);
SCCDEBUG(__FUNCTION__) << "run3, iteration " << i << " TX: " << *trans;
dut.intor_pe.transport(*trans, false);
state.read_tx[axi::get_axi_id(*trans)].first.emplace_back(trans);
StartAddr += state.BurstSizeBytes;
}
});
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_ace<testbench::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 4);
trans->set_command(tlm::TLM_WRITE_COMMAND);
randomize(*trans);
SCCDEBUG(__FUNCTION__) << "run4, iteration " << i << " TX: " << *trans;
dut.intor_pe.transport(*trans, false);
state.write_tx[axi::get_axi_id(*trans)].first.emplace_back(trans);
StartAddr += state.BurstSizeBytes;
}
});
auto run5 = 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_ace<testbench::bus_cfg>(StartAddr, 4, state.CachelineSizeBytes, state.BurstSizeBytes, 5);
trans->set_command(tlm::TLM_READ_COMMAND);
SCCDEBUG(__FUNCTION__) << "run1, iteration " << i << "snoop_id = " << snoop_id << " TX: " << *trans;
dut.ace_tgt_pe.snoop(*trans);
SCCDEBUG(__FUNCTION__) << "run1, after iteration " << i;
state.snoop_tx[snoop_id].first.emplace_back(trans);
snoop_id++;
StartAddr += state.BurstSizeBytes;
}
});
unsigned cycles{0};
while(cycles < 1000 && !(run1.terminated() && run2.terminated() && run3.terminated() && run4.terminated())) {
// while(cycles<1000 && !(run5.terminated())){
sc_start(10 * dut.clk.period());
cycles += 10;
}
return cycles;
}
TEST_CASE("ace_burst_alignment", "[AXI][pin-level]") {
struct {
unsigned int ResetCycles{4};
unsigned int BurstLengthByte{16};
unsigned int BurstSizeBytes{8};
unsigned int NumberOfIterations{2};
unsigned int CachelineSizeBytes = {64}; //
std::unordered_map<unsigned, std::pair<std::vector<tlm::scc::tlm_gp_shared_ptr>, std::vector<tlm::scc::tlm_gp_shared_ptr>>> read_tx;
std::unordered_map<unsigned, std::pair<std::vector<tlm::scc::tlm_gp_shared_ptr>, std::vector<tlm::scc::tlm_gp_shared_ptr>>>
write_tx;
std::unordered_map<unsigned, std::pair<std::vector<tlm::scc::tlm_gp_shared_ptr>, std::vector<tlm::scc::tlm_gp_shared_ptr>>>
snoop_tx;
unsigned resp_cnt{0};
} state;
state.resp_cnt = 0;
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);
// REQUIRE(state.resp_cnt==1*state.NumberOfIterations);
for(auto& e : state.write_tx) {
auto const& send_tx = e.second.first;
auto const& recv_tx = e.second.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]));
}
}
for(auto& e : state.read_tx) {
auto const& send_tx = e.second.first;
auto const& recv_tx = e.second.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);
SCCDEBUG(__FUNCTION__) << " index = " << i;
// SCCDEBUG(__FUNCTION__) <<" send value = "<<*send_tx[i];
// SCCDEBUG(__FUNCTION__) <<" received value = "<<*recv_tx[i];
CHECK(is_equal(*send_tx[i], *recv_tx[i]));
}
}
for(auto& e : state.snoop_tx) {
auto const& snoop_tx = e.second.first;
auto const& recv_tx = e.second.second;
REQUIRE(snoop_tx.size() == recv_tx.size());
for(auto i = 0; i < snoop_tx.size(); ++i) {
REQUIRE(snoop_tx[i]->get_response_status() == tlm::TLM_OK_RESPONSE);
SCCDEBUG(__FUNCTION__) << " index = " << i;
SCCDEBUG(__FUNCTION__) << " send snoop value = " << *snoop_tx[i];
SCCDEBUG(__FUNCTION__) << " received value = " << *recv_tx[i];
// CHECK(*snoop_tx[i] == *recv_tx[i]);
}
}
}
TEST_CASE("ace_narrow_burst", "[AXI][pin-level]") {
struct {
unsigned int ResetCycles{4};
unsigned int BurstLengthByte{16};
unsigned int BurstSizeBytes{8};
unsigned int NumberOfIterations{2};
unsigned int CachelineSizeBytes = {64}; //
std::unordered_map<unsigned, std::pair<std::vector<tlm::scc::tlm_gp_shared_ptr>, std::vector<tlm::scc::tlm_gp_shared_ptr>>> read_tx;
std::unordered_map<unsigned, std::pair<std::vector<tlm::scc::tlm_gp_shared_ptr>, std::vector<tlm::scc::tlm_gp_shared_ptr>>>
write_tx;
std::unordered_map<unsigned, std::pair<std::vector<tlm::scc::tlm_gp_shared_ptr>, std::vector<tlm::scc::tlm_gp_shared_ptr>>>
snoop_tx;
unsigned resp_cnt{0};
} state;
state.resp_cnt = 0;
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);
for(auto& e : state.write_tx) {
auto const& send_tx = e.second.first;
auto const& recv_tx = e.second.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]));
}
for(auto& e : state.read_tx) {
auto const& send_tx = e.second.first;
auto const& recv_tx = e.second.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]));
}
}

View File

@ -0,0 +1,104 @@
#ifndef _TESTBENCH_H_
#define _TESTBENCH_H_
#include <axi/pe/axi_initiator.h>
#include <axi/pe/simple_ace_target.h>
#include <axi/pe/simple_target.h>
#include <axi/pin/ace_initiator.h>
#include <axi/pin/ace_target.h>
#include <axi/scv/recorder_modules.h>
#include <scc.h>
using namespace sc_core;
using namespace axi;
using namespace axi::pe;
class testbench : public sc_core::sc_module, public tlm::scc::pe::intor_bw_b {
public:
using bus_cfg = axi::ace_cfg</*BUSWIDTH=*/64, /*ADDRWIDTH=*/32, /*IDWIDTH=*/4, /*USERWIDTH=*/1, /*CACHELINE*/ 64>;
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{"rst"};
// test interface, which is bound to initiator bw_o
sc_core::sc_export<tlm::scc::pe::intor_bw_b> bw_i{"bw_i"};
// initiator side
axi::ace_initiator_socket<bus_cfg::BUSWIDTH> intor{"ace_intor"};
axi::pin::ace_initiator<bus_cfg> intor_bfm{"ace_intor_bfm"};
// signal accurate bus
axi::aw_ace<bus_cfg, axi::signal_types> aw;
axi::wdata_ace<bus_cfg, axi::signal_types> wdata;
axi::b_ace<bus_cfg, axi::signal_types> b;
axi::ar_ace<bus_cfg, axi::signal_types> ar;
axi::rresp_ace<bus_cfg, axi::signal_types> rresp;
axi::ac_ace<bus_cfg, axi::signal_types> ac;
axi::cr_ace<bus_cfg, axi::signal_types> cr;
axi::cd_ace<bus_cfg, axi::signal_types> cd;
axi::pin::ace_target<bus_cfg> tgt_bfm{"ace_tgt_bfm"};
// target side
axi::ace_target_socket<bus_cfg::BUSWIDTH> tgt_ace{"tgt_ace"};
axi::axi_target_socket<bus_cfg::BUSWIDTH> tgt_axi{"tgt_axi"};
// engines
axi::pe::ace_initiator<bus_cfg::BUSWIDTH> intor_pe;
axi::pe::simple_target<bus_cfg::BUSWIDTH> axi_tgt_pe;
axi::pe::simple_ace_target<bus_cfg::BUSWIDTH> ace_tgt_pe;
public:
SC_HAS_PROCESS(testbench);
testbench()
: testbench("testbench") {}
testbench(sc_core::sc_module_name nm)
: sc_core::sc_module(nm)
, intor_pe("ace_intor_pe", intor)
, ace_tgt_pe("ace_tgt_pe", tgt_ace)
, axi_tgt_pe("axi_tgt_pe", tgt_axi) {
bw_i.bind(*this);
intor_pe.clk_i(clk);
intor_bfm.clk_i(clk);
tgt_bfm.clk_i(clk);
axi_tgt_pe.clk_i(clk);
ace_tgt_pe.clk_i(clk);
// pe socket to recorder
intor(intor_bfm.tsckt);
// bfm to signals
intor_bfm.bind_aw(aw);
intor_bfm.bind_w(wdata);
intor_bfm.bind_b(b);
intor_bfm.bind_ar(ar);
intor_bfm.bind_r(rresp);
intor_bfm.bind_ac(ac);
intor_bfm.bind_cr(cr);
intor_bfm.bind_cd(cd);
// signals to bfm
tgt_bfm.bind_aw(aw);
tgt_bfm.bind_w(wdata);
tgt_bfm.bind_b(b);
tgt_bfm.bind_ar(ar);
tgt_bfm.bind_r(rresp);
tgt_bfm.bind_ac(ac);
tgt_bfm.bind_cr(cr);
tgt_bfm.bind_cd(cd);
// bfm to ace target
tgt_bfm.isckt(tgt_ace);
ace_tgt_pe.isckt_axi(tgt_axi);
// for updating snooop transaction
intor_pe.bw_o(bw_i);
}
unsigned transport(tlm::tlm_generic_payload& trans) override {
if(transport_cb)
return transport_cb(trans);
else
return 0;
}
std::function<unsigned(tlm::tlm_generic_payload&)> transport_cb;
};
#endif // _TESTBENCH_H_

View File

@ -0,0 +1,9 @@
project (ahb_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,251 @@
#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<ahb::ahb_extension>(len);
trans->set_address(start_address);
tlm::scc::setId(*trans, ++id);
auto ext = trans->get_extension<ahb::ahb_extension>();
trans->set_data_length(len);
trans->set_streaming_width(len);
ext->set_burst(ahb::burst_e::INCR);
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.tsck.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++;
return 0;
});
dut.rst_n.write(false);
sc_start(state.ResetCycles * dut.clk.period());
dut.rst_n.write(true);
sc_start(dut.clk.period());
dut.HSEL.write(true);
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::DWIDTH>(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::DWIDTH>(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::DWIDTH>(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::DWIDTH>(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("ahb_read_write", "[AHB][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("ahb_narrow_read_write", "[AHB][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());
for(auto i = 0; i < send_tx.size(); ++i)
CHECK(is_equal(*send_tx[i], *recv_tx[i]));
}
}
TEST_CASE("ahb_delayed_read_write", "[AHB][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, 1);
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,78 @@
#ifndef _TESTBENCH_H_
#define _TESTBENCH_H_
#include <ahb/pin/initiator.h>
#include <ahb/pin/target.h>
#include <scc.h>
using namespace sc_core;
class testbench : public sc_core::sc_module {
public:
enum { DWIDTH = 32 };
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<DWIDTH>> isck{"isck"};
ahb::pin::initiator<DWIDTH> intor_bfm{"intor_bfm"};
// signal accurate bus
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<DWIDTH>> HWDATA{"HWDATA"};
sc_core::sc_signal<bool> HWRITE{"HWRITE"};
sc_core::sc_signal<sc_dt::sc_uint<DWIDTH>> HRDATA{"HRDATA"};
sc_core::sc_signal<bool> HREADY{"HREADY"};
sc_core::sc_signal<bool> HRESP{"HRESP"};
sc_core::sc_signal<bool> HSEL{"HSEL"};
// target side
ahb::pin::target<DWIDTH, 32> 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.HCLK_i(clk);
tgt_bfm.HCLK_i(clk);
// bfm to signals
isck(intor_bfm.tsckt);
intor_bfm.HRESETn_i(rst_n);
intor_bfm.HADDR_o(HADDR);
intor_bfm.HBURST_o(HBURST);
intor_bfm.HMASTLOCK_o(HMASTLOCK);
intor_bfm.HPROT_o(HPROT);
intor_bfm.HSIZE_o(HSIZE);
intor_bfm.HTRANS_o(HTRANS);
intor_bfm.HWDATA_o(HWDATA);
intor_bfm.HWRITE_o(HWRITE);
intor_bfm.HRDATA_i(HRDATA);
intor_bfm.HREADY_i(HREADY);
intor_bfm.HRESP_i(HRESP);
// signals to bfm
tgt_bfm.HRESETn_i(rst_n);
tgt_bfm.HADDR_i(HADDR);
tgt_bfm.HBURST_i(HBURST);
tgt_bfm.HMASTLOCK_i(HMASTLOCK);
tgt_bfm.HPROT_i(HPROT);
tgt_bfm.HSIZE_i(HSIZE);
tgt_bfm.HTRANS_i(HTRANS);
tgt_bfm.HWDATA_i(HWDATA);
tgt_bfm.HWRITE_i(HWRITE);
tgt_bfm.HSEL_i(HSEL);
tgt_bfm.HRDATA_o(HRDATA);
tgt_bfm.HREADY_o(HREADY);
tgt_bfm.HRESP_o(HRESP);
tgt_bfm.isckt(tsck);
}
void run1() {}
};
#endif // _TESTBENCH_H_

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

@ -1,7 +1,7 @@
project (axi4_pin_level)
add_executable(${PROJECT_NAME}
narrow_burst_test.cpp
burst_test.cpp
${test_util_SOURCE_DIR}/sc_main.cpp
)
target_link_libraries (${PROJECT_NAME} PUBLIC test_util)

View File

@ -0,0 +1,319 @@
#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 tlm_gp_shared_ptr_vec = std::vector<tlm::scc::tlm_gp_shared_ptr>;
factory::add<testbench> tb;
//// DataTransfer()
//// ==============
// void DataTransfer(uint64_t Start_Address, unsigned axsize, unsigned axlen, unsigned Data_Bus_Bytes, axi::burst_e Mode, bool IsWrite) {
// auto Number_Bytes = 2u<<axsize;
// auto Burst_Length = axlen+1;
//// Data_Bus_Bytes is the number of 8-bit byte lanes in the bus
//// Mode is the AXI transfer mode
//// IsWrite is TRUE for a write, and FALSE for a read
// auto addr = Start_Address; // Variable for current address
// auto Aligned_Address = (unsigned(addr/Number_Bytes) * Number_Bytes);
// auto aligned = (Aligned_Address == addr); // Check whether addr is aligned to nbytes
// auto dtsize = Number_Bytes * Burst_Length; // Maximum total data transaction size
// auto Lower_Wrap_Boundary = 0ULL;
// auto Upper_Wrap_Boundary = 0ULL
// if(Mode == axi::burst_e::WRAP){
// Lower_Wrap_Boundary = (uint64_t(addr/dtsize) * dtsize);
// // addr must be aligned for a wrapping burst
// Upper_Wrap_Boundary = Lower_Wrap_Boundary + dtsize;
// }
// for(unsigned i=0; i<Burst_Length; ++i) {
// auto n = i+1;
// auto Lower_Byte_Lane = addr - (uint64_t(addr/Data_Bus_Bytes)) * Data_Bus_Bytes;
// if(aligned){
// auto Upper_Byte_Lane = Lower_Byte_Lane + Number_Bytes - 1;
// } else {
// auto Upper_Byte_Lane = Aligned_Address + Number_Bytes - 1
// - (uint64_t(addr/Data_Bus_Bytes)) * Data_Bus_Bytes;
// }
// // Peform data transfer
// if(IsWrite)
// dwrite(addr, low_byte, high_byte);
// else
// dread(addr, low_byte, high_byte);
// // Increment address if necessary
// if(Mode != axi::burst_e::FIXED) {
// if(aligned){
// addr = addr + Number_Bytes;
// if(Mode == axi::burst_e::WRAP){
// // WRAP mode is always aligned
// if(addr >= Upper_Wrap_Boundary) addr = Lower_Wrap_Boundary;
// }
// } else {
// addr = Aligned_Address + Number_Bytes;
// aligned = true; // All transfers after the first are aligned
// }
// }
// }
// return;
// }
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 <typename bus_cfg>
tlm::tlm_generic_payload* prepare_trans(uint64_t start_address, unsigned addr_incr, unsigned len, unsigned width, unsigned id) {
auto trans = tlm::scc::tlm_mm<>::get().allocate<axi::axi4_extension>(len);
trans->set_address(start_address);
tlm::scc::setId(*trans, id);
auto ext = trans->get_extension<axi::axi4_extension>();
trans->set_data_length(len);
trans->set_streaming_width(len);
ext->set_size(scc::ilog2(width));
sc_assert(len < (bus_cfg::BUSWIDTH / 8) || len % (bus_cfg::BUSWIDTH / 8) == 0);
auto length = (len * 8 - 1) / (8 * width);
// if(width == (bus_cfg::BUSWIDTH / 8) && start_address % (bus_cfg::BUSWIDTH / 8))
// length++;
if(start_address % (bus_cfg::BUSWIDTH / 8) + width > (bus_cfg::BUSWIDTH / 8))
length++;
ext->set_length(length);
// ext->set_burst(len * 8 > bus_cfg::buswidth ? axi::burst_e::INCR : axi::burst_e::FIXED);
ext->set_burst(axi::burst_e::INCR);
ext->set_id(id);
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) {
auto& dut = factory::get<testbench>();
dut.tgt_pe.set_operation_cb([&state](axi::axi_protocol_types::tlm_payload_type& trans) -> unsigned {
auto id = axi::get_axi_id(trans);
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[id].second.emplace_back(&trans);
}
if(trans.is_write())
state.write_tx[id].second.emplace_back(&trans);
SCCDEBUG(__FUNCTION__) << "RX: " << trans;
state.resp_cnt++;
return 0;
});
dut.rst.write(false);
sc_start(state.ResetCycles * dut.clk.period());
dut.rst.write(true);
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::bus_cfg>(StartAddr + (state.unaligned ? 2 : 0), 4, state.BurstLengthByte, state.BurstSizeBytes, 1);
trans->set_command(tlm::TLM_READ_COMMAND);
SCCDEBUG("run1") << "iteration " << i << " TX: " << *trans;
dut.intor_pe.transport(*trans, false);
state.read_tx[axi::get_axi_id(*trans)].first.emplace_back(trans);
StartAddr += state.BurstSizeBytes;
}
SCCDEBUG("run1") << "finished " << state.NumberOfIterations << " iterations";
});
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::bus_cfg>(StartAddr + (state.unaligned ? 2 : 0), 4, state.BurstLengthByte, state.BurstSizeBytes, 2);
trans->set_command(tlm::TLM_WRITE_COMMAND);
randomize(*trans);
SCCDEBUG("run2") << "iteration " << i << " TX: " << *trans;
dut.intor_pe.transport(*trans, false);
state.write_tx[axi::get_axi_id(*trans)].first.emplace_back(trans);
StartAddr += state.BurstSizeBytes;
}
SCCDEBUG("run2") << "finished " << state.NumberOfIterations << " iterations";
});
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::bus_cfg>(StartAddr + (state.unaligned ? 2 : 0), 4, state.BurstLengthByte, state.BurstSizeBytes, 3);
trans->set_command(tlm::TLM_READ_COMMAND);
SCCDEBUG("run3") << "iteration " << i << " TX: " << *trans;
dut.intor_pe.transport(*trans, false);
state.read_tx[axi::get_axi_id(*trans)].first.emplace_back(trans);
StartAddr += state.BurstSizeBytes;
}
SCCDEBUG("run3") << "finished " << state.NumberOfIterations << " iterations";
});
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::bus_cfg>(StartAddr + (state.unaligned ? 2 : 0), 4, state.BurstLengthByte, state.BurstSizeBytes, 4);
trans->set_command(tlm::TLM_WRITE_COMMAND);
randomize(*trans);
SCCDEBUG("run4") << "iteration " << i << " TX: " << *trans;
dut.intor_pe.transport(*trans, false);
state.write_tx[axi::get_axi_id(*trans)].first.emplace_back(trans);
StartAddr += state.BurstSizeBytes;
}
SCCDEBUG("run4") << "finished " << state.NumberOfIterations << " iterations";
});
unsigned cycles{0};
while(cycles < 1000 && !(run1.terminated() && run2.terminated() && run3.terminated() && run4.terminated())) {
sc_start(10 * dut.clk.period());
cycles += 10;
}
return cycles;
}
void axi4_burst_alignment(bool pipelined_wrreq, bool write_bp, bool unaligned = false) {
SCCINFO(__FUNCTION__) << "starting with pipelined_wrreq=" << pipelined_wrreq << " and write_bp=" << write_bp;
struct {
unsigned int ResetCycles{4};
unsigned int BurstLengthByte{16};
unsigned int BurstSizeBytes{8};
unsigned int NumberOfIterations{8};
std::unordered_map<unsigned, std::pair<tlm_gp_shared_ptr_vec, tlm_gp_shared_ptr_vec>> read_tx;
std::unordered_map<unsigned, std::pair<tlm_gp_shared_ptr_vec, tlm_gp_shared_ptr_vec>> write_tx;
unsigned resp_cnt{0};
bool unaligned{false};
} state;
state.unaligned = unaligned;
auto& dut = factory::get<testbench>();
dut.intor_bfm.pipelined_wrreq = pipelined_wrreq;
dut.tgt_pe.wr_data_accept_delay.set_value(write_bp ? 1 : 0);
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);
for(auto& e : state.write_tx) {
auto const& send_tx = e.second.first;
auto const& recv_tx = e.second.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]));
}
}
for(auto& e : state.read_tx) {
auto const& send_tx = e.second.first;
auto const& recv_tx = e.second.second;
REQUIRE(send_tx.size() == recv_tx.size());
for(auto i = 0; i < send_tx.size(); ++i) {
auto addr = send_tx[i]->get_address();
if(addr % (testbench::bus_cfg::ADDRWIDTH / 8)) {
CHECK(send_tx[i]->get_data_length() <= recv_tx[i]->get_data_length());
CHECK(send_tx[i]->get_byte_enable_length() <= recv_tx[i]->get_byte_enable_length());
// adjust the length of the read due to misalignment
recv_tx[i]->set_data_length(send_tx[i]->get_data_length());
recv_tx[i]->set_byte_enable_length(send_tx[i]->get_byte_enable_length());
recv_tx[i]->set_streaming_width(send_tx[i]->get_streaming_width());
}
REQUIRE(send_tx[i]->get_response_status() == tlm::TLM_OK_RESPONSE);
CHECK(is_equal(*send_tx[i], *recv_tx[i]));
}
}
}
void axi4_narrow_burst(bool pipelined_wrreq, bool write_bp, bool unaligned = false) {
SCCINFO(__FUNCTION__) << "starting with pipelined_wrreq=" << pipelined_wrreq << ", write_bp = " << write_bp
<< " and unaligned=" << unaligned;
struct {
unsigned int ResetCycles{4};
unsigned int BurstLengthByte{16};
unsigned int BurstSizeBytes{4};
unsigned int NumberOfIterations{8};
std::unordered_map<unsigned, std::pair<tlm_gp_shared_ptr_vec, tlm_gp_shared_ptr_vec>> read_tx;
std::unordered_map<unsigned, std::pair<tlm_gp_shared_ptr_vec, tlm_gp_shared_ptr_vec>> write_tx;
unsigned resp_cnt{0};
bool unaligned{false};
} state;
state.unaligned = unaligned;
auto& dut = factory::get<testbench>();
dut.intor_bfm.pipelined_wrreq = pipelined_wrreq;
dut.tgt_pe.wr_data_accept_delay.set_value(write_bp ? 1 : 0);
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);
for(auto& e : state.write_tx) {
auto const& send_tx = e.second.first;
auto const& recv_tx = e.second.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]));
}
for(auto& e : state.read_tx) {
auto const& send_tx = e.second.first;
auto const& recv_tx = e.second.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]));
}
}
TEST_CASE("axi4_burst_alignment", "[AXI][pin-level]") { axi4_burst_alignment(false, false); }
TEST_CASE("axi4_burst_alignment_unaligned_addr", "[AXI][pin-level]") { axi4_burst_alignment(false, false, true); }
TEST_CASE("axi4_narrow_burst", "[AXI][pin-level]") { axi4_narrow_burst(false, false); }
// TEST_CASE("axi4_narrow_burst_unaligned_addr", "[AXI][pin-level]") { axi4_narrow_burst(false, false, true); }
TEST_CASE("axi4_burst_alignment_with_bp", "[AXI][pin-level]") { axi4_burst_alignment(false, true); }
TEST_CASE("axi4_burst_alignment_with_bp_unaligned_addr", "[AXI][pin-level]") { axi4_burst_alignment(false, true, true); }
TEST_CASE("axi4_narrow_burst_with_bp", "[AXI][pin-level]") { axi4_narrow_burst(false, true); }
// TEST_CASE("axi4_narrow_burst_with_bp_unaligned_addr", "[AXI][pin-level]") { axi4_narrow_burst(false, true, true); }
TEST_CASE("axi4_burst_alignment_pipelined_write", "[AXI][pin-level]") { axi4_burst_alignment(true, false); }
TEST_CASE("axi4_burst_alignment_pipelined_write_unaligned_addr", "[AXI][pin-level]") { axi4_burst_alignment(true, false, true); }
TEST_CASE("axi4_narrow_burst_pipelined_write", "[AXI][pin-level]") { axi4_narrow_burst(true, false); }
// TEST_CASE("axi4_narrow_burst_pipelined_write_unaligned_addr", "[AXI][pin-level]") { axi4_narrow_burst(true, false, true); }
TEST_CASE("axi4_burst_alignment_pipelined_write_with_bp", "[AXI][pin-level]") { axi4_burst_alignment(true, true); }
TEST_CASE("axi4_burst_alignment_pipelined_write_with_bp_unaligned_addr", "[AXI][pin-level]") { axi4_burst_alignment(true, true, true); }
TEST_CASE("axi4_narrow_burst_pipelined_write_with_bp", "[AXI][pin-level]") { axi4_narrow_burst(true, true); }
// TEST_CASE("axi4_narrow_burst_pipelined_write_with_bp_unaligned_addr", "[AXI][pin-level]") { axi4_narrow_burst(true, true, true); }

View File

@ -1,211 +0,0 @@
#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;
factory::add<testbench> tb;
bool operator==(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<typename bus_cfg>
tlm::tlm_generic_payload* prepare_trans(uint64_t start_address, unsigned addr_incr, unsigned len, unsigned width, unsigned id) {
auto trans = tlm::scc::tlm_mm<>::get().allocate<axi::axi4_extension>(len);
trans->set_address(start_address);
tlm::scc::setId(*trans, id);
auto ext = trans->get_extension<axi::axi4_extension>();
trans->set_data_length(len);
trans->set_streaming_width(len);
ext->set_size(scc::ilog2(width));
sc_assert(len < (bus_cfg::BUSWIDTH / 8) || len % (bus_cfg::BUSWIDTH / 8) == 0);
auto length = (len * 8 - 1) / (8*width);
if(width==(bus_cfg::BUSWIDTH / 8) && start_address % (bus_cfg::BUSWIDTH / 8))
length++;
ext->set_length(length);
// ext->set_burst(len * 8 > bus_cfg::buswidth ? axi::burst_e::INCR : axi::burst_e::FIXED);
ext->set_burst(axi::burst_e::INCR);
ext->set_id(id);
return trans;
}
inline void randomize(tlm::tlm_generic_payload& gp) {
static uint8_t req_cnt{0};
auto addr = gp.get_address();
uint8_t const* src = reinterpret_cast<uint8_t const*>(&addr);
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){
auto& dut = factory::get<testbench>();
dut.tgt_pe.set_operation_cb([&state](axi::axi_protocol_types::tlm_payload_type& trans) -> unsigned {
auto id = axi::get_axi_id(trans);
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[id].second.emplace_back(&trans);
}
if(trans.is_write())
state.write_tx[id].second.emplace_back(&trans);
SCCDEBUG(__FUNCTION__)<<"RX: "<<trans;
state.resp_cnt++;
return 0;
});
dut.rst.write(false);
sc_start(state.ResetCycles*dut.clk.period());
dut.rst.write(true);
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::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 1);
trans->set_command(tlm::TLM_READ_COMMAND);
SCCDEBUG(__FUNCTION__) << "run1, iteration " << i <<" TX: "<<*trans;
dut.intor_pe.transport(*trans, false);
state.read_tx[axi::get_axi_id(*trans)].first.emplace_back(trans);
StartAddr += state.BurstSizeBytes;
}
});
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::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 2);
trans->set_command(tlm::TLM_WRITE_COMMAND);
randomize(*trans);
SCCDEBUG(__FUNCTION__) << "run2, iteration " << i <<" TX: "<<*trans;
dut.intor_pe.transport(*trans, false);
state.write_tx[axi::get_axi_id(*trans)].first.emplace_back(trans);
StartAddr += state.BurstSizeBytes;
}
});
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::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 3);
trans->set_command(tlm::TLM_READ_COMMAND);
SCCDEBUG(__FUNCTION__) << "run3, iteration " << i <<" TX: "<<*trans;
dut.intor_pe.transport(*trans, false);
state.read_tx[axi::get_axi_id(*trans)].first.emplace_back(trans);
StartAddr += state.BurstSizeBytes;
}
});
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::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 4);
trans->set_command(tlm::TLM_WRITE_COMMAND);
randomize(*trans);
SCCDEBUG(__FUNCTION__) << "run4, iteration " << i <<" TX: "<<*trans;
dut.intor_pe.transport(*trans, false);
state.write_tx[axi::get_axi_id(*trans)].first.emplace_back(trans);
StartAddr += state.BurstSizeBytes;
}
});
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("axi4_burst_alignment", "[AXI][pin-level]") {
struct {
unsigned int ResetCycles{4};
unsigned int BurstLengthByte{16};
unsigned int BurstSizeBytes{8};
unsigned int NumberOfIterations{8};
std::unordered_map<unsigned, std::pair<std::vector<tlm::scc::tlm_gp_shared_ptr>, std::vector<tlm::scc::tlm_gp_shared_ptr>>> read_tx;
std::unordered_map<unsigned, 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);
for(auto& e: state.write_tx) {
auto const& send_tx = e.second.first;
auto const& recv_tx = e.second.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(*send_tx[i] == *recv_tx[i]);
}
}
for(auto& e: state.read_tx) {
auto const& send_tx = e.second.first;
auto const& recv_tx = e.second.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(*send_tx[i] == *recv_tx[i]);
}
}
}
TEST_CASE("axi4_narrow_burst", "[AXI][pin-level]") {
struct {
unsigned int ResetCycles{4};
unsigned int BurstLengthByte{16};
unsigned int BurstSizeBytes{4};
unsigned int NumberOfIterations{8};
std::unordered_map<unsigned, std::pair<std::vector<tlm::scc::tlm_gp_shared_ptr>, std::vector<tlm::scc::tlm_gp_shared_ptr>>> read_tx;
std::unordered_map<unsigned, 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);
for(auto& e: state.write_tx) {
auto const& send_tx = e.second.first;
auto const& recv_tx = e.second.second;
REQUIRE(send_tx.size() == recv_tx.size());
for(auto i = 0; i<send_tx.size(); ++i)
CHECK(*send_tx[i] == *recv_tx[i]);
}
for(auto& e: state.read_tx) {
auto const& send_tx = e.second.first;
auto const& recv_tx = e.second.second;
REQUIRE(send_tx.size() == recv_tx.size());
for(auto i = 0; i<send_tx.size(); ++i)
CHECK(*send_tx[i] == *recv_tx[i]);
}
}

View File

@ -24,11 +24,11 @@ public:
axi::scv::axi_recorder_module<bus_cfg::BUSWIDTH> intor_rec{"intor_rec"};
axi::pin::axi4_initiator<bus_cfg> intor_bfm{"intor_bfm"};
// signal accurate bus
axi::aw_ch<bus_cfg, axi::signal_types> aw;
axi::wdata_ch<bus_cfg, axi::signal_types> wdata;
axi::b_ch<bus_cfg, axi::signal_types> b;
axi::ar_ch<bus_cfg, axi::signal_types> ar;
axi::rresp_ch<bus_cfg, axi::signal_types> rresp;
axi::aw_axi<bus_cfg, axi::signal_types> aw;
axi::wdata_axi<bus_cfg, axi::signal_types> wdata;
axi::b_axi<bus_cfg, axi::signal_types> b;
axi::ar_axi<bus_cfg, axi::signal_types> ar;
axi::rresp_axi<bus_cfg, axi::signal_types> rresp;
axi::pin::axi4_target<bus_cfg> tgt_bfm{"tgt_bfm"};
// target side
axi::scv::axi_recorder_module<bus_cfg::BUSWIDTH> tgt_rec{"tgt_rec"};
@ -39,7 +39,8 @@ public:
public:
SC_HAS_PROCESS(testbench);
testbench(): testbench("testbench") {}
testbench()
: testbench("testbench") {}
testbench(sc_core::sc_module_name nm)
: sc_core::sc_module(nm)
, intor_pe("intor_pe", intor)
@ -70,9 +71,7 @@ public:
tgt_rec.isckt(tgt);
}
void run1() {
}
void run1() {}
};
#endif // _TESTBENCH_H_

View File

@ -0,0 +1,116 @@
[*]
[*] GTKWave Analyzer v3.3.118 (w)1999-2023 BSI
[*] Wed Jan 8 16:33:12 2025
[*]
[dumpfile] "/scratch/eyck/workarea/MINRES/SystemC-Components-Test/axi4_pin_level.fst"
[dumpfile_mtime] "Wed Jan 8 16:32:32 2025"
[dumpfile_size] 7261
[savefile] "/scratch/eyck/workarea/MINRES/SystemC-Components-Test/tests/axi4_pin_level/waves.gtkw"
[timestart] 0
[size] 2560 1288
[pos] -1 -1
*-20.062529 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] testbench.
[sst_width] 304
[signals_width] 243
[sst_expanded] 1
[sst_vpaned_height] 396
@28
testbench.clk
testbench.rst
@800200
-ar
@28
testbench.ar_valid
testbench.ar_ready
@22
testbench.ar_addr[31:0]
@28
testbench.ar_burst[1:0]
@22
testbench.ar_cache[3:0]
testbench.ar_id[3:0]
testbench.ar_len[7:0]
@28
testbench.ar_lock
testbench.ar_prot[2:0]
@22
testbench.ar_qos[3:0]
testbench.ar_region[3:0]
@28
testbench.ar_size[2:0]
testbench.ar_user
@1000200
-ar
@800200
-r
@28
testbench.r_valid
testbench.r_ready
testbench.r_last
@22
testbench.r_data[63:0]
testbench.r_id[3:0]
@28
testbench.r_resp[1:0]
testbench.r_trace
testbench.r_user
@1000200
-r
@800200
-aw
@28
testbench.aw_valid
testbench.aw_ready
@22
testbench.aw_id[3:0]
testbench.aw_addr[31:0]
@28
testbench.aw_burst[1:0]
@22
testbench.aw_cache[3:0]
testbench.aw_len[7:0]
@28
testbench.aw_lock
testbench.aw_prot[2:0]
@22
testbench.aw_qos[3:0]
testbench.aw_region[3:0]
@28
testbench.aw_size[2:0]
testbench.aw_user
@1000200
-aw
@800200
-w
@29
testbench.w_valid
testbench.w_ready
testbench.w_ack
@23
testbench.w_data[63:0]
testbench.w_id[3:0]
@29
testbench.w_last
@23
testbench.w_strb[7:0]
@29
testbench.w_trace
testbench.w_user
@1000200
-w
@800200
-b
@28
testbench.b_valid
testbench.b_ready
@22
testbench.b_id[3:0]
@28
testbench.b_resp[1:0]
testbench.b_trace
testbench.b_user
@1000200
-b
[pattern_trace] 1
[pattern_trace] 0

View File

@ -0,0 +1,9 @@
project (cci_param_restricted)
add_executable(${PROJECT_NAME}
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,145 @@
#ifndef SC_INCLUDE_DYNAMIC_PROCESSES
#define SC_INCLUDE_DYNAMIC_PROCESSES
#include <sysc/kernel/sc_simcontext.h>
#endif
#include <array>
#include <catch2/catch_all.hpp>
#include <factory.h>
#include <scc/cci_param_restricted.h>
#include <scc/utilities.h>
#include <systemc>
using namespace sc_core;
struct top : public sc_core::sc_module {
top()
: top("top") {}
top(sc_module_name const& nm)
: sc_core::sc_module(nm) {}
scc::cci_param_restricted<int> param1{"param1", 5, scc::min_max_restriction(0, 10), "This is parameter 1"};
scc::cci_param_restricted<int> param2{"param2", 5, scc::min_max_excl_restriction(0, 10), "This is parameter 3"};
scc::cci_param_restricted<int> param3{"param3", 10, scc::min_restriction(0), "This is parameter 2"};
scc::cci_param_restricted<int> param4{"param4", 10, scc::min_excl_restriction(0), "This is parameter 4"};
scc::cci_param_restricted<int> param5{"param5", 1, scc::max_restriction(10), "This is parameter 5"};
scc::cci_param_restricted<int> param6{"param6", 1, scc::max_excl_restriction(10), "This is parameter 6"};
scc::cci_param_restricted<int> param7{"param7", 4, scc::discrete_restriction({1, 2, 4, 8, 16}), "This is parameter 7"};
std::array<int, 5> values_arr{1, 2, 4, 8, 16};
scc::cci_param_restricted<int> param8{"param8", 4, scc::discrete_restriction(values_arr), "This is parameter 8"};
std::vector<int> values_vec{1, 2, 4, 8, 16};
scc::cci_param_restricted<int> param9{"param9", 4, scc::discrete_restriction(values_vec), "This is parameter 9"};
};
factory::add<top> tb;
TEST_CASE("simple cci_param_restricted min_max test", "[SCC][cci_param_restricted]") {
sc_report_handler::set_actions(SC_ERROR, SC_LOG | SC_CACHE_REPORT | SC_DISPLAY | SC_DO_NOTHING);
auto& dut = factory::get<top>();
auto run1 = sc_spawn([&dut]() {
sc_core::wait(1_ns);
for(auto i : {0, 5, 10, -1, 11}) {
dut.param1.set_value(i);
sc_core::wait(1_ns);
}
});
sc_start(10_ns);
REQUIRE(run1.terminated());
REQUIRE(sc_report_handler::get_count(SC_ERROR) == 2);
REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0);
sc_report_handler::initialize();
auto run2 = sc_spawn([&dut]() {
sc_core::wait(1_ns);
for(auto i : {0, 5, 10, -1, 11}) {
dut.param2.set_value(i);
sc_core::wait(1_ns);
}
});
sc_start(10_ns);
REQUIRE(run2.terminated());
REQUIRE(sc_report_handler::get_count(SC_ERROR) == 4);
REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0);
sc_report_handler::initialize();
}
TEST_CASE("simple cci_param_restricted min test", "[SCC][cci_param_restricted]") {
sc_report_handler::set_actions(SC_ERROR, SC_LOG | SC_CACHE_REPORT | SC_DISPLAY | SC_DO_NOTHING);
auto& dut = factory::get<top>();
auto run1 = sc_spawn([&dut]() {
sc_core::wait(1_ns);
for(auto i : {0, 5, -1}) {
dut.param3.set_value(i);
sc_core::wait(1_ns);
}
});
sc_start(10_ns);
REQUIRE(run1.terminated());
REQUIRE(sc_report_handler::get_count(SC_ERROR) == 1);
REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0);
sc_report_handler::initialize();
auto run2 = sc_spawn([&dut]() {
sc_core::wait(1_ns);
for(auto i : {0, 5, -1}) {
dut.param4.set_value(i);
sc_core::wait(1_ns);
}
});
sc_start(10_ns);
REQUIRE(run2.terminated());
REQUIRE(sc_report_handler::get_count(SC_ERROR) == 2);
REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0);
sc_report_handler::initialize();
}
TEST_CASE("simple cci_param_restricted max test", "[SCC][cci_param_restricted]") {
sc_report_handler::set_actions(SC_ERROR, SC_LOG | SC_CACHE_REPORT | SC_DISPLAY | SC_DO_NOTHING);
auto& dut = factory::get<top>();
auto run1 = sc_spawn([&dut]() {
sc_core::wait(1_ns);
for(auto i : {0, 10, 11}) {
dut.param5.set_value(i);
sc_core::wait(1_ns);
}
});
sc_start(10_ns);
REQUIRE(run1.terminated());
REQUIRE(sc_report_handler::get_count(SC_ERROR) == 1);
REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0);
sc_report_handler::initialize();
auto run2 = sc_spawn([&dut]() {
sc_core::wait(1_ns);
for(auto i : {0, 10, 11}) {
dut.param6.set_value(i);
sc_core::wait(1_ns);
}
});
sc_start(10_ns);
REQUIRE(run2.terminated());
REQUIRE(sc_report_handler::get_count(SC_ERROR) == 2);
REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0);
sc_report_handler::initialize();
}
TEST_CASE("simple cci_param_restricted discrete test", "[SCC][cci_param_restricted]") {
sc_report_handler::set_actions(SC_ERROR, SC_LOG | SC_CACHE_REPORT | SC_DISPLAY | SC_DO_NOTHING);
auto& dut = factory::get<top>();
auto run1 = sc_spawn([&dut]() {
sc_core::wait(1_ns);
for(auto i : {4, 10}) {
dut.param7.set_value(i);
dut.param8.set_value(i);
dut.param9.set_value(i);
sc_core::wait(1_ns);
}
});
sc_start(10_ns);
REQUIRE(run1.terminated());
REQUIRE(sc_report_handler::get_count(SC_ERROR) == 3);
REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0);
sc_report_handler::initialize();
}

View File

@ -32,10 +32,10 @@
#define EXAMPLES_EX09_HIERARCHICAL_OVERRIDE_OF_PARAMETER_VALUES_INITIATOR_H_
#include <cci_configuration>
#include <tlm>
#include <string>
#include <tlm_utils/simple_initiator_socket.h>
#include <scc/report.h>
#include <string>
#include <tlm>
#include <tlm_utils/simple_initiator_socket.h>
/**
* @class initiator
@ -46,7 +46,7 @@ SC_MODULE(initiator) {
public:
int data;
tlm_utils::simple_initiator_socket<initiator, 32> initiator_socket; ///< Instance of TLM2 simple initiator socket
tlm_utils::simple_initiator_socket<initiator, 32> initiator_socket; ///< Instance of TLM2 simple initiator socket
/**
* @fn initiator
@ -54,13 +54,13 @@ public:
* @return void
*/
SC_CTOR(initiator)
:
data(0), initiator_socket("initiator_socket"), initiator_ID("initiator_ID", "initiator_default") {
: data(0)
, initiator_socket("initiator_socket")
, initiator_ID("initiator_ID", "initiator_default") {
SCCINFO(SCMOD) << "[" << initiator_ID.get_value() << " C_TOR] ------- [INITIATOR CONSTRUCTOR BEGINS HERE] --------";
// initiator's SC_THREAD declaration
SC_THREAD(run_initiator);
}
/**
@ -69,18 +69,18 @@ public:
* @return void
*/
void run_initiator(void) {
tlm::tlm_generic_payload *trans = new tlm::tlm_generic_payload;
tlm::tlm_generic_payload* trans = new tlm::tlm_generic_payload;
int i = 0;
static tlm::tlm_command cmds[8] =
{ tlm::TLM_WRITE_COMMAND, tlm::TLM_READ_COMMAND, tlm::TLM_WRITE_COMMAND, tlm::TLM_READ_COMMAND, tlm::TLM_READ_COMMAND,
tlm::TLM_READ_COMMAND, tlm::TLM_WRITE_COMMAND, tlm::TLM_WRITE_COMMAND };
while (1) {
static tlm::tlm_command cmds[8] = {tlm::TLM_WRITE_COMMAND, tlm::TLM_READ_COMMAND, tlm::TLM_WRITE_COMMAND, tlm::TLM_READ_COMMAND,
tlm::TLM_READ_COMMAND, tlm::TLM_READ_COMMAND, tlm::TLM_WRITE_COMMAND, tlm::TLM_WRITE_COMMAND};
while(1) {
tlm::tlm_command cmd = cmds[(i >> 2) % 8];
//static_cast<tlm::tlm_command>(cmd_dist(rng));
// static_cast<tlm::tlm_command>(cmd_dist(rng));
if (cmd == tlm::TLM_WRITE_COMMAND) data = 0xFF000000 | i;
if(cmd == tlm::TLM_WRITE_COMMAND)
data = 0xFF000000 | i;
trans->set_command(cmd);
trans->set_address(i);
@ -92,27 +92,28 @@ public:
trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
sc_core::sc_time delay = sc_core::sc_time(0, sc_core::SC_NS);
if (cmd == tlm::TLM_WRITE_COMMAND) {
if(cmd == tlm::TLM_WRITE_COMMAND) {
SCCINFO(SCMOD) << "[Initiators Message]=>At address " << std::hex << i << " sending transaction with command = Write"
<< ", data=" << std::hex << data << " at time " << sc_core::sc_time_stamp();
<< ", data=" << std::hex << data << " at time " << sc_core::sc_time_stamp();
} else {
SCCINFO(SCMOD) << "[Initiators Message]=>At address " << std::hex << i << " sending transaction with command= Read "
<< " at time " << sc_core::sc_time_stamp();
<< " at time " << sc_core::sc_time_stamp();
}
initiator_socket->b_transport(*trans, delay);
if (trans->is_response_error())
SCCERR(SCMOD) << "TLM_2" << trans->get_response_string().c_str();
if(trans->is_response_error())
SCCERR(SCMOD) << "TLM_2" << trans->get_response_string().c_str();
if (delay.to_double() != 0) wait(delay);
if(delay.to_double() != 0)
wait(delay);
if (cmd == tlm::TLM_WRITE_COMMAND) {
if(cmd == tlm::TLM_WRITE_COMMAND) {
SCCINFO(SCMOD) << "[Initiators Message]=>At address " << std::hex << i << " received response of Write transaction "
<< " at time " << sc_core::sc_time_stamp();
<< " at time " << sc_core::sc_time_stamp();
} else {
SCCINFO(SCMOD) << "[Initiators Message]=>At address " << std::hex << i << " received response of Read transaction "
<< " data " << data << " at time " << sc_core::sc_time_stamp();
<< " data " << data << " at time " << sc_core::sc_time_stamp();
}
SCCINFO(SCMOD) << "--------------------------------------------------------";
@ -124,17 +125,15 @@ public:
}
private:
cci::cci_param<std::string, cci::CCI_MUTABLE_PARAM> initiator_ID; ///< Elab Time Param for assigning initiator ID (initialized by top_module)
cci::cci_param<std::string, cci::CCI_MUTABLE_PARAM>
initiator_ID; ///< Elab Time Param for assigning initiator ID (initialized by top_module)
/**
* @fn void end_of_elaboration()
* @brief end of elaboration function to lock structural param
* @return void
*/
void end_of_elaboration() {
initiator_ID.lock();
}
void end_of_elaboration() { initiator_ID.lock(); }
};
// initiator
// initiator
#endif // EXAMPLES_EX09_HIERARCHICAL_OVERRIDE_OF_PARAMETER_VALUES_INITIATOR_H_
#endif // EXAMPLES_EX09_HIERARCHICAL_OVERRIDE_OF_PARAMETER_VALUES_INITIATOR_H_

View File

@ -35,13 +35,13 @@
#endif
#include <cci_configuration>
#include <iomanip>
#include <sstream>
#include <tlm>
#include <vector>
#include <sstream>
#include <iomanip>
#include <tlm_utils/multi_passthrough_target_socket.h>
#include <tlm_utils/multi_passthrough_initiator_socket.h>
#include <tlm_utils/multi_passthrough_target_socket.h>
/**
* @class router
@ -59,9 +59,13 @@ public:
* @return void
*/
SC_CTOR(router)
:
Router_target("Router_target"), Router_initiator("Router_initiator"), r_initiators("r_initiators", 0), r_targets("r_targets",
0), addr_limit("addr_max", 64), m_broker(cci::cci_get_broker()), addrSize(0) {
: Router_target("Router_target")
, Router_initiator("Router_initiator")
, r_initiators("r_initiators", 0)
, r_targets("r_targets", 0)
, addr_limit("addr_max", 64)
, m_broker(cci::cci_get_broker())
, addrSize(0) {
SCCINFO(SCMOD) << "[ROUTER C_TOR] ----- [ROUTER CONSTRUCTOR BEGINS HERE] ------";
// Register b_transport
@ -78,8 +82,8 @@ public:
SCCINFO(SCMOD) << "[ROUTER in beoe] : Number of target(s) : " << r_targets.get_value();
SCCINFO(SCMOD) << "[ROUTER in beoe] : Maximum Addressable Limit of the router : " << addr_limit.get_value();
char targetName[10]; ///< Holds router table's fields' names
addrSize = (unsigned int) (addr_limit.get_value() / r_targets);
char targetName[10]; ///< Holds router table's fields' names
addrSize = (unsigned int)(addr_limit.get_value() / r_targets);
// Printing the Router Table contents
SCCINFO(SCMOD) << "============= ROUTER TABLE INFORMATION ==============";
@ -89,7 +93,7 @@ public:
// Sets the contents of the routing table with (default) values
// calculated within 'beoe' phase
for (int i = 0; i < r_targets; i++) {
for(int i = 0; i < r_targets; i++) {
snprintf(targetName, sizeof(targetName), "r_index_%d", i);
r_target_index.push_back(new cci::cci_param<unsigned int, cci::CCI_IMMUTABLE_PARAM>(targetName, i));
@ -100,37 +104,37 @@ public:
r_addr_end.push_back(new cci::cci_param<unsigned int, cci::CCI_IMMUTABLE_PARAM>(targetName, ((i + 1) * addrSize - 1)));
}
for (int i = 0; i < r_targets; i++) {
for(int i = 0; i < r_targets; i++) {
snprintf(stringName, sizeof(stringName), "top_module_inst.target_%d.s_base_addr", i);
base_handle = m_broker.get_param_handle(stringName);
if (!base_handle.is_valid()) {
if(!base_handle.is_valid()) {
sc_assert(!"target Base Address Handle returned is NULL");
}
std::stringstream row_ss;
row_ss << "| " << std::setw(10) << r_target_index[i]->get_value() << " | " << std::setw(10) << std::hex << std::showbase
<< r_addr_start[i]->get_value() << " | " << std::setw(10) << r_addr_end[i]->get_value() << " | " << std::setw(10)
<< base_handle.get_cci_value().to_json() << " |";
<< r_addr_start[i]->get_value() << " | " << std::setw(10) << r_addr_end[i]->get_value() << " | " << std::setw(10)
<< base_handle.get_cci_value().to_json() << " |";
SCCINFO(SCMOD) << row_ss.str().c_str();
SCCINFO(SCMOD) << "-----------------------------------------------------";
}
}
// Blocking transport implementation of the router
void b_transport(int i_, tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {
void b_transport(int i_, tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) {
wait(delay);
delay = sc_core::SC_ZERO_TIME;
sc_dt::uint64 addr = trans.get_address();
if (addr >= static_cast<sc_dt::uint64>(addr_limit.get_value())) {
if(addr >= static_cast<sc_dt::uint64>(addr_limit.get_value())) {
trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
return;
}
for (unsigned int i = 0; i < r_target_index.size(); i++) {
if ((addr >= (r_addr_start[i]->get_value())) && (addr <= (r_addr_end[i]->get_value()))) {
for(unsigned int i = 0; i < r_target_index.size(); i++) {
if((addr >= (r_addr_start[i]->get_value())) && (addr <= (r_addr_end[i]->get_value()))) {
SCCINFO(SCMOD) << "[Router in 'b_transport' layer]";
SCCINFO(SCMOD) << "Address = " << std::hex << addr;
SCCINFO(SCMOD) << "Index = " << (r_target_index[i])->get_value();
@ -145,15 +149,15 @@ public:
private:
/// Demonstrates Model-to-Model Configuration (UC12)
/// Elaboration Time Parameters for setting up the model hierarcy;
cci::cci_param<int, cci::CCI_MUTABLE_PARAM> r_initiators; ///< initiator ID assigned by the top_module upon instantiation
cci::cci_param<int, cci::CCI_MUTABLE_PARAM> r_targets; ///< target ID assigned by the top_module upon instantiation
cci::cci_param<unsigned int, cci::CCI_MUTABLE_PARAM> addr_limit; ///< Router Addressing Range
cci::cci_broker_handle m_broker; ///< CCI configuration broker handle
cci::cci_param<int, cci::CCI_MUTABLE_PARAM> r_initiators; ///< initiator ID assigned by the top_module upon instantiation
cci::cci_param<int, cci::CCI_MUTABLE_PARAM> r_targets; ///< target ID assigned by the top_module upon instantiation
cci::cci_param<unsigned int, cci::CCI_MUTABLE_PARAM> addr_limit; ///< Router Addressing Range
cci::cci_broker_handle m_broker; ///< CCI configuration broker handle
/// Router Table contents holding targets related information
std::vector<cci::cci_param<unsigned int, cci::CCI_IMMUTABLE_PARAM>*> r_target_index; ///< Router table target index
std::vector<cci::cci_param<unsigned int, cci::CCI_IMMUTABLE_PARAM>*> r_addr_start; ///< Router table start address
std::vector<cci::cci_param<unsigned int, cci::CCI_IMMUTABLE_PARAM>*> r_addr_end; ///< Router table end address
std::vector<cci::cci_param<unsigned int, cci::CCI_IMMUTABLE_PARAM>*> r_target_index; ///< Router table target index
std::vector<cci::cci_param<unsigned int, cci::CCI_IMMUTABLE_PARAM>*> r_addr_start; ///< Router table start address
std::vector<cci::cci_param<unsigned int, cci::CCI_IMMUTABLE_PARAM>*> r_addr_end; ///< Router table end address
cci::cci_param_handle base_handle; ///< CCI base parameter handle for target base address
@ -170,6 +174,6 @@ private:
int addrSize;
char stringName[50];
};
// router
// router
#endif // EXAMPLES_EX09_HIERARCHICAL_OVERRIDE_OF_PARAMETER_VALUES_ROUTER_H_
#endif // EXAMPLES_EX09_HIERARCHICAL_OVERRIDE_OF_PARAMETER_VALUES_ROUTER_H_

View File

@ -31,10 +31,9 @@
* @date 29th April, 2011 (Friday)
*/
#include <cci_configuration>
#include <cci_utils/broker.h>
#include <string>
#include "top_module.h"
#include <cci_configuration>
#include <string>
/**
* @fn int sc_main(int argc, char* argv[])
@ -43,7 +42,7 @@
* @param argv The list of input arguments
* @return An integer for the execution status
*/
int sc_main(int sc_argc, char *sc_argv[]) {
int sc_main(int sc_argc, char* sc_argv[]) {
scc::init_logging(scc::log::INFO);
cci::cci_originator me = cci::cci_originator("sc_main");
// Get handle to the default broker
@ -83,4 +82,4 @@ int sc_main(int sc_argc, char *sc_argv[]) {
SCCINFO("sc_main") << "End Simulation.";
return EXIT_SUCCESS;
} // End of 'sc_main'
} // End of 'sc_main'

View File

@ -32,10 +32,10 @@
#define EXAMPLES_EX09_HIERARCHICAL_OVERRIDE_OF_PARAMETER_VALUES_TARGET_H_
#include <cci_configuration>
#include <tlm>
#include <string>
#include <tlm_utils/simple_target_socket.h>
#include <scc/report.h>
#include <string>
#include <tlm>
#include <tlm_utils/simple_target_socket.h>
/**
* @class target
@ -47,8 +47,10 @@ public:
sc_core::sc_time read_latency, write_latency;
SC_CTOR(target)
:
target_socket("target_socket"), target_ID("target_ID", "target_default"), s_base_addr("s_base_addr", 0), s_size("s_size", 256) {
: target_socket("target_socket")
, target_ID("target_ID", "target_default")
, s_base_addr("s_base_addr", 0)
, s_size("s_size", 256) {
SCCINFO(SCMOD) << "[" << target_ID.get_value() << " C_TOR] ------- [TARGET CONSTRUCTOR BEGINS HERE] --------";
SCCINFO(SCMOD) << "[" << target_ID.get_value() << " C_TOR] : Base Address : " << s_base_addr.get_value();
@ -60,7 +62,7 @@ public:
mem = new int[s_size.get_value()];
for (unsigned int i = 0; i < s_size.get_value(); i++)
for(unsigned int i = 0; i < s_size.get_value(); i++)
mem[i] = 0xAABBCCDD | i;
// target's SC_THREAD declaration
@ -72,8 +74,7 @@ public:
* @brief The run thread of the modeul (does nothing)
* @return void
*/
void run_target(void) {
}
void run_target(void) {}
/**
* @fn void b_transport(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay)
@ -82,49 +83,49 @@ public:
* @param delay The annotated delay associated with the transaction
* @return void
*/
void b_transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {
void b_transport(tlm::tlm_generic_payload & trans, sc_core::sc_time & delay) {
tlm::tlm_command cmd = trans.get_command();
sc_dt::uint64 adr = trans.get_address() - s_base_addr.get_value();
unsigned char *ptr = trans.get_data_ptr();
unsigned char* ptr = trans.get_data_ptr();
unsigned int len = trans.get_data_length();
unsigned char *byt = trans.get_byte_enable_ptr();
unsigned char* byt = trans.get_byte_enable_ptr();
unsigned int wid = trans.get_streaming_width();
SCCINFO(SCMOD) << "[TARGET] : adr ---- " << std::hex << adr;
SCCINFO(SCMOD) << "[TARGET] : base addr ---- " << std::hex << s_base_addr.get_value();
// Check for storage address overflow
if (adr > s_size.get_value()) {
if(adr > s_size.get_value()) {
trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
return;
}
// Target unable to support byte enable attribute
if (byt) {
if(byt) {
trans.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE);
return;
}
// Target unable to support streaming width attribute
if (wid < len) {
if(wid < len) {
trans.set_response_status(tlm::TLM_BURST_ERROR_RESPONSE);
return;
}
if (cmd == tlm::TLM_READ_COMMAND) {
if(cmd == tlm::TLM_READ_COMMAND) {
memcpy(ptr, &mem[adr], len);
delay = delay + read_latency;
} else
if (cmd == tlm::TLM_WRITE_COMMAND) {
memcpy(&mem[adr], ptr, len);
delay = delay + write_latency;
}
} else if(cmd == tlm::TLM_WRITE_COMMAND) {
memcpy(&mem[adr], ptr, len);
delay = delay + write_latency;
}
trans.set_response_status(tlm::TLM_OK_RESPONSE);
}
private:
cci::cci_param<std::string, cci::CCI_MUTABLE_PARAM> target_ID; ///< Elaboration Time Param for assigning target ID (initialized by top_module)
cci::cci_param<std::string, cci::CCI_MUTABLE_PARAM>
target_ID; ///< Elaboration Time Param for assigning target ID (initialized by top_module)
cci::cci_param<int, cci::CCI_MUTABLE_PARAM> s_base_addr; ///< Mutable time param for setting target's base addr (initialized by router)
@ -140,8 +141,8 @@ private:
s_base_addr.lock();
}
int *mem;
int* mem;
};
// target
// target
#endif // EXAMPLES_EX09_HIERARCHICAL_OVERRIDE_OF_PARAMETER_VALUES_TARGET_H_
#endif // EXAMPLES_EX09_HIERARCHICAL_OVERRIDE_OF_PARAMETER_VALUES_TARGET_H_

View File

@ -32,13 +32,13 @@
#define EXAMPLES_EX09_HIERARCHICAL_OVERRIDE_OF_PARAMETER_VALUES_TOP_MODULE_H_
#include <cci_configuration>
#include <scc/report.h>
#include <sstream>
#include <tlm>
#include <vector>
#include <sstream>
#include <scc/report.h>
#include "router.h"
#include "initiator.h"
#include "router.h"
#include "target.h"
/**
@ -52,8 +52,9 @@ public:
* @brief The class constructor
*/
SC_CTOR(top_module)
:
n_initiators("number_of_initiators", 0), n_targets("number_of_targets", 0), m_broker(cci::cci_get_broker()) {
: n_initiators("number_of_initiators", 0)
, n_targets("number_of_targets", 0)
, m_broker(cci::cci_get_broker()) {
std::stringstream ss;
SCCINFO(SCMOD) << "[TOP_MODULE C_TOR] -- [TOP MODULE CONSTRUCTOR BEGINS HERE]";
@ -80,14 +81,14 @@ public:
// ----------------------------------------------------------------
cci::cci_param_handle r_addr_limit_handle = m_broker.get_param_handle("top_module_inst.RouterInstance.addr_limit");
if (r_addr_limit_handle.is_valid()) {
if(r_addr_limit_handle.is_valid()) {
r_addr_max = atoi((r_addr_limit_handle.get_cci_value().to_json()).c_str());
SCCINFO(SCMOD) << "[TOP_MODULE C_TOR] : Router's maximum addressable limit : " << r_addr_max;
}
/// Creating instances of initiator(s)
for (int i = 0; i < n_initiators; i++) {
for(int i = 0; i < n_initiators; i++) {
snprintf(initiatorName, sizeof(initiatorName), "initiator_%d", i);
SCCINFO(SCMOD) << "[TOP_MODULE C_TOR] : Creating initiator : " << initiatorName;
@ -107,7 +108,7 @@ public:
targetSize = 128;
// Creating instances of target(s)
for (int i = 0; i < n_targets; i++) {
for(int i = 0; i < n_targets; i++) {
snprintf(targetName, sizeof(targetName), "target_%d", i);
SCCINFO(SCMOD) << "[TOP_MODULE C_TOR] : Creating target : " << targetName;
@ -131,7 +132,7 @@ public:
}
// Try re-setting locked values for Router Table contents
for (int i = 0; i < n_targets; i++) {
for(int i = 0; i < n_targets; i++) {
snprintf(targetName, sizeof(targetName), "%s.RouterInstance.r_index_%d", name(), i);
ss.clear();
ss.str("");
@ -140,7 +141,7 @@ public:
try {
SCCINFO(SCMOD) << "[TOP_MODULE C_TOR] : Re-setting fields of target_" << i;
m_broker.set_preset_cci_value(targetName, cci::cci_value::from_json(ss.str()));
} catch (sc_core::sc_report const &exception) {
} catch(sc_core::sc_report const& exception) {
SCCINFO(SCMOD) << "[ROUTER : Caught] : " << exception.what();
}
@ -157,7 +158,7 @@ public:
try {
SCCINFO(SCMOD) << "[TOP_MODULE C_TOR] : Re-setting start addr of target_" << i;
m_broker.set_preset_cci_value(targetName, cci::cci_value::from_json(ss.str()));
} catch (sc_core::sc_report const &exception) {
} catch(sc_core::sc_report const& exception) {
SCCINFO(SCMOD) << "[ROUTER : Caught] : " << exception.what();
}
@ -169,7 +170,7 @@ public:
try {
SCCINFO(SCMOD) << "[TOP_MODULE C_TOR] : Re-setting end addr of target_" << i;
m_broker.set_preset_cci_value(targetName, cci::cci_value::from_json(ss.str()));
} catch (sc_core::sc_report const &exception) {
} catch(sc_core::sc_report const& exception) {
SCCINFO(SCMOD) << "[ROUTER : Caught] : " << exception.what();
}
}
@ -181,16 +182,16 @@ public:
* @return void
*/
~top_module() {
if (!initiatorList.empty()) {
for (std::vector<initiator*>::iterator it = initiatorList.begin(); it != initiatorList.end(); ++it) {
delete (*it);
if(!initiatorList.empty()) {
for(std::vector<initiator*>::iterator it = initiatorList.begin(); it != initiatorList.end(); ++it) {
delete(*it);
}
initiatorList.clear();
}
if (!targetList.empty()) {
for (std::vector<target*>::iterator it = targetList.begin(); it != targetList.end(); ++it) {
delete (*it);
if(!targetList.empty()) {
for(std::vector<target*>::iterator it = targetList.begin(); it != targetList.end(); ++it) {
delete(*it);
}
targetList.clear();
}
@ -199,26 +200,25 @@ public:
private:
// Immutable type cci-parameters
cci::cci_param<int, cci::CCI_IMMUTABLE_PARAM> n_initiators; ///< Number of initiators to be instantiated
cci::cci_param<int, cci::CCI_IMMUTABLE_PARAM> n_targets; ///< Number of targets to be instantiated
cci::cci_param<int, cci::CCI_IMMUTABLE_PARAM> n_targets; ///< Number of targets to be instantiated
cci::cci_broker_handle m_broker; ///< Configuration broker handle
router *routerInstance; ///< Declaration of a router pointer
router* routerInstance; ///< Declaration of a router pointer
// STD::VECTORs for creating instances of initiator and target
std::vector<initiator*> initiatorList; ///< STD::VECTOR for initiators
std::vector<target*> targetList; ///< STD::VECTOR for targets
std::vector<initiator*> initiatorList; ///< STD::VECTOR for initiators
std::vector<target*> targetList; ///< STD::VECTOR for targets
char initiatorName[50]; ///< initiator_ID
char targetName[50]; ///< target_ID
char stringMisc[50]; ///< String to be used for misc things
char targetBaseAddr[50]; ///< The base address of the target
char initiatorName[50]; ///< initiator_ID
char targetName[50]; ///< target_ID
char stringMisc[50]; ///< String to be used for misc things
char targetBaseAddr[50]; ///< The base address of the target
int addrValue
{ 0 }; ///< Address Value
int targetSize; ///< Maximum target Size (preset value)
int r_addr_max; ///< Maximum Router Table's memory range
int addrValue{0}; ///< Address Value
int targetSize; ///< Maximum target Size (preset value)
int r_addr_max; ///< Maximum Router Table's memory range
};
// top_module
// top_module
#endif // EXAMPLES_EX09_HIERARCHICAL_OVERRIDE_OF_PARAMETER_VALUES_TOP_MODULE_H_
#endif // EXAMPLES_EX09_HIERARCHICAL_OVERRIDE_OF_PARAMETER_VALUES_TOP_MODULE_H_

View File

@ -0,0 +1,3 @@
add_executable (configurer sc_main.cpp)
target_link_libraries (configurer LINK_PUBLIC scc-sysc)
add_test(NAME configurer_test COMMAND configurer ${CMAKE_CURRENT_SOURCE_DIR}/test.yaml)

View File

@ -0,0 +1,74 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
****************************************************************************/
#ifndef SC_INCLUDE_DYNAMIC_PROCESSES
#define SC_INCLUDE_DYNAMIC_PROCESSES
#endif
/**
* @file main.cpp
* @brief Testbench file
* This file declares and implements the functionality of the target.
* Few of the parameters of the target sc_module are configured by the
* router sc_module.
* @author P V S Phaneendra, CircuitSutra Technologies <pvs@circuitsutra.com>
* @date 29th April, 2011 (Friday)
*/
#include <scc/cci_util.h>
#include <scc/configurer.h>
#include <string>
DEFINE_ENUM4CCI(trace_lvl, (NONE)(LOW)(MEDIUM)(HIGH)(FULL))
DEFINE_NS_ENUM4CCI(test, log_lvl, (NONE)(LOW)(MEDIUM)(HIGH)(FULL))
/**
* @fn int sc_main(int argc, char* argv[])
* @brief The testbench for the hierarchical override of parameter values example
* @param argc The number of input arguments
* @param argv The list of input arguments
* @return An integer for the execution status
*/
int sc_main(int sc_argc, char* sc_argv[]) {
scc::init_logging(scc::log::INFO);
scc::configurer cfg(sc_argc == 2 ? sc_argv[1] : "test.yaml");
cfg.dump_configuration("dump.yaml", true);
cci::cci_originator sc_main_orig("SC_MAIN");
cci::cci_param<int> int_param0{"int_param0", 0, "This is parameter 1", cci::CCI_ABSOLUTE_NAME, sc_main_orig};
cci::cci_param<int> int_param1{"int_param1", 1, "This is parameter 3", cci::CCI_ABSOLUTE_NAME, sc_main_orig};
cci::cci_param<int64_t> int64_param0{"int64_param0", 10, "This is parameter 2", cci::CCI_ABSOLUTE_NAME, sc_main_orig};
cci::cci_param<int64_t> int64_param1{"int64_param1", 10, "This is parameter 4", cci::CCI_ABSOLUTE_NAME, sc_main_orig};
cci::cci_param<unsigned> unsigned_param{"unsigned_param", 1, "This is parameter 5", cci::CCI_ABSOLUTE_NAME, sc_main_orig};
cci::cci_param<uint64_t> uint64_param{"uint64_param", 1, "This is parameter 6", cci::CCI_ABSOLUTE_NAME, sc_main_orig};
cci::cci_param<float> float_param{"float_param", 4, "This is parameter 7", cci::CCI_ABSOLUTE_NAME, sc_main_orig};
cci::cci_param<double> double_param{"double_param", 4, "This is parameter 7", cci::CCI_ABSOLUTE_NAME, sc_main_orig};
cci::cci_param<std::string> string_param{"string_param", "", "This is parameter 7", cci::CCI_ABSOLUTE_NAME, sc_main_orig};
cci::cci_param<sc_core::sc_time> sc_time_param{"sc_time_param", sc_core::SC_ZERO_TIME, "This is parameter 7", cci::CCI_ABSOLUTE_NAME,
sc_main_orig};
cci::cci_param<trace_lvl> trace_lvl_param{"trace_lvl_param", trace_lvl::NONE, "This is parameter 8", cci::CCI_ABSOLUTE_NAME,
sc_main_orig};
cci::cci_param<test::log_lvl> test_log_lvl_param{"test_log_lvl_param", test::log_lvl::NONE, "This is parameter 9",
cci::CCI_ABSOLUTE_NAME, sc_main_orig};
// Start the simulation
SCCINFO("sc_main") << "Begin Simulation.";
sc_core::sc_start(sc_core::SC_ZERO_TIME);
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'

View File

@ -0,0 +1,11 @@
int_param0: 1
int_param1: -1
int64_param0: 2
int64_param1: -2
unsigned_param: 3
uint64_param: 4
float_param: 5.0
double_param: 6
string_param: test entry
sc_time_param: 10 ns
trace_lvl_param: MEDIUM

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,24 @@
/*
* main.cpp
*
* Created on: 01.01.2019
* Author: eyck
*/
#include <cassert>
#include <cstdio>
#include <iostream>
#include <util/io-redirector.h>
using namespace util;
int main(int arcg, char* argv[]) {
IoRedirector::get().start();
auto result1 = IoRedirector::get().get_output();
assert(result1 == "");
printf("Some output");
std::cout << "Some other output" << std::endl;
auto result2 = IoRedirector::get().get_output();
assert(result2 == "Some outputSome other output\n");
IoRedirector::get().stop();
}

View File

@ -1,17 +1,17 @@
#define CATCH_CONFIG_MAIN
#include <catch2/catch_all.hpp>
#include <util/io-redirector.h>
#include <iostream>
#include <cstdio>
#include <iostream>
#include <util/io-redirector.h>
TEST_CASE( "io-redirector", "[io-redirector]" ) {
TEST_CASE("io-redirector", "[io-redirector]") {
util::IoRedirector::get().start();
auto result1 = util::IoRedirector::get().get_output();
printf("Some output");
std::cout<<"Some other output"<<std::endl;
std::cout << "Some other output" << std::endl;
auto result2 = util::IoRedirector::get().get_output();
util::IoRedirector::get().stop();
REQUIRE( result1=="" );
REQUIRE( result2=="Some outputSome other output\n" );
REQUIRE(result1 == "");
REQUIRE(result2 == "Some outputSome other output\n");
}

View File

@ -1,15 +1,19 @@
#ifndef SC_INCLUDE_DYNAMIC_PROCESSES
#define SC_INCLUDE_DYNAMIC_PROCESSES
#endif
#include <catch2/catch_all.hpp>
#include <factory.h>
#include <scc/ordered_semaphore.h>
#include <scc/utilities.h>
#include <factory.h>
#include <catch2/catch_all.hpp>
#include <systemc>
using namespace sc_core;
struct top: public sc_core::sc_module {
top():top("top"){}
top(sc_module_name const& nm):sc_core::sc_module(nm) {}
struct top : public sc_core::sc_module {
top()
: top("top") {}
top(sc_module_name const& nm)
: sc_core::sc_module(nm) {}
scc::ordered_semaphore sem{"sem", 2};
scc::ordered_semaphore_t<2> sem_t{"sem_t"};
};
@ -19,7 +23,7 @@ factory::add<top> tb;
TEST_CASE("simple ordered_semaphore test", "[SCC][ordered_semaphore]") {
auto& dut = factory::get<top>();
auto run1 = sc_spawn([&dut](){
auto run1 = sc_spawn([&dut]() {
dut.sem.wait();
dut.sem_t.wait();
dut.sem.set_capacity(4);

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'

View File

@ -14,20 +14,18 @@ struct packet {
std::vector<uint8_t> routing;
};
struct packet_ext: public tlm::tlm_extension<packet_ext>, public packet {
struct packet_ext : public tlm::tlm_extension<packet_ext>, public packet {
packet_ext() = default;
packet_ext& operator=(packet_ext const& o) = default;
tlm_extension_base* clone() const override {
return new packet_ext(*this);
}
tlm_extension_base* clone() const override { return new packet_ext(*this); }
void copy_from(tlm_extension_base const & o) override {
void copy_from(tlm_extension_base const& o) override {
auto* ext = dynamic_cast<packet_ext const*>(&o);
if(ext)
this->routing=ext->routing;
this->routing = ext->routing;
}
};

View File

@ -12,88 +12,85 @@
using namespace sc_core;
pkt_sender::pkt_sender(const sc_core::sc_module_name &nm, unsigned dim, unsigned pos_x, unsigned pos_y, unsigned count)
pkt_sender::pkt_sender(const sc_core::sc_module_name& nm, unsigned dim, unsigned pos_x, unsigned pos_y, unsigned count)
: sc_module(nm)
, bw_peq("bw_peq")
, fw_peq("fw_peq")
, my_pos{pos_x,pos_y}
, my_pos{pos_x, pos_y}
, dim{dim}
, count{count}
{
SCCDEBUG(SCMOD)<<"instantiating sender "<<pos_x<<"/"<<pos_y;
, count{count} {
SCCDEBUG(SCMOD) << "instantiating sender " << pos_x << "/" << pos_y;
SC_HAS_PROCESS(pkt_sender);
isck.register_nb_transport_bw([this](tlm::tlm_generic_payload &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay)->tlm::tlm_sync_enum{
return this->nb_bw(gp, phase, delay);
});
tsck.register_nb_transport_fw([this](tlm::tlm_generic_payload &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay)->tlm::tlm_sync_enum{
return this->nb_fw(gp, phase, delay);
});
isck.register_nb_transport_bw([this](tlm::tlm_generic_payload& gp, tlm::tlm_phase& phase,
sc_core::sc_time& delay) -> tlm::tlm_sync_enum { return this->nb_bw(gp, phase, delay); });
tsck.register_nb_transport_fw([this](tlm::tlm_generic_payload& gp, tlm::tlm_phase& phase,
sc_core::sc_time& delay) -> tlm::tlm_sync_enum { return this->nb_fw(gp, phase, delay); });
SC_METHOD(received);
sensitive<<fw_peq.get_event();
sensitive << fw_peq.get_event();
dont_initialize();
SC_THREAD(run);
}
void pkt_sender::gen_routing(std::vector<uint8_t> &route_vec) {
if(std::get<0>(my_pos)==0){
for(auto i=0; i<dim; ++i)
void pkt_sender::gen_routing(std::vector<uint8_t>& route_vec) {
if(std::get<0>(my_pos) == 0) {
for(auto i = 0; i < dim; ++i)
route_vec.push_back(RIGHT);
} else if(std::get<0>(my_pos)==dim+1){
for(auto i=0; i<dim; ++i)
} else if(std::get<0>(my_pos) == dim + 1) {
for(auto i = 0; i < dim; ++i)
route_vec.push_back(LEFT);
} else if(std::get<1>(my_pos)==0){
for(auto i=0; i<dim; ++i)
} else if(std::get<1>(my_pos) == 0) {
for(auto i = 0; i < dim; ++i)
route_vec.push_back(BOTTOM);
} else if(std::get<1>(my_pos)==dim+1){
for(auto i=0; i<dim; ++i)
} else if(std::get<1>(my_pos) == dim + 1) {
for(auto i = 0; i < dim; ++i)
route_vec.push_back(TOP);
} else
SCCERR(SCMOD)<<"WTF!?!";
SCCERR(SCMOD) << "WTF!?!";
}
void pkt_sender::run() {
wait(clk_i.posedge_event());
for(auto i=0U; i<count; i++){
for(auto i = 0U; i < count; i++) {
tlm::tlm_generic_payload* gp = tlm::scc::tlm_mm<>::get().allocate<packet_ext>();
gen_routing(gp->get_extension<packet_ext>()->routing);
tlm::tlm_phase phase{tlm::BEGIN_REQ};
sc_time delay;
gp->acquire();
auto sync = isck->nb_transport_fw(*gp, phase, delay);
sc_assert(sync==tlm::TLM_UPDATED && phase==tlm::END_REQ);
sc_assert(sync == tlm::TLM_UPDATED && phase == tlm::END_REQ);
tlm::tlm_generic_payload* ret{nullptr};
while(!(ret=bw_peq.get_next_transaction())){
while(!(ret = bw_peq.get_next_transaction())) {
wait(bw_peq.get_event());
}
sc_assert(gp==ret);
sc_assert(gp == ret);
ret->release();
}
finish_evt.notify(SC_ZERO_TIME);
}
tlm::tlm_sync_enum pkt_sender::nb_bw(tlm::tlm_generic_payload &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay) {
sc_assert(phase==tlm::BEGIN_RESP);
tlm::tlm_sync_enum pkt_sender::nb_bw(tlm::tlm_generic_payload& gp, tlm::tlm_phase& phase, sc_core::sc_time& delay) {
sc_assert(phase == tlm::BEGIN_RESP);
bw_peq.notify(gp, delay);
phase=tlm::END_RESP;
phase = tlm::END_RESP;
return tlm::TLM_COMPLETED;
}
tlm::tlm_sync_enum pkt_sender::nb_fw(tlm::tlm_generic_payload &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay) {
sc_assert(phase==tlm::BEGIN_REQ);
tlm::tlm_sync_enum pkt_sender::nb_fw(tlm::tlm_generic_payload& gp, tlm::tlm_phase& phase, sc_core::sc_time& delay) {
sc_assert(phase == tlm::BEGIN_REQ);
auto ext = gp.get_extension<packet_ext>();
sc_assert(ext->routing.size()==0);
sc_assert(ext->routing.size() == 0);
gp.acquire();
fw_peq.notify(gp, delay);
phase=tlm::END_REQ;
phase = tlm::END_REQ;
return tlm::TLM_UPDATED;
}
void pkt_sender::received() {
if(auto gp = fw_peq.get_next_transaction()){
if(auto gp = fw_peq.get_next_transaction()) {
tlm::tlm_phase phase{tlm::BEGIN_RESP};
sc_time delay;
auto sync = tsck->nb_transport_bw(*gp, phase, delay);
sc_assert(sync==tlm::TLM_COMPLETED && phase==tlm::END_RESP);
sc_assert(sync == tlm::TLM_COMPLETED && phase == tlm::END_RESP);
gp->release();
}
}

View File

@ -8,12 +8,11 @@
#ifndef _SIM_PERFORMANCE_PKT_SENDER_H_
#define _SIM_PERFORMANCE_PKT_SENDER_H_
#include <systemc>
#include "packet.h"
#include <systemc>
#include <tlm/scc/initiator_mixin.h>
#include <tlm/scc/target_mixin.h>
class pkt_sender : sc_core::sc_module {
public:
sc_core::sc_in<bool> clk_i{"clk_i"};
@ -21,7 +20,8 @@ public:
tlm::scc::target_mixin<tlm::tlm_target_socket<32>> tsck;
pkt_sender(sc_core::sc_module_name const&, unsigned dim, unsigned pos_x, unsigned pos_y, unsigned count);
virtual ~pkt_sender() = default;
sc_core::sc_event const& get_finish_event(){return finish_evt;}
sc_core::sc_event const& get_finish_event() { return finish_evt; }
private:
void run();
void gen_routing(std::vector<uint8_t>& route_vec);

View File

@ -14,63 +14,67 @@
using namespace sc_core;
pkt_switch::pkt_switch(const sc_core::sc_module_name &nm):sc_module(nm) {
pkt_switch::pkt_switch(const sc_core::sc_module_name& nm)
: sc_module(nm) {
SC_HAS_PROCESS(pkt_switch);
auto index = 0U;
for(auto& s:isck){
s.register_nb_transport_bw([this](unsigned id, tlm::tlm_generic_payload &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay)->tlm::tlm_sync_enum{
return this->nb_bw(id, gp, phase, delay);
}, index++);
for(auto& s : isck) {
s.register_nb_transport_bw([this](unsigned id, tlm::tlm_generic_payload& gp, tlm::tlm_phase& phase,
sc_core::sc_time& delay) -> tlm::tlm_sync_enum { return this->nb_bw(id, gp, phase, delay); },
index++);
}
index = 0U;
for(auto& s:tsck){
s.register_nb_transport_fw([this](unsigned id, tlm::tlm_generic_payload &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay)->tlm::tlm_sync_enum{
return this->nb_fw(id, gp, phase, delay);
}, index++);
for(auto& s : tsck) {
s.register_nb_transport_fw([this](unsigned id, tlm::tlm_generic_payload& gp, tlm::tlm_phase& phase,
sc_core::sc_time& delay) -> tlm::tlm_sync_enum { return this->nb_fw(id, gp, phase, delay); },
index++);
}
SC_METHOD(clock_cb);
sensitive<<clk_i.pos();
sensitive << clk_i.pos();
dont_initialize();
for(auto i=0U; i<SIDES; ++i){
for(auto i = 0U; i < SIDES; ++i) {
sc_core::sc_spawn_options opts;
opts.spawn_method();
opts.set_sensitivity(&out_fifo[i].data_written_event());
sc_core::sc_spawn([this, i]()->void {this->output_cb(i);}, sc_core::sc_gen_unique_name("out_peq"), &opts);
sc_core::sc_spawn([this, i]() -> void { this->output_cb(i); }, sc_core::sc_gen_unique_name("out_peq"), &opts);
}
}
tlm::tlm_sync_enum pkt_switch::nb_fw(unsigned id, tlm::tlm_generic_payload &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay) {
tlm::tlm_sync_enum pkt_switch::nb_fw(unsigned id, tlm::tlm_generic_payload& gp, tlm::tlm_phase& phase, sc_core::sc_time& delay) {
in_tx[id].write(&gp);
if(phase==tlm::BEGIN_REQ) phase=tlm::END_REQ;
else SCCERR(SCMOD)<<"WTF!?!";
if(phase == tlm::BEGIN_REQ)
phase = tlm::END_REQ;
else
SCCERR(SCMOD) << "WTF!?!";
return tlm::TLM_UPDATED;
}
void pkt_switch::clock_cb() {
std::array<std::vector<unsigned>, SIDES> routing{};
bool nothing_todo=true;
for(auto i=0U; i<SIDES; ++i){
if(auto gp = in_tx[i].read()){
bool nothing_todo = true;
for(auto i = 0U; i < SIDES; ++i) {
if(auto gp = in_tx[i].read()) {
auto ext = gp->get_extension<packet_ext>();
sc_assert(ext);
routing[ext->routing.back()].push_back(i);
nothing_todo = false;
}
}
if(nothing_todo) return;
for(auto i=0U; i<SIDES; ++i){
if(routing[i].size()){
auto selected_input=routing[i].front();
if(nothing_todo)
return;
for(auto i = 0U; i < SIDES; ++i) {
if(routing[i].size()) {
auto selected_input = routing[i].front();
auto* gp = in_tx[selected_input].read();
if(out_fifo[i].nb_write(gp)){
if(out_fifo[i].nb_write(gp)) {
auto ext = gp->get_extension<packet_ext>();
ext->routing.pop_back();
gp->acquire();
tlm::tlm_phase phase{tlm::BEGIN_RESP};
sc_core::sc_time delay;
auto res = tsck[selected_input]->nb_transport_bw(*gp, phase, delay);
if(res!=tlm::TLM_COMPLETED && !(res==tlm::TLM_UPDATED && phase==tlm::END_RESP))
SCCERR(SCMOD)<<"WTF!?!";
if(res != tlm::TLM_COMPLETED && !(res == tlm::TLM_UPDATED && phase == tlm::END_RESP))
SCCERR(SCMOD) << "WTF!?!";
in_tx[selected_input].clear();
}
}
@ -79,18 +83,18 @@ void pkt_switch::clock_cb() {
void pkt_switch::output_cb(unsigned id) {
if(out_fifo[id].num_available()){
if(out_fifo[id].num_available()) {
auto* gp = out_fifo[id].read();
tlm::tlm_phase phase{tlm::BEGIN_REQ};
sc_time delay;
auto sync = isck[id]->nb_transport_fw(*gp, phase, delay);
sc_assert(sync==tlm::TLM_UPDATED && phase==tlm::END_REQ);
sc_assert(sync == tlm::TLM_UPDATED && phase == tlm::END_REQ);
}
}
tlm::tlm_sync_enum pkt_switch::nb_bw(unsigned id, tlm::tlm_generic_payload &gp, tlm::tlm_phase &phase, sc_core::sc_time &delay) {
tlm::tlm_sync_enum pkt_switch::nb_bw(unsigned id, tlm::tlm_generic_payload& gp, tlm::tlm_phase& phase, sc_core::sc_time& delay) {
gp.release();
sc_assert(phase==tlm::BEGIN_RESP);
phase=tlm::END_RESP;
sc_assert(phase == tlm::BEGIN_RESP);
phase = tlm::END_RESP;
return tlm::TLM_COMPLETED;
}

View File

@ -8,22 +8,22 @@
#ifndef _SIM_PERFORMANCE_PKT_SWITCH_H_
#define _SIM_PERFORMANCE_PKT_SWITCH_H_
#include <systemc>
#include "packet.h"
#include <array>
#include <scc/sc_owning_signal.h>
#include <systemc>
#include <tlm/scc/tagged_initiator_mixin.h>
#include <tlm/scc/tagged_target_mixin.h>
#include <scc/sc_owning_signal.h>
#include <array>
class pkt_switch : sc_core::sc_module {
public:
enum {NONE=std::numeric_limits<unsigned>::max()};
enum { NONE = std::numeric_limits<unsigned>::max() };
sc_core::sc_in<bool> clk_i{"clk_i"};
sc_core::sc_vector<tlm::scc::tagged_target_mixin<tlm::tlm_target_socket<32>>> tsck{"tsck",4};
sc_core::sc_vector<tlm::scc::tagged_initiator_mixin<tlm::tlm_initiator_socket<32>>> isck{"isck",4};
sc_core::sc_vector<tlm::scc::tagged_target_mixin<tlm::tlm_target_socket<32>>> tsck{"tsck", 4};
sc_core::sc_vector<tlm::scc::tagged_initiator_mixin<tlm::tlm_initiator_socket<32>>> isck{"isck", 4};
pkt_switch(sc_core::sc_module_name const&);
virtual ~pkt_switch() = default;
private:
void clock_cb();
void output_cb(unsigned);

View File

@ -21,10 +21,10 @@
*/
#include "top.h"
#include <boost/program_options.hpp>
#include <scc/perf_estimator.h>
#include <scc/report.h>
#include <scc/tracer.h>
#include <boost/program_options.hpp>
using namespace scc;
namespace po = boost::program_options;
@ -35,8 +35,8 @@ const size_t SUCCESS = 0;
const size_t ERROR_UNHANDLED_EXCEPTION = 2;
} // namespace
int sc_main(int argc, char *argv[]) {
sc_core::sc_report_handler::set_actions( "/IEEE_Std_1666/deprecated", sc_core::SC_DO_NOTHING );
int sc_main(int argc, char* argv[]) {
sc_core::sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", sc_core::SC_DO_NOTHING);
sc_core::sc_report_handler::set_actions(sc_core::SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, sc_core::SC_DO_NOTHING);
///////////////////////////////////////////////////////////////////////////
// CLI argument parsing
@ -54,13 +54,13 @@ int sc_main(int argc, char *argv[]) {
try {
po::store(po::parse_command_line(argc, argv, desc), vm); // can throw
// --help option
if (vm.count("help")) {
if(vm.count("help")) {
std::cout << "JIT-ISS simulator for AVR" << 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) {
} catch(po::error& e) {
std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
std::cerr << desc << std::endl;
return ERROR_IN_COMMAND_LINE;
@ -68,20 +68,20 @@ int sc_main(int argc, char *argv[]) {
///////////////////////////////////////////////////////////////////////////
// configure logging
///////////////////////////////////////////////////////////////////////////
scc::init_logging(vm.count("debug")?scc::log::DEBUG:scc::log::INFO);
scc::init_logging(vm.count("debug") ? scc::log::DEBUG : scc::log::INFO);
///////////////////////////////////////////////////////////////////////////
// set up tracing & transaction recording
///////////////////////////////////////////////////////////////////////////
//tracer trace("simple_system", tracer::TEXT, vm.count("trace"));
// todo: fix displayed clock period in VCD
// tracer trace("simple_system", tracer::TEXT, vm.count("trace"));
// todo: fix displayed clock period in VCD
try {
///////////////////////////////////////////////////////////////////////////
// instantiate top level
///////////////////////////////////////////////////////////////////////////
perf_estimator estimator;
auto const count=vm["count"].as<unsigned>();
auto const count = vm["count"].as<unsigned>();
auto const dim = vm["dim"].as<unsigned>();
SCCINFO()<<"Instantiating "<<(unsigned)dim<<"x"<<(unsigned)dim<<" matrix and executing "<<count<<" accesses";
SCCINFO() << "Instantiating " << (unsigned)dim << "x" << (unsigned)dim << " matrix and executing " << count << " accesses";
top i_top("i_top", dim, count);
///////////////////////////////////////////////////////////////////////////
// run simulation

View File

@ -6,34 +6,35 @@
*/
#include "top.h"
#include <scc/utilities.h>
#include <scc/report.h>
#include <fmt/format.h>
#include <scc/report.h>
#include <scc/utilities.h>
using namespace sc_core;
using namespace fmt;
top::top(sc_core::sc_module_name const& nm, uint8_t dimension,unsigned count) :sc_module(nm){
sc_assert(dimension>0);
top::top(sc_core::sc_module_name const& nm, uint8_t dimension, unsigned count)
: sc_module(nm) {
sc_assert(dimension > 0);
SC_HAS_PROCESS(top);
for(auto yidx=0U; yidx<dimension; ++yidx){
for(auto xidx=0U; xidx<dimension; ++xidx){
for(auto yidx = 0U; yidx < dimension; ++yidx) {
for(auto xidx = 0U; xidx < dimension; ++xidx) {
auto name = format("sw_{}_{}", xidx, yidx);
SCCDEBUG(SCMOD)<<"instantiating switch "<<xidx<<"/"<<yidx;
SCCDEBUG(SCMOD) << "instantiating switch " << xidx << "/" << yidx;
switches.push_back(scc::make_unique<pkt_switch>(sc_module_name(name.c_str())));
switches.back()->clk_i(clk);
}
}
for(auto yidx=0U; yidx<dimension; ++yidx){
for(auto xidx=0U; xidx<dimension; ++xidx){
auto& sw = switches[yidx*dimension+xidx];
if(xidx<dimension-1) {
auto& swr = switches[yidx*dimension+(xidx+1)];
for(auto yidx = 0U; yidx < dimension; ++yidx) {
for(auto xidx = 0U; xidx < dimension; ++xidx) {
auto& sw = switches[yidx * dimension + xidx];
if(xidx < dimension - 1) {
auto& swr = switches[yidx * dimension + (xidx + 1)];
sw->isck[RIGHT](swr->tsck[LEFT]);
swr->isck[LEFT](sw->tsck[RIGHT]);
}
if(yidx<dimension-1){
auto& swb = switches[(yidx+1)*dimension+xidx];
if(yidx < dimension - 1) {
auto& swb = switches[(yidx + 1) * dimension + xidx];
sw->isck[BOTTOM](swb->tsck[TOP]);
swb->isck[TOP](sw->tsck[BOTTOM]);
}
@ -41,42 +42,42 @@ top::top(sc_core::sc_module_name const& nm, uint8_t dimension,unsigned count) :s
}
auto yidx = 0U;
auto xidx = 0U;
for(xidx=0U; xidx<dimension; ++xidx){
auto name = format("snd_{}_{}", xidx+1, 0);
senders[TOP].push_back(scc::make_unique<pkt_sender>(sc_module_name(name.c_str()), dimension, xidx+1, 0, count));
for(xidx = 0U; xidx < dimension; ++xidx) {
auto name = format("snd_{}_{}", xidx + 1, 0);
senders[TOP].push_back(scc::make_unique<pkt_sender>(sc_module_name(name.c_str()), dimension, xidx + 1, 0, count));
auto& snd = senders[TOP].back();
snd->clk_i(clk);
auto& sw = switches[yidx*dimension+xidx];
auto& sw = switches[yidx * dimension + xidx];
snd->isck(sw->tsck[TOP]);
sw->isck[TOP](snd->tsck);
}
yidx=dimension-1;
for(xidx=0U; xidx<dimension; ++xidx){
auto name = format("snd_{}_{}", xidx+1, dimension+1);
senders[BOTTOM].push_back(scc::make_unique<pkt_sender>(sc_module_name(name.c_str()), dimension, xidx+1, dimension+1, count));
yidx = dimension - 1;
for(xidx = 0U; xidx < dimension; ++xidx) {
auto name = format("snd_{}_{}", xidx + 1, dimension + 1);
senders[BOTTOM].push_back(scc::make_unique<pkt_sender>(sc_module_name(name.c_str()), dimension, xidx + 1, dimension + 1, count));
auto& snd = senders[BOTTOM].back();
snd->clk_i(clk);
auto& sw = switches[yidx*dimension+xidx];
auto& sw = switches[yidx * dimension + xidx];
snd->isck(sw->tsck[BOTTOM]);
sw->isck[BOTTOM](snd->tsck);
}
xidx=0U;
for(yidx=0U; yidx<dimension; ++yidx){
auto name = format("snd_{}_{}", 0, yidx+1);
senders[LEFT].push_back(scc::make_unique<pkt_sender>(sc_module_name(name.c_str()), dimension, 0, yidx+1, count));
xidx = 0U;
for(yidx = 0U; yidx < dimension; ++yidx) {
auto name = format("snd_{}_{}", 0, yidx + 1);
senders[LEFT].push_back(scc::make_unique<pkt_sender>(sc_module_name(name.c_str()), dimension, 0, yidx + 1, count));
auto& snd = senders[LEFT].back();
snd->clk_i(clk);
auto& sw = switches[yidx*dimension+xidx];
auto& sw = switches[yidx * dimension + xidx];
snd->isck(sw->tsck[LEFT]);
sw->isck[LEFT](snd->tsck);
}
xidx=dimension-1;
for(yidx=0U; yidx<dimension; ++yidx){
auto name = format("snd_{}_{}", dimension+1, yidx+1);
senders[RIGHT].push_back(scc::make_unique<pkt_sender>(sc_module_name(name.c_str()), dimension, dimension+1, yidx+1, count));
xidx = dimension - 1;
for(yidx = 0U; yidx < dimension; ++yidx) {
auto name = format("snd_{}_{}", dimension + 1, yidx + 1);
senders[RIGHT].push_back(scc::make_unique<pkt_sender>(sc_module_name(name.c_str()), dimension, dimension + 1, yidx + 1, count));
auto& snd = senders[RIGHT].back();
snd->clk_i(clk);
auto& sw = switches[yidx*dimension+xidx];
auto& sw = switches[yidx * dimension + xidx];
snd->isck(sw->tsck[RIGHT]);
sw->isck[RIGHT](snd->tsck);
}
@ -85,12 +86,11 @@ top::top(sc_core::sc_module_name const& nm, uint8_t dimension,unsigned count) :s
void top::run() {
sc_event_and_list evt_list;
for(auto& sides:senders) {
for(auto& sender:sides){
evt_list&=sender->get_finish_event();
for(auto& sides : senders) {
for(auto& sender : sides) {
evt_list &= sender->get_finish_event();
}
}
wait(evt_list);
sc_stop();
}

View File

@ -8,17 +8,18 @@
#ifndef _SIM_PERFORMANCE_TOP_H_
#define _SIM_PERFORMANCE_TOP_H_
#include <systemc>
#include <memory>
#include <vector>
#include "pkt_sender.h"
#include "pkt_switch.h"
#include "types.h"
#include <memory>
#include <systemc>
#include <vector>
class top: public sc_core::sc_module {
class top : public sc_core::sc_module {
public:
top(sc_core::sc_module_name const&, uint8_t, unsigned);
virtual ~top() = default;
private:
void run();
sc_core::sc_clock clk;

View File

@ -8,6 +8,6 @@
#ifndef TESTS_SIM_PERFORMANCE_TYPES_H_
#define TESTS_SIM_PERFORMANCE_TYPES_H_
enum {TOP=0, RIGHT=1, BOTTOM=2, LEFT=3, SIDES=4};
enum { TOP = 0, RIGHT = 1, BOTTOM = 2, LEFT = 3, SIDES = 4 };
#endif /* TESTS_SIM_PERFORMANCE_TYPES_H_ */