Compare commits
83 Commits
1c486cf9ec
...
main
Author | SHA1 | Date | |
---|---|---|---|
c684bbf891 | |||
ea802247da | |||
5490f0203f | |||
9fcd203f87 | |||
2c18dd4d17 | |||
5be69cfa75 | |||
085423620d | |||
1eba464c61 | |||
2e4d0efb50 | |||
f8f1f2f54c | |||
a0bd767bc9 | |||
89920683e9 | |||
a8d883475d | |||
82b219f267 | |||
6df06684bc | |||
56024ae892 | |||
bc2ba8161d | |||
2043e43140 | |||
12f3ecd6f3 | |||
9a41d1ac80 | |||
614b1f9215 | |||
8f8e8f928c | |||
771f1fea26 | |||
c22518a1f4 | |||
99b0d443d0 | |||
8c25ce1ddf | |||
c6e480d134 | |||
29b8de6c16 | |||
08c9e36fae | |||
7ebfb5897c | |||
78d52ce741 | |||
e8def0bb86 | |||
e91e5de6ab | |||
53ed979fa3 | |||
c30656841c | |||
1e7f9cfc22 | |||
892554f1f3 | |||
c929dcb5ea | |||
f8bd40cd60 | |||
f82c3ce229 | |||
904d897773 | |||
aff456d6f4 | |||
f639576ac0 | |||
0992cefeb8 | |||
3a8a675bfd | |||
775cacf2b5 | |||
c6167118d5 | |||
f4506a064b | |||
90002786a4 | |||
d7ce4b9a8e | |||
e27b33947b | |||
7f508b1006 | |||
c0a95d0a57 | |||
1a7d7829ed | |||
7bad0c3381 | |||
1d8120b43b | |||
cd6100bd47 | |||
5b5feb51f5 | |||
b9c9e15166 | |||
288f0577f1 | |||
1f37801f05 | |||
6ecd234c2c | |||
6c07dd99ff | |||
f83e61aa1f | |||
e30a569cfa | |||
50bd12b4ec | |||
3f97fcc28c | |||
972eb6b001 | |||
c445c1cda1 | |||
19580227a9 | |||
af670d7004 | |||
56be3388a3 | |||
1e71d4c9d2 | |||
95faedd3d0 | |||
8895fa0c26 | |||
238bb2f23c | |||
ecf44871b7 | |||
f58a58d465 | |||
27ecf48ac0 | |||
66ca4222e0 | |||
c0d0dce683 | |||
0535f2e353 | |||
c72b02f99f |
@ -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
3
.clang-tidy
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
Checks: 'clang-diagnostic-*,clang-analyzer-*,clang-diagnostic-*,clang-analyzer-*'
|
||||
WarningsAsErrors: ''
|
152
.cproject
152
.cproject
@ -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>$<cmake4eclipse_dyn></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>$<cmake4eclipse_dyn></buildArguments>
|
||||
<buildTarget>format-check</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
</buildTargets>
|
||||
</storageModule>
|
||||
</cproject>
|
10
.envrc
Normal file
10
.envrc
Normal 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
8
.gitignore
vendored
@ -40,3 +40,11 @@
|
||||
/*.vcd
|
||||
/.venv/
|
||||
/.pydevproject
|
||||
/*.fst
|
||||
/*.ftr
|
||||
/*.gtkw
|
||||
/.envrc.*
|
||||
/.direnv/
|
||||
/.venv/
|
||||
/.cache
|
||||
/CMakeUserPresets.json
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -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
|
||||
|
1
.project
1
.project
@ -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
25
.vscode/launch.json
vendored
Normal 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
16
.vscode/tasks.json
vendored
Normal 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",
|
||||
}
|
||||
]
|
||||
}
|
@ -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
40
CMakePresets.json
Normal 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
101
Jenkinsfile
vendored
Normal 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>
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
|
57
README.md
57
README.md
@ -1,50 +1,21 @@
|
||||
[](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
1
cmake-conan
Submodule
Submodule cmake-conan added at c22bbf0af0
44
conanfile.txt
Normal file
44
conanfile.txt
Normal 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
3
requirements.txt
Normal file
@ -0,0 +1,3 @@
|
||||
conan>=2.0
|
||||
cmake
|
||||
clang-format==14.0
|
2
scc
2
scc
Submodule scc updated: e510457db9...bccc9269ff
@ -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();
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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()
|
||||
|
9
tests/ace_pin_level/CMakeLists.txt
Normal file
9
tests/ace_pin_level/CMakeLists.txt
Normal 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})
|
275
tests/ace_pin_level/ace_narrow_burst_test.cpp
Normal file
275
tests/ace_pin_level/ace_narrow_burst_test.cpp
Normal 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]));
|
||||
}
|
||||
}
|
104
tests/ace_pin_level/testbench.h
Normal file
104
tests/ace_pin_level/testbench.h
Normal 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_
|
9
tests/ahb_pin_level/CMakeLists.txt
Normal file
9
tests/ahb_pin_level/CMakeLists.txt
Normal 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})
|
251
tests/ahb_pin_level/bus_test.cpp
Normal file
251
tests/ahb_pin_level/bus_test.cpp
Normal 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]));
|
||||
}
|
||||
}
|
||||
}
|
78
tests/ahb_pin_level/testbench.h
Normal file
78
tests/ahb_pin_level/testbench.h
Normal 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_
|
9
tests/apb_pin_level/CMakeLists.txt
Normal file
9
tests/apb_pin_level/CMakeLists.txt
Normal 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})
|
255
tests/apb_pin_level/bus_test.cpp
Normal file
255
tests/apb_pin_level/bus_test.cpp
Normal 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]));
|
||||
}
|
||||
}
|
||||
}
|
89
tests/apb_pin_level/testbench.h
Normal file
89
tests/apb_pin_level/testbench.h
Normal 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_
|
@ -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)
|
||||
|
319
tests/axi4_pin_level/burst_test.cpp
Normal file
319
tests/axi4_pin_level/burst_test.cpp
Normal 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); }
|
@ -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]);
|
||||
|
||||
}
|
||||
}
|
@ -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_
|
||||
|
116
tests/axi4_pin_level/waves.gtkw
Normal file
116
tests/axi4_pin_level/waves.gtkw
Normal 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
|
9
tests/cci_param_restricted/CMakeLists.txt
Normal file
9
tests/cci_param_restricted/CMakeLists.txt
Normal 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})
|
145
tests/cci_param_restricted/test.cpp
Normal file
145
tests/cci_param_restricted/test.cpp
Normal 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();
|
||||
}
|
@ -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_
|
||||
|
@ -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_
|
||||
|
@ -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'
|
||||
|
@ -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_
|
||||
|
@ -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_
|
||||
|
3
tests/configurer/CMakeLists.txt
Normal file
3
tests/configurer/CMakeLists.txt
Normal 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)
|
74
tests/configurer/sc_main.cpp
Normal file
74
tests/configurer/sc_main.cpp
Normal 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'
|
11
tests/configurer/test.yaml
Normal file
11
tests/configurer/test.yaml
Normal 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
|
8
tests/cxs_tlm/CMakeLists.txt
Normal file
8
tests/cxs_tlm/CMakeLists.txt
Normal 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})
|
171
tests/cxs_tlm/csx_packet_test.cpp
Normal file
171
tests/cxs_tlm/csx_packet_test.cpp
Normal 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
77
tests/cxs_tlm/testbench.h
Normal 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_
|
24
tests/io-redirector/main.cpp
Normal file
24
tests/io-redirector/main.cpp
Normal 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();
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
@ -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);
|
||||
|
3
tests/sc_fixed_tracing/CMakeLists.txt
Normal file
3
tests/sc_fixed_tracing/CMakeLists.txt
Normal 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 )
|
82
tests/sc_fixed_tracing/sc_main.cpp
Normal file
82
tests/sc_fixed_tracing/sc_main.cpp
Normal 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'
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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_ */
|
||||
|
Reference in New Issue
Block a user