systemc: Initial import of TLM headers from Accellera.

These headers will need to be cleaned up and have some Accellera
specific quirks ironed out of them, but I'll do that in a later change
to make it clear what those changes are.

Change-Id: Ia4e08633ab552b4c616c66c9b7e2bbd78ebfe7b9
Reviewed-on: https://gem5-review.googlesource.com/c/15055
Reviewed-by: Anthony Gutierrez <anthony.gutierrez@amd.com>
Maintainer: Anthony Gutierrez <anthony.gutierrez@amd.com>
This commit is contained in:
Gabe Black
2018-12-08 01:58:26 -08:00
parent 3e1e21da61
commit 7364acfc75
63 changed files with 11667 additions and 0 deletions

33
src/systemc/ext/tlm Normal file
View File

@@ -0,0 +1,33 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_HEADER__
#define __TLM_HEADER__
#include <systemc> // main SystemC header
#include "tlm_core/tlm_2/tlm_version.h"
#include "tlm_core/tlm_1/tlm_analysis/tlm_analysis.h"
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_req_rsp.h"
#include "tlm_core/tlm_2/tlm_2_interfaces/tlm_2_interfaces.h"
#include "tlm_core/tlm_2/tlm_generic_payload/tlm_generic_payload.h"
#include "tlm_core/tlm_2/tlm_sockets/tlm_sockets.h"
#include "tlm_core/tlm_2/tlm_quantum/tlm_quantum.h"
#endif /* TLM_HEADER_INCLUDED_ */

22
src/systemc/ext/tlm.h Normal file
View File

@@ -0,0 +1,22 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
// kept for backwards compatibility
#include "tlm"

View File

@@ -0,0 +1,97 @@
## ****************************************************************************
##
## Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
## more contributor license agreements. See the NOTICE file distributed
## with this work for additional information regarding copyright ownership.
## Accellera licenses this file to you under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with the
## License. You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
## implied. See the License for the specific language governing
## permissions and limitations under the License.
##
## ****************************************************************************
##
## src/tlm_core/Makefile.am --
## Process this file with automake to produce a Makefile.in file.
##
## Original Author: Philipp A. Hartmann, OFFIS, 2013-05-17
##
## ****************************************************************************
##
## MODIFICATION LOG - modifiers, enter your name, affiliation, date and
## changes you are making here.
##
## Name, Affiliation, Date:
## Description of Modification:
##
## ****************************************************************************
include $(top_srcdir)/config/Make-rules.sysc
H_FILES = \
tlm_2/tlm_version.h \
tlm_2/tlm_2_interfaces/tlm_2_interfaces.h \
tlm_2/tlm_2_interfaces/tlm_dmi.h \
tlm_2/tlm_2_interfaces/tlm_fw_bw_ifs.h \
\
tlm_2/tlm_generic_payload/tlm_array.h \
tlm_2/tlm_generic_payload/tlm_endian_conv.h \
tlm_2/tlm_generic_payload/tlm_generic_payload.h \
tlm_2/tlm_generic_payload/tlm_gp.h \
tlm_2/tlm_generic_payload/tlm_helpers.h \
tlm_2/tlm_generic_payload/tlm_phase.h \
\
tlm_2/tlm_quantum/tlm_global_quantum.h \
tlm_2/tlm_quantum/tlm_quantum.h \
\
tlm_2/tlm_sockets/tlm_base_socket_if.h \
tlm_2/tlm_sockets/tlm_initiator_socket.h \
tlm_2/tlm_sockets/tlm_sockets.h \
tlm_2/tlm_sockets/tlm_target_socket.h \
\
tlm_1/tlm_analysis/tlm_analysis.h \
tlm_1/tlm_analysis/tlm_analysis_fifo.h \
tlm_1/tlm_analysis/tlm_analysis_if.h \
tlm_1/tlm_analysis/tlm_analysis_port.h \
tlm_1/tlm_analysis/tlm_analysis_triple.h \
tlm_1/tlm_analysis/tlm_write_if.h \
\
tlm_1/tlm_req_rsp/tlm_req_rsp.h \
tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h \
tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_fifo_ifs.h \
tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_master_slave_ifs.h \
tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_tag.h \
\
tlm_1/tlm_req_rsp/tlm_adapters/tlm_adapters.h \
\
tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/circular_buffer.h \
tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h \
tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_peek.h \
tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_put_get.h \
tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_resize.h \
tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_put_get_imp.h \
tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_req_rsp_channels.h \
\
tlm_1/tlm_req_rsp/tlm_ports/tlm_event_finder.h \
tlm_1/tlm_req_rsp/tlm_ports/tlm_nonblocking_port.h
CXX_FILES = \
tlm_2/tlm_generic_payload/tlm_gp.cpp \
tlm_2/tlm_generic_payload/tlm_phase.cpp \
tlm_2/tlm_quantum/tlm_global_quantum.cpp
EXTRA_DIST += \
tlm_1/README.txt \
tlm_2/README.txt
localincludedir = $(includedir)/tlm_core
nobase_localinclude_HEADERS = $(H_FILES)
noinst_LTLIBRARIES = libtlm_core.la
libtlm_core_la_SOURCES = $(NO_H_FILES) $(CXX_FILES)

View File

@@ -0,0 +1,799 @@
# Makefile.in generated by automake 1.14 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# top-level SystemC include directory is added in Make-rules.{sysc,examples}
# build flags
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
DIST_COMMON = $(top_srcdir)/config/Make-rules.sysc \
$(top_srcdir)/config/Make-rules.common $(srcdir)/Makefile.in \
$(srcdir)/Makefile.am $(top_srcdir)/config/depcomp \
$(nobase_localinclude_HEADERS)
@WANT_DEBUG_TRUE@am__append_1 = $(DEBUG_CXXFLAGS)
@WANT_DEBUG_TRUE@am__append_2 = $(DEBUG_CXXFLAGS)
@WANT_DEBUG_TRUE@am__append_3 = $(DEBUG_CXXFLAGS)
@WANT_OPTIMIZE_TRUE@am__append_4 = $(OPT_CXXFLAGS)
@WANT_OPTIMIZE_TRUE@am__append_5 = $(OPT_CXXFLAGS)
# either for async_update locking or pthread processes
@USES_PTHREADS_LIB_TRUE@am__append_6 = $(PTHREAD_CFLAGS)
@USES_PTHREADS_LIB_TRUE@am__append_7 = $(PTHREAD_CFLAGS)
@USES_PTHREADS_LIB_TRUE@am__append_8 = $(PTHREAD_LIBS)
@DISABLE_ASYNC_UPDATES_TRUE@am__append_9 = -DSC_DISABLE_ASYNC_UPDATES
@ENABLE_CALLBACKS_TRUE@am__append_10 = -DSC_ENABLE_SIMULATION_PHASE_CALLBACKS
@ENABLE_CALLBACKS_TRACING_TRUE@am__append_11 = -DSC_ENABLE_SIMULATION_PHASE_CALLBACKS_TRACING
@WANT_PTHREADS_THREADS_TRUE@am__append_12 = -DSC_USE_PTHREADS
@DISABLE_VCD_SCOPES_TRUE@am__append_13 = -DSC_DISABLE_VCD_SCOPES
subdir = src/tlm_core
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/config/ax_check_define.m4 \
$(top_srcdir)/config/ax_pthread.m4 \
$(top_srcdir)/config/libtool.m4 \
$(top_srcdir)/config/ltoptions.m4 \
$(top_srcdir)/config/ltsugar.m4 \
$(top_srcdir)/config/ltversion.m4 \
$(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libtlm_core_la_LIBADD =
am__dirstamp = $(am__leading_dot)dirstamp
am__objects_1 = tlm_2/tlm_generic_payload/tlm_gp.lo \
tlm_2/tlm_generic_payload/tlm_phase.lo \
tlm_2/tlm_quantum/tlm_global_quantum.lo
am_libtlm_core_la_OBJECTS = $(am__objects_1)
libtlm_core_la_OBJECTS = $(am_libtlm_core_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
AM_V_CXX = $(am__v_CXX_@AM_V@)
am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
am__v_CXX_0 = @echo " CXX " $@;
am__v_CXX_1 =
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
SOURCES = $(libtlm_core_la_SOURCES)
DIST_SOURCES = $(libtlm_core_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(localincludedir)"
HEADERS = $(nobase_localinclude_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCAS = @CCAS@
CCASDEPMODE = @CCASDEPMODE@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEBUG_CXXFLAGS = @DEBUG_CXXFLAGS@
DEFS = $(PKGCONFIG_DEFINES) $(EXTRA_DEFINES)
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
EXPLICIT_LPTHREAD = @EXPLICIT_LPTHREAD@
EXTRA_ASFLAGS = @EXTRA_ASFLAGS@
EXTRA_CFLAGS = @EXTRA_CFLAGS@
EXTRA_CXXFLAGS = @EXTRA_CXXFLAGS@
EXTRA_LDFLAGS = @EXTRA_LDFLAGS@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LDFLAG_RPATH = @LDFLAG_RPATH@
LIBCONFIG_DEFINES = @LIBCONFIG_DEFINES@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIB_ARCH_SUFFIX = @LIB_ARCH_SUFFIX@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPT_CXXFLAGS = @OPT_CXXFLAGS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKGCONFIG_CFLAGS = @PKGCONFIG_CFLAGS@
PKGCONFIG_DEFINES = @PKGCONFIG_DEFINES@
PKGCONFIG_LDPRIV = @PKGCONFIG_LDPRIV@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
QT_ARCH = @QT_ARCH@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TARGET_ARCH = @TARGET_ARCH@
TLM_PACKAGE_VERSION = @TLM_PACKAGE_VERSION@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
examplesdir = @examplesdir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libarchdir = @libarchdir@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
rootdocdir = @rootdocdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CPPFLAGS = -I$(top_srcdir)/src
AM_CFLAGS = $(EXTRA_CFLAGS) $(am__append_2) $(am__append_5) \
$(am__append_7)
AM_CXXFLAGS = $(EXTRA_CXXFLAGS) $(am__append_1) $(am__append_4) \
$(am__append_6)
AM_CCASFLAGS = $(EXTRA_ASFLAGS) $(am__append_3)
AM_LDFLAGS = $(EXTRA_LDFLAGS) $(am__append_8)
# always add fix-point support
EXTRA_DEFINES = -DSC_INCLUDE_FX -DSC_BUILD $(am__append_9) \
$(am__append_10) $(am__append_11) $(am__append_12) \
$(am__append_13)
# initialize some useful variables (filled later)
CLEANFILES =
EXTRA_DIST = tlm_1/README.txt tlm_2/README.txt
H_FILES = \
tlm_2/tlm_version.h \
tlm_2/tlm_2_interfaces/tlm_2_interfaces.h \
tlm_2/tlm_2_interfaces/tlm_dmi.h \
tlm_2/tlm_2_interfaces/tlm_fw_bw_ifs.h \
\
tlm_2/tlm_generic_payload/tlm_array.h \
tlm_2/tlm_generic_payload/tlm_endian_conv.h \
tlm_2/tlm_generic_payload/tlm_generic_payload.h \
tlm_2/tlm_generic_payload/tlm_gp.h \
tlm_2/tlm_generic_payload/tlm_helpers.h \
tlm_2/tlm_generic_payload/tlm_phase.h \
\
tlm_2/tlm_quantum/tlm_global_quantum.h \
tlm_2/tlm_quantum/tlm_quantum.h \
\
tlm_2/tlm_sockets/tlm_base_socket_if.h \
tlm_2/tlm_sockets/tlm_initiator_socket.h \
tlm_2/tlm_sockets/tlm_sockets.h \
tlm_2/tlm_sockets/tlm_target_socket.h \
\
tlm_1/tlm_analysis/tlm_analysis.h \
tlm_1/tlm_analysis/tlm_analysis_fifo.h \
tlm_1/tlm_analysis/tlm_analysis_if.h \
tlm_1/tlm_analysis/tlm_analysis_port.h \
tlm_1/tlm_analysis/tlm_analysis_triple.h \
tlm_1/tlm_analysis/tlm_write_if.h \
\
tlm_1/tlm_req_rsp/tlm_req_rsp.h \
tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h \
tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_fifo_ifs.h \
tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_master_slave_ifs.h \
tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_tag.h \
\
tlm_1/tlm_req_rsp/tlm_adapters/tlm_adapters.h \
\
tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/circular_buffer.h \
tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h \
tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_peek.h \
tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_put_get.h \
tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_resize.h \
tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_put_get_imp.h \
tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_req_rsp_channels.h \
\
tlm_1/tlm_req_rsp/tlm_ports/tlm_event_finder.h \
tlm_1/tlm_req_rsp/tlm_ports/tlm_nonblocking_port.h
CXX_FILES = \
tlm_2/tlm_generic_payload/tlm_gp.cpp \
tlm_2/tlm_generic_payload/tlm_phase.cpp \
tlm_2/tlm_quantum/tlm_global_quantum.cpp
localincludedir = $(includedir)/tlm_core
nobase_localinclude_HEADERS = $(H_FILES)
noinst_LTLIBRARIES = libtlm_core.la
libtlm_core_la_SOURCES = $(NO_H_FILES) $(CXX_FILES)
all: all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/config/Make-rules.sysc $(top_srcdir)/config/Make-rules.common $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/tlm_core/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/tlm_core/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_srcdir)/config/Make-rules.sysc $(top_srcdir)/config/Make-rules.common:
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
tlm_2/tlm_generic_payload/$(am__dirstamp):
@$(MKDIR_P) tlm_2/tlm_generic_payload
@: > tlm_2/tlm_generic_payload/$(am__dirstamp)
tlm_2/tlm_generic_payload/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) tlm_2/tlm_generic_payload/$(DEPDIR)
@: > tlm_2/tlm_generic_payload/$(DEPDIR)/$(am__dirstamp)
tlm_2/tlm_generic_payload/tlm_gp.lo: \
tlm_2/tlm_generic_payload/$(am__dirstamp) \
tlm_2/tlm_generic_payload/$(DEPDIR)/$(am__dirstamp)
tlm_2/tlm_generic_payload/tlm_phase.lo: \
tlm_2/tlm_generic_payload/$(am__dirstamp) \
tlm_2/tlm_generic_payload/$(DEPDIR)/$(am__dirstamp)
tlm_2/tlm_quantum/$(am__dirstamp):
@$(MKDIR_P) tlm_2/tlm_quantum
@: > tlm_2/tlm_quantum/$(am__dirstamp)
tlm_2/tlm_quantum/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) tlm_2/tlm_quantum/$(DEPDIR)
@: > tlm_2/tlm_quantum/$(DEPDIR)/$(am__dirstamp)
tlm_2/tlm_quantum/tlm_global_quantum.lo: \
tlm_2/tlm_quantum/$(am__dirstamp) \
tlm_2/tlm_quantum/$(DEPDIR)/$(am__dirstamp)
libtlm_core.la: $(libtlm_core_la_OBJECTS) $(libtlm_core_la_DEPENDENCIES) $(EXTRA_libtlm_core_la_DEPENDENCIES)
$(AM_V_CXXLD)$(CXXLINK) $(libtlm_core_la_OBJECTS) $(libtlm_core_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
-rm -f tlm_2/tlm_generic_payload/*.$(OBJEXT)
-rm -f tlm_2/tlm_generic_payload/*.lo
-rm -f tlm_2/tlm_quantum/*.$(OBJEXT)
-rm -f tlm_2/tlm_quantum/*.lo
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@tlm_2/tlm_generic_payload/$(DEPDIR)/tlm_gp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@tlm_2/tlm_generic_payload/$(DEPDIR)/tlm_phase.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@tlm_2/tlm_quantum/$(DEPDIR)/tlm_global_quantum.Plo@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
-rm -rf tlm_2/tlm_generic_payload/.libs tlm_2/tlm_generic_payload/_libs
-rm -rf tlm_2/tlm_quantum/.libs tlm_2/tlm_quantum/_libs
install-nobase_localincludeHEADERS: $(nobase_localinclude_HEADERS)
@$(NORMAL_INSTALL)
@list='$(nobase_localinclude_HEADERS)'; test -n "$(localincludedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(localincludedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(localincludedir)" || exit 1; \
fi; \
$(am__nobase_list) | while read dir files; do \
xfiles=; for file in $$files; do \
if test -f "$$file"; then xfiles="$$xfiles $$file"; \
else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
test -z "$$xfiles" || { \
test "x$$dir" = x. || { \
echo " $(MKDIR_P) '$(DESTDIR)$(localincludedir)/$$dir'"; \
$(MKDIR_P) "$(DESTDIR)$(localincludedir)/$$dir"; }; \
echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(localincludedir)/$$dir'"; \
$(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(localincludedir)/$$dir" || exit $$?; }; \
done
uninstall-nobase_localincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(nobase_localinclude_HEADERS)'; test -n "$(localincludedir)" || list=; \
$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
dir='$(DESTDIR)$(localincludedir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(localincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-rm -f tlm_2/tlm_generic_payload/$(DEPDIR)/$(am__dirstamp)
-rm -f tlm_2/tlm_generic_payload/$(am__dirstamp)
-rm -f tlm_2/tlm_quantum/$(DEPDIR)/$(am__dirstamp)
-rm -f tlm_2/tlm_quantum/$(am__dirstamp)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-am
-rm -rf tlm_2/tlm_generic_payload/$(DEPDIR) tlm_2/tlm_quantum/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-nobase_localincludeHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf tlm_2/tlm_generic_payload/$(DEPDIR) tlm_2/tlm_quantum/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-nobase_localincludeHEADERS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-nobase_localincludeHEADERS \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
uninstall-nobase_localincludeHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@@ -0,0 +1,97 @@
TLM-1.0 header files
====================
Dir: include/tlm_core/tlm_1/
SubDirs: tlm_analysis/
tlm_req_rsp/
Files: README.txt
Comments
========
User code should only #include the tlm or tlm.h header file in the include/
directory and avoid including any of the include files in this directory
directly. All objects defined in this file hierarchy are in the tlm namespace.
The header files are organizated, by subdirectory, as follows:
tlm_analysis/
--------------
This contains the analysis interfaces, ports, and fifos. These files were not
part of the original TLM-1.0 release, but have been grouped with TLM-1.0 in this
release of TLM-2.0
Files:
tlm_analysis.h (includes the other header files in this directory )
tlm_analysis_fifo.h (defines tlm_analysis_fifo )
tlm_analysis_if.h (defines tlm_analysis_if and tlm_delayed_analysis_if )
tlm_analysis_port.h (defines tlm_analysis_port )
tlm_analysis_triple.h (defines tlm_analysis_triple )
tlm_write_if.h (defines tlm_write_if and tlm_delayed_write_if )
tlm_req_rsp/
------------
This provides support for TLM modeling based on a request/response pair that
are passed by value. This is the original TLM 1.0 standard, with the addition
of an overloading of the blocking transport method with pass-by-reference arguments.
Files:
tlm_req_rsp.h (includes the key header files from the other directories)
tlm_1_interfaces/
tlm_core_ifs.h (defines the TLM 1.0 core interfaces:
tlm_transport_if
tlm_blocking_get_if
tlm_blocking_put_if
tlm_nonblocking_get_if
tlm_nonblocking_put_if
tlm_get_if
tlm_put_if
tlm_blocking_peek_if
tlm_nonblocking_peek_if
tlm_peek_if
tlm_blocking_get_peek_if
tlm_nonblocking_get_peek_if
tlm_get_peek_if )
tlm_fifo_ifs.h ( defines the TLM1.0 fifo interfaces:
tlm_fifo_debug_if
tlm_fifo_put_if
tlm_fifo_get_if
tlm_fifo_config_size_if )
tlm_master_slave_ifs.h ( defines the TLM1.0 master slave interfaces:
tlm_blocking_master_if
tlm_blocking_slave_if
tlm_nonblocking_master_if
tlm_nonblocking_slave_if
tlm_master_if
tlm_slave_if )
tlm_tag.h ( defines tlm_tag )
tlm_ports/
tlm_nonblocking_port.h (defines tlm_nonblocking_put_port,
tlm_nonblocking_get_port and
tlm_nonblocking_peek_port )
tlm_event_finder.h (defines tlm_event_finder_t )
tlm_channels/
tlm_fifo/
tlm_fifo.h (defines tlm_fifo, includes the other files )
tlm_fifo_peek.h (defines peek and poke interfaces for tlm_fifo )
tlm_fifo_put_get.h (defines put and get interfaces for tlm_fifo )
tlm_fifo_resize.h (defines expand, reduce, bound and unbound
interfaces for tlm_fifo )
circular_buffer.h (defines circular buffer used by tlm_fifo )
tlm_req_rsp_channels/
tlm_req_rsp_channels.h (defines tlm_req_rsp_channel and
tlm_transport_channel )
tlm_put_get_imp.h (contains implementatins used by the channels)
tlm_adapters/
tlm_adapters.h (defines transport_to_master and tlm_slave_to_transport)

View File

@@ -0,0 +1,33 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_ANALYSIS_H__
#define __TLM_ANALYSIS_H__
#include "tlm_core/tlm_1/tlm_analysis/tlm_write_if.h"
#include "tlm_core/tlm_1/tlm_analysis/tlm_analysis_if.h"
#include "tlm_core/tlm_1/tlm_analysis/tlm_analysis_triple.h"
#include "tlm_core/tlm_1/tlm_analysis/tlm_analysis_port.h"
#include "tlm_core/tlm_1/tlm_analysis/tlm_analysis_fifo.h"
#endif

View File

@@ -0,0 +1,54 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_ANALYSIS_FIFO_H__
#define __TLM_ANALYSIS_FIFO_H__
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h"
#include "tlm_core/tlm_1/tlm_analysis/tlm_analysis_if.h"
#include "tlm_core/tlm_1/tlm_analysis/tlm_analysis_triple.h"
namespace tlm {
template< typename T >
class tlm_analysis_fifo :
public tlm_fifo< T > ,
public virtual tlm_analysis_if< T > ,
public virtual tlm_analysis_if< tlm_analysis_triple< T > > {
public:
// analysis fifo is an unbounded tlm_fifo
tlm_analysis_fifo( const char *nm ) : tlm_fifo<T>( nm , -16 ) {}
tlm_analysis_fifo() : tlm_fifo<T>( -16 ) {}
void write( const tlm_analysis_triple<T> &t ) {
nb_put( t );
}
void write( const T &t ) {
nb_put( t );
}
};
} // namespace tlm
#endif

View File

@@ -0,0 +1,39 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_ANALYSIS_IF_H__
#define __TLM_ANALYSIS_IF_H__
#include "tlm_core/tlm_1/tlm_analysis/tlm_write_if.h"
namespace tlm {
template < typename T >
class tlm_analysis_if : public virtual tlm_write_if<T>
{
};
template < typename T >
class tlm_delayed_analysis_if : public virtual tlm_delayed_write_if<T>
{
};
} // namespace tlm
#endif

View File

@@ -0,0 +1,84 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_ANALYSIS_PORT_H__
#define __TLM_ANALYSIS_PORT_H__
#include "tlm_core/tlm_1/tlm_analysis/tlm_analysis_if.h"
#include <deque>
#include <algorithm>
namespace tlm {
template < typename T>
class tlm_analysis_port :
public sc_core::sc_object ,
public virtual tlm_analysis_if< T >
{
public:
tlm_analysis_port() : sc_core::sc_object() {}
tlm_analysis_port( const char *nm ) : sc_core::sc_object( nm ) {}
// bind and () work for both interfaces and analysis ports, since
// analysis ports implement the analysis interface
virtual void bind( tlm_analysis_if<T> &_if ) {
m_interfaces.push_back( &_if );
}
void operator() ( tlm_analysis_if<T> &_if ) { bind( _if ); }
virtual bool unbind( tlm_analysis_if<T> &_if ) {
typename std::deque< tlm_analysis_if<T> * >::iterator i
= std::remove( m_interfaces.begin(), m_interfaces.end(), &_if );
if( i != m_interfaces.end() ) {
m_interfaces.erase(i, m_interfaces.end() );
return 1;
}
return 0;
}
void write( const T &t ) {
typename std::deque< tlm_analysis_if<T> * >::iterator i;
for( i = m_interfaces.begin();
i != m_interfaces.end();
i++ ) {
(*i)->write( t );
}
}
private:
std::deque< tlm_analysis_if<T> * > m_interfaces;
};
} // namespace tlm
#endif

View File

@@ -0,0 +1,53 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_ANALYSIS_TRIPLE_H__
#define __TLM_ANALYSIS_TRIPLE_H__
//#include <systemc>
namespace tlm {
template< typename T>
struct tlm_analysis_triple {
sc_core::sc_time start_time;
T transaction;
sc_core::sc_time end_time;
tlm_analysis_triple() {}
tlm_analysis_triple( const tlm_analysis_triple &triple ) {
start_time = triple.start_time;
transaction = triple.transaction;
end_time = triple.end_time;
}
tlm_analysis_triple( const T &t ) {
transaction = t;
}
operator T() { return transaction; }
operator const T &() const { return transaction; }
};
} // namespace tlm
#endif

View File

@@ -0,0 +1,42 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_WRITE_IF_H__
#define __TLM_WRITE_IF_H__
#include <systemc>
namespace tlm {
template <typename T>
class tlm_write_if : public virtual sc_core::sc_interface {
public:
virtual void write(const T& t) = 0;
};
template <typename T>
class tlm_delayed_write_if : public virtual sc_core::sc_interface {
public:
virtual void write(const T& t, const sc_core::sc_time& time) = 0;
};
} // namespace tlm
#endif

View File

@@ -0,0 +1,149 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
//
// Note to the LRM writer : This is the core of the TLM standard
//
#ifndef __TLM_CORE_IFS_H__
#define __TLM_CORE_IFS_H__
//#include <systemc>
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_tag.h"
namespace tlm {
// bidirectional blocking interfaces
template < typename REQ , typename RSP >
class tlm_transport_if : public virtual sc_core::sc_interface
{
public:
virtual RSP transport( const REQ & ) = 0;
virtual void transport( const REQ &req , RSP &rsp ) {
rsp = transport( req );
}
};
// uni-directional blocking interfaces
template < typename T >
class tlm_blocking_get_if : public virtual sc_core::sc_interface
{
public:
virtual T get( tlm_tag<T> *t = 0 ) = 0;
virtual void get( T &t ) { t = get(); }
};
template < typename T >
class tlm_blocking_put_if : public virtual sc_core::sc_interface
{
public:
virtual void put( const T &t ) = 0;
};
// uni-directional non blocking interfaces
template < typename T >
class tlm_nonblocking_get_if : public virtual sc_core::sc_interface
{
public:
virtual bool nb_get( T &t ) = 0;
virtual bool nb_can_get( tlm_tag<T> *t = 0 ) const = 0;
virtual const sc_core::sc_event &ok_to_get( tlm_tag<T> *t = 0 ) const = 0;
};
template < typename T >
class tlm_nonblocking_put_if : public virtual sc_core::sc_interface
{
public:
virtual bool nb_put( const T &t ) = 0;
virtual bool nb_can_put( tlm_tag<T> *t = 0 ) const = 0;
virtual const sc_core::sc_event &ok_to_put( tlm_tag<T> *t = 0 ) const = 0;
};
// combined uni-directional blocking and non blocking
template < typename T >
class tlm_get_if :
public virtual tlm_blocking_get_if< T > ,
public virtual tlm_nonblocking_get_if< T > {};
template < typename T >
class tlm_put_if :
public virtual tlm_blocking_put_if< T > ,
public virtual tlm_nonblocking_put_if< T > {};
// peek interfaces
template < typename T >
class tlm_blocking_peek_if : public virtual sc_core::sc_interface
{
public:
virtual T peek( tlm_tag<T> *t = 0 ) const = 0;
virtual void peek( T &t ) const { t = peek(); }
};
template < typename T >
class tlm_nonblocking_peek_if : public virtual sc_core::sc_interface
{
public:
virtual bool nb_peek( T &t ) const = 0;
virtual bool nb_can_peek( tlm_tag<T> *t = 0 ) const = 0;
virtual const sc_core::sc_event &ok_to_peek( tlm_tag<T> *t = 0 ) const = 0;
};
template < typename T >
class tlm_peek_if :
public virtual tlm_blocking_peek_if< T > ,
public virtual tlm_nonblocking_peek_if< T > {};
// get_peek interfaces
template < typename T >
class tlm_blocking_get_peek_if :
public virtual tlm_blocking_get_if<T> ,
public virtual tlm_blocking_peek_if<T> {};
template < typename T >
class tlm_nonblocking_get_peek_if :
public virtual tlm_nonblocking_get_if<T> ,
public virtual tlm_nonblocking_peek_if<T> {};
template < typename T >
class tlm_get_peek_if :
public virtual tlm_get_if<T> ,
public virtual tlm_peek_if<T> ,
public virtual tlm_blocking_get_peek_if<T> ,
public virtual tlm_nonblocking_get_peek_if<T>
{};
} // namespace tlm
#endif

View File

@@ -0,0 +1,85 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
//
// Note to the LRM writer : These interfaces are channel specific interfaces
// useful in the context of tlm_fifo.
//
#ifndef __TLM_FIFO_IFS_H__
#define __TLM_FIFO_IFS_H__
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h"
namespace tlm {
//
// Fifo specific interfaces
//
// Fifo Debug Interface
template< typename T >
class tlm_fifo_debug_if : public virtual sc_core::sc_interface
{
public:
virtual int used() const = 0;
virtual int size() const = 0;
virtual void debug() const = 0;
//
// non blocking peek and poke - no notification
//
// n is index of data :
// 0 <= n < size(), where 0 is most recently written, and size() - 1
// is oldest ie the one about to be read.
//
virtual bool nb_peek( T & , int n ) const = 0;
virtual bool nb_poke( const T & , int n = 0 ) = 0;
};
// fifo interfaces = extended + debug
template < typename T >
class tlm_fifo_put_if :
public virtual tlm_put_if<T> ,
public virtual tlm_fifo_debug_if<T> {};
template < typename T >
class tlm_fifo_get_if :
public virtual tlm_get_peek_if<T> ,
public virtual tlm_fifo_debug_if<T> {};
class tlm_fifo_config_size_if : public virtual sc_core::sc_interface
{
public:
virtual void nb_expand( unsigned int n = 1 ) = 0;
virtual void nb_unbound( unsigned int n = 16 ) = 0;
virtual bool nb_reduce( unsigned int n = 1 ) = 0;
virtual bool nb_bound( unsigned int n ) = 0;
};
} // namespace tlm
#endif

View File

@@ -0,0 +1,73 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_MASTER_SLAVE_IFS_H__
#define __TLM_MASTER_SLAVE_IFS_H__
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h"
namespace tlm {
//
// req/rsp combined interfaces
//
// blocking
template < typename REQ , typename RSP>
class tlm_blocking_master_if :
public virtual tlm_blocking_put_if< REQ > ,
public virtual tlm_blocking_get_peek_if< RSP > {};
template < typename REQ , typename RSP>
class tlm_blocking_slave_if :
public virtual tlm_blocking_put_if< RSP > ,
public virtual tlm_blocking_get_peek_if< REQ > {};
// nonblocking
template < typename REQ , typename RSP >
class tlm_nonblocking_master_if :
public virtual tlm_nonblocking_put_if< REQ > ,
public virtual tlm_nonblocking_get_peek_if< RSP > {};
template < typename REQ , typename RSP >
class tlm_nonblocking_slave_if :
public virtual tlm_nonblocking_put_if< RSP > ,
public virtual tlm_nonblocking_get_peek_if< REQ > {};
// combined
template < typename REQ , typename RSP >
class tlm_master_if :
public virtual tlm_put_if< REQ > ,
public virtual tlm_get_peek_if< RSP > ,
public virtual tlm_blocking_master_if< REQ , RSP > ,
public virtual tlm_nonblocking_master_if< REQ , RSP > {};
template < typename REQ , typename RSP >
class tlm_slave_if :
public virtual tlm_put_if< RSP > ,
public virtual tlm_get_peek_if< REQ > ,
public virtual tlm_blocking_slave_if< REQ , RSP > ,
public virtual tlm_nonblocking_slave_if< REQ , RSP > {};
} // namespace tlm
#endif

View File

@@ -0,0 +1,31 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
//
// Note to the LRM writer : This is part of the core TLM standard
//
#ifndef __TLM_TAG_H__
#define __TLM_TAG_H__
namespace tlm {
template<class T> class tlm_tag {};
}
#endif

View File

@@ -0,0 +1,105 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_ADAPTERS_H__
#define __TLM_ADAPTERS_H__
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_master_slave_ifs.h"
namespace tlm {
template< typename REQ , typename RSP >
class tlm_transport_to_master :
public sc_core::sc_module ,
public virtual tlm_transport_if< REQ , RSP >
{
public:
sc_core::sc_export< tlm_transport_if< REQ , RSP > > target_export;
sc_core::sc_port< tlm_master_if< REQ , RSP > > master_port;
tlm_transport_to_master( sc_core::sc_module_name nm ) :
sc_core::sc_module( nm ) {
target_export( *this );
}
tlm_transport_to_master() :
sc_core::sc_module( sc_core::sc_module_name( sc_core::sc_gen_unique_name( "transport_to_master" ) ) ){
target_export( *this );
}
RSP transport( const REQ &req ) {
mutex.lock();
master_port->put( req );
rsp = master_port->get();
mutex.unlock();
return rsp;
}
private:
sc_core::sc_mutex mutex;
RSP rsp;
};
template< typename REQ , typename RSP >
class tlm_slave_to_transport : public sc_core::sc_module
{
public:
SC_HAS_PROCESS( tlm_slave_to_transport );
sc_core::sc_port< tlm_slave_if< REQ , RSP > > slave_port;
sc_core::sc_port< tlm_transport_if< REQ , RSP > > initiator_port;
tlm_slave_to_transport( sc_core::sc_module_name nm ) : sc_core::sc_module( nm )
{}
tlm_slave_to_transport() :
sc_core::sc_module( sc_core::sc_module_name( sc_core::sc_gen_unique_name("slave_to_transport") ) )
{}
private:
void run() {
REQ req;
RSP rsp;
while( true ) {
slave_port->get( req );
rsp = initiator_port->transport( req );
slave_port->put( rsp );
}
}
};
} // namespace tlm
#endif

View File

@@ -0,0 +1,268 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
//
// To the LRM writer : this class is purely an artifact of the implementation.
//
#ifndef __CIRCULAR_BUFFER_H__
#define __CIRCULAR_BUFFER_H__
#include <iostream>
namespace tlm {
template < typename T >
class circular_buffer
{
public:
explicit
circular_buffer( int size = 0 );
~circular_buffer();
void resize( int size );
void clear();
T read();
void write( const T & );
bool is_empty() const { return used() == 0; }
bool is_full() const { return free() == 0; }
int size() const { return m_size; }
int used() const { return m_used; }
int free() const { return m_free; }
const T& read_data() const
{ return buf_read( m_buf, m_ri ); }
const T& peek_data( int i ) const
{ return buf_read( m_buf, (m_ri + i) % size() ); }
T & poke_data( int i )
{ return buf_read( m_buf , (m_wi + i) % size() ); }
void debug() const;
private:
void increment_write_pos( int i = 1 );
void increment_read_pos( int i = 1 );
void init();
circular_buffer( const circular_buffer<T> &b ); // disabled
circular_buffer<T> &operator=( const circular_buffer<T> & ); // disabled
void* buf_alloc( int size );
void buf_free( void*& buf );
void buf_write( void* buf, int n, const T & t );
T& buf_read( void* buf, int n ) const;
void buf_clear( void* buf, int n );
private:
int m_size; // size of the buffer
void* m_buf; // the buffer
int m_free; // number of free spaces
int m_used; // number of used spaces
int m_ri; // index of next read
int m_wi; // index of next write
};
template< typename T >
void
circular_buffer<T>::debug() const
{
std::cout << "Buffer debug" << std::endl;
std::cout << "Size : " << size() << std::endl;
std::cout << "Free/Used " << free() << "/" << used() << std::endl;
std::cout << "Indices : r/w = " << m_ri << "/" << m_wi << std::endl;
if( is_empty() ) {
std::cout << "empty" << std::endl;
}
if( is_full() ) {
std::cout << "full" << std::endl;
}
std::cout << "Data : " << std::endl;
for( int i = 0; i < used(); i++ ) {
std::cout << peek_data( i ) << std::endl;
}
}
template < typename T >
circular_buffer<T>::circular_buffer( int size )
: m_size(size)
, m_buf(0)
{
init();
}
template < typename T >
void
circular_buffer<T>::clear()
{
for( int i=0; i < used(); i++ ) {
buf_clear( m_buf, (m_ri + i) % m_size );
}
m_free = m_size;
m_used = m_ri = m_wi = 0;
}
template < typename T >
circular_buffer<T>::~circular_buffer()
{
clear();
buf_free( m_buf );
}
template < typename T >
void
circular_buffer<T>::resize( int size )
{
int i;
void * new_buf = buf_alloc(size);
for( i = 0; i < size && i < used(); i++ ) {
buf_write( new_buf, i, peek_data( i ) );
buf_clear( m_buf, (m_ri + i) % m_size );
}
buf_free( m_buf );
m_size = size;
m_ri = 0;
m_wi = i % m_size;
m_used = i;
m_free = m_size - m_used;
m_buf = new_buf;
}
template < typename T >
void
circular_buffer<T>::init() {
if( m_size > 0 ) {
m_buf = buf_alloc( m_size );
}
m_free = m_size;
m_used = 0;
m_ri = 0;
m_wi = 0;
}
template < typename T >
T
circular_buffer<T>::read()
{
T t = read_data();
buf_clear( m_buf, m_ri );
increment_read_pos();
return t;
}
template < typename T >
void
circular_buffer<T>::write( const T &t )
{
buf_write( m_buf, m_wi, t );
increment_write_pos();
}
template < typename T >
void
circular_buffer<T>::increment_write_pos( int i ) {
m_wi = ( m_wi + i ) % m_size;
m_used += i;
m_free -= i;
}
template < typename T >
void
circular_buffer<T>::increment_read_pos( int i ) {
m_ri = ( m_ri + i ) % m_size;
m_used -= i;
m_free += i;
}
template < typename T >
inline void*
circular_buffer<T>::buf_alloc( int size )
{ return new unsigned char[ size * sizeof(T) ]; }
template < typename T >
inline void
circular_buffer<T>::buf_free( void* & buf )
{ delete [] static_cast<unsigned char*>(buf); buf = 0; }
template < typename T >
inline void
circular_buffer<T>::buf_write( void* buf, int n, const T & t )
{
T* p = static_cast<T*>(buf) + n;
new (p) T(t);
}
template < typename T >
inline T&
circular_buffer<T>::buf_read( void* buf, int n ) const
{
T* p = static_cast<T*>(buf) + n;
return *p;
}
template < typename T >
inline void
circular_buffer<T>::buf_clear( void* buf, int n )
{
T* p = static_cast<T*>(buf) + n;
p->~T();
}
} // namespace tlm
#endif

View File

@@ -0,0 +1,263 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_FIFO_H__
#define __TLM_FIFO_H__
//
// This implements put, get and peek
//
// It also implements 0 and infinite size fifos - but the size
// zero fifos aren't rendezvous like zero length fifos, they simply are both
// full and empty at the same time.
//
// The size can be dynamically changed using the resize interface
//
// To get an infinite fifo use a -ve size in the constructor.
// The absolute value of the size is taken as the starting size of the
// actual physical buffer.
//
//#include <systemc>
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_fifo_ifs.h"
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/circular_buffer.h"
namespace tlm {
template <typename T>
class tlm_fifo :
public virtual tlm_fifo_get_if<T>,
public virtual tlm_fifo_put_if<T>,
public sc_core::sc_prim_channel
{
public:
// constructors
explicit tlm_fifo( int size_ = 1 )
: sc_core::sc_prim_channel( sc_core::sc_gen_unique_name( "fifo" ) ) {
init( size_ );
}
explicit tlm_fifo( const char* name_, int size_ = 1 )
: sc_core::sc_prim_channel( name_ ) {
init( size_ );
}
// destructor
virtual ~tlm_fifo() {}
// tlm get interface
T get( tlm_tag<T> * = 0 );
bool nb_get( T& );
bool nb_can_get( tlm_tag<T> * = 0 ) const;
const sc_core::sc_event &ok_to_get( tlm_tag<T> * = 0 ) const {
return m_data_written_event;
}
// tlm peek interface
T peek( tlm_tag<T> * = 0 ) const;
bool nb_peek( T& ) const;
bool nb_can_peek( tlm_tag<T> * = 0 ) const;
const sc_core::sc_event &ok_to_peek( tlm_tag<T> * = 0 ) const {
return m_data_written_event;
}
// tlm put interface
void put( const T& );
bool nb_put( const T& );
bool nb_can_put( tlm_tag<T> * = 0 ) const;
const sc_core::sc_event& ok_to_put( tlm_tag<T> * = 0 ) const {
return m_data_read_event;
}
// resize if
void nb_expand( unsigned int n = 1 );
void nb_unbound( unsigned int n = 16 );
bool nb_reduce( unsigned int n = 1 );
bool nb_bound( unsigned int n );
// debug interface
bool nb_peek( T & , int n ) const;
bool nb_poke( const T & , int n = 0 );
int used() const {
return m_num_readable - m_num_read;
}
int size() const {
return m_size;
}
void debug() const {
if( is_empty() ) std::cout << "empty" << std::endl;
if( is_full() ) std::cout << "full" << std::endl;
std::cout << "size " << size() << " - " << used() << " used "
<< std::endl;
std::cout << "readable " << m_num_readable
<< std::endl;
std::cout << "written/read " << m_num_written << "/" << m_num_read
<< std::endl;
}
// support functions
static const char* const kind_string;
const char* kind() const
{ return kind_string; }
protected:
sc_core::sc_event &read_event( tlm_tag<T> * = 0 ) {
return m_data_read_event;
}
protected:
void update();
// support methods
void init( int );
protected:
circular_buffer<T> buffer;
int m_size; // logical size of fifo
int m_num_readable; // #samples readable
int m_num_read; // #samples read during this delta cycle
int m_num_written; // #samples written during this delta cycle
bool m_expand; // has an expand occurred during this delta cycle ?
int m_num_read_no_notify; // #samples read without notify during this delta cycle
sc_core::sc_event m_data_read_event;
sc_core::sc_event m_data_written_event;
private:
// disabled
tlm_fifo( const tlm_fifo<T>& );
tlm_fifo& operator = ( const tlm_fifo<T>& );
//
// use nb_can_get() and nb_can_put() rather than the following two
// private functions
//
bool is_empty() const {
return used() == 0;
}
bool is_full() const {
//return size() == m_num_readable + m_num_written; // Old buggy code
if( size() < 0 )
return false;
else
return size() <= m_num_readable + m_num_written;
}
};
template <typename T>
const char* const tlm_fifo<T>::kind_string = "tlm_fifo";
/******************************************************************
//
// init and update
//
******************************************************************/
template< typename T >
inline
void
tlm_fifo<T>::init( int size_ ) {
if( size_ > 0 ) {
buffer.resize( size_ );
}
else if( size_ < 0 ) {
buffer.resize( -size_ );
}
else {
buffer.resize( 16 );
}
m_size = size_;
m_num_readable = 0;
m_num_read = 0;
m_num_written = 0;
m_expand = false;
m_num_read_no_notify = false;
}
template < typename T>
inline
void
tlm_fifo<T>::update()
{
if( m_num_read > m_num_read_no_notify || m_expand ) {
m_data_read_event.notify( sc_core::SC_ZERO_TIME );
}
if( m_num_written > 0 ) {
m_data_written_event.notify( sc_core::SC_ZERO_TIME );
}
m_expand = false;
m_num_read = 0;
m_num_written = 0;
m_num_readable = buffer.used();
m_num_read_no_notify = 0;
}
} // namespace tlm
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_put_get.h"
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_peek.h"
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_resize.h"
#endif

View File

@@ -0,0 +1,98 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_FIFO_PEEK_H__
#define __TLM_FIFO_PEEK_H__
namespace tlm {
template < typename T>
inline
T
tlm_fifo<T>::peek( tlm_tag<T> * ) const {
while( is_empty() ) {
// call free-standing sc_core::wait(),
// since sc_prim_channel::wait(.) is not const
sc_core::wait( m_data_written_event );
}
return buffer.read_data();
}
template < typename T>
inline
bool
tlm_fifo<T>::nb_peek( T &t ) const {
if( used() < 1 ) {
return false;
}
t = buffer.peek_data( 0 );
return true;
}
template < typename T>
inline
bool
tlm_fifo<T>::nb_peek( T &t , int n ) const {
if( n >= used() || n < -1 ) {
return false;
}
if( n == -1 ) {
n = used() - 1;
}
t = buffer.peek_data( n );
return true;
}
template< typename T >
inline
bool
tlm_fifo<T>::nb_can_peek( tlm_tag<T> * ) const
{
return !is_empty();
}
template < typename T>
inline
bool
tlm_fifo<T>::nb_poke( const T &t , int n ) {
if( n >= used() || n < 0 ) {
return false;
}
buffer.poke_data( n ) = t;
return true;
}
} // namespace tlm
#endif

View File

@@ -0,0 +1,140 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_FIFO_PUT_GET_IF_H__
#define __TLM_FIFO_PUT_GET_IF_H__
namespace tlm {
/******************************************************************
//
// get interface
//
******************************************************************/
template <typename T>
inline
T
tlm_fifo<T>::get( tlm_tag<T> * )
{
while( is_empty() ) {
wait( m_data_written_event );
}
m_num_read ++;
request_update();
return buffer.read();
}
// non-blocking read
template <typename T>
inline
bool
tlm_fifo<T>::nb_get( T& val_ )
{
if( is_empty() ) {
return false;
}
m_num_read ++;
request_update();
val_ = buffer.read();
return true;
}
template <typename T>
inline
bool
tlm_fifo<T>::nb_can_get( tlm_tag<T> * ) const {
return !is_empty();
}
/******************************************************************
//
// put interface
//
******************************************************************/
template <typename T>
inline
void
tlm_fifo<T>::put( const T& val_ )
{
while( is_full() ) {
wait( m_data_read_event );
}
if( buffer.is_full() ) {
buffer.resize( buffer.size() * 2 );
}
m_num_written ++;
buffer.write( val_ );
request_update();
}
template <typename T>
inline
bool
tlm_fifo<T>::nb_put( const T& val_ )
{
if( is_full() ) {
return false;
}
if( buffer.is_full() ) {
buffer.resize( buffer.size() * 2 );
}
m_num_written ++;
buffer.write( val_ );
request_update();
return true;
}
template < typename T >
inline
bool
tlm_fifo<T>::nb_can_put( tlm_tag<T> * ) const {
return !is_full();
}
} // namespace tlm
#endif

View File

@@ -0,0 +1,93 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_FIFO_RESIZE_H__
#define __TLM_FIFO_RESIZE_H__
/******************************************************************
//
// resize interface
//
******************************************************************/
namespace tlm {
template < typename T>
inline
void
tlm_fifo<T>::nb_expand( unsigned int n ) {
if( m_size >= 0 ) {
m_expand = true;
m_size += n;
request_update();
}
}
template < typename T>
inline
void
tlm_fifo<T>::nb_unbound( unsigned int n ) {
m_expand = true;
m_size = -n;
if( buffer.size() < static_cast<int>( n ) ) {
buffer.resize( n );
}
request_update();
}
template < typename T>
inline
bool
tlm_fifo<T>::nb_reduce( unsigned int n ) {
if( m_size < 0 ) {
return false;
}
return nb_bound( size() - n );
}
template < typename T>
inline
bool
tlm_fifo<T>::nb_bound( unsigned int new_size ) {
bool ret = true;
if( static_cast<int>( new_size ) < used() ) {
new_size = used();
ret = false;
}
m_size = new_size;
return ret;
}
} // namespace tlm
#endif

View File

@@ -0,0 +1,114 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
//
// To the LRM writer : these classes are purely artifacts of the implementation.
//
#ifndef __TLM_PUT_GET_IMP_H__
#define __TLM_PUT_GET_IMP_H__
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_master_slave_ifs.h"
namespace tlm {
template < typename PUT_DATA , typename GET_DATA>
class tlm_put_get_imp :
private virtual tlm_put_if< PUT_DATA > ,
private virtual tlm_get_peek_if< GET_DATA >
{
public:
tlm_put_get_imp( tlm_put_if<PUT_DATA> &p ,
tlm_get_peek_if<GET_DATA> &g ) :
put_fifo( p ) , get_fifo( g ) {}
// put interface
void put( const PUT_DATA &t ) { put_fifo.put( t ); }
bool nb_put( const PUT_DATA &t ) { return put_fifo.nb_put( t ); }
bool nb_can_put( tlm_tag<PUT_DATA> *t = 0 ) const {
return put_fifo.nb_can_put( t );
}
const sc_core::sc_event &ok_to_put( tlm_tag<PUT_DATA> *t = 0 ) const {
return put_fifo.ok_to_put( t );
}
// get interface
GET_DATA get( tlm_tag<GET_DATA> * = 0 ) { return get_fifo.get(); }
bool nb_get( GET_DATA &t ) { return get_fifo.nb_get( t ); }
bool nb_can_get( tlm_tag<GET_DATA> *t = 0 ) const {
return get_fifo.nb_can_get( t );
}
virtual const sc_core::sc_event &ok_to_get( tlm_tag<GET_DATA> *t = 0 ) const {
return get_fifo.ok_to_get( t );
}
// peek interface
GET_DATA peek( tlm_tag<GET_DATA> * = 0 ) const { return get_fifo.peek(); }
bool nb_peek( GET_DATA &t ) const { return get_fifo.nb_peek( t ); }
bool nb_can_peek( tlm_tag<GET_DATA> *t = 0 ) const {
return get_fifo.nb_can_peek( t );
}
virtual const sc_core::sc_event &ok_to_peek( tlm_tag<GET_DATA> *t = 0 ) const {
return get_fifo.ok_to_peek( t );
}
private:
tlm_put_if<PUT_DATA> &put_fifo;
tlm_get_peek_if<GET_DATA> &get_fifo;
};
template < typename REQ , typename RSP >
class tlm_master_imp :
private tlm_put_get_imp< REQ , RSP > ,
public virtual tlm_master_if< REQ , RSP >
{
public:
tlm_master_imp( tlm_put_if<REQ> &req ,
tlm_get_peek_if<RSP> &rsp ) :
tlm_put_get_imp<REQ,RSP>( req , rsp ) {}
};
template < typename REQ , typename RSP >
class tlm_slave_imp :
private tlm_put_get_imp< RSP , REQ > ,
public virtual tlm_slave_if< REQ , RSP >
{
public:
tlm_slave_imp( tlm_get_peek_if<REQ> &req ,
tlm_put_if<RSP> &rsp ) :
tlm_put_get_imp<RSP,REQ>( rsp , req ) {}
};
} // namespace tlm
#endif

View File

@@ -0,0 +1,155 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_REQ_RSP_CHANNELS_H__
#define __TLM_REQ_RSP_CHANNELS_H__
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_adapters/tlm_adapters.h"
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h"
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_put_get_imp.h"
namespace tlm {
template < typename REQ , typename RSP ,
typename REQ_CHANNEL = tlm_fifo<REQ> ,
typename RSP_CHANNEL = tlm_fifo<RSP> >
class tlm_req_rsp_channel : public sc_core::sc_module
{
public:
// uni-directional slave interface
sc_core::sc_export< tlm_fifo_get_if< REQ > > get_request_export;
sc_core::sc_export< tlm_fifo_put_if< RSP > > put_response_export;
// uni-directional master interface
sc_core::sc_export< tlm_fifo_put_if< REQ > > put_request_export;
sc_core::sc_export< tlm_fifo_get_if< RSP > > get_response_export;
// master / slave interfaces
sc_core::sc_export< tlm_master_if< REQ , RSP > > master_export;
sc_core::sc_export< tlm_slave_if< REQ , RSP > > slave_export;
tlm_req_rsp_channel( int req_size = 1 , int rsp_size = 1 ) :
sc_core::sc_module( sc_core::sc_module_name( sc_core::sc_gen_unique_name("tlm_req_rsp_channel") ) ) ,
request_fifo( req_size ) ,
response_fifo( rsp_size ) ,
master( request_fifo , response_fifo ) ,
slave( request_fifo , response_fifo )
{
bind_exports();
}
tlm_req_rsp_channel( sc_core::sc_module_name module_name ,
int req_size = 1 , int rsp_size = 1 ) :
sc_core::sc_module( module_name ) ,
request_fifo( req_size ) ,
response_fifo( rsp_size ) ,
master( request_fifo , response_fifo ) ,
slave( request_fifo , response_fifo )
{
bind_exports();
}
private:
void bind_exports() {
put_request_export( request_fifo );
get_request_export( request_fifo );
put_response_export( response_fifo );
get_response_export( response_fifo );
master_export( master );
slave_export( slave );
}
protected:
REQ_CHANNEL request_fifo;
RSP_CHANNEL response_fifo;
tlm_master_imp< REQ , RSP > master;
tlm_slave_imp< REQ , RSP > slave;
};
template < typename REQ , typename RSP ,
typename REQ_CHANNEL = tlm_fifo<REQ> ,
typename RSP_CHANNEL = tlm_fifo<RSP> >
class tlm_transport_channel : public sc_core::sc_module
{
public:
// master transport interface
sc_core::sc_export< tlm_transport_if< REQ , RSP > > target_export;
// slave interfaces
sc_core::sc_export< tlm_fifo_get_if< REQ > > get_request_export;
sc_core::sc_export< tlm_fifo_put_if< RSP > > put_response_export;
sc_core::sc_export< tlm_slave_if< REQ , RSP > > slave_export;
tlm_transport_channel() :
sc_core::sc_module( sc_core::sc_module_name( sc_core::sc_gen_unique_name("transport_channel" ) ) ) ,
target_export("target_export") ,
req_rsp( "req_rsp" , 1 , 1 ) ,
t2m("ts2m")
{
do_binding();
}
tlm_transport_channel( sc_core::sc_module_name nm ) :
sc_core::sc_module( nm ) ,
target_export("target_export") ,
req_rsp( "req_rsp" , 1 , 1 ) ,
t2m("tsm" )
{
do_binding();
}
private:
void do_binding() {
target_export( t2m.target_export );
t2m.master_port( req_rsp.master_export );
get_request_export( req_rsp.get_request_export );
put_response_export( req_rsp.put_response_export );
slave_export( req_rsp.slave_export );
}
tlm_req_rsp_channel< REQ , RSP , REQ_CHANNEL , RSP_CHANNEL > req_rsp;
tlm_transport_to_master< REQ , RSP > t2m;
};
} // namespace tlm
#endif

View File

@@ -0,0 +1,76 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef TLM_CORE_TLM_EVENT_FINDER_H_INCLUDED_
#define TLM_CORE_TLM_EVENT_FINDER_H_INCLUDED_
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_tag.h"
namespace tlm {
template <class IF , class T>
class tlm_event_finder_t
: public sc_core::sc_event_finder
{
public:
// constructor
tlm_event_finder_t( const sc_core::sc_port_base& port_,
const sc_core::sc_event& (IF::*event_method_) ( tlm_tag<T> * ) const )
: sc_core::sc_event_finder( port_ ), m_event_method( event_method_ )
{}
// destructor (does nothing)
virtual ~tlm_event_finder_t()
{}
virtual const sc_core::sc_event& find_event( sc_core::sc_interface* if_p = 0 ) const;
private:
const sc_core::sc_event& (IF::*m_event_method) ( tlm_tag<T> * ) const;
private:
// disabled
tlm_event_finder_t();
tlm_event_finder_t( const tlm_event_finder_t<IF,T>& );
tlm_event_finder_t<IF,T>& operator = ( const tlm_event_finder_t<IF,T>& );
};
template <class IF , class T>
inline
const sc_core::sc_event&
tlm_event_finder_t<IF,T>::find_event( sc_core::sc_interface* if_p ) const
{
const IF* iface = ( if_p ) ? dynamic_cast<const IF*>( if_p ) :
dynamic_cast<const IF*>( port().get_interface() );
if( iface == 0 ) {
report_error( sc_core::SC_ID_FIND_EVENT_, "port is not bound" );
return sc_core::sc_event::none;
}
return (const_cast<IF*>( iface )->*m_event_method) ( 0 );
}
} // namespace tlm
#endif // TLM_CORE_TLM_EVENT_FINDER_H_INCLUDED_

View File

@@ -0,0 +1,91 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_NONBLOCKING_PORT_H__
#define __TLM_NONBLOCKING_PORT_H__
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h"
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_event_finder.h"
namespace tlm {
template < typename T >
class tlm_nonblocking_get_port :
public sc_core::sc_port< tlm_nonblocking_get_if< T > , 1 >
{
public:
typedef tlm_nonblocking_get_if<T> get_if_type;
tlm_nonblocking_get_port( const char *port_name ) :
sc_core::sc_port< tlm_nonblocking_get_if< T > , 1 >( port_name ) {}
sc_core::sc_event_finder& ok_to_get() const {
return *new tlm_event_finder_t< get_if_type , T >(
*this,
&get_if_type::ok_to_get );
}
};
template < typename T >
class tlm_nonblocking_peek_port :
public sc_core::sc_port< tlm_nonblocking_peek_if< T > , 1 >
{
public:
typedef tlm_nonblocking_peek_if<T> peek_if_type;
tlm_nonblocking_peek_port( const char *port_name ) :
sc_core::sc_port< tlm_nonblocking_peek_if< T > , 1 >( port_name ) {}
sc_core::sc_event_finder& ok_to_peek() const {
return *new tlm_event_finder_t< peek_if_type , T >(
*this,
&peek_if_type::ok_to_peek );
}
};
template < typename T >
class tlm_nonblocking_put_port :
public sc_core::sc_port< tlm_nonblocking_put_if< T > , 1 >
{
public:
typedef tlm_nonblocking_put_if<T> put_if_type;
tlm_nonblocking_put_port( const char *port_name ) :
sc_core::sc_port< tlm_nonblocking_put_if< T > , 1 >( port_name ) {}
sc_core::sc_event_finder& ok_to_put() const {
return *new tlm_event_finder_t< put_if_type , T >(
*this,
&put_if_type::ok_to_put );
}
};
} // namespace tlm
#endif

View File

@@ -0,0 +1,37 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_REQ_RSP_H__
#define __TLM_REQ_RSP_H__
// The unannotated TLM interfaces
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h"
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_master_slave_ifs.h"
// The channels : tlm_fifo, tlm_transport_channel and tlm_req_rsp_channel
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_req_rsp_channels.h"
// Some non blocking ports to provide static sensitivity
#include "tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_nonblocking_port.h"
#endif /* __TLM_REQ_RSP_H__ */

View File

@@ -0,0 +1,111 @@
TLM-2.0 interoperability layer header files
===========================================
Dir: include/tlm_core/tlm_2/
SubDirs: tlm_2_interfaces/
tlm_generic_payload/
tlm_quantum/
tlm_sockets
Files: README.txt
tlm_version.h
Comments
========
User code should only #include the tlm or tlm.h header file in the include/
directory and avoid including any of the include files in this directory
directly. All objects defined in this file hierarchy are in the tlm namespace.
tlm_version.h contains the definitions for the version string and integer values
The header files are organizated, by subdirectory, as follows:
tlm_2_interfaces/
-----------------
Contains the TLM-2.0 core interfaces
Files:
tlm_2_interfaces.h (includes the other header files in this directory )
tlm_fw_bw_ifs.h (defines the TLM 2.0 interface API's:
tlm_fw_nonblocking_transport_if
tlm_bw_nonblocking_transport_if
tlm_blocking_transport_if
tlm_fw_direct_mem_if
tlm_bw_direct_mem_if
tlm_transport_dbg_if
the enumeration type
tlm_sync_enum
and the TLM 2.0 standard interfaces using the API's
tlm_fw_transport_if
tlm_bw_transport_if )
tlm_dmi.h (defines tlm_dmi)
tlm_generic_payload/
--------------------
Contains the TLM-2.0 generic payload and associated classes and helper functions
Files:
tlm_generic_payload.h ( includes the other header files in this directory)
tlm_gp.h (defines the TLM 2.0 generic payload classes:
tlm_generic_payload
tlm_extension
tlm_extension_base
tlm_mm_interface
and the enumeration types
tlm_command
tlm_response_status )
tlm_array.h (defines array class used by the extention
mechanism )
tlm_endian_conv.h (defines the implementation for the endianness
helper functions:
tlm_to_hostendian_generic()
tlm_from_hostendian_generic()
tlm_to_hostendian_word()
tlm_from_hostendian_word()
tlm_to_hostendian_aligned()
tlm_from_hostendian_aligned()
tlm_to_hostendian_single()
tlm_from_hostendian_single() )
tlm_helpers.h (defines the helper functions to determine the
hostendianness:
get_host_endianness()
host_has_little_endianness()
has_host_endianness()
and defines the enumeration type:
tlm_endianness
tlm_phase.h (defines tlm_phase as an extendable enum type)
tlm_sockets/
------------
Contains the standard TLM-2.0 initiator and target sockets (which are used as
the base classes for the convenience sockets in tlm_utils)
Files:
tlm_sockets.h (includes the other header files in this directory)
tlm_initiator_socket.h (defines the initiator sockets:
tlm_initiator_socket_base
tlm_initiator_socket_b
tlm_initiator_socket
tlm_target_socket.h (defines the target sockets:
tlm_target_socket_base
tlm_target_socket_b
tlm_target_socket
tlm_quantum/
------------
This contains the global quantum. (The quantum keeper is in tlm_utils)
Files:
tlm_quantum.h ( includes the other header file in this directory )
tlm_global_quantum.h ( defines tlm_global_quantum )

View File

@@ -0,0 +1,27 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_2_INTERFACES_H__
#define __TLM_2_INTERFACES_H__
#include "tlm_core/tlm_2/tlm_2_interfaces/tlm_dmi.h"
#include "tlm_core/tlm_2/tlm_2_interfaces/tlm_fw_bw_ifs.h"
#endif

View File

@@ -0,0 +1,114 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_DMI_H__
#define __TLM_DMI_H__
#include <systemc>
namespace tlm {
class tlm_dmi
{
public:
// Enum for indicating the access granted to the initiator.
// The initiator uses gp.m_command to indicate it intention (read/write)
// The target is allowed to promote DMI_ACCESS_READ or DMI_ACCESS_WRITE
// requests to dmi_access_read_write.
enum dmi_access_e
{ DMI_ACCESS_NONE = 0x00 // no access
, DMI_ACCESS_READ = 0x01 // read access
, DMI_ACCESS_WRITE = 0x02 // write access
, DMI_ACCESS_READ_WRITE = DMI_ACCESS_READ | DMI_ACCESS_WRITE // read/write access
};
tlm_dmi (void)
{
init();
}
void init (void)
{
m_dmi_ptr = 0x0;
m_dmi_start_address = 0x0;
m_dmi_end_address = (sc_dt::uint64)(-1);
m_dmi_access = DMI_ACCESS_NONE;
m_dmi_read_latency = sc_core::SC_ZERO_TIME;
m_dmi_write_latency = sc_core::SC_ZERO_TIME;
}
unsigned char* get_dmi_ptr (void) const {return m_dmi_ptr;}
sc_dt::uint64 get_start_address (void) const {return m_dmi_start_address;}
sc_dt::uint64 get_end_address (void) const {return m_dmi_end_address;}
sc_core::sc_time get_read_latency (void) const {return m_dmi_read_latency;}
sc_core::sc_time get_write_latency (void) const {return m_dmi_write_latency;}
dmi_access_e get_granted_access (void) const {return m_dmi_access;}
bool is_none_allowed (void) const {return m_dmi_access == DMI_ACCESS_NONE;}
bool is_read_allowed (void) const {return (m_dmi_access & DMI_ACCESS_READ) == DMI_ACCESS_READ;}
bool is_write_allowed (void) const {return (m_dmi_access & DMI_ACCESS_WRITE) == DMI_ACCESS_WRITE;}
bool is_read_write_allowed (void) const {return (m_dmi_access & DMI_ACCESS_READ_WRITE) == DMI_ACCESS_READ_WRITE;}
void set_dmi_ptr (unsigned char* p) {m_dmi_ptr = p;}
void set_start_address (sc_dt::uint64 addr) {m_dmi_start_address = addr;}
void set_end_address (sc_dt::uint64 addr) {m_dmi_end_address = addr;}
void set_read_latency (sc_core::sc_time t) {m_dmi_read_latency = t;}
void set_write_latency (sc_core::sc_time t) {m_dmi_write_latency = t;}
void set_granted_access (dmi_access_e a) {m_dmi_access = a;}
void allow_none (void) {m_dmi_access = DMI_ACCESS_NONE;}
void allow_read (void) {m_dmi_access = DMI_ACCESS_READ;}
void allow_write (void) {m_dmi_access = DMI_ACCESS_WRITE;}
void allow_read_write (void) {m_dmi_access = DMI_ACCESS_READ_WRITE;}
private:
// If the forward call is successful, the target returns the dmi_ptr,
// which must point to the data element corresponding to the
// dmi_start_address. The data is organized as a byte array with the
// endianness of the target (endianness member of the tlm_dmi struct).
unsigned char* m_dmi_ptr;
// The absolute start and end addresses of the DMI region. If the decoder
// logic in the interconnect changes the address field e.g. by masking, the
// interconnect is responsible to transform the relative address back to an
// absolute address again.
sc_dt::uint64 m_dmi_start_address;
sc_dt::uint64 m_dmi_end_address;
// Granted access
dmi_access_e m_dmi_access;
// These members define the latency of read/write transactions. The
// initiator must initialize these members to zero before requesting a
// dmi pointer, because both the interconnect as well as the target can
// add to the total transaction latency.
// Depending on the 'type' attribute only one, or both of these attributes
// will be valid.
sc_core::sc_time m_dmi_read_latency;
sc_core::sc_time m_dmi_write_latency;
};
} // namespace tlm
#endif /* TLM_DMI_HEADER */

View File

@@ -0,0 +1,223 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_FW_BW_IFS_H__
#define __TLM_FW_BW_IFS_H__
#include <systemc>
#include "tlm_core/tlm_2/tlm_generic_payload/tlm_generic_payload.h"
#include "tlm_core/tlm_2/tlm_2_interfaces/tlm_dmi.h"
namespace tlm {
enum tlm_sync_enum { TLM_ACCEPTED, TLM_UPDATED, TLM_COMPLETED };
////////////////////////////////////////////////////////////////////////////
// Basic interfaces
////////////////////////////////////////////////////////////////////////////
template <typename TRANS = tlm_generic_payload,
typename PHASE = tlm_phase>
class tlm_fw_nonblocking_transport_if : public virtual sc_core::sc_interface {
public:
virtual tlm_sync_enum nb_transport_fw(TRANS& trans,
PHASE& phase,
sc_core::sc_time& t) = 0;
};
template <typename TRANS = tlm_generic_payload,
typename PHASE = tlm_phase>
class tlm_bw_nonblocking_transport_if : public virtual sc_core::sc_interface {
public:
virtual tlm_sync_enum nb_transport_bw(TRANS& trans,
PHASE& phase,
sc_core::sc_time& t) = 0;
};
template <typename TRANS = tlm_generic_payload>
class tlm_blocking_transport_if : public virtual sc_core::sc_interface {
public:
virtual void b_transport(TRANS& trans,
sc_core::sc_time& t) = 0;
};
//////////////////////////////////////////////////////////////////////////
// DMI interfaces for getting and invalidating DMI pointers:
//////////////////////////////////////////////////////////////////////////
// The semantics of the forward interface are as follows:
//
// - An initiator that wants to get direct access to a target's memory region
// can call the get_direct_mem_ptr method with the 'trans' parameter set to
// the address that it wants to gain access to. It sets the trans.m_command
// to specify if the initiator intended use (read or write)
// to the target's DMI region. The initiator is responsible for calling the
// method with a freshly initialized tlm_dmi object either by using a newly
// constructed object, or by calling an existing object's init() method.
// - Although a reference to a complete 'TRANS' type is passed to the get_
// direct_mem_ptr call, only the address command, and extension fields are of
// interest in most cases.
// - Read and write ranges are not necessarily identical. If they are, a target
// can specify that the range is valid for all accesses with the tlm_data
// m_type attribute in the.
// - The interconnect, if any, needs to decode the address and forward the
// call to the corresponding target. It needs to handle the address exactly
// as the target would expect on a transaction call, e.g. mask the address
// according to the target's address width.
// - If the target supports DMI access for the given address, it sets the
// data fields in the DMI struct and returns true.
// - If a target does not support DMI access it needs to return false.
// The target can either set the correct address range in the DMI struct
// to indicate the memory region where DMI is disallowed, or it can specify
// the complete address range if it doesn't know it's memory range. In this
// case the interconnect is responsible for clipping the address range to
// the correct range that the target serves.
// - The interconnect must always translate the addresses to the initiator's
// address space. This must be the inverse operation of what the
// interconnect needed to do when forwarding the call. In case the
// component wants to change any member of the tlm_dmi object, e.g. for
// its own latency to the target's latency, it must only do so *after* the
// target has been called. The target is always allowed to overwrite all
// values in the tlm_dmi object.
// - In case the slave returned with an invalid region the bus/interconnect
// must fill in the complete address region for the particular slave in the
// DMI data structure.
//
// DMI hint optimization:
//
// Initiators may use the DMI hint in the tlm_generic_payload to avoid
// unnecessary DMI attempts. The recommended sequence of interface
// method calls would be:
//
// - The initiator first tries to check if it has a valid DMI region for the
// address that it wants to access next.
// - If not, it performs a normal transaction.
// - If the DMI hint in this transaction is true, the initiator can try and
// get the DMI region.
//
// Note that the DMI hint optimization is completely optional and every
// initiator model is free to ignore the DMI hint. However, a target is
// required to set the DMI hint to true if a DMI request on the given address
// with the given transaction type (read or write) would have succeeded.
template <typename TRANS = tlm_generic_payload>
class tlm_fw_direct_mem_if : public virtual sc_core::sc_interface
{
public:
virtual bool get_direct_mem_ptr(TRANS& trans,
tlm_dmi& dmi_data) = 0;
};
// The semantics of the backwards call is as follows:
//
// - An interconnect component or a target is required to invalidate all
// affected DMI regions whenever any change in the regions take place.
// The exact rule is that a component must invalidate all those DMI regions
// that it already reported, if it would answer the same DMI request
// with any member of the tlm_dmi data structure set differently.
// - An interconnect component must forward the invalidate_direct_mem_ptr call
// to all initiators that could potentially have a DMI pointer to the region
// specified in the method arguments. A safe implementation is to call
// every attached initiator.
// - An interconnect component must transform the address region of an
// incoming invalidate_direct_mem_ptr to the corresponding address space
// for the initiators. Basically, this is the same address transformation
// that the interconnect does on the DMI ranges on the forward direction.
// - Each initiator must check if it has a pointer to the given region and
// throw this away. It is recommended that the initiator throws away all DMI
// regions that have any overlap with the given regions, but this is not a
// hard requirement.
//
// - A full DMI pointer invalidation, e.g. for a bus remap can be signaled
// by setting the range: 0x0 - 0xffffffffffffffffull = (sc_dt::uint64)-1
// - An initiator must throw away all DMI pointers in this case.
//
// - Under no circumstances a model is allowed to call the get_direct_mem_ptr
// from within the invalidate_direct_mem_ptr method, directly or indirectly.
//
class tlm_bw_direct_mem_if : public virtual sc_core::sc_interface
{
public:
virtual void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
sc_dt::uint64 end_range) = 0;
};
/////////////////////////////////////////////////////////////////////
// debug interface for memory access
/////////////////////////////////////////////////////////////////////
//
// This interface can be used to gain access to a targets memory or registers
// in a non-intrusive manner. No side effects, waits or event notifications
// must happen in the course of the method.
//
// Semantics:
// - The initiator calls the transport_dbg method with transaction 'trans' as
// argument. The commonly used parts of trans for debug are:
// . address: The start address that it wants to peek or poke.
// . length: The number of bytes that it requests to read or write.
// . command: Indicates a read or write access.
// . data: A pointer to the initiator-allocated data buffer, which must
// be at least num_bytes large. The data is always organized in
// the endianness of the machine.
// . extensions: Any extension that could affect the transaction.
// - The interconnect, if any, will decode the address and forward the call to
// the appropriate target.
// - The target must return the number of successfully transmitted bytes, where
// this number must be <= num_bytes. Thus, a target can safely return 0 if it
// does not support debug transactions.
//
template <typename TRANS = tlm_generic_payload>
class tlm_transport_dbg_if : public virtual sc_core::sc_interface
{
public:
// The return value of defines the number of bytes successfully
// transferred.
virtual unsigned int transport_dbg(TRANS& trans) = 0;
};
////////////////////////////////////////////////////////////////////////////
// Combined interfaces
////////////////////////////////////////////////////////////////////////////
struct tlm_base_protocol_types
{
typedef tlm_generic_payload tlm_payload_type;
typedef tlm_phase tlm_phase_type;
};
// The forward interface:
template <typename TYPES = tlm_base_protocol_types>
class tlm_fw_transport_if
: public virtual tlm_fw_nonblocking_transport_if<typename TYPES::tlm_payload_type,
typename TYPES::tlm_phase_type>
, public virtual tlm_blocking_transport_if<typename TYPES::tlm_payload_type>
, public virtual tlm_fw_direct_mem_if<typename TYPES::tlm_payload_type>
, public virtual tlm_transport_dbg_if<typename TYPES::tlm_payload_type>
{};
// The backward interface:
template <typename TYPES = tlm_base_protocol_types>
class tlm_bw_transport_if
: public virtual tlm_bw_nonblocking_transport_if<typename TYPES::tlm_payload_type,
typename TYPES::tlm_phase_type>
, public virtual tlm_bw_direct_mem_if
{};
} // namespace tlm
#endif /* __TLM_FW_BW_IFS_H__ */

View File

@@ -0,0 +1,126 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef TLM_CORE_TLM2_TLM_ARRAY_H_INCLUDED_
#define TLM_CORE_TLM2_TLM_ARRAY_H_INCLUDED_
#include <vector>
#if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN)
#pragma warning(push)
#pragma warning(disable: 4251) // DLL import for std::string,vector
#endif
namespace tlm {
//
// To the LRM writer: the below class is an artifact of the tlm_generic_payload
// implementation and not part of the core TLM standard
//
// This implements a lean and fast array class that supports array expansion on
// request. The class is primarily used in the tlm_generic_payload class for
// storing the pointers to the extensions.
//
// Individual array elements can be accessed through the [] operators, and the
// array length is returned by the size() method.
//
// The size can be dynamically expanded using the expand(uint) method. There
// is no shrinking mechanism implemented, because the extension mechanism
// does not require this feature. Bear in mind that calling the expand method
// may invalidate all direct pointers into the array.
//the tlm_array shall always be used with T=tlm_extension_base*
template <typename T>
class tlm_array
: private std::vector<T>
{
typedef std::vector<T> base_type;
typedef typename base_type::size_type size_type;
public:
// constructor:
tlm_array(size_type size = 0)
: base_type(size)
, m_entries()
{
//m_entries.reserve(size); // optional
}
// copy constructor:
// tlm_array(const tlm_array& orig) = default;
// destructor:
// ~tlm_array() = default;
// operators for dereferencing:
using base_type::operator[];
// array size:
using base_type::size;
// expand the array if needed:
void expand(size_type new_size)
{
if (new_size > size())
{
base_type::resize(new_size);
//m_entries.reserve(new_size); // optional
}
}
static const char* const kind_string;
const char* kind() const { return kind_string; }
//this function shall get a pointer to a array slot
// it stores this slot in a cache of active slots
void insert_in_cache(T* p)
{
//sc_assert( (p-&(*this)[0]) < size() );
m_entries.push_back( p-&(*this)[0] );
}
//this functions clears all active slots of the array
void free_entire_cache()
{
while(m_entries.size())
{
if ((*this)[m_entries.back()]) //we make sure no one cleared the slot manually
(*this)[m_entries.back()]->free();//...and then we call free on the content of the slot
(*this)[m_entries.back()]=0; //afterwards we set the slot to NULL
m_entries.pop_back();
}
}
protected:
std::vector<size_type> m_entries;
};
template <typename T>
const char* const tlm_array<T>::kind_string = "tlm_array";
#if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN)
#pragma warning(pop)
#endif
} // namespace tlm
#endif /* TLM_CORE_TLM2_TLM_ARRAY_H_INCLUDED_ */

View File

@@ -0,0 +1,791 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_ENDIAN_CONV_H__
#define __TLM_ENDIAN_CONV_H__
#include "tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h"
#include <cstring> // std::memset
namespace tlm {
/*
Tranaction-Level Modelling
Endianness Helper Functions
DESCRIPTION
A set of functions for helping users to get the endianness
right in their TLM models of system initiators. These functions are
for use within an initiator. They can not be used as-is outside
an initiator because the extension used to store context will not work
if cascaded, and they do not respect the generic payload mutability
rules. However this code may be easily copied and adapted for use
in bridges, etc..
These functions are not compulsory. There are other legitimate ways to
achieve the same functionality. If extra information is available at
compile time about the nature of an initiator's transactions, this can
be exploited to accelerate simulations by creating further functions
similar to those in this file. In general a functional transaction can be
described in more than one way by a TLM-2 GP object.
The functions convert the endianness of a GP object, either on request or
response. They should only be used when the initiator's endianness
does not match the host's endianness. They assume 'arithmetic mode'
meaning that within a data word the byte order is always host-endian.
For non-arithmetic mode initiators they can be used with a data word
size of 1 byte.
All the functions are templates, for example:
template<class DATAWORD> inline void
to_hostendian_generic(tlm_generic_payload *txn, int sizeof_databus)
The template parameter provides the data word width. Having this as a class
makes it easy to use it for copy and swap operations within the functions.
If the assignment operator for this class is overloaded, the endianness
conversion function may not have the desired effect.
All the functions have the same signature except for different names.
The principle is that a function to_hostendian_convtype() is called when the
initiator-endian transaction is created, and the matching function
from_hostendian_convtype() is called when the transaction is completed, for
example before read data can be used. In some cases the from_ function is
redundant but an empty function is provided anyway. It is strongly
recommended that the from_ function is called, in case it ceases to be
redundant in future versions of this code.
No context needs to be managed outside the two functions, except that they
must be called with the same template parameter and the same bus width.
For initiator models that can not easily manage this context information,
a single entry point for the from_ function is provided, which will be
a little slower than calling the correct from_ function directly, as
it can not be inlined.
All functions assume power-of-2 bus and data word widths.
Functions offered:
0) A pair of functions that work for almost all TLM2 GP transactions. The
only limitations are that data and bus widths should be powers of 2, and that
the data length should be an integer number of streaming widths and that the
streaming width should be an integer number of data words.
These functions always allocate new data and byte enable buffers and copy
data one byte at a time.
tlm_to_hostendian_generic(tlm_generic_payload *txn, int sizeof_databus)
tlm_from_hostendian_generic(tlm_generic_payload *txn, int sizeof_databus)
1) A pair of functions that work for all transactions regardless of data and
bus data sizes and address alignment except for the the following
limitations:
- byte-enables are supported only when byte-enable granularity is no finer
than the data word (every data word is wholly enabled or wholly disabled)
- byte-enable-length is not supported (if byte enables are present, the byte
enable length must be equal to the data length).
- streaming width is not supported
- data word wider than bus word is not supported
A new data buffer and a new byte enable buffer are always allocated. Byte
enables are assumed to be needed even if not required for the original
(unconverted) transaction. Data is copied to the new buffer on request
(for writes) or on response (for reads). Copies are done word-by-word
where possible.
tlm_to_hostendian_word(tlm_generic_payload *txn, int sizeof_databus)
tlm_from_hostendian_word(tlm_generic_payload *txn, int sizeof_databus)
2) If the original transaction is both word and bus-aligned then this pair of
functions can be used. It will complete faster than the generic function
because the data reordering function is much simpler and no address
conversion is required.
The following limitations apply:
- byte-enables are supported only when byte-enable granularity is no finer
than the data word (every data word is wholly enabled or wholly disabled)
- byte-enable-length is not supported (if byte enables are present, the byte
enable length must be equal to the data length).
- streaming width is not supported
- data word wider than bus word is not supported
- the transaction must be an integer number of bus words
- the address must be aligned to the bus width
tlm_to_hostendian_aligned(tlm_generic_payload *txn, int sizeof_databus)
tlm_from_hostendian_aligned(tlm_generic_payload *txn, int sizeof_databus)
3) For single word transactions that don't cross a bus word boundary it
is always safe to work in-place and the conversion is very simple. Again,
streaming width and byte-enable length are not supported, and byte-enables
may not changes within a data word.
tlm_to_hostendian_single(tlm_generic_payload *txn, int sizeof_databus)
tlm_from_hostendian_single(tlm_generic_payload *txn, int sizeof_databus)
4) A single entry point for accessing the correct from_ function without
needing to store context.
tlm_from_hostendian(tlm_generic_payload *txn)
*/
#ifndef uchar
#define uchar unsigned char
#else
#define TLM_END_CONV_DONT_UNDEF_UCHAR
#endif
///////////////////////////////////////////////////////////////////////////////
// Generic Utilities
class tlm_endian_context;
class tlm_endian_context_pool {
public:
tlm_endian_context *first;
inline tlm_endian_context_pool();
inline ~tlm_endian_context_pool();
inline tlm_endian_context *pop();
inline void push(tlm_endian_context *c);
};
static tlm_endian_context_pool global_tlm_endian_context_pool;
// an extension to keep the information needed for reconversion of response
class tlm_endian_context : public tlm_extension<tlm_endian_context> {
public:
tlm_endian_context() : dbuf_size(0), bebuf_size(0) {}
~tlm_endian_context() {
if(dbuf_size > 0) delete [] new_dbuf;
if(bebuf_size > 0) delete [] new_bebuf;
}
sc_dt::uint64 address; // used by generic, word
sc_dt::uint64 new_address; // used by generic
uchar *data_ptr; // used by generic, word, aligned
uchar *byte_enable; // used by word
int length; // used by generic, word
int stream_width; // used by generic
// used by common entry point on response
void (*from_f)(tlm_generic_payload *txn, unsigned int sizeof_databus);
int sizeof_databus;
// reordering buffers for data and byte-enables
uchar *new_dbuf, *new_bebuf;
int dbuf_size, bebuf_size;
void establish_dbuf(int len) {
if(len <= dbuf_size) return;
if(dbuf_size > 0) delete [] new_dbuf;
new_dbuf = new uchar[len];
dbuf_size = len;
}
void establish_bebuf(int len) {
if(len <= bebuf_size) return;
if(bebuf_size > 0) delete [] new_bebuf;
new_bebuf = new uchar[len];
bebuf_size = len;
}
// required for extension management
void free() {
global_tlm_endian_context_pool.push(this);
}
tlm_extension_base* clone() const {return 0;}
void copy_from(tlm_extension_base const &) {return;}
// for pooling
tlm_endian_context *next;
};
// Assumptions about transaction contexts:
// 1) only the address attribute of a transaction
// is mutable. all other attributes are unchanged from the request to
// response side conversion.
// 2) the conversion functions in this file do not respect the mutability
// rules and do not put the transaction back into its original state after
// completion. so if the initiator has any cleaning up to do (eg of byte
// enable buffers), it needs to store its own context. the transaction
// returned to the initiator may contain pointers to data and byte enable
// that can/must not be deleted.
// 3) the conversion functions in this file use an extension to store
// context information. they do not remove this extension. the initiator
// should not remove it unless it deletes the generic payload
// object.
inline tlm_endian_context *establish_context(tlm_generic_payload *txn) {
tlm_endian_context *tc = txn->get_extension<tlm_endian_context>();
if(tc == 0) {
tc = global_tlm_endian_context_pool.pop();
txn->set_extension(tc);
}
return tc;
}
inline tlm_endian_context_pool::tlm_endian_context_pool() : first(0) {}
inline tlm_endian_context_pool::~tlm_endian_context_pool() {
while(first != 0) {
tlm_endian_context *next = first->next;
delete first;
first = next;
}
}
tlm_endian_context *tlm_endian_context_pool::pop() {
if(first == 0) return new tlm_endian_context;
tlm_endian_context *r = first;
first = first->next;
return r;
}
void tlm_endian_context_pool::push(tlm_endian_context *c) {
c->next = first;
first = c;
}
// a set of constants for efficient filling of byte enables
template<class D> class tlm_bool {
public:
static D TLM_TRUE;
static D TLM_FALSE;
static D make_uchar_array(uchar c) {
D d;
uchar *tmp = (uchar *)(&d);
for(ptrdiff_t i=0; i!=sizeof(D); i++) tmp[i] = c; // 64BITFIX negligable risk but easy fix //
return d;
}
// also provides an syntax-efficient tester, using a
// copy constuctor and an implicit cast to boolean
tlm_bool(D &d) : b(*((uchar*)&d) != TLM_BYTE_DISABLED) {}
operator bool() const {return b;}
private:
bool b;
};
template<class D> D tlm_bool<D>::TLM_TRUE
= tlm_bool<D>::make_uchar_array(TLM_BYTE_ENABLED);
template<class D> D tlm_bool<D>::TLM_FALSE
= tlm_bool<D>::make_uchar_array(TLM_BYTE_DISABLED);
///////////////////////////////////////////////////////////////////////////////
// function set (0): Utilities
inline void copy_db0(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
*dest1 = *src1;
*dest2 = *src2;
}
inline void copy_dbtrue0(uchar *src1, uchar * /* src2 */, uchar *dest1, uchar *dest2) {
*dest1 = *src1;
*dest2 = TLM_BYTE_ENABLED;
}
inline void copy_btrue0(uchar * /* src1 */, uchar * /* src2 */, uchar * /* dest1 */, uchar *dest2) {
*dest2 = TLM_BYTE_ENABLED;
}
inline void copy_b0(uchar * /* src1 */, uchar *src2, uchar * /* dest1 */, uchar *dest2) {
*dest2 = *src2;
}
inline void copy_dbyb0(uchar *src1, uchar * /* src2 */, uchar *dest1, uchar *dest2) {
if(*dest2 == TLM_BYTE_ENABLED) *src1 = *dest1;
}
template<class D,
void COPY(uchar *he_d, uchar *he_b, uchar *ie_d, uchar *ie_b)>
inline void loop_generic0(int new_len, int new_stream_width,
int orig_stream_width, int sizeof_databus,
sc_dt::uint64 orig_start_address, sc_dt::uint64 new_start_address, int be_length,
uchar *ie_data, uchar *ie_be, uchar *he_data, uchar *he_be) {
for(int orig_sword = 0, new_sword = 0; new_sword < new_len;
new_sword += new_stream_width, orig_sword += orig_stream_width) {
sc_dt::uint64 ie_addr = orig_start_address;
for(int orig_dword = orig_sword;
orig_dword < orig_sword + orig_stream_width; orig_dword += sizeof(D)) {
for(int curr_byte = orig_dword + sizeof(D) - 1;
curr_byte >= orig_dword; curr_byte--) {
ptrdiff_t he_index = ((ie_addr++) ^ (sizeof_databus - 1))
- new_start_address + new_sword; // 64BITFIX //
COPY(ie_data+curr_byte,
ie_be+(curr_byte % be_length), // 64BITRISK no risk of overflow, always positive //
he_data+he_index, he_be+he_index);
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
// function set (0): Response
template<class DATAWORD> inline void
tlm_from_hostendian_generic(tlm_generic_payload *txn, unsigned int sizeof_databus) {
if(txn->is_read()) {
tlm_endian_context *tc = txn->template get_extension<tlm_endian_context>();
loop_generic0<DATAWORD, &copy_dbyb0>(txn->get_data_length(),
txn->get_streaming_width(), tc->stream_width, sizeof_databus, tc->address,
tc->new_address, txn->get_data_length(), tc->data_ptr, 0, txn->get_data_ptr(),
txn->get_byte_enable_ptr());
}
}
///////////////////////////////////////////////////////////////////////////////
// function set (0): Request
template<class DATAWORD> inline void
tlm_to_hostendian_generic(tlm_generic_payload *txn, unsigned int sizeof_databus) {
tlm_endian_context *tc = establish_context(txn);
tc->from_f = &(tlm_from_hostendian_generic<DATAWORD>);
tc->sizeof_databus = sizeof_databus;
// calculate new size: nr stream words multiplied by big enough stream width
int s_width = txn->get_streaming_width();
int length = txn->get_data_length();
if(s_width >= length) s_width = length;
int nr_stream_words = length/s_width;
// find out in which bus word the stream word starts and ends
sc_dt::uint64 new_address = (txn->get_address() & ~(sizeof_databus - 1));
sc_dt::uint64 end_address = ((txn->get_address() + s_width - 1)
& ~(sizeof_databus - 1));
int new_stream_width = end_address - new_address + sizeof_databus;
int new_length = new_stream_width * nr_stream_words;
// store context
tc->data_ptr = txn->get_data_ptr();
tc->address = txn->get_address();
tc->new_address = new_address;
tc->stream_width = s_width;
uchar *orig_be = txn->get_byte_enable_ptr();
int orig_be_length = txn->get_byte_enable_length();
// create data and byte-enable buffers
txn->set_address(new_address);
tc->establish_dbuf(new_length);
txn->set_data_ptr(tc->new_dbuf);
tc->establish_bebuf(new_length);
txn->set_byte_enable_ptr(tc->new_bebuf);
std::memset(txn->get_byte_enable_ptr(), TLM_BYTE_DISABLED, new_length);
txn->set_streaming_width(new_stream_width);
txn->set_data_length(new_length);
txn->set_byte_enable_length(new_length);
// copy data and/or byte enables
if(txn->is_write()) {
if(orig_be == 0) {
loop_generic0<DATAWORD, &copy_dbtrue0>(new_length,
new_stream_width, s_width, sizeof_databus, tc->address,
new_address, new_length, tc->data_ptr, 0, txn->get_data_ptr(),
txn->get_byte_enable_ptr());
} else {
loop_generic0<DATAWORD, &copy_db0>(new_length,
new_stream_width, s_width, sizeof_databus, tc->address,
new_address, orig_be_length, tc->data_ptr, orig_be, txn->get_data_ptr(),
txn->get_byte_enable_ptr());
}
} else { // read transaction
if(orig_be == 0) {
loop_generic0<DATAWORD, &copy_btrue0>(new_length,
new_stream_width, s_width, sizeof_databus, tc->address,
new_address, new_length, tc->data_ptr, 0, txn->get_data_ptr(),
txn->get_byte_enable_ptr());
} else {
loop_generic0<DATAWORD, &copy_b0>(new_length,
new_stream_width, s_width, sizeof_databus, tc->address,
new_address, orig_be_length, tc->data_ptr, orig_be, txn->get_data_ptr(),
txn->get_byte_enable_ptr());
}
}
}
///////////////////////////////////////////////////////////////////////////////
// function set (1): Utilities
template<class D>
inline void copy_d1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
*((D *)dest1) = *((D *)src1);
*((D *)dest2) = tlm_bool<D>::TLM_TRUE;
}
template<class D>
inline void copy_db1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
*((D *)dest1) = *((D *)src1);
*((D *)dest2) = *((D *)src2);
}
template<class D>
inline void true_b1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
*((D *)dest2) = tlm_bool<D>::TLM_TRUE;
}
template<class D>
inline void copy_b1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
*((D *)dest2) = *((D *)src2);
}
template<class D>
inline void copy_dbyb1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
if(*src2 != TLM_BYTE_DISABLED) *((D *)src1) = *((D *)dest1);
}
template<class D>
inline void copy_dbytrue1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
*((D *)src1) = *((D *)dest1);
}
template<class D> inline void false_b1(uchar *dest1) {
*((D *)dest1) = tlm_bool<D>::TLM_FALSE;
}
template<class D> inline void no_b1(uchar *dest1) {
}
template<class D,
void COPY(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2),
void COPYuchar(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2),
void FILLFALSE(uchar *dest1), void FILLFALSEuchar(uchar *dest1)>
inline int loop_word1(
int bytes_left, int len0, int lenN, int sizeof_databus,
uchar *start, uchar *end, uchar *src, uchar *bsrc, uchar *dest, uchar *bdest) {
ptrdiff_t d2b_src = bsrc - src; // 64BITFIX was int //
ptrdiff_t d2b_dest = bdest - dest; // 64BITFIX was int //
uchar *original_dest = dest;
while(true) {
// len0 bytes at start of a bus word
if((src >= start) && (src < end)) {
for(int i=0; i<len0; i++) {
COPYuchar(src, src+d2b_src, dest, dest+d2b_dest);
src++;
dest++;
}
bytes_left -= len0;
if(bytes_left <= 0) return int(dest - original_dest);
} else {
for(int i=0; i<len0; i++) {
FILLFALSEuchar(dest+d2b_dest);
src++;
dest++;
}
}
src -= 2 * sizeof(D);
// sequence of full data word fragments
for(unsigned int i=1; i<sizeof_databus/sizeof(D); i++) {
if((src >= start) && (src < end)) {
COPY(src, src+d2b_src, dest, dest+d2b_dest);
bytes_left -= sizeof(D);
} else {
FILLFALSE(dest+d2b_dest);
}
dest += sizeof(D);
if(bytes_left <= 0) return int(dest - original_dest);
src -= sizeof(D);
}
// lenN bytes at end of bus word
if((src >= start) && (src < end)) {
for(int i=0; i<lenN; i++) {
COPYuchar(src, src+d2b_src, dest, dest+d2b_dest);
src++;
dest++;
}
bytes_left -= lenN;
if(bytes_left <= 0) return int(dest - original_dest);
} else {
for(int i=0; i<lenN; i++) {
FILLFALSEuchar(dest+d2b_dest);
src++;
dest++;
}
}
src += 2 * sizeof_databus;
}
}
///////////////////////////////////////////////////////////////////////////////
// function set (1): Response
template<class DATAWORD> inline void
tlm_from_hostendian_word(tlm_generic_payload *txn, unsigned int sizeof_databus) {
if(txn->is_read()) {
tlm_endian_context *tc = txn->template get_extension<tlm_endian_context>();
sc_dt::uint64 b_mask = sizeof_databus - 1;
int d_mask = sizeof(DATAWORD) - 1;
int a_offset = static_cast<int>(tc->address & b_mask);
int len0 = (sizeof_databus - a_offset) & d_mask;
int lenN = sizeof(DATAWORD) - len0;
uchar *d_start = tc->data_ptr;
uchar *d_end = ptrdiff_t(tc->length) + d_start; // 64BITFIX probably redundant //
uchar *d = ptrdiff_t(((sizeof_databus - a_offset) & ~d_mask) + lenN) + d_start; // 64BITFIX probably redundant //
// iterate over transaction copying data qualified by byte-enables
if(tc->byte_enable == 0) {
loop_word1<DATAWORD, &copy_dbytrue1<DATAWORD>,
&copy_dbytrue1<uchar>, &no_b1<DATAWORD>, &no_b1<uchar> >(
tc->length, len0, lenN, sizeof_databus, d_start, d_end, d,
0, txn->get_data_ptr(), 0);
} else {
loop_word1<DATAWORD, &copy_dbyb1<DATAWORD>,
&copy_dbyb1<uchar>, &no_b1<DATAWORD>, &no_b1<uchar> >(
tc->length, len0, lenN, sizeof_databus, d_start, d_end, d,
tc->byte_enable - d_start + d, txn->get_data_ptr(), 0);
}
}
}
///////////////////////////////////////////////////////////////////////////////
// function set (1): Request
template<class DATAWORD> inline void
tlm_to_hostendian_word(tlm_generic_payload *txn, unsigned int sizeof_databus) {
tlm_endian_context *tc = establish_context(txn);
tc->from_f = &(tlm_from_hostendian_word<DATAWORD>);
tc->sizeof_databus = sizeof_databus;
sc_dt::uint64 b_mask = sizeof_databus - 1;
int d_mask = sizeof(DATAWORD) - 1;
sc_dt::uint64 a_aligned = txn->get_address() & ~b_mask;
int a_offset = static_cast<int>(txn->get_address() & b_mask);
int len0 = (sizeof_databus - a_offset) & d_mask;
int lenN = sizeof(DATAWORD) - len0;
uchar *d_start = txn->get_data_ptr();
uchar *d_end = ptrdiff_t(txn->get_data_length()) + d_start; // 64BITFIX probably redundant //
uchar *d = ptrdiff_t(((sizeof_databus - a_offset) & ~d_mask) + lenN) + d_start; // 64BITFIX probably redundant //
// create new data and byte enable buffers
int long_enough = txn->get_data_length() + 2 * sizeof_databus;
tc->establish_dbuf(long_enough);
uchar *new_data = tc->new_dbuf;
tc->establish_bebuf(long_enough);
uchar *new_be = tc->new_bebuf;
if(txn->is_read()) {
tc->data_ptr = d_start;
tc->address = txn->get_address();
tc->byte_enable = txn->get_byte_enable_ptr();
tc->length = txn->get_data_length();
if(txn->get_byte_enable_ptr() == 0) {
// iterate over transaction creating new byte enables from all-true
txn->set_data_length(loop_word1<DATAWORD, &true_b1<DATAWORD>,
&true_b1<uchar>, &false_b1<DATAWORD>, &false_b1<uchar> >(
txn->get_data_length(), len0, lenN, sizeof_databus,
d_start, d_end, d, 0, new_data, new_be));
} else {
// iterate over transaction copying byte enables
txn->set_data_length(loop_word1<DATAWORD, &copy_b1<DATAWORD>,
&copy_b1<uchar>, &false_b1<DATAWORD>, &false_b1<uchar> >(
txn->get_data_length(), len0, lenN, sizeof_databus, d_start, d_end,
d, txn->get_byte_enable_ptr() - d_start + d, new_data, new_be));
}
} else {
// WRITE
if(txn->get_byte_enable_ptr() == 0) {
// iterate over transaction copying data and creating new byte-enables
txn->set_data_length(loop_word1<DATAWORD, &copy_d1<DATAWORD>,
&copy_d1<uchar>, &false_b1<DATAWORD>, &false_b1<uchar> >(
txn->get_data_length(), len0, lenN, sizeof_databus,
d_start, d_end, d, 0, new_data, new_be));
} else {
// iterate over transaction copying data and byte-enables
txn->set_data_length(loop_word1<DATAWORD, &copy_db1<DATAWORD>,
&copy_db1<uchar>, &false_b1<DATAWORD>, &false_b1<uchar> >(
txn->get_data_length(), len0, lenN, sizeof_databus, d_start, d_end,
d, txn->get_byte_enable_ptr() - d_start + d, new_data, new_be));
}
}
txn->set_byte_enable_length(txn->get_data_length());
txn->set_streaming_width(txn->get_data_length());
txn->set_data_ptr(new_data);
txn->set_byte_enable_ptr(new_be);
txn->set_address(a_aligned);
}
///////////////////////////////////////////////////////////////////////////////
// function set (2): Utilities
template<class D> inline void copy_d2(D *src1, D *src2, D *dest1, D *dest2) {
*dest1 = *src1;
}
template<class D> inline void copy_db2(D *src1, D *src2, D *dest1, D *dest2) {
*dest1 = *src1;
*dest2 = *src2;
}
template<class D>
inline void copy_dbyb2(D *src1, D *src2, D *dest1, D *dest2) {
if(tlm_bool<D>(*src2)) *dest1 = *src1;
}
template<class D, void COPY(D *src1, D *src2, D *dest1, D *dest2)>
inline void loop_aligned2(D *src1, D *src2, D *dest1, D *dest2,
int words, int words_per_bus) {
ptrdiff_t src1to2 = (char *)src2 - (char *)src1; // 64BITFIX was int and operands were cast to int //
ptrdiff_t dest1to2 = (char *)dest2 - (char *)dest1; // 64BITFIX was int and operands were cast to int //
D *done = src1 + ptrdiff_t(words); // 64BITFIX //
D *bus_start = src1;
src1 += ptrdiff_t(words_per_bus - 1); // 64BITFIX //
while(true) {
COPY(src1, (D *)(src1to2+(char *)src1), dest1, (D *)(dest1to2+(char *)dest1)); // 64BITFIX //
dest1++;
if((--src1) < bus_start) {
bus_start += ptrdiff_t(words_per_bus); // 64BITFIX //
if(bus_start == done) break;
src1 = bus_start + ptrdiff_t(words_per_bus - 1); // 64BITFIX //
}
}
}
///////////////////////////////////////////////////////////////////////////////
// function set (2): Response
template<class DATAWORD> inline void
tlm_from_hostendian_aligned(tlm_generic_payload *txn, unsigned int sizeof_databus) {
int words_per_bus = sizeof_databus/sizeof(DATAWORD);
if(words_per_bus == 1) return;
int words = (txn->get_data_length())/sizeof(DATAWORD);
tlm_endian_context *tc = txn->template get_extension<tlm_endian_context>();
if(txn->get_byte_enable_ptr() == 0) {
// no byte enables
if(txn->is_read()) {
// RD without byte enables. Copy data to original buffer
loop_aligned2<DATAWORD, &copy_d2<DATAWORD> >(
(DATAWORD *)(txn->get_data_ptr()),
0, (DATAWORD *)(tc->data_ptr), 0, words, words_per_bus);
}
} else {
// byte enables present
if(txn->is_read()) {
// RD with byte enables. Copy data qualified by byte-enables
loop_aligned2<DATAWORD, &copy_dbyb2<DATAWORD> >(
(DATAWORD *)(txn->get_data_ptr()),
(DATAWORD *)(txn->get_byte_enable_ptr()),
(DATAWORD *)(tc->data_ptr), 0, words, words_per_bus);
}
}
}
///////////////////////////////////////////////////////////////////////////////
// function set (2): Request
template<class DATAWORD> inline void
tlm_to_hostendian_aligned(tlm_generic_payload *txn, unsigned int sizeof_databus) {
tlm_endian_context *tc = establish_context(txn);
tc->from_f = &(tlm_from_hostendian_aligned<DATAWORD>);
tc->sizeof_databus = sizeof_databus;
int words_per_bus = sizeof_databus/sizeof(DATAWORD);
if(words_per_bus == 1) return;
int words = (txn->get_data_length())/sizeof(DATAWORD);
DATAWORD *original_be = (DATAWORD *)(txn->get_byte_enable_ptr());
DATAWORD *original_data = (DATAWORD *)(txn->get_data_ptr());
// always allocate a new data buffer
tc->establish_dbuf(txn->get_data_length());
txn->set_data_ptr(tc->new_dbuf);
if(original_be == 0) {
// no byte enables
if(txn->is_write()) {
// WR no byte enables. Copy data
loop_aligned2<DATAWORD, &copy_d2<DATAWORD> >(original_data, 0,
(DATAWORD *)(txn->get_data_ptr()), 0,
words, words_per_bus);
} else {
// RD no byte enables. Save original data pointer
tc->data_ptr = (uchar *)original_data;
}
} else {
// byte enables present
// allocate a new buffer for them
tc->establish_bebuf(txn->get_data_length());
txn->set_byte_enable_ptr(tc->new_bebuf);
txn->set_byte_enable_length(txn->get_data_length());
if(txn->is_write()) {
// WR with byte enables. Copy data and BEs
loop_aligned2<DATAWORD, &copy_db2<DATAWORD> >(original_data, original_be,
(DATAWORD *)(txn->get_data_ptr()),
(DATAWORD *)(txn->get_byte_enable_ptr()), words, words_per_bus);
} else {
// RD with byte enables. Save original data pointer
tc->data_ptr = (uchar *)original_data;
// Copy byte enables to new buffer
loop_aligned2<DATAWORD, &copy_d2<DATAWORD> >(original_be, 0,
(DATAWORD *)(txn->get_byte_enable_ptr()), 0,
words, words_per_bus);
}
}
}
///////////////////////////////////////////////////////////////////////////////
// function set (3): Response
template<class DATAWORD> inline void
tlm_from_hostendian_single(tlm_generic_payload *txn, unsigned int sizeof_databus) {
// nothing needs to be done here
}
///////////////////////////////////////////////////////////////////////////////
// function set (3): Request
template<class DATAWORD> inline void
tlm_to_hostendian_single(tlm_generic_payload *txn, unsigned int sizeof_databus) {
tlm_endian_context *tc = establish_context(txn);
tc->from_f = &(tlm_from_hostendian_single<DATAWORD>);
tc->sizeof_databus = sizeof_databus;
// only need to change the address, always safe to work in-place
sc_dt::uint64 mask = sizeof_databus-1;
sc_dt::uint64 a = txn->get_address();
txn->set_address((a & ~mask) |
(sizeof_databus - (a & mask) - sizeof(DATAWORD)));
}
///////////////////////////////////////////////////////////////////////////////
// helper function which works for all responses
inline void tlm_from_hostendian(tlm_generic_payload *txn) {
tlm_endian_context *tc = txn->get_extension<tlm_endian_context>();
(*(tc->from_f))(txn, tc->sizeof_databus);
}
#ifndef TLM_END_CONV_DONT_UNDEF_UCHAR
#undef uchar
#endif
} // namespace tlm
#endif // multiple-inclusion protection

View File

@@ -0,0 +1,29 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_GENERIC_PAYLOAD_H__
#define __TLM_GENERIC_PAYLOAD_H__
#include "tlm_core/tlm_2/tlm_generic_payload/tlm_helpers.h"
#include "tlm_core/tlm_2/tlm_generic_payload/tlm_phase.h"
#include "tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h"
#include "tlm_core/tlm_2/tlm_generic_payload/tlm_endian_conv.h"
#endif

View File

@@ -0,0 +1,402 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
// 12-Jan-2009 John Aynsley Bug fix. has_mm() and get_ref_count() should both be const
// 23-Mar-2009 John Aynsley Add method update_original_from()
// 20-Apr-2009 John Aynsley Bug fix for 64-bit machines: unsigned long int -> unsigned int
// 5-May-2011 JA and Philipp Hartmann Add tlm_gp_option, set_gp_option, get_gp_option
// 11-May-2011 John Aynsley Add run-time check to release()
#ifndef TLM_CORE_TLM2_TLM_GP_H_INCLUDED_
#define TLM_CORE_TLM2_TLM_GP_H_INCLUDED_
#include "sysc/kernel/sc_cmnhdr.h" // SC_API
#include "sysc/utils/sc_report.h" // sc_assert
#include "sysc/datatypes/int/sc_nbdefs.h" // sc_dt::uint64
#include "tlm_core/tlm_2/tlm_generic_payload/tlm_array.h"
#include <typeinfo> // std::type_info
namespace tlm {
class tlm_generic_payload;
class tlm_mm_interface {
public:
virtual void free(tlm_generic_payload*) = 0;
virtual ~tlm_mm_interface() {}
};
//---------------------------------------------------------------------------
// Classes and helpers for the extension mechanism
//---------------------------------------------------------------------------
// Helper function:
SC_API unsigned int max_num_extensions();
// This class can be used for storing pointers to the extension classes, used
// in tlm_generic_payload:
class SC_API tlm_extension_base
{
public:
virtual tlm_extension_base* clone() const = 0;
virtual void free() { delete this; }
virtual void copy_from(tlm_extension_base const &) = 0;
protected:
virtual ~tlm_extension_base() {}
static unsigned int register_extension(const std::type_info&);
};
// Base class for all extension classes, derive your extension class in
// the following way:
// class my_extension : public tlm_extension<my_extension> { ...
// This triggers proper extension registration during C++ static
// contruction time. my_extension::ID will hold the unique index in the
// tlm_generic_payload::m_extensions array.
template <typename T>
class tlm_extension : public tlm_extension_base
{
public:
virtual tlm_extension_base* clone() const = 0;
virtual void copy_from(tlm_extension_base const &ext) = 0;
virtual ~tlm_extension() {}
const static unsigned int ID;
};
template <typename T>
const unsigned int tlm_extension<T>::ID
= tlm_extension_base::register_extension(typeid(T));
//---------------------------------------------------------------------------
// enumeration types
//---------------------------------------------------------------------------
enum tlm_command {
TLM_READ_COMMAND,
TLM_WRITE_COMMAND,
TLM_IGNORE_COMMAND
};
enum tlm_response_status {
TLM_OK_RESPONSE = 1,
TLM_INCOMPLETE_RESPONSE = 0,
TLM_GENERIC_ERROR_RESPONSE = -1,
TLM_ADDRESS_ERROR_RESPONSE = -2,
TLM_COMMAND_ERROR_RESPONSE = -3,
TLM_BURST_ERROR_RESPONSE = -4,
TLM_BYTE_ENABLE_ERROR_RESPONSE = -5
};
enum tlm_gp_option {
TLM_MIN_PAYLOAD,
TLM_FULL_PAYLOAD,
TLM_FULL_PAYLOAD_ACCEPTED
};
#define TLM_BYTE_DISABLED 0x0
#define TLM_BYTE_ENABLED 0xff
//---------------------------------------------------------------------------
// The generic payload class:
//---------------------------------------------------------------------------
SC_API_TEMPLATE_DECL_ tlm_array<tlm_extension_base*>;
class SC_API tlm_generic_payload {
public:
//---------------
// Constructors
//---------------
// Default constructor
tlm_generic_payload();
explicit tlm_generic_payload(tlm_mm_interface* mm);
void acquire() { sc_assert(m_mm != 0); m_ref_count++; }
void release() {
sc_assert(m_mm != 0 && m_ref_count > 0);
if (--m_ref_count==0)
m_mm->free(this);
}
int get_ref_count() const { return m_ref_count; }
void set_mm(tlm_mm_interface* mm) { m_mm = mm; }
bool has_mm() const { return m_mm != 0; }
void reset();
private:
//disabled copy ctor and assignment operator.
tlm_generic_payload(const tlm_generic_payload& x) /* = delete */;
tlm_generic_payload& operator= (const tlm_generic_payload& x) /* = delete */;
public:
// non-virtual deep-copying of the object
void deep_copy_from(const tlm_generic_payload & other);
// 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_generic_payload & other,
bool use_byte_enable_on_read = true);
void update_extensions_from(const tlm_generic_payload & other);
// 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();
//--------------
// Destructor
//--------------
virtual ~tlm_generic_payload();
//----------------
// API (including setters & getters)
//---------------
// Command related method
bool is_read() const {return (m_command == TLM_READ_COMMAND);}
void set_read() {m_command = TLM_READ_COMMAND;}
bool is_write() const {return (m_command == TLM_WRITE_COMMAND);}
void set_write() {m_command = TLM_WRITE_COMMAND;}
tlm_command get_command() const {return m_command;}
void set_command(const tlm_command command) {m_command = command;}
// Address related methods
sc_dt::uint64 get_address() const {return m_address;}
void set_address(const sc_dt::uint64 address) {m_address = address;}
// Data related methods
unsigned char* get_data_ptr() const {return m_data;}
void set_data_ptr(unsigned char* data) {m_data = data;}
// Transaction length (in bytes) related methods
unsigned int get_data_length() const {return m_length;}
void set_data_length(const unsigned int length) {m_length = length;}
// Response status related methods
bool is_response_ok() const {return (m_response_status > 0);}
bool is_response_error() const {return (m_response_status <= 0);}
tlm_response_status get_response_status() const {return m_response_status;}
void set_response_status(const tlm_response_status response_status)
{m_response_status = response_status;}
std::string get_response_string() const;
// Streaming related methods
unsigned int get_streaming_width() const {return m_streaming_width;}
void set_streaming_width(const unsigned int streaming_width) {m_streaming_width = streaming_width; }
// Byte enable related methods
unsigned char* get_byte_enable_ptr() const {return m_byte_enable;}
void set_byte_enable_ptr(unsigned char* byte_enable){m_byte_enable = byte_enable;}
unsigned int get_byte_enable_length() const {return m_byte_enable_length;}
void set_byte_enable_length(const unsigned int byte_enable_length){m_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) { m_dmi = dmi_allowed; }
bool is_dmi_allowed() const { return m_dmi; }
// Use full set of attributes in DMI/debug?
tlm_gp_option get_gp_option() const { return m_gp_option; }
void set_gp_option( const tlm_gp_option gp_opt ) { m_gp_option = gp_opt; }
private:
/* --------------------------------------------------------------------- */
/* 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 m_address;
tlm_command m_command;
unsigned char* m_data;
unsigned int m_length;
tlm_response_status m_response_status;
bool m_dmi;
unsigned char* m_byte_enable;
unsigned int m_byte_enable_length;
unsigned int m_streaming_width;
tlm_gp_option m_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_extension_base* set_extension(unsigned int index,
tlm_extension_base* ext);
// Stick the pointer to an extension into the vector, return the
// previous value and schedule its release
template <typename T> T* set_auto_extension(T* ext)
{
return static_cast<T*>(set_auto_extension(T::ID, ext));
}
// non-templatized version with manual index:
tlm_extension_base* set_auto_extension(unsigned int index,
tlm_extension_base* ext);
// 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_extension_base* get_extension(unsigned int index) const;
//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);
// Non-templatized version with manual index
void release_extension(unsigned int index);
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();
private:
tlm_array<tlm_extension_base*> m_extensions;
tlm_mm_interface* m_mm;
unsigned int m_ref_count;
};
} // namespace tlm
#endif /* TLM_CORE_TLM2_TLM_GP_H_INCLUDED_ */

View File

@@ -0,0 +1,80 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
/* ---------------------------------------------------------------------------------------
@file tlm_helpers.h
@brief
Original Authors:
Charles Wilson, ESLX
--------------------------------------------------------------------------------------- */
#ifndef __TLM_HELPERS_H__
#define __TLM_HELPERS_H__
//#include <sys/param.h>
//#include <cstring>
namespace tlm {
enum tlm_endianness { TLM_UNKNOWN_ENDIAN, TLM_LITTLE_ENDIAN, TLM_BIG_ENDIAN };
inline tlm_endianness get_host_endianness(void)
{
static tlm_endianness host_endianness = TLM_UNKNOWN_ENDIAN;
if (host_endianness == TLM_UNKNOWN_ENDIAN) {
unsigned int number = 1;
unsigned char *p_msb_or_lsb = (unsigned char*)&number;
host_endianness = (p_msb_or_lsb[0] == 0) ? TLM_BIG_ENDIAN : TLM_LITTLE_ENDIAN;
}
return host_endianness;
}
inline bool host_has_little_endianness(void)
{
static tlm_endianness host_endianness = TLM_UNKNOWN_ENDIAN;
static bool host_little_endian = false;
if (host_endianness == TLM_UNKNOWN_ENDIAN) {
unsigned int number = 1;
unsigned char *p_msb_or_lsb = (unsigned char*)&number;
host_little_endian = (p_msb_or_lsb[0] == 0) ? false : true;
}
return host_little_endian;
}
inline bool has_host_endianness(tlm_endianness endianness)
{
if (host_has_little_endianness()) {
return endianness == TLM_LITTLE_ENDIAN;
} else {
return endianness == TLM_BIG_ENDIAN;
}
}
} // namespace tlm
#endif /* __TLM_HELPERS_H__ */

View File

@@ -0,0 +1,108 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef TLM_CORE_TLM2_TLM_PHASE_H_INCLUDED_
#define TLM_CORE_TLM2_TLM_PHASE_H_INCLUDED_
#include <string>
#include <iostream>
#include <typeinfo>
#include <vector>
#include "sysc/kernel/sc_cmnhdr.h" // SC_API
#include "sysc/kernel/sc_macros.h" // SC_CONCAT_HELPER_, SC_STRINGIFY_HELPER_
namespace tlm {
enum SC_API tlm_phase_enum
{
UNINITIALIZED_PHASE=0,
BEGIN_REQ=1,
END_REQ,
BEGIN_RESP,
END_RESP
};
class SC_API tlm_phase
{
public:
tlm_phase();
tlm_phase(unsigned int id); // TODO: should be dropped
tlm_phase(tlm_phase_enum standard);
tlm_phase& operator=(tlm_phase_enum standard);
operator unsigned int() const { return m_id; }
const char* get_name() const;
protected:
// register extended phase
tlm_phase( const std::type_info & type, const char* name );
private:
unsigned int m_id;
};
inline
tlm_phase::tlm_phase()
: m_id( UNINITIALIZED_PHASE )
{}
inline
tlm_phase::tlm_phase( tlm_phase_enum standard )
: m_id( standard )
{}
inline
tlm_phase& tlm_phase::operator=( tlm_phase_enum standard )
{
m_id = standard;
return *this;
}
inline
std::ostream& operator<<(std::ostream& s, const tlm_phase& p)
{
s << p.get_name();
return s;
}
#define TLM_DECLARE_EXTENDED_PHASE(name_arg) \
static class SC_CONCAT_HELPER_(tlm_phase_, name_arg) \
: public ::tlm::tlm_phase \
{ \
typedef SC_CONCAT_HELPER_(tlm_phase_, name_arg) this_type; \
public: \
SC_CONCAT_HELPER_(tlm_phase_, name_arg)() /* register extended phase */ \
: ::tlm::tlm_phase( typeid(*this), SC_STRINGIFY_HELPER_(name_arg) ) \
{} \
\
static const this_type& get_phase() /* needed only for IEEE 1666-2011 */ \
{ static this_type this_; return this_; } \
} \
const name_arg
// for backwards-compatibility
#define DECLARE_EXTENDED_PHASE( NameArg ) \
TLM_DECLARE_EXTENDED_PHASE( NameArg )
} // namespace tlm
#endif /* TLM_CORE_TLM2_TLM_PHASE_H_INCLUDED_ */
// Taf!

View File

@@ -0,0 +1,82 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef TLM_CORE_TLM2_TLM_GLOBAL_QUANTUM_H_INCLUDED_
#define TLM_CORE_TLM2_TLM_GLOBAL_QUANTUM_H_INCLUDED_
#include "sysc/kernel/sc_time.h"
namespace tlm {
//
// tlm_global_quantum class
//
// The global quantum is the maximum time an initiator can run ahead of
// SystemC time. All initiators should synchronize on timingpoints that
// are multiples of the global quantum value.
//
// sc_set_time_resolution can only be called before the first
// sc_time object is created. This means that after setting the
// global quantum it will not be possible to call sc_set_time_resolution.
// If sc_set_time_resolution must be called this must be done before
// the global quantum is set.
//
class SC_API tlm_global_quantum
{
public:
//
// Returns a reference to the tlm_global_quantum singleton
//
static tlm_global_quantum& instance();
public:
//
// Setter/getter for the global quantum
//
void set(const sc_core::sc_time& t)
{
m_global_quantum = t;
}
const sc_core::sc_time& get() const
{
return m_global_quantum;
}
//
// This function will calculate the maximum value for the next local
// quantum for an initiator. All initiators should synchronize on
// integer multiples of the global quantum value. The value for the
// local quantum of an initiator can be smaller, but should never be
// greater than the value returned by this method.
//
sc_core::sc_time compute_local_quantum();
protected:
tlm_global_quantum();
protected:
sc_core::sc_time m_global_quantum;
};
} // namespace tlm
#endif // TLM_CORE_TLM2_TLM_GLOBAL_QUANTUM_H_INCLUDED_

View File

@@ -0,0 +1,25 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef TLM_CORE_TLM2_TLM_QUANTUM_H_INCLUDED_
#define TLM_CORE_TLM2_TLM_QUANTUM_H_INCLUDED_
#include "tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.h"
#endif // TLM_CORE_TLM2_TLM_QUANTUM_H_INCLUDED_

View File

@@ -0,0 +1,56 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef TLM_CORE_TLM_BASE_SOCKET_IF_H_INCLUDED_
#define TLM_CORE_TLM_BASE_SOCKET_IF_H_INCLUDED_
#include "sysc/utils/sc_typeindex.h"
namespace tlm {
enum tlm_socket_category
{
TLM_UNKNOWN_SOCKET = 0,
TLM_INITIATOR_SOCKET = 0x1,
TLM_TARGET_SOCKET = 0x2,
TLM_MULTI_SOCKET = 0x10,
TLM_MULTI_INITIATOR_SOCKET = TLM_INITIATOR_SOCKET | TLM_MULTI_SOCKET,
TLM_MULTI_TARGET_SOCKET = TLM_TARGET_SOCKET | TLM_MULTI_SOCKET
};
class tlm_base_socket_if
{
public:
virtual sc_core::sc_port_base & get_port_base() = 0;
virtual sc_core::sc_port_base const & get_port_base() const = 0;
virtual sc_core::sc_export_base & get_export_base() = 0;
virtual sc_core::sc_export_base const & get_export_base() const = 0;
virtual unsigned int get_bus_width() const = 0;
virtual sc_core::sc_type_index get_protocol_types() const = 0;
virtual tlm_socket_category get_socket_category() const = 0;
protected:
virtual ~tlm_base_socket_if() {}
};
} // namespace tlm
#endif // TLM_CORE_TLM_BASE_SOCKET_IF_H_INCLUDED_

View File

@@ -0,0 +1,240 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef TLM_CORE_TLM_INITIATOR_SOCKET_H_INCLUDED_
#define TLM_CORE_TLM_INITIATOR_SOCKET_H_INCLUDED_
#include "tlm_core/tlm_2/tlm_sockets/tlm_base_socket_if.h"
#include "tlm_core/tlm_2/tlm_2_interfaces/tlm_fw_bw_ifs.h"
#if defined(__clang__) || \
(defined(__GNUC__) && ((__GNUC__ * 1000 + __GNUC_MINOR__) >= 4006))
// ignore warning about deliberately hidden "bind()" overloads
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Woverloaded-virtual"
#endif
namespace tlm {
template <unsigned int BUSWIDTH = 32,
typename FW_IF = tlm_fw_transport_if<>,
typename BW_IF = tlm_bw_transport_if<> >
class tlm_base_initiator_socket_b
{
public:
virtual ~tlm_base_initiator_socket_b() {}
virtual sc_core::sc_port_b<FW_IF> & get_base_port() = 0;
virtual sc_core::sc_port_b<FW_IF> const & get_base_port() const = 0;
virtual BW_IF & get_base_interface() = 0;
virtual BW_IF const & get_base_interface() const = 0;
virtual sc_core::sc_export<BW_IF> & get_base_export() = 0;
virtual sc_core::sc_export<BW_IF> const & get_base_export() const = 0;
};
template <unsigned int BUSWIDTH,
typename FW_IF,
typename BW_IF> class tlm_base_target_socket_b;
template <unsigned int BUSWIDTH,
typename FW_IF,
typename BW_IF,
int N,
sc_core::sc_port_policy POL> class tlm_base_target_socket;
template <unsigned int BUSWIDTH = 32,
typename FW_IF = tlm_fw_transport_if<>,
typename BW_IF = tlm_bw_transport_if<>,
int N = 1,
sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
class tlm_base_initiator_socket : public tlm_base_socket_if,
public tlm_base_initiator_socket_b<BUSWIDTH, FW_IF, BW_IF>,
public sc_core::sc_port<FW_IF, N, POL>
{
public:
typedef FW_IF fw_interface_type;
typedef BW_IF bw_interface_type;
typedef sc_core::sc_port<fw_interface_type,N,POL> port_type;
typedef sc_core::sc_export<bw_interface_type> export_type;
typedef tlm_base_target_socket_b<BUSWIDTH,
fw_interface_type,
bw_interface_type> base_target_socket_type;
typedef tlm_base_initiator_socket_b<BUSWIDTH,
fw_interface_type,
bw_interface_type> base_type;
template <unsigned int, typename, typename, int, sc_core::sc_port_policy>
friend class tlm_base_target_socket;
public:
tlm_base_initiator_socket()
: port_type(sc_core::sc_gen_unique_name("tlm_base_initiator_socket"))
, m_export(sc_core::sc_gen_unique_name("tlm_base_initiator_socket_export"))
{
}
explicit tlm_base_initiator_socket(const char* name)
: port_type(name)
, m_export(sc_core::sc_gen_unique_name((std::string(name) + "_export").c_str()))
{
}
virtual const char* kind() const
{
return "tlm_base_initiator_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
(get_base_port())(s.get_base_interface());
// target.port -> initiator.export
(s.get_base_port())(get_base_interface());
}
void operator() (base_target_socket_type& s)
{
bind(s);
}
//
// Bind initiator socket to initiator socket (hierarchical bind)
// - Binds both the export and the port
//
virtual void bind(base_type& s)
{
// port
(get_base_port())(s.get_base_port());
// export
(s.get_base_export())(get_base_export());
}
void operator() (base_type& s)
{
bind(s);
}
//
// Bind interface to socket
// - Binds the interface to the export of this socket
//
virtual void bind(bw_interface_type& ifs)
{
(get_base_export())(ifs);
}
void operator() (bw_interface_type& s)
{
bind(s);
}
// Implementation of tlm_base_socket_if functions
virtual sc_core::sc_port_base & get_port_base()
{ return *this; }
virtual sc_core::sc_port_base const & get_port_base() const
{ return *this; }
virtual sc_core::sc_export_base & get_export_base()
{ return m_export; }
virtual sc_core::sc_export_base const & get_export_base() const
{ return m_export; }
virtual unsigned int get_bus_width() const
{ return BUSWIDTH; }
virtual tlm_socket_category get_socket_category() const
{ return TLM_INITIATOR_SOCKET; }
// Implementation of tlm_base_target_socket_b functions
virtual sc_core::sc_port_b<FW_IF> & get_base_port()
{ return *this; }
virtual sc_core::sc_port_b<FW_IF> const & get_base_port() const
{ return *this; }
virtual BW_IF & get_base_interface()
{ return m_export; }
virtual BW_IF const & get_base_interface() const
{ return m_export; }
virtual sc_core::sc_export<BW_IF> & get_base_export()
{ return m_export; }
virtual sc_core::sc_export<BW_IF> const & get_base_export() const
{ return m_export; }
protected:
export_type m_export;
};
//
// Convenience socket classes
//
template <unsigned int BUSWIDTH = 32,
typename TYPES = tlm_base_protocol_types,
int N = 1,
sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
class tlm_initiator_socket :
public tlm_base_initiator_socket<BUSWIDTH,
tlm_fw_transport_if<TYPES>,
tlm_bw_transport_if<TYPES>,
N, POL>
{
public:
tlm_initiator_socket() :
tlm_base_initiator_socket<BUSWIDTH,
tlm_fw_transport_if<TYPES>,
tlm_bw_transport_if<TYPES>,
N, POL>()
{
}
explicit tlm_initiator_socket(const char* name) :
tlm_base_initiator_socket<BUSWIDTH,
tlm_fw_transport_if<TYPES>,
tlm_bw_transport_if<TYPES>,
N, POL>(name)
{
}
virtual const char* kind() const
{
return "tlm_initiator_socket";
}
virtual sc_core::sc_type_index get_protocol_types() const
{
return typeid(TYPES);
}
};
} // namespace tlm
#if defined(__clang__) || \
(defined(__GNUC__) && ((__GNUC__ * 1000 + __GNUC_MINOR__) >= 4006))
#pragma GCC diagnostic pop
#endif
#endif // TLM_CORE_TLM_INITIATOR_SOCKET_H_INCLUDED_

View File

@@ -0,0 +1,26 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef __TLM_SOCKETS_H__
#define __TLM_SOCKETS_H__
#include "tlm_core/tlm_2/tlm_sockets/tlm_initiator_socket.h"
#include "tlm_core/tlm_2/tlm_sockets/tlm_target_socket.h"
#endif /* __TLM_SOCKETS_H__ */

View File

@@ -0,0 +1,255 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef TLM_CORE_TLM_TARGET_SOCKET_H_INCLUDED_
#define TLM_CORE_TLM_TARGET_SOCKET_H_INCLUDED_
#include "tlm_core/tlm_2/tlm_sockets/tlm_base_socket_if.h"
#include "tlm_core/tlm_2/tlm_2_interfaces/tlm_fw_bw_ifs.h"
namespace tlm {
template <unsigned int BUSWIDTH = 32,
typename FW_IF = tlm_fw_transport_if<>,
typename BW_IF = tlm_bw_transport_if<> >
class tlm_base_target_socket_b
{
public:
virtual ~tlm_base_target_socket_b() {}
virtual sc_core::sc_port_b<BW_IF> & get_base_port() = 0;
virtual sc_core::sc_export<FW_IF> & get_base_export() = 0;
virtual FW_IF & get_base_interface() = 0;
};
template <unsigned int BUSWIDTH,
typename FW_IF,
typename BW_IF> class tlm_base_initiator_socket_b;
template <unsigned int BUSWIDTH,
typename FW_IF,
typename BW_IF,
int N,
sc_core::sc_port_policy POL> class tlm_base_initiator_socket;
template <unsigned int BUSWIDTH = 32,
typename FW_IF = tlm_fw_transport_if<>,
typename BW_IF = tlm_bw_transport_if<>,
int N = 1,
sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
class tlm_base_target_socket : public tlm_base_socket_if,
public tlm_base_target_socket_b<BUSWIDTH, FW_IF, BW_IF>,
public sc_core::sc_export<FW_IF>
{
public:
typedef FW_IF fw_interface_type;
typedef BW_IF bw_interface_type;
typedef sc_core::sc_port<bw_interface_type, N , POL> port_type;
typedef sc_core::sc_export<fw_interface_type> export_type;
typedef tlm_base_initiator_socket_b<BUSWIDTH,
fw_interface_type,
bw_interface_type> base_initiator_socket_type;
typedef tlm_base_target_socket_b<BUSWIDTH,
fw_interface_type,
bw_interface_type> base_type;
template <unsigned int, typename, typename, int, sc_core::sc_port_policy>
friend class tlm_base_initiator_socket;
public:
tlm_base_target_socket()
: export_type(sc_core::sc_gen_unique_name("tlm_base_target_socket"))
, m_port(sc_core::sc_gen_unique_name("tlm_base_target_socket_port"))
{
}
explicit tlm_base_target_socket(const char* name)
: export_type(name)
, m_port(sc_core::sc_gen_unique_name((std::string(name) + "_port").c_str()))
{
}
virtual const char* kind() const
{
return "tlm_base_target_socket";
}
//
// Bind target socket to initiator 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_initiator_socket_type& s)
{
// initiator.port -> target.export
(s.get_base_port())(get_base_interface());
// target.port -> initiator.export
get_base_port()(s.get_base_interface());
}
void operator() (base_initiator_socket_type& s)
{
bind(s);
}
//
// Bind target socket to target socket (hierarchical bind)
// - Binds both the export and the port
//
virtual void bind(base_type& s)
{
// export
(get_base_export())(s.get_base_export());
// port
(s.get_base_port())(get_base_port());
}
void operator() (base_type& s)
{
bind(s);
}
//
// Bind interface to socket
// - Binds the interface to the export
//
virtual void bind(fw_interface_type& ifs)
{
export_type* exp = &get_base_export();
if( this == exp ) {
export_type::bind( ifs ); // non-virtual function call
} else {
exp->bind( ifs );
}
}
void operator() (fw_interface_type& s)
{
bind(s);
}
//
// Forward to 'size()' of port class
//
int size() const
{
return m_port.size();
}
//
// Forward to 'operator->()' of port class
//
bw_interface_type* operator->()
{
return m_port.operator->();
}
//
// Forward to 'operator[]()' of port class
//
bw_interface_type* operator[](int i)
{
return m_port.operator[](i);
}
// Implementation of tlm_base_socket_if functions
virtual sc_core::sc_port_base & get_port_base()
{ return m_port; }
virtual sc_core::sc_port_base const & get_port_base() const
{ return m_port; }
virtual sc_core::sc_export_base & get_export_base()
{ return *this; }
virtual sc_core::sc_export_base const & get_export_base() const
{ return *this; }
virtual unsigned int get_bus_width() const
{ return BUSWIDTH; }
virtual tlm_socket_category get_socket_category() const
{ return TLM_TARGET_SOCKET; }
// Implementation of tlm_base_target_socket_b functions
virtual sc_core::sc_port_b<BW_IF> & get_base_port()
{ return m_port; }
virtual sc_core::sc_port_b<BW_IF> const & get_base_port() const
{ return m_port; }
virtual FW_IF & get_base_interface()
{ return *this; }
virtual FW_IF const & get_base_interface() const
{ return *this; }
virtual sc_core::sc_export<FW_IF> & get_base_export()
{ return *this; }
virtual sc_core::sc_export<FW_IF> const & get_base_export() const
{ return *this; }
protected:
port_type m_port;
};
//
// Convenience blocking and non-blocking socket classes
//
template <unsigned int BUSWIDTH = 32,
typename TYPES = tlm_base_protocol_types,
int N = 1,
sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
class tlm_target_socket :
public tlm_base_target_socket <BUSWIDTH,
tlm_fw_transport_if<TYPES>,
tlm_bw_transport_if<TYPES>,
N, POL>
{
public:
tlm_target_socket() :
tlm_base_target_socket<BUSWIDTH,
tlm_fw_transport_if<TYPES>,
tlm_bw_transport_if<TYPES>,
N, POL>()
{
}
explicit tlm_target_socket(const char* name) :
tlm_base_target_socket<BUSWIDTH,
tlm_fw_transport_if<TYPES>,
tlm_bw_transport_if<TYPES>,
N, POL>(name)
{
}
virtual const char* kind() const
{
return "tlm_target_socket";
}
virtual sc_core::sc_type_index get_protocol_types() const
{
return typeid(TYPES);
}
};
} // namespace tlm
#endif // TLM_CORE_TLM_TARGET_SOCKET_H_INCLUDED_

View File

@@ -0,0 +1,180 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
/* ---------------------------------------------------------------------------------------
@file tlm_version.h
@brief TLM version header
Original Author:
Charles Wilson, XtremeEDA Corporation
@description
This header contains preprocessor and compiler symbols to allow for the determination
of the TLM version information. This conforms to IEEE 1666-2005 section 8.5.5 - 8.5.7
.
The following are provided:
.
preprocessor: TLM_VERSION_MAJOR numeric
TLM_VERSION_MINOR numeric
TLM_VERSION_PATCH numeric
TLM_VERSION_ORIGINATOR string ([A-Z][a-z][0-9]_)
TLM_VERSION_RELEASE_DATE ISO8601 date (YYYYMMDD)
TLM_VERSION_PRERELEASE string ([A-Z][a-z][0-9]_)
TLM_IS_PRERELEASE bool (1,0)
TLM_VERSION string {2.0.0_DR3-TLMWG}
TLM_COPYRIGHT string
.
compiler: tlm_version_major const unsigned int
tlm_version_minor const unsigned int
tlm_version_patch const unsigned int
tlm_version_originator const std::string
tlm_version_release_date const std::string
tlm_version_prerelease const std::string
tlm_is_prerelease const bool
tlm_version const string
tlm_copyright const string
.
accessors: inline const char* tlm_release (void)
inline const char* tlm_version (void)
inline const char* tlm_copyright (void)
--------------------------------------------------------------------------------------- */
#ifndef __TLM_VERSION_H__
#define __TLM_VERSION_H__
namespace tlm
{
#define TLM_VERSION_MAJOR 2 ///< version major level ( numeric )
#define TLM_VERSION_MINOR 0 ///< version minor level ( numeric )
#define TLM_VERSION_PATCH 4 ///< version patch level ( numeric )
#define TLM_VERSION_ORIGINATOR "Accellera" ///< TLM creator string
#define TLM_VERSION_SEPARATOR "." ///< version string separator
#define TLM_IS_PRERELEASE 0 ///< pre-release flag ( 1 / 0 )
#if TLM_IS_PRERELEASE
# define TLM_VERSION_PRERELEASE "pub_rev" ///< pre-release version string
#else
# define TLM_VERSION_PRERELEASE "" ///< pre-release version string
#endif
#define TLM_VERSION_RELEASE_YEAR "2017" ///< release year ( YYYY )
#define TLM_VERSION_RELEASE_MONTH "10" ///< release month ( MM )
#define TLM_VERSION_RELEASE_DAY "12" ///< release day ( DD )
#define TLM_COPYRIGHT \
"Copyright (c) 1996-" TLM_VERSION_RELEASE_YEAR " by all Contributors\n" \
"ALL RIGHTS RESERVED"
/************************** do not modify below this line *******************************/
/******************************* preprocessor symbols ***********************************/
#define TLM_VERSION_RELEASE_DATE TLM_VERSION_RELEASE_YEAR \
TLM_VERSION_RELEASE_MONTH \
TLM_VERSION_RELEASE_DAY
#define TLM_VERSION_STR(x) TLM_VERSION_STR_HELPER(x)
#define TLM_VERSION_STR_HELPER(x) #x
#define TLM_VERSION_STRING_MAJOR TLM_VERSION_STR(TLM_VERSION_MAJOR)
#define TLM_VERSION_STRING_MINOR TLM_VERSION_STR(TLM_VERSION_MINOR)
#define TLM_VERSION_STRING_PATCH TLM_VERSION_STR(TLM_VERSION_PATCH)
#define TLM_VERSION_STRING_MMP TLM_VERSION_STRING_MAJOR TLM_VERSION_SEPARATOR \
TLM_VERSION_STRING_MINOR TLM_VERSION_SEPARATOR \
TLM_VERSION_STRING_PATCH
#define TLM_VERSION_STRING_PRE_START "_"
#define TLM_VERSION_STRING_PRE_END "-"
#if ( TLM_IS_PRERELEASE == 1 )
#define TLM_VERSION_STRING_PRERELEASE TLM_VERSION_PRERELEASE
#define TLM_VERSION_STRING_RELEASE_DATE ""
#else /* TLM_IS_PRERELEASE == 1 */
#define TLM_VERSION_STRING_PRERELEASE ""
#define TLM_VERSION_STRING_RELEASE_DATE TLM_VERSION_RELEASE_DATE
#endif /* TLM_IS_PRERELEASE == 1 */
#define TLM_VERSION_STRING TLM_VERSION_STRING_MMP \
TLM_VERSION_STRING_PRE_START \
TLM_VERSION_STRING_PRERELEASE \
TLM_VERSION_STRING_PRE_END \
TLM_VERSION_ORIGINATOR
#define TLM_VERSION_STRING_2 "TLM " \
TLM_VERSION_STRING_MMP \
" --- " \
TLM_VERSION_RELEASE_YEAR \
"-" \
TLM_VERSION_RELEASE_MONTH \
"-" \
TLM_VERSION_RELEASE_DAY
#define TLM_VERSION TLM_VERSION_STRING
/********************************* compiler symbols **************************************/
const unsigned int tlm_version_major ( TLM_VERSION_MAJOR );
const unsigned int tlm_version_minor ( TLM_VERSION_MINOR );
const unsigned int tlm_version_patch ( TLM_VERSION_PATCH );
const bool tlm_is_prerelease ( TLM_IS_PRERELEASE );
const std::string tlm_version_string ( TLM_VERSION_STRING );
const std::string tlm_version_originator ( TLM_VERSION_ORIGINATOR );
const std::string tlm_version_prerelease ( TLM_VERSION_PRERELEASE );
const std::string tlm_version_release_date ( TLM_VERSION_STRING_RELEASE_DATE );
const std::string tlm_copyright_string ( TLM_COPYRIGHT );
const std::string tlm_version_string_2 ( TLM_VERSION_STRING_2 );
inline const char*
tlm_release
( void
)
{
return tlm_version_string.c_str ();
}
inline const char*
tlm_version
( void
)
{
return tlm_version_string_2.c_str ();
}
inline const char*
tlm_copyright
( void
)
{
return tlm_copyright_string.c_str ();
}
} // namespace tlm
#endif /* __TLM_VERSION_H__ */

View File

@@ -0,0 +1,62 @@
## ****************************************************************************
##
## Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
## more contributor license agreements. See the NOTICE file distributed
## with this work for additional information regarding copyright ownership.
## Accellera licenses this file to you under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with the
## License. You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
## implied. See the License for the specific language governing
## permissions and limitations under the License.
##
## ****************************************************************************
##
## src/tlm_utils/Makefile.am --
## Process this file with automake to produce a Makefile.in file.
##
## Original Author: Alan Fitch, Doulos, 2012-03-10
##
## ****************************************************************************
##
## MODIFICATION LOG - modifiers, enter your name, affiliation, date and
## changes you are making here.
##
## Name, Affiliation, Date:
## Description of Modification:
##
## ****************************************************************************
include $(top_srcdir)/config/Make-rules.sysc
H_FILES = \
convenience_socket_bases.h \
instance_specific_extensions.h \
instance_specific_extensions_int.h \
multi_passthrough_initiator_socket.h \
multi_passthrough_target_socket.h \
multi_socket_bases.h \
passthrough_target_socket.h \
peq_with_cb_and_phase.h \
peq_with_get.h \
simple_initiator_socket.h \
simple_target_socket.h \
tlm_quantumkeeper.h
CXX_FILES = \
convenience_socket_bases.cpp \
instance_specific_extensions.cpp
EXTRA_DIST += \
README.txt
localincludedir = $(includedir)/tlm_utils
nobase_localinclude_HEADERS = $(H_FILES)
noinst_LTLIBRARIES = libtlm_utils.la
libtlm_utils_la_SOURCES = $(NO_H_FILES) $(CXX_FILES)

View File

@@ -0,0 +1,731 @@
# Makefile.in generated by automake 1.14 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# top-level SystemC include directory is added in Make-rules.{sysc,examples}
# build flags
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
DIST_COMMON = $(top_srcdir)/config/Make-rules.sysc \
$(top_srcdir)/config/Make-rules.common $(srcdir)/Makefile.in \
$(srcdir)/Makefile.am $(top_srcdir)/config/depcomp \
$(nobase_localinclude_HEADERS)
@WANT_DEBUG_TRUE@am__append_1 = $(DEBUG_CXXFLAGS)
@WANT_DEBUG_TRUE@am__append_2 = $(DEBUG_CXXFLAGS)
@WANT_DEBUG_TRUE@am__append_3 = $(DEBUG_CXXFLAGS)
@WANT_OPTIMIZE_TRUE@am__append_4 = $(OPT_CXXFLAGS)
@WANT_OPTIMIZE_TRUE@am__append_5 = $(OPT_CXXFLAGS)
# either for async_update locking or pthread processes
@USES_PTHREADS_LIB_TRUE@am__append_6 = $(PTHREAD_CFLAGS)
@USES_PTHREADS_LIB_TRUE@am__append_7 = $(PTHREAD_CFLAGS)
@USES_PTHREADS_LIB_TRUE@am__append_8 = $(PTHREAD_LIBS)
@DISABLE_ASYNC_UPDATES_TRUE@am__append_9 = -DSC_DISABLE_ASYNC_UPDATES
@ENABLE_CALLBACKS_TRUE@am__append_10 = -DSC_ENABLE_SIMULATION_PHASE_CALLBACKS
@ENABLE_CALLBACKS_TRACING_TRUE@am__append_11 = -DSC_ENABLE_SIMULATION_PHASE_CALLBACKS_TRACING
@WANT_PTHREADS_THREADS_TRUE@am__append_12 = -DSC_USE_PTHREADS
@DISABLE_VCD_SCOPES_TRUE@am__append_13 = -DSC_DISABLE_VCD_SCOPES
subdir = src/tlm_utils
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/config/ax_check_define.m4 \
$(top_srcdir)/config/ax_pthread.m4 \
$(top_srcdir)/config/libtool.m4 \
$(top_srcdir)/config/ltoptions.m4 \
$(top_srcdir)/config/ltsugar.m4 \
$(top_srcdir)/config/ltversion.m4 \
$(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libtlm_utils_la_LIBADD =
am__objects_1 = convenience_socket_bases.lo \
instance_specific_extensions.lo
am_libtlm_utils_la_OBJECTS = $(am__objects_1)
libtlm_utils_la_OBJECTS = $(am_libtlm_utils_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
AM_V_CXX = $(am__v_CXX_@AM_V@)
am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
am__v_CXX_0 = @echo " CXX " $@;
am__v_CXX_1 =
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
SOURCES = $(libtlm_utils_la_SOURCES)
DIST_SOURCES = $(libtlm_utils_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(localincludedir)"
HEADERS = $(nobase_localinclude_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCAS = @CCAS@
CCASDEPMODE = @CCASDEPMODE@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEBUG_CXXFLAGS = @DEBUG_CXXFLAGS@
DEFS = $(PKGCONFIG_DEFINES) $(EXTRA_DEFINES)
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
EXPLICIT_LPTHREAD = @EXPLICIT_LPTHREAD@
EXTRA_ASFLAGS = @EXTRA_ASFLAGS@
EXTRA_CFLAGS = @EXTRA_CFLAGS@
EXTRA_CXXFLAGS = @EXTRA_CXXFLAGS@
EXTRA_LDFLAGS = @EXTRA_LDFLAGS@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LDFLAG_RPATH = @LDFLAG_RPATH@
LIBCONFIG_DEFINES = @LIBCONFIG_DEFINES@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIB_ARCH_SUFFIX = @LIB_ARCH_SUFFIX@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPT_CXXFLAGS = @OPT_CXXFLAGS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKGCONFIG_CFLAGS = @PKGCONFIG_CFLAGS@
PKGCONFIG_DEFINES = @PKGCONFIG_DEFINES@
PKGCONFIG_LDPRIV = @PKGCONFIG_LDPRIV@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
QT_ARCH = @QT_ARCH@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TARGET_ARCH = @TARGET_ARCH@
TLM_PACKAGE_VERSION = @TLM_PACKAGE_VERSION@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
examplesdir = @examplesdir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libarchdir = @libarchdir@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
rootdocdir = @rootdocdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CPPFLAGS = -I$(top_srcdir)/src
AM_CFLAGS = $(EXTRA_CFLAGS) $(am__append_2) $(am__append_5) \
$(am__append_7)
AM_CXXFLAGS = $(EXTRA_CXXFLAGS) $(am__append_1) $(am__append_4) \
$(am__append_6)
AM_CCASFLAGS = $(EXTRA_ASFLAGS) $(am__append_3)
AM_LDFLAGS = $(EXTRA_LDFLAGS) $(am__append_8)
# always add fix-point support
EXTRA_DEFINES = -DSC_INCLUDE_FX -DSC_BUILD $(am__append_9) \
$(am__append_10) $(am__append_11) $(am__append_12) \
$(am__append_13)
# initialize some useful variables (filled later)
CLEANFILES =
EXTRA_DIST = README.txt
H_FILES = \
convenience_socket_bases.h \
instance_specific_extensions.h \
instance_specific_extensions_int.h \
multi_passthrough_initiator_socket.h \
multi_passthrough_target_socket.h \
multi_socket_bases.h \
passthrough_target_socket.h \
peq_with_cb_and_phase.h \
peq_with_get.h \
simple_initiator_socket.h \
simple_target_socket.h \
tlm_quantumkeeper.h
CXX_FILES = \
convenience_socket_bases.cpp \
instance_specific_extensions.cpp
localincludedir = $(includedir)/tlm_utils
nobase_localinclude_HEADERS = $(H_FILES)
noinst_LTLIBRARIES = libtlm_utils.la
libtlm_utils_la_SOURCES = $(NO_H_FILES) $(CXX_FILES)
all: all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/config/Make-rules.sysc $(top_srcdir)/config/Make-rules.common $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/tlm_utils/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/tlm_utils/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_srcdir)/config/Make-rules.sysc $(top_srcdir)/config/Make-rules.common:
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
libtlm_utils.la: $(libtlm_utils_la_OBJECTS) $(libtlm_utils_la_DEPENDENCIES) $(EXTRA_libtlm_utils_la_DEPENDENCIES)
$(AM_V_CXXLD)$(CXXLINK) $(libtlm_utils_la_OBJECTS) $(libtlm_utils_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/convenience_socket_bases.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/instance_specific_extensions.Plo@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-nobase_localincludeHEADERS: $(nobase_localinclude_HEADERS)
@$(NORMAL_INSTALL)
@list='$(nobase_localinclude_HEADERS)'; test -n "$(localincludedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(localincludedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(localincludedir)" || exit 1; \
fi; \
$(am__nobase_list) | while read dir files; do \
xfiles=; for file in $$files; do \
if test -f "$$file"; then xfiles="$$xfiles $$file"; \
else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
test -z "$$xfiles" || { \
test "x$$dir" = x. || { \
echo " $(MKDIR_P) '$(DESTDIR)$(localincludedir)/$$dir'"; \
$(MKDIR_P) "$(DESTDIR)$(localincludedir)/$$dir"; }; \
echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(localincludedir)/$$dir'"; \
$(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(localincludedir)/$$dir" || exit $$?; }; \
done
uninstall-nobase_localincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(nobase_localinclude_HEADERS)'; test -n "$(localincludedir)" || list=; \
$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
dir='$(DESTDIR)$(localincludedir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(localincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-nobase_localincludeHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-nobase_localincludeHEADERS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-nobase_localincludeHEADERS \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
uninstall-nobase_localincludeHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@@ -0,0 +1,85 @@
TLM-2.0 standard utilities
==========================
Dir: include/tlm_utils
SubDirs:
Files: README.txt
instance_specific_extensions.h
multi_passthrough_initiator_socket.h
multi_passthrough_target_socket.h
multi_socket_bases.h
peq_with_get.h
simple_initiator_socket.h
simple_target_socket.h
peq_with_cb_and_phase.h
passthrough_target_socket.h
tlm_quantumkeeper.h
Comments
========
This directory contains a number of ease-of-use and convenience implementations
for the interoperability standard. All objects defined in the header files of
this directory are contained in the tlm_util namespace.
There is no tlm_utils.h header files containing all includes in order to avoid
additional dependencies for TLM 2.0
Files:
simple_initiator_socket.h
version of an initiator socket that has a default implementation of all
interfaces and allows to register an implementation for any of the
interfaces to the socket, either unique interfaces or tagged interfaces
(carrying an additional id)
simple_target_socket.h
version of a target socket that has a default implementation of all
interfaces and allows to register an implementation for any of the
interfaces to the socket, either unique interfaces or tagged interfaces
(carrying an additional id)
This socket allows to register only 1 of the transport interfaces
(blocking or non-blocking) and implements a conversion in case the
socket is used on the other interface
passthrough_target_socket.h
version of a target socket that has a default implementation of all
interfaces and allows to register an implementation for any of the
interfaces to the socket.
multi_passthrough_initiator_socket.h
an implementation of a socket that allows to bind multiple targets to the
same initiator socket. Implements a mechanism to allow to identify in the
backward path through which index of the socket the call passed through
multi_passthrough_target_socket.h
an implementation of a socket that allows to bind multiple initiators to
the same target socket. Implements a mechanism to allow to identify in the
forward path through which index of the socket the call passed through
multi_socket_bases.h
contains base class definitions used by the multi_passthrough sockets
peq_with_get.h
payload event queue (PEQ) implementation using a pull interface.
Has a get_next_transaction API that returns the transaction that is
scheduled in the event queue
peq_with_cb_and_phase.h
another payload event queue, this one with a push interface (callback
mechanism ). Allows to register a callback that will be called whenever
the event in the event queue is triggered, the callback gets transaction
and phase as arguments
instance_specific_extensions.h
is an implementation for adding extentions in the generic payload that
are specific to an instance along the path of a transaction, to allow that
extentions of the same type can be used by the different blocks along
the path of the transaction
tlm_quantumkeeper.h
is an convenience object used to keep track of the local time in
an initiator (how much it has run ahead of the SystemC time), to
synchronize with SystemC time etc.

View File

@@ -0,0 +1,77 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef TLM_UTILS_CONVENIENCE_SOCKET_BASES_H_INCLUDED_
#define TLM_UTILS_CONVENIENCE_SOCKET_BASES_H_INCLUDED_
#include <sysc/kernel/sc_cmnhdr.h>
namespace sc_core { class SC_API sc_object; }
namespace tlm_utils {
// implementation-defined base class helper for convenience sockets
class SC_API convenience_socket_base
{
public:
void display_warning(const char* msg) const;
void display_error(const char* msg) const;
protected:
virtual ~convenience_socket_base(){}
private:
virtual const char* get_report_type() const = 0;
virtual const sc_core::sc_object* get_socket() const = 0;
};
// implementation-defined base class helper for simple sockets
class SC_API simple_socket_base : public convenience_socket_base
{
virtual const char* get_report_type() const;
protected:
void elaboration_check(const char* action) const;
};
// implementation-defined base class helper for passthrough sockets
class SC_API passthrough_socket_base : public convenience_socket_base
{
virtual const char* get_report_type() const;
};
// implementation-defined base class helper for multi sockets
class SC_API multi_socket_base : public convenience_socket_base
{
virtual const char* get_report_type() const;
};
// implementation-defined base class for callback helpers
class SC_API convenience_socket_cb_holder
{
public:
void display_warning(const char* msg) const;
void display_error(const char* msg) const;
protected:
explicit convenience_socket_cb_holder(convenience_socket_base* owner)
: m_owner(owner) {}
private:
convenience_socket_base* m_owner;
};
} // namespace tlm_utils
#endif // TLM_UTILS_CONVENIENCE_SOCKET_BASES_H_INCLUDED_

View File

@@ -0,0 +1,124 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
/*
Instance specific extensions, are extension that only a single instance of a module
may access. They are invisible to all other modules; they are private to this
instance so to speak.
As they are only of value to a certain instance, this instance knows very well
when it needs them and when it does not need them any longer (usually when
a transaction passes through a module for the last time).
It does not have to care if anyone else in the system may still have a
reference to the transaction as this one is not able to access the extension
anyway.
Therefore the instance is obliged to call set_extension when it wants to add a
private extension and clear_extension when it does not need it any more.
To get access to an instance specifc extension the module must own a so called
instance_specific_extension_accessor that provides the exclusive access rights.
Assuming the instance_specific_extension_accessor of a given module is called m_accessor
and the transaction of which the private extension is about to be accessed
is called txn, then the calls have to be
m_accessor(txn).set_extension(...);
or
m_accessor(txn).clear_extension(...);
The owner of the private extension is responsible to allocate/deallocate
the extension before/after setting/clearing the extension.
*/
#ifndef TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_H_INCLUDED_
#define TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_H_INCLUDED_
#include "tlm_utils/instance_specific_extensions_int.h"
namespace tlm_utils {
//The templated private extension. Similar to normal extension
template <typename T>
class instance_specific_extension : public ispex_base {
public:
virtual ~instance_specific_extension() {}
const static unsigned int priv_id;
};
template <typename T>
const unsigned int instance_specific_extension<T>::priv_id
= ispex_base::register_private_extension(typeid(T));
// ----------------------------------------------------------------------------
// This is the class that actually sits in the extension array
// - we keep this small since that one gets allocated and deallocated all the times
// - we keep the implementation in the header to avoid registration
// of the extension itself unless used in the model
class instance_specific_extension_carrier
: public tlm::tlm_extension<instance_specific_extension_carrier>
{
friend class instance_specific_extension_accessor;
public:
instance_specific_extension_carrier()
: m_container()
{}
virtual tlm::tlm_extension_base* clone() const {
//we don't clone since private info is instance specific and associated to a given txn (the original)
//so the deep copied txn will be virgin in terms of private info
return NULL;
}
void copy_from(tlm::tlm_extension_base const &) { return; }
void free() { return; }
private:
instance_specific_extension_container* m_container;
};
// ----------------------------------------------------------------------------
template<typename T>
instance_specific_extensions_per_accessor&
instance_specific_extension_accessor::operator()(T& txn)
{
instance_specific_extension_carrier* carrier = NULL;
txn.get_extension(carrier);
if (!carrier) {
carrier = new instance_specific_extension_carrier();
carrier->m_container = instance_specific_extension_container::create();
carrier->m_container->attach_carrier(carrier, &txn, &release_carrier<T>);
txn.set_extension(carrier);
}
return *carrier->m_container->get_accessor(m_index);
}
template<typename T>
void
instance_specific_extension_accessor::
release_carrier(instance_specific_extension_carrier* carrier, void* txn)
{
T* typed_txn = static_cast<T*>(txn);
typed_txn->clear_extension(carrier);
delete carrier;
}
} // namespace tlm_utils
#endif // TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_H_INCLUDED_

View File

@@ -0,0 +1,174 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_
#define TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_
#ifndef SC_BUILD // incluce full TLM, when not building the library
#include <tlm>
#else
#include "tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h"
#endif // SC_BUILD
namespace tlm_utils {
class SC_API ispex_base;
class SC_API instance_specific_extension_accessor;
class SC_API instance_specific_extension_container;
class instance_specific_extension_carrier;
class instance_specific_extension_container_pool;
}
namespace tlm {
SC_API_TEMPLATE_DECL_ tlm_array<tlm_utils::ispex_base*>;
} // namespace tlm
namespace tlm_utils {
//The private extension base. Similar to normal extension base, but without clone and free
class SC_API ispex_base
{
friend class tlm::tlm_array<ispex_base*>;
void free() {} // needed for explicit tlm_array instantiation
public:
virtual ~ispex_base() {}
protected:
static unsigned int register_private_extension(const std::type_info&);
};
//this thing is basically a snippet of the generic_payload
// it contains all the extension specific code (the extension API so to speak)
// the differences are:
// - it calls back to its owner whenever a real (==non-NULL) extension gets set for the first time
// - it calls back to its owner whenever a living (==non-NULL) extension gets cleared
class SC_API instance_specific_extensions_per_accessor
{
public:
typedef instance_specific_extension_container container_type;
explicit
instance_specific_extensions_per_accessor(container_type* container)
: m_container(container)
{}
template <typename T> T* set_extension(T* ext)
{
return static_cast<T*>( set_extension(T::priv_id, ext) );
}
// non-templatized version with manual index:
ispex_base* set_extension(unsigned int index, ispex_base* ext);
// Check for an extension, ext will point to 0 if not present
template <typename T> void get_extension(T*& ext) const
{
ext = static_cast<T*>(get_extension(T::priv_id));
}
// Non-templatized version:
ispex_base* get_extension(unsigned int index) const;
// Clear extension, the argument is needed to find the right index:
template <typename T> void clear_extension(const T*)
{
clear_extension(T::priv_id);
}
// Non-templatized version with manual index
void clear_extension(unsigned int index);
// 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();
private:
tlm::tlm_array<ispex_base*> m_extensions;
container_type* m_container;
}; // class instance_specific_extensions_per_accessor
#if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN)
#pragma warning(push)
#pragma warning(disable: 4251) // DLL import for vector
#endif
//this thing contains the vector of extensions per accessor
//which can be really large so this one should be pool allocated
// therefore it keeps a use_count of itself to automatically free itself
// - to this end it provides callbacks to the extensions per accessor
// to increment and decrement the use_count
class SC_API instance_specific_extension_container
{
friend class instance_specific_extension_accessor;
friend class instance_specific_extension_carrier;
friend class instance_specific_extension_container_pool;
friend class instance_specific_extensions_per_accessor;
typedef void release_fn(instance_specific_extension_carrier*,void*);
instance_specific_extension_container();
~instance_specific_extension_container();
void resize();
void inc_use_count();
void dec_use_count();
static instance_specific_extension_container* create();
void attach_carrier(instance_specific_extension_carrier*, void* txn, release_fn*);
instance_specific_extensions_per_accessor* get_accessor(unsigned int index);
std::vector<instance_specific_extensions_per_accessor*> m_ispex_per_accessor;
unsigned int use_count;
void* m_txn;
release_fn* m_release_fn;
instance_specific_extension_carrier* m_carrier;
instance_specific_extension_container* next; //for pooling
}; // class instance_specific_extension_container
#if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN)
#pragma warning(pop)
#endif
// ----------------------------------------------------------------------------
//This class 'hides' all the instance specific extension stuff from the user
// he instantiates one of those (e.g. instance_specific_extension_accessor extAcc;) and can then access
// the private extensions
// extAcc(txn).extensionAPIFnCall()
// where extensionAPIFnCall is set_extension, get_extension, clear_extension,...
class SC_API instance_specific_extension_accessor
{
public:
instance_specific_extension_accessor();
template<typename T> // implementation in instance_specific_extensions.h
inline instance_specific_extensions_per_accessor& operator()(T& txn);
protected:
template<typename T>
static void release_carrier(instance_specific_extension_carrier*, void* txn);
unsigned int m_index;
}; // class instance_specific_extension_accessor
} // namespace tlm_utils
#endif // TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_

View File

@@ -0,0 +1,286 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef TLM_UTILS_MULTI_PASSTHROUGH_INITIATOR_SOCKET_H_INCLUDED_
#define TLM_UTILS_MULTI_PASSTHROUGH_INITIATOR_SOCKET_H_INCLUDED_
#include "multi_socket_bases.h"
namespace tlm_utils {
/*
This class implements a trivial multi initiator socket.
The triviality refers to the fact that the socket does not
do blocking to non-blocking or non-blocking to blocking conversions.
It allows to connect multiple targets to this socket.
The user has to register callbacks for the bw interface methods
he likes to use. The callbacks are basically equal to the bw interface
methods but carry an additional integer that indicates to which
index of this socket the calling target is connected.
*/
template <typename MODULE,
unsigned int BUSWIDTH = 32,
typename TYPES = tlm::tlm_base_protocol_types,
unsigned int N=0, sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
class multi_passthrough_initiator_socket
: public multi_init_base< BUSWIDTH, TYPES, N, POL>
{
public:
//typedefs
// tlm 2.0 types for nb_transport
typedef typename TYPES::tlm_payload_type transaction_type;
typedef typename TYPES::tlm_phase_type phase_type;
typedef tlm::tlm_sync_enum sync_enum_type;
// typedefs to keep the fn ptr notations short
typedef sync_enum_type (MODULE::*nb_cb)(int,
transaction_type&,
phase_type&,
sc_core::sc_time&);
typedef void (MODULE::*dmi_cb)(int, sc_dt::uint64, sc_dt::uint64);
typedef multi_init_base<BUSWIDTH, TYPES, N, POL> base_type;
typedef typename base_type::base_target_socket_type base_target_socket_type;
static const char* default_name()
{ return sc_core::sc_gen_unique_name("multi_passthrough_initiator_socket"); }
//CTOR
explicit multi_passthrough_initiator_socket(const char* name = default_name())
: base_type(name)
, m_hierarch_bind(0)
, m_beoe_disabled(false)
, m_dummy(this,42)
{
}
~multi_passthrough_initiator_socket(){
//clean up everything allocated by 'new'
for (unsigned int i=0; i<m_binders.size(); i++) delete m_binders[i];
}
//register callback for nb transport of bw interface
void register_nb_transport_bw(MODULE* mod,
sync_enum_type (MODULE::*cb)(int,
transaction_type&,
phase_type&,
sc_core::sc_time&))
{
//warn if there already is a callback
if (m_nb_f.is_valid()){
display_warning("NBTransport_bw callback already registered.");
return;
}
//set the functor
m_nb_f.set_function(mod, cb);
}
//register callback for dmi function of bw interface
void register_invalidate_direct_mem_ptr(MODULE* mod,
void (MODULE::*cb)(int, sc_dt::uint64, sc_dt::uint64))
{
//warn if there already is a callback
if (m_dmi_f.is_valid()){
display_warning("InvalidateDMI callback already registered.");
return;
}
//set the functor
m_dmi_f.set_function(mod, cb);
}
//Override virtual functions of the tlm_initiator_socket:
// this function is called whenever an sc_port (as part of a target socket)
// wants to bind to the export of the underlying tlm_initiator_socket
//At this time a callback binder is created an returned to the sc_port
// of the target socket, so that it binds to the callback binder
virtual tlm::tlm_bw_transport_if<TYPES>& get_base_interface()
{
m_binders.push_back(new callback_binder_bw<TYPES>(this, m_binders.size()));
return *m_binders[m_binders.size()-1];
}
// const overload not allowed for multi-sockets
virtual const tlm::tlm_bw_transport_if<TYPES>& get_base_interface() const
{
display_error("'get_base_interface()' const not allowed for multi-sockets.");
return base_type::get_base_interface();
}
//Override virtual functions of the tlm_initiator_socket:
// this function is called whenever an sc_export (as part of a initiator socket)
// wants to bind to the export of the underlying tlm_initiator_socket
// i.e. a hierarchical bind takes place
virtual sc_core::sc_export<tlm::tlm_bw_transport_if<TYPES> >& get_base_export()
{
if (!m_beoe_disabled) //we are not bound hierarchically
base_type::m_export.bind(m_dummy); //so we bind the dummy to avoid a SystemC error
return base_type::get_base_export(); //and then return our own export so that the hierarchical binding is set up properly
}
virtual const sc_core::sc_export<tlm::tlm_bw_transport_if<TYPES> >& get_base_export() const
{
return base_type::get_base_export();
}
//bind against a target socket
virtual void bind(base_target_socket_type& s)
{
//error if this socket is already bound hierarchically
if (m_hierarch_bind) {
display_error("Already hierarchically bound.");
return;
}
base_type::bind(s); //satisfy systemC, leads to a call to get_base_interface()
//try to cast the target socket into a fw interface
sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >* p_ex_s=dynamic_cast<sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >*>(&s);
if (!p_ex_s) {
display_error("Multi socket not bound to tlm_socket.");
return;
}
//try a cast into a multi sockets
multi_to_multi_bind_base<TYPES>* test=dynamic_cast<multi_to_multi_bind_base<TYPES>*> (p_ex_s);
if (test) //did we just do a multi-multi bind??
//if that is the case the multi target socket must have just created a callback binder
// which we want to get from it.
//Moreover, we also just created one, which we will pass to it.
m_sockets.push_back(test->get_last_binder(m_binders[m_binders.size()-1]));
else{ // if not just bind normally
sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >& ex_s=*p_ex_s;
m_sockets.push_back(&((tlm::tlm_fw_transport_if<TYPES>&)ex_s)); //store the interface we are bound against
}
}
//operator notation for direct bind
void operator() (base_target_socket_type& s)
{
bind(s);
}
//SystemC standard callback before end of elaboration
void before_end_of_elaboration(){
//if our export hasn't been bound yet (due to a hierarch binding)
// we bind it now to avoid a SystemC error.
//We must do that, because it is legal not to register a callback on this socket
// as the user might only use b_transport
if (!base_type::m_export.get_interface()){
base_type::m_export.bind(m_dummy);
}
//'break' here if the socket was told not to do callback binding
if (m_beoe_disabled) return;
//get the callback binders of the top of the hierachical bind chain
// NOTE: this could be the same socket if there is no hierachical bind
std::vector<callback_binder_bw<TYPES>* >& binders=get_hierarch_bind()->get_binders();
//get the interfaces bound to the top of the hierachical bind chain
// NOTE: this could be the same socket if there is no hierachical bind
m_used_sockets=get_hierarch_bind()->get_sockets();
//register the callbacks of this socket with the callback binders
// we just got from the top of the hierachical bind chain
for (unsigned int i=0; i<binders.size(); i++) {
binders[i]->set_callbacks(m_nb_f, m_dmi_f);
}
}
//
// Bind multi initiator socket to multi initiator socket (hierarchical bind)
//
virtual void bind(base_type& s)
{
if (m_binders.size()) {
//a multi socket is either bound hierarchically or directly
display_error("Socket already directly bound.");
return;
}
if (m_hierarch_bind){
display_warning("Socket already bound hierarchically. Bind attempt ignored.");
return;
}
//remember to which socket we are hierarchically bound and disable it,
// so that it won't try to register callbacks itself
s.disable_cb_bind();
m_hierarch_bind=&s;
base_type::bind(s); //satisfy SystemC
}
//operator notation for hierarchical bind
void operator() (base_type& s)
{
bind(s);
}
//get access to sub port
tlm::tlm_fw_transport_if<TYPES>* operator[](int i){return m_used_sockets[i];}
//get the number of bound targets
// NOTE: this is only valid at end of elaboration!
unsigned int size() {return get_hierarch_bind()->get_sockets().size();}
protected:
using base_type::display_warning;
using base_type::display_error;
//implementation of base class interface
base_type* get_hierarch_bind(){if (m_hierarch_bind) return m_hierarch_bind->get_hierarch_bind(); else return this;}
void disable_cb_bind(){ m_beoe_disabled=true;}
std::vector<callback_binder_bw<TYPES>* >& get_binders(){return m_binders;}
std::vector<tlm::tlm_fw_transport_if<TYPES>*>& get_sockets(){return m_sockets;}
//vector of connected sockets
std::vector<tlm::tlm_fw_transport_if<TYPES>*> m_sockets;
std::vector<tlm::tlm_fw_transport_if<TYPES>*> m_used_sockets;
//vector of binders that convert untagged interface into tagged interface
std::vector<callback_binder_bw<TYPES>*> m_binders;
base_type* m_hierarch_bind; //pointer to hierarchical bound multi port
bool m_beoe_disabled; // bool that remembers whether this socket shall bind callbacks or not
callback_binder_bw<TYPES> m_dummy; //a callback binder that is bound to the underlying export
// in case there was no real bind
//callbacks as functors
// (allows to pass the callback to another socket that does not know the type of the module that owns
// the callbacks)
typename callback_binder_bw<TYPES>::nb_func_type m_nb_f;
typename callback_binder_bw<TYPES>::dmi_func_type m_dmi_f;
};
template <typename MODULE,
unsigned int BUSWIDTH = 32,
typename TYPES = tlm::tlm_base_protocol_types,
unsigned int N=0>
class multi_passthrough_initiator_socket_optional
: public multi_passthrough_initiator_socket<MODULE,BUSWIDTH,TYPES,N,sc_core::SC_ZERO_OR_MORE_BOUND>
{
typedef multi_passthrough_initiator_socket<MODULE,BUSWIDTH,TYPES,N,sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
public:
multi_passthrough_initiator_socket_optional() : socket_b() {}
explicit multi_passthrough_initiator_socket_optional(const char* name) : socket_b(name) {}
};
} // namespace tlm_utils
#endif // TLM_UTILS_MULTI_PASSTHROUGH_INITIATOR_SOCKET_H_INCLUDED_

View File

@@ -0,0 +1,328 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef TLM_UTILS_MULTI_PASSTHROUGH_TARGET_SOCKET_H_INCLUDED_
#define TLM_UTILS_MULTI_PASSTHROUGH_TARGET_SOCKET_H_INCLUDED_
#include "tlm_utils/multi_socket_bases.h"
namespace tlm_utils {
/*
This class implements a trivial multi target socket.
The triviality refers to the fact that the socket does not
do blocking to non-blocking or non-blocking to blocking conversions.
It allows to connect multiple initiators to this socket.
The user has to register callbacks for the fw interface methods
he likes to use. The callbacks are basically equal to the fw interface
methods but carry an additional integer that indicates to which
index of this socket the calling initiator is connected.
*/
template <typename MODULE,
unsigned int BUSWIDTH = 32,
typename TYPES = tlm::tlm_base_protocol_types,
unsigned int N=0,
sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
class multi_passthrough_target_socket
: public multi_target_base< BUSWIDTH, TYPES, N, POL>
, public multi_to_multi_bind_base<TYPES>
{
public:
//typedefs
// tlm 2.0 types for nb_transport
typedef typename TYPES::tlm_payload_type transaction_type;
typedef typename TYPES::tlm_phase_type phase_type;
typedef tlm::tlm_sync_enum sync_enum_type;
// typedefs to keep the fn ptr notations short
typedef sync_enum_type (MODULE::*nb_cb)(int, transaction_type&, phase_type&, sc_core::sc_time&);
typedef void (MODULE::*b_cb)(int, transaction_type&, sc_core::sc_time&);
typedef unsigned int (MODULE::*dbg_cb)(int, transaction_type& txn);
typedef bool (MODULE::*dmi_cb)(int, transaction_type& txn, tlm::tlm_dmi& dmi);
typedef multi_target_base<BUSWIDTH, TYPES, N, POL> base_type;
typedef typename base_type::base_initiator_socket_type base_initiator_socket_type;
static const char* default_name()
{ return sc_core::sc_gen_unique_name("multi_passthrough_target_socket"); }
//CTOR
explicit multi_passthrough_target_socket(const char* name = default_name())
: base_type(name)
, m_hierarch_bind(0)
, m_eoe_disabled(false)
, m_export_callback_created(false)
{
}
~multi_passthrough_target_socket(){
//clean up everything allocated by 'new'
for (unsigned int i=0; i<m_binders.size(); i++) delete m_binders[i];
}
void check_export_binding()
{
//if our export hasn't been bound yet (due to a hierarch binding)
// we bind it now.
//We do that here as the user of the target port HAS to bind at least on callback,
//otherwise the socket was useless. Nevertheless, the target socket may still
// stay unbound afterwards.
if (!sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::get_interface())
{
// We bind to a callback_binder that will be used as the first interface
// i.e. calls to the sc_export will have the same ID as calls from the first initator
// socket bound
callback_binder_fw<TYPES> * binder;
if (m_binders.size() == 0)
{
binder = new callback_binder_fw<TYPES>(this, m_binders.size());
m_binders.push_back(binder);
m_export_callback_created = true;
}
else
{
binder = m_binders[0];
}
sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::bind(*binder);
}
}
//register callback for nb transport of fw interface
void register_nb_transport_fw(MODULE* mod,
nb_cb cb)
{
check_export_binding();
//warn if there already is a callback
if (m_nb_f.is_valid()){
display_warning("NBTransport_bw callback already registered.");
return;
}
//set the functor
m_nb_f.set_function(mod, cb);
}
//register callback for b transport of fw interface
void register_b_transport(MODULE* mod,
b_cb cb)
{
check_export_binding();
//warn if there already is a callback
if (m_b_f.is_valid()){
display_warning("BTransport callback already registered.");
return;
}
//set the functor
m_b_f.set_function(mod, cb);
}
//register callback for debug transport of fw interface
void register_transport_dbg(MODULE* mod,
dbg_cb cb)
{
check_export_binding();
//warn if there already is a callback
if (m_dbg_f.is_valid()){
display_warning("DebugTransport callback already registered.");
return;
}
//set the functor
m_dbg_f.set_function(mod, cb);
}
//register callback for DMI of fw interface
void register_get_direct_mem_ptr(MODULE* mod,
dmi_cb cb)
{
check_export_binding();
//warn if there already is a callback
if (m_dmi_f.is_valid()){
display_warning("DMI callback already registered.");
return;
}
//set the functor
m_dmi_f.set_function(mod, cb);
}
//Override virtual functions of the tlm_target_socket:
// this function is called whenever an sc_port (as part of a init socket)
// wants to bind to the export of the underlying tlm_target_socket
//At this time a callback binder is created an returned to the sc_port
// of the init socket, so that it binds to the callback binder
virtual tlm::tlm_fw_transport_if<TYPES>& get_base_interface()
{
//error if this socket is already bound hierarchically
if (m_hierarch_bind) display_error("Socket already bound hierarchically.");
if (m_export_callback_created) {
// consume binder created from the callback registration
m_export_callback_created = false;
} else {
m_binders.push_back(new callback_binder_fw<TYPES>(this, m_binders.size()));
}
return *m_binders[m_binders.size()-1];
}
// const overload not allowed for multi-sockets
virtual const tlm::tlm_fw_transport_if<TYPES>& get_base_interface() const
{
display_error("'get_base_interface() const' not allowed for multi-sockets.");
return base_type::get_base_interface();
}
//just return the export of the underlying tlm_target_socket in case of a hierarchical bind
virtual sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >& get_base_export()
{
return *this;
}
//just return the export of the underlying tlm_target_socket in case of a hierarchical bind
virtual const sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >& get_base_export() const
{
return base_type::get_base_export();
}
//the standard end of elaboration callback
void end_of_elaboration(){
//'break' here if the socket was told not to do callback binding
if (m_eoe_disabled) return;
//get the callback binders and the multi binds of the top of the hierachical bind chain
// NOTE: this could be the same socket if there is no hierachical bind
std::vector<callback_binder_fw<TYPES>* >& binders=get_hierarch_bind()->get_binders();
std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*>& multi_binds=get_hierarch_bind()->get_multi_binds();
// complete binding only if there has been a real bind
bool unbound = (binders.size() == 1 && m_export_callback_created);
// no call to get_base_interface has consumed the export - ignore
if (unbound) return;
// iterate over all binders
for (unsigned int i=0; i<binders.size(); i++) {
binders[i]->set_callbacks(m_nb_f, m_b_f, m_dmi_f, m_dbg_f); //set the callbacks for the binder
if (multi_binds.find(i)!=multi_binds.end()) //check if this connection is multi-multi
//if so remember the interface
m_sockets.push_back(multi_binds[i]);
else{ //if we are bound to a normal socket
//get the calling port and try to cast it into a tlm socket base
base_initiator_socket_type* test=dynamic_cast<base_initiator_socket_type*>(binders[i]->get_other_side());
if (!test){display_error("Not bound to tlm_socket.");}
m_sockets.push_back(&test->get_base_interface()); //remember the interface
}
}
}
//
// Bind multi target socket to multi target socket (hierarchical bind)
//
virtual void bind(base_type& s)
{
//warn if already bound hierarchically
if (m_eoe_disabled){
display_warning("Socket already bound hierarchically. Bind attempt ignored.");
return;
}
//disable our own end of elaboration call
disable_cb_bind();
//inform the bound target socket that it is bound hierarchically now
s.set_hierarch_bind((base_type*)this);
base_type::bind(s); //satisfy SystemC
}
//operator notation for hierarchical bind
void operator() (base_type& s)
{
bind(s);
}
//get access to sub port
tlm::tlm_bw_transport_if<TYPES>* operator[](int i){return m_sockets[i];}
//get number of bound initiators
// NOTE: this is only valid at end of elaboration!
unsigned int size(){return get_hierarch_bind()->get_binders().size();}
protected:
using base_type::display_warning;
using base_type::display_error;
//implementation of base class interface
base_type* get_hierarch_bind(){if (m_hierarch_bind) return m_hierarch_bind->get_hierarch_bind(); else return this;}
std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*>& get_multi_binds(){return m_multi_binds;}
void set_hierarch_bind(base_type* h){m_hierarch_bind=h;}
tlm::tlm_fw_transport_if<TYPES>* get_last_binder(tlm::tlm_bw_transport_if<TYPES>* other){
m_multi_binds[m_binders.size()-1]=other;
return m_binders[m_binders.size()-1];
}
//map that stores to which index a multi init socket is connected
// and the interface of the multi init socket
std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*> m_multi_binds;
void disable_cb_bind(){ m_eoe_disabled=true;}
std::vector<callback_binder_fw<TYPES>* >& get_binders(){return m_binders;}
//vector of connected sockets
std::vector<tlm::tlm_bw_transport_if<TYPES>*> m_sockets;
//vector of binders that convert untagged interface into tagged interface
std::vector<callback_binder_fw<TYPES>*> m_binders;
base_type* m_hierarch_bind; //pointer to hierarchical bound multi port
bool m_eoe_disabled; //bool that disables callback bindings at end of elaboration
bool m_export_callback_created; //bool that indicates that a binder has been created from a callback registration
//callbacks as functors
// (allows to pass the callback to another socket that does not know the type of the module that owns
// the callbacks)
typename callback_binder_fw<TYPES>::nb_func_type m_nb_f;
typename callback_binder_fw<TYPES>::b_func_type m_b_f;
typename callback_binder_fw<TYPES>::debug_func_type m_dbg_f;
typename callback_binder_fw<TYPES>::dmi_func_type m_dmi_f;
};
template <typename MODULE,
unsigned int BUSWIDTH = 32,
typename TYPES = tlm::tlm_base_protocol_types,
unsigned int N=0>
class multi_passthrough_target_socket_optional
: public multi_passthrough_target_socket<MODULE,BUSWIDTH,TYPES,N,sc_core::SC_ZERO_OR_MORE_BOUND>
{
typedef multi_passthrough_target_socket<MODULE,BUSWIDTH,TYPES,N,sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
public:
multi_passthrough_target_socket_optional() : socket_b() {}
explicit multi_passthrough_target_socket_optional(const char* name) : socket_b(name) {}
};
} // namespace tlm_utils
#endif // TLM_UTILS_MULTI_PASSTHROUGH_TARGET_SOCKET_H_INCLUDED_

View File

@@ -0,0 +1,440 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef TLM_UTILS_MULTI_SOCKET_BASES_H_INCLUDED_
#define TLM_UTILS_MULTI_SOCKET_BASES_H_INCLUDED_
#include <tlm>
#include "tlm_utils/convenience_socket_bases.h"
#include <map>
namespace tlm_utils {
template <typename signature>
struct fn_container{
signature function;
};
#define TLM_DEFINE_FUNCTOR(name) \
template <typename MODULE, typename TRAITS> \
inline TLM_RET_VAL static_##name( void* mod \
, void* fn \
, int index \
, TLM_FULL_ARG_LIST) \
{ \
typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> fn_container_type; \
MODULE* tmp_mod=static_cast<MODULE*>(mod); \
fn_container_type* tmp_cb =static_cast<fn_container_type*> (fn); \
return (tmp_mod->*(tmp_cb->function))(index, TLM_ARG_LIST_WITHOUT_TYPES); \
}\
\
template <typename MODULE, typename TRAITS> \
inline void delete_fn_container_of_##name(void* fn) \
{ \
typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> fn_container_type; \
fn_container_type* tmp_cb =static_cast<fn_container_type*> (fn); \
if (tmp_cb) delete tmp_cb;\
} \
\
template <typename TRAITS> \
class name##_functor{ \
public: \
typedef typename TRAITS::tlm_payload_type payload_type; \
typedef typename TRAITS::tlm_phase_type phase_type; \
typedef TLM_RET_VAL (*call_fn)(void*,void*, int, TLM_FULL_ARG_LIST); \
typedef void (*del_fn)(void*); \
\
name##_functor(): m_fn(0), m_del_fn(0), m_mod(0), m_mem_fn(0){} \
~name##_functor(){if (m_del_fn) (*m_del_fn)(m_mem_fn);} \
\
template <typename MODULE> \
void set_function(MODULE* mod, TLM_RET_VAL (MODULE::*cb)(int, TLM_FULL_ARG_LIST)){ \
typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> fn_container_type; \
m_fn=&static_##name<MODULE,TRAITS>;\
m_del_fn=&delete_fn_container_of_##name<MODULE,TRAITS>;\
m_del_fn(m_mem_fn); \
fn_container_type* tmp= new fn_container_type(); \
tmp->function=cb; \
m_mod=static_cast<void*>(mod); \
m_mem_fn=static_cast<void*>(tmp); \
} \
\
TLM_RET_VAL operator()(int index, TLM_FULL_ARG_LIST){ \
return m_fn(m_mod,m_mem_fn, index, TLM_ARG_LIST_WITHOUT_TYPES); \
} \
\
bool is_valid(){return (m_mod!=0 && m_mem_fn!=0 && m_fn!=0);}\
\
protected: \
call_fn m_fn;\
del_fn m_del_fn; \
void* m_mod; \
void* m_mem_fn; \
private: \
name##_functor& operator=(const name##_functor&); \
}
#define TLM_RET_VAL tlm::tlm_sync_enum
#define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn, typename TRAITS::tlm_phase_type& ph, sc_core::sc_time& t
#define TLM_ARG_LIST_WITHOUT_TYPES txn,ph,t
TLM_DEFINE_FUNCTOR(nb_transport);
#undef TLM_RET_VAL
#undef TLM_FULL_ARG_LIST
#undef TLM_ARG_LIST_WITHOUT_TYPES
#define TLM_RET_VAL void
#define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn, sc_core::sc_time& t
#define TLM_ARG_LIST_WITHOUT_TYPES txn,t
TLM_DEFINE_FUNCTOR(b_transport);
#undef TLM_RET_VAL
#undef TLM_FULL_ARG_LIST
#undef TLM_ARG_LIST_WITHOUT_TYPES
#define TLM_RET_VAL unsigned int
#define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn
#define TLM_ARG_LIST_WITHOUT_TYPES txn
TLM_DEFINE_FUNCTOR(debug_transport);
#undef TLM_RET_VAL
#undef TLM_FULL_ARG_LIST
#undef TLM_ARG_LIST_WITHOUT_TYPES
#define TLM_RET_VAL bool
#define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn, tlm::tlm_dmi& dmi
#define TLM_ARG_LIST_WITHOUT_TYPES txn,dmi
TLM_DEFINE_FUNCTOR(get_dmi_ptr);
#undef TLM_RET_VAL
#undef TLM_FULL_ARG_LIST
#undef TLM_ARG_LIST_WITHOUT_TYPES
#define TLM_RET_VAL void
#define TLM_FULL_ARG_LIST sc_dt::uint64 l, sc_dt::uint64 u
#define TLM_ARG_LIST_WITHOUT_TYPES l,u
TLM_DEFINE_FUNCTOR(invalidate_dmi);
#undef TLM_RET_VAL
#undef TLM_FULL_ARG_LIST
#undef TLM_ARG_LIST_WITHOUT_TYPES
#undef TLM_DEFINE_FUNCTOR
/*
This class implements the fw interface.
It allows to register a callback for each of the fw interface methods.
The callbacks simply forward the fw interface call, but add the id (an int)
of the callback binder to the signature of the call.
*/
template <typename TYPES>
class callback_binder_fw
: public tlm::tlm_fw_transport_if<TYPES>
, protected convenience_socket_cb_holder
{
public:
//typedefs according to the used TYPES class
typedef typename TYPES::tlm_payload_type transaction_type;
typedef typename TYPES::tlm_phase_type phase_type;
typedef tlm::tlm_sync_enum sync_enum_type;
//typedefs for the callbacks
typedef nb_transport_functor<TYPES> nb_func_type;
typedef b_transport_functor<TYPES> b_func_type;
typedef debug_transport_functor<TYPES> debug_func_type;
typedef get_dmi_ptr_functor<TYPES> dmi_func_type;
//ctor: an ID is needed to create a callback binder
callback_binder_fw(multi_socket_base* owner, int id)
: convenience_socket_cb_holder(owner), m_id(id)
, m_nb_f(0), m_b_f(0), m_dbg_f(0), m_dmi_f(0)
, m_caller_port(0)
{}
//the nb_transport method of the fw interface
sync_enum_type nb_transport_fw(transaction_type& txn,
phase_type& p,
sc_core::sc_time& t){
//check if a callback is registered
if (m_nb_f && m_nb_f->is_valid()) {
return (*m_nb_f)(m_id, txn, p, t); //do the callback
}
display_error("Call to nb_transport_fw without a registered callback for nb_transport_fw.");
return tlm::TLM_COMPLETED;
}
//the b_transport method of the fw interface
void b_transport(transaction_type& trans,sc_core::sc_time& t){
//check if a callback is registered
if (m_b_f && m_b_f->is_valid()) {
(*m_b_f)(m_id, trans,t); //do the callback
return;
}
display_error("Call to b_transport without a registered callback for b_transport.");
}
//the DMI method of the fw interface
bool get_direct_mem_ptr(transaction_type& trans, tlm::tlm_dmi& dmi_data){
//check if a callback is registered
if (m_dmi_f && m_dmi_f->is_valid()) {
return (*m_dmi_f)(m_id, trans,dmi_data); //do the callback
}
dmi_data.allow_none();
dmi_data.set_start_address(0x0);
dmi_data.set_end_address((sc_dt::uint64)-1);
return false;
}
//the debug method of the fw interface
unsigned int transport_dbg(transaction_type& trans){
//check if a callback is registered
if (m_dbg_f && m_dbg_f->is_valid()) {
return (*m_dbg_f)(m_id, trans); //do the callback
}
return 0;
}
//the SystemC standard callback register_port:
// - called when a port if bound to the interface
// - allowd to find out who is bound to that callback binder
void register_port(sc_core::sc_port_base& b, const char* /*name*/){
m_caller_port=&b;
}
//register callbacks for all fw interface methods at once
void set_callbacks(nb_func_type& cb1, b_func_type& cb2, dmi_func_type& cb3, debug_func_type& cb4){
m_nb_f=&cb1;
m_b_f=&cb2;
m_dmi_f=&cb3;
m_dbg_f=&cb4;
}
//getter method to get the port that is bound to that callback binder
// NOTE: this will only return a valid value at end of elaboration
// (but not before end of elaboration!)
sc_core::sc_port_base* get_other_side(){return m_caller_port;}
private:
//the ID of the callback binder
int m_id;
//the callbacks
nb_func_type* m_nb_f;
b_func_type* m_b_f;
debug_func_type* m_dbg_f;
dmi_func_type* m_dmi_f;
//the port bound to that callback binder
sc_core::sc_port_base* m_caller_port;
};
/*
This class implements the bw interface.
It allows to register a callback for each of the bw interface methods.
The callbacks simply forward the bw interface call, but add the id (an int)
of the callback binder to the signature of the call.
*/
template <typename TYPES>
class callback_binder_bw
: public tlm::tlm_bw_transport_if<TYPES>
, protected convenience_socket_cb_holder
{
public:
//typedefs according to the used TYPES class
typedef typename TYPES::tlm_payload_type transaction_type;
typedef typename TYPES::tlm_phase_type phase_type;
typedef tlm::tlm_sync_enum sync_enum_type;
//typedefs for the callbacks
typedef nb_transport_functor<TYPES> nb_func_type;
typedef invalidate_dmi_functor<TYPES> dmi_func_type;
//ctor: an ID is needed to create a callback binder
callback_binder_bw(multi_socket_base* owner, int id)
: convenience_socket_cb_holder(owner), m_id(id)
, m_nb_f(0), m_dmi_f(0) {}
//the nb_transport method of the bw interface
sync_enum_type nb_transport_bw(transaction_type& txn,
phase_type& p,
sc_core::sc_time& t){
//check if a callback is registered
if (m_nb_f && m_nb_f->is_valid()) {
return (*m_nb_f)(m_id, txn, p, t); //do the callback
}
display_error("Call to nb_transport_bw without a registered callback for nb_transport_bw");
return tlm::TLM_COMPLETED;
}
//the DMI method of the bw interface
void invalidate_direct_mem_ptr(sc_dt::uint64 l, sc_dt::uint64 u){
//check if a callback is registered
if (m_dmi_f && m_dmi_f->is_valid()) {
(*m_dmi_f)(m_id,l,u); //do the callback
}
}
//register callbacks for all bw interface methods at once
void set_callbacks(nb_func_type& cb1, dmi_func_type& cb2){
m_nb_f=&cb1;
m_dmi_f=&cb2;
}
private:
//the ID of the callback binder
int m_id;
//the callbacks
nb_func_type* m_nb_f;
dmi_func_type* m_dmi_f;
};
/*
This class forms the base for multi initiator sockets,
with fewer template parameters than the multi_init_base.
This class is implementation-defined.
*/
template <typename TYPES = tlm::tlm_base_protocol_types>
class multi_init_base_if {
public:
//this method shall return a vector of the callback binders of multi initiator socket
virtual std::vector<callback_binder_bw<TYPES>* >& get_binders()=0;
//this method shall return a vector of all target interfaces bound to this multi init socket
virtual std::vector<tlm::tlm_fw_transport_if<TYPES>*>& get_sockets()=0;
protected:
virtual ~multi_init_base_if() {}
};
/*
This class forms the base for multi initiator sockets.
It enforces a multi initiator socket to implement all functions
needed to do hierarchical bindings.
*/
template <unsigned int BUSWIDTH = 32,
typename TYPES = tlm::tlm_base_protocol_types,
unsigned int N=0,
sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
class multi_init_base
: public tlm::tlm_initiator_socket<BUSWIDTH, TYPES, N, POL>
, public multi_init_base_if<TYPES>
, protected multi_socket_base
{
public:
//typedef for the base type: the standard tlm initiator socket
typedef tlm::tlm_initiator_socket<BUSWIDTH, TYPES, N, POL> base_type;
//this method shall disable the code that does the callback binding
// that registers callbacks to binders
virtual void disable_cb_bind()=0;
//this method shall return the multi_init_base to which the
// multi_init_base is bound hierarchically
// If the base is not bound hierarchically it shall return a pointer to itself
virtual multi_init_base* get_hierarch_bind()=0;
virtual tlm::tlm_socket_category get_socket_category() const
{
return tlm::TLM_MULTI_INITIATOR_SOCKET;
}
//ctor and dtor
virtual ~multi_init_base(){}
multi_init_base():base_type(sc_core::sc_gen_unique_name("multi_init_base")){}
multi_init_base(const char* name):base_type(name){}
private:
const sc_core::sc_object* get_socket() const { return this; }
};
/*
This class forms the base for multi target sockets,
with fewer template parameters than the multi_target_base.
This class is implementation-defined.
*/
template <typename TYPES = tlm::tlm_base_protocol_types>
class multi_target_base_if {
public:
//this method shall return a vector of the callback binders of multi initiator socket
virtual std::vector<callback_binder_fw<TYPES>* >& get_binders()=0;
//this method shall return a map of all multi initiator sockets that are
// bound to this multi target the key of the map is the index at which the
// multi initiator i bound, while the value is the interface of the multi
// initiator socket that is bound at that index
virtual std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*>& get_multi_binds()=0;
protected:
virtual ~multi_target_base_if() {}
};
/*
This class forms the base for multi target sockets.
It enforces a multi target socket to implement all functions
needed to do hierarchical bindings.
*/
template <unsigned int BUSWIDTH = 32,
typename TYPES = tlm::tlm_base_protocol_types,
unsigned int N=0,
sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
class multi_target_base
: public tlm::tlm_target_socket<BUSWIDTH, TYPES, N, POL>
, public multi_target_base_if<TYPES>
, protected multi_socket_base
{
public:
//typedef for the base type: the standard tlm target socket
typedef tlm::tlm_target_socket<BUSWIDTH, TYPES, N, POL > base_type;
//this method shall return the multi_init_base to which the
// multi_init_base is bound hierarchically
// If the base is not bound hierarchically it shall return a pointer to itself
virtual multi_target_base* get_hierarch_bind()=0;
//this method shall inform the multi target socket that it is bound
// hierarchically and to which other multi target socket it is bound hierarchically
virtual void set_hierarch_bind(multi_target_base*)=0;
virtual tlm::tlm_socket_category get_socket_category() const
{
return tlm::TLM_MULTI_TARGET_SOCKET;
}
//ctor and dtor
virtual ~multi_target_base(){}
multi_target_base():base_type(sc_core::sc_gen_unique_name("multi_target_base")){}
multi_target_base(const char* name):base_type(name){}
private:
const sc_core::sc_object* get_socket() const { return this; }
};
/*
All multi sockets must additionally derive from this class.
It enforces a multi socket to implement a function
needed to do multi init to multi target bindings.
*/
template <typename TYPES>
class multi_to_multi_bind_base{
public:
virtual ~multi_to_multi_bind_base(){}
virtual tlm::tlm_fw_transport_if<TYPES>* get_last_binder(tlm::tlm_bw_transport_if<TYPES>*)=0;
};
} // namespace tlm_utils
#endif // TLM_UTILS_MULTI_SOCKET_BASES_H_INCLUDED_

View File

@@ -0,0 +1,477 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef TLM_UTILS_PASSTHROUGH_TARGET_SOCKET_H_INCLUDED_
#define TLM_UTILS_PASSTHROUGH_TARGET_SOCKET_H_INCLUDED_
#include <tlm>
#include "tlm_utils/convenience_socket_bases.h"
namespace tlm_utils {
template< typename MODULE, unsigned int BUSWIDTH, typename TYPES
, sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND >
class passthrough_target_socket_b
: public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>
, protected passthrough_socket_base
{
public:
typedef typename TYPES::tlm_payload_type transaction_type;
typedef typename TYPES::tlm_phase_type phase_type;
typedef tlm::tlm_sync_enum sync_enum_type;
typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
typedef tlm::tlm_target_socket<BUSWIDTH,TYPES,1,POL> base_type;
public:
static const char* default_name()
{ return sc_core::sc_gen_unique_name("passthrough_target_socket"); }
explicit passthrough_target_socket_b(const char* n = default_name())
: base_type(n)
, m_process(this)
{
bind(m_process);
}
using base_type::bind;
// REGISTER_XXX
void register_nb_transport_fw(MODULE* mod,
sync_enum_type (MODULE::*cb)(transaction_type&,
phase_type&,
sc_core::sc_time&))
{
m_process.set_nb_transport_ptr(mod, cb);
}
void register_b_transport(MODULE* mod,
void (MODULE::*cb)(transaction_type&,
sc_core::sc_time&))
{
m_process.set_b_transport_ptr(mod, cb);
}
void register_transport_dbg(MODULE* mod,
unsigned int (MODULE::*cb)(transaction_type&))
{
m_process.set_transport_dbg_ptr(mod, cb);
}
void register_get_direct_mem_ptr(MODULE* mod,
bool (MODULE::*cb)(transaction_type&,
tlm::tlm_dmi&))
{
m_process.set_get_direct_mem_ptr(mod, cb);
}
private:
class process
: public tlm::tlm_fw_transport_if<TYPES>
, protected convenience_socket_cb_holder
{
public:
typedef sync_enum_type (MODULE::*NBTransportPtr)(transaction_type&,
phase_type&,
sc_core::sc_time&);
typedef void (MODULE::*BTransportPtr)(transaction_type&,
sc_core::sc_time&);
typedef unsigned int (MODULE::*TransportDbgPtr)(transaction_type&);
typedef bool (MODULE::*GetDirectMem_ptr)(transaction_type&,
tlm::tlm_dmi&);
explicit process(passthrough_socket_base* owner)
: convenience_socket_cb_holder(owner), m_mod(0)
, m_nb_transport_ptr(0)
, m_b_transport_ptr(0)
, m_transport_dbg_ptr(0)
, m_get_direct_mem_ptr(0)
{
}
void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
{
if (m_nb_transport_ptr) {
display_warning("non-blocking callback already registered");
return;
}
sc_assert(!m_mod || m_mod == mod);
m_mod = mod;
m_nb_transport_ptr = p;
}
void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
{
if (m_b_transport_ptr) {
display_warning("blocking callback already registered");
return;
}
sc_assert(!m_mod || m_mod == mod);
m_mod = mod;
m_b_transport_ptr = p;
}
void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
{
if (m_transport_dbg_ptr) {
display_warning("debug callback already registered");
return;
}
sc_assert(!m_mod || m_mod == mod);
m_mod = mod;
m_transport_dbg_ptr = p;
}
void set_get_direct_mem_ptr(MODULE* mod, GetDirectMem_ptr p)
{
if (m_get_direct_mem_ptr) {
display_warning("get DMI pointer callback already registered");
return;
}
sc_assert(!m_mod || m_mod == mod);
m_mod = mod;
m_get_direct_mem_ptr = p;
}
sync_enum_type nb_transport_fw(transaction_type& trans,
phase_type& phase,
sc_core::sc_time& t)
{
if (m_nb_transport_ptr) {
// forward call
sc_assert(m_mod);
return (m_mod->*m_nb_transport_ptr)(trans, phase, t);
}
display_error("no non-blocking callback registered");
return tlm::TLM_COMPLETED;
}
void b_transport(transaction_type& trans, sc_core::sc_time& t)
{
if (m_b_transport_ptr) {
// forward call
sc_assert(m_mod);
return (m_mod->*m_b_transport_ptr)(trans, t);
}
display_error("no blocking callback registered");
}
unsigned int transport_dbg(transaction_type& trans)
{
if (m_transport_dbg_ptr) {
// forward call
sc_assert(m_mod);
return (m_mod->*m_transport_dbg_ptr)(trans);
}
// No debug support
return 0;
}
bool get_direct_mem_ptr(transaction_type& trans,
tlm::tlm_dmi& dmi_data)
{
if (m_get_direct_mem_ptr) {
// forward call
sc_assert(m_mod);
return (m_mod->*m_get_direct_mem_ptr)(trans, dmi_data);
}
// No DMI support
dmi_data.allow_read_write();
dmi_data.set_start_address(0x0);
dmi_data.set_end_address((sc_dt::uint64)-1);
return false;
}
private:
MODULE* m_mod;
NBTransportPtr m_nb_transport_ptr;
BTransportPtr m_b_transport_ptr;
TransportDbgPtr m_transport_dbg_ptr;
GetDirectMem_ptr m_get_direct_mem_ptr;
};
private:
const sc_core::sc_object* get_socket() const { return this; }
private:
process m_process;
};
template< typename MODULE, unsigned int BUSWIDTH = 32
, typename TYPES = tlm::tlm_base_protocol_types >
class passthrough_target_socket
: public passthrough_target_socket_b<MODULE,BUSWIDTH,TYPES>
{
typedef passthrough_target_socket_b<MODULE,BUSWIDTH,TYPES> socket_b;
public:
passthrough_target_socket() : socket_b() {}
explicit passthrough_target_socket(const char* name) : socket_b(name) {}
};
template< typename MODULE, unsigned int BUSWIDTH = 32
, typename TYPES = tlm::tlm_base_protocol_types >
class passthrough_target_socket_optional
: public passthrough_target_socket_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND>
{
typedef passthrough_target_socket_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
public:
passthrough_target_socket_optional() : socket_b() {}
explicit passthrough_target_socket_optional(const char* name) : socket_b(name) {}
};
//ID Tagged version
template< typename MODULE, unsigned int BUSWIDTH, typename TYPES
, sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND >
class passthrough_target_socket_tagged_b
: public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>
, protected passthrough_socket_base
{
public:
typedef typename TYPES::tlm_payload_type transaction_type;
typedef typename TYPES::tlm_phase_type phase_type;
typedef tlm::tlm_sync_enum sync_enum_type;
typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
typedef tlm::tlm_target_socket<BUSWIDTH,TYPES,1,POL> base_type;
static const char* default_name()
{ return sc_core::sc_gen_unique_name("passthrough_target_socket_tagged"); }
public:
explicit passthrough_target_socket_tagged_b(const char* n = default_name())
: base_type(n)
, m_process(this)
{
bind(m_process);
}
using base_type::bind;
// REGISTER_XXX
void register_nb_transport_fw(MODULE* mod,
sync_enum_type (MODULE::*cb)(int id,
transaction_type&,
phase_type&,
sc_core::sc_time&),
int id)
{
m_process.set_nb_transport_ptr(mod, cb);
m_process.set_nb_transport_user_id(id);
}
void register_b_transport(MODULE* mod,
void (MODULE::*cb)(int id,
transaction_type&,
sc_core::sc_time&),
int id)
{
m_process.set_b_transport_ptr(mod, cb);
m_process.set_b_transport_user_id(id);
}
void register_transport_dbg(MODULE* mod,
unsigned int (MODULE::*cb)(int id,
transaction_type&),
int id)
{
m_process.set_transport_dbg_ptr(mod, cb);
m_process.set_transport_dbg_user_id(id);
}
void register_get_direct_mem_ptr(MODULE* mod,
bool (MODULE::*cb)(int id,
transaction_type&,
tlm::tlm_dmi&),
int id)
{
m_process.set_get_direct_mem_ptr(mod, cb);
m_process.set_get_dmi_user_id(id);
}
private:
class process
: public tlm::tlm_fw_transport_if<TYPES>
, protected convenience_socket_cb_holder
{
public:
typedef sync_enum_type (MODULE::*NBTransportPtr)(int id,
transaction_type&,
phase_type&,
sc_core::sc_time&);
typedef void (MODULE::*BTransportPtr)(int id,
transaction_type&,
sc_core::sc_time&);
typedef unsigned int (MODULE::*TransportDbgPtr)(int id,
transaction_type&);
typedef bool (MODULE::*GetDirectMem_ptr)(int id,
transaction_type&,
tlm::tlm_dmi&);
process(passthrough_socket_base* owner)
: convenience_socket_cb_holder(owner), m_mod(0)
, m_nb_transport_ptr(0)
, m_b_transport_ptr(0)
, m_transport_dbg_ptr(0)
, m_get_direct_mem_ptr(0)
, m_nb_transport_user_id(0)
, m_b_transport_user_id(0)
, m_transport_dbg_user_id(0)
, m_get_dmi_user_id(0)
{
}
void set_nb_transport_user_id(int id) { m_nb_transport_user_id = id; }
void set_b_transport_user_id(int id) { m_b_transport_user_id = id; }
void set_transport_dbg_user_id(int id) { m_transport_dbg_user_id = id; }
void set_get_dmi_user_id(int id) { m_get_dmi_user_id = id; }
void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
{
if (m_nb_transport_ptr) {
display_warning("non-blocking callback already registered");
return;
}
sc_assert(!m_mod || m_mod == mod);
m_mod = mod;
m_nb_transport_ptr = p;
}
void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
{
if (m_b_transport_ptr) {
display_warning("blocking callback already registered");
return;
}
sc_assert(!m_mod || m_mod == mod);
m_mod = mod;
m_b_transport_ptr = p;
}
void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
{
if (m_transport_dbg_ptr) {
display_warning("debug callback already registered");
return;
}
sc_assert(!m_mod || m_mod == mod);
m_mod = mod;
m_transport_dbg_ptr = p;
}
void set_get_direct_mem_ptr(MODULE* mod, GetDirectMem_ptr p)
{
if (m_get_direct_mem_ptr) {
display_warning("get DMI pointer callback already registered");
return;
}
sc_assert(!m_mod || m_mod == mod);
m_mod = mod;
m_get_direct_mem_ptr = p;
}
sync_enum_type nb_transport_fw(transaction_type& trans,
phase_type& phase,
sc_core::sc_time& t)
{
if (m_nb_transport_ptr) {
// forward call
sc_assert(m_mod);
return (m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, trans, phase, t);
}
display_error("no non-blocking callback registered");
return tlm::TLM_COMPLETED;
}
void b_transport(transaction_type& trans, sc_core::sc_time& t)
{
if (m_b_transport_ptr) {
// forward call
sc_assert(m_mod);
return (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, trans, t);
}
display_error("no blocking callback registered");
}
unsigned int transport_dbg(transaction_type& trans)
{
if (m_transport_dbg_ptr) {
// forward call
sc_assert(m_mod);
return (m_mod->*m_transport_dbg_ptr)(m_transport_dbg_user_id, trans);
}
// No debug support
return 0;
}
bool get_direct_mem_ptr(transaction_type& trans,
tlm::tlm_dmi& dmi_data)
{
if (m_get_direct_mem_ptr) {
// forward call
sc_assert(m_mod);
return (m_mod->*m_get_direct_mem_ptr)(m_get_dmi_user_id, trans, dmi_data);
}
// No DMI support
dmi_data.allow_read_write();
dmi_data.set_start_address(0x0);
dmi_data.set_end_address((sc_dt::uint64)-1);
return false;
}
private:
MODULE* m_mod;
NBTransportPtr m_nb_transport_ptr;
BTransportPtr m_b_transport_ptr;
TransportDbgPtr m_transport_dbg_ptr;
GetDirectMem_ptr m_get_direct_mem_ptr;
int m_nb_transport_user_id;
int m_b_transport_user_id;
int m_transport_dbg_user_id;
int m_get_dmi_user_id;
};
private:
const sc_core::sc_object* get_socket() const { return this; }
private:
process m_process;
};
template< typename MODULE, unsigned int BUSWIDTH = 32
, typename TYPES = tlm::tlm_base_protocol_types >
class passthrough_target_socket_tagged
: public passthrough_target_socket_tagged_b<MODULE,BUSWIDTH,TYPES>
{
typedef passthrough_target_socket_tagged_b<MODULE,BUSWIDTH,TYPES> socket_b;
public:
passthrough_target_socket_tagged() : socket_b() {}
explicit passthrough_target_socket_tagged(const char* name) : socket_b(name) {}
};
template< typename MODULE, unsigned int BUSWIDTH = 32
, typename TYPES = tlm::tlm_base_protocol_types >
class passthrough_target_socket_tagged_optional
: public passthrough_target_socket_tagged_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND>
{
typedef passthrough_target_socket_tagged_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
public:
passthrough_target_socket_tagged_optional() : socket_b() {}
explicit passthrough_target_socket_tagged_optional(const char* name) : socket_b(name) {}
};
} // namespace tlm_utils
#endif // TLM_UTILS_PASSTHROUGH_TARGET_SOCKET_H_INCLUDED_

View File

@@ -0,0 +1,301 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
// 12-Jan-2009 John Aynsley Bug fix. Phase argument to notify should be const
// 20-Mar-2009 John Aynsley Add cancel_all() method
#ifndef __PEQ_WITH_CB_AND_PHASE_H__
#define __PEQ_WITH_CB_AND_PHASE_H__
#ifndef SC_INCLUDE_DYNAMIC_PROCESSES // needed for sc_spawn
# define SC_INCLUDE_DYNAMIC_PROCESSES
#endif
#include <vector>
#include <systemc>
#include <tlm>
namespace tlm_utils {
template <typename PAYLOAD>
class time_ordered_list
{
public:
struct element
{
struct element *next;
PAYLOAD p;
sc_core::sc_time t;
sc_dt::uint64 d;
element(PAYLOAD& p, sc_core::sc_time t, sc_dt::uint64 d): p(p),t(t),d(d) {}
element(){}
};
element *nill;
element *empties;
element *list;
unsigned int size;
time_ordered_list()
: nill(new element()),
empties(NULL),
list(nill),
size(0)
{
}
~time_ordered_list() {
reset();
while(empties){
struct element *e=empties->next;
delete empties;
empties=e;
}
delete nill;
}
void reset() {
while(size) {
delete_top();
}
}
void insert(const PAYLOAD& p, sc_core::sc_time t) {
if (!empties) {
empties=new struct element();
empties->next=NULL;
}
struct element *e=empties;
empties=empties->next;
e->p=p;
e->t=t;
e->d=sc_core::sc_delta_count();
struct element * ancestor=nill;
struct element * iterator=list;
while (iterator!=nill && iterator->t<=t){
ancestor=iterator;
iterator=iterator->next;
}
if (ancestor==nill){
e->next=list;
list=e;
}
else {
e->next=iterator;
ancestor->next=e;
}
size++;
}
void delete_top(){
if (list != nill) {
struct element *e=list;
list=list->next;
e->next=empties;
empties=e;
size--;
}
}
unsigned int get_size()
{
return size;
}
PAYLOAD &top()
{
return list->p;
}
sc_core::sc_time top_time()
{
return list->t;
}
sc_dt::uint64& top_delta()
{
return list->d;
}
sc_core::sc_time next_time()
{
return list->next->t;
}
};
//---------------------------------------------------------------------------
/**
* An event queue that can contain any number of pending
* notifications. Each notification have an associate payload.
*/
//---------------------------------------------------------------------------
template<typename OWNER,typename TYPES=tlm::tlm_base_protocol_types>
class peq_with_cb_and_phase:
public sc_core::sc_object
{
typedef typename TYPES::tlm_payload_type tlm_payload_type;
typedef typename TYPES::tlm_phase_type tlm_phase_type;
typedef std::pair<tlm_payload_type*, tlm_phase_type> PAYLOAD;
typedef void (OWNER::*cb)(tlm_payload_type&, const tlm_phase_type&);
class delta_list{
public:
delta_list(){
reset();
entries.resize(100);
}
inline void insert(const PAYLOAD& p){
if (size==entries.size()){
entries.resize(entries.size()*2);
}
entries[size++]=p;
}
inline PAYLOAD& get(){
return entries[out++];
}
inline bool next(){
return out<size;
}
inline void reset(){
size=0;
out=0;
}
public:
unsigned int size;
private:
std::vector<PAYLOAD> entries;
unsigned int out;
};
public:
peq_with_cb_and_phase(OWNER* _owner, cb _cb)
:sc_core::sc_object( sc_core::sc_gen_unique_name( "peq_with_cb_and_phase" ) )
,m_owner(_owner)
,m_cb(_cb)
{
sc_core::sc_spawn_options opts;
opts.spawn_method();
opts.set_sensitivity(&m_e);
opts.dont_initialize();
sc_core::sc_spawn(sc_bind(&peq_with_cb_and_phase::fec, this),
sc_core::sc_gen_unique_name("fec"), &opts);
}
peq_with_cb_and_phase(const char* _name, OWNER* _owner,cb _cb)
: sc_core::sc_object( _name )
,m_owner(_owner)
,m_cb(_cb)
{
sc_core::sc_spawn_options opts;
opts.spawn_method();
opts.set_sensitivity(&m_e);
opts.dont_initialize();
sc_core::sc_spawn(sc_bind(&peq_with_cb_and_phase::fec, this),
sc_core::sc_gen_unique_name("fec"), &opts);
}
~peq_with_cb_and_phase(){}
void notify (tlm_payload_type& t, const tlm_phase_type& p, const sc_core::sc_time& when){
//t.aquire();
if (when==sc_core::SC_ZERO_TIME) {
if (sc_core::sc_delta_count() & (sc_dt::uint64)0x1) //uneven delta cycle so delta delay is for even cylce
m_even_delta.insert(PAYLOAD(&t,p));
else
m_uneven_delta.insert(PAYLOAD(&t,p)); //even delta cycle so delta delay is for uneven delta
m_e.notify(sc_core::SC_ZERO_TIME);
}
else {
m_ppq.insert(PAYLOAD(&t,p), when + sc_core::sc_time_stamp() );
m_e.notify(when); // note, this will only over-right the "newest" event.
}
}
void notify (tlm_payload_type& t, const tlm_phase_type& p){
m_immediate_yield.insert(PAYLOAD(&t,p));
m_e.notify(); // immediate notification
}
// Cancel all events from the event queue
void cancel_all() {
m_ppq.reset();
m_uneven_delta.reset();
m_even_delta.reset();
m_immediate_yield.reset();
m_e.cancel();
}
private:
void fec(){
//immediate yield notifications
while(m_immediate_yield.next()) {PAYLOAD& tmp=m_immediate_yield.get(); (m_owner->*m_cb)(*tmp.first, tmp.second);} //tmp.first->release();}
m_immediate_yield.reset();
//delta notifications
if (sc_core::sc_delta_count() & (sc_dt::uint64) 0x1) {//uneven delta so put out all payloads for uneven delta
while (m_uneven_delta.next()) {PAYLOAD& tmp=m_uneven_delta.get(); (m_owner->*m_cb)(*tmp.first, tmp.second);} //tmp.first->release();}
m_uneven_delta.reset();
if (m_even_delta.size) m_e.notify(sc_core::SC_ZERO_TIME);
}
else {
while (m_even_delta.next()) {PAYLOAD& tmp=m_even_delta.get(); (m_owner->*m_cb)(*tmp.first, tmp.second);} //tmp.first->release();}
m_even_delta.reset();
if (m_uneven_delta.size) m_e.notify(sc_core::SC_ZERO_TIME);
}
if (!m_ppq.get_size()) return; //there were only delta notification
//timed notifications
const sc_core::sc_time now=sc_core::sc_time_stamp();
sc_core::sc_time top=m_ppq.top_time();
while(m_ppq.get_size() && top==now) { // push all active ones into target
PAYLOAD& tmp=m_ppq.top();
(m_owner->*m_cb)(*tmp.first, tmp.second); //tmp.first->release();}
m_ppq.delete_top();
top=m_ppq.top_time();
}
if ( m_ppq.get_size()) {
m_e.notify( top - now) ;
}
}
OWNER* m_owner;
cb m_cb;
time_ordered_list<PAYLOAD> m_ppq;
delta_list m_uneven_delta;
delta_list m_even_delta;
delta_list m_immediate_yield;
sc_core::sc_event m_e; // default event
};
}
#endif // __PEQ_WITH_CB_AND_PHASE_H__

View File

@@ -0,0 +1,94 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
// 12-Jan-2009 John Aynsley Bug fix. sc_time argument to notify should be const
// 20-Mar-2009 John Aynsley Add cancel_all() method
#ifndef __PEQ_WITH_GET_H__
#define __PEQ_WITH_GET_H__
#include <systemc>
//#include <tlm>
#include <map>
namespace tlm_utils {
template <class PAYLOAD>
class peq_with_get : public sc_core::sc_object
{
public:
typedef PAYLOAD transaction_type;
typedef std::pair<const sc_core::sc_time, transaction_type*> pair_type;
public:
peq_with_get(const char* name) : sc_core::sc_object(name)
{
}
void notify(transaction_type& trans, const sc_core::sc_time& t)
{
m_scheduled_events.insert(pair_type(t + sc_core::sc_time_stamp(), &trans));
m_event.notify(t);
}
void notify(transaction_type& trans)
{
m_scheduled_events.insert(pair_type(sc_core::sc_time_stamp(), &trans));
m_event.notify(); // immediate notification
}
// needs to be called until it returns 0
transaction_type* get_next_transaction()
{
if (m_scheduled_events.empty()) {
return 0;
}
sc_core::sc_time now = sc_core::sc_time_stamp();
if (m_scheduled_events.begin()->first <= now) {
transaction_type* trans = m_scheduled_events.begin()->second;
m_scheduled_events.erase(m_scheduled_events.begin());
return trans;
}
m_event.notify(m_scheduled_events.begin()->first - now);
return 0;
}
sc_core::sc_event& get_event()
{
return m_event;
}
// Cancel all events from the event queue
void cancel_all() {
m_scheduled_events.clear();
m_event.cancel();
}
private:
std::multimap<const sc_core::sc_time, transaction_type*> m_scheduled_events;
sc_core::sc_event m_event;
};
}
#endif

View File

@@ -0,0 +1,316 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#ifndef TLM_UTILS_SIMPLE_INITIATOR_SOCKET_H_INCLUDED_
#define TLM_UTILS_SIMPLE_INITIATOR_SOCKET_H_INCLUDED_
#include <tlm>
#include "tlm_utils/convenience_socket_bases.h"
namespace tlm_utils {
template< typename MODULE, unsigned int BUSWIDTH, typename TYPES
, sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND >
class simple_initiator_socket_b
: public tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL>
, protected simple_socket_base
{
public:
typedef typename TYPES::tlm_payload_type transaction_type;
typedef typename TYPES::tlm_phase_type phase_type;
typedef tlm::tlm_sync_enum sync_enum_type;
typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
typedef tlm::tlm_initiator_socket<BUSWIDTH,TYPES,1,POL> base_type;
public:
static const char* default_name()
{ return sc_core::sc_gen_unique_name("simple_initiator_socket"); }
explicit simple_initiator_socket_b(const char* n = default_name())
: base_type(n)
, m_process(this)
{
this->m_export.bind(m_process);
}
void register_nb_transport_bw(MODULE* mod,
sync_enum_type (MODULE::*cb)(transaction_type&,
phase_type&,
sc_core::sc_time&))
{
m_process.set_transport_ptr(mod, cb);
}
void register_invalidate_direct_mem_ptr(MODULE* mod,
void (MODULE::*cb)(sc_dt::uint64, sc_dt::uint64))
{
m_process.set_invalidate_direct_mem_ptr(mod, cb);
}
private:
class process
: public tlm::tlm_bw_transport_if<TYPES>
, protected convenience_socket_cb_holder
{
public:
typedef sync_enum_type (MODULE::*TransportPtr)(transaction_type&,
phase_type&,
sc_core::sc_time&);
typedef void (MODULE::*InvalidateDirectMemPtr)(sc_dt::uint64,
sc_dt::uint64);
explicit process(simple_socket_base* owner)
: convenience_socket_cb_holder(owner), m_mod(0)
, m_transport_ptr(0)
, m_invalidate_direct_mem_ptr(0)
{
}
void set_transport_ptr(MODULE* mod, TransportPtr p)
{
if (m_transport_ptr) {
display_warning("non-blocking callback already registered");
return;
}
sc_assert(!m_mod || m_mod == mod);
m_mod = mod;
m_transport_ptr = p;
}
void set_invalidate_direct_mem_ptr(MODULE* mod, InvalidateDirectMemPtr p)
{
if (m_invalidate_direct_mem_ptr) {
display_warning("invalidate DMI callback already registered");
return;
}
sc_assert(!m_mod || m_mod == mod);
m_mod = mod;
m_invalidate_direct_mem_ptr = p;
}
sync_enum_type nb_transport_bw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t)
{
if (m_transport_ptr) {
// forward call
sc_assert(m_mod);
return (m_mod->*m_transport_ptr)(trans, phase, t);
}
display_error("no transport callback registered");
return tlm::TLM_COMPLETED;
}
void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
sc_dt::uint64 end_range)
{
if (m_invalidate_direct_mem_ptr) {
// forward call
sc_assert(m_mod);
(m_mod->*m_invalidate_direct_mem_ptr)(start_range, end_range);
}
}
private:
MODULE* m_mod;
TransportPtr m_transport_ptr;
InvalidateDirectMemPtr m_invalidate_direct_mem_ptr;
};
private:
const sc_core::sc_object* get_socket() const { return this; }
private:
process m_process;
};
template< typename MODULE, unsigned int BUSWIDTH = 32
, typename TYPES = tlm::tlm_base_protocol_types >
class simple_initiator_socket
: public simple_initiator_socket_b<MODULE,BUSWIDTH,TYPES>
{
typedef simple_initiator_socket_b<MODULE,BUSWIDTH,TYPES> socket_b;
public:
simple_initiator_socket() : socket_b() {}
explicit simple_initiator_socket(const char* name) : socket_b(name) {}
};
template< typename MODULE, unsigned int BUSWIDTH = 32
, typename TYPES = tlm::tlm_base_protocol_types >
class simple_initiator_socket_optional
: public simple_initiator_socket_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND>
{
typedef simple_initiator_socket_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
public:
simple_initiator_socket_optional() : socket_b() {}
explicit simple_initiator_socket_optional(const char* name) : socket_b(name) {}
};
// Tagged version
template< typename MODULE, unsigned int BUSWIDTH, typename TYPES
, sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND >
class simple_initiator_socket_tagged_b
: public tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL>
, protected simple_socket_base
{
public:
typedef typename TYPES::tlm_payload_type transaction_type;
typedef typename TYPES::tlm_phase_type phase_type;
typedef tlm::tlm_sync_enum sync_enum_type;
typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
typedef tlm::tlm_initiator_socket<BUSWIDTH,TYPES,1,POL> base_type;
public:
static const char* default_name()
{ return sc_core::sc_gen_unique_name("simple_initiator_socket_tagged"); }
explicit simple_initiator_socket_tagged_b(const char* n = default_name())
: base_type(n)
, m_process(this)
{
this->m_export.bind(m_process);
}
void register_nb_transport_bw(MODULE* mod,
sync_enum_type (MODULE::*cb)(int,
transaction_type&,
phase_type&,
sc_core::sc_time&),
int id)
{
m_process.set_transport_ptr(mod, cb);
m_process.set_transport_user_id(id);
}
void register_invalidate_direct_mem_ptr(MODULE* mod,
void (MODULE::*cb)(int, sc_dt::uint64, sc_dt::uint64),
int id)
{
m_process.set_invalidate_direct_mem_ptr(mod, cb);
m_process.set_invalidate_dmi_user_id(id);
}
private:
class process
: public tlm::tlm_bw_transport_if<TYPES>
, protected convenience_socket_cb_holder
{
public:
typedef sync_enum_type (MODULE::*TransportPtr)(int,
transaction_type&,
phase_type&,
sc_core::sc_time&);
typedef void (MODULE::*InvalidateDirectMemPtr)(int,
sc_dt::uint64,
sc_dt::uint64);
explicit process(simple_socket_base* owner)
: convenience_socket_cb_holder(owner), m_mod(0)
, m_transport_ptr(0)
, m_invalidate_direct_mem_ptr(0)
, m_transport_user_id(0)
, m_invalidate_direct_mem_user_id(0)
{
}
void set_transport_user_id(int id) { m_transport_user_id = id; }
void set_invalidate_dmi_user_id(int id) { m_invalidate_direct_mem_user_id = id; }
void set_transport_ptr(MODULE* mod, TransportPtr p)
{
if (m_transport_ptr) {
display_warning("non-blocking callback already registered");
return;
}
sc_assert(!m_mod || m_mod == mod);
m_mod = mod;
m_transport_ptr = p;
}
void set_invalidate_direct_mem_ptr(MODULE* mod, InvalidateDirectMemPtr p)
{
if (m_invalidate_direct_mem_ptr) {
display_warning("invalidate DMI callback already registered");
return;
}
sc_assert(!m_mod || m_mod == mod);
m_mod = mod;
m_invalidate_direct_mem_ptr = p;
}
sync_enum_type nb_transport_bw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t)
{
if (m_transport_ptr) {
// forward call
sc_assert(m_mod);
return (m_mod->*m_transport_ptr)(m_transport_user_id, trans, phase, t);
}
display_error("no transport callback registered");
return tlm::TLM_COMPLETED;
}
void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
sc_dt::uint64 end_range)
{
if (m_invalidate_direct_mem_ptr) {
// forward call
sc_assert(m_mod);
(m_mod->*m_invalidate_direct_mem_ptr)(m_invalidate_direct_mem_user_id, start_range, end_range);
}
}
private:
MODULE* m_mod;
TransportPtr m_transport_ptr;
InvalidateDirectMemPtr m_invalidate_direct_mem_ptr;
int m_transport_user_id;
int m_invalidate_direct_mem_user_id;
};
private:
const sc_core::sc_object* get_socket() const { return this; }
private:
process m_process;
};
template< typename MODULE, unsigned int BUSWIDTH = 32
, typename TYPES = tlm::tlm_base_protocol_types >
class simple_initiator_socket_tagged
: public simple_initiator_socket_tagged_b<MODULE,BUSWIDTH,TYPES>
{
typedef simple_initiator_socket_tagged_b<MODULE,BUSWIDTH,TYPES> socket_b;
public:
simple_initiator_socket_tagged() : socket_b() {}
explicit simple_initiator_socket_tagged(const char* name) : socket_b(name) {}
};
template< typename MODULE, unsigned int BUSWIDTH = 32
, typename TYPES = tlm::tlm_base_protocol_types >
class simple_initiator_socket_tagged_optional
: public simple_initiator_socket_tagged_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND>
{
typedef simple_initiator_socket_tagged_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
public:
simple_initiator_socket_tagged_optional() : socket_b() {}
explicit simple_initiator_socket_tagged_optional(const char* name) : socket_b(name) {}
};
} // namespace tlm_utils
#endif // TLM_UTILS_SIMPLE_INITIATOR_SOCKET_H_INCLUDED_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,172 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
// 20-Mar-2009 John Aynsley Add set_and_sync() method
#ifndef __TLM_QUANTUMKEEPER_H__
#define __TLM_QUANTUMKEEPER_H__
#include "tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.h"
namespace tlm_utils {
//
// tlm_quantumkeeper class
//
// The tlm_quantumkeeper class is used to keep track of the local time in
// an initiator (how much it has run ahead of the SystemC time), to
// synchronize with SystemC time etc.
//
class tlm_quantumkeeper
{
public:
//
// Static setters/getters for the global quantum value.
//
// The global quantum is the maximum time an initiator can run ahead of
// systemC time. All initiators will synchronize on timingpoints that are
// multiples of the global quantum value.
//
static void set_global_quantum(const sc_core::sc_time& t)
{
tlm::tlm_global_quantum::instance().set(t);
}
static const sc_core::sc_time& get_global_quantum()
{
return tlm::tlm_global_quantum::instance().get();
}
public:
tlm_quantumkeeper() :
m_next_sync_point(sc_core::SC_ZERO_TIME),
m_local_time(sc_core::SC_ZERO_TIME)
{
}
virtual ~tlm_quantumkeeper() {}
//
// Increment the local time (the time the initiator is ahead of the
// systemC time) After incrementing the local time an initiator should
// check (with the need_sync method) if a sync is required.
//
virtual void inc(const sc_core::sc_time& t)
{
m_local_time += t;
}
//
// Sets the local time (the time the initiator is ahead of the
// systemC time) After changing the local time an initiator should
// check (with the need_sync method) if a sync is required.
//
virtual void set(const sc_core::sc_time& t)
{
m_local_time = t;
}
//
// Checks if a sync to systemC is required for this initiator. This will
// be the case if the local time becomes greater than the local (current)
// quantum value for this initiator.
//
virtual bool need_sync() const
{
return sc_core::sc_time_stamp() + m_local_time >= m_next_sync_point;
}
//
// Synchronize to systemC. This call will do a wait for the time the
// initiator was running ahead of systemC time and reset the
// tlm_quantumkeeper.
//
virtual void sync()
{
sc_core::wait(m_local_time);
reset();
}
//
// Non-virtual convenience method to set the local time and sync only if needed
//
void set_and_sync(const sc_core::sc_time& t)
{
set(t);
if (need_sync())
sync();
}
//
// Resets the local time to SC_ZERO_TIME and computes the value of the
// next local quantum. This method should be called by an initiator after
// a wait because of a synchronization request by a target (TLM_ACCEPTED,
// or TLM_UPDATED).
//
virtual void reset()
{
m_local_time = sc_core::SC_ZERO_TIME;
m_next_sync_point = sc_core::sc_time_stamp() + compute_local_quantum();
}
//
// Helper function to get the current systemC time, taken the local time
// into account. The current systemC time is calculated as the time
// returned by sc_time_stamp incremeneted with the time the initiator is
// running ahead.
//
virtual sc_core::sc_time get_current_time() const
{
return sc_core::sc_time_stamp() + m_local_time;
}
//
// Helper functions to get the time the initiator is running ahead of
// systenC (local time). This time should be passed to a target in the
// nb_transport call
//
virtual sc_core::sc_time get_local_time() const
{
return m_local_time;
}
protected:
//
// Calculate the next local quantum for this initiator.
//
// The method can be overloaded in a derived object if an initiator wants
// to use another local quantum. This derived object should also take the
// global quantum into account. It's local quantum should not be set to a
// value that is larger than the quantum returned by the
// compute_local_quantum of the tlm_global_quantum singleton.
//
virtual sc_core::sc_time compute_local_quantum()
{
return tlm::tlm_global_quantum::instance().compute_local_quantum();
}
protected:
sc_core::sc_time m_next_sync_point;
sc_core::sc_time m_local_time;
};
} // namespace tlm
#endif

View File

@@ -0,0 +1,367 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#include "tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h"
#include "sysc/utils/sc_typeindex.h" // sc_typeindex
#include <map>
#include <cstring> // std::memcpy et.al.
using sc_core::sc_type_index;
namespace tlm {
template class SC_API tlm_array<tlm_extension_base*>;
//---------------------------------------------------------------------------
// Classes for the extension mechanism
//---------------------------------------------------------------------------
/* anonymous */ namespace {
class tlm_extension_registry
{
typedef unsigned int key_type;
typedef std::map<sc_core::sc_type_index, key_type> type_map;
public:
static tlm_extension_registry& instance()
{
if (!instance_) // don't cleanup registry
instance_ = new tlm_extension_registry();
return *instance_;
}
unsigned int register_extension(sc_type_index type)
{
type_map::const_iterator it = ids_.find( type );
if( it == ids_.end() ) { // new extension - generate/store ID
type_map::value_type v( type, static_cast<key_type>(ids_.size()) );
ids_.insert( v );
return v.second;
}
return it->second;
}
static unsigned int max_num_extensions()
{ return (instance_) ? instance().ids_.size() : 0; }
private:
static tlm_extension_registry* instance_;
type_map ids_;
tlm_extension_registry() /* = default */ {}
}; // class tlm_extension_registry
tlm_extension_registry* tlm_extension_registry::instance_ = NULL;
} // anonymous namespace
unsigned int max_num_extensions()
{
return tlm_extension_registry::max_num_extensions();
}
unsigned int
tlm_extension_base::register_extension(const std::type_info& type)
{
return tlm_extension_registry::instance().register_extension(type);
}
//---------------------------------------------------------------------------
// The generic payload class:
//---------------------------------------------------------------------------
//---------------
// Constructors
//---------------
// Default constructor
tlm_generic_payload::tlm_generic_payload()
: m_address(0)
, m_command(TLM_IGNORE_COMMAND)
, m_data(0)
, m_length(0)
, m_response_status(TLM_INCOMPLETE_RESPONSE)
, m_dmi(false)
, m_byte_enable(0)
, m_byte_enable_length(0)
, m_streaming_width(0)
, m_gp_option(TLM_MIN_PAYLOAD)
, m_extensions(max_num_extensions())
, m_mm(0)
, m_ref_count(0)
{}
tlm_generic_payload::tlm_generic_payload(tlm_mm_interface* mm)
: m_address(0)
, m_command(TLM_IGNORE_COMMAND)
, m_data(0)
, m_length(0)
, m_response_status(TLM_INCOMPLETE_RESPONSE)
, m_dmi(false)
, m_byte_enable(0)
, m_byte_enable_length(0)
, m_streaming_width(0)
, m_gp_option(TLM_MIN_PAYLOAD)
, m_extensions(max_num_extensions())
, m_mm(mm)
, m_ref_count(0)
{}
void tlm_generic_payload::reset() {
//should the other members be reset too?
m_gp_option = TLM_MIN_PAYLOAD;
m_extensions.free_entire_cache();
};
// non-virtual deep-copying of the object
void
tlm_generic_payload::deep_copy_from(const tlm_generic_payload & other)
{
m_command = other.get_command();
m_address = other.get_address();
m_length = other.get_data_length();
m_response_status = other.get_response_status();
m_byte_enable_length = other.get_byte_enable_length();
m_streaming_width = other.get_streaming_width();
m_gp_option = other.get_gp_option();
m_dmi = other.is_dmi_allowed();
// deep copy data
// there must be enough space in the target transaction!
if(m_data && other.m_data)
{
std::memcpy(m_data, other.m_data, m_length);
}
// deep copy byte enables
// there must be enough space in the target transaction!
if(m_byte_enable && other.m_byte_enable)
{
std::memcpy(m_byte_enable, other.m_byte_enable, m_byte_enable_length);
}
// deep copy extensions (sticky and non-sticky)
if(m_extensions.size() < other.m_extensions.size()) {
m_extensions.expand(other.m_extensions.size());
}
for(unsigned int i=0; i<other.m_extensions.size(); i++)
{
if(other.m_extensions[i])
{ //original has extension i
if(!m_extensions[i])
{ //We don't: clone.
tlm_extension_base *ext = other.m_extensions[i]->clone();
if(ext) //extension may not be clonable.
{
if(has_mm())
{ //mm can take care of removing cloned extensions
set_auto_extension(i, ext);
}
else
{ // no mm, user will call free_all_extensions().
set_extension(i, ext);
}
}
}
else
{ //We already have such extension. Copy original over it.
m_extensions[i]->copy_from(*other.m_extensions[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
tlm_generic_payload::update_original_from(const tlm_generic_payload & other,
bool use_byte_enable_on_read)
{
// Copy back extensions that are present on the original
update_extensions_from(other);
// Copy back the response status and DMI hint attributes
m_response_status = other.get_response_status();
m_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() && m_data && other.m_data && m_data != other.m_data)
{
if (m_byte_enable && use_byte_enable_on_read)
{
if (m_byte_enable_length == 8 && m_length % 8 == 0 )
{
// Optimized implementation copies 64-bit words by masking
for (unsigned int i = 0; i < m_length; i += 8)
{
typedef sc_dt::uint64* u;
*reinterpret_cast<u>(&m_data[i]) &= ~*reinterpret_cast<u>(m_byte_enable);
*reinterpret_cast<u>(&m_data[i]) |= *reinterpret_cast<u>(&other.m_data[i]) &
*reinterpret_cast<u>(m_byte_enable);
}
}
else if (m_byte_enable_length == 4 && m_length % 4 == 0 )
{
// Optimized implementation copies 32-bit words by masking
for (unsigned int i = 0; i < m_length; i += 4)
{
typedef unsigned int* u;
*reinterpret_cast<u>(&m_data[i]) &= ~*reinterpret_cast<u>(m_byte_enable);
*reinterpret_cast<u>(&m_data[i]) |= *reinterpret_cast<u>(&other.m_data[i]) &
*reinterpret_cast<u>(m_byte_enable);
}
}
else
// Unoptimized implementation
for (unsigned int i = 0; i < m_length; i++)
if ( m_byte_enable[i % m_byte_enable_length] )
m_data[i] = other.m_data[i];
}
else
std::memcpy(m_data, other.m_data, m_length);
}
}
void
tlm_generic_payload::update_extensions_from(const tlm_generic_payload & other)
{
// deep copy extensions that are already present
sc_assert(m_extensions.size() <= other.m_extensions.size());
for(unsigned int i=0; i<m_extensions.size(); i++)
{
if(other.m_extensions[i])
{ //original has extension i
if(m_extensions[i])
{ //We have it too. copy.
m_extensions[i]->copy_from(*other.m_extensions[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 tlm_generic_payload::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
//--------------
tlm_generic_payload::~tlm_generic_payload() {
for(unsigned int i=0; i<m_extensions.size(); i++)
if(m_extensions[i]) m_extensions[i]->free();
}
//----------------
// API (including setters & getters)
//---------------
std::string
tlm_generic_payload::get_response_string() const
{
switch(m_response_status)
{
case TLM_OK_RESPONSE: return "TLM_OK_RESPONSE";
case TLM_INCOMPLETE_RESPONSE: return "TLM_INCOMPLETE_RESPONSE";
case TLM_GENERIC_ERROR_RESPONSE: return "TLM_GENERIC_ERROR_RESPONSE";
case TLM_ADDRESS_ERROR_RESPONSE: return "TLM_ADDRESS_ERROR_RESPONSE";
case TLM_COMMAND_ERROR_RESPONSE: return "TLM_COMMAND_ERROR_RESPONSE";
case TLM_BURST_ERROR_RESPONSE: return "TLM_BURST_ERROR_RESPONSE";
case TLM_BYTE_ENABLE_ERROR_RESPONSE: return "TLM_BYTE_ENABLE_ERROR_RESPONSE";
}
return "TLM_UNKNOWN_RESPONSE";
}
/* --------------------------------------------------------------------- */
/* Dynamic extension mechanism: */
/* --------------------------------------------------------------------- */
tlm_extension_base*
tlm_generic_payload::set_extension(unsigned int index,
tlm_extension_base* ext)
{
sc_assert(index < m_extensions.size());
tlm_extension_base* tmp = m_extensions[index];
m_extensions[index] = ext;
return tmp;
}
tlm_extension_base*
tlm_generic_payload::set_auto_extension(unsigned int index,
tlm_extension_base* ext)
{
sc_assert(index < m_extensions.size());
tlm_extension_base* tmp = m_extensions[index];
m_extensions[index] = ext;
if (!tmp) m_extensions.insert_in_cache(&m_extensions[index]);
sc_assert(m_mm != 0);
return tmp;
}
tlm_extension_base*
tlm_generic_payload::get_extension(unsigned int index) const
{
sc_assert(index < m_extensions.size());
return m_extensions[index];
}
void tlm_generic_payload::clear_extension(unsigned int index)
{
sc_assert(index < m_extensions.size());
m_extensions[index] = static_cast<tlm_extension_base*>(0);
}
void tlm_generic_payload::release_extension(unsigned int index)
{
sc_assert(index < m_extensions.size());
if (m_mm)
{
m_extensions.insert_in_cache(&m_extensions[index]);
}
else
{
m_extensions[index]->free();
m_extensions[index] = static_cast<tlm_extension_base*>(0);
}
}
void tlm_generic_payload::resize_extensions()
{
m_extensions.expand(max_num_extensions());
}
} // namespace tlm

View File

@@ -0,0 +1,113 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#include "tlm_core/tlm_2/tlm_generic_payload/tlm_phase.h"
#include "sysc/utils/sc_string_view.h"
#include "sysc/utils/sc_typeindex.h"
#include "sysc/utils/sc_report.h"
#include <cstring>
#include <map>
using sc_core::sc_string_view;
using sc_core::sc_type_index;
namespace tlm {
/* anonymous */ namespace {
struct tlm_phase_registry
{
typedef unsigned int key_type;
static tlm_phase_registry& instance()
{ static tlm_phase_registry inst; return inst; }
unsigned int register_phase(sc_type_index type, sc_string_view name)
{
type_map::const_iterator it = ids_.find( type );
if( name.empty() ) {
SC_REPORT_FATAL( sc_core::SC_ID_INTERNAL_ERROR_,
"unexpected empty tlm_phase name" );
return UNINITIALIZED_PHASE;
}
if( it == ids_.end() ) { // new phase - generate/store ID and name
type_map::value_type v( type, static_cast<key_type>(names_.size()) );
names_.push_back( name_table::value_type(name.data(), name.size()) );
ids_.insert( v );
return v.second;
}
if( names_[it->second] != name ) {
SC_REPORT_FATAL( sc_core::SC_ID_INTERNAL_ERROR_,
"tlm_phase registration failed: duplicate type info" );
sc_core::sc_abort();
}
return it->second;
}
const char* get_name( key_type id ) const
{
sc_assert( id < names_.size() );
return names_[id].c_str();
}
private:
typedef std::map<sc_type_index, key_type> type_map;
typedef std::vector<std::string> name_table;
type_map ids_;
name_table names_;
tlm_phase_registry()
: names_( END_RESP+1 )
{
# define BUILTIN_PHASE(phase) \
names_[phase] = #phase
BUILTIN_PHASE( UNINITIALIZED_PHASE );
BUILTIN_PHASE( BEGIN_REQ );
BUILTIN_PHASE( END_REQ );
BUILTIN_PHASE( BEGIN_RESP );
BUILTIN_PHASE( END_RESP );
}
}; // class tlm_phase_registry
} // anonymous namespace
tlm_phase::tlm_phase( unsigned int id )
: m_id(id)
{
// TODO: validate id?
// TODO: add deprecation warning?
}
tlm_phase::tlm_phase( const std::type_info& type, const char* name )
: m_id( tlm_phase_registry::instance().register_phase(type, name) )
{}
const char*
tlm_phase::get_name() const
{
return tlm_phase_registry::instance().get_name( m_id );
}
} // namespace tlm
// Taf!

View File

@@ -0,0 +1,49 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#include "tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.h"
#include "sysc/kernel/sc_simcontext.h" // sc_time_stamp
namespace tlm {
tlm_global_quantum::tlm_global_quantum()
: m_global_quantum(sc_core::SC_ZERO_TIME)
{}
tlm_global_quantum& tlm_global_quantum::instance()
{
static tlm_global_quantum instance_;
return instance_;
}
sc_core::sc_time
tlm_global_quantum::compute_local_quantum()
{
if (m_global_quantum != sc_core::SC_ZERO_TIME) {
const sc_core::sc_time current = sc_core::sc_time_stamp();
const sc_core::sc_time g_quant = m_global_quantum;
return g_quant - (current % g_quant);
} else {
return sc_core::SC_ZERO_TIME;
}
}
} // namespace tlm

View File

@@ -0,0 +1,84 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#include "tlm_utils/convenience_socket_bases.h"
#include "sysc/kernel/sc_object.h"
#include "sysc/kernel/sc_simcontext.h"
#include "sysc/utils/sc_report.h"
#include <sstream>
namespace tlm_utils {
void
convenience_socket_base::display_warning(const char* text) const
{
std::stringstream s;
s << get_socket()->name() << ": " << text;
SC_REPORT_WARNING(get_report_type(), s.str().c_str());
}
void
convenience_socket_base::display_error(const char* text) const
{
std::stringstream s;
s << get_socket()->name() << ": " << text;
SC_REPORT_ERROR(get_report_type(), s.str().c_str());
}
//simple helpers for warnings an errors to shorten in code notation
void
convenience_socket_cb_holder::display_warning(const char* msg) const
{
m_owner->display_warning(msg);
}
void
convenience_socket_cb_holder::display_error(const char* msg) const
{
m_owner->display_error(msg);
}
const char*
simple_socket_base::get_report_type() const {
return "/OSCI_TLM-2/simple_socket";
}
void
simple_socket_base::elaboration_check(const char* action) const
{
if (sc_core::sc_get_curr_simcontext()->elaboration_done()) {
std::stringstream s;
s << " elaboration completed, " << action << " not allowed";
display_error(s.str().c_str());
}
}
const char*
passthrough_socket_base::get_report_type() const {
return "/OSCI_TLM-2/passthrough_socket";
}
const char*
multi_socket_base::get_report_type() const {
return "/OSCI_TLM-2/multi_socket";
}
} // namespace tlm_utils

View File

@@ -0,0 +1,249 @@
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
#include "tlm_utils/instance_specific_extensions_int.h"
#include "sysc/utils/sc_typeindex.h" // sc_typeindex
#include <map>
#include <iostream>
namespace tlm {
template class SC_API tlm_array<tlm_utils::ispex_base*>;
} // namespace tlm
namespace tlm_utils {
/* anonymous */ namespace {
class ispex_registry // copied from tlm_gp.cpp
{
typedef unsigned int key_type;
typedef std::map<sc_core::sc_type_index, key_type> type_map;
public:
static ispex_registry& instance()
{
if (!instance_) // don't cleanup registry
instance_ = new ispex_registry();
return *instance_;
}
unsigned int register_extension(sc_core::sc_type_index type)
{
type_map::const_iterator it = ids_.find( type );
if( it == ids_.end() ) { // new extension - generate/store ID
type_map::value_type v( type, static_cast<key_type>(ids_.size()) );
ids_.insert( v );
return v.second;
}
return it->second;
}
static unsigned int max_num_extensions()
{ return (instance_) ? instance().ids_.size() : 0; }
private:
static ispex_registry* instance_;
type_map ids_;
ispex_registry() /* = default */ {}
}; // class ispex_registry
ispex_registry* ispex_registry::instance_ = NULL;
} // anonymous namespace
unsigned int
ispex_base::register_private_extension(const std::type_info& type)
{
return ispex_registry::instance().register_extension(type);
}
//Helper to do the numbering of private extension accessors
static unsigned int max_num_ispex_accessors(bool increment=false)
{
static unsigned int max_num = 0;
if (increment) ++max_num;
return max_num;
}
// ----------------------------------------------------------------------------
//the pool for the container, plain as can be
class instance_specific_extension_container_pool
{
instance_specific_extension_container_pool()
: unused(NULL){}
~instance_specific_extension_container_pool();
public:
static instance_specific_extension_container_pool& instance()
{
static instance_specific_extension_container_pool inst;
return inst;
}
instance_specific_extension_container* create();
void free(instance_specific_extension_container*);
private:
instance_specific_extension_container* unused;
}; // class instance_specific_extension_container_pool
instance_specific_extension_container*
instance_specific_extension_container_pool::create()
{
if (!unused) {
unused =new instance_specific_extension_container();
}
instance_specific_extension_container* tmp = unused;
unused = unused->next;
return tmp;
}
void
instance_specific_extension_container_pool::
free(instance_specific_extension_container* cont)
{
cont->next=unused;
unused=cont;
}
instance_specific_extension_container_pool::
~instance_specific_extension_container_pool()
{
while(unused) {
instance_specific_extension_container* tmp = unused;
unused=unused->next;
delete tmp;
}
}
// ----------------------------------------------------------------------------
instance_specific_extension_container*
instance_specific_extension_container::create()
{
return instance_specific_extension_container_pool::instance().create();
}
instance_specific_extension_container::instance_specific_extension_container()
: use_count(0)
, m_txn(NULL)
, m_release_fn(NULL)
, m_carrier(NULL)
, next(NULL)
{
resize();
}
void
instance_specific_extension_container::
attach_carrier(instance_specific_extension_carrier* carrier,
void* txn, release_fn* rel_fn)
{
m_txn = txn;
m_release_fn = rel_fn;
m_carrier = carrier;
}
void
instance_specific_extension_container::resize()
{
m_ispex_per_accessor.resize( max_num_ispex_accessors() );
for (unsigned int i=0; i < m_ispex_per_accessor.size(); ++i) {
m_ispex_per_accessor[i] = new instance_specific_extensions_per_accessor(this);
m_ispex_per_accessor[i]->resize_extensions();
}
}
instance_specific_extension_container::
~instance_specific_extension_container()
{
for (unsigned int i=0; i<m_ispex_per_accessor.size(); ++i)
delete m_ispex_per_accessor[i];
}
void
instance_specific_extension_container::inc_use_count()
{
use_count++;
}
void
instance_specific_extension_container::dec_use_count()
{
if ((--use_count)==0) { // if this container isn't used any more
// we release the carrier extension
m_release_fn(m_carrier, m_txn);
// we send it back to our pool
instance_specific_extension_container_pool::instance().free(this);
}
}
instance_specific_extensions_per_accessor*
instance_specific_extension_container::get_accessor(unsigned int idx)
{
return m_ispex_per_accessor[idx];
}
// ----------------------------------------------------------------------------
// non-templatized version with manual index:
ispex_base*
instance_specific_extensions_per_accessor::
set_extension(unsigned int index, ispex_base* ext)
{
resize_extensions();
ispex_base* tmp = m_extensions[index];
m_extensions[index] = ext;
if (!tmp && ext) m_container->inc_use_count();
return tmp;
}
ispex_base*
instance_specific_extensions_per_accessor::
get_extension(unsigned int index) const
{
return (index < m_extensions.size()) ? m_extensions[index] : NULL;
}
void
instance_specific_extensions_per_accessor::
clear_extension(unsigned int index)
{
if (index < m_extensions.size())
{
if (m_extensions[index]) m_container->dec_use_count();
m_extensions[index] = static_cast<ispex_base*>(0);
}
}
void
instance_specific_extensions_per_accessor::resize_extensions()
{
m_extensions.expand(ispex_registry::max_num_extensions());
}
// ----------------------------------------------------------------------------
instance_specific_extension_accessor::instance_specific_extension_accessor()
: m_index(max_num_ispex_accessors(true)-1)
{}
} // namespace tlm_utils