systemc: Initial import of TLM headers from Accellera.
authorGabe Black <gabeblack@google.com>
Sat, 8 Dec 2018 09:58:26 +0000 (01:58 -0800)
committerGabe Black <gabeblack@google.com>
Wed, 9 Jan 2019 01:31:53 +0000 (01:31 +0000)
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>

63 files changed:
src/systemc/ext/tlm [new file with mode: 0644]
src/systemc/ext/tlm.h [new file with mode: 0644]
src/systemc/ext/tlm_core/Makefile.am [new file with mode: 0644]
src/systemc/ext/tlm_core/Makefile.in [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/README.txt [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_analysis.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_analysis_fifo.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_analysis_if.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_analysis_port.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_analysis_triple.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_write_if.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_fifo_ifs.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_master_slave_ifs.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_tag.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_adapters/tlm_adapters.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/circular_buffer.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_peek.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_put_get.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_resize.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_put_get_imp.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_req_rsp_channels.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_event_finder.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_nonblocking_port.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_req_rsp.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_2/README.txt [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_2/tlm_2_interfaces/tlm_2_interfaces.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_2/tlm_2_interfaces/tlm_dmi.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_2/tlm_2_interfaces/tlm_fw_bw_ifs.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_array.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_endian_conv.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_generic_payload.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_helpers.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_2/tlm_quantum/tlm_quantum.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_2/tlm_sockets/tlm_base_socket_if.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_2/tlm_sockets/tlm_initiator_socket.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_2/tlm_sockets/tlm_sockets.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_2/tlm_sockets/tlm_target_socket.h [new file with mode: 0644]
src/systemc/ext/tlm_core/tlm_2/tlm_version.h [new file with mode: 0644]
src/systemc/ext/tlm_utils/Makefile.am [new file with mode: 0644]
src/systemc/ext/tlm_utils/Makefile.in [new file with mode: 0644]
src/systemc/ext/tlm_utils/README.txt [new file with mode: 0644]
src/systemc/ext/tlm_utils/convenience_socket_bases.h [new file with mode: 0644]
src/systemc/ext/tlm_utils/instance_specific_extensions.h [new file with mode: 0644]
src/systemc/ext/tlm_utils/instance_specific_extensions_int.h [new file with mode: 0644]
src/systemc/ext/tlm_utils/multi_passthrough_initiator_socket.h [new file with mode: 0644]
src/systemc/ext/tlm_utils/multi_passthrough_target_socket.h [new file with mode: 0644]
src/systemc/ext/tlm_utils/multi_socket_bases.h [new file with mode: 0644]
src/systemc/ext/tlm_utils/passthrough_target_socket.h [new file with mode: 0644]
src/systemc/ext/tlm_utils/peq_with_cb_and_phase.h [new file with mode: 0644]
src/systemc/ext/tlm_utils/peq_with_get.h [new file with mode: 0644]
src/systemc/ext/tlm_utils/simple_initiator_socket.h [new file with mode: 0644]
src/systemc/ext/tlm_utils/simple_target_socket.h [new file with mode: 0644]
src/systemc/ext/tlm_utils/tlm_quantumkeeper.h [new file with mode: 0644]
src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.cpp [new file with mode: 0644]
src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.cpp [new file with mode: 0644]
src/systemc/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.cpp [new file with mode: 0644]
src/systemc/tlm_utils/convenience_socket_bases.cpp [new file with mode: 0644]
src/systemc/tlm_utils/instance_specific_extensions.cpp [new file with mode: 0644]

diff --git a/src/systemc/ext/tlm b/src/systemc/ext/tlm
new file mode 100644 (file)
index 0000000..b4fb9fe
--- /dev/null
@@ -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_ */
diff --git a/src/systemc/ext/tlm.h b/src/systemc/ext/tlm.h
new file mode 100644 (file)
index 0000000..36d6263
--- /dev/null
@@ -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"
diff --git a/src/systemc/ext/tlm_core/Makefile.am b/src/systemc/ext/tlm_core/Makefile.am
new file mode 100644 (file)
index 0000000..38098a8
--- /dev/null
@@ -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)
diff --git a/src/systemc/ext/tlm_core/Makefile.in b/src/systemc/ext/tlm_core/Makefile.in
new file mode 100644 (file)
index 0000000..0202a6b
--- /dev/null
@@ -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:
diff --git a/src/systemc/ext/tlm_core/tlm_1/README.txt b/src/systemc/ext/tlm_core/tlm_1/README.txt
new file mode 100644 (file)
index 0000000..c7e1c5e
--- /dev/null
@@ -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)
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_analysis.h b/src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_analysis.h
new file mode 100644 (file)
index 0000000..777f714
--- /dev/null
@@ -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 
+
+
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_analysis_fifo.h b/src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_analysis_fifo.h
new file mode 100644 (file)
index 0000000..1f01b2a
--- /dev/null
@@ -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
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_analysis_if.h b/src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_analysis_if.h
new file mode 100644 (file)
index 0000000..bc24fee
--- /dev/null
@@ -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
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_analysis_port.h b/src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_analysis_port.h
new file mode 100644 (file)
index 0000000..9990925
--- /dev/null
@@ -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
+
+
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_analysis_triple.h b/src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_analysis_triple.h
new file mode 100644 (file)
index 0000000..f65a25a
--- /dev/null
@@ -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
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_write_if.h b/src/systemc/ext/tlm_core/tlm_1/tlm_analysis/tlm_write_if.h
new file mode 100644 (file)
index 0000000..b66a591
--- /dev/null
@@ -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
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h b/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h
new file mode 100644 (file)
index 0000000..4c13403
--- /dev/null
@@ -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
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_fifo_ifs.h b/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_fifo_ifs.h
new file mode 100644 (file)
index 0000000..d9b2b98
--- /dev/null
@@ -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
+
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_master_slave_ifs.h b/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_master_slave_ifs.h
new file mode 100644 (file)
index 0000000..5bac3c8
--- /dev/null
@@ -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
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_tag.h b/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_tag.h
new file mode 100644 (file)
index 0000000..230b77d
--- /dev/null
@@ -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
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_adapters/tlm_adapters.h b/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_adapters/tlm_adapters.h
new file mode 100644 (file)
index 0000000..1320718
--- /dev/null
@@ -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
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/circular_buffer.h b/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/circular_buffer.h
new file mode 100644 (file)
index 0000000..50309e3
--- /dev/null
@@ -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
+
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h b/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h
new file mode 100644 (file)
index 0000000..7b44a32
--- /dev/null
@@ -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
+
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_peek.h b/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_peek.h
new file mode 100644 (file)
index 0000000..e856c56
--- /dev/null
@@ -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
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_put_get.h b/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_put_get.h
new file mode 100644 (file)
index 0000000..2728e03
--- /dev/null
@@ -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
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_resize.h b/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_resize.h
new file mode 100644 (file)
index 0000000..39932fe
--- /dev/null
@@ -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
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_put_get_imp.h b/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_put_get_imp.h
new file mode 100644 (file)
index 0000000..36dbd21
--- /dev/null
@@ -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
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_req_rsp_channels.h b/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_req_rsp_channels.h
new file mode 100644 (file)
index 0000000..7bd5652
--- /dev/null
@@ -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
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_event_finder.h b/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_event_finder.h
new file mode 100644 (file)
index 0000000..4ca0428
--- /dev/null
@@ -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_
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_nonblocking_port.h b/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_nonblocking_port.h
new file mode 100644 (file)
index 0000000..0af1e34
--- /dev/null
@@ -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
diff --git a/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_req_rsp.h b/src/systemc/ext/tlm_core/tlm_1/tlm_req_rsp/tlm_req_rsp.h
new file mode 100644 (file)
index 0000000..88f1d0e
--- /dev/null
@@ -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__ */
diff --git a/src/systemc/ext/tlm_core/tlm_2/README.txt b/src/systemc/ext/tlm_core/tlm_2/README.txt
new file mode 100644 (file)
index 0000000..cb02af2
--- /dev/null
@@ -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 ) 
diff --git a/src/systemc/ext/tlm_core/tlm_2/tlm_2_interfaces/tlm_2_interfaces.h b/src/systemc/ext/tlm_core/tlm_2/tlm_2_interfaces/tlm_2_interfaces.h
new file mode 100644 (file)
index 0000000..8a0c543
--- /dev/null
@@ -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
+
diff --git a/src/systemc/ext/tlm_core/tlm_2/tlm_2_interfaces/tlm_dmi.h b/src/systemc/ext/tlm_core/tlm_2/tlm_2_interfaces/tlm_dmi.h
new file mode 100644 (file)
index 0000000..d7c3304
--- /dev/null
@@ -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 */
diff --git a/src/systemc/ext/tlm_core/tlm_2/tlm_2_interfaces/tlm_fw_bw_ifs.h b/src/systemc/ext/tlm_core/tlm_2/tlm_2_interfaces/tlm_fw_bw_ifs.h
new file mode 100644 (file)
index 0000000..59e81c6
--- /dev/null
@@ -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__ */
diff --git a/src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_array.h b/src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_array.h
new file mode 100644 (file)
index 0000000..1a49b08
--- /dev/null
@@ -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_ */
diff --git a/src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_endian_conv.h b/src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_endian_conv.h
new file mode 100644 (file)
index 0000000..cf17a1f
--- /dev/null
@@ -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
+
diff --git a/src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_generic_payload.h b/src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_generic_payload.h
new file mode 100644 (file)
index 0000000..3e25e56
--- /dev/null
@@ -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
+
diff --git a/src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h b/src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h
new file mode 100644 (file)
index 0000000..99bb1e9
--- /dev/null
@@ -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_ */
diff --git a/src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_helpers.h b/src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_helpers.h
new file mode 100644 (file)
index 0000000..da3abb4
--- /dev/null
@@ -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__ */
diff --git a/src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.h b/src/systemc/ext/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.h
new file mode 100644 (file)
index 0000000..a06ccc4
--- /dev/null
@@ -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!
diff --git a/src/systemc/ext/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.h b/src/systemc/ext/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.h
new file mode 100644 (file)
index 0000000..5c08acf
--- /dev/null
@@ -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_
diff --git a/src/systemc/ext/tlm_core/tlm_2/tlm_quantum/tlm_quantum.h b/src/systemc/ext/tlm_core/tlm_2/tlm_quantum/tlm_quantum.h
new file mode 100644 (file)
index 0000000..f06a463
--- /dev/null
@@ -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_
diff --git a/src/systemc/ext/tlm_core/tlm_2/tlm_sockets/tlm_base_socket_if.h b/src/systemc/ext/tlm_core/tlm_2/tlm_sockets/tlm_base_socket_if.h
new file mode 100644 (file)
index 0000000..c847835
--- /dev/null
@@ -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_
diff --git a/src/systemc/ext/tlm_core/tlm_2/tlm_sockets/tlm_initiator_socket.h b/src/systemc/ext/tlm_core/tlm_2/tlm_sockets/tlm_initiator_socket.h
new file mode 100644 (file)
index 0000000..b703ec2
--- /dev/null
@@ -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_
diff --git a/src/systemc/ext/tlm_core/tlm_2/tlm_sockets/tlm_sockets.h b/src/systemc/ext/tlm_core/tlm_2/tlm_sockets/tlm_sockets.h
new file mode 100644 (file)
index 0000000..013e292
--- /dev/null
@@ -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__ */
diff --git a/src/systemc/ext/tlm_core/tlm_2/tlm_sockets/tlm_target_socket.h b/src/systemc/ext/tlm_core/tlm_2/tlm_sockets/tlm_target_socket.h
new file mode 100644 (file)
index 0000000..0306432
--- /dev/null
@@ -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_
diff --git a/src/systemc/ext/tlm_core/tlm_2/tlm_version.h b/src/systemc/ext/tlm_core/tlm_2/tlm_version.h
new file mode 100644 (file)
index 0000000..3cf2300
--- /dev/null
@@ -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__ */
diff --git a/src/systemc/ext/tlm_utils/Makefile.am b/src/systemc/ext/tlm_utils/Makefile.am
new file mode 100644 (file)
index 0000000..cd9e960
--- /dev/null
@@ -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)
diff --git a/src/systemc/ext/tlm_utils/Makefile.in b/src/systemc/ext/tlm_utils/Makefile.in
new file mode 100644 (file)
index 0000000..6c1469c
--- /dev/null
@@ -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:
diff --git a/src/systemc/ext/tlm_utils/README.txt b/src/systemc/ext/tlm_utils/README.txt
new file mode 100644 (file)
index 0000000..8be587b
--- /dev/null
@@ -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.
diff --git a/src/systemc/ext/tlm_utils/convenience_socket_bases.h b/src/systemc/ext/tlm_utils/convenience_socket_bases.h
new file mode 100644 (file)
index 0000000..81efaac
--- /dev/null
@@ -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_
diff --git a/src/systemc/ext/tlm_utils/instance_specific_extensions.h b/src/systemc/ext/tlm_utils/instance_specific_extensions.h
new file mode 100644 (file)
index 0000000..5d9f66b
--- /dev/null
@@ -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_
diff --git a/src/systemc/ext/tlm_utils/instance_specific_extensions_int.h b/src/systemc/ext/tlm_utils/instance_specific_extensions_int.h
new file mode 100644 (file)
index 0000000..192a600
--- /dev/null
@@ -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_
diff --git a/src/systemc/ext/tlm_utils/multi_passthrough_initiator_socket.h b/src/systemc/ext/tlm_utils/multi_passthrough_initiator_socket.h
new file mode 100644 (file)
index 0000000..0a0dd69
--- /dev/null
@@ -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_
diff --git a/src/systemc/ext/tlm_utils/multi_passthrough_target_socket.h b/src/systemc/ext/tlm_utils/multi_passthrough_target_socket.h
new file mode 100644 (file)
index 0000000..0b759d4
--- /dev/null
@@ -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_
diff --git a/src/systemc/ext/tlm_utils/multi_socket_bases.h b/src/systemc/ext/tlm_utils/multi_socket_bases.h
new file mode 100644 (file)
index 0000000..d937511
--- /dev/null
@@ -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_
diff --git a/src/systemc/ext/tlm_utils/passthrough_target_socket.h b/src/systemc/ext/tlm_utils/passthrough_target_socket.h
new file mode 100644 (file)
index 0000000..b2c97ae
--- /dev/null
@@ -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_
diff --git a/src/systemc/ext/tlm_utils/peq_with_cb_and_phase.h b/src/systemc/ext/tlm_utils/peq_with_cb_and_phase.h
new file mode 100644 (file)
index 0000000..60f96e6
--- /dev/null
@@ -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__
diff --git a/src/systemc/ext/tlm_utils/peq_with_get.h b/src/systemc/ext/tlm_utils/peq_with_get.h
new file mode 100644 (file)
index 0000000..5c85f25
--- /dev/null
@@ -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
diff --git a/src/systemc/ext/tlm_utils/simple_initiator_socket.h b/src/systemc/ext/tlm_utils/simple_initiator_socket.h
new file mode 100644 (file)
index 0000000..0cf9c56
--- /dev/null
@@ -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_
diff --git a/src/systemc/ext/tlm_utils/simple_target_socket.h b/src/systemc/ext/tlm_utils/simple_target_socket.h
new file mode 100644 (file)
index 0000000..7e4c3a1
--- /dev/null
@@ -0,0 +1,1132 @@
+/*****************************************************************************
+
+  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.
+
+ *****************************************************************************/
+
+// *****************************************************************************
+// Modified by John Aynsley, Doulos, Feb 2009,
+// Fix a bug in simple_target_socket and simple_target_socket_tagged
+// with the addition of one new line of code in each:  wait(*e);
+// *****************************************************************************
+
+// *****************************************************************************
+// Modified by John Aynsley on behalf of Robert Guenzel, May 2011,
+// Fix a bug in simple_target_socket and simple_target_socket_tagged
+// with the addition of one new line of code in each:  wait(t);
+// *****************************************************************************
+
+
+#ifndef TLM_UTILS_SIMPLE_TARGET_SOCKET_H_INCLUDED_
+#define TLM_UTILS_SIMPLE_TARGET_SOCKET_H_INCLUDED_
+
+#ifndef SC_INCLUDE_DYNAMIC_PROCESSES // needed for sc_spawn
+#  define SC_INCLUDE_DYNAMIC_PROCESSES
+#endif
+
+#include <systemc>
+#include <tlm>
+#include "tlm_utils/convenience_socket_bases.h"
+#include "tlm_utils/peq_with_get.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_target_socket_b
+  : public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>
+  , protected simple_socket_base
+{
+  friend class fw_process;
+  friend class bw_process;
+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("simple_target_socket"); }
+
+  explicit simple_target_socket_b(const char* n = default_name())
+    : base_type(n)
+    , m_fw_process(this)
+    , m_bw_process(this)
+  {
+    bind(m_fw_process);
+  }
+
+  using base_type::bind;
+
+  // bw transport must come thru us.
+  tlm::tlm_bw_transport_if<TYPES> * operator ->() {return &m_bw_process;}
+
+  // REGISTER_XXX
+  void register_nb_transport_fw(MODULE* mod,
+                                sync_enum_type (MODULE::*cb)(transaction_type&,
+                                                             phase_type&,
+                                                             sc_core::sc_time&))
+  {
+    elaboration_check("register_nb_transport_fw");
+    m_fw_process.set_nb_transport_ptr(mod, cb);
+  }
+
+  void register_b_transport(MODULE* mod,
+                            void (MODULE::*cb)(transaction_type&,
+                                               sc_core::sc_time&))
+  {
+    elaboration_check("register_b_transport");
+    m_fw_process.set_b_transport_ptr(mod, cb);
+  }
+
+  void register_transport_dbg(MODULE* mod,
+                              unsigned int (MODULE::*cb)(transaction_type&))
+  {
+    elaboration_check("register_transport_dbg");
+    m_fw_process.set_transport_dbg_ptr(mod, cb);
+  }
+
+  void register_get_direct_mem_ptr(MODULE* mod,
+                                   bool (MODULE::*cb)(transaction_type&,
+                                                      tlm::tlm_dmi&))
+  {
+    elaboration_check("register_get_direct_mem_ptr");
+    m_fw_process.set_get_direct_mem_ptr(mod, cb);
+  }
+
+protected:
+  void start_of_simulation()
+  {
+    base_type::start_of_simulation();
+    m_fw_process.start_of_simulation();
+  }
+
+private:
+  //make call on bw path.
+  sync_enum_type bw_nb_transport(transaction_type &trans, phase_type &phase, sc_core::sc_time &t)
+  {
+    return base_type::operator ->()->nb_transport_bw(trans, phase, t);
+  }
+
+  void bw_invalidate_direct_mem_ptr(sc_dt::uint64 s,sc_dt::uint64 e)
+  {
+    base_type::operator ->()->invalidate_direct_mem_ptr(s, e);
+  }
+
+  //Helper class to handle bw path calls
+  // Needed to detect transaction end when called from b_transport.
+  class bw_process : public tlm::tlm_bw_transport_if<TYPES>
+  {
+  public:
+    bw_process(simple_target_socket_b *p_own) : m_owner(p_own)
+    {
+    }
+
+    sync_enum_type nb_transport_bw(transaction_type &trans, phase_type &phase, sc_core::sc_time &t)
+    {
+      typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
+        m_owner->m_pending_trans.find(&trans);
+
+      if(it == m_owner->m_pending_trans.end()) {
+        // Not a blocking call, forward.
+        return m_owner->bw_nb_transport(trans, phase, t);
+
+      }
+
+      if (phase == tlm::END_REQ) {
+        m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME);
+        return tlm::TLM_ACCEPTED;
+      }
+      if (phase == tlm::BEGIN_RESP) {
+        if (m_owner->m_current_transaction == &trans) {
+          m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME);
+        }
+        //TODO: add response-accept delay?
+        it->second->notify(t);
+        m_owner->m_pending_trans.erase(it);
+        return tlm::TLM_COMPLETED;
+      }
+      m_owner->display_error("invalid phase received");
+      return tlm::TLM_COMPLETED;
+    }
+
+    void invalidate_direct_mem_ptr(sc_dt::uint64 s,sc_dt::uint64 e)
+    {
+      return m_owner->bw_invalidate_direct_mem_ptr(s, e);
+    }
+
+  private:
+    simple_target_socket_b *m_owner;
+  };
+
+  class fw_process : public tlm::tlm_fw_transport_if<TYPES>,
+                    public tlm::tlm_mm_interface
+  {
+  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::*GetDirectMemPtr)(transaction_type&,
+                                            tlm::tlm_dmi&);
+
+    fw_process(simple_target_socket_b *p_own) :
+      m_owner(p_own),
+      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_peq(sc_core::sc_gen_unique_name("m_peq")),
+      m_response_in_progress(false)
+    {}
+
+    void start_of_simulation()
+    {
+      if (!m_b_transport_ptr && m_nb_transport_ptr) { // only spawn b2nb_thread, if needed
+        sc_core::sc_spawn_options opts;
+        opts.set_sensitivity(&m_peq.get_event());
+        opts.dont_initialize();
+        sc_core::sc_spawn(sc_bind(&fw_process::b2nb_thread, this),
+                          sc_core::sc_gen_unique_name("b2nb_thread"), &opts);
+      }
+    }
+
+    void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
+    {
+      if (m_nb_transport_ptr) {
+        m_owner->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) {
+        m_owner->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) {
+        m_owner->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, GetDirectMemPtr p)
+    {
+      if (m_get_direct_mem_ptr) {
+        m_owner->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;
+    }
+// Interface implementation
+    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);
+      }
+
+      // nb->b conversion
+      if (m_b_transport_ptr) {
+        if (phase == tlm::BEGIN_REQ) {
+          // prepare thread to do blocking call
+          process_handle_class * ph = m_process_handle.get_handle(&trans);
+
+          if (!ph) { // create new dynamic process
+            ph = new process_handle_class(&trans);
+            m_process_handle.put_handle(ph);
+
+            sc_core::sc_spawn_options opts;
+            opts.dont_initialize();
+            opts.set_sensitivity(&ph->m_e);
+
+            sc_core::sc_spawn(sc_bind(&fw_process::nb2b_thread,this, ph),
+                            sc_core::sc_gen_unique_name("nb2b_thread"), &opts);
+          }
+
+          ph->m_e.notify(t);
+          return tlm::TLM_ACCEPTED;
+        }
+        if (phase == tlm::END_RESP) {
+          m_response_in_progress = false;
+          m_end_response.notify(t);
+          return tlm::TLM_COMPLETED;
+        }
+        m_owner->display_error("invalid phase received");
+        return tlm::TLM_COMPLETED;
+      }
+      m_owner->display_error("no non-blocking transport 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);
+        (m_mod->*m_b_transport_ptr)(trans, t);
+        return;
+      }
+
+      // b->nb conversion
+      if (m_nb_transport_ptr) {
+        m_peq.notify(trans, t);
+        t = sc_core::SC_ZERO_TIME;
+
+        mm_end_event_ext mm_ext;
+        const bool mm_added = !trans.has_mm();
+
+        if (mm_added) {
+          trans.set_mm(this);
+          trans.set_auto_extension(&mm_ext);
+          trans.acquire();
+        }
+
+        // wait until transaction is finished
+        sc_core::sc_event end_event;
+        m_owner->m_pending_trans[&trans] = &end_event;
+        sc_core::wait(end_event);
+
+        if (mm_added) {
+          // release will not delete the transaction, it will notify mm_ext.done
+          trans.release();
+          if (trans.get_ref_count()) {
+            sc_core::wait(mm_ext.done);
+          }
+          trans.set_mm(0);
+        }
+        return;
+      }
+
+      // should not be reached
+      m_owner->display_error("no blocking transport 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:
+
+// dynamic process handler for nb2b conversion
+
+    class process_handle_class {
+    public:
+      explicit process_handle_class(transaction_type * trans)
+        : m_trans(trans),m_suspend(false) {}
+
+      transaction_type*  m_trans;
+      sc_core::sc_event  m_e;
+      bool m_suspend;
+    };
+
+    class process_handle_list {
+    public:
+      process_handle_list() {}
+
+      ~process_handle_list() {
+        for( typename std::vector<process_handle_class*>::iterator
+               it=v.begin(), end = v.end(); it != end; ++it )
+          delete *it;
+      }
+
+      process_handle_class* get_handle(transaction_type *trans)
+      {
+        typename std::vector<process_handle_class*>::iterator it;
+
+        for(it = v.begin(); it != v.end(); it++) {
+          if ((*it)->m_suspend) {  // found suspended dynamic process, re-use it
+            (*it)->m_trans   = trans; // replace to new one
+            (*it)->m_suspend = false;
+            return *it;
+          }
+        }
+        return NULL; // no suspended process
+      }
+
+      void put_handle(process_handle_class* ph)
+      {
+        v.push_back(ph);
+      }
+
+    private:
+      std::vector<process_handle_class*> v;
+    };
+
+    process_handle_list m_process_handle;
+
+
+    void nb2b_thread(process_handle_class* h)
+    {
+
+      while(1) {
+        transaction_type *trans = h->m_trans;
+        sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+
+        // forward call
+        sc_assert(m_mod);
+        (m_mod->*m_b_transport_ptr)(*trans, t);
+
+        sc_core::wait(t);
+
+        // return path
+        while (m_response_in_progress) {
+          sc_core::wait(m_end_response);
+        }
+        t = sc_core::SC_ZERO_TIME;
+        phase_type phase    = tlm::BEGIN_RESP;
+        sync_enum_type sync = m_owner->bw_nb_transport(*trans, phase, t);
+        if ( !(sync == tlm::TLM_COMPLETED ||
+              (sync == tlm::TLM_UPDATED && phase == tlm::END_RESP)) ) {
+          m_response_in_progress = true;
+        }
+
+        // suspend until next transaction
+        h->m_suspend = true;
+        sc_core::wait();
+      }
+    }
+
+    void b2nb_thread()
+    {
+      while (true) {
+        transaction_type* trans;
+        while ((trans = m_peq.get_next_transaction())!=0) {
+          sc_assert(m_mod);
+          sc_assert(m_nb_transport_ptr);
+          phase_type phase = tlm::BEGIN_REQ;
+          sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+
+          switch ((m_mod->*m_nb_transport_ptr)(*trans, phase, t)) {
+          case tlm::TLM_COMPLETED:
+          {
+            // notify transaction is finished
+            typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
+              m_owner->m_pending_trans.find(trans);
+            sc_assert(it != m_owner->m_pending_trans.end());
+            it->second->notify(t);
+            m_owner->m_pending_trans.erase(it);
+            break;
+          }
+
+          case tlm::TLM_ACCEPTED:
+          case tlm::TLM_UPDATED:
+            switch (phase) {
+            case tlm::BEGIN_REQ:
+              m_owner->m_current_transaction = trans;
+              sc_core::wait(m_owner->m_end_request);
+              m_owner->m_current_transaction = 0;
+              break;
+
+            case tlm::END_REQ:
+              sc_core::wait(t);
+              break;
+
+            case tlm::BEGIN_RESP:
+            {
+              phase = tlm::END_RESP;
+              sc_core::wait(t);  // This line is a bug fix added in TLM-2.0.2
+              t = sc_core::SC_ZERO_TIME;
+              (m_mod->*m_nb_transport_ptr)(*trans, phase, t);
+
+              // notify transaction is finished
+              typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
+                m_owner->m_pending_trans.find(trans);
+              sc_assert(it != m_owner->m_pending_trans.end());
+              it->second->notify(t);
+              m_owner->m_pending_trans.erase(it);
+              break;
+            }
+
+            default:
+              m_owner->display_error("invalid phase received");
+            }
+            break;
+
+          default:
+            m_owner->display_error("invalid sync value received");
+          }
+        }
+        sc_core::wait();
+      }
+    }
+
+    void free(tlm::tlm_generic_payload* trans)
+    {
+      mm_end_event_ext* ext = trans->template get_extension<mm_end_event_ext>();
+      sc_assert(ext);
+      // notif event first before freeing extensions (reset)
+      ext->done.notify();
+      trans->reset();
+    }
+
+  private:
+    struct mm_end_event_ext : public tlm::tlm_extension<mm_end_event_ext>
+    {
+      tlm::tlm_extension_base* clone() const { return NULL; }
+      void free() {}
+      void copy_from(tlm::tlm_extension_base const &) {}
+      sc_core::sc_event done;
+    };
+
+  private:
+    simple_target_socket_b *m_owner;
+    MODULE* m_mod;
+    NBTransportPtr m_nb_transport_ptr;
+    BTransportPtr m_b_transport_ptr;
+    TransportDbgPtr m_transport_dbg_ptr;
+    GetDirectMemPtr m_get_direct_mem_ptr;
+    peq_with_get<transaction_type> m_peq;
+    bool m_response_in_progress;
+    sc_core::sc_event m_end_response;
+  };
+
+private:
+  const sc_core::sc_object* get_socket() const { return this; }
+private:
+  fw_process m_fw_process;
+  bw_process m_bw_process;
+  std::map<transaction_type*, sc_core::sc_event *> m_pending_trans;
+  sc_core::sc_event m_end_request;
+  transaction_type* m_current_transaction;
+};
+
+template< typename MODULE, unsigned int BUSWIDTH = 32
+        , typename TYPES = tlm::tlm_base_protocol_types >
+class simple_target_socket
+  : public simple_target_socket_b<MODULE,BUSWIDTH,TYPES>
+{
+  typedef simple_target_socket_b<MODULE,BUSWIDTH,TYPES> socket_b;
+public:
+  simple_target_socket() : socket_b() {}
+  explicit simple_target_socket(const char* name) : socket_b(name) {}
+};
+
+template< typename MODULE, unsigned int BUSWIDTH = 32
+        , typename TYPES = tlm::tlm_base_protocol_types >
+class simple_target_socket_optional
+  : public simple_target_socket_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND>
+{
+  typedef simple_target_socket_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
+public:
+  simple_target_socket_optional() : socket_b() {}
+  explicit simple_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 simple_target_socket_tagged_b
+  : public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>
+  , protected simple_socket_base
+{
+  friend class fw_process;
+  friend class bw_process;
+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("simple_target_socket_tagged"); }
+
+  explicit simple_target_socket_tagged_b(const char* n = default_name())
+    : base_type(n)
+    , m_fw_process(this)
+    , m_bw_process(this)
+  {
+    bind(m_fw_process);
+  }
+
+  using base_type::bind;
+
+  // bw transport must come thru us.
+  tlm::tlm_bw_transport_if<TYPES> * operator ->() {return &m_bw_process;}
+
+  // 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)
+  {
+    elaboration_check("register_nb_transport_fw");
+    m_fw_process.set_nb_transport_ptr(mod, cb);
+    m_fw_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)
+  {
+    elaboration_check("register_b_transport");
+    m_fw_process.set_b_transport_ptr(mod, cb);
+    m_fw_process.set_b_transport_user_id(id);
+  }
+
+  void register_transport_dbg(MODULE* mod,
+                              unsigned int (MODULE::*cb)(int id,
+                                                         transaction_type&),
+                              int id)
+  {
+    elaboration_check("register_transport_dbg");
+    m_fw_process.set_transport_dbg_ptr(mod, cb);
+    m_fw_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)
+  {
+    elaboration_check("register_get_direct_mem_ptr");
+    m_fw_process.set_get_direct_mem_ptr(mod, cb);
+    m_fw_process.set_get_dmi_user_id(id);
+  }
+
+protected:
+  void start_of_simulation()
+  {
+    base_type::start_of_simulation();
+    m_fw_process.start_of_simulation();
+  }
+
+private:
+  //make call on bw path.
+  sync_enum_type bw_nb_transport(transaction_type &trans, phase_type &phase, sc_core::sc_time &t)
+  {
+    return base_type::operator ->()->nb_transport_bw(trans, phase, t);
+  }
+
+  void bw_invalidate_direct_mem_ptr(sc_dt::uint64 s,sc_dt::uint64 e)
+  {
+    base_type::operator ->()->invalidate_direct_mem_ptr(s, e);
+  }
+
+  //Helper class to handle bw path calls
+  // Needed to detect transaction end when called from b_transport.
+  class bw_process : public tlm::tlm_bw_transport_if<TYPES>
+  {
+  public:
+    bw_process(simple_target_socket_tagged_b *p_own) : m_owner(p_own)
+    {
+    }
+
+    sync_enum_type nb_transport_bw(transaction_type &trans, phase_type &phase, sc_core::sc_time &t)
+    {
+      typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
+        m_owner->m_pending_trans.find(&trans);
+
+      if(it == m_owner->m_pending_trans.end()) {
+        // Not a blocking call, forward.
+        return m_owner->bw_nb_transport(trans, phase, t);
+      }
+      if (phase == tlm::END_REQ) {
+        m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME);
+        return tlm::TLM_ACCEPTED;
+      }
+      if (phase == tlm::BEGIN_RESP) {
+        if (m_owner->m_current_transaction == &trans) {
+          m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME);
+        }
+        //TODO: add response-accept delay?
+        it->second->notify(t);
+        m_owner->m_pending_trans.erase(it);
+        return tlm::TLM_COMPLETED;
+      }
+      m_owner->display_error("invalid phase received");
+      return tlm::TLM_COMPLETED;
+    }
+
+    void invalidate_direct_mem_ptr(sc_dt::uint64 s,sc_dt::uint64 e)
+    {
+      return m_owner->bw_invalidate_direct_mem_ptr(s, e);
+    }
+
+  private:
+    simple_target_socket_tagged_b *m_owner;
+  };
+
+  class fw_process : public tlm::tlm_fw_transport_if<TYPES>,
+                     public tlm::tlm_mm_interface
+  {
+  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::*GetDirectMemPtr)(int id,
+                                            transaction_type&,
+                                            tlm::tlm_dmi&);
+
+    fw_process(simple_target_socket_tagged_b *p_own) :
+      m_owner(p_own),
+      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),
+      m_peq(sc_core::sc_gen_unique_name("m_peq")),
+      m_response_in_progress(false)
+    {}
+
+    void start_of_simulation()
+    {
+      if (!m_b_transport_ptr && m_nb_transport_ptr) { // only spawn b2nb_thread, if needed
+        sc_core::sc_spawn_options opts;
+        opts.set_sensitivity(&m_peq.get_event());
+        opts.dont_initialize();
+        sc_core::sc_spawn(sc_bind(&fw_process::b2nb_thread, this),
+                          sc_core::sc_gen_unique_name("b2nb_thread"), &opts);
+      }
+    }
+
+    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) {
+        m_owner->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) {
+        m_owner->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) {
+        m_owner->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, GetDirectMemPtr p)
+    {
+      if (m_get_direct_mem_ptr) {
+        m_owner->display_warning("get DMI pointer callback already registered");
+      }
+      sc_assert(!m_mod || m_mod == mod);
+      m_mod = mod;
+      m_get_direct_mem_ptr = p;
+    }
+// Interface implementation
+    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);
+      }
+
+      // nb->b conversion
+      if (m_b_transport_ptr) {
+        if (phase == tlm::BEGIN_REQ) {
+
+          // prepare thread to do blocking call
+          process_handle_class * ph = m_process_handle.get_handle(&trans);
+
+          if (!ph) { // create new dynamic process
+            ph = new process_handle_class(&trans);
+            m_process_handle.put_handle(ph);
+
+            sc_core::sc_spawn_options opts;
+            opts.dont_initialize();
+            opts.set_sensitivity(&ph->m_e);
+
+            sc_core::sc_spawn(sc_bind(&fw_process::nb2b_thread, this, ph),
+                            sc_core::sc_gen_unique_name("nb2b_thread"), &opts);
+          }
+
+          ph->m_e.notify(t);
+          return tlm::TLM_ACCEPTED;
+        }
+        if (phase == tlm::END_RESP) {
+          m_response_in_progress = false;
+          m_end_response.notify(t);
+          return tlm::TLM_COMPLETED;
+        }
+        m_owner->display_error("invalid phase");
+        return tlm::TLM_COMPLETED;
+      }
+
+      m_owner->display_error("no non-blocking transport 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);
+        (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, trans, t);
+        return;
+      }
+
+      // b->nb conversion
+      if (m_nb_transport_ptr) {
+        m_peq.notify(trans, t);
+        t = sc_core::SC_ZERO_TIME;
+
+        mm_end_event_ext mm_ext;
+        const bool mm_added = !trans.has_mm();
+
+        if (mm_added){
+          trans.set_mm(this);
+          trans.set_auto_extension(&mm_ext);
+          trans.acquire();
+        }
+
+        // wait until transaction is finished
+        sc_core::sc_event end_event;
+        m_owner->m_pending_trans[&trans] = &end_event;
+        sc_core::wait(end_event);
+
+        if (mm_added) {
+          // release will not delete the transaction, it will notify mm_ext.done
+          trans.release();
+          if (trans.get_ref_count()) {
+            sc_core::wait(mm_ext.done);
+          }
+          trans.set_mm(0);
+        }
+        return;
+      }
+
+      m_owner->display_error("no transport 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:
+// dynamic process handler for nb2b conversion
+
+    class process_handle_class {
+    public:
+      explicit process_handle_class(transaction_type * trans)
+        : m_trans(trans),m_suspend(false){}
+
+      transaction_type*  m_trans;
+      sc_core::sc_event  m_e;
+      bool m_suspend;
+    };
+
+    class process_handle_list {
+    public:
+      process_handle_list() {}
+
+      ~process_handle_list() {
+        for( typename std::vector<process_handle_class*>::iterator
+               it=v.begin(), end = v.end(); it != end; ++it )
+          delete *it;
+      }
+
+      process_handle_class* get_handle(transaction_type *trans)
+      {
+        typename std::vector<process_handle_class*>::iterator it;
+
+        for(it = v.begin(); it != v.end(); it++) {
+          if ((*it)->m_suspend) {  // found suspended dynamic process, re-use it
+            (*it)->m_trans   = trans; // replace to new one
+            (*it)->m_suspend = false;
+            return *it;
+          }
+        }
+        return NULL; // no suspended process
+      }
+
+      void put_handle(process_handle_class* ph)
+      {
+        v.push_back(ph);
+      }
+
+    private:
+      std::vector<process_handle_class*> v;
+    };
+
+    process_handle_list m_process_handle;
+
+    void nb2b_thread(process_handle_class* h)
+    {
+
+      while(1) {
+        transaction_type * trans = h->m_trans;
+        sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+
+        // forward call
+        sc_assert(m_mod);
+        (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, *trans, t);
+
+        sc_core::wait(t);
+
+        // return path
+        while (m_response_in_progress) {
+          sc_core::wait(m_end_response);
+        }
+        t = sc_core::SC_ZERO_TIME;
+        phase_type phase    = tlm::BEGIN_RESP;
+        sync_enum_type sync = m_owner->bw_nb_transport(*trans, phase, t);
+        if ( !(sync == tlm::TLM_COMPLETED ||
+              (sync == tlm::TLM_UPDATED && phase == tlm::END_RESP)) ) {
+          m_response_in_progress = true;
+        }
+
+        // suspend until next transaction
+        h->m_suspend = true;
+        sc_core::wait();
+      }
+    }
+
+    void b2nb_thread()
+    {
+      while (true) {
+        transaction_type* trans;
+        while ((trans = m_peq.get_next_transaction())!=0) {
+          sc_assert(m_mod);
+          sc_assert(m_nb_transport_ptr);
+          phase_type phase = tlm::BEGIN_REQ;
+          sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+
+          switch ((m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, *trans, phase, t)) {
+          case tlm::TLM_COMPLETED:
+          {
+            // notify transaction is finished
+            typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
+              m_owner->m_pending_trans.find(trans);
+            sc_assert(it != m_owner->m_pending_trans.end());
+            it->second->notify(t);
+            m_owner->m_pending_trans.erase(it);
+            break;
+          }
+
+          case tlm::TLM_ACCEPTED:
+          case tlm::TLM_UPDATED:
+            switch (phase) {
+            case tlm::BEGIN_REQ:
+              m_owner->m_current_transaction = trans;
+              sc_core::wait(m_owner->m_end_request);
+              m_owner->m_current_transaction = 0;
+              break;
+
+            case tlm::END_REQ:
+              sc_core::wait(t);
+              break;
+
+            case tlm::BEGIN_RESP:
+            {
+              phase = tlm::END_RESP;
+              sc_core::wait(t);  // This line is a bug fix added in TLM-2.0.2
+              t = sc_core::SC_ZERO_TIME;
+              (m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, *trans, phase, t);
+
+              // notify transaction is finished
+              typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
+                m_owner->m_pending_trans.find(trans);
+              sc_assert(it != m_owner->m_pending_trans.end());
+              it->second->notify(t);
+              m_owner->m_pending_trans.erase(it);
+              break;
+            }
+
+            default:
+              m_owner->display_error("invalid phase received");
+            };
+            break;
+
+          default:
+            m_owner->display_error("invalid sync value received");
+          }
+        }
+        sc_core::wait();
+      }
+    }
+
+    void free(tlm::tlm_generic_payload* trans)
+    {
+      mm_end_event_ext* ext = trans->template get_extension<mm_end_event_ext>();
+      sc_assert(ext);
+      // notif event first before freeing extensions (reset)
+      ext->done.notify();
+      trans->reset();
+    }
+
+  private:
+    struct mm_end_event_ext : public tlm::tlm_extension<mm_end_event_ext>
+    {
+      tlm::tlm_extension_base* clone() const { return NULL; }
+      void free() {}
+      void copy_from(tlm::tlm_extension_base const &) {}
+      sc_core::sc_event done;
+    };
+
+  private:
+    simple_target_socket_tagged_b *m_owner;
+    MODULE* m_mod;
+    NBTransportPtr m_nb_transport_ptr;
+    BTransportPtr m_b_transport_ptr;
+    TransportDbgPtr m_transport_dbg_ptr;
+    GetDirectMemPtr 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;
+    peq_with_get<transaction_type> m_peq;
+    bool m_response_in_progress;
+    sc_core::sc_event m_end_response;
+  };
+
+private:
+  const sc_core::sc_object* get_socket() const { return this; }
+private:
+  fw_process m_fw_process;
+  bw_process m_bw_process;
+  std::map<transaction_type*, sc_core::sc_event *> m_pending_trans;
+  sc_core::sc_event m_end_request;
+  transaction_type* m_current_transaction;
+};
+
+template< typename MODULE, unsigned int BUSWIDTH = 32
+        , typename TYPES = tlm::tlm_base_protocol_types >
+class simple_target_socket_tagged
+  : public simple_target_socket_tagged_b<MODULE,BUSWIDTH,TYPES>
+{
+  typedef simple_target_socket_tagged_b<MODULE,BUSWIDTH,TYPES> socket_b;
+public:
+  simple_target_socket_tagged() : socket_b() {}
+  explicit simple_target_socket_tagged(const char* name) : socket_b(name) {}
+};
+
+template< typename MODULE, unsigned int BUSWIDTH = 32
+        , typename TYPES = tlm::tlm_base_protocol_types >
+class simple_target_socket_tagged_optional
+  : public simple_target_socket_tagged_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND>
+{
+  typedef simple_target_socket_tagged_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
+public:
+  simple_target_socket_tagged_optional() : socket_b() {}
+  explicit simple_target_socket_tagged_optional(const char* name) : socket_b(name) {}
+};
+
+} // namespace tlm_utils
+#endif // TLM_UTILS_SIMPLE_TARGET_SOCKET_H_INCLUDED_
diff --git a/src/systemc/ext/tlm_utils/tlm_quantumkeeper.h b/src/systemc/ext/tlm_utils/tlm_quantumkeeper.h
new file mode 100644 (file)
index 0000000..ed21166
--- /dev/null
@@ -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
diff --git a/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.cpp b/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.cpp
new file mode 100644 (file)
index 0000000..6843db3
--- /dev/null
@@ -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
diff --git a/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.cpp b/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.cpp
new file mode 100644 (file)
index 0000000..5f3fb25
--- /dev/null
@@ -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!
diff --git a/src/systemc/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.cpp b/src/systemc/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.cpp
new file mode 100644 (file)
index 0000000..8ac09cc
--- /dev/null
@@ -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
diff --git a/src/systemc/tlm_utils/convenience_socket_bases.cpp b/src/systemc/tlm_utils/convenience_socket_bases.cpp
new file mode 100644 (file)
index 0000000..5d03fd2
--- /dev/null
@@ -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
diff --git a/src/systemc/tlm_utils/instance_specific_extensions.cpp b/src/systemc/tlm_utils/instance_specific_extensions.cpp
new file mode 100644 (file)
index 0000000..9406dc8
--- /dev/null
@@ -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