Removed SCV code

This commit is contained in:
Eyck Jentzsch 2016-10-08 21:53:07 +02:00
parent 96d628d322
commit 79c49e6f1d
15 changed files with 0 additions and 162006 deletions

View File

@ -1,152 +0,0 @@
<?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.config.gnu.macosx.exe.debug.133691581">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.macosx.exe.debug.133691581" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" 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"/>
<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.MachO64" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.macosx.exe.debug.133691581" name="Debug" parent="cdt.managedbuild.config.gnu.macosx.exe.debug">
<folderInfo id="cdt.managedbuild.config.gnu.macosx.exe.debug.133691581." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.macosx.exe.debug.500082514" name="MacOSX GCC" superClass="cdt.managedbuild.toolchain.gnu.macosx.exe.debug">
<targetPlatform id="cdt.managedbuild.target.gnu.platform.macosx.exe.debug.493103663" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.macosx.exe.debug"/>
<builder buildPath="${workspace_loc:/scv_tr_sqlite}/Debug" id="cdt.managedbuild.target.gnu.builder.base.214255941" keepEnvironmentInBuildfile="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
<tool id="cdt.managedbuild.tool.macosx.c.linker.macosx.exe.debug.1022976995" name="MacOS X C Linker" superClass="cdt.managedbuild.tool.macosx.c.linker.macosx.exe.debug"/>
<tool command="c++" id="cdt.managedbuild.tool.macosx.cpp.linker.macosx.exe.debug.1153644061" name="MacOS X C++ Linker" superClass="cdt.managedbuild.tool.macosx.cpp.linker.macosx.exe.debug">
<option id="macosx.cpp.link.option.paths.33338975" name="Library search path (-L)" superClass="macosx.cpp.link.option.paths" valueType="libPaths">
<listOptionValue builtIn="false" value="/Users/eyck//Library/Frameworks/SystemC.framework/Versions/2.3.1/lib-macosx64"/>
</option>
<option id="macosx.cpp.link.option.libs.1238143593" name="Libraries (-l)" superClass="macosx.cpp.link.option.libs" valueType="libs">
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="systemc"/>
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="scv"/>
</option>
<inputType id="cdt.managedbuild.tool.macosx.cpp.linker.input.10448631" superClass="cdt.managedbuild.tool.macosx.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.assembler.macosx.exe.debug.1589927489" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.macosx.exe.debug">
<option id="gnu.both.asm.option.include.paths.1741076851" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="/usr/include"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1649108682" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.archiver.macosx.base.422966961" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.macosx.base"/>
<tool command="c++" id="cdt.managedbuild.tool.gnu.cpp.compiler.macosx.exe.debug.1149501692" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.macosx.exe.debug">
<option id="gnu.cpp.compilermacosx.exe.debug.option.optimization.level.1228519118" name="Optimization Level" superClass="gnu.cpp.compilermacosx.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
<option id="gnu.cpp.compiler.macosx.exe.debug.option.debugging.level.1854731682" name="Debug Level" superClass="gnu.cpp.compiler.macosx.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
<option id="gnu.cpp.compiler.option.include.paths.2045160591" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1"/>
<listOptionValue builtIn="false" value="/Users/eyck//Library/Frameworks/SystemC.framework/Versions/2.3.1/include"/>
<listOptionValue builtIn="false" value="/usr/include"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.506955043" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool command="clang" id="cdt.managedbuild.tool.gnu.c.compiler.macosx.exe.debug.1993665797" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.macosx.exe.debug">
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.macosx.exe.debug.option.optimization.level.1133705337" name="Optimization Level" superClass="gnu.c.compiler.macosx.exe.debug.option.optimization.level" valueType="enumerated"/>
<option id="gnu.c.compiler.macosx.exe.debug.option.debugging.level.396108330" name="Debug Level" superClass="gnu.c.compiler.macosx.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<option id="gnu.c.compiler.option.include.paths.28061496" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="/usr/include"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1884051627" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="cdt.managedbuild.config.macosx.exe.release.222902119">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.macosx.exe.release.222902119" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" 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"/>
<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.MachO64" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.macosx.exe.release.222902119" name="Release" parent="cdt.managedbuild.config.macosx.exe.release">
<folderInfo id="cdt.managedbuild.config.macosx.exe.release.222902119." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.macosx.exe.release.370067321" name="MacOSX GCC" superClass="cdt.managedbuild.toolchain.gnu.macosx.exe.release">
<targetPlatform id="cdt.managedbuild.target.gnu.platform.macosx.exe.release.1613432662" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.macosx.exe.release"/>
<builder buildPath="${workspace_loc:/scv_tr_sqlite}/Release" id="cdt.managedbuild.target.gnu.builder.macosx.exe.release.1921784777" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.macosx.exe.release"/>
<tool id="cdt.managedbuild.tool.macosx.c.linker.macosx.exe.release.835264205" name="MacOS X C Linker" superClass="cdt.managedbuild.tool.macosx.c.linker.macosx.exe.release"/>
<tool id="cdt.managedbuild.tool.macosx.cpp.linker.macosx.exe.release.807087528" name="MacOS X C++ Linker" superClass="cdt.managedbuild.tool.macosx.cpp.linker.macosx.exe.release">
<option id="macosx.cpp.link.option.paths.1094947030" name="Library search path (-L)" superClass="macosx.cpp.link.option.paths" valueType="libPaths">
<listOptionValue builtIn="false" value="/Users/eyck//Library/Frameworks/SystemC.framework/Versions/2.3.1/lib-macosx64"/>
</option>
<inputType id="cdt.managedbuild.tool.macosx.cpp.linker.input.1729026262" superClass="cdt.managedbuild.tool.macosx.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.assembler.macosx.exe.release.960768765" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.macosx.exe.release">
<option id="gnu.both.asm.option.include.paths.1211035001" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="/usr/include"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1845360319" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.archiver.macosx.base.2005529856" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.macosx.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.macosx.exe.release.1207281858" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.macosx.exe.release">
<option id="gnu.cpp.compiler.macosx.exe.release.option.optimization.level.1947685650" name="Optimization Level" superClass="gnu.cpp.compiler.macosx.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
<option id="gnu.cpp.compiler.macosx.exe.release.option.debugging.level.1098045969" name="Debug Level" superClass="gnu.cpp.compiler.macosx.exe.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
<option id="gnu.cpp.compiler.option.include.paths.2920067" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="/Users/eyck//Library/Frameworks/SystemC.framework/Versions/2.3.1/include"/>
<listOptionValue builtIn="false" value="/usr/include"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.749408456" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.macosx.exe.release.2136924185" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.macosx.exe.release">
<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.macosx.exe.release.option.optimization.level.713312654" name="Optimization Level" superClass="gnu.c.compiler.macosx.exe.release.option.optimization.level" valueType="enumerated"/>
<option id="gnu.c.compiler.macosx.exe.release.option.debugging.level.1629703352" name="Debug Level" superClass="gnu.c.compiler.macosx.exe.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
<option id="gnu.c.compiler.option.include.paths.1878457622" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="/usr/include"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.220005104" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="scv_tr_sqlite.cdt.managedbuild.target.macosx.exe.1724881597" name="Executable" projectType="cdt.managedbuild.target.macosx.exe"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.macosx.exe.debug.133691581;cdt.managedbuild.config.gnu.macosx.exe.debug.133691581.;cdt.managedbuild.tool.gnu.cpp.compiler.macosx.exe.debug.1149501692;cdt.managedbuild.tool.gnu.cpp.compiler.input.506955043">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.macosx.exe.release.222902119;cdt.managedbuild.config.macosx.exe.release.222902119.;cdt.managedbuild.tool.gnu.c.compiler.macosx.exe.release.2136924185;cdt.managedbuild.tool.gnu.c.compiler.input.220005104">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.macosx.exe.debug.133691581;cdt.managedbuild.config.gnu.macosx.exe.debug.133691581.;cdt.managedbuild.tool.gnu.c.compiler.macosx.exe.debug.1993665797;cdt.managedbuild.tool.gnu.c.compiler.input.1884051627">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.macosx.exe.release.222902119;cdt.managedbuild.config.macosx.exe.release.222902119.;cdt.managedbuild.tool.gnu.cpp.compiler.macosx.exe.release.1207281858;cdt.managedbuild.tool.gnu.cpp.compiler.input.749408456">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope"/>
</cproject>

View File

@ -1,4 +0,0 @@
/Debug/
/*.txlog
/*.txdb
/my_db.vcd

View File

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>scv_tr_sqlite</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<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>
</natures>
</projectDescription>

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="cdt.managedbuild.config.gnu.macosx.exe.debug.133691581" name="Debug">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider-reference id="org.eclipse.cdt.ui.UserLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" 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="(gcc)|([gc]\+\+)|(clang)" prefer-non-shared="true"/>
</extension>
</configuration>
<configuration id="cdt.managedbuild.config.macosx.exe.release.222902119" 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-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" ref="shared-provider"/>
</extension>
</configuration>
</project>

View File

@ -1,722 +0,0 @@
/*
* tlm_recording.h
*
* Created on: 07.11.2015
* Author: eyck
*/
#ifndef TLM2_RECORDER_H_
#define TLM2_RECORDER_H_
#include <scv.h>
#include <tlm>
#include "tlm_gp_data_ext.h"
#include "tlm_recording_extension.h"
#include <map>
#include <string>
#include <vector>
namespace scv4tlm {
/*! \brief The TLM2 transaction extensions recorder interface
*
* This interface is used by the TLM2 transaction recorder. It can be used to register custom recorder functionality
* to also record the payload extensions
*/
template< typename TYPES = tlm::tlm_base_protocol_types>
struct tlm2_extensions_recording_if {
/*! \brief recording attributes in extensions at the beginning, it is intended to be overload as it does nothing
*
*/
virtual void recordBeginTx(scv_tr_handle& handle, typename TYPES::tlm_payload_type& payload) = 0;
/*! \brief recording attributes in extensions at the end, it is intended to be overload as it does nothing
*
*/
virtual void recordEndTx(scv_tr_handle& handle, typename TYPES::tlm_payload_type& payload) = 0;
virtual ~tlm2_extensions_recording_if(){}
};
/*! \brief The TLM2 transaction recorder
*
* This module records all TLM transaction to a SCV transaction stream for further viewing and analysis.
* The handle of the created transaction is storee in an tlm_extension so that another instance of the scv_tlm2_recorder
* e.g. further down the opath can link to it.
*/
template< typename TYPES = tlm::tlm_base_protocol_types>
class tlm2_recorder:
public virtual tlm::tlm_fw_transport_if<TYPES>,
public virtual tlm::tlm_bw_transport_if<TYPES>,
public sc_core::sc_object {
public:
SC_HAS_PROCESS(tlm2_recorder<TYPES>);
//! \brief the attribute to selectively enable/disable recording
sc_core::sc_attribute<bool> enable;
//! \brief the attribute to selectively enable/disable timed recording
sc_core::sc_attribute<bool> enableTimed;
//! \brief the port where fw accesses are forwarded to
sc_core::sc_port<tlm::tlm_fw_transport_if<TYPES> > fw_port;
//! \brief the port where bw accesses are forwarded to
sc_core::sc_port<tlm::tlm_bw_transport_if<TYPES> > bw_port;
/*! \brief The constructor of the component
*
* \param name is the SystemC module name of the recorder
* \param tr_db is a pointer to a transaction recording database. If none is provided the default one is retrieved.
* If this database is not initialized (e.g. by not calling scv_tr_db::set_default_db() ) recording is disabled.
*/
tlm2_recorder(bool recording_enabled = true, scv_tr_db* tr_db = scv_tr_db::get_default_db()){
this->tlm2_recorder::tlm2_recorder(sc_core::sc_gen_unique_name("tlm2_recorder"), recording_enabled, tr_db);
}
/*! \brief The constructor of the component
*
* \param name is the SystemC module name of the recorder
* \param tr_db is a pointer to a transaction recording database. If none is provided the default one is retrieved.
* If this database is not initialized (e.g. by not calling scv_tr_db::set_default_db() ) recording is disabled.
*/
tlm2_recorder(const char* name, bool recording_enabled = true, scv_tr_db* tr_db = scv_tr_db::get_default_db())
: sc_core::sc_object(name)
, enable("enable", recording_enabled)
, enableTimed("enableTimed", recording_enabled)
, fw_port(sc_core::sc_gen_unique_name("fw"))
, bw_port(sc_core::sc_gen_unique_name("bw"))
, mm(new RecodingMemoryManager())
, b_timed_peq(this, &tlm2_recorder::btx_cb)
, nb_timed_peq(this, &tlm2_recorder::nbtx_cb)
, m_db(tr_db)
, b_streamHandle(NULL)
, b_streamHandleTimed(NULL)
, b_trTimedHandle(3)
, nb_streamHandle(2)
, nb_streamHandleTimed(2)
, nb_fw_trHandle(3)
, nb_txReqHandle(3)
, nb_bw_trHandle(3)
, nb_txRespHandle(3)
, dmi_streamHandle(NULL)
, dmi_trGetHandle(NULL)
, dmi_trInvalidateHandle(NULL)
, extensionRecording(NULL)
{
}
virtual ~tlm2_recorder(){
delete b_streamHandle;
delete b_streamHandleTimed;
for(size_t i = 0; i<b_trTimedHandle.size(); ++i) delete b_trTimedHandle[i];
for(size_t i = 0; i<nb_streamHandle.size(); ++i) delete nb_streamHandle[i];
for(size_t i = 0; i<nb_streamHandleTimed.size(); ++i) delete nb_streamHandleTimed[i];
for(size_t i = 0; i<nb_fw_trHandle.size(); ++i) delete nb_fw_trHandle[i];
for(size_t i = 0; i<nb_txReqHandle.size(); ++i) delete nb_txReqHandle[i];
for(size_t i = 0; i<nb_bw_trHandle.size(); ++i) delete nb_bw_trHandle[i];
for(size_t i = 0; i<nb_txRespHandle.size(); ++i) delete nb_txRespHandle[i];
delete dmi_streamHandle;
delete dmi_trGetHandle;
delete dmi_trInvalidateHandle;
delete extensionRecording;
}
// TLM-2.0 interface methods for initiator and target sockets, surrounded with Tx Recording
/*! \brief The non-blocking forward transport function
*
* This type of transaction is forwarded and recorded to a transaction stream named "nb_fw" with current timestamps.
* \param trans is the generic payload of the transaction
* \param phase is the current phase of the transaction
* \param delay is the annotated delay
* \return the sync state of the transaction
*/
virtual tlm::tlm_sync_enum nb_transport_fw(typename TYPES::tlm_payload_type& trans, typename TYPES::tlm_phase_type& phase,
sc_core::sc_time& delay);
/*! \brief The non-blocking backward transport function
*
* This type of transaction is forwarded and recorded to a transaction stream named "nb_bw" with current timestamps.
* \param trans is the generic payload of the transaction
* \param phase is the current phase of the transaction
* \param delay is the annotated delay
* \return the sync state of the transaction
*/
virtual tlm::tlm_sync_enum nb_transport_bw(typename TYPES::tlm_payload_type& trans, typename TYPES::tlm_phase_type& phase,
sc_core::sc_time& delay);
/*! \brief The blocking transport function
*
* This type of transaction is forwarded and recorded to a transaction stream named "b_tx" with current timestamps. Additionally a "b_tx_timed"
* is been created recording the transactions at their annotated delay
* \param trans is the generic payload of the transaction
* \param delay is the annotated delay
*/
virtual void b_transport(typename TYPES::tlm_payload_type& trans, sc_core::sc_time& delay);
/*! \brief The direct memory interface forward function
*
* This type of transaction is just forwarded and not recorded.
* \param trans is the generic payload of the transaction
* \param dmi_data is the structure holding the dmi information
* \return if the dmi structure is valid
*/
virtual bool get_direct_mem_ptr(typename TYPES::tlm_payload_type& trans, tlm::tlm_dmi& dmi_data);
/*! \brief The direct memory interface backward function
*
* This type of transaction is just forwarded and not recorded.
* \param start_addr is the start address of the memory area being invalid
* \param end_addr is the end address of the memory area being invalid
*/
virtual void invalidate_direct_mem_ptr(sc_dt::uint64 start_addr, sc_dt::uint64 end_addr);
/*! \brief The debug transportfunction
*
* This type of transaction is just forwarded and not recorded.
* \param trans is the generic payload of the transaction
* \return the sync state of the transaction
*/
virtual unsigned int transport_dbg(typename TYPES::tlm_payload_type& trans);
/*! \brief get the current state of transaction recording
*
* \return if true transaction recording is enabled otherwise transaction recording is bypassed
*/
const bool isRecordingEnabled() const {
return m_db != NULL && enable.value;
}
void setExtensionRecording(tlm2_extensions_recording_if<TYPES>* extensionRecording){
this->extensionRecording=extensionRecording;
}
private:
//! \brief the struct to hold the information to be recorded on the timed streams
struct tlm_recording_payload: public TYPES::tlm_payload_type {
scv_tr_handle parent;
uint64 id;
tlm_recording_payload& operator=(const typename TYPES::tlm_payload_type& x){
id=(uint64)&x;
set_command(x.get_command());
set_address(x.get_address());
set_data_ptr(x.get_data_ptr());
set_data_length(x.get_data_length());
set_response_status(x.get_response_status());
set_byte_enable_ptr(x.get_byte_enable_ptr());
set_byte_enable_length(x.get_byte_enable_length());
set_streaming_width(x.get_streaming_width());
return (*this);
}
explicit tlm_recording_payload(tlm::tlm_mm_interface* mm) :
TYPES::tlm_payload_type(mm), parent(), id(0) {
}
};
//! \brief Memory manager for the tlm_recording_payload
struct RecodingMemoryManager: public tlm::tlm_mm_interface {
RecodingMemoryManager() :
free_list(0), empties(0) {
}
tlm_recording_payload* allocate() {
typename TYPES::tlm_payload_type* ptr;
if (free_list) {
ptr = free_list->trans;
empties = free_list;
free_list = free_list->next;
} else {
ptr = new tlm_recording_payload(this);
}
return (tlm_recording_payload*) ptr;
}
void free(typename TYPES::tlm_payload_type* trans) {
trans->reset();
if (!empties) {
empties = new access;
empties->next = free_list;
empties->prev = 0;
if (free_list)
free_list->prev = empties;
}
free_list = empties;
free_list->trans = trans;
empties = free_list->prev;
}
private:
struct access {
typename TYPES::tlm_payload_type* trans;
access* next;
access* prev;
};
access *free_list, *empties;
};
RecodingMemoryManager* mm;
//! peq type definition
struct recording_types {
typedef tlm_recording_payload tlm_payload_type;
typedef typename TYPES::tlm_phase_type tlm_phase_type;
};
//! event queue to hold time points of blocking transactions
tlm_utils::peq_with_cb_and_phase<tlm2_recorder, recording_types> b_timed_peq;
//! event queue to hold time points of non-blocking transactions
tlm_utils::peq_with_cb_and_phase<tlm2_recorder, recording_types> nb_timed_peq;
/*! \brief The thread processing the blocking accesses with their annotated times
* to generate the timed view of blocking tx
*/
void btx_cb(tlm_recording_payload& rec_parts, const typename TYPES::tlm_phase_type& phase);
/*! \brief The thread processing the non-blocking requests with their annotated times
* to generate the timed view of non-blocking tx
*/
void nbtx_cb(tlm_recording_payload& rec_parts, const typename TYPES::tlm_phase_type& phase);
//! transaction recording database
scv_tr_db* m_db;
//! blocking transaction recording stream handle
scv_tr_stream* b_streamHandle;
//! transaction generator handle for blocking transactions
scv_tr_generator<sc_dt::uint64, sc_dt::uint64>* b_trHandle[3];
//! timed blocking transaction recording stream handle
scv_tr_stream* b_streamHandleTimed;
//! transaction generator handle for blocking transactions with annotated delays
std::vector<scv_tr_generator<tlm::tlm_command, tlm::tlm_response_status>*> b_trTimedHandle;
std::map<uint64, scv_tr_handle> btx_handle_map;
enum DIR{FW, BW};
//! non-blocking transaction recording stream handle
std::vector<scv_tr_stream*> nb_streamHandle;
//! non-blocking transaction recording stream handle
std::vector<scv_tr_stream*> nb_streamHandleTimed;
//! transaction generator handle for forward non-blocking transactions
std::vector<scv_tr_generator<tlm::tlm_phase_enum, tlm::tlm_sync_enum>*> nb_fw_trHandle;
//! transaction generator handle for forward non-blocking transactions with annotated delays
std::vector<scv_tr_generator<>*> nb_txReqHandle;
map<uint64, scv_tr_handle> nbtx_req_handle_map;
//! transaction generator handle for backward non-blocking transactions
std::vector<scv_tr_generator<tlm::tlm_phase_enum, tlm::tlm_sync_enum>*> nb_bw_trHandle;
//! transaction generator handle for backward non-blocking transactions with annotated delays
std::vector<scv_tr_generator<>*> nb_txRespHandle;
map<uint64, scv_tr_handle> nbtx_last_req_handle_map;
//! dmi transaction recording stream handle
scv_tr_stream* dmi_streamHandle;
//! transaction generator handle for DMI transactions
scv_tr_generator<tlm_gp_data, tlm_dmi_data>* dmi_trGetHandle;
scv_tr_generator<sc_dt::uint64, sc_dt::uint64>* dmi_trInvalidateHandle;
tlm2_extensions_recording_if<TYPES>* extensionRecording;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// implementations of functions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template< typename TYPES>
void tlm2_recorder<TYPES>::b_transport(typename TYPES::tlm_payload_type& trans, sc_core::sc_time& delay) {
tlm_recording_payload* req;
if (!isRecordingEnabled()) {
fw_port->b_transport(trans, delay);
return;
}
if (b_streamHandle == NULL) {
string basename(this->name());
b_streamHandle = new scv_tr_stream((basename + ".blocking").c_str(), "TRANSACTOR", m_db);
b_trHandle[tlm::TLM_READ_COMMAND] = new scv_tr_generator<sc_dt::uint64, sc_dt::uint64>("read", *b_streamHandle, "start_delay",
"end_delay");
b_trHandle[tlm::TLM_WRITE_COMMAND] = new scv_tr_generator<sc_dt::uint64, sc_dt::uint64>("write", *b_streamHandle, "start_delay",
"end_delay");
b_trHandle[tlm::TLM_IGNORE_COMMAND] = new scv_tr_generator<sc_dt::uint64, sc_dt::uint64>("ignore", *b_streamHandle, "start_delay",
"end_delay");
}
// Get a handle for the new transaction
scv_tr_handle h = b_trHandle[trans.get_command()]->begin_transaction(delay.value(), sc_time_stamp());
tlm_gp_data tgd(trans);
/*************************************************************************
* do the timed notification
*************************************************************************/
if (enableTimed.value) {
req = mm->allocate();
req->acquire();
(*req) = trans;
req->parent = h;
req->id=h.get_id();
#ifdef DEBUG
cout<<"notify addition of parent with id "<<req->id<<" to btx_handle_map with delay "<<delay<<std::endl;
#endif
b_timed_peq.notify(*req, tlm::BEGIN_REQ, delay);
}
if(extensionRecording) extensionRecording->recordBeginTx(h, trans);
tlm_recording_extension* preExt = NULL;
trans.get_extension(preExt);
if (preExt == NULL) { // we are the first recording this transaction
preExt = new tlm_recording_extension(h, this);
trans.set_extension(preExt);
} else {
h.add_relation(rel_str(PREDECESSOR_SUCCESSOR), preExt->txHandle);
}
scv_tr_handle preTx(preExt->txHandle);
fw_port->b_transport(trans, delay);
trans.get_extension(preExt);
if (preExt->get_creator() == this) {
// clean-up the extension if this is the original creator
delete preExt;
trans.set_extension((tlm_recording_extension*) NULL);
} else {
preExt->txHandle=preTx;
}
tgd.set_response_status(trans.get_response_status());
h.record_attribute("trans", tgd);
h.record_attribute("trans.data_value", *(uint64_t*)trans.get_data_ptr());
if(extensionRecording) extensionRecording->recordEndTx(h, trans);
// End the transaction
b_trHandle[trans.get_command()]->end_transaction(h, delay.value(), sc_time_stamp());
// and now the stuff for the timed tx
if (enableTimed.value){
#ifdef DEBUG
cout<<"notify removal of parent with id "<<req->id<<" to btx_handle_map with delay "<<delay<<std::endl;
#endif
b_timed_peq.notify(*req, tlm::END_RESP, delay);
}
}
template< typename TYPES>
void tlm2_recorder<TYPES>::btx_cb(tlm_recording_payload& rec_parts, const typename TYPES::tlm_phase_type& phase) {
scv_tr_handle h;
if (b_trTimedHandle[0] == NULL) {
std::string basename(this->name());
b_streamHandleTimed = new scv_tr_stream((basename + ".blocking_annotated").c_str(), "TRANSACTOR", m_db);
b_trTimedHandle[0] = new scv_tr_generator<tlm::tlm_command, tlm::tlm_response_status>("read", *b_streamHandleTimed);
b_trTimedHandle[1] = new scv_tr_generator<tlm::tlm_command, tlm::tlm_response_status>("write", *b_streamHandleTimed);
b_trTimedHandle[2] = new scv_tr_generator<tlm::tlm_command, tlm::tlm_response_status>("ignore", *b_streamHandleTimed);
}
// Now process outstanding recordings
switch (phase) {
case tlm::BEGIN_REQ:
{
tlm_gp_data tgd(rec_parts);
h = b_trTimedHandle[rec_parts.get_command()]->begin_transaction(rec_parts.get_command());
h.record_attribute("trans", tgd);
h.add_relation(rel_str(PARENT_CHILD), rec_parts.parent);
#ifdef DEBUG
cout<<"adding parent with id "<<rec_parts.id<<" to btx_handle_map"<<std::endl;
#endif
btx_handle_map[rec_parts.id] = h;
}
break;
case tlm::END_RESP: {
#ifdef DEBUG
cout<<"retrieving parent with id "<<rec_parts.id<<" from btx_handle_map"<<std::endl;
#endif
std::map<uint64, scv_tr_handle>::iterator it = btx_handle_map.find(rec_parts.id);
sc_assert(it != btx_handle_map.end());
h = it->second;
btx_handle_map.erase(it);
h.end_transaction(h, rec_parts.get_response_status());
rec_parts.release();
}
break;
default:
sc_assert(!"phase not supported!");
}
return;
}
template< typename TYPES>
tlm::tlm_sync_enum tlm2_recorder<TYPES>::nb_transport_fw(
typename TYPES::tlm_payload_type& trans,
typename TYPES::tlm_phase_type& phase,
sc_core::sc_time& delay) {
if (!isRecordingEnabled())
return fw_port->nb_transport_fw(trans, phase, delay);
// initialize stream and generator if not yet done
if (nb_streamHandle[FW] == NULL) {
string basename(this->name());
nb_streamHandle[FW] = new scv_tr_stream((basename + ".nb_forward").c_str(), "TRANSACTOR", m_db);
nb_fw_trHandle[tlm::TLM_READ_COMMAND] = new scv_tr_generator<tlm::tlm_phase_enum, tlm::tlm_sync_enum>("read", *nb_streamHandle[FW], "tlm_phase", "tlm_sync");
nb_fw_trHandle[tlm::TLM_WRITE_COMMAND] = new scv_tr_generator<tlm::tlm_phase_enum, tlm::tlm_sync_enum>("write", *nb_streamHandle[FW], "tlm_phase", "tlm_sync");
nb_fw_trHandle[tlm::TLM_IGNORE_COMMAND] = new scv_tr_generator<tlm::tlm_phase_enum, tlm::tlm_sync_enum>("ignore", *nb_streamHandle[FW], "tlm_phase", "tlm_sync");
}
/*************************************************************************
* prepare recording
*************************************************************************/
// Get a handle for the new transaction
scv_tr_handle h = nb_fw_trHandle[trans.get_command()]->begin_transaction((tlm::tlm_phase_enum) (unsigned) phase);
tlm_recording_extension* preExt = NULL;
trans.get_extension(preExt);
if (phase == tlm::BEGIN_REQ && preExt == NULL) { // we are the first recording this transaction
preExt = new tlm_recording_extension(h, this);
trans.set_extension(preExt);
} else if (preExt != NULL) {
// link handle if we have a predecessor
h.add_relation(rel_str(PREDECESSOR_SUCCESSOR), preExt->txHandle);
} else {
sc_assert(preExt!=NULL && "ERROR on forward path in phase other than tlm::BEGIN_REQ");
}
// update the extension
preExt->txHandle = h;
h.record_attribute("delay", delay.to_string());
if(extensionRecording) extensionRecording->recordBeginTx(h, trans);
tlm_gp_data tgd(trans);
/*************************************************************************
* do the timed notification
*************************************************************************/
if (enableTimed.value) {
tlm_recording_payload* req = mm->allocate();
req->acquire();
(*req) = trans;
req->parent = h;
nb_timed_peq.notify(*req, phase, delay);
}
/*************************************************************************
* do the access
*************************************************************************/
tlm::tlm_sync_enum status = fw_port->nb_transport_fw(trans, phase, delay);
/*************************************************************************
* handle recording
*************************************************************************/
tgd.set_response_status(trans.get_response_status());
h.record_attribute("trans", tgd);
if(extensionRecording) extensionRecording->recordEndTx(h, trans);
h.record_attribute("tlm_phase[return_path]", (tlm::tlm_phase_enum) (unsigned) phase);
h.record_attribute("delay[return_path]", delay.to_string());
// get the extension and free the memory if it was mine
if (status == tlm::TLM_COMPLETED || (status == tlm::TLM_ACCEPTED && phase == tlm::END_RESP)) {
trans.get_extension(preExt);
if (preExt->get_creator() == this) {
delete preExt;
trans.set_extension((tlm_recording_extension*) NULL);
}
/*************************************************************************
* do the timed notification if req. finished here
*************************************************************************/
tlm_recording_payload* req = mm->allocate();
req->acquire();
(*req) = trans;
req->parent = h;
nb_timed_peq.notify(*req, (status == tlm::TLM_COMPLETED && phase == tlm::BEGIN_REQ) ? tlm::END_RESP : phase,
delay);
} else if (status == tlm::TLM_UPDATED) {
tlm_recording_payload* req = mm->allocate();
req->acquire();
(*req) = trans;
req->parent = h;
nb_timed_peq.notify(*req, phase, delay);
}
// End the transaction
nb_fw_trHandle[trans.get_command()]->end_transaction(h, status);
return status;
}
template< typename TYPES>
tlm::tlm_sync_enum tlm2_recorder<TYPES>::nb_transport_bw(typename TYPES::tlm_payload_type& trans, typename TYPES::tlm_phase_type& phase,
sc_core::sc_time& delay) {
if (!isRecordingEnabled())
return bw_port->nb_transport_bw(trans, phase, delay);
if (nb_streamHandle[BW] == NULL) {
string basename(this->name());
nb_streamHandle[BW] = new scv_tr_stream((basename + ".nb_backward").c_str(), "TRANSACTOR", m_db);
nb_bw_trHandle[0] = new scv_tr_generator<tlm::tlm_phase_enum, tlm::tlm_sync_enum>("read", *nb_streamHandle[BW], "tlm_phase", "tlm_sync");
nb_bw_trHandle[1] = new scv_tr_generator<tlm::tlm_phase_enum, tlm::tlm_sync_enum>("write", *nb_streamHandle[BW], "tlm_phase", "tlm_sync");
nb_bw_trHandle[2] = new scv_tr_generator<tlm::tlm_phase_enum, tlm::tlm_sync_enum>("ignore", *nb_streamHandle[BW], "tlm_phase", "tlm_sync");
}
/*************************************************************************
* prepare recording
*************************************************************************/
tlm_recording_extension* preExt = NULL;
trans.get_extension(preExt);
sc_assert(preExt!=NULL && "ERROR on backward path");
// Get a handle for the new transaction
scv_tr_handle h = nb_bw_trHandle[trans.get_command()]->begin_transaction((tlm::tlm_phase_enum) (unsigned) phase);
// link handle if we have a predecessor and that's not ourself
h.add_relation(rel_str(PREDECESSOR_SUCCESSOR), preExt->txHandle);
// and set the extension handle to this transaction
preExt->txHandle = h;
h.record_attribute("delay", delay.to_string());
if(extensionRecording) extensionRecording->recordBeginTx(h, trans);
tlm_gp_data tgd(trans);
/*************************************************************************
* do the timed notification
*************************************************************************/
if (enableTimed.value) {
tlm_recording_payload* req = mm->allocate();
req->acquire();
(*req) = trans;
req->parent = h;
nb_timed_peq.notify(*req, phase, delay);
}
/*************************************************************************
* do the access
*************************************************************************/
tlm::tlm_sync_enum status = bw_port->nb_transport_bw(trans, phase, delay);
/*************************************************************************
* handle recording
*************************************************************************/
tgd.set_response_status(trans.get_response_status());
h.record_attribute("trans", tgd);
if(extensionRecording) extensionRecording->recordEndTx(h, trans);
// phase and delay are already recorded
h.record_attribute("phase_upd", (tlm::tlm_phase_enum) (unsigned) phase);
h.record_attribute("delay_upd", delay.to_string());
// End the transaction
nb_bw_trHandle[trans.get_command()]->end_transaction(h, status);
if (status == tlm::TLM_COMPLETED || (status == tlm::TLM_UPDATED && phase == tlm::END_RESP)) {
// the transaction is finished
trans.get_extension(preExt);
if (preExt->get_creator() == this) {
// clean-up the extension if this is the original creator
delete preExt;
trans.set_extension((tlm_recording_extension*) NULL);
}
/*************************************************************************
* do the timed notification if req. finished here
*************************************************************************/
tlm_recording_payload* req = mm->allocate();
req->acquire();
(*req) = trans;
req->parent = h;
nb_timed_peq.notify(*req, phase, delay);
}
return status;
}
template< typename TYPES>
void tlm2_recorder<TYPES>::nbtx_cb(tlm_recording_payload& rec_parts, const typename TYPES::tlm_phase_type& phase) {
scv_tr_handle h;
std::map<uint64, scv_tr_handle>::iterator it;
if (nb_streamHandleTimed[FW] == NULL) {
std::string basename(this->name());
nb_streamHandleTimed[FW] = new scv_tr_stream((basename + ".nb_request_annotated").c_str(), "TRANSACTOR", m_db);
nb_txReqHandle[0] = new scv_tr_generator<>("read", *nb_streamHandleTimed[FW]);
nb_txReqHandle[1] = new scv_tr_generator<>("write", *nb_streamHandleTimed[FW]);
nb_txReqHandle[2] = new scv_tr_generator<>("ignore", *nb_streamHandleTimed[FW]);
}
if (nb_streamHandleTimed[BW] == NULL) {
std::string basename(this->name());
nb_streamHandleTimed[BW] = new scv_tr_stream((basename + ".nb_response_annotated").c_str(), "TRANSACTOR", m_db);
nb_txRespHandle[0] = new scv_tr_generator<>("read", *nb_streamHandleTimed[BW]);
nb_txRespHandle[1] = new scv_tr_generator<>("write", *nb_streamHandleTimed[BW]);
nb_txRespHandle[2] = new scv_tr_generator<>("ignore", *nb_streamHandleTimed[BW]);
}
tlm_gp_data tgd(rec_parts);
switch (phase) { // Now process outstanding recordings
case tlm::BEGIN_REQ:
h = nb_txReqHandle[rec_parts.get_command()]->begin_transaction();
h.record_attribute("trans", tgd);
h.add_relation(rel_str(PARENT_CHILD), rec_parts.parent);
#ifdef NBDEBUG
cout<<"adding parent with id "<<rec_parts.id<<" to nbtx_req_handle_map"<<std::endl;
#endif
nbtx_req_handle_map[rec_parts.id] = h;
break;
case tlm::END_REQ:
#ifdef NBDEBUG
cout<<"retrieving parent with id "<<rec_parts.id<<" from nbtx_req_handle_map"<<std::endl;
#endif
it = nbtx_req_handle_map.find(rec_parts.id);
sc_assert(it != nbtx_req_handle_map.end());
h = it->second;
nbtx_req_handle_map.erase(it);
h.end_transaction();
nbtx_last_req_handle_map[rec_parts.id] = h;
break;
case tlm::BEGIN_RESP:
#ifdef NBDEBUG
cout<<"retrieving parent with id "<<rec_parts.id<<" from nbtx_req_handle_map"<<std::endl;
#endif
it = nbtx_req_handle_map.find(rec_parts.id);
if (it != nbtx_req_handle_map.end()) {
h = it->second;
nbtx_req_handle_map.erase(it);
h.end_transaction();
nbtx_last_req_handle_map[rec_parts.id] = h;
}
h = nb_txRespHandle[rec_parts.get_command()]->begin_transaction();
h.record_attribute("trans", tgd);
h.add_relation(rel_str(PARENT_CHILD), rec_parts.parent);
nbtx_req_handle_map[rec_parts.id] = h;
it = nbtx_last_req_handle_map.find(rec_parts.id);
if (it != nbtx_last_req_handle_map.end()) {
scv_tr_handle pred = it->second;
nbtx_last_req_handle_map.erase(it);
h.add_relation(rel_str(PREDECESSOR_SUCCESSOR), pred);
}
break;
case tlm::END_RESP:
#ifdef NBDEBUG
cout<<"retrieving parent with id "<<rec_parts.id<<" from nbtx_req_handle_map"<<std::endl;
#endif
it = nbtx_req_handle_map.find(rec_parts.id);
if (it != nbtx_req_handle_map.end()) {
h = it->second;
nbtx_req_handle_map.erase(it);
h.end_transaction();
}
break;
default:
sc_assert(!"phase not supported!");
}
rec_parts.release();
return;
}
template< typename TYPES>
bool tlm2_recorder<TYPES>::get_direct_mem_ptr(typename TYPES::tlm_payload_type& trans, tlm::tlm_dmi& dmi_data) {
if (!isRecordingEnabled()) {
return fw_port->get_direct_mem_ptr(trans, dmi_data);
}
if (dmi_streamHandle == NULL) {
string basename(this->name());
dmi_streamHandle = new scv_tr_stream((basename + ".dmi").c_str(), "TRANSACTOR", m_db);
dmi_trGetHandle = new scv_tr_generator<tlm_gp_data, tlm_dmi_data>("get_dmi_ptr", *b_streamHandle, "trans",
"dmi_data");
dmi_trInvalidateHandle = new scv_tr_generator<sc_dt::uint64, sc_dt::uint64>("invalidate", *b_streamHandle, "start_delay",
"end_delay");
}
scv_tr_handle h = dmi_trGetHandle->begin_transaction(tlm_gp_data(trans));
bool status= fw_port->get_direct_mem_ptr(trans, dmi_data);
dmi_trGetHandle->end_transaction(h, tlm_dmi_data(dmi_data));
return status;
}
/*! \brief The direct memory interface backward function
*
* This type of transaction is just forwarded and not recorded.
* \param start_addr is the start address of the memory area being invalid
* \param end_addr is the end address of the memory area being invalid
*/
template< typename TYPES>
void tlm2_recorder<TYPES>::invalidate_direct_mem_ptr(sc_dt::uint64 start_addr, sc_dt::uint64 end_addr) {
if (!isRecordingEnabled()) {
bw_port->invalidate_direct_mem_ptr(start_addr, end_addr);
return;
}
if (dmi_streamHandle == NULL) {
string basename(this->name());
dmi_streamHandle = new scv_tr_stream((basename + ".dmi").c_str(), "TRANSACTOR", m_db);
dmi_trGetHandle = new scv_tr_generator<tlm_gp_data, tlm_dmi_data>("get_dmi_ptr", *b_streamHandle, "trans",
"dmi_data");
dmi_trInvalidateHandle = new scv_tr_generator<sc_dt::uint64, sc_dt::uint64>("invalidate", *b_streamHandle, "start_delay",
"end_delay");
}
scv_tr_handle h = dmi_trInvalidateHandle->begin_transaction(start_addr);
bw_port->invalidate_direct_mem_ptr(start_addr, end_addr);
dmi_trInvalidateHandle->end_transaction(h, end_addr);
return;
}
/*! \brief The debug transportfunction
*
* This type of transaction is just forwarded and not recorded.
* \param trans is the generic payload of the transaction
* \return the sync state of the transaction
*/
template< typename TYPES>
unsigned int tlm2_recorder<TYPES>::transport_dbg(typename TYPES::tlm_payload_type& trans) {
unsigned int count = fw_port->transport_dbg(trans);
return count;
}
} // namespace
#endif /* TLM2_RECORDER_H_ */

View File

@ -1,61 +0,0 @@
/*
* tlm_recorder.h
*
* Created on: 07.11.2015
* Author: eyck
*/
#ifndef TLM2_RECORDER_MODULE_H_
#define TLM2_RECORDER_MODULE_H_
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/simple_target_socket.h>
#include "tlm2_recorder.h"
namespace scv4tlm {
/*! \brief The TLM2 transaction recorder
*
* This module records all TLM transaction to a SCV transaction stream for further viewing and analysis.
* The handle of the created transaction is storee in an tlm_extension so that another instance of the scv_tlm2_recorder
* e.g. further down the opath can link to it.
* The transaction recorder is simply bound between an existing pair of initiator and target sockets
*/
template<unsigned int BUSWIDTH = 32, typename TYPES=tlm::tlm_base_protocol_types>
class tlm2_recorder_module: public sc_core::sc_module, public tlm2_recorder<TYPES> {
public:
SC_HAS_PROCESS(tlm2_recorder_module);
//! The target socket of the recorder to be bound to the initiator
tlm::tlm_target_socket<BUSWIDTH, TYPES, 1> target;
//! The initiator to be bound to the target socket
tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1> initiator;
/*! \brief The constructor of the component
*
* \param name is the SystemC module name of the recorder
* \param tr_db is a pointer to a transaction recording database. If none is provided the default one is retrieved.
* If this database is not initialized (e.g. by not calling scv_tr_db::set_default_db() ) recording is disabled.
*/
tlm2_recorder_module(sc_core::sc_module_name name, bool recording_enabled = true, scv_tr_db* tr_db = scv_tr_db::get_default_db())
: sc_module(name)
, tlm2_recorder<TYPES>(recording_enabled, tr_db)
{
// bind the sockets to the module
target.bind(*this);
initiator.bind(*this);
}
virtual ~tlm2_recorder_module(){}
virtual tlm::tlm_fw_transport_if<tlm::tlm_base_protocol_types>* get_fw_if() {
return initiator.get_base_port().operator->();
}
virtual tlm::tlm_bw_transport_if<tlm::tlm_base_protocol_types>* get_bw_if() {
return target.get_base_port().operator->();
}
};
} // namespace
#endif /* TLM2_RECORDER_MODULE_H_ */

View File

@ -1,557 +0,0 @@
/*
* tlm_gp_data.h
*
* Created on: 07.11.2015
* Author: eyck
*/
#ifndef TLM_GP_DATA_H_
#define TLM_GP_DATA_H_
#include <tlm>
#include <assert.h>
namespace scv4tlm {
struct tlm_gp_data {
//---------------
// Constructors
//---------------
// Default constructor
tlm_gp_data()
: address(0)
, command(tlm::TLM_IGNORE_COMMAND)
, data(0)
, data_length(0)
, response_status(tlm::TLM_INCOMPLETE_RESPONSE)
, dmi(false)
, byte_enable(0)
, byte_enable_length(0)
, streaming_width(0)
, gp_option(tlm::TLM_MIN_PAYLOAD)
, m_extensions(tlm::max_num_extensions())
, m_ref_count(0)
{
}
explicit tlm_gp_data(tlm::tlm_mm_interface* mm)
: address(0)
, command(tlm::TLM_IGNORE_COMMAND)
, data(0)
, data_length(0)
, response_status(tlm::TLM_INCOMPLETE_RESPONSE)
, dmi(false)
, byte_enable(0)
, byte_enable_length(0)
, streaming_width(0)
, gp_option(tlm::TLM_MIN_PAYLOAD)
, m_extensions(tlm::max_num_extensions())
, m_ref_count(0) {
}
int get_ref_count() const {
return m_ref_count;
}
void reset() {
//should the other members be reset too?
gp_option = tlm::TLM_MIN_PAYLOAD;
m_extensions.free_entire_cache();
}
;
tlm_gp_data(const tlm::tlm_generic_payload& x)
: address(x.get_address())
, command(x.get_command())
, data(x.get_data_ptr())
, data_length(x.get_data_length())
, response_status(x.get_response_status())
, dmi(x.is_dmi_allowed())
, byte_enable(x.get_byte_enable_ptr())
, byte_enable_length(x.get_byte_enable_length())
, streaming_width(x.get_streaming_width())
, gp_option(x.get_gp_option())
, m_extensions(tlm::max_num_extensions())
, m_ref_count(0)
{
}
private:
//disabled copy ctor and assignment operator.
// Copy constructor
tlm_gp_data(const tlm_gp_data& x)
: address(x.get_address())
, command(x.get_command())
, data(x.get_data_ptr())
, data_length(x.get_data_length())
, response_status(x.get_response_status())
, dmi(x.is_dmi_allowed())
, byte_enable(x.get_byte_enable_ptr())
, byte_enable_length(x.get_byte_enable_length())
, streaming_width(x.get_streaming_width())
, gp_option(x.gp_option)
, m_extensions(tlm::max_num_extensions())
, m_ref_count(0)
{
}
public:
// Assignment operator needed for SCV introspection
tlm_gp_data& operator=(const tlm_gp_data& x) {
command = x.get_command();
address = x.get_address();
data = x.get_data_ptr();
data_length = x.get_data_length();
response_status = x.get_response_status();
byte_enable = x.get_byte_enable_ptr();
byte_enable_length = x.get_byte_enable_length();
streaming_width = x.get_streaming_width();
gp_option = x.get_gp_option();
dmi = x.is_dmi_allowed();
// extension copy: all extension arrays must be of equal size by
// construction (i.e. it must either be constructed after C++
// static construction time, or the resize_extensions() method must
// have been called prior to using the object)
for (unsigned int i = 0; i < m_extensions.size(); i++) {
m_extensions[i] = x.get_extension(i);
}
return (*this);
}
// non-virtual deep-copying of the object
void deep_copy_from(const scv4tlm::tlm_gp_data & other) {
command = other.get_command();
address = other.get_address();
data_length = other.get_data_length();
response_status = other.get_response_status();
byte_enable_length = other.get_byte_enable_length();
streaming_width = other.get_streaming_width();
gp_option = other.get_gp_option();
dmi = other.is_dmi_allowed();
// deep copy data
// there must be enough space in the target transaction!
if (data && other.get_data_ptr()) {
memcpy(data, other.get_data_ptr(), data_length);
}
// deep copy byte enables
// there must be enough space in the target transaction!
if (byte_enable && other.get_byte_enable_ptr()) {
memcpy(byte_enable, other.get_byte_enable_ptr(), byte_enable_length);
}
// deep copy extensions (sticky and non-sticky)
for (unsigned int i = 0; i < other.m_extensions.size(); i++) {
if (other.get_extension(i)) { //original has extension i
if (!m_extensions[i]) { //We don't: clone.
tlm::tlm_extension_base *ext = other.get_extension(i)->clone();
if (ext) //extension may not be clonable.
{
set_extension(i, ext);
}
} else { //We already have such extension. Copy original over it.
m_extensions[i]->copy_from(*other.get_extension(i));
}
}
}
}
// To update the state of the original generic payload from a deep copy
// Assumes that "other" was created from the original by calling deep_copy_from
// Argument use_byte_enable_on_read determines whether to use or ignores byte enables
// when copying back the data array on a read command
void update_original_from(const tlm::tlm_generic_payload & other, bool use_byte_enable_on_read = true) {
// Copy back extensions that are present on the original
// update_extensions_from(other);
// Copy back the response status and DMI hint attributes
response_status = other.get_response_status();
dmi = other.is_dmi_allowed();
// Copy back the data array for a read command only
// deep_copy_from allowed null pointers, and so will we
// We assume the arrays are the same size
// We test for equal pointers in case the original and the copy share the same array
if (is_read() && data && other.get_data_ptr() && data != other.get_data_ptr()) {
if (byte_enable && use_byte_enable_on_read) {
if (byte_enable_length == 8 && data_length % 8 == 0) {
// Optimized implementation copies 64-bit words by masking
for (unsigned int i = 0; i < data_length; i += 8) {
typedef sc_dt::uint64* u;
*reinterpret_cast<u>(&data[i]) &= ~*reinterpret_cast<u>(byte_enable);
*reinterpret_cast<u>(&data[i]) |= *reinterpret_cast<u>(&other.get_data_ptr()[i])
& *reinterpret_cast<u>(byte_enable);
}
} else if (byte_enable_length == 4 && data_length % 4 == 0) {
// Optimized implementation copies 32-bit words by masking
for (unsigned int i = 0; i < data_length; i += 4) {
typedef unsigned int* u;
*reinterpret_cast<u>(&data[i]) &= ~*reinterpret_cast<u>(byte_enable);
*reinterpret_cast<u>(&data[i]) |= *reinterpret_cast<u>(&other.get_data_ptr()[i])
& *reinterpret_cast<u>(byte_enable);
}
} else
// Unoptimized implementation
for (unsigned int i = 0; i < data_length; i++)
if (byte_enable[i % byte_enable_length])
data[i] = other.get_data_ptr()[i];
} else
memcpy(data, other.get_data_ptr(), data_length);
}
}
/*
void update_extensions_from(const tlm::tlm_generic_payload & other) {
// deep copy extensions that are already present
for (unsigned int i = 0; i < tlm::max_num_extensions(); i++) {
if (other.get_extension(i)) { //original has extension i
if (m_extensions[i]) { //We have it too. copy.
m_extensions[i]->copy_from(*other.get_extension(i));
}
}
}
}
*/
// Free all extensions. Useful when reusing a cloned transaction that doesn't have memory manager.
// normal and sticky extensions are freed and extension array cleared.
void free_all_extensions() {
m_extensions.free_entire_cache();
for (unsigned int i = 0; i < m_extensions.size(); i++) {
if (m_extensions[i]) {
m_extensions[i]->free();
m_extensions[i] = 0;
}
}
}
//--------------
// Destructor
//--------------
virtual ~tlm_gp_data() {
for(unsigned int i=0; i<m_extensions.size(); i++)
if(m_extensions[i]) m_extensions[i]->free();
}
//----------------
// API (including setters & getters)
//---------------
// Command related method
bool is_read() const {
return (command == tlm::TLM_READ_COMMAND);
}
void set_read() {
command = tlm::TLM_READ_COMMAND;
}
bool is_write() const {
return (command == tlm::TLM_WRITE_COMMAND);
}
void set_write() {
command = tlm::TLM_WRITE_COMMAND;
}
tlm::tlm_command get_command() const {
return command;
}
void set_command(const tlm::tlm_command command) {
this->command = command;
}
// Address related methods
sc_dt::uint64 get_address() const {
return address;
}
void set_address(const sc_dt::uint64 address) {
this->address = address;
}
// Data related methods
unsigned char* get_data_ptr() const {
return data;
}
void set_data_ptr(unsigned char* data) {
this->data = data;
}
// Transaction length (in bytes) related methods
unsigned int get_data_length() const {
return data_length;
}
void set_data_length(const unsigned int length) {
data_length = length;
}
// Response status related methods
bool is_response_ok() const {
return (response_status > 0);
}
bool is_response_error() const {
return (response_status <= 0);
}
tlm::tlm_response_status get_response_status() const {
return response_status;
}
void set_response_status(const tlm::tlm_response_status response_status) {
this->response_status = response_status;
}
std::string get_response_string() const {
switch (response_status) {
case tlm::TLM_OK_RESPONSE:
return "TLM_OK_RESPONSE";
case tlm::TLM_INCOMPLETE_RESPONSE:
return "TLM_INCOMPLETE_RESPONSE";
case tlm::TLM_GENERIC_ERROR_RESPONSE:
return "TLM_GENERIC_ERROR_RESPONSE";
case tlm::TLM_ADDRESS_ERROR_RESPONSE:
return "TLM_ADDRESS_ERROR_RESPONSE";
case tlm::TLM_COMMAND_ERROR_RESPONSE:
return "TLM_COMMAND_ERROR_RESPONSE";
case tlm::TLM_BURST_ERROR_RESPONSE:
return "TLM_BURST_ERROR_RESPONSE";
case tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE:
return "TLM_BYTE_ENABLE_ERROR_RESPONSE";
}
return "TLM_UNKNOWN_RESPONSE";
}
// Streaming related methods
unsigned int get_streaming_width() const {
return streaming_width;
}
void set_streaming_width(const unsigned int streaming_width) {
this->streaming_width = streaming_width;
}
// Byte enable related methods
unsigned char* get_byte_enable_ptr() const {
return byte_enable;
}
void set_byte_enable_ptr(unsigned char* byte_enable) {
this->byte_enable = byte_enable;
}
unsigned int get_byte_enable_length() const {
return byte_enable_length;
}
void set_byte_enable_length(const unsigned int byte_enable_length) {
this->byte_enable_length = byte_enable_length;
}
// This is the "DMI-hint" a slave can set this to true if it
// wants to indicate that a DMI request would be supported:
void set_dmi_allowed(bool dmi_allowed) {
dmi = dmi_allowed;
}
bool is_dmi_allowed() const {
return dmi;
}
// Use full set of attributes in DMI/debug?
tlm::tlm_gp_option get_gp_option() const {
return gp_option;
}
void set_gp_option(const tlm::tlm_gp_option gp_opt) {
gp_option = gp_opt;
}
public:
/* --------------------------------------------------------------------- */
/* Generic Payload attributes: */
/* --------------------------------------------------------------------- */
/* - m_command : Type of transaction. Three values supported: */
/* - TLM_WRITE_COMMAND */
/* - TLM_READ_COMMAND */
/* - TLM_IGNORE_COMMAND */
/* - m_address : Transaction base address (byte-addressing). */
/* - m_data : When m_command = TLM_WRITE_COMMAND contains a */
/* pointer to the data to be written in the target.*/
/* When m_command = TLM_READ_COMMAND contains a */
/* pointer where to copy the data read from the */
/* target. */
/* - m_length : Total number of bytes of the transaction. */
/* - m_response_status : This attribute indicates whether an error has */
/* occurred during the transaction. */
/* Values supported are: */
/* - TLM_OK_RESP */
/* - TLM_INCOMPLETE_RESP */
/* - TLM_GENERIC_ERROR_RESP */
/* - TLM_ADDRESS_ERROR_RESP */
/* - TLM_COMMAND_ERROR_RESP */
/* - TLM_BURST_ERROR_RESP */
/* - TLM_BYTE_ENABLE_ERROR_RESP */
/* */
/* - m_byte_enable : It can be used to create burst transfers where */
/* the address increment between each beat is greater */
/* than the word length of each beat, or to place */
/* words in selected byte lanes of a bus. */
/* - m_byte_enable_length : For a read or a write command, the target */
/* interpret the byte enable length attribute as the */
/* number of elements in the bytes enable array. */
/* - m_streaming_width : */
/* --------------------------------------------------------------------- */
sc_dt::uint64 address;
tlm::tlm_command command;
unsigned char* data;
unsigned int data_length;
tlm::tlm_response_status response_status;
bool dmi;
unsigned char* byte_enable;
unsigned int byte_enable_length;
unsigned int streaming_width;
tlm::tlm_gp_option gp_option;
public:
/* --------------------------------------------------------------------- */
/* Dynamic extension mechanism: */
/* --------------------------------------------------------------------- */
/* The extension mechanism is intended to enable initiator modules to */
/* optionally and transparently add data fields to the */
/* tlm_generic_payload. Target modules are free to check for extensions */
/* and may or may not react to the data in the extension fields. The */
/* definition of the extensions' semantics is solely in the */
/* responsibility of the user. */
/* */
/* The following rules apply: */
/* */
/* - Every extension class must be derived from tlm_extension, e.g.: */
/* class my_extension : public tlm_extension<my_extension> { ... } */
/* */
/* - A tlm_generic_payload object should be constructed after C++ */
/* static initialization time. This way it is guaranteed that the */
/* extension array is of sufficient size to hold all possible */
/* extensions. Alternatively, the initiator module can enforce a valid */
/* extension array size by calling the resize_extensions() method */
/* once before the first transaction with the payload object is */
/* initiated. */
/* */
/* - Initiators should use the the set_extension(e) or clear_extension(e)*/
/* methods for manipulating the extension array. The type of the */
/* argument must be a pointer to the specific registered extension */
/* type (my_extension in the above example) and is used to */
/* automatically locate the appropriate index in the array. */
/* */
/* - Targets can check for a specific extension by calling */
/* get_extension(e). e will point to zero if the extension is not */
/* present. */
/* */
/* --------------------------------------------------------------------- */
// Stick the pointer to an extension into the vector, return the
// previous value:
template<typename T> T* set_extension(T* ext) {
return static_cast<T*>(set_extension(T::ID, ext));
}
// non-templatized version with manual index:
tlm::tlm_extension_base* set_extension(unsigned int index, tlm::tlm_extension_base* ext) {
tlm::tlm_extension_base* tmp = m_extensions[index];
m_extensions[index] = ext;
return tmp;
}
// Check for an extension, ext will point to 0 if not present
template<typename T> void get_extension(T*& ext) const {
ext = get_extension<T>();
}
template<typename T> T* get_extension() const {
return static_cast<T*>(get_extension(T::ID));
}
// Non-templatized version with manual index:
tlm::tlm_extension_base* get_extension(unsigned int index) const {
return m_extensions[index];
}
//this call just removes the extension from the txn but does not
// call free() or tells the MM to do so
// it return false if there was active MM so you are now in an unsafe situation
// recommended use: when 100% sure there is no MM
template<typename T> void clear_extension(const T* ext) {
clear_extension<T>();
}
//this call just removes the extension from the txn but does not
// call free() or tells the MM to do so
// it return false if there was active MM so you are now in an unsafe situation
// recommended use: when 100% sure there is no MM
template<typename T> void clear_extension() {
clear_extension(T::ID);
}
//this call removes the extension from the txn and does
// call free() or tells the MM to do so when the txn is finally done
// recommended use: when not sure there is no MM
template<typename T> void release_extension(T* ext) {
release_extension<T>();
}
//this call removes the extension from the txn and does
// call free() or tells the MM to do so when the txn is finally done
// recommended use: when not sure there is no MM
template<typename T> void release_extension() {
release_extension(T::ID);
}
private:
// Non-templatized version with manual index
void clear_extension(unsigned int index) {
m_extensions[index] = static_cast<tlm::tlm_extension_base*>(0);
}
// Non-templatized version with manual index
void release_extension(unsigned int index) {
m_extensions[index]->free();
m_extensions[index] = static_cast<tlm::tlm_extension_base*>(0);
}
public:
// Make sure the extension array is large enough. Can be called once by
// an initiator module (before issuing the first transaction) to make
// sure that the extension array is of correct size. This is only needed
// if the initiator cannot guarantee that the generic payload object is
// allocated after C++ static construction time.
void resize_extensions() {
m_extensions.expand(tlm::max_num_extensions());
}
private:
tlm::tlm_array<tlm::tlm_extension_base*> m_extensions;
unsigned int m_ref_count;
};
struct tlm_dmi_data {
tlm_dmi_data()
:dmi_ptr(0)
,dmi_start_address(0)
,dmi_end_address(0)
,dmi_access(tlm::tlm_dmi::DMI_ACCESS_NONE)
,dmi_read_latency(0)
,dmi_write_latency(0)
{}
tlm_dmi_data(tlm::tlm_dmi& dmi_data)
:dmi_ptr(dmi_data.get_dmi_ptr())
,dmi_start_address(dmi_data.get_start_address())
,dmi_end_address(dmi_data.get_end_address())
,dmi_access(dmi_data.get_granted_access())
,dmi_read_latency(dmi_data.get_read_latency().value())
,dmi_write_latency(dmi_data.get_write_latency().value())
{}
//--------------
// Destructor
//--------------
virtual ~tlm_dmi_data() {}
unsigned char* dmi_ptr;
sc_dt::uint64 dmi_start_address;
sc_dt::uint64 dmi_end_address;
tlm::tlm_dmi::dmi_access_e dmi_access;
sc_dt::uint64 dmi_read_latency;
sc_dt::uint64 dmi_write_latency;
};
}
#endif /* TLM_GP_DATA_H_ */

View File

@ -1,131 +0,0 @@
/*
* tlm_gp_data_ext.h
*
* Created on: 07.11.2015
* Author: eyck
*/
#ifndef TLM_GP_DATA_EXT_H_
#define TLM_GP_DATA_EXT_H_
#include "scv.h"
#include "tlm_gp_data.h"
template<>
class scv_extensions<tlm::tlm_command> : public scv_enum_base<tlm::tlm_command> {
public:
SCV_ENUM_CTOR(tlm::tlm_command) {
SCV_ENUM(tlm::TLM_READ_COMMAND);
SCV_ENUM(tlm::TLM_WRITE_COMMAND);
SCV_ENUM(tlm::TLM_IGNORE_COMMAND);
}
};
template<>
class scv_extensions<tlm::tlm_response_status> : public scv_enum_base<tlm::tlm_response_status> {
public:
SCV_ENUM_CTOR(tlm::tlm_response_status) {
SCV_ENUM(tlm::TLM_OK_RESPONSE);
SCV_ENUM(tlm::TLM_INCOMPLETE_RESPONSE);
SCV_ENUM(tlm::TLM_GENERIC_ERROR_RESPONSE);
SCV_ENUM(tlm::TLM_ADDRESS_ERROR_RESPONSE);
SCV_ENUM(tlm::TLM_COMMAND_ERROR_RESPONSE);
SCV_ENUM(tlm::TLM_BURST_ERROR_RESPONSE);
SCV_ENUM(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE);
}
};
template<>
class scv_extensions<tlm::tlm_gp_option> : public scv_enum_base<tlm::tlm_gp_option> {
public:
SCV_ENUM_CTOR(tlm::tlm_gp_option) {
SCV_ENUM(tlm::TLM_MIN_PAYLOAD);
SCV_ENUM(tlm::TLM_FULL_PAYLOAD);
SCV_ENUM(tlm::TLM_FULL_PAYLOAD_ACCEPTED);
}
};
template<>
class scv_extensions<tlm::tlm_phase_enum> : public scv_enum_base<tlm::tlm_phase_enum> {
public:
SCV_ENUM_CTOR(tlm::tlm_phase_enum) {
SCV_ENUM(tlm::UNINITIALIZED_PHASE);
SCV_ENUM(tlm::BEGIN_REQ);
SCV_ENUM(tlm::END_REQ);
SCV_ENUM(tlm::BEGIN_RESP);
SCV_ENUM(tlm::END_RESP);
}
};
template<>
class scv_extensions<tlm::tlm_sync_enum> : public scv_enum_base<tlm::tlm_sync_enum> {
public:
SCV_ENUM_CTOR(tlm::tlm_sync_enum) {
SCV_ENUM(tlm::TLM_ACCEPTED);
SCV_ENUM(tlm::TLM_UPDATED);
SCV_ENUM(tlm::TLM_COMPLETED);
}
};
template<>
class scv_extensions<scv4tlm::tlm_gp_data> : public scv_extensions_base<scv4tlm::tlm_gp_data> {
public:
scv_extensions<sc_dt::uint64> address;
scv_extensions<tlm::tlm_command> command;
scv_extensions<unsigned char*> data;
scv_extensions<unsigned int> data_length;
scv_extensions<tlm::tlm_response_status> response_status;
scv_extensions<bool> dmi;
scv_extensions<unsigned char*> byte_enable;
scv_extensions<unsigned int> byte_enable_length;
scv_extensions<unsigned int> streaming_width;
scv_extensions<tlm::tlm_gp_option> gp_option;
SCV_EXTENSIONS_CTOR(scv4tlm::tlm_gp_data) {
//must be in order
SCV_FIELD(address);
SCV_FIELD(command);
SCV_FIELD(data);
SCV_FIELD(data_length);
SCV_FIELD(response_status);
SCV_FIELD(dmi);
SCV_FIELD(byte_enable);
SCV_FIELD(byte_enable_length);
SCV_FIELD(streaming_width);
SCV_FIELD(gp_option);
}
};
template<>
class scv_extensions<tlm::tlm_dmi::dmi_access_e> : public scv_enum_base<tlm::tlm_dmi::dmi_access_e> {
public:
SCV_ENUM_CTOR(tlm::tlm_dmi::dmi_access_e) {
SCV_ENUM(tlm::tlm_dmi::DMI_ACCESS_NONE);
SCV_ENUM(tlm::tlm_dmi::DMI_ACCESS_READ);
SCV_ENUM(tlm::tlm_dmi::DMI_ACCESS_WRITE);
SCV_ENUM(tlm::tlm_dmi::DMI_ACCESS_READ_WRITE);
}
};
template<>
class scv_extensions<scv4tlm::tlm_dmi_data> : public scv_extensions_base<scv4tlm::tlm_dmi_data> {
public:
scv_extensions<unsigned char*> dmi_ptr;
scv_extensions<sc_dt::uint64> dmi_start_address;
scv_extensions<sc_dt::uint64> dmi_end_address;
scv_extensions<tlm::tlm_dmi::dmi_access_e> dmi_access;
scv_extensions<sc_dt::uint64> dmi_read_latency;
scv_extensions<sc_dt::uint64> dmi_write_latency;
SCV_EXTENSIONS_CTOR(scv4tlm::tlm_dmi_data) {
//must be in order
SCV_FIELD(dmi_ptr);
SCV_FIELD(dmi_start_address);
SCV_FIELD(dmi_end_address);
SCV_FIELD(dmi_access);
SCV_FIELD(dmi_read_latency);
SCV_FIELD(dmi_write_latency);
}
};
#endif /* TLM_GP_DATA_EXT_H_ */

View File

@ -1,125 +0,0 @@
/*
* tlm_rec_target_socket.h
*
* Created on: 08.11.2015
* Author: eyck
*/
#ifndef TLM_REC_INITIATOR_SOCKET_H_
#define TLM_REC_INITIATOR_SOCKET_H_
#include <tlm_core/tlm_2/tlm_sockets/tlm_initiator_socket.h>
#include "tlm2_recorder.h"
namespace scv4tlm {
template<unsigned int BUSWIDTH = 32, typename TYPES = tlm::tlm_base_protocol_types, int N = 1
#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
, sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND
#endif
>
class tlm_rec_initiator_socket: public tlm::tlm_initiator_socket<BUSWIDTH
, TYPES
, N
#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
, POL
#endif
> {
static std::string gen_name(const char* first, const char* second){
std::stringstream ss;
ss<<first<<"_"<<second;
return ss.str();
}
public:
typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
typedef sc_core::sc_port<fw_interface_type, N
#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
, POL
#endif
> port_type;
typedef sc_core::sc_export<bw_interface_type> export_type;
typedef tlm::tlm_base_target_socket_b<BUSWIDTH,
fw_interface_type,
bw_interface_type> base_target_socket_type;
typedef tlm::tlm_base_initiator_socket_b<BUSWIDTH,
fw_interface_type,
bw_interface_type> base_type;
tlm_rec_initiator_socket() :
tlm::tlm_initiator_socket<BUSWIDTH
, TYPES
, N
#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
, POL
#endif
>()
,recorder()
{
}
explicit tlm_rec_initiator_socket(const char* name) :
tlm::tlm_initiator_socket<BUSWIDTH
, TYPES
, N
#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
, POL
#endif
>(name)
,recorder(gen_name(name, "rec").c_str())
{
}
virtual ~tlm_rec_initiator_socket(){}
virtual const char* kind() const {
return "tlm_rec_target_socket";
}
//
// Bind initiator socket to target socket
// - Binds the port of the initiator socket to the export of the target
// socket
// - Binds the port of the target socket to the export of the initiator
// socket
//
virtual void bind(base_target_socket_type& s) {
// initiator.port -> target.export
(this->get_base_port())(recorder);
recorder.fw_port(s.get_base_interface());
// target.port -> initiator.export
(s.get_base_port())(recorder);
recorder.bw_port(this->get_base_interface());
}
//
// Bind initiator socket to initiator socket (hierarchical bind)
// - Binds both the export and the port
//
virtual void bind(base_type& s){
// port
(this->get_base_port())(recorder);
recorder.fw_port(s.get_base_port());
// export
(s.get_base_export())(recorder);
recorder.bw_port(this->get_base_export());
}
//
// Bind interface to socket
// - Binds the interface to the export of this socket
//
virtual void bind(bw_interface_type& ifs) {
(this->get_base_export())(ifs);
}
void setExtensionRecording(tlm_extensions_recording_if<TYPES>* extensionRecording){
recorder.setExtensionRecording(extensionRecording);
}
protected:
scv4tlm::tlm2_recorder<TYPES> recorder;
};
}
// namespace scv4tlm
#endif /* TLM_REC_TARGET_SOCKET_H_ */

View File

@ -1,119 +0,0 @@
/*
* tlm_rec_target_socket.h
*
* Created on: 08.11.2015
* Author: eyck
*/
#ifndef TLM_REC_TARGET_SOCKET_H_
#define TLM_REC_TARGET_SOCKET_H_
#include <tlm_core/tlm_2/tlm_sockets/tlm_target_socket.h>
#include "tlm2_recorder.h"
namespace scv4tlm {
template<unsigned int BUSWIDTH = 32, typename TYPES = tlm::tlm_base_protocol_types, int N = 1
#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
, sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND
#endif
>
class tlm_rec_target_socket: public tlm::tlm_target_socket<BUSWIDTH
, TYPES
, N
#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
, POL
#endif
> {
static std::string gen_name(const char* first, const char* second){
std::stringstream ss;
ss<<first<<"_"<<second;
return ss.str();
}
public:
typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
typedef sc_core::sc_port<bw_interface_type, N
#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
, POL
#endif
> port_type;
typedef sc_core::sc_export<fw_interface_type> export_type;
typedef tlm::tlm_base_initiator_socket_b<BUSWIDTH, fw_interface_type, bw_interface_type> base_initiator_socket_type;
typedef tlm::tlm_base_target_socket_b<BUSWIDTH, fw_interface_type, bw_interface_type> base_type;
tlm_rec_target_socket() :
tlm::tlm_target_socket<BUSWIDTH
, TYPES
, N
#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
, POL
#endif
>()
,recorder()
{
}
explicit tlm_rec_target_socket(const char* name) :
tlm::tlm_target_socket<BUSWIDTH
, TYPES
, N
#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
, POL
#endif
>(name)
,recorder(gen_name(name, "rec").c_str())
{
}
virtual ~tlm_rec_target_socket(){}
virtual const char* kind() const {
return "tlm_rec_target_socket";
}
//
// Bind target socket to target socket (hierarchical bind)
// - Binds both the export and the port
//
virtual void bind(base_type& s) {
// export
(this->get_base_export())(s.get_base_export()); // will be handled by bind(fw_interface_type& ifs)
// port
(s.get_base_port())(recorder); // bind the recording interface to the port, recording will use the m_port
}
//
// Bind interface to socket
// - Binds the interface to the export
//
virtual void bind(fw_interface_type& ifs){
export_type* exp = &this->get_base_export();
if( this == exp ) {
export_type::bind(recorder); // non-virtual function call
recorder.fw_port(ifs);
recorder.bw_port(this->get_base_port());
} else {
exp->bind( ifs );
}
}
//
// Forward to 'operator->()' of port class
//
bw_interface_type* operator->() {
return &recorder;
}
scv4tlm::tlm2_recorder<TYPES>& get_recorder(){
return recorder;
}
protected:
scv4tlm::tlm2_recorder<TYPES> recorder;
};
}
// namespace scv4tlm
#endif /* TLM_REC_TARGET_SOCKET_H_ */

View File

@ -1,77 +0,0 @@
/*
* tlm2_tx_record_extension.h
*
* Created on: 07.11.2015
* Author: eyck
*/
#ifndef TLM_RECORDING_EXTENSION_H_
#define TLM_RECORDING_EXTENSION_H_
#include <scv.h>
namespace scv4tlm {
//! transaction relationships
enum tx_rel {
PARENT_CHILD = 0, /*!< indicates parent child relationship */
PREDECESSOR_SUCCESSOR /*!< indicates predecessor successor relationship */
};
//! the string representation of the tx_rel
static char const* tx_rel_str[] = { "PARENT/CHILD", "PRED/SUCC" };
/*! \brief cast the tx_rel enum to a string
*
* \param tc_rel is the relationship enum
*/
inline const char* rel_str(tx_rel rel) {
return (tx_rel_str[rel]);
}
/*! \brief generic payload extension class holding the handle of the last recorded SCV transaction
*
* This extension is been used in the \ref scv_tlm2_recorder. The recorder stores the handle to the generated SCV transaction and
* forwrds it along with the generic payload. If the recorder finds an extension containing a valid handle it links the generated
* SCV transdaction to the found one using the \ref PREDECESSOR releationship
*/
struct tlm_recording_extension: public tlm::tlm_extension<tlm_recording_extension> {
/*! \brief clone the given extension and duplicate the SCV transaction handle.
*
*/
virtual tlm_extension_base* clone() const {
tlm_recording_extension* t = new tlm_recording_extension(this->txHandle, this->creator);
return t;
}
/*! \brief copy data between extensions.
*
* \param from is the source extension.
*/
virtual void copy_from(tlm_extension_base const& from) {
txHandle = static_cast<tlm_recording_extension const &>(from).txHandle;
creator = static_cast<tlm_recording_extension const &>(from).creator;
}
/*! \brief constructor storing the handle of the transaction and the owner of this extension
*
* \param handle is the handle of the created SCV transaction.
* \param creator_ is the pointer to the owner of this extension (usually an instance of scv_tlm2_recorder).
*/
tlm_recording_extension(scv_tr_handle handle, void* creator_) :
txHandle(handle), creator(creator_) {
}
/*! \brief accessor to the owner, the property is read only.
*
*/
void* get_creator() {
return creator;
}
/*! \brief accessor to the SCV transaction handle.
*
*/
scv_tr_handle txHandle;
private:
//! the owner of this transaction
void* creator;
};
}
#endif /* TLM_RECORDING_EXTENSION_H_ */

View File

@ -1,383 +0,0 @@
// -*- C++ -*- <this line is for emacs to recognize it as C++ code>
/*****************************************************************************
The following code is derived, directly or indirectly, from the SystemC
source code Copyright (c) 1996-2014 by all Contributors.
All Rights reserved.
The contents of this file are subject to the restrictions and limitations
set forth in the SystemC Open Source License (the "License");
You may not use this file except in compliance with such restrictions and
limitations. You may obtain instructions on how to receive a copy of the
License at http://www.accellera.org/. Software distributed by Contributors
under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
ANY KIND, either express or implied. See the License for the specific
language governing rights and limitations under the License.
*****************************************************************************/
#include "scv.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") {
}
virtual void trace( sc_trace_file* tf ) const;
};
void pipelined_bus_ports::trace( sc_trace_file* tf ) const {
sc_trace(tf, clk, clk.name());
sc_trace(tf, rw, rw.name());
sc_trace(tf, addr_req, addr_req.name());
sc_trace(tf, addr_ack, addr_ack.name());
sc_trace(tf, bus_addr, bus_addr.name());
sc_trace(tf, data_rdy, data_rdy.name());
sc_trace(tf, bus_data, bus_data.name());
}
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<_scv_tr_generator_default_data, sc_uint<8> > rdata_gen;
scv_tr_generator<sc_uint<8> > wdata_gen;
public:
rw_pipelined_transactor(sc_module_name nm)
: pipelined_bus_ports(nm)
, addr_phase("addr_phase")
, data_phase("data_phase")
, pipelined_stream((std::string(name()) +".pipelined_stream").c_str(), "transactor")
, addr_stream( (std::string(name()) +".addr_stream").c_str(), "transactor")
, data_stream((std::string(name()) +".data_stream").c_str(), "transactor")
, read_gen("read", pipelined_stream, "addr", "data")
, write_gen("write", pipelined_stream, "addr", "data")
, addr_gen("addr", addr_stream, "addr")
, rdata_gen("rdata", data_stream, NULL, "data")
, wdata_gen("wdata", data_stream, "data")
{
}
virtual data_t read(const addr_t* p_addr);
virtual void write(const write_t * req);
};
rw_task_if::data_t rw_pipelined_transactor::read(const addr_t* addr) {
addr_phase.lock();
scv_tr_handle h = read_gen.begin_transaction(*addr);
h.record_attribute("data_size", sizeof(data_t));
scv_tr_handle h1 = addr_gen.begin_transaction(*addr, "addr_phase", h);
wait(clk->posedge_event());
bus_addr = *addr;
rw=false;
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 = rdata_gen.begin_transaction("data_phase", h);
wait(data_rdy->posedge_event());
data_t data = bus_data.read();
wait(data_rdy->negedge_event());
rdata_gen.end_transaction(h2, data);
read_gen.end_transaction(h, data);
data_phase.unlock();
return data;
}
void rw_pipelined_transactor::write(const write_t * req) {
addr_phase.lock();
scv_tr_handle h = write_gen.begin_transaction(req->addr);
h.record_attribute("data_size", sizeof(data_t));
scv_tr_handle h1 = addr_gen.begin_transaction(req->addr, "addr_phase", h);
wait(clk->posedge_event());
bus_addr = req->addr;
rw=true;
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 = wdata_gen.begin_transaction(req->data, "data_phase", h);
bus_data=req->data;
wait(data_rdy->posedge_event());
wait(data_rdy->negedge_event());
wdata_gen.end_transaction(h2);
write_gen.end_transaction(h, req->data);
data_phase.unlock();
}
class test: public sc_module {
public:
sc_port<rw_task_if> transactor;
SC_HAS_PROCESS(test);
test( ::sc_core::sc_module_name ){
SC_THREAD(main1);
SC_THREAD(main2);
}
void main1();
void main2();
};
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) {
}
inline void test::main1() {
// 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);
}
}
inline void test::main2() {
// 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, 140);
distribution.push(2, 160);
data->set_mode(distribution);
for (int i = 0; i < 3; i++) {
data->next();
process(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();
};
inline 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;
}
}
inline 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() == false) {
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 << "writing memory address " << outstandingAddresses.front() << " with value "
<< bus_data << endl;
memory[outstandingAddresses.front().to_ulong()]=bus_data;
data_rdy = 1;
wait(clk->posedge_event());
data_rdy = 0;
}
outstandingAddresses.pop_front();
outstandingType.pop_front();
}
}
extern void scv_tr_sqlite_init();
int sc_main(int argc, char *argv[]) {
scv_startup();
#if 0
scv_tr_text_init();
const char* fileName = "my_db.txlog";
#else
scv_tr_sqlite_init();
const char* fileName = "my_db";
#endif
scv_tr_db db(fileName);
scv_tr_db::set_default_db(&db);
sc_trace_file* tf = sc_create_vcd_trace_file("my_db");
// create signals
sc_clock clk("clk", 20.0, SC_NS, 0.5, 0.0, SC_NS, true);
sc_signal<bool> rw;
sc_signal<bool> addr_req;
sc_signal<bool> addr_ack;
sc_signal<sc_uint<8> > bus_addr;
sc_signal<bool> data_rdy;
sc_signal<sc_uint<8> > bus_data;
// create modules/channels
test t("t");
rw_pipelined_transactor tr("tr");
design duv("duv");
// 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);
tr.trace(tf);
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);
duv.trace(tf);
// 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);
sc_close_vcd_trace_file(tf);
return 0;
}

View File

@ -1,379 +0,0 @@
/*******************************************************************************
* Copyright (c) 2014, 2015 MINRES Technologies GmbH and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* MINRES Technologies GmbH - initial API and implementation
*******************************************************************************/
#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
#include "scv/scv_util.h"
#include "scv/scv_introspection.h"
#include "scv/scv_tr.h"
#include "sqlite3.h"
// ----------------------------------------------------------------------------
#define SQLITEWRAPPER_ERROR 1000
// ----------------------------------------------------------------------------
using namespace std;
struct SQLiteDB {
struct SQLiteException : public runtime_error{
SQLiteException(const int nErrCode, const char* msg, bool doFree=true)
: runtime_error(msg), mnErrCode(0){
if (doFree && msg) sqlite3_free(const_cast<char*>(msg));
}
const int errorCode() { return mnErrCode; }
const char* errorMessage() { return what(); }
private:
int mnErrCode;
};
SQLiteDB():busyTimeoutMs(60000), db(NULL){}
void open(const string szFile){
int nRet = sqlite3_open(szFile.c_str(), &db);
if (nRet != SQLITE_OK) throw SQLiteException(nRet, sqlite3_errmsg(db), false);
sqlite3_busy_timeout(db, busyTimeoutMs);
}
inline
bool isOpen(){return db!=NULL;}
void close(){
if (db){
if (sqlite3_close(db) == SQLITE_OK)
db = 0;
else
throw SQLiteException(SQLITEWRAPPER_ERROR, "Unable to close database", false);
}
}
inline
int exec(const string szSQL){return exec(szSQL.c_str());};
int exec(const char* szSQL){
checkDB();
char* szError=0;
int nRet = sqlite3_exec(db, szSQL, 0, 0, &szError);
if (nRet == SQLITE_OK)
return sqlite3_changes(db);
else
throw SQLiteException(nRet, szError);
}
protected:
inline void checkDB(){
if (!db) throw SQLiteException(SQLITEWRAPPER_ERROR, "Database not open", false);
}
private:
int busyTimeoutMs;
sqlite3* db;
};
// ----------------------------------------------------------------------------
static SQLiteDB db;
static ostringstream stringBuilder, queryBuilder;
static vector<vector<uint64_t>*> concurrencyLevel;
// ----------------------------------------------------------------------------
enum EventType {BEGIN, RECORD, END};
typedef scv_extensions_if::data_type data_type;
// ----------------------------------------------------------------------------
#define SIM_PROPS "ScvSimProps"
#define STREAM_TABLE "ScvStream"
#define GENERATOR_TABLE "ScvGenerator"
#define TX_TABLE "ScvTx"
#define TX_EVENT_TABLE "ScvTxEvent"
#define TX_ATTRIBUTE_TABLE "ScvTxAttribute"
#define TX_RELATION_TABLE "ScvTxRelation"
static void dbCb(const scv_tr_db& _scv_tr_db, scv_tr_db::callback_reason reason, void* data) {
// This is called from the scv_tr_db ctor.
static string fName("DEFAULT_scv_tr_sqlite");
switch (reason) {
case scv_tr_db::CREATE:
if ((_scv_tr_db.get_name() != NULL) && (strlen(_scv_tr_db.get_name()) != 0))
fName = _scv_tr_db.get_name();
try {
if(fName.size()<5 || fName.find(".txdb", fName.size() - 5) == string::npos)
fName+=".txdb";
remove(fName.c_str());
db.open(fName.c_str());
// performance related according to http://blog.quibb.org/2010/08/fast-bulk-inserts-into-sqlite/
db.exec("PRAGMA synchronous=OFF");
db.exec("PRAGMA count_changes=OFF");
db.exec("PRAGMA journal_mode=MEMORY");
db.exec("PRAGMA temp_store=MEMORY");
// scv_out << "TB Transaction Recording has started, file = " << my_sqlite_file_name << endl;
db.exec("CREATE TABLE IF NOT EXISTS " STREAM_TABLE "(id INTEGER NOT NULL PRIMARY KEY, name TEXT, kind TEXT);");
db.exec("CREATE TABLE IF NOT EXISTS " GENERATOR_TABLE "(id INTEGER NOT NULL PRIMARY KEY, stream INTEGER REFERENCES " STREAM_TABLE "(id), name TEXT, begin_attr INTEGER, end_attr INTEGER);");
db.exec("CREATE TABLE IF NOT EXISTS " TX_TABLE "(id INTEGER NOT NULL PRIMARY KEY, generator INTEGER REFERENCES " GENERATOR_TABLE "(id), stream INTEGER REFERENCES " STREAM_TABLE "(id), concurrencyLevel INTEGER);");
db.exec("CREATE TABLE IF NOT EXISTS " TX_EVENT_TABLE "(tx INTEGER REFERENCES " TX_TABLE "(id), type INTEGER, time INTEGER);");
db.exec("CREATE TABLE IF NOT EXISTS " TX_ATTRIBUTE_TABLE "(tx INTEGER REFERENCES " TX_TABLE "(id), type INTEGER, name TEXT, data_type INTEGER, data_value TEXT);");
db.exec("CREATE TABLE IF NOT EXISTS " TX_RELATION_TABLE "(name TEXT, src INTEGER REFERENCES " TX_TABLE "(id), sink INTEGER REFERENCES " TX_TABLE "(id));");
db.exec("CREATE TABLE IF NOT EXISTS " SIM_PROPS "(time_resolution INTEGER);");
db.exec("BEGIN TRANSACTION");
queryBuilder.str("");
queryBuilder << "INSERT INTO " SIM_PROPS " (time_resolution) values ("
<< (long)(sc_get_time_resolution().to_seconds()*1e15) << ");";
db.exec(queryBuilder.str().c_str());
} catch (SQLiteDB::SQLiteException& e) {
_scv_message::message(_scv_message::TRANSACTION_RECORDING_INTERNAL, "Can't open recording file");
}
break;
case scv_tr_db::DELETE:
try {
// scv_out << "Transaction Recording is closing file: " << my_sqlite_file_name << endl;
db.exec("COMMIT TRANSACTION");
db.close();
} catch (SQLiteDB::SQLiteException& e) {
_scv_message::message(_scv_message::TRANSACTION_RECORDING_INTERNAL, "Can't close recording file");
}
break;
default:
_scv_message::message(_scv_message::TRANSACTION_RECORDING_INTERNAL, "Unknown reason in scv_tr_db callback");
}
}
// ----------------------------------------------------------------------------
static void streamCb(const scv_tr_stream& s, scv_tr_stream::callback_reason reason, void* data) {
if (reason == scv_tr_stream::CREATE && db.isOpen()) {
try {
queryBuilder.str("");
queryBuilder << "INSERT INTO " STREAM_TABLE " (id, name, kind) values (" << s.get_id() << ",'" << s.get_name() << "','"
<< (s.get_stream_kind() ? s.get_stream_kind() : "<unnamed>") << "');";
db.exec(queryBuilder.str().c_str());
if(concurrencyLevel.size()<=s.get_id())concurrencyLevel.resize(s.get_id()+1);
concurrencyLevel[s.get_id()]=new vector<uint64_t>();
} catch (SQLiteDB::SQLiteException& e) {
_scv_message::message(_scv_message::TRANSACTION_RECORDING_INTERNAL, "Can't create stream");
}
}
}
// ----------------------------------------------------------------------------
void recordAttribute(uint64_t id, EventType event, const string& name, data_type type, const string& value) {
try {
queryBuilder.str("");
queryBuilder << "INSERT INTO " TX_ATTRIBUTE_TABLE " (tx,type,name,data_type,data_value)" << " values ("
<< id << "," << event << ",'"<< name << "'," << type << ",'" << value << "');";
db.exec(queryBuilder.str().c_str());
} catch (SQLiteDB::SQLiteException& e) {
_scv_message::message(_scv_message::TRANSACTION_RECORDING_INTERNAL, "Can't create attribute entry");
}
}
// ----------------------------------------------------------------------------
inline
void recordAttribute(uint64_t id, EventType event, const string& name, data_type type, long long value) {
stringBuilder.str("");
stringBuilder <<value;
recordAttribute(id,event,name,type,stringBuilder.str());
}
// ----------------------------------------------------------------------------
inline
void recordAttribute(uint64_t id, EventType event, const string& name, data_type type, double value) {
stringBuilder.str("");
stringBuilder <<value;
recordAttribute(id,event,name,type,stringBuilder.str());
}
// ----------------------------------------------------------------------------
static void recordAttributes(uint64_t id, EventType eventType, string& prefix, const scv_extensions_if* my_exts_p){
if (my_exts_p == 0) return;
string name;
if (prefix == "") {
name = my_exts_p->get_name();
} else {
if ((my_exts_p->get_name() == 0) || (strlen(my_exts_p->get_name()) == 0)) {
name = prefix;
} else {
name = prefix + "." + my_exts_p->get_name();
}
}
if (name == "") name = "<unnamed>";
switch (my_exts_p->get_type()) {
case scv_extensions_if::RECORD:
{
int num_fields = my_exts_p->get_num_fields();
if (num_fields > 0) {
for (int field_counter = 0; field_counter < num_fields; field_counter++) {
const scv_extensions_if* field_data_p = my_exts_p->get_field(field_counter);
recordAttributes(id, eventType, prefix, field_data_p);
}
}
}
break;
case scv_extensions_if::ENUMERATION:
recordAttribute(id, eventType, name, scv_extensions_if::ENUMERATION, my_exts_p->get_enum_string((int) (my_exts_p->get_integer())));
break;
case scv_extensions_if::BOOLEAN:
recordAttribute(id, eventType, name, scv_extensions_if::BOOLEAN, my_exts_p->get_bool()?"TRUE":"FALSE");
break;
case scv_extensions_if::INTEGER:
case scv_extensions_if::FIXED_POINT_INTEGER:
recordAttribute(id, eventType, name, scv_extensions_if::INTEGER, my_exts_p->get_integer());
break;
case scv_extensions_if::UNSIGNED:
recordAttribute(id, eventType, name, scv_extensions_if::UNSIGNED, my_exts_p->get_integer());
break;
case scv_extensions_if::POINTER:
recordAttribute(id, eventType, name, scv_extensions_if::POINTER, (long long)my_exts_p->get_pointer());
break;
case scv_extensions_if::STRING:
recordAttribute(id, eventType, name, scv_extensions_if::STRING, my_exts_p->get_string());
break;
case scv_extensions_if::FLOATING_POINT_NUMBER:
recordAttribute(id, eventType, name, scv_extensions_if::FLOATING_POINT_NUMBER, my_exts_p->get_double());
break;
case scv_extensions_if::BIT_VECTOR:
{
sc_bv_base tmp_bv(my_exts_p->get_bitwidth());
my_exts_p->get_value(tmp_bv);
recordAttribute(id, eventType, name, scv_extensions_if::BIT_VECTOR, tmp_bv.to_string());
}
break;
case scv_extensions_if::LOGIC_VECTOR:
{
sc_lv_base tmp_lv(my_exts_p->get_bitwidth());
my_exts_p->get_value(tmp_lv);
recordAttribute(id, eventType, name, scv_extensions_if::LOGIC_VECTOR, tmp_lv.to_string());
}
break;
case scv_extensions_if::ARRAY:
for (int array_elt_index = 0; array_elt_index < my_exts_p->get_array_size(); array_elt_index++) {
const scv_extensions_if* field_data_p = my_exts_p->get_array_elt(array_elt_index);
recordAttributes(id, eventType, prefix, field_data_p);
}
break;
default: {
char tmpString[100];
sprintf(tmpString, "Unsupported attribute type = %d", my_exts_p->get_type());
_scv_message::message(_scv_message::TRANSACTION_RECORDING_INTERNAL, tmpString);
}
}
}
// ----------------------------------------------------------------------------
static void generatorCb(const scv_tr_generator_base& g, scv_tr_generator_base::callback_reason reason, void* data) {
if (reason == scv_tr_generator_base::CREATE && db.isOpen()) {
try {
queryBuilder.str("");
queryBuilder << "INSERT INTO " GENERATOR_TABLE " (id,stream, name)"
<<" values (" << g.get_id() << ","<<g.get_scv_tr_stream().get_id()<<",'" << g.get_name() << "');";
db.exec(queryBuilder.str().c_str());
} catch (SQLiteDB::SQLiteException& e) {
_scv_message::message(_scv_message::TRANSACTION_RECORDING_INTERNAL, "Can't create generator entry");
}
}
}
// ----------------------------------------------------------------------------
static void transactionCb(const scv_tr_handle& t, scv_tr_handle::callback_reason reason, void* data) {
if (!db.isOpen()) return;
if (t.get_scv_tr_stream().get_scv_tr_db() == NULL) return;
if (t.get_scv_tr_stream().get_scv_tr_db()->get_recording() == false) return;
uint64_t id = t.get_id();
uint64_t streamId = t.get_scv_tr_stream().get_id();
vector<uint64_t>::size_type concurrencyIdx;
const scv_extensions_if* my_exts_p;
switch (reason) {
case scv_tr_handle::BEGIN:{
try {
if(concurrencyLevel.size()<=streamId)
concurrencyLevel.resize(streamId+1);
vector<uint64_t>* levels=concurrencyLevel[streamId];
if(levels==NULL){
levels=new vector<uint64_t>();
concurrencyLevel[id]=levels;
}
for(concurrencyIdx=0; concurrencyIdx<levels->size(); ++concurrencyIdx)
if((*levels)[concurrencyIdx]==0) break;
if(concurrencyIdx==levels->size())
levels->push_back(id);
else
(*levels)[concurrencyIdx]=id;
queryBuilder.str("");
queryBuilder << "INSERT INTO " TX_TABLE " (id,generator,stream, concurrencyLevel)" << " values (" << id << "," << t.get_scv_tr_generator_base().get_id()
<<","<<t.get_scv_tr_stream().get_id()<< ","<< concurrencyIdx <<");";
db.exec(queryBuilder.str().c_str());
queryBuilder.str("");
queryBuilder << "INSERT INTO " TX_EVENT_TABLE " (tx,type,time)" << " values (" << id << "," << BEGIN << ","
<< t.get_begin_sc_time().value() << ");";
db.exec(queryBuilder.str().c_str());
} catch (SQLiteDB::SQLiteException& e) {
_scv_message::message(_scv_message::TRANSACTION_RECORDING_INTERNAL, e.errorMessage());
}
my_exts_p = t.get_begin_exts_p();
if (my_exts_p == NULL) {
my_exts_p = t.get_scv_tr_generator_base().get_begin_exts_p();
}
string tmp_str =
t.get_scv_tr_generator_base().get_begin_attribute_name() ? t.get_scv_tr_generator_base().get_begin_attribute_name() : "";
recordAttributes(id, BEGIN, tmp_str, my_exts_p);
} break;
case scv_tr_handle::END:{
try {
vector<uint64_t>* levels=concurrencyLevel[streamId];
for(concurrencyIdx=0; concurrencyIdx<levels->size(); ++concurrencyIdx)
if((*levels)[concurrencyIdx]==id) break;
if(concurrencyIdx==levels->size())
levels->push_back(id);
else
levels->at(concurrencyIdx)=id;
queryBuilder.str("");
queryBuilder << "INSERT INTO " TX_EVENT_TABLE " (tx,type,time)" << " values (" << t.get_id() << "," << END << ","
<< t.get_end_sc_time().value() << ");";
db.exec(queryBuilder.str().c_str());
} catch (SQLiteDB::SQLiteException& e) {
_scv_message::message(_scv_message::TRANSACTION_RECORDING_INTERNAL, "Can't create transaction end");
}
my_exts_p = t.get_end_exts_p();
if (my_exts_p == NULL) {
my_exts_p = t.get_scv_tr_generator_base().get_end_exts_p();
}
string tmp_str =
t.get_scv_tr_generator_base().get_end_attribute_name() ? t.get_scv_tr_generator_base().get_end_attribute_name() : "";
recordAttributes(t.get_id(), END, tmp_str, my_exts_p);
} break;
default:
;
}
}
// ----------------------------------------------------------------------------
static void attributeCb(const scv_tr_handle& t, const char* name, const scv_extensions_if* ext, void* data) {
if (!db.isOpen()) return;
if (t.get_scv_tr_stream().get_scv_tr_db() == NULL) return;
if (t.get_scv_tr_stream().get_scv_tr_db()->get_recording() == false) return;
string tmp_str(name == 0?"":name);
recordAttributes(t.get_id(), RECORD, tmp_str, ext);
}
// ----------------------------------------------------------------------------
static void relationCb(const scv_tr_handle& tr_1, const scv_tr_handle& tr_2, void* data,
scv_tr_relation_handle_t relation_handle) {
if (!db.isOpen()) return;
if (tr_1.get_scv_tr_stream().get_scv_tr_db() == NULL) return;
if (tr_1.get_scv_tr_stream().get_scv_tr_db()->get_recording() == false) return;
try {
queryBuilder.str("");
queryBuilder << "INSERT INTO " TX_RELATION_TABLE " (name,sink,src)"
<< "values ('" << tr_1.get_scv_tr_stream().get_scv_tr_db()->get_relation_name(relation_handle) << "',"
<< tr_1.get_id() << ","<< tr_2.get_id() << ");";
db.exec(queryBuilder.str().c_str());
} catch (SQLiteDB::SQLiteException& e) {
_scv_message::message(_scv_message::TRANSACTION_RECORDING_INTERNAL, "Can't create transaction relation");
}
}
// ----------------------------------------------------------------------------
void scv_tr_sqlite_init() {
scv_tr_db::register_class_cb(dbCb);
scv_tr_stream::register_class_cb(streamCb);
scv_tr_generator_base::register_class_cb(generatorCb);
scv_tr_handle::register_class_cb(transactionCb);
scv_tr_handle::register_record_attribute_cb(attributeCb);
scv_tr_handle::register_relation_cb(relationCb);
}
// ----------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff