Browse Source

Started from SystemC-Quickstart

master
Eyck Jentzsch 2 years ago
commit
262f093eb5
28 changed files with 1638 additions and 0 deletions
  1. +120
    -0
      .cproject
  2. +1
    -0
      .gitignore
  3. +0
    -0
      .gitmodules
  4. +34
    -0
      .project
  5. +6
    -0
      .pydevproject
  6. +29
    -0
      .settings/language.settings.xml
  7. +13
    -0
      .settings/org.eclipse.cdt.managedbuilder.core.prefs
  8. +35
    -0
      CMakeLists.txt
  9. +201
    -0
      LICENSE
  10. +28
    -0
      README.md
  11. +45
    -0
      cmake/Conan.cmake
  12. +18
    -0
      components/components.h
  13. +136
    -0
      components/initiator.cpp
  14. +36
    -0
      components/initiator.h
  15. +115
    -0
      components/logging.cpp
  16. +42
    -0
      components/logging.h
  17. +133
    -0
      components/router.h
  18. +18
    -0
      components/router_example.cpp
  19. +102
    -0
      components/target.cpp
  20. +46
    -0
      components/target.h
  21. +33
    -0
      components/top.h
  22. +44
    -0
      components/tx_example.cpp
  23. +140
    -0
      components/tx_example_mods.cpp
  24. +136
    -0
      components/tx_example_mods.h
  25. +49
    -0
      components/txtop.cpp
  26. +31
    -0
      components/txtop.h
  27. +11
    -0
      conanfile.txt
  28. +36
    -0
      router_example.py

+ 120
- 0
.cproject View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="cdt.managedbuild.toolchain.gnu.base.1318364290">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.1318364290" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" 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="cdt.managedbuild.toolchain.gnu.base.1318364290" 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="cdt.managedbuild.toolchain.gnu.base.1318364290.1772265551" name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.base.23298673" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.GNU_ELF" id="cdt.managedbuild.target.gnu.platform.base.155199250" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
<builder buildPath="/PySC/build/Debug" id="de.marw.cdt.cmake.core.genscriptbuilder.254681974" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="CMake Builder (portable)" parallelBuildOn="false" superClass="de.marw.cdt.cmake.core.genscriptbuilder"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1512061726" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.2080867410" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1337388874" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.1556398415" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1270594028" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.base.1434944209" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.541288630" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1837859128" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.assembler.base.924674275" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1920005488" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule buildDir="build/${ConfigName}" moduleId="de.marw.cdt.cmake.core.settings">
<options/>
<linux command="cmake" generator="UnixMakefiles" use-default="true">
<defs/>
<undefs/>
</linux>
<win32 command="cmake" generator="MinGWMakefiles" use-default="true">
<defs/>
<undefs/>
</win32>
</storageModule>
</cconfiguration>
<cconfiguration id="cdt.managedbuild.toolchain.gnu.base.1318364290.125067248">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.1318364290.125067248" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" 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="cdt.managedbuild.toolchain.gnu.base.1318364290.125067248" 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="cdt.managedbuild.toolchain.gnu.base.1318364290.125067248." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.base.1937159319" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.GNU_ELF" id="cdt.managedbuild.target.gnu.platform.base.2099590281" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
<builder id="de.marw.cdt.cmake.core.genscriptbuilder.1942834753" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="CMake Builder (portable)" parallelBuildOn="false" superClass="de.marw.cdt.cmake.core.genscriptbuilder"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1557460296" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1166559926" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1168647341" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.1407028084" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1427330719" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.base.1533638993" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.2085689440" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.736637697" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.assembler.base.293886081" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.2133927954" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule buildDir="build/${ConfigName}" moduleId="de.marw.cdt.cmake.core.settings">
<options/>
</storageModule>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="PySC.null.180822119" name="PySC"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Default">
<resource resourceType="PROJECT" workspacePath="/PySC"/>
</configuration>
<configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/PySC"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.1318364290;cdt.managedbuild.toolchain.gnu.base.1318364290.1772265551;cdt.managedbuild.tool.gnu.c.compiler.base.1556398415;cdt.managedbuild.tool.gnu.c.compiler.input.1270594028">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.1318364290;cdt.managedbuild.toolchain.gnu.base.1318364290.1772265551;cdt.managedbuild.tool.gnu.cpp.compiler.base.2080867410;cdt.managedbuild.tool.gnu.cpp.compiler.input.1337388874">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
</cproject>

+ 1
- 0
.gitignore View File

@ -0,0 +1 @@
/build/

+ 0
- 0
.gitmodules View File


+ 34
- 0
.project View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>PySysC-SC</name>
<comment></comment>
<projects>
<project>PySysC</project>
</projects>
<buildSpec>
<buildCommand>
<name>org.python.pydev.PyDevBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<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>

+ 6
- 0
.pydevproject View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?eclipse-pydev version="1.0"?><pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">PySysC Python 3.6.3</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python interpreter</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_ADDITIONAL_GRAMMAR_VALIDATION">3.6</pydev_property>
</pydev_project>

+ 29
- 0
.settings/language.settings.xml View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="cdt.managedbuild.toolchain.gnu.base.1318364290" name="Debug">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser" keep-relative-paths="false" name="CDT GCC Build Output Parser" parameter="(g?cc)|([gc]\+\+)|(clang)" prefer-non-shared="true"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-24234131794715112" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="de.marw.cmake.cdt.language.settings.providers.BuiltinsCompileCommandsJsonParser" ref="shared-provider"/>
<provider-reference id="de.marw.cmake.cdt.language.settings.providers.CompileCommandsJsonParser" ref="shared-provider"/>
</extension>
</configuration>
<configuration id="cdt.managedbuild.toolchain.gnu.base.1318364290.125067248" name="Release">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider copy-of="extension" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-24234131794715112" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
</extension>
</configuration>
</project>

+ 13
- 0
.settings/org.eclipse.cdt.managedbuilder.core.prefs View File

@ -0,0 +1,13 @@
eclipse.preferences.version=1
environment/buildEnvironmentInclude/cdt.managedbuild.toolchain.gnu.base.1318364290/CPATH/delimiter=\:
environment/buildEnvironmentInclude/cdt.managedbuild.toolchain.gnu.base.1318364290/CPATH/operation=remove
environment/buildEnvironmentInclude/cdt.managedbuild.toolchain.gnu.base.1318364290/CPLUS_INCLUDE_PATH/delimiter=\:
environment/buildEnvironmentInclude/cdt.managedbuild.toolchain.gnu.base.1318364290/CPLUS_INCLUDE_PATH/operation=remove
environment/buildEnvironmentInclude/cdt.managedbuild.toolchain.gnu.base.1318364290/C_INCLUDE_PATH/delimiter=\:
environment/buildEnvironmentInclude/cdt.managedbuild.toolchain.gnu.base.1318364290/C_INCLUDE_PATH/operation=remove
environment/buildEnvironmentInclude/cdt.managedbuild.toolchain.gnu.base.1318364290/append=true
environment/buildEnvironmentInclude/cdt.managedbuild.toolchain.gnu.base.1318364290/appendContributed=true
environment/buildEnvironmentLibrary/cdt.managedbuild.toolchain.gnu.base.1318364290/LIBRARY_PATH/delimiter=\:
environment/buildEnvironmentLibrary/cdt.managedbuild.toolchain.gnu.base.1318364290/LIBRARY_PATH/operation=remove
environment/buildEnvironmentLibrary/cdt.managedbuild.toolchain.gnu.base.1318364290/append=true
environment/buildEnvironmentLibrary/cdt.managedbuild.toolchain.gnu.base.1318364290/appendContributed=true

+ 35
- 0
CMakeLists.txt View File

@ -0,0 +1,35 @@
project(TransactionExample CXX)
cmake_minimum_required(VERSION 3.9)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
include(Conan)
setup_conan()
conan_basic_setup(TARGETS)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_library(components SHARED
components/tx_example_mods.cpp
components/initiator.cpp
components/target.cpp
components/logging.cpp)
target_link_libraries(components PUBLIC CONAN_PKG::SystemC)
target_link_libraries(components PUBLIC CONAN_PKG::SystemCVerification)
add_executable(TransactionExample
components/tx_example.cpp
components/txtop.cpp)
target_link_libraries(TransactionExample components)
add_executable(router_example
components/router_example.cpp)
target_link_libraries(router_example components)
# CTest is a testing tool that can be used to test your project.
# enable_testing()
# add_test(NAME example
# WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
# COMMAND example)

+ 201
- 0
LICENSE View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed 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.

+ 28
- 0
README.md View File

@ -0,0 +1,28 @@
# PySysC-SC
A simple C++/SystemC/CMake project to test pysysc
# How to build
> Currently only Linux and MacOS are tested
```
pip install conan
conan remote add minres https://api.bintray.com/conan/minres/conan-repo
cd PySysC-SC
mkdir build
cd build
conan install .. --build=missing
cmake ..
cmake --build .
```
## Notes
If you encounter issues when linking wrt. c++11 symbols you might have run into GCC ABI incompatibility introduced from GCC 5.0 onwards. You can fix this by adding '-s compiler.libcxx=libstdc++11' to the conan call or changing compiler.libcxx to
```
compiler.libcxx=libstdc++11
```
in $HOME/.conan/profiles/default

+ 45
- 0
cmake/Conan.cmake View File

@ -0,0 +1,45 @@
macro(setup_conan)
find_program(conan conan)
if(NOT EXISTS ${conan})
message(FATAL_ERROR "Conan is required. Please see README.md")
return()
endif()
if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL Darwin)
set(os Macos)
else()
set(os ${CMAKE_HOST_SYSTEM_NAME})
endif()
if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU)
set(compiler gcc)
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL AppleClang)
set(compiler apple-clang)
else()
message(FATAL_ERROR "Unknown compiler: ${CMAKE_CXX_COMPILER_ID}")
endif()
string(SUBSTRING ${CMAKE_CXX_COMPILER_VERSION} 0 3 compiler_version)
set(conanfile ${CMAKE_SOURCE_DIR}/conanfile.txt)
set(conanfile_cmake ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
set(compiler_libcxx libstdc++11)
if("${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CONAN_BUILD_TYPE Debug)
elseif("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
set(CONAN_BUILD_TYPE Release)
else()
set(CONAN_BUILD_TYPE ${CMAKE_BUILD_TYPE})
endif()
execute_process(COMMAND ${conan} install --build=missing
-s build_type=${CONAN_BUILD_TYPE} -s compiler.libcxx=${compiler_libcxx}
${CMAKE_SOURCE_DIR} RESULT_VARIABLE return_code)
if(NOT ${return_code} EQUAL 0)
message(FATAL_ERROR "conan install command failed.")
endif()
include(${conanfile_cmake})
conan_basic_setup()
endmacro()

+ 18
- 0
components/components.h View File

@ -0,0 +1,18 @@
/*
* components.h
*
* Created on: 02.12.2018
* Author: eyck
*/
#ifndef COMPONENTS_H_
#define COMPONENTS_H_
//#include "tx_example_mods.h"
#include <systemc.h>
#include "logging.h"
#include "initiator.h"
#include "router.h"
#include "target.h"
#endif /* COMPONENTS_H_ */

+ 136
- 0
components/initiator.cpp View File

@ -0,0 +1,136 @@
/*
* initiator.cpp
*
* Created on: 02.12.2018
* Author: eyck
*/
#include "initiator.h"
#include "logging.h"
Initiator::Initiator(::sc_core::sc_module_name nm)
: socket("socket") // Construct and name socket
, dmi_ptr_valid(false)
{
// Register callbacks for incoming interface method calls
socket.register_invalidate_direct_mem_ptr(this, &Initiator::invalidate_direct_mem_ptr);
SC_THREAD(thread_process);
}
void Initiator::thread_process() {
{
// TLM-2 generic payload transaction, reused across calls to b_transport, DMI and debug
tlm::tlm_generic_payload* trans = new tlm::tlm_generic_payload;
sc_time delay = sc_time(10, SC_NS);
// Generate a random sequence of reads and writes
for (int i = 256-64; i < 256+64; i += 4)
{
int data;
tlm::tlm_command cmd = static_cast<tlm::tlm_command>(rand() % 2);
if (cmd == tlm::TLM_WRITE_COMMAND) data = 0xFF000000 | i;
// Use DMI if it is available
if (dmi_ptr_valid && sc_dt::uint64(i) >= dmi_data.get_start_address()
&& sc_dt::uint64(i) <= dmi_data.get_end_address())
{
// Bypass transport interface and use direct memory interface
// Implement target latency
if ( cmd == tlm::TLM_READ_COMMAND )
{
assert( dmi_data.is_read_allowed() );
memcpy(&data, dmi_data.get_dmi_ptr() + i - dmi_data.get_start_address(), 4);
wait( dmi_data.get_read_latency() );
}
else if ( cmd == tlm::TLM_WRITE_COMMAND )
{
assert( dmi_data.is_write_allowed() );
memcpy(dmi_data.get_dmi_ptr() + i - dmi_data.get_start_address(), &data, 4);
wait( dmi_data.get_write_latency() );
}
LOG_INFO << "DMI = { " << (cmd ? 'W' : 'R') << ", " << hex << i
<< " } , data = " << hex << data << " at time " << sc_time_stamp();
}
else
{
trans->set_command( cmd );
trans->set_address( i );
trans->set_data_ptr( reinterpret_cast<unsigned char*>(&data) );
trans->set_data_length( 4 );
trans->set_streaming_width( 4 ); // = data_length to indicate no streaming
trans->set_byte_enable_ptr( 0 ); // 0 indicates unused
trans->set_dmi_allowed( false ); // Mandatory initial value
trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE ); // Mandatory initial value
#ifdef INJECT_ERROR
if (i > 90) trans->set_streaming_width(2);
#endif
// Other fields default: byte enable = 0, streaming width = 0, DMI_hint = false, no extensions
socket->b_transport( *trans, delay ); // Blocking transport call
// Initiator obliged to check response status
if ( trans->is_response_error() )
{
// Print response string
char txt[100];
sprintf(txt, "Error from b_transport, response status = %s",
trans->get_response_string().c_str());
SC_REPORT_ERROR("TLM-2", txt);
}
// Check DMI hint
if ( trans->is_dmi_allowed() )
{
// *********************************************
// Re-use transaction object for DMI. Reset the address because it could
// have been modified by the interconnect on the previous transport call
// *********************************************
trans->set_address( i );
dmi_ptr_valid = socket->get_direct_mem_ptr( *trans, dmi_data );
}
LOG_INFO << "trans = { " << (cmd ? 'W' : 'R') << ", " << hex << i
<< " } , data = " << hex << data << " at time " << sc_time_stamp();
}
}
// Use debug transaction interface to dump memory contents, reusing same transaction object
sc_dt::uint64 A = 128;
trans->set_address(A);
trans->set_read();
trans->set_data_length(256);
unsigned char* data = new unsigned char[256];
trans->set_data_ptr(data);
unsigned int n_bytes = socket->transport_dbg( *trans );
for (unsigned int i = 0; i < n_bytes; i += 4)
{
LOG_INFO << "mem[" << (A + i) << "] = "
<< *(reinterpret_cast<unsigned int*>( &data[i] ));
}
A = 256;
trans->set_address(A);
trans->set_data_length(128);
n_bytes = socket->transport_dbg( *trans );
for (unsigned int i = 0; i < n_bytes; i += 4)
{
LOG_INFO << "mem[" << (A + i) << "] = "
<< *(reinterpret_cast<unsigned int*>( &data[i] ));
}
}
}

+ 36
- 0
components/initiator.h View File

@ -0,0 +1,36 @@
#ifndef INITIATOR_H
#define INITIATOR_H
#include "systemc"
using namespace sc_core;
using namespace sc_dt;
using namespace std;
#include "tlm.h"
#include "tlm_utils/simple_initiator_socket.h"
// Initiator module generating generic payload transactions
struct Initiator: sc_module
{
// TLM-2 socket, defaults to 32-bits wide, base protocol
tlm_utils::simple_initiator_socket<Initiator> socket;
SC_HAS_PROCESS(Initiator);
Initiator( ::sc_core::sc_module_name );
void thread_process();
// TLM-2 backward DMI method
void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range){
// Ignore range and invalidate all DMI pointers regardless
dmi_ptr_valid = false;
}
bool dmi_ptr_valid;
tlm::tlm_dmi dmi_data;
};
#endif

+ 115
- 0
components/logging.cpp View File

@ -0,0 +1,115 @@
/*
* logging.cpp
*
* Created on: 24.12.2018
* Author: eyck
*/
#include "logging.h"
#include <systemc>
#include <deque>
#include <array>
#include <sstream>
#include <iomanip>
using namespace sc_core;
enum log_level {NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE};
namespace {
static std::deque<std::string> msg_buf;
inline log_level verbosity2log(int verb) {
if (verb >= sc_core::SC_FULL) return TRACE;
if (verb >= sc_core::SC_HIGH) return DEBUG;
return INFO;
}
std::string time2string(const sc_core::sc_time &t) {
const std::array<const char *, 6> time_units{"fs", "ps", "ns", "us", "ms", "s "};
const std::array<uint64_t, 6> multiplier{1ULL,
1000ULL,
1000ULL * 1000,
1000ULL * 1000 * 1000,
1000ULL * 1000 * 1000 * 1000,
1000ULL * 1000 * 1000 * 1000 * 1000};
std::ostringstream oss;
const sc_core::sc_time_tuple tt{t};
const auto val = tt.value();
if (!val) {
oss << "0 s";
} else {
const unsigned scale = tt.unit();
const auto fs_val = val * multiplier[scale];
for (int j = multiplier.size() - 1; j >= scale; --j) {
if (fs_val > multiplier[j]) {
const auto i = val / multiplier[j - scale];
const auto f = val % multiplier[j - scale];
oss << i << '.' << std::setw(3 * (j - scale)) << std::setfill('0') << std::left << f << ' '
<< time_units[j];
break;
}
}
}
return oss.str();
}
const std::string compose_message(const sc_report &rep) {
std::stringstream os;
os << "[" << std::setw(20) << time2string(sc_core::sc_time_stamp()) << "] ";
if (rep.get_id() >= 0)
os << "("
<< "IWEF"[rep.get_severity()] << rep.get_id() << ") ";
os << rep.get_msg_type();
if (*rep.get_msg()) os << ": " << rep.get_msg();
if (rep.get_severity() > SC_INFO) {
std::array<char, 16> line_number_str;
os << " [FILE:" << rep.get_file_name() << ":" << rep.get_line_number() << "]";
sc_simcontext *simc = sc_get_curr_simcontext();
if (simc && sc_is_running()) {
const char *proc_name = rep.get_process_name();
if (proc_name) os << "[PROCESS:" << proc_name << "]";
}
}
return os.str();
}
void report_handler(const sc_report &rep, const sc_actions &actions) {
std::array<const log_level, 4> map = {{INFO, WARNING, ERROR, FATAL}};
if (actions & SC_DISPLAY) {
auto level = rep.get_severity() > sc_core::SC_INFO ? map[rep.get_severity()] : verbosity2log(rep.get_verbosity());
msg_buf.push_back(compose_message(rep));
}
if (actions & SC_STOP) sc_stop();
if (actions & SC_ABORT) abort();
if (actions & SC_THROW) throw rep;
}
}
bool has_output(){
return !msg_buf.empty();
}
std::string get_output(){
std::string ret = msg_buf.front();
msg_buf.pop_front();
return ret;
}
void init_logging(unsigned level) {
const std::array<int, 8> verbosity = {SC_NONE, // Logging::NONE
SC_LOW, // Logging::FATAL
SC_LOW, // Logging::ERROR
SC_LOW, // Logging::WARNING
SC_MEDIUM, // Logging::INFO
SC_HIGH, // logging::DEBUG
SC_FULL, // logging::TRACE
SC_DEBUG}; // logging::TRACE+1
sc_report_handler::set_verbosity_level(verbosity[level]);
sc_report_handler::set_handler(report_handler);
}

+ 42
- 0
components/logging.h View File

@ -0,0 +1,42 @@
/*
* logging.h
*
* Created on: 24.12.2018
* Author: eyck
*/
#ifndef LOGGING_H_
#define LOGGING_H_
#include <string>
#include <sstream>
#include <systemc.h>
bool has_output();
std::string get_output();
void init_logging(unsigned level);
class Log {
public:
Log(const char* file, int line):messageLevel(sc_core::SC_INFO), file(file), line(line){};
Log(const Log&) = delete;
Log& operator =(const Log&) = delete;
virtual ~Log(){
::sc_core::sc_report_handler::report(messageLevel, "", os.str().c_str(), file, line );
}
std::ostringstream& Get(sc_core::sc_severity level = sc_core::SC_INFO){
messageLevel = level;
return os;
}
protected:
std::ostringstream os;
sc_core::sc_severity messageLevel;
const char* file;
int line;
};
#define LOG(level) Log(__FILE__, __LINE__).Get(level)
#define LOG_INFO Log(__FILE__, __LINE__).Get(sc_core::SC_INFO)
#define LOG_WARN Log(__FILE__, __LINE__).Get(sc_core::SC_WARNING)
#define LOG_ERR Log(__FILE__, __LINE__).Get(sc_core::SC_ERROR)
#endif /* LOGGING_H_ */

+ 133
- 0
components/router.h View File

@ -0,0 +1,133 @@
#ifndef ROUTER_H
#define ROUTER_H
#include "systemc"
using namespace sc_core;
using namespace sc_dt;
using namespace std;
#include "tlm.h"
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
// *********************************************
// Generic payload blocking transport router
// *********************************************
template<unsigned int N_TARGETS>
struct Router: sc_module
{
// TLM-2 socket, defaults to 32-bits wide, base protocol
tlm_utils::simple_target_socket<Router> target_socket;
// *********************************************
// Use tagged sockets to be able to distinguish incoming backward path calls
// *********************************************
sc_core::sc_vector<tlm_utils::simple_initiator_socket_tagged<Router>> initiator_socket;
SC_CTOR(Router)
: target_socket("target_socket")
, initiator_socket("socket", N_TARGETS)
{
// Register callbacks for incoming interface method calls
target_socket.register_b_transport( this, &Router::b_transport);
target_socket.register_get_direct_mem_ptr(this, &Router::get_direct_mem_ptr);
target_socket.register_transport_dbg( this, &Router::transport_dbg);
for (unsigned int i = 0; i < N_TARGETS; i++)
{
char txt[20];
sprintf(txt, "socket_%d", i);
// *********************************************
// Register callbacks for incoming interface method calls, including tags
// *********************************************
initiator_socket[i].register_invalidate_direct_mem_ptr(this, &Router::invalidate_direct_mem_ptr, i);
}
}
// ****************
// FORWARD PATH
// ****************
// TLM-2 blocking transport method
virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay )
{
sc_dt::uint64 address = trans.get_address();
sc_dt::uint64 masked_address;
unsigned int target_nr = decode_address( address, masked_address);
// Modify address within transaction
trans.set_address( masked_address );
// Forward transaction to appropriate target
initiator_socket[target_nr]->b_transport( trans, delay );
}
// TLM-2 forward DMI method
virtual bool get_direct_mem_ptr(tlm::tlm_generic_payload& trans,
tlm::tlm_dmi& dmi_data)
{
sc_dt::uint64 masked_address;
unsigned int target_nr = decode_address( trans.get_address(), masked_address );
trans.set_address( masked_address );
bool status = initiator_socket[target_nr]->get_direct_mem_ptr( trans, dmi_data );
// Calculate DMI address of target in system address space
dmi_data.set_start_address( compose_address( target_nr, dmi_data.get_start_address() ));
dmi_data.set_end_address ( compose_address( target_nr, dmi_data.get_end_address() ));
return status;
}
// TLM-2 debug transaction method
virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans)
{
sc_dt::uint64 masked_address;
unsigned int target_nr = decode_address( trans.get_address(), masked_address );
trans.set_address( masked_address );
// Forward debug transaction to appropriate target
return initiator_socket[target_nr]->transport_dbg( trans );
}
// ****************
// BACKWARD PATH
// ****************
// **************************
// Tagged backward DMI method
// **************************
virtual void invalidate_direct_mem_ptr(int id,
sc_dt::uint64 start_range,
sc_dt::uint64 end_range)
{
// Reconstruct address range in system memory map
sc_dt::uint64 bw_start_range = compose_address( id, start_range );
sc_dt::uint64 bw_end_range = compose_address( id, end_range );
target_socket->invalidate_direct_mem_ptr(bw_start_range, bw_end_range);
}
// ****************
// ROUTER INTERNALS
// ****************
// Simple fixed address decoding
inline unsigned int decode_address( sc_dt::uint64 address, sc_dt::uint64& masked_address )
{
unsigned int target_nr = static_cast<unsigned int>( (address >> 8) & 0x3 );
masked_address = address & 0xFF;
return target_nr;
}
inline sc_dt::uint64 compose_address( unsigned int target_nr, sc_dt::uint64 address)
{
return (target_nr << 8) | (address & 0xFF);
}
};
#endif

+ 18
- 0
components/router_example.cpp View File

@ -0,0 +1,18 @@
/*
* router_example.cpp
*
* Created on: 02.12.2018
* Author: eyck
*/
#include "top.h"
int sc_main(int argc, char* argv[])
{
Top top("top");
sc_start();
return 0;
}

+ 102
- 0
components/target.cpp View File

@ -0,0 +1,102 @@
/*
* target.cpp
*
* Created on: 02.12.2018
* Author: eyck
*/
#include "target.h"
void Memory::b_transport(tlm::tlm_generic_payload& trans, sc_time& delay) {
tlm::tlm_command cmd = trans.get_command();
sc_dt::uint64 adr = trans.get_address() / 4;
unsigned char* ptr = trans.get_data_ptr();
unsigned int len = trans.get_data_length();
unsigned char* byt = trans.get_byte_enable_ptr();
unsigned int wid = trans.get_streaming_width();
// Obliged to check address range and check for unsupported features,
// i.e. byte enables, streaming, and bursts
// Can ignore extensions
// Generate the appropriate error response
if (adr >= SIZE) {
trans.set_response_status( tlm::TLM_ADDRESS_ERROR_RESPONSE );
return;
}
if (byt != 0) {
trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE );
return;
}
if (len > 4 || wid < len) {
trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE );
return;
}
wait(delay);
delay = SC_ZERO_TIME;
// Obliged to implement read and write commands
if ( cmd == tlm::TLM_READ_COMMAND )
memcpy(ptr, &mem[adr], len);
else if ( cmd == tlm::TLM_WRITE_COMMAND )
memcpy(&mem[adr], ptr, len);
// Set DMI hint to indicated that DMI is supported
trans.set_dmi_allowed(true);
// Obliged to set response status to indicate successful completion
trans.set_response_status( tlm::TLM_OK_RESPONSE );
}
bool Memory::get_direct_mem_ptr(tlm::tlm_generic_payload& trans,
tlm::tlm_dmi& dmi_data)
{
// Permit read and write access
dmi_data.allow_read_write();
// Set other details of DMI region
dmi_data.set_dmi_ptr( reinterpret_cast<unsigned char*>( &mem[0] ) );
dmi_data.set_start_address( 0 );
dmi_data.set_end_address( SIZE*4-1 );
dmi_data.set_read_latency( LATENCY );
dmi_data.set_write_latency( LATENCY );
return true;
}
Memory::Memory(sc_core::sc_module_name nm)
: socket("socket"), LATENCY(10, SC_NS)
{
// Register callbacks for incoming interface method calls
socket.register_b_transport( this, &Memory::b_transport);
socket.register_get_direct_mem_ptr(this, &Memory::get_direct_mem_ptr);
socket.register_transport_dbg( this, &Memory::transport_dbg);
// Initialize memory with random data
for (int i = 0; i < SIZE; i++)
mem[i] = 0xAA000000 | (mem_nr << 20) | (rand() % 256);
++mem_nr;
}
// TLM-2 debug transaction method
unsigned int Memory::transport_dbg(tlm::tlm_generic_payload& trans)
{
tlm::tlm_command cmd = trans.get_command();
sc_dt::uint64 adr = trans.get_address() / 4;
unsigned char* ptr = trans.get_data_ptr();
unsigned int len = trans.get_data_length();
// Calculate the number of bytes to be actually copied
unsigned int num_bytes = (len < (SIZE - adr) * 4) ? len : (SIZE - adr) * 4;
if ( cmd == tlm::TLM_READ_COMMAND )
memcpy(ptr, &mem[adr], num_bytes);
else if ( cmd == tlm::TLM_WRITE_COMMAND )
memcpy(&mem[adr], ptr, num_bytes);
return num_bytes;
}

+ 46
- 0
components/target.h View File

@ -0,0 +1,46 @@
#ifndef TARGET_H
#define TARGET_H
// Needed for the simple_target_socket
#define SC_INCLUDE_DYNAMIC_PROCESSES
#include "systemc"
using namespace sc_core;
using namespace sc_dt;
using namespace std;
#include "tlm.h"
#include "tlm_utils/simple_target_socket.h"
// Target module representing a simple memory
struct Memory: sc_module
{
// TLM-2 socket, defaults to 32-bits wide, base protocol
tlm_utils::simple_target_socket<Memory> socket;
enum { SIZE = 256 };
const sc_time LATENCY;
SC_HAS_PROCESS(Memory);
Memory(sc_core::sc_module_name nm);
protected:
// TLM-2 blocking transport method
void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay );
// TLM-2 forward DMI method
bool get_direct_mem_ptr(tlm::tlm_generic_payload& trans,
tlm::tlm_dmi& dmi_data);
// TLM-2 debug transaction method
unsigned int transport_dbg(tlm::tlm_generic_payload& trans);
int mem[SIZE];
static unsigned int mem_nr;
};
unsigned int Memory::mem_nr = 0;
#endif

+ 33
- 0
components/top.h View File

@ -0,0 +1,33 @@
#ifndef TOP_H
#define TOP_H
#include "initiator.h"
#include "target.h"
#include "router.h"
SC_MODULE(Top)
{
Initiator* initiator;
Router<4>* router;
Memory* memory[4];
SC_CTOR(Top)
{
// Instantiate components
initiator = new Initiator("initiator");
router = new Router<4>("router");
for (int i = 0; i < 4; i++)
{
char txt[20];
sprintf(txt, "memory_%d", i);
memory[i] = new Memory(txt);
}
// Bind sockets
initiator->socket.bind( router->target_socket );
for (int i = 0; i < 4; i++)
router->initiator_socket[i].bind( memory[i]->socket );
}
};
#endif

+ 44
- 0
components/tx_example.cpp View File

@ -0,0 +1,44 @@
// -*- C++ -*- <this line is for emacs to recognize it as C++ code>
/*****************************************************************************
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.
*****************************************************************************/
// this code compiles and runs with our latest prototype for this specification
#include "txtop.h"
int sc_main (int argc , char *argv[])
{
scv_startup();
scv_tr_text_init();
scv_tr_db db("transaction_example.txlog");
scv_tr_db::set_default_db(&db);
tx_top top("top");
// Accellera SystemC >=2.2 got picky about multiple drivers.
// Disable check for bus simulation.
sc_report_handler::set_actions(SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, SC_DO_NOTHING);
// run the simulation
sc_start(1.0, SC_MS);
return 0;
}

+ 140
- 0
components/tx_example_mods.cpp View File

@ -0,0 +1,140 @@
// -*- C++ -*- <this line is for emacs to recognize it as C++ code>
/*****************************************************************************
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.
*****************************************************************************/
// this code compiles and runs with our latest prototype for this specification
#include "tx_example_mods.h"
rw_task_if::data_t rw_pipelined_transactor::read(const rw_task_if::addr_t*
addr) {
addr_phase.lock();
scv_tr_handle h = read_gen.begin_transaction(*addr);
scv_tr_handle h1 = addr_gen.begin_transaction(*addr,"addr_phase",h);
wait(clk->posedge_event());
bus_addr = *addr;
addr_req = 1;
wait(addr_ack->posedge_event());
wait(clk->negedge_event());
addr_req = 0;
wait(addr_ack->negedge_event());
addr_gen.end_transaction(h1);
addr_phase.unlock();
data_phase.lock();
scv_tr_handle h2 = data_gen.begin_transaction("data_phase",h);
wait(data_rdy->posedge_event());
data_t data = bus_data.read();
wait(data_rdy->negedge_event());
data_gen.end_transaction(h2);
read_gen.end_transaction(h,data);
data_phase.unlock();
return data;
}
void rw_pipelined_transactor::write(const write_t * req) {
scv_tr_handle h = write_gen.begin_transaction(req->addr);
// ...
write_gen.end_transaction(h,req->data);
}
void test::main() {
// simple sequential tests
for (int i=0; i<3; i++) {
rw_task_if::addr_t addr = i;
rw_task_if::data_t data = transactor->read(&addr);
cout << "at time " << sc_time_stamp() << ": ";
cout << "received data : " << data << endl;
}
scv_smart_ptr<rw_task_if::addr_t> addr;
for (int i=0; i<3; i++) {
addr->next();
rw_task_if::data_t data = transactor->read( addr->get_instance() );
cout << "data for address " << *addr << " is " << data << endl;
}
scv_smart_ptr<rw_task_if::write_t> write;
for (int i=0; i<3; i++) {
write->next();
transactor->write( write->get_instance() );
cout << "send data : " << write->data << endl;
}
scv_smart_ptr<int> data;
scv_bag<int> distribution;
distribution.push(1,40);
distribution.push(2,60);
data->set_mode(distribution);
for (int i=0;i<3; i++) { data->next(); process(data); }
}
void design::addr_phase() {
while (1) {
while (addr_req.read() != 1) {
wait(addr_req->value_changed_event());
}
sc_uint<8> _addr = bus_addr.read();
bool _rw = rw.read();
int cycle = rand() % 10 + 1;
while (cycle-- > 0) {
wait(clk->posedge_event());
}
addr_ack = 1;
wait(clk->posedge_event());
addr_ack = 0;
outstandingAddresses.push_back(_addr);
outstandingType.push_back(_rw);
cout << "at time " << sc_time_stamp() << ": ";
cout << "received request for memory address " << _addr << endl;
}
}
void design::data_phase() {
while (1) {
while (outstandingAddresses.empty()) {
wait(clk->posedge_event());
}
int cycle = rand() % 10 + 1;
while (cycle-- > 0) {
wait(clk->posedge_event());
}
if (outstandingType.front() == 0) {
cout << "reading memory address " << outstandingAddresses.front()
<< " with value " << memory[outstandingAddresses.front().to_ulong()] << endl;
bus_data = memory[outstandingAddresses.front().to_ulong()];
data_rdy = 1;
wait(clk->posedge_event());
data_rdy = 0;
} else {
cout << "not implemented yet" << endl;
}
outstandingAddresses.pop_front();
outstandingType.pop_front();
}
}

+ 136
- 0
components/tx_example_mods.h View File

@ -0,0 +1,136 @@
// -*- C++ -*- <this line is for emacs to recognize it as C++ code>
/*****************************************************************************
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.
*****************************************************************************/
// this code compiles and runs with our latest prototype for this specification
#include <scv.h>
#include <systemc.h>
// hack to fake a true fifo_mutex
#define fifo_mutex sc_mutex
const unsigned ram_size = 256;
class rw_task_if : virtual public sc_interface {
public:
typedef sc_uint<8> addr_t;
typedef sc_uint<8> data_t;
struct write_t {
addr_t addr;
data_t data;
};
virtual data_t read(const addr_t*) = 0;
virtual void write(const write_t*) = 0;
};
SCV_EXTENSIONS(rw_task_if::write_t) {
public:
scv_extensions<rw_task_if::addr_t> addr;
scv_extensions<rw_task_if::data_t> data;
SCV_EXTENSIONS_CTOR(rw_task_if::write_t) {
SCV_FIELD(addr);
SCV_FIELD(data);
}
};
class pipelined_bus_ports : public sc_module {
public:
sc_in< bool > clk;
sc_inout< bool > rw;
sc_inout< bool > addr_req;
sc_inout< bool > addr_ack;
sc_inout< sc_uint<8> > bus_addr;
sc_inout< bool > data_rdy;
sc_inout< sc_uint<8> > bus_data;
SC_CTOR(pipelined_bus_ports)
: clk("clk"), rw("rw"),
addr_req("addr_req"),
addr_ack("addr_ack"), bus_addr("bus_addr"),
data_rdy("data_rdy"), bus_data("bus_data") {}
};
class rw_pipelined_transactor
: public rw_task_if,
public pipelined_bus_ports {
fifo_mutex addr_phase;
fifo_mutex data_phase;
scv_tr_stream pipelined_stream;
scv_tr_stream addr_stream;
scv_tr_stream data_stream;
scv_tr_generator<sc_uint<8>, sc_uint<8> > read_gen;
scv_tr_generator<sc_uint<8>, sc_uint<8> > write_gen;
scv_tr_generator<sc_uint<8> > addr_gen;
scv_tr_generator<sc_uint<8> > data_gen;
public:
rw_pipelined_transactor(sc_module_name nm) :
pipelined_bus_ports(nm),
addr_phase("addr_phase"),
data_phase("data_phase"),
pipelined_stream("pipelined_stream", "transactor"),
addr_stream("addr_stream", "transactor"),
data_stream("data_stream", "transactor"),
read_gen("read",pipelined_stream,"addr","data"),
write_gen("write",pipelined_stream,"addr","data"),
addr_gen("addr",addr_stream,"addr"),
data_gen("data",data_stream,"data")
{}
virtual data_t read(const addr_t* p_addr);
virtual void write(const write_t * req);
};
class test : public sc_module {
public:
sc_port< rw_task_if > transactor;
SC_CTOR(test) {
SC_THREAD(main);
}
void main();
};
class write_constraint : virtual public scv_constraint_base {
public:
scv_smart_ptr<rw_task_if::write_t> write;
SCV_CONSTRAINT_CTOR(write_constraint) {
SCV_CONSTRAINT( write->addr() <= ram_size );
SCV_CONSTRAINT( write->addr() != write->data() );
}
};
inline void process(scv_smart_ptr<int> data) {}
class design : public pipelined_bus_ports {
std::list< sc_uint<8> > outstandingAddresses;
std::list< bool > outstandingType;
sc_uint<8> memory[ram_size];
public:
SC_HAS_PROCESS(design);
design(sc_module_name nm) : pipelined_bus_ports(nm) {
for (unsigned i=0; i<ram_size; ++i) { memory[i] = i; }
SC_THREAD(addr_phase);
SC_THREAD(data_phase);
}
void addr_phase();
void data_phase();
};

+ 49
- 0
components/txtop.cpp View File

@ -0,0 +1,49 @@
/*
* top1.cpp
*
* Created on: 02.12.2018
* Author: eyck
*/
#include "txtop.h"
using namespace sc_core;
tx_top::tx_top(sc_core::sc_module_name nm)
: sc_module(nm)
, clk("clk", 20.0, SC_NS, 0.5 ,0.0, SC_NS, true)
, rw("rw")
, addr_req("addr_reg")
, addr_ack("addr_ack")
, bus_addr("bus_addr")
, data_rdy("data_rdy")
, bus_data("bus_data")
, t("t")
, tr("tr")
, duv("duv")
{
// TODO Auto-generated constructor stub
// connect them up
t.transactor(tr);
tr.clk(clk);
tr.rw(rw);
tr.addr_req(addr_req);
tr.addr_ack(addr_ack);
tr.bus_addr(bus_addr);
tr.data_rdy(data_rdy);
tr.bus_data(bus_data);
duv.clk(clk);
duv.rw(rw);
duv.addr_req(addr_req);
duv.addr_ack(addr_ack);
duv.bus_addr(bus_addr);
duv.data_rdy(data_rdy);
duv.bus_data(bus_data);
}
tx_top::~tx_top() {
// TODO Auto-generated destructor stub
}

+ 31
- 0
components/txtop.h View File

@ -0,0 +1,31 @@
/*
* top1.h
*
* Created on: 02.12.2018
* Author: eyck
*/
#ifndef TXTOP_H_
#define TXTOP_H_
#include "tx_example_mods.h"
#include <systemc>
class tx_top: public sc_core::sc_module {
public:
tx_top(sc_core::sc_module_name nm);
virtual ~tx_top();
sc_core::sc_clock clk;
sc_core::sc_signal< bool > rw;
sc_core::sc_signal< bool > addr_req;
sc_core::sc_signal< bool > addr_ack;
sc_core::sc_signal< sc_dt::sc_uint<8> > bus_addr;