systemc: Add some common test include files.
authorGabe Black <gabeblack@google.com>
Sat, 16 Jun 2018 03:02:54 +0000 (20:02 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 28 Aug 2018 21:16:31 +0000 (21:16 +0000)
These are "common" in the sense that they're not in a particular test
directory, but I think they're only used by one test.

Change-Id: I4ffd209d04ed0e5253085810913827b87412b302
Reviewed-on: https://gem5-review.googlesource.com/11272
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>

23 files changed:
src/systemc/tests/SConscript
src/systemc/tests/include/CoreDecouplingLTInitiator.h [new file with mode: 0644]
src/systemc/tests/include/ExplicitATTarget.h [new file with mode: 0644]
src/systemc/tests/include/ExplicitLTTarget.h [new file with mode: 0644]
src/systemc/tests/include/README.txt [new file with mode: 0644]
src/systemc/tests/include/SimpleATInitiator1.h [new file with mode: 0644]
src/systemc/tests/include/SimpleATInitiator2.h [new file with mode: 0644]
src/systemc/tests/include/SimpleATTarget1.h [new file with mode: 0644]
src/systemc/tests/include/SimpleATTarget2.h [new file with mode: 0644]
src/systemc/tests/include/SimpleBusAT.h [new file with mode: 0644]
src/systemc/tests/include/SimpleBusLT.h [new file with mode: 0644]
src/systemc/tests/include/SimpleLTInitiator1.h [new file with mode: 0644]
src/systemc/tests/include/SimpleLTInitiator1_DMI.h [new file with mode: 0644]
src/systemc/tests/include/SimpleLTInitiator2.h [new file with mode: 0644]
src/systemc/tests/include/SimpleLTInitiator2_DMI.h [new file with mode: 0644]
src/systemc/tests/include/SimpleLTInitiator3.h [new file with mode: 0644]
src/systemc/tests/include/SimpleLTInitiator3_DMI.h [new file with mode: 0644]
src/systemc/tests/include/SimpleLTTarget1.h [new file with mode: 0644]
src/systemc/tests/include/SimpleLTTarget2.h [new file with mode: 0644]
src/systemc/tests/include/specialized_signals/scx_signal_int.h [new file with mode: 0644]
src/systemc/tests/include/specialized_signals/scx_signal_signed.h [new file with mode: 0644]
src/systemc/tests/include/specialized_signals/scx_signal_uint.h [new file with mode: 0644]
src/systemc/tests/include/specialized_signals/scx_signal_unsigned.h [new file with mode: 0644]

index 81f122dabd4ce6c0103781471517b91f167b26dc..086ffee26f4a8eed059182ca78f96c0288302427 100644 (file)
@@ -62,6 +62,7 @@ if env['USE_SYSTEMC']:
             }
 
     ext_dir = Dir('..').Dir('ext')
+    test_dir = Dir('.')
     class SystemCTestBin(Executable):
         def __init__(self, test):
             super(SystemCTestBin, self).__init__(test.target, *test.sources)
@@ -75,6 +76,7 @@ if env['USE_SYSTEMC']:
             env['CCFLAGS'] = \
                 filter(lambda f: f not in to_remove, env['CCFLAGS'])
 
+            env.Append(CPPPATH=test_dir.Dir('include'))
             env.Append(CPPPATH=ext_dir)
 
             super(SystemCTestBin, cls).declare_all(env)
diff --git a/src/systemc/tests/include/CoreDecouplingLTInitiator.h b/src/systemc/tests/include/CoreDecouplingLTInitiator.h
new file mode 100644 (file)
index 0000000..b3c0e43
--- /dev/null
@@ -0,0 +1,166 @@
+/*****************************************************************************
+
+  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.
+
+ *****************************************************************************/
+
+//====================================================================
+//  Nov 06, 2008
+//
+//  Updated by:
+//    Xiaopeng Qiu, JEDA Technologies, Inc
+//    Email:  qiuxp@jedatechnologies.net
+//
+//  To fix violations of TLM2.0 rules, which are detected by JEDA 
+//  TLM2.0 checker.
+//
+//====================================================================
+
+#ifndef __CORE_DECOUPLING_LT_INITIATOR_H__
+#define __CORE_DECOUPLING_LT_INITIATOR_H__
+
+#include "tlm.h"
+#include "tlm_utils/simple_initiator_socket.h"
+#include "tlm_utils/tlm_quantumkeeper.h"
+//#include <systemc>
+#include <cassert>
+//#include <iostream>
+
+class CoreDecouplingLTInitiator : public sc_core::sc_module
+{
+public:
+  typedef tlm::tlm_generic_payload                         transaction_type;
+  typedef tlm_utils::simple_initiator_socket<CoreDecouplingLTInitiator> initiator_socket_type;
+
+public:
+  initiator_socket_type socket;
+
+public:
+  SC_HAS_PROCESS(CoreDecouplingLTInitiator);
+  CoreDecouplingLTInitiator(sc_core::sc_module_name name,
+                            unsigned int nrOfTransactions = 0x5,
+                            unsigned int baseAddress = 0) :
+    sc_core::sc_module(name),
+    socket("socket"),
+    mNrOfTransactions(nrOfTransactions),
+    mBaseAddress(baseAddress),
+    mTransactionCount(0)
+  {
+    tlm_utils::tlm_quantumkeeper::set_global_quantum(sc_core::sc_time(500, sc_core::SC_NS));
+    mQuantumKeeper.reset();
+
+    // Initiator thread
+    SC_THREAD(run);
+  }
+
+  bool initTransaction(transaction_type& trans)
+  {
+    if (mTransactionCount < mNrOfTransactions) {
+      trans.set_address(mBaseAddress + 4*mTransactionCount);
+      mData = mTransactionCount;
+      trans.set_command(tlm::TLM_WRITE_COMMAND);
+
+    } else if (mTransactionCount < 2 * mNrOfTransactions) {
+      trans.set_address(mBaseAddress + 4*(mTransactionCount - mNrOfTransactions));
+      mData = 0;
+      trans.set_command(tlm::TLM_READ_COMMAND);
+
+    } else {
+      return false;
+    }
+
+    trans.set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
+    trans.set_data_length(4);
+    trans.set_streaming_width(4);
+    trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
+
+    ++mTransactionCount;
+    return true;
+  }
+
+  void logStartTransation(transaction_type& trans)
+  {
+    if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+      std::cout << name() << ": Send write request: A = 0x"
+                << std::hex << (unsigned int)trans.get_address()
+                << ", D = 0x" << mData << std::dec
+                << " @ " << mQuantumKeeper.get_current_time()
+                << " (" << sc_core::sc_time_stamp() << " + "
+                << mQuantumKeeper.get_local_time() << ")"
+                << std::endl;
+      
+    } else {
+      std::cout << name() << ": Send read request: A = 0x"
+                << std::hex << (unsigned int)trans.get_address()
+                << " @ " << mQuantumKeeper.get_current_time()
+                << " (" << sc_core::sc_time_stamp() << " + "
+                << mQuantumKeeper.get_local_time() << ")"
+                << std::endl;
+    }
+  }
+
+  void logEndTransaction(transaction_type& trans)
+  {
+    if (trans.get_response_status() != tlm::TLM_OK_RESPONSE) {
+      std::cout << name() << ": Received error response @ "
+                << mQuantumKeeper.get_current_time()
+                << " (" << sc_core::sc_time_stamp() << " + "
+                << mQuantumKeeper.get_local_time() << ")"
+                << std::endl;
+
+    } else {
+      std::cout << name() <<  ": Received ok response";
+      if (trans.get_command() == tlm::TLM_READ_COMMAND) {
+          std::cout << ": D = 0x" << std::hex << mData << std::dec;
+      }
+      std::cout << " @ " << mQuantumKeeper.get_current_time()
+                << " (" << sc_core::sc_time_stamp() << " + "
+                << mQuantumKeeper.get_local_time() << ")"
+                << std::endl;
+    }
+  }
+
+  void run()
+  {
+    transaction_type trans;
+
+    while (initTransaction(trans)) {
+      logStartTransation(trans);
+      
+      // exec instr
+      sc_core::sc_time t = mQuantumKeeper.get_local_time();
+      socket->b_transport(trans, t);
+      mQuantumKeeper.set(t);
+      // Target may have added a delay to the quantum -> sync if needed
+      if (mQuantumKeeper.need_sync()) {
+        std::cout << "Sync'ing..." << std::endl;
+        mQuantumKeeper.sync();
+      }
+
+      logEndTransaction(trans);
+    }
+    wait();
+  }
+
+private:
+  unsigned int mNrOfTransactions;
+  unsigned int mBaseAddress;
+  unsigned int mTransactionCount;
+  unsigned int mData;
+  tlm_utils::tlm_quantumkeeper mQuantumKeeper;
+};
+
+#endif
diff --git a/src/systemc/tests/include/ExplicitATTarget.h b/src/systemc/tests/include/ExplicitATTarget.h
new file mode 100644 (file)
index 0000000..ccde70a
--- /dev/null
@@ -0,0 +1,176 @@
+/*****************************************************************************
+
+  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 __EXPLICIT_AT_TARGET_H__
+#define __EXPLICIT_AT_TARGET_H__
+
+#include "tlm.h"
+#include "tlm_utils/simple_target_socket.h"
+//#include <systemc>
+#include <cassert>
+#include <vector>
+#include <queue>
+//#include <iostream>
+
+class ExplicitATTarget : public sc_core::sc_module
+{
+public:
+  typedef tlm::tlm_generic_payload                 transaction_type;
+  typedef tlm::tlm_phase                           phase_type;
+  typedef tlm::tlm_sync_enum                       sync_enum_type;
+  typedef tlm_utils::simple_target_socket<ExplicitATTarget>     target_socket_type;
+
+public:
+  target_socket_type socket;
+
+public:
+  SC_HAS_PROCESS(ExplicitATTarget);
+  ExplicitATTarget(sc_core::sc_module_name name) :
+    sc_core::sc_module(name),
+    socket("socket"),
+    mCurrentTransaction(0)
+  {
+    // register nb_transport method
+    socket.register_nb_transport_fw(this, &ExplicitATTarget::myNBTransport);
+    socket.register_transport_dbg(this, &ExplicitATTarget::transport_dbg);
+
+    SC_THREAD(beginResponse)
+  }
+
+  sync_enum_type myNBTransport(transaction_type& trans, phase_type& phase, sc_core::sc_time& t)
+  {
+    if (phase == tlm::BEGIN_REQ) {
+      sc_dt::uint64 address = trans.get_address();
+      assert(address < 400);
+
+      // This target only supports one transaction at a time
+      // This will only work with LT initiators
+      assert(mCurrentTransaction == 0);
+
+      unsigned int& data = *reinterpret_cast<unsigned int*>(trans.get_data_ptr());
+      if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+        std::cout << name() << ": Received write request: A = 0x"
+                  << std::hex << (unsigned int)address << ", D = 0x" << data
+                  << std::dec << " @ " << sc_core::sc_time_stamp()
+                  << std::endl;
+
+        *reinterpret_cast<unsigned int*>(&mMem[address]) = data;
+
+        // Synchronization on demand (eg need to assert an interrupt)
+        mResponseEvent.notify(t);
+        mCurrentTransaction = &trans;
+
+        // End request phase
+        phase = tlm::END_REQ;
+        return tlm::TLM_UPDATED;
+
+      } else {
+        std::cout << name() << ": Received read request: A = 0x"
+                  << std::hex << (unsigned int)address
+                  << std::dec << " @ " << sc_core::sc_time_stamp()
+                  << std::endl;
+
+        data = *reinterpret_cast<unsigned int*>(&mMem[address]);
+        trans.set_response_status(tlm::TLM_OK_RESPONSE);
+
+        // Finish transaction (use timing annotation)
+        t += sc_core::sc_time(100, sc_core::SC_NS);
+        return tlm::TLM_COMPLETED;
+      }
+
+    } else if (phase == tlm::END_RESP) {
+
+      // Transaction finished
+      mCurrentTransaction = 0;
+      return tlm::TLM_COMPLETED;
+    }
+
+    // Not possible
+    assert(0); exit(1);
+//    return tlm::TLM_COMPLETED;  //unreachable code
+  }
+
+  void beginResponse()
+  {
+    while (true) {
+      // Wait for next synchronization request
+      wait(mResponseEvent);
+
+      assert(mCurrentTransaction);
+      // start response phase
+      phase_type phase = tlm::BEGIN_RESP;
+      sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+
+      // Set response data
+      mCurrentTransaction->set_response_status(tlm::TLM_OK_RESPONSE);
+      assert(mCurrentTransaction->get_command() == tlm::TLM_WRITE_COMMAND);
+
+      sc_dt::uint64 address = mCurrentTransaction->get_address();
+      assert(address < 400);
+      *reinterpret_cast<unsigned int*>(mCurrentTransaction->get_data_ptr()) =
+        *reinterpret_cast<unsigned int*>(&mMem[address]);
+
+      // We are synchronized, we can read/write sc_signals, wait,...
+      // Wait before sending the response
+      wait(50, sc_core::SC_NS);
+
+      if (socket->nb_transport_bw(*mCurrentTransaction, phase, t) == tlm::TLM_COMPLETED) {
+        mCurrentTransaction = 0;
+
+      } else {
+        // Initiator will call nb_transport(trans, END_RESP, t)
+      }
+    }
+  }
+
+  unsigned int transport_dbg(transaction_type& r)
+  {
+    if (r.get_address() >= 400) return 0;
+
+    unsigned int tmp = (int)r.get_address();
+    unsigned int num_bytes;
+    if (tmp + r.get_data_length() >= 400) {
+      num_bytes = 400 - tmp;
+
+    } else {
+      num_bytes = r.get_data_length();
+    }
+    if (!r.is_read() && !r.is_write()) {
+      return 0;
+       }
+    if (r.is_read()) {
+      for (unsigned int i = 0; i < num_bytes; ++i) {
+        r.get_data_ptr()[i] = mMem[i + tmp];
+      }
+
+    } else {
+      for (unsigned int i = 0; i < num_bytes; ++i) {
+        mMem[i + tmp] = r.get_data_ptr()[i];
+      }
+    }
+    return num_bytes;
+  }
+
+private:
+  unsigned char mMem[400];
+  sc_core::sc_event mResponseEvent;
+  transaction_type* mCurrentTransaction;
+};
+
+#endif
diff --git a/src/systemc/tests/include/ExplicitLTTarget.h b/src/systemc/tests/include/ExplicitLTTarget.h
new file mode 100644 (file)
index 0000000..2c308d9
--- /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.
+
+ *****************************************************************************/
+
+#ifndef __EXPLICIT_LT_TARGET_H__
+#define __EXPLICIT_LT_TARGET_H__
+
+#include "tlm.h"
+#include "tlm_utils/simple_target_socket.h"
+//#include <systemc>
+#include <cassert>
+#include <vector>
+#include <queue>
+//#include <iostream>
+
+class ExplicitLTTarget : public sc_core::sc_module
+{
+public:
+  typedef tlm::tlm_generic_payload                 transaction_type;
+  typedef tlm::tlm_phase                           phase_type;
+  typedef tlm::tlm_sync_enum                       sync_enum_type;
+  typedef tlm_utils::simple_target_socket<ExplicitLTTarget>     target_socket_type;
+
+public:
+  target_socket_type socket;
+
+public:
+  SC_HAS_PROCESS(ExplicitLTTarget);
+  ExplicitLTTarget(sc_core::sc_module_name name) :
+    sc_core::sc_module(name),
+    socket("socket")
+  {
+    // register nb_transport method
+    socket.register_b_transport(this, &ExplicitLTTarget::myBTransport);
+    socket.register_transport_dbg(this, &ExplicitLTTarget::transport_dbg);
+  }
+
+  void myBTransport(transaction_type& trans, sc_core::sc_time& t)
+  {
+    sc_dt::uint64 address = trans.get_address();
+    assert(address < 400);
+
+    unsigned int& data = *reinterpret_cast<unsigned int*>(trans.get_data_ptr());
+    if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+      std::cout << name() << ": Received write request: A = 0x"
+                << std::hex << (unsigned int)address << ", D = 0x" << data
+                << std::dec << " @ " << sc_core::sc_time_stamp()
+                << std::endl;
+
+      *reinterpret_cast<unsigned int*>(&mMem[address]) = data;
+
+      // Synchronization on demand (eg need to assert an interrupt)
+      // Wait for passed timing annotation + wait for an extra 50 ns
+      wait(t + sc_core::sc_time(50, sc_core::SC_NS));
+      t = sc_core::SC_ZERO_TIME;
+
+      // We are synchronized, we can read/write sc_signals, wait,...
+
+      *reinterpret_cast<unsigned int*>(trans.get_data_ptr()) =
+        *reinterpret_cast<unsigned int*>(&mMem[address]);
+
+    } else {
+      std::cout << name() << ": Received read request: A = 0x"
+                << std::hex << (unsigned int)address
+                << std::dec << " @ " << sc_core::sc_time_stamp()
+                << std::endl;
+
+      data = *reinterpret_cast<unsigned int*>(&mMem[address]);
+
+      // Finish transaction (use timing annotation)
+      t += sc_core::sc_time(100, sc_core::SC_NS);
+    }
+
+    trans.set_response_status(tlm::TLM_OK_RESPONSE);
+  }
+
+  unsigned int transport_dbg(transaction_type& r)
+  {
+    if (r.get_address() >= 400) return 0;
+
+    unsigned int tmp = (int)r.get_address();
+    unsigned int num_bytes;
+    if (tmp + r.get_data_length() >= 400) {
+      num_bytes = 400 - tmp;
+
+    } else {
+      num_bytes = r.get_data_length();
+    }
+    if (!r.is_read() && !r.is_write()) {
+      return 0;
+       }
+    if (r.is_read()) {
+      for (unsigned int i = 0; i < num_bytes; ++i) {
+        r.get_data_ptr()[i] = mMem[i + tmp];
+      }
+
+    } else {
+      for (unsigned int i = 0; i < num_bytes; ++i) {
+        mMem[i + tmp] = r.get_data_ptr()[i];
+      }
+    }
+    return num_bytes;
+  }
+
+private:
+  unsigned char mMem[400];
+};
+
+#endif
diff --git a/src/systemc/tests/include/README.txt b/src/systemc/tests/include/README.txt
new file mode 100644 (file)
index 0000000..2636918
--- /dev/null
@@ -0,0 +1,92 @@
+SimpleLTInitiator1/SimpleLTTarget1
+----------------------------------
+
+- LT Initiator/Target model using the base (standard) tlm socket
+- Added support for DMI in SimpleLTTarget1
+
+SimpleLTInitiator1_DMI
+----------------------
+
+- uses DMI transactions, the DMI structure is using the DMI-hint
+  to check if a DMI request would make sense.
+- uses a single transport_dbg transaction at end_of_simulation()
+
+SimpleLTInitiator2/SimpleLTTarget2
+----------------------------------
+
+- LT Initiator/Target model using the convenience tlm socket
+- Target and Initiator model use the REGISTER_DEBUGTRANSPORT macro to register
+  a transport callback to the socket
+- Added support for DMI handling, callback registration with
+  REGISTER_DMI
+- SimpleLTTarget2 does not register the transport_dbg callback, so that
+  we are able to test this case in bus_dmi.
+
+SimpleLTInitiator2_DMI
+----------------------
+
+- uses DMI transactions, but ignoring the DMI hint
+- uses a single transport_dbg transaction at end_of_simulation()
+
+SimpleLTInitiator3
+------------------
+
+- LT Initiator model using the convenience tlm socket
+- Initiator model uses the endEvent of the socket to wait until the
+  transaction is finished
+
+SimpleLTInitiator3_DMI
+----------------------
+
+- based on SimpleInitiator3, uses DMI (without DMI hint)
+
+SimpleATInitiator1/SimpleATTarget1
+----------------------------------
+
+- AT Initiator/Target model implementing the AT protocol
+- one call of nb_transport for each timing point in the protocol (BEGIN_REQ,
+  END_REQ, BEGIN_RESP and END_RESP)
+
+SimpleATInitiator2/SimpleATTarget2
+----------------------------------
+
+- AT Initiator/Target model implementing the AT protocol with timing annotation
+- only a call of nb_transport for the start of a phase (BEGIN_REQ and
+  BEGIN_RESP)
+- end of a phase is notified via timing annotation (t argument)
+
+CoreDecouplingLTInitiator
+-------------------------
+
+- LT Initiator using 'Core Decoupling'
+
+ExplicitLTTarget
+----------------
+
+- LT Target that uses explicit timing (calls wait)
+- added support for debug transactions
+
+ExplicitLTTarget
+----------------
+
+- AT Target, only registers nb_transport
+
+SimpleBus
+---------
+
+- Simple bus model
+- Runtime switcheable between LT and AT (can only switch if no transactions
+  are pending)
+- No limitation on number of pending transactions (all targets that can return
+  false must support multiple transactions)
+- added support for DMI and debug transactions
+- LT mode:
+-- Forward nb_transport calls to initiator/targets
+-- Only one active request/response phase
+- AT mode:
+-- Incoming transactions are queued
+-- AT protocol is executed from a different SC_THREAD
+-- A target is notified immediately of the end of a transaction (using timing
+   annotation). This is needed because the initiator can re-use the
+   transaction (and the target may use the transaction pointer to identify the
+   transaction)
diff --git a/src/systemc/tests/include/SimpleATInitiator1.h b/src/systemc/tests/include/SimpleATInitiator1.h
new file mode 100644 (file)
index 0000000..8becbb9
--- /dev/null
@@ -0,0 +1,333 @@
+/*****************************************************************************
+
+  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.
+
+ *****************************************************************************/
+
+//====================================================================
+//  Nov 06, 2008
+//
+//  Updated by:
+//    Xiaopeng Qiu, JEDA Technologies, Inc
+//    Email:  qiuxp@jedatechnologies.net
+//
+//  To fix violations of TLM2.0 rules, which are detected by JEDA 
+//  TLM2.0 checker.
+//
+//====================================================================
+
+#ifndef __SIMPLE_AT_INITIATOR1_H__
+#define __SIMPLE_AT_INITIATOR1_H__
+
+#include "tlm.h"
+#include "tlm_utils/simple_initiator_socket.h"
+//#include <systemc>
+#include <cassert>
+#include <queue>
+//#include <iostream>
+
+class SimpleATInitiator1 : public sc_core::sc_module
+{
+public:
+  typedef tlm::tlm_generic_payload                  transaction_type;
+  typedef tlm::tlm_phase                            phase_type;
+  typedef tlm::tlm_sync_enum                        sync_enum_type;
+  typedef tlm_utils::simple_initiator_socket<SimpleATInitiator1> initiator_socket_type;
+
+public:
+  // extended transaction, holds tlm_generic_payload + data storage
+  template <typename DT>
+  class MyTransaction : public transaction_type
+  {
+  public:
+    MyTransaction()
+    {
+      this->set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
+    }
+    MyTransaction(tlm::tlm_mm_interface* mm) : transaction_type(mm)
+    {
+      this->set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
+    }
+
+    void setData(DT& data) { mData = data; }
+    DT getData() const { return mData; }
+
+  private:
+    DT mData;
+  };
+  typedef MyTransaction<unsigned int>  mytransaction_type;
+
+  // Dummy Transaction Pool
+  class SimplePool : public tlm::tlm_mm_interface
+  {
+  public:
+    SimplePool() {}
+    mytransaction_type* claim()
+    { 
+      mytransaction_type* t = new mytransaction_type(this);
+      t->acquire();
+      return t;
+    }
+    void release(mytransaction_type* t)
+    {
+      t->release();
+    }
+    void free(tlm::tlm_generic_payload* t)
+    {
+      t->reset(); 
+      delete t;
+    }
+  };
+
+public:
+  initiator_socket_type socket;
+
+public:
+  SC_HAS_PROCESS(SimpleATInitiator1);
+  SimpleATInitiator1(sc_core::sc_module_name name,
+                  unsigned int nrOfTransactions = 0x5,
+                  unsigned int baseAddress = 0x0) :
+    sc_core::sc_module(name),
+    socket("socket"),
+    ACCEPT_DELAY(10, sc_core::SC_NS),
+    mNrOfTransactions(nrOfTransactions),
+    mBaseAddress(baseAddress),
+    mTransactionCount(0),
+    mCurrentTransaction(0)
+  {
+    // register nb_transport method
+    socket.register_nb_transport_bw(this, &SimpleATInitiator1::myNBTransport);
+
+    // Initiator thread
+    SC_THREAD(run);
+
+    SC_METHOD(endResponse)
+    sensitive << mEndResponseEvent;
+    dont_initialize();
+  }
+
+  bool initTransaction(mytransaction_type*& trans)
+  {
+    if (mTransactionCount < mNrOfTransactions) {
+      trans = transPool.claim();
+      trans->set_address(mBaseAddress + 4*mTransactionCount);
+      trans->setData(mTransactionCount);
+      trans->set_command(tlm::TLM_WRITE_COMMAND);
+
+    } else if (mTransactionCount < 2 * mNrOfTransactions) {
+      trans = transPool.claim();
+      trans->set_address(mBaseAddress + 4*(mTransactionCount - mNrOfTransactions));
+      trans->set_command(tlm::TLM_READ_COMMAND);
+
+    } else {
+      return false;
+    }
+
+    trans->set_data_length(4);
+    trans->set_streaming_width(4);
+
+    ++mTransactionCount;
+    return true;
+  }
+
+  void logStartTransation(mytransaction_type& trans)
+  {
+    if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+      std::cout << name() << ": Send write request: A = 0x"
+                << std::hex << (unsigned int)trans.get_address()
+                << ", D = 0x" << trans.getData() << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+      
+    } else {
+      std::cout << name() << ": Send read request: A = 0x"
+                << std::hex << (int)trans.get_address() << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+    }
+  }
+
+  void logEndTransaction(mytransaction_type& trans)
+  {
+    if (trans.get_response_status() != tlm::TLM_OK_RESPONSE) {
+      std::cout << name() << ": Received error response @ "
+                << sc_core::sc_time_stamp() << std::endl;
+
+    } else {
+      std::cout << name() <<  ": Received ok response";
+      if (trans.get_command() == tlm::TLM_READ_COMMAND) {
+        std::cout << ": D = 0x" << trans.getData() << std::dec;
+      }
+      std::cout << " @ " << sc_core::sc_time_stamp() << std::endl;
+    }
+  }
+
+  //
+  // Simple AT Initiator
+  // - Request must be accepted by the target before the next request can be
+  //   send
+  // - Responses can come out of order
+  // - Responses will be accepted after fixed delay
+  //
+  void run()
+  {
+    phase_type phase;
+    sc_core::sc_time t;
+    
+    mytransaction_type* ptrans;
+    while (initTransaction(ptrans)) {
+      // Create transaction and initialise phase and t
+      mytransaction_type& trans = *ptrans;
+      phase = tlm::BEGIN_REQ;
+      t = sc_core::SC_ZERO_TIME;
+
+      logStartTransation(trans);
+
+      switch (socket->nb_transport_fw(trans, phase, t)) {
+      case tlm::TLM_COMPLETED:
+        // Transaction Finished, wait for the returned delay
+        wait(t);
+        logEndTransaction(trans);
+        transPool.release(&trans);
+        break;
+
+      case tlm::TLM_ACCEPTED:
+      case tlm::TLM_UPDATED:
+        switch (phase) {
+        case tlm::BEGIN_REQ:
+          // Request phase not yet finished
+          // Wait until end of request phase before sending new request
+          
+          // FIXME
+          mCurrentTransaction = &trans;
+          wait(mEndRequestPhase);
+          mCurrentTransaction = 0;
+          break;
+
+        case tlm::END_REQ:
+          // Request phase ended
+          if (t != sc_core::SC_ZERO_TIME) {
+            // Wait until end of request time before sending new request
+            wait(t);
+          }
+          break;
+
+        case tlm::BEGIN_RESP:
+          // Request phase ended and response phase already started
+          if (t != sc_core::SC_ZERO_TIME) {
+            // Wait until end of request time before sending new request
+            wait(t);
+          }
+          if (mEndResponseQueue.empty()) {
+            // Notify end of response phase after ACCEPT delay
+            mEndResponseEvent.notify(ACCEPT_DELAY);
+          }
+          mEndResponseQueue.push(&trans);
+          break;
+
+        case tlm::END_RESP:   // fall-through
+        default:
+          // A target should never return with these phases
+          // If phase == END_RESP, nb_transport should have returned true
+          assert(0); exit(1);
+          break;
+        }
+        break;
+
+      default:
+        assert(0); exit(1);
+      };
+    }
+    wait();
+  }
+
+  sync_enum_type myNBTransport(transaction_type& trans, phase_type& phase, sc_core::sc_time& t)
+  {
+    switch (phase) {
+    case tlm::END_REQ:
+      assert(t == sc_core::SC_ZERO_TIME); // FIXME: can t != 0?
+      // Request phase ended
+      mEndRequestPhase.notify(sc_core::SC_ZERO_TIME);
+      return tlm::TLM_ACCEPTED;
+
+    case tlm::BEGIN_RESP:
+    {
+      assert(t == sc_core::SC_ZERO_TIME); // FIXME: can t != 0?
+
+      // Notify end of request phase if run thread is waiting for it
+      // FIXME
+      if (&trans == mCurrentTransaction) {
+        mEndRequestPhase.notify(sc_core::SC_ZERO_TIME);
+      }
+
+      assert(dynamic_cast<mytransaction_type*>(&trans));
+      mytransaction_type* myTrans = static_cast<mytransaction_type*>(&trans);
+      assert(myTrans); 
+
+      if (mEndResponseQueue.empty()) {
+        // Notify end of response phase after ACCEPT delay
+        mEndResponseEvent.notify(ACCEPT_DELAY);
+      }
+      mEndResponseQueue.push(myTrans);
+      return tlm::TLM_ACCEPTED;
+    }
+
+    case tlm::BEGIN_REQ: // fall-through
+    case tlm::END_RESP:  // fall-through
+    default:
+      // A target should never call nb_transport with these phases
+      assert(0); exit(1);
+//      return tlm::TLM_COMPLETED;  //unreachable code
+    };
+  }
+
+  void endResponse()
+  {
+    assert(!mEndResponseQueue.empty());
+    // end response phase
+    phase_type phase = tlm::END_RESP;
+    sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+    mytransaction_type* trans = mEndResponseQueue.front();
+    assert(trans);
+    mEndResponseQueue.pop();
+    #if ( ! NDEBUG )
+    sync_enum_type r = socket->nb_transport_fw(*trans, phase, t);
+    #endif /* ! NDEBUG */
+    assert(r == tlm::TLM_COMPLETED); // FIXME: target should return TLM_COMPLETED?
+    assert(t == sc_core::SC_ZERO_TIME); // t must be SC_ZERO_TIME
+
+    logEndTransaction(*trans);
+    transPool.release(trans);
+
+    if (!mEndResponseQueue.empty()) {
+      // Notify end of response phase after ACCEPT delay
+      mEndResponseEvent.notify(ACCEPT_DELAY);
+    }
+  }
+
+private:
+  const sc_core::sc_time ACCEPT_DELAY;
+
+private:
+  unsigned int mNrOfTransactions;
+  unsigned int mBaseAddress;
+  SimplePool transPool;
+  unsigned int mTransactionCount;
+  sc_core::sc_event mEndRequestPhase;
+  std::queue<mytransaction_type*> mEndResponseQueue;
+  sc_core::sc_event mEndResponseEvent;
+  transaction_type* mCurrentTransaction;
+};
+
+#endif
diff --git a/src/systemc/tests/include/SimpleATInitiator2.h b/src/systemc/tests/include/SimpleATInitiator2.h
new file mode 100644 (file)
index 0000000..6decf11
--- /dev/null
@@ -0,0 +1,306 @@
+/*****************************************************************************
+
+  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.
+
+ *****************************************************************************/
+
+//====================================================================
+//  Nov 06, 2008
+//
+//  Updated by:
+//    Xiaopeng Qiu, JEDA Technologies, Inc
+//    Email:  qiuxp@jedatechnologies.net
+//
+//  To fix violations of TLM2.0 rules, which are detected by JEDA 
+//  TLM2.0 checker.
+//
+//====================================================================
+
+#ifndef __SIMPLE_AT_INITIATOR2_H__
+#define __SIMPLE_AT_INITIATOR2_H__
+
+#include "tlm.h"
+#include "tlm_utils/simple_initiator_socket.h"
+//#include <systemc>
+#include <cassert>
+#include <queue>
+//#include <iostream>
+
+class SimpleATInitiator2 : public sc_core::sc_module
+{
+public:
+  typedef tlm::tlm_generic_payload                   transaction_type;
+  typedef tlm::tlm_phase                             phase_type;
+  typedef tlm::tlm_sync_enum                         sync_enum_type;
+  typedef tlm_utils::simple_initiator_socket<SimpleATInitiator2>  initiator_socket_type;
+
+public:
+  // extended transaction, holds tlm_generic_payload + data storage
+  template <typename DT>
+  class MyTransaction : public transaction_type
+  {
+  public:
+    MyTransaction()
+    {
+      this->set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
+    }
+    MyTransaction(tlm::tlm_mm_interface* mm) : transaction_type(mm)
+    {
+      this->set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
+    }
+
+    void setData(DT& data) { mData = data; }
+    DT getData() const { return mData; }
+
+  private:
+    DT mData;
+  };
+  typedef MyTransaction<unsigned int>  mytransaction_type;
+
+  // Dummy Transaction Pool
+  class SimplePool : public tlm::tlm_mm_interface
+  {
+  public:
+    SimplePool() {}
+    mytransaction_type* claim()
+    { 
+      mytransaction_type* t = new mytransaction_type(this);
+      t->acquire();
+      return t;
+    }
+    void release(mytransaction_type* t)
+    {
+      t->release();
+    }
+    void free(tlm::tlm_generic_payload* t)
+    {
+      t->reset(); 
+      delete t;
+    }
+  };
+
+public:
+  initiator_socket_type socket;
+
+public:
+  SC_HAS_PROCESS(SimpleATInitiator2);
+  SimpleATInitiator2(sc_core::sc_module_name name,
+                     unsigned int nrOfTransactions = 0x5,
+                     unsigned int baseAddress = 0) :
+    sc_core::sc_module(name),
+    socket("socket"),
+    ACCEPT_DELAY(10, sc_core::SC_NS),
+    mNrOfTransactions(nrOfTransactions),
+    mBaseAddress(baseAddress),
+    mTransactionCount(0),
+    mCurrentTransaction(0)
+  {
+    // register nb_transport method
+    socket.register_nb_transport_bw(this, &SimpleATInitiator2::myNBTransport);
+
+    // Initiator thread
+    SC_THREAD(run);
+  }
+
+  bool initTransaction(mytransaction_type*& trans)
+  {
+    if (mTransactionCount < mNrOfTransactions) {
+      trans = transPool.claim();
+      trans->set_address(mBaseAddress + 4*mTransactionCount);
+      trans->setData(mTransactionCount);
+      trans->set_command(tlm::TLM_WRITE_COMMAND);
+
+    } else if (mTransactionCount < 2 * mNrOfTransactions) {
+      trans = transPool.claim();
+      trans->set_address(mBaseAddress + 4*(mTransactionCount - mNrOfTransactions));
+      trans->set_command(tlm::TLM_READ_COMMAND);
+
+    } else {
+      return false;
+    }
+
+    trans->set_data_length(4);
+    trans->set_streaming_width(4);
+
+    ++mTransactionCount;
+    return true;
+  }
+
+  void logStartTransation(mytransaction_type& trans)
+  {
+    if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+      std::cout << name() << ": Send write request: A = 0x"
+                << std::hex << (unsigned int)trans.get_address()
+                << ", D = 0x" << trans.getData() << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+      
+    } else {
+      std::cout << name() << ": Send read request: A = 0x"
+                << std::hex << (unsigned int)trans.get_address() << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+    }
+  }
+
+  void logEndTransaction(mytransaction_type& trans)
+  {
+    if (trans.get_response_status() != tlm::TLM_OK_RESPONSE) {
+      std::cout << name() << ": Received error response @ "
+                << sc_core::sc_time_stamp() << std::endl;
+
+    } else {
+      std::cout << name() <<  ": Received ok response";
+      if (trans.get_command() == tlm::TLM_READ_COMMAND) {
+        std::cout << ": D = 0x" << std::hex << trans.getData() << std::dec;
+      }
+      std::cout << " @ " << sc_core::sc_time_stamp() << std::endl;
+    }
+  }
+
+  //
+  // Simple AT Initiator
+  // - Request must be accepted by the target before the next request can be
+  //   send
+  // - Responses can come out of order
+  // - Responses will be accepted after fixed delay
+  //
+  void run()
+  {
+    phase_type phase;
+    sc_core::sc_time t;
+    
+    mytransaction_type* ptrans;
+    while (initTransaction(ptrans)) {
+      // Create transaction and initialise phase and t
+      mytransaction_type& trans = *ptrans;
+      phase = tlm::BEGIN_REQ;
+      t = sc_core::SC_ZERO_TIME;
+
+      logStartTransation(trans);
+
+      switch (socket->nb_transport_fw(trans, phase, t)) {
+      case tlm::TLM_COMPLETED:
+        // Transaction Finished, wait for the returned delay
+        wait(t);
+        logEndTransaction(trans);
+        transPool.release(&trans);
+        break;
+
+      case tlm::TLM_ACCEPTED:
+      case tlm::TLM_UPDATED:
+        switch (phase) {
+        case tlm::BEGIN_REQ:
+          // Request phase not yet finished
+          // Wait until end of request phase before sending new request
+          
+          // FIXME
+          mCurrentTransaction = &trans;
+          wait(mEndRequestPhase);
+         mCurrentTransaction = 0;
+          break;
+
+        case tlm::END_REQ:
+          // Request phase ended
+          if (t != sc_core::SC_ZERO_TIME) {
+            // Wait until end of request time before sending new request
+            wait(t);
+          }
+          break;
+
+        case tlm::BEGIN_RESP:
+          // Request phase ended and response phase already started
+          if (t != sc_core::SC_ZERO_TIME) {
+            // Wait until end of request time before sending new request
+            wait(t);
+          }
+          // Notify end of response phase after ACCEPT delay
+          t += ACCEPT_DELAY;
+          phase = tlm::END_RESP;
+          socket->nb_transport_fw(trans, phase, t);
+          logEndTransaction(trans);
+          transPool.release(&trans);
+          break;
+
+        case tlm::END_RESP:   // fall-through
+        default:
+          // A target should never return with these phases
+          // If phase == END_RESP, nb_transport should have returned true
+          assert(0); exit(1);
+          break;
+        }
+        break;
+
+      default:
+        assert(0); exit(1);
+      };
+    }
+    wait();
+
+  }
+
+  sync_enum_type myNBTransport(transaction_type& trans, phase_type& phase, sc_core::sc_time& t)
+  {
+    switch (phase) {
+    case tlm::END_REQ:
+      assert(t == sc_core::SC_ZERO_TIME); // FIXME: can t != 0?
+      // Request phase ended
+      mEndRequestPhase.notify(sc_core::SC_ZERO_TIME);
+      return tlm::TLM_ACCEPTED;
+
+    case tlm::BEGIN_RESP:
+    {
+      assert(t == sc_core::SC_ZERO_TIME); // FIXME: can t != 0?
+
+      // Notify end of request phase if run thread is waiting for it
+      // FIXME
+      if (&trans == mCurrentTransaction) {
+        mEndRequestPhase.notify(sc_core::SC_ZERO_TIME);
+      }
+
+      assert(dynamic_cast<mytransaction_type*>(&trans));
+      mytransaction_type* myTrans = static_cast<mytransaction_type*>(&trans);
+      assert(myTrans);
+
+      // Notify end of response phase after ACCEPT delay
+      t += ACCEPT_DELAY;
+      phase = tlm::END_RESP;
+      logEndTransaction(*myTrans);
+      transPool.release(myTrans);
+
+      return tlm::TLM_COMPLETED;
+    }
+
+    case tlm::BEGIN_REQ: // fall-through
+    case tlm::END_RESP:  // fall-through
+    default:
+      // A target should never call nb_transport with these phases
+      assert(0); exit(1);
+//      return tlm::TLM_COMPLETED;  //unreachable code
+    };
+  }
+
+private:
+  const sc_core::sc_time ACCEPT_DELAY;
+
+private:
+  unsigned int mNrOfTransactions;
+  unsigned int mBaseAddress;
+  SimplePool transPool;
+  unsigned int mTransactionCount;
+  sc_core::sc_event mEndRequestPhase;
+  transaction_type* mCurrentTransaction;
+};
+
+#endif
diff --git a/src/systemc/tests/include/SimpleATTarget1.h b/src/systemc/tests/include/SimpleATTarget1.h
new file mode 100644 (file)
index 0000000..d99ec3b
--- /dev/null
@@ -0,0 +1,211 @@
+/*****************************************************************************
+
+  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 __SIMPLE_AT_TARGET1_H__
+#define __SIMPLE_AT_TARGET1_H__
+
+#include "tlm.h"
+#include "tlm_utils/simple_target_socket.h"
+//#include <systemc>
+#include <cassert>
+#include <vector>
+#include <queue>
+//#include <iostream>
+
+class SimpleATTarget1 : public sc_core::sc_module
+{
+public:
+  typedef tlm::tlm_generic_payload            transaction_type;
+  typedef tlm::tlm_phase                      phase_type;
+  typedef tlm::tlm_sync_enum                  sync_enum_type;
+  typedef tlm_utils::simple_target_socket<SimpleATTarget1> target_socket_type;
+
+public:
+  target_socket_type socket;
+
+public:
+  SC_HAS_PROCESS(SimpleATTarget1);
+  SimpleATTarget1(sc_core::sc_module_name name) :
+    sc_core::sc_module(name),
+    socket("socket"),
+    ACCEPT_DELAY(25, sc_core::SC_NS),
+    RESPONSE_DELAY(100, sc_core::SC_NS)
+  {
+    // register nb_transport method
+    socket.register_nb_transport_fw(this, &SimpleATTarget1::myNBTransport);
+
+    SC_METHOD(endRequest)
+    sensitive << mEndRequestEvent;
+    dont_initialize();
+
+    SC_METHOD(beginResponse)
+    sensitive << mBeginResponseEvent;
+    dont_initialize();
+
+    SC_METHOD(endResponse)
+    sensitive << mEndResponseEvent;
+    dont_initialize();
+  }
+
+  //
+  // Simple AT target
+  // - Request is accepted after ACCEPT delay (relative to end of prev request
+  //   phase)
+  // - Response is started after RESPONSE delay (relative to end of prev resp
+  //   phase)
+  //
+  sync_enum_type myNBTransport(transaction_type& trans, phase_type& phase, sc_core::sc_time& t)
+  {
+    if (phase == tlm::BEGIN_REQ) {
+      // transactions may be kept in queue after the initiator has send END_REQ
+      trans.acquire();
+
+      sc_dt::uint64 address = trans.get_address();
+      assert(address < 400);
+
+      unsigned int& data = *reinterpret_cast<unsigned int*>(trans.get_data_ptr());
+      if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+        std::cout << name() << ": Received write request: A = 0x"
+                  << std::hex << (unsigned int)address << ", D = 0x"
+                  << data << std::dec
+                  << " @ " << sc_core::sc_time_stamp() << std::endl;
+
+        *reinterpret_cast<unsigned int*>(&mMem[address]) = data;
+
+      } else {
+        std::cout << name() << ": Received read request: A = 0x"
+                  << std::hex << (unsigned int)address << std::dec
+                  << " @ " << sc_core::sc_time_stamp() << std::endl;
+
+        data = *reinterpret_cast<unsigned int*>(&mMem[address]);
+      }
+
+      // Notify end of request phase after ACCEPT delay
+      if (mEndRequestQueue.empty()) {
+        mEndRequestEvent.notify(t + ACCEPT_DELAY);
+      }
+      mEndRequestQueue.push(&trans);
+
+      // AT-noTA target
+      // - always return false
+      // - seperate call to indicate end of phase (do not update phase or t)
+      return tlm::TLM_ACCEPTED;
+
+    } else if (phase == tlm::END_RESP) {
+
+      // response phase ends after t
+      mEndResponseEvent.notify(t);
+
+      return tlm::TLM_COMPLETED;
+    }
+
+    // Not possible
+    assert(0); exit(1);
+//    return tlm::TLM_COMPLETED;  //unreachable code
+  }
+
+  void endRequest()
+  {
+    assert(!mEndRequestQueue.empty());
+    // end request phase of oldest transaction
+    phase_type phase = tlm::END_REQ;
+    sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+    transaction_type* trans = mEndRequestQueue.front();
+    assert(trans);
+    mEndRequestQueue.pop();
+    #if ( ! NDEBUG )
+    sync_enum_type r = socket->nb_transport_bw(*trans, phase, t);
+    #endif /* ! NDEBUG */
+    assert(r == tlm::TLM_ACCEPTED); // FIXME: initiator should return TLM_ACCEPTED?
+    assert(t == sc_core::SC_ZERO_TIME); // t must be SC_ZERO_TIME
+
+    // Notify end of request phase for next transaction after ACCEPT delay
+    if (!mEndRequestQueue.empty()) {
+      mEndRequestEvent.notify(ACCEPT_DELAY);
+    }
+
+    if (mResponseQueue.empty()) {
+      // Start processing transaction
+      // Notify begin of response phase after RESPONSE delay
+      mBeginResponseEvent.notify(RESPONSE_DELAY);
+    }
+    mResponseQueue.push(trans);
+  }
+
+  void beginResponse()
+  {
+    assert(!mResponseQueue.empty());
+    // start response phase of oldest transaction
+    phase_type phase = tlm::BEGIN_RESP;
+    sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+    transaction_type* trans = mResponseQueue.front();
+    assert(trans);
+
+    // Set response data
+    trans->set_response_status(tlm::TLM_OK_RESPONSE);
+    if (trans->get_command() == tlm::TLM_READ_COMMAND) {
+       sc_dt::uint64 address = trans->get_address();
+       assert(address < 400);
+      *reinterpret_cast<unsigned int*>(trans->get_data_ptr()) =
+        *reinterpret_cast<unsigned int*>(&mMem[address]);
+    }
+
+    switch (socket->nb_transport_bw(*trans, phase, t)) {
+    case tlm::TLM_COMPLETED:
+      // response phase ends after t
+      mEndResponseEvent.notify(t);
+      break;
+
+    case tlm::TLM_ACCEPTED:
+    case tlm::TLM_UPDATED:
+     // initiator will call nb_transport to indicate end of response phase
+     break;
+
+    default:
+      assert(0); exit(1);
+    };
+  }
+
+  void endResponse()
+  {
+    assert(!mResponseQueue.empty());
+    mResponseQueue.front()->release();
+    mResponseQueue.pop();
+
+    if (!mResponseQueue.empty()) {
+      // Start processing next transaction
+      // Notify begin of response phase after RESPONSE delay
+      mBeginResponseEvent.notify(RESPONSE_DELAY);
+    }
+  }
+
+private:
+  const sc_core::sc_time ACCEPT_DELAY;
+  const sc_core::sc_time RESPONSE_DELAY;
+
+private:
+  unsigned char mMem[400];
+  std::queue<transaction_type*> mEndRequestQueue;
+  sc_core::sc_event mEndRequestEvent;
+  std::queue<transaction_type*> mResponseQueue;
+  sc_core::sc_event mBeginResponseEvent;
+  sc_core::sc_event mEndResponseEvent;
+};
+
+#endif
diff --git a/src/systemc/tests/include/SimpleATTarget2.h b/src/systemc/tests/include/SimpleATTarget2.h
new file mode 100644 (file)
index 0000000..d4f2ae7
--- /dev/null
@@ -0,0 +1,178 @@
+/*****************************************************************************
+
+  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 __SIMPLE_AT_TARGET2_H__
+#define __SIMPLE_AT_TARGET2_H__
+
+#include "tlm.h"
+#include "tlm_utils/simple_target_socket.h"
+//#include <systemc>
+#include <cassert>
+#include <vector>
+#include <queue>
+//#include <iostream>
+
+class SimpleATTarget2 : public sc_core::sc_module
+{
+public:
+  typedef tlm::tlm_generic_payload            transaction_type;
+  typedef tlm::tlm_phase                      phase_type;
+  typedef tlm::tlm_sync_enum                  sync_enum_type;
+  typedef tlm_utils::simple_target_socket<SimpleATTarget2> target_socket_type;
+
+public:
+  target_socket_type socket;
+
+public:
+  SC_HAS_PROCESS(SimpleATTarget2);
+  SimpleATTarget2(sc_core::sc_module_name name) :
+    sc_core::sc_module(name),
+    socket("socket"),
+    ACCEPT_DELAY(25, sc_core::SC_NS),
+    RESPONSE_DELAY(100, sc_core::SC_NS)
+  {
+    // register nb_transport method
+    socket.register_nb_transport_fw(this, &SimpleATTarget2::myNBTransport);
+
+    SC_METHOD(beginResponse)
+    sensitive << mBeginResponseEvent;
+    dont_initialize();
+
+    SC_METHOD(endResponse)
+    sensitive << mEndResponseEvent;
+    dont_initialize();
+  }
+
+  //
+  // Simple AT-TA target
+  // - Request is accepted after fixed delay (relative to end of prev request
+  //   phase)
+  // - Response is started after fixed delay (relative to end of prev resp
+  //   phase)
+  //
+  sync_enum_type myNBTransport(transaction_type& trans,
+                               phase_type& phase,
+                               sc_core::sc_time& t)
+  {
+    if (phase == tlm::BEGIN_REQ) {
+      // transactions may be kept in queue after the initiator has send END_REQ
+      trans.acquire();
+
+      sc_dt::uint64 address = trans.get_address();
+      assert(address < 400);
+
+      unsigned int& data = *reinterpret_cast<unsigned int*>(trans.get_data_ptr());
+      if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+        std::cout << name() << ": Received write request: A = 0x"
+                  << std::hex << (unsigned int)address << ", D = 0x" << data
+                  << std::dec << " @ " << sc_core::sc_time_stamp()
+                  << std::endl;
+
+        *reinterpret_cast<unsigned int*>(&mMem[address]) = data;
+
+      } else {
+        std::cout << name() << ": Received read request: A = 0x"
+                  << std::hex << (unsigned int)address
+                  << std::dec << " @ " << sc_core::sc_time_stamp()
+                  << std::endl;
+
+        data = *reinterpret_cast<unsigned int*>(&mMem[address]);
+      }
+
+      // End request phase after accept delay
+      t += ACCEPT_DELAY;
+      phase = tlm::END_REQ;
+
+      if (mResponseQueue.empty()) {
+        // Start processing transaction after accept delay
+        // Notify begin of response phase after accept delay + response delay
+        mBeginResponseEvent.notify(t + RESPONSE_DELAY);
+      }
+      mResponseQueue.push(&trans);
+
+      // AT-noTA target
+      // - always return false
+      // - immediately return delay to indicate end of phase
+      return tlm::TLM_UPDATED;
+
+    } else if (phase == tlm::END_RESP) {
+
+      // response phase ends after t
+      mEndResponseEvent.notify(t);
+
+      return tlm::TLM_COMPLETED;
+    }
+
+    // Not possible
+    assert(0); exit(1);
+//    return tlm::TLM_COMPLETED;  //unreachable code
+  }
+
+  void beginResponse()
+  {
+    assert(!mResponseQueue.empty());
+    // start response phase of oldest transaction
+    phase_type phase = tlm::BEGIN_RESP;
+    sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+    transaction_type* trans = mResponseQueue.front();
+    assert(trans);
+
+    // Set response data
+    trans->set_response_status(tlm::TLM_OK_RESPONSE);
+    if (trans->get_command() == tlm::TLM_READ_COMMAND) {
+       sc_dt::uint64 address = trans->get_address();
+       assert(address < 400);
+      *reinterpret_cast<unsigned int*>(trans->get_data_ptr()) =
+        *reinterpret_cast<unsigned int*>(&mMem[address]);
+    }
+
+    if (socket->nb_transport_bw(*trans, phase, t) == tlm::TLM_COMPLETED) {
+      // response phase ends after t
+      mEndResponseEvent.notify(t);
+
+    } else {
+      // initiator will call nb_transport to indicate end of response phase
+    }
+  }
+
+  void endResponse()
+  {
+    assert(!mResponseQueue.empty());
+    mResponseQueue.front()->release();
+    mResponseQueue.pop();
+
+    // Start processing next transaction when previous response is accepted.
+    // Notify begin of response phase after RESPONSE delay
+    if (!mResponseQueue.empty()) {
+      mBeginResponseEvent.notify(RESPONSE_DELAY);
+    }
+  }
+
+private:
+  const sc_core::sc_time ACCEPT_DELAY;
+  const sc_core::sc_time RESPONSE_DELAY;
+
+private:
+  unsigned char mMem[400];
+  std::queue<transaction_type*> mResponseQueue;
+  sc_core::sc_event mBeginResponseEvent;
+  sc_core::sc_event mEndResponseEvent;
+};
+
+#endif
diff --git a/src/systemc/tests/include/SimpleBusAT.h b/src/systemc/tests/include/SimpleBusAT.h
new file mode 100644 (file)
index 0000000..db68033
--- /dev/null
@@ -0,0 +1,378 @@
+/*****************************************************************************
+
+  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 __SIMPLEBUSAT_H__
+#define __SIMPLEBUSAT_H__
+
+//#include <systemc>
+#include "tlm.h"
+
+#include "tlm_utils/simple_target_socket.h"
+#include "tlm_utils/simple_initiator_socket.h"
+
+#include "tlm_utils/peq_with_get.h"
+
+template <int NR_OF_INITIATORS, int NR_OF_TARGETS>
+class SimpleBusAT : public sc_core::sc_module
+{
+public:
+  typedef tlm::tlm_generic_payload               transaction_type;
+  typedef tlm::tlm_phase                         phase_type;
+  typedef tlm::tlm_sync_enum                     sync_enum_type;
+  typedef tlm_utils::simple_target_socket_tagged<SimpleBusAT>    target_socket_type;
+  typedef tlm_utils::simple_initiator_socket_tagged<SimpleBusAT> initiator_socket_type;
+
+public:
+  target_socket_type target_socket[NR_OF_INITIATORS];
+  initiator_socket_type initiator_socket[NR_OF_TARGETS];
+
+public:
+  SC_HAS_PROCESS(SimpleBusAT);
+  SimpleBusAT(sc_core::sc_module_name name) :
+    sc_core::sc_module(name),
+    mRequestPEQ("requestPEQ"),
+    mResponsePEQ("responsePEQ")
+  {
+     for (unsigned int i = 0; i < NR_OF_INITIATORS; ++i) {
+       target_socket[i].register_nb_transport_fw(this, &SimpleBusAT::initiatorNBTransport, i);
+       target_socket[i].register_transport_dbg(this, &SimpleBusAT::transportDebug, i);
+       target_socket[i].register_get_direct_mem_ptr(this, &SimpleBusAT::getDMIPointer, i);
+     }
+     for (unsigned int i = 0; i < NR_OF_TARGETS; ++i) {
+       initiator_socket[i].register_nb_transport_bw(this, &SimpleBusAT::targetNBTransport, i);
+       initiator_socket[i].register_invalidate_direct_mem_ptr(this, &SimpleBusAT::invalidateDMIPointers, i);
+     }
+
+     SC_THREAD(RequestThread);
+     SC_THREAD(ResponseThread);
+  }
+
+  //
+  // Dummy decoder:
+  // - address[31-28]: portId
+  // - address[27-0]: masked address
+  //
+
+  unsigned int getPortId(const sc_dt::uint64& address)
+  {
+    return (unsigned int)address >> 28;
+  }
+
+  sc_dt::uint64 getAddressOffset(unsigned int portId)
+  {
+    return portId << 28;
+  }
+
+  sc_dt::uint64 getAddressMask(unsigned int portId)
+  {
+    return 0xfffffff;
+  }
+
+  unsigned int decode(const sc_dt::uint64& address)
+  {
+    // decode address:
+    // - return initiator socket id
+
+    return getPortId(address);
+  }
+
+  //
+  // AT protocol
+  //
+
+  void RequestThread()
+  {
+    while (true) {
+      wait(mRequestPEQ.get_event());
+
+      transaction_type* trans;
+      while ((trans = mRequestPEQ.get_next_transaction())!=0) {
+        unsigned int portId = decode(trans->get_address());
+        assert(portId < NR_OF_TARGETS);
+        initiator_socket_type* decodeSocket = &initiator_socket[portId];
+        trans->set_address(trans->get_address() & getAddressMask(portId));
+
+        // Fill in the destination port
+        PendingTransactionsIterator it = mPendingTransactions.find(trans);
+        assert(it != mPendingTransactions.end());
+        it->second.to = decodeSocket;
+
+        phase_type phase = tlm::BEGIN_REQ;
+        sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+
+        // FIXME: No limitation on number of pending transactions
+        //        All targets (that return false) must support multiple transactions
+        switch ((*decodeSocket)->nb_transport_fw(*trans, phase, t)) {
+        case tlm::TLM_ACCEPTED:
+        case tlm::TLM_UPDATED:
+          // Transaction not yet finished
+          if (phase == tlm::BEGIN_REQ) {
+            // Request phase not yet finished
+            wait(mEndRequestEvent);
+
+          } else if (phase == tlm::END_REQ) {
+            // Request phase finished, but response phase not yet started
+            wait(t);
+
+          } else if (phase == tlm::BEGIN_RESP) {
+            mResponsePEQ.notify(*trans, t);
+            // Not needed to send END_REQ to initiator
+            continue;
+
+          } else { // END_RESP
+            assert(0); exit(1);
+          }
+
+          // only send END_REQ to initiator if BEGIN_RESP was not already send
+          if (it->second.from) {
+            phase = tlm::END_REQ;
+            t = sc_core::SC_ZERO_TIME;
+            (*it->second.from)->nb_transport_bw(*trans, phase, t);
+          }
+
+          break;
+
+        case tlm::TLM_COMPLETED:
+          // Transaction finished
+          mResponsePEQ.notify(*trans, t);
+
+          // reset to destination port (we must not send END_RESP to target)
+          it->second.to = 0;
+
+          wait(t);
+          break;
+
+        default:
+          assert(0); exit(1);
+        };
+      }
+    }
+  }
+
+  void ResponseThread()
+  {
+    while (true) {
+      wait(mResponsePEQ.get_event());
+
+      transaction_type* trans;
+      while ((trans = mResponsePEQ.get_next_transaction())!=0) {
+        PendingTransactionsIterator it = mPendingTransactions.find(trans);
+        assert(it != mPendingTransactions.end());
+
+        phase_type phase = tlm::BEGIN_RESP;
+        sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+
+        target_socket_type* initiatorSocket = it->second.from;
+        // if BEGIN_RESP is send first we don't have to send END_REQ anymore
+        it->second.from = 0;
+
+        switch ((*initiatorSocket)->nb_transport_bw(*trans, phase, t)) {
+        case tlm::TLM_COMPLETED:
+          // Transaction finished
+          wait(t);
+          break;
+
+        case tlm::TLM_ACCEPTED:
+        case tlm::TLM_UPDATED:
+          // Transaction not yet finished
+          wait(mEndResponseEvent);
+          break;
+
+        default:
+          assert(0); exit(1);
+        };
+
+        // forward END_RESP to target
+        if (it->second.to) {
+          phase = tlm::END_RESP;
+          t = sc_core::SC_ZERO_TIME;
+          #if ( ! NDEBUG )
+          sync_enum_type r = (*it->second.to)->nb_transport_fw(*trans, phase, t);
+          #endif /* ! NDEBUG */
+          assert(r == tlm::TLM_COMPLETED);
+        }
+
+        mPendingTransactions.erase(it);
+        trans->release();
+      }
+    }
+  }
+
+  //
+  // interface methods
+  //
+
+  sync_enum_type initiatorNBTransport(int initiator_id,
+                                      transaction_type& trans,
+                                      phase_type& phase,
+                                      sc_core::sc_time& t)
+  {
+    if (phase == tlm::BEGIN_REQ) {
+      trans.acquire();
+      addPendingTransaction(trans, 0, initiator_id);
+
+      mRequestPEQ.notify(trans, t);
+
+    } else if (phase == tlm::END_RESP) {
+      mEndResponseEvent.notify(t);
+      return tlm::TLM_COMPLETED;
+
+    } else {
+      std::cout << "ERROR: '" << name()
+                << "': Illegal phase received from initiator." << std::endl;
+      assert(false); exit(1);
+    }
+
+    return tlm::TLM_ACCEPTED;
+  }
+
+  sync_enum_type targetNBTransport(int portId,
+                                   transaction_type& trans,
+                                   phase_type& phase,
+                                   sc_core::sc_time& t)
+  {
+    if (phase != tlm::END_REQ && phase != tlm::BEGIN_RESP) {
+      std::cout << "ERROR: '" << name()
+                << "': Illegal phase received from target." << std::endl;
+      assert(false); exit(1);
+    }
+
+    mEndRequestEvent.notify(t);
+    if (phase == tlm::BEGIN_RESP) {
+      mResponsePEQ.notify(trans, t);
+    }
+
+    return tlm::TLM_ACCEPTED;
+  }
+
+  unsigned int transportDebug(int initiator_id, transaction_type& trans)
+  {
+    unsigned int portId = decode(trans.get_address());
+    assert(portId < NR_OF_TARGETS);
+    initiator_socket_type* decodeSocket = &initiator_socket[portId];
+    trans.set_address( trans.get_address() & getAddressMask(portId) );
+    
+    return (*decodeSocket)->transport_dbg(trans);
+  }
+
+  bool limitRange(unsigned int portId, sc_dt::uint64& low, sc_dt::uint64& high)
+  {
+    sc_dt::uint64 addressOffset = getAddressOffset(portId);
+    sc_dt::uint64 addressMask = getAddressMask(portId);
+
+    if (low > addressMask) {
+      // Range does not overlap with addressrange for this target
+      return false;
+    }
+
+    low += addressOffset;
+    if (high > addressMask) {
+      high = addressOffset + addressMask;
+
+    } else {
+      high += addressOffset;
+    }
+    return true;
+  }
+
+  bool getDMIPointer(int initiator_id,
+                     transaction_type& trans,
+                     tlm::tlm_dmi&  dmi_data)
+  {
+    // FIXME: DMI not supported for AT bus?
+    sc_dt::uint64 address = trans.get_address();
+
+    unsigned int portId = decode(address);
+    assert(portId < NR_OF_TARGETS);
+    initiator_socket_type* decodeSocket = &initiator_socket[portId];
+    sc_dt::uint64 maskedAddress = address & getAddressMask(portId);
+
+    trans.set_address(maskedAddress);
+
+    bool result =
+      (*decodeSocket)->get_direct_mem_ptr(trans, dmi_data);
+    
+    if (result)
+    {
+      // Range must contain address
+      assert(dmi_data.get_start_address() <= maskedAddress);
+      assert(dmi_data.get_end_address() >= maskedAddress);
+    }
+    
+    // Should always succeed
+       sc_dt::uint64 start, end;
+       start = dmi_data.get_start_address();
+       end = dmi_data.get_end_address();
+       
+       limitRange(portId, start, end);
+       
+       dmi_data.set_start_address(start);
+       dmi_data.set_end_address(end);
+
+    return result;
+  }
+
+  void invalidateDMIPointers(int portId,
+                             sc_dt::uint64 start_range,
+                             sc_dt::uint64 end_range)
+  {
+    // FIXME: probably faster to always invalidate everything?
+
+    if ((portId >= 0) && !limitRange(portId, start_range, end_range)) {
+      // Range does not fall into address range of target
+      return;
+    }
+    
+    for (unsigned int i = 0; i < NR_OF_INITIATORS; ++i) {
+      (target_socket[i])->invalidate_direct_mem_ptr(start_range, end_range);
+    }
+  }
+
+private:
+  void addPendingTransaction(transaction_type& trans,
+                             initiator_socket_type* to,
+                             int initiatorId)
+  {
+    const ConnectionInfo info = { &target_socket[initiatorId], to };
+    assert(mPendingTransactions.find(&trans) == mPendingTransactions.end());
+    mPendingTransactions[&trans] = info;
+  }
+
+private:
+  struct ConnectionInfo {
+    target_socket_type* from;
+    initiator_socket_type* to;
+  };
+  typedef std::map<transaction_type*, ConnectionInfo> PendingTransactions;
+  typedef typename PendingTransactions::iterator PendingTransactionsIterator;
+  typedef typename PendingTransactions::const_iterator PendingTransactionsConstIterator;
+
+private:
+  PendingTransactions mPendingTransactions;
+
+  tlm_utils::peq_with_get<transaction_type> mRequestPEQ;
+  sc_core::sc_event mBeginRequestEvent;
+  sc_core::sc_event mEndRequestEvent;
+
+  tlm_utils::peq_with_get<transaction_type> mResponsePEQ;
+  sc_core::sc_event mBeginResponseEvent;
+  sc_core::sc_event mEndResponseEvent;
+};
+
+#endif
diff --git a/src/systemc/tests/include/SimpleBusLT.h b/src/systemc/tests/include/SimpleBusLT.h
new file mode 100644 (file)
index 0000000..a2e71d8
--- /dev/null
@@ -0,0 +1,193 @@
+/*****************************************************************************
+
+  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 __SIMPLEBUSLT_H__
+#define __SIMPLEBUSLT_H__
+
+//#include <systemc>
+#include "tlm.h"
+
+#include "tlm_utils/simple_target_socket.h"
+#include "tlm_utils/simple_initiator_socket.h"
+
+template <int NR_OF_INITIATORS, int NR_OF_TARGETS>
+class SimpleBusLT : public sc_core::sc_module
+{
+public:
+  typedef tlm::tlm_generic_payload                 transaction_type;
+  typedef tlm::tlm_phase                           phase_type;
+  typedef tlm::tlm_sync_enum                       sync_enum_type;
+  typedef tlm_utils::simple_target_socket_tagged<SimpleBusLT>    target_socket_type;
+  typedef tlm_utils::simple_initiator_socket_tagged<SimpleBusLT> initiator_socket_type;
+
+public:
+  target_socket_type target_socket[NR_OF_INITIATORS];
+  initiator_socket_type initiator_socket[NR_OF_TARGETS];
+
+public:
+  SC_HAS_PROCESS(SimpleBusLT);
+  SimpleBusLT(sc_core::sc_module_name name) :
+    sc_core::sc_module(name)
+  {
+    for (unsigned int i = 0; i < NR_OF_INITIATORS; ++i) {
+      target_socket[i].register_b_transport(this, &SimpleBusLT::initiatorBTransport, i);
+      target_socket[i].register_transport_dbg(this, &SimpleBusLT::transportDebug, i);
+      target_socket[i].register_get_direct_mem_ptr(this, &SimpleBusLT::getDMIPointer, i);
+    }
+    for (unsigned int i = 0; i < NR_OF_TARGETS; ++i) {
+      initiator_socket[i].register_invalidate_direct_mem_ptr(this, &SimpleBusLT::invalidateDMIPointers, i);
+    }
+  }
+
+  //
+  // Dummy decoder:
+  // - address[31-28]: portId
+  // - address[27-0]: masked address
+  //
+
+  unsigned int getPortId(const sc_dt::uint64& address)
+  {
+    return (unsigned int)address >> 28;
+  }
+
+  sc_dt::uint64 getAddressOffset(unsigned int portId)
+  {
+    return portId << 28;
+  }
+
+  sc_dt::uint64 getAddressMask(unsigned int portId)
+  {
+    return 0xfffffff;
+  }
+
+  unsigned int decode(const sc_dt::uint64& address)
+  {
+    // decode address:
+    // - return initiator socket id
+
+    return getPortId(address);
+  }
+
+  //
+  // interface methods
+  //
+
+  //
+  // LT protocol
+  // - forward each call to the target/initiator
+  //
+  void initiatorBTransport(int SocketId,
+                           transaction_type& trans,
+                           sc_core::sc_time& t)
+  {
+    initiator_socket_type* decodeSocket;
+    unsigned int portId = decode(trans.get_address());
+    assert(portId < NR_OF_TARGETS);
+    decodeSocket = &initiator_socket[portId];
+    trans.set_address(trans.get_address() & getAddressMask(portId));
+
+    (*decodeSocket)->b_transport(trans, t);
+  }
+
+  unsigned int transportDebug(int SocketId,
+                              transaction_type& trans)
+  {
+    unsigned int portId = decode(trans.get_address());
+    assert(portId < NR_OF_TARGETS);
+    initiator_socket_type* decodeSocket = &initiator_socket[portId];
+    trans.set_address( trans.get_address() & getAddressMask(portId) );
+    
+    return (*decodeSocket)->transport_dbg(trans);
+  }
+
+  bool limitRange(unsigned int portId, sc_dt::uint64& low, sc_dt::uint64& high)
+  {
+    sc_dt::uint64 addressOffset = getAddressOffset(portId);
+    sc_dt::uint64 addressMask = getAddressMask(portId);
+
+    if (low > addressMask) {
+      // Range does not overlap with addressrange for this target
+      return false;
+    }
+
+    low += addressOffset;
+    if (high > addressMask) {
+      high = addressOffset + addressMask;
+
+    } else {
+      high += addressOffset;
+    }
+    return true;
+  }
+
+  bool getDMIPointer(int SocketId,
+                     transaction_type& trans,
+                     tlm::tlm_dmi&  dmi_data)
+  {
+    sc_dt::uint64 address = trans.get_address();
+
+    unsigned int portId = decode(address);
+    assert(portId < NR_OF_TARGETS);
+    initiator_socket_type* decodeSocket = &initiator_socket[portId];
+    sc_dt::uint64 maskedAddress = address & getAddressMask(portId);
+
+    trans.set_address(maskedAddress);
+
+    bool result =
+      (*decodeSocket)->get_direct_mem_ptr(trans, dmi_data);
+    
+    if (result)
+    {
+      // Range must contain address
+      assert(dmi_data.get_start_address() <= maskedAddress);
+      assert(dmi_data.get_end_address() >= maskedAddress);
+    }
+    
+    // Should always succeed
+       sc_dt::uint64 start, end;
+       start = dmi_data.get_start_address();
+       end = dmi_data.get_end_address();
+       
+       limitRange(portId, start, end);
+       
+       dmi_data.set_start_address(start);
+       dmi_data.set_end_address(end);
+
+    return result;
+  }
+
+  void invalidateDMIPointers(int port_id,
+                             sc_dt::uint64 start_range,
+                             sc_dt::uint64 end_range)
+  {
+    // FIXME: probably faster to always invalidate everything?
+
+    if (!limitRange(port_id, start_range, end_range)) {
+      // Range does not fall into address range of target
+      return;
+    }
+    
+    for (unsigned int i = 0; i < NR_OF_INITIATORS; ++i) {
+      (target_socket[i])->invalidate_direct_mem_ptr(start_range, end_range);
+    }
+  }
+
+};
+
+#endif
diff --git a/src/systemc/tests/include/SimpleLTInitiator1.h b/src/systemc/tests/include/SimpleLTInitiator1.h
new file mode 100644 (file)
index 0000000..6f12712
--- /dev/null
@@ -0,0 +1,162 @@
+/*****************************************************************************
+
+  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.
+
+ *****************************************************************************/
+
+//====================================================================
+//  Nov 06, 2008
+//
+//  Updated by:
+//    Xiaopeng Qiu, JEDA Technologies, Inc
+//    Email:  qiuxp@jedatechnologies.net
+//
+//  To fix violations of TLM2.0 rules, which are detected by JEDA 
+//  TLM2.0 checker.
+//
+//====================================================================
+
+#ifndef __SIMPLE_LT_INITIATOR1_H__
+#define __SIMPLE_LT_INITIATOR1_H__
+
+#include "tlm.h"     /// TLM definitions
+#include <cassert>   /// STD assert ()
+
+class SimpleLTInitiator1 :
+  public sc_core::sc_module,
+  public virtual tlm::tlm_bw_transport_if<>
+{
+public:
+  typedef tlm::tlm_generic_payload        transaction_type;
+  typedef tlm::tlm_phase                  phase_type;
+  typedef tlm::tlm_sync_enum              sync_enum_type;
+  typedef tlm::tlm_fw_transport_if<>      fw_interface_type;
+  typedef tlm::tlm_bw_transport_if<>      bw_interface_type;
+  typedef tlm::tlm_initiator_socket<32>   initiator_socket_type;
+
+public:
+  initiator_socket_type socket;
+
+public:
+  SC_HAS_PROCESS(SimpleLTInitiator1);
+  SimpleLTInitiator1(sc_core::sc_module_name name,
+                  unsigned int nrOfTransactions = 0x5,
+                  unsigned int baseAddress = 0x0) :
+    sc_core::sc_module(name),
+    socket("socket"),
+    mNrOfTransactions(nrOfTransactions),
+    mBaseAddress(baseAddress),
+    mTransactionCount(0)
+  {
+    // Bind this initiator's interface to the initiator socket
+    socket(*this);
+
+    // Initiator thread
+    SC_THREAD(run);
+  }
+
+  bool initTransaction(transaction_type& trans)
+  {
+    if (mTransactionCount < mNrOfTransactions) {
+      trans.set_address(mBaseAddress + 4*mTransactionCount);
+      mData = mTransactionCount;
+      trans.set_command(tlm::TLM_WRITE_COMMAND);
+
+    } else if (mTransactionCount < 2 * mNrOfTransactions) {
+      trans.set_address(mBaseAddress + 4*(mTransactionCount - mNrOfTransactions));
+      mData = 0;
+      trans.set_command(tlm::TLM_READ_COMMAND);
+
+    } else {
+      return false;
+    }
+
+    trans.set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
+    trans.set_data_length(4);
+    trans.set_streaming_width(4);
+    trans.set_dmi_allowed(false);
+    trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
+
+    ++mTransactionCount;
+    return true;
+  }
+
+  void logStartTransation(transaction_type& trans)
+  {
+    if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+      std::cout << name() << ": Send write request: A = 0x"
+                << std::hex << (unsigned int)trans.get_address()
+                << ", D = 0x" << mData << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+
+    } else {
+      std::cout << name() << ": Send read request: A = 0x"
+                << std::hex << (unsigned int)trans.get_address() << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+    }
+  }
+
+  void logEndTransaction(transaction_type& trans)
+  {
+    if (trans.get_response_status() != tlm::TLM_OK_RESPONSE) {
+      std::cout << name() << ": Received error response @ "
+                << sc_core::sc_time_stamp() << std::endl;
+
+    } else {
+      std::cout << name() <<  ": Received ok response";
+      if (trans.get_command() == tlm::TLM_READ_COMMAND) {
+        std::cout << ": D = 0x" << std::hex << mData << std::dec;
+      }
+      std::cout << " @ " << sc_core::sc_time_stamp() << std::endl;
+    }
+  }
+
+  void run()
+  {
+    transaction_type trans;
+    sc_core::sc_time t(sc_core::SC_ZERO_TIME);
+    while (initTransaction(trans)) {
+      logStartTransation(trans);
+      socket->b_transport(trans, t);
+      wait(t);
+      logEndTransaction(trans);
+      t = sc_core::SC_ZERO_TIME;
+    }
+    wait();
+
+  }
+
+  tlm::tlm_sync_enum nb_transport_bw(transaction_type &,phase_type &,sc_core::sc_time & )
+  {
+    assert(0);  // should never happen
+    return tlm::TLM_COMPLETED;
+  }
+
+  void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
+                                 sc_dt::uint64 end_range)
+  {
+    // No DMI support: ignore
+  }
+
+private:
+  sc_core::sc_event mEndEvent;
+  unsigned int mNrOfTransactions;
+  unsigned int mBaseAddress;
+  unsigned int mTransactionCount;
+  unsigned int mData;
+};
+
+#endif
diff --git a/src/systemc/tests/include/SimpleLTInitiator1_DMI.h b/src/systemc/tests/include/SimpleLTInitiator1_DMI.h
new file mode 100644 (file)
index 0000000..4d98226
--- /dev/null
@@ -0,0 +1,305 @@
+/*****************************************************************************
+
+  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.
+
+ *****************************************************************************/
+
+//====================================================================
+//  Nov 06, 2008
+//
+//  Updated by:
+//    Xiaopeng Qiu, JEDA Technologies, Inc
+//    Email:  qiuxp@jedatechnologies.net
+//
+//  To fix violations of TLM2.0 rules, which are detected by JEDA 
+//  TLM2.0 checker.
+//
+//====================================================================
+
+#ifndef __SIMPLE_LT_INITIATOR1_DMI_H__
+#define __SIMPLE_LT_INITIATOR1_DMI_H__
+
+#include "tlm.h"
+#include <systemc>
+#include <cassert>
+#include <iostream>
+#include <iomanip>
+
+class SimpleLTInitiator1_dmi :
+  public sc_core::sc_module,
+  public virtual tlm::tlm_bw_transport_if<>
+{
+public:
+  typedef tlm::tlm_generic_payload      transaction_type;
+  typedef tlm::tlm_dmi                  dmi_type;
+  typedef tlm::tlm_phase                phase_type;
+  typedef tlm::tlm_sync_enum            sync_enum_type;
+  typedef tlm::tlm_fw_transport_if<>    fw_interface_type;
+  typedef tlm::tlm_bw_transport_if<>    bw_interface_type;
+  typedef tlm::tlm_initiator_socket<>   initiator_socket_type;
+
+public:
+  initiator_socket_type socket;
+
+public:
+  SC_HAS_PROCESS(SimpleLTInitiator1_dmi);
+  SimpleLTInitiator1_dmi(sc_core::sc_module_name name,
+                         unsigned int nrOfTransactions = 0x5,
+                         unsigned int baseAddress = 0x0) :
+    sc_core::sc_module(name),
+    socket("socket"),
+    mNrOfTransactions(nrOfTransactions),
+    mBaseAddress(baseAddress),
+    mTransactionCount(0)
+  {
+    invalidate(mDMIData);
+
+    // Bind this initiator's interface to the initiator socket
+    socket(*this);
+
+    // Initiator thread
+    SC_THREAD(run);
+  }
+
+  bool initTransaction(transaction_type& trans)
+  {
+    // initialize DMI hint:
+    trans.set_dmi_allowed(false);
+
+    if (mTransactionCount < mNrOfTransactions) {
+      trans.set_address(mBaseAddress + 4*mTransactionCount);
+      mData = mTransactionCount;
+      trans.set_command(tlm::TLM_WRITE_COMMAND);
+
+    } else if (mTransactionCount < 2 * mNrOfTransactions) {
+      trans.set_address(mBaseAddress + 4*(mTransactionCount-mNrOfTransactions));
+      mData = 0;
+      trans.set_command(tlm::TLM_READ_COMMAND);
+
+    } else {
+      return false;
+    }
+
+    trans.set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
+    trans.set_data_length(4);
+    trans.set_streaming_width(4);
+
+    ++mTransactionCount;
+    return true;
+  }
+
+  void logStartTransation(transaction_type& trans)
+  {
+    if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+      std::cout << name() << ": Send write request: A = 0x"
+                << std::hex << (unsigned int)trans.get_address()
+                << ", D = 0x" << mData << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+      
+    } else {
+      std::cout << name() << ": Send read request: A = 0x"
+                << std::hex << (unsigned int)trans.get_address() << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+    }
+  }
+
+  void logEndTransaction(transaction_type& trans)
+  {
+    if (trans.get_response_status() != tlm::TLM_OK_RESPONSE) {
+      std::cout << name() << ": Received error response @ "
+                << sc_core::sc_time_stamp() << std::endl;
+
+    } else {
+      std::cout << name() <<  ": Received ok response";
+      if (trans.get_command() == tlm::TLM_READ_COMMAND) {
+        std::cout << ": D = 0x" << std::hex << mData << std::dec;
+      }
+      std::cout << " @ " << sc_core::sc_time_stamp() << std::endl;
+    }
+  }
+
+  void run()
+  {
+    transaction_type trans;
+    phase_type phase;
+    sc_core::sc_time t;
+    
+    while (initTransaction(trans)) {
+      // Create transaction and initialise phase and t
+      phase = tlm::BEGIN_REQ;
+      t = sc_core::SC_ZERO_TIME;
+
+      logStartTransation(trans);
+
+      ///////////////////////////////////////////////////////////
+      // DMI handling:
+      // We use the DMI hint to check if it makes sense to ask for
+      // DMI pointers. The pattern is:
+      // - if the address is covered by a DMI region do a DMI access
+      // - otherwise do a normal transaction
+      //   -> check if we get a DMI hint and acquire the DMI pointers if it is
+      //      set
+      ///////////////////////////////////////////////////////////
+
+      // Check if the address is covered by our DMI region
+      if ( (trans.get_address() >= mDMIData.get_start_address()) &&
+           (trans.get_address() <= mDMIData.get_end_address()) ) {
+          // We can handle the data here. As the logEndTransaction is assuming
+          // something to happen in the data structure, we really need to
+          // do this:
+          trans.set_response_status(tlm::TLM_OK_RESPONSE);
+          sc_dt::uint64 tmp = trans.get_address() - mDMIData.get_start_address();
+          if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+              *(unsigned int*)&mDMIData.get_dmi_ptr()[tmp] = mData;
+
+          } else {
+              mData = *(unsigned int*)&mDMIData.get_dmi_ptr()[tmp];
+          }
+          
+          // Do the wait immediately. Note that doing the wait here eats almost
+          // all the performance anyway, so we only gain something if we're
+          // using temporal decoupling.
+          if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+            wait(mDMIData.get_write_latency());
+
+          } else {
+            wait(mDMIData.get_read_latency());
+          }
+          
+          logEndTransaction(trans);
+
+      } else { // we need a full transaction
+          sc_dt::uint64 addr = trans.get_address(); //Save address before it is mutated
+          socket->b_transport(trans, t);
+          wait(t);
+          logEndTransaction(trans);
+          
+                 // Acquire DMI pointer on is available:
+          if (trans.is_dmi_allowed())
+          {
+              dmi_type tmp;
+              tmp.init();
+              trans.set_address(addr);  //restore address, in case it was mutated.
+              trans.set_write();
+              if ( socket->get_direct_mem_ptr(trans, tmp)
+                   && tmp.is_write_allowed() )
+              {
+                  mDMIData = tmp;
+              }
+          }
+      }
+    }
+    wait();
+  }
+
+  sync_enum_type nb_transport_bw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t)
+  {
+      // We should never be called
+      assert(0);
+      return tlm::TLM_COMPLETED;
+  }
+
+  void invalidate(dmi_type& dmiData)
+  {
+    dmiData.set_start_address(1);
+    dmiData.set_end_address(0);
+  }
+
+  // Invalidate DMI pointer(s)
+  void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
+                                 sc_dt::uint64 end_range)
+  {
+      // do the invalidation if there is an address range overlap
+      if (start_range <= mDMIData.get_end_address ()&&
+          end_range >= mDMIData.get_start_address()) {
+          std::cout <<  name() << ": got DMI pointer invalidation"
+                    << " @ " << sc_core::sc_time_stamp() << std::endl;
+          
+          invalidate(mDMIData);
+      } else {
+          std::cout <<  name() << ": ignored DMI invalidation for addresses "
+                    << std::hex << start_range << ", "
+                    << end_range << std::dec
+                    << " @ " << sc_core::sc_time_stamp() << std::endl;
+      }
+  }
+
+  // Test for transport_dbg:
+  // FIXME: use a configurable address
+  void end_of_simulation()
+  {
+    std::cout <<  name() << ", <<SimpleLTInitiator1>>:" << std::endl
+              << std::endl;
+    unsigned char data[32];
+
+    transaction_type trans;
+    trans.set_address(mBaseAddress);
+    trans.set_data_length(32);
+    trans.set_data_ptr(data);
+    trans.set_read();
+
+    unsigned int n = socket->transport_dbg(trans);
+        
+    std::cout << "Mem @" << std::hex << mBaseAddress << std::endl;
+    unsigned int j = 0;
+        
+    if (n > 0)
+    {
+        // always align endianness, so that we don't get a diff when
+        // printing the raw data
+        int e_start = 0;
+        int e_end = 4;
+        int e_increment = 1;
+        if (!tlm::host_has_little_endianness())
+        {
+            e_start = 3;
+            e_end = -1;
+            e_increment = -1;
+        }
+        
+        for (unsigned int i=0; i<n; i+=4)
+        {
+            for (int k=e_start; k!=e_end; k+=e_increment)
+            {
+                std::cout << std::setw(2) << std::setfill('0')
+                          << (int)data[i+k];
+                j++;
+                if (j==16) {
+                    j=0;
+                    std::cout << std::endl;
+                } else {
+                    std::cout << " ";
+                }
+            }
+        }
+    }
+    else
+    {
+        std::cout << "ERROR: debug transaction didn't give data." << std::endl;
+    }
+    std::cout << std::dec << std::endl;  
+  }
+private:
+  dmi_type mDMIData;
+
+  sc_core::sc_event mEndEvent;
+  unsigned int mNrOfTransactions;
+  unsigned int mBaseAddress;
+  unsigned int mTransactionCount;
+  unsigned int mData;
+};
+
+#endif
diff --git a/src/systemc/tests/include/SimpleLTInitiator2.h b/src/systemc/tests/include/SimpleLTInitiator2.h
new file mode 100644 (file)
index 0000000..ee0118a
--- /dev/null
@@ -0,0 +1,151 @@
+/*****************************************************************************
+
+  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.
+
+ *****************************************************************************/
+
+//====================================================================
+//  Nov 06, 2008
+//
+//  Updated by:
+//    Xiaopeng Qiu, JEDA Technologies, Inc
+//    Email:  qiuxp@jedatechnologies.net
+//
+//  To fix violations of TLM2.0 rules, which are detected by JEDA 
+//  TLM2.0 checker.
+//
+//====================================================================
+
+#ifndef __SIMPLE_LT_INITIATOR2_H__
+#define __SIMPLE_LT_INITIATOR2_H__
+
+#include "tlm.h"
+#include "tlm_utils/simple_initiator_socket.h"
+//#include <systemc>
+#include <cassert>
+//#include <iostream>
+
+class SimpleLTInitiator2 : public sc_core::sc_module
+{
+public:
+  typedef tlm::tlm_generic_payload                  transaction_type;
+  typedef tlm::tlm_phase                            phase_type;
+  typedef tlm::tlm_sync_enum                        sync_enum_type;
+  typedef tlm_utils::simple_initiator_socket<SimpleLTInitiator2> initiator_socket_type;
+
+public:
+  initiator_socket_type socket;
+
+public:
+  SC_HAS_PROCESS(SimpleLTInitiator2);
+  SimpleLTInitiator2(sc_core::sc_module_name name,
+                     unsigned int nrOfTransactions = 0x5,
+                     unsigned int baseAddress = 0x0) :
+    sc_core::sc_module(name),
+    socket("socket"),
+    mNrOfTransactions(nrOfTransactions),
+    mBaseAddress(baseAddress),
+    mTransactionCount(0)
+  {
+    // Initiator thread
+    SC_THREAD(run);
+  }
+
+  bool initTransaction(transaction_type& trans)
+  {
+    if (mTransactionCount < mNrOfTransactions) {
+      trans.set_address(mBaseAddress + 4*mTransactionCount);
+      mData = mTransactionCount;
+      trans.set_command(tlm::TLM_WRITE_COMMAND);
+
+    } else if (mTransactionCount < 2 * mNrOfTransactions) {
+      trans.set_address(mBaseAddress + 4*(mTransactionCount - mNrOfTransactions));
+      mData = 0;
+      trans.set_command(tlm::TLM_READ_COMMAND);
+
+    } else {
+      return false;
+    }
+
+    trans.set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
+    trans.set_data_length(4);
+    trans.set_streaming_width(4);
+    trans.set_dmi_allowed(false);
+    trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
+
+    ++mTransactionCount;
+    return true;
+  }
+
+  void logStartTransation(transaction_type& trans)
+  {
+    if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+      std::cout << name() << ": Send write request: A = 0x"
+                << std::hex << (unsigned int)trans.get_address()
+                << ", D = 0x" << mData << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+
+    } else {
+      std::cout << name() << ": Send read request: A = 0x"
+                << std::hex << (unsigned int)trans.get_address() << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+    }
+  }
+
+  void logEndTransaction(transaction_type& trans)
+  {
+    if (trans.get_response_status() != tlm::TLM_OK_RESPONSE) {
+      std::cout << name() << ": Received error response @ "
+                << sc_core::sc_time_stamp() << std::endl;
+
+    } else {
+      std::cout << name() <<  ": Received ok response";
+      if (trans.get_command() == tlm::TLM_READ_COMMAND) {
+        std::cout << ": D = 0x" << std::hex << mData << std::dec;
+      }
+      std::cout << " @ " << sc_core::sc_time_stamp() << std::endl;
+    }
+  }
+
+  void run()
+  {
+    transaction_type trans;
+    sc_core::sc_time t;
+
+    while (initTransaction(trans)) {
+      // Create transaction and initialise t
+      t = sc_core::SC_ZERO_TIME;
+
+      logStartTransation(trans);
+
+      socket->b_transport(trans, t);
+      wait(t);
+
+      logEndTransaction(trans);
+    }
+    wait();
+
+  }
+
+private:
+  sc_core::sc_event mEndEvent;
+  unsigned int mNrOfTransactions;
+  unsigned int mBaseAddress;
+  unsigned int mTransactionCount;
+  unsigned int mData;
+};
+
+#endif
diff --git a/src/systemc/tests/include/SimpleLTInitiator2_DMI.h b/src/systemc/tests/include/SimpleLTInitiator2_DMI.h
new file mode 100644 (file)
index 0000000..39fb76b
--- /dev/null
@@ -0,0 +1,299 @@
+/*****************************************************************************
+
+  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.
+
+ *****************************************************************************/
+
+//====================================================================
+//  Nov 06, 2008
+//
+//  Updated by:
+//    Xiaopeng Qiu, JEDA Technologies, Inc
+//    Email:  qiuxp@jedatechnologies.net
+//
+//  To fix violations of TLM2.0 rules, which are detected by JEDA 
+//  TLM2.0 checker.
+//
+//====================================================================
+
+#ifndef __SIMPLE_LT_INITIATOR2_DMI_H__
+#define __SIMPLE_LT_INITIATOR2_DMI_H__
+
+#include "tlm.h"
+#include "tlm_utils/simple_initiator_socket.h"
+#include <systemc>
+#include <cassert>
+#include <iostream>
+#include <iomanip>
+#include <map>
+
+class SimpleLTInitiator2_dmi : public sc_core::sc_module
+{
+public:
+  typedef tlm::tlm_generic_payload                      transaction_type;
+  typedef tlm::tlm_dmi                                  dmi_type;
+  typedef tlm::tlm_phase                                phase_type;
+  typedef tlm::tlm_sync_enum                            sync_enum_type;
+  typedef tlm_utils::simple_initiator_socket<SimpleLTInitiator2_dmi> initiator_socket_type;
+
+public:
+  initiator_socket_type socket;
+
+public:
+  SC_HAS_PROCESS(SimpleLTInitiator2_dmi);
+  SimpleLTInitiator2_dmi(sc_core::sc_module_name name,
+                  unsigned int nrOfTransactions = 0x5,
+                  unsigned int baseAddress = 0x0) :
+    sc_core::sc_module(name),
+    socket("socket"),
+    mNrOfTransactions(nrOfTransactions),
+    mBaseAddress(baseAddress),
+    mTransactionCount(0)
+  {
+    mDMIDataReads.first.set_start_address(1);
+    mDMIDataReads.first.set_end_address(0);
+    mDMIDataWrites.first.set_start_address(1);
+    mDMIDataWrites.first.set_end_address(0);
+
+    // register invalidate method
+    socket.register_invalidate_direct_mem_ptr(this, &SimpleLTInitiator2_dmi::invalidate_direct_mem_ptr);
+
+    // Initiator thread
+    SC_THREAD(run);
+  }
+
+  bool initTransaction(transaction_type& trans)
+  {
+    if (mTransactionCount < mNrOfTransactions) {
+      trans.set_address(mBaseAddress + 4*mTransactionCount);
+      mData = mTransactionCount;
+      trans.set_command(tlm::TLM_WRITE_COMMAND);
+
+    } else if (mTransactionCount < 2 * mNrOfTransactions) {
+      trans.set_address(mBaseAddress + 4*(mTransactionCount-mNrOfTransactions));
+      mData = 0;
+      trans.set_command(tlm::TLM_READ_COMMAND);
+
+    } else {
+      return false;
+    }
+
+    trans.set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
+    trans.set_data_length(4);
+    trans.set_streaming_width(4);
+    trans.set_dmi_allowed(false);
+    trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
+
+    ++mTransactionCount;
+    return true;
+  }
+
+  void logStartTransation(transaction_type& trans)
+  {
+    if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+      std::cout << name() << ": Send write request: A = 0x"
+                << std::hex << (unsigned int)trans.get_address()
+                << ", D = 0x" << mData << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+      
+    } else {
+      std::cout << name() << ": Send read request: A = 0x"
+                << std::hex << (unsigned int)trans.get_address() << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+    }
+  }
+
+  void logEndTransaction(transaction_type& trans)
+  {
+    if (trans.get_response_status() != tlm::TLM_OK_RESPONSE) {
+      std::cout << name() << ": Received error response @ "
+                << sc_core::sc_time_stamp() << std::endl;
+
+    } else {
+      std::cout << name() <<  ": Received ok response";
+      if (trans.get_command() == tlm::TLM_READ_COMMAND) {
+        std::cout << ": D = 0x" << std::hex << mData << std::dec;
+      }
+      std::cout << " @ " << sc_core::sc_time_stamp() << std::endl;
+    }
+  }
+
+  std::pair<dmi_type, bool>& getDMIData(const transaction_type& trans)
+  {
+    if (trans.get_command() == tlm::TLM_READ_COMMAND) {
+      return mDMIDataReads;
+
+    } else { // WRITE
+      return mDMIDataWrites;
+    }
+  }
+
+  void run()
+  {
+    transaction_type trans;
+    sc_core::sc_time t;
+    
+    while (initTransaction(trans)) {
+      // Create transaction and initialise t
+      t = sc_core::SC_ZERO_TIME;
+
+      logStartTransation(trans);
+
+      ///////////////////////////////////////////////////////////
+      // DMI handling:
+      // We do *not* use the DMI hint to check if it makes sense to ask for
+      // DMI pointers. So the pattern is:
+      // - if the address is not covered by a DMI region try to acquire DMI
+      //   pointers
+      // - if we have a DMI pointer, do the DMI "transaction"
+      // - otherwise fall back to a normal transaction
+      ///////////////////////////////////////////////////////////
+
+      std::pair<dmi_type, bool>& dmi_data = getDMIData(trans);
+
+      // Check if we need to acquire a DMI pointer
+      if((trans.get_address() < dmi_data.first.get_start_address()) ||
+         (trans.get_address() > dmi_data.first.get_end_address()) )
+      {
+          sc_dt::uint64 address = trans.get_address(); //save original address
+          dmi_data.second =
+            socket->get_direct_mem_ptr(trans,
+                                       dmi_data.first);
+          trans.set_address(address);
+      }
+      // Do DMI "transaction" if we have a valid region
+      if (dmi_data.second &&
+          (trans.get_address() >= dmi_data.first.get_start_address()) &&
+          (trans.get_address() <= dmi_data.first.get_end_address()) )
+      {
+          // We can handle the data here. As the logEndTransaction is assuming
+          // something to happen in the data structure, we really need to
+          // do this:
+          trans.set_response_status(tlm::TLM_OK_RESPONSE);
+          sc_dt::uint64 tmp = trans.get_address() - dmi_data.first.get_start_address();
+          if (trans.get_command() == tlm::TLM_WRITE_COMMAND)
+          {
+              *(unsigned int*)&dmi_data.first.get_dmi_ptr()[tmp] = mData;
+          }
+          else
+          {
+              mData = *(unsigned int*)&dmi_data.first.get_dmi_ptr()[tmp];
+          }
+          
+          // Do the wait immediately. Note that doing the wait here eats almost
+          // all the performance anyway, so we only gain something if we're
+          // using temporal decoupling.
+          if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+            wait(dmi_data.first.get_write_latency());
+
+          } else {
+            wait(dmi_data.first.get_read_latency());
+          }
+      }
+      else // we need a full transaction
+      {
+          socket->b_transport(trans, t);
+          wait(t);
+      }
+      logEndTransaction(trans);
+    }
+    wait();
+
+  }
+
+  // Invalidate DMI pointer(s)
+  void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
+                                 sc_dt::uint64 end_range)
+  {
+    // FIXME: probably faster to always invalidate everything?
+    if (start_range <= mDMIDataReads.first.get_end_address ()&&
+        end_range >= mDMIDataReads.first.get_start_address()) {
+        mDMIDataReads.second = false;
+    }
+    if (start_range <= mDMIDataWrites.first.get_end_address ()&&
+        end_range >= mDMIDataWrites.first.get_start_address()) {
+      mDMIDataWrites.second = false;
+    }
+  }
+
+  // Test for transport_dbg, this one should fail in bus_dmi as we address
+  // a target that doesn't support transport_dbg:
+  // FIXME: use a configurable address
+  void end_of_simulation()
+  {
+    std::cout <<  name() << ", <<SimpleLTInitiator1>>:" << std::endl
+              << std::endl;
+    unsigned char data[32];
+
+    transaction_type trans;
+    trans.set_address(mBaseAddress);
+    trans.set_data_length(32);
+    trans.set_data_ptr(data);
+    trans.set_read();
+
+    unsigned int n = socket->transport_dbg(trans);
+    
+    std::cout << "Mem @" << std::hex << mBaseAddress << std::endl;
+    unsigned int j = 0;
+        
+    if (n > 0)
+    {
+        // always align endianness, so that we don't get a diff when
+        // printing the raw data
+        int e_start = 0;
+        int e_end = 4;
+        int e_increment = 1;
+        if (!tlm::host_has_little_endianness())
+        {
+            e_start = 3;
+            e_end = -1;
+            e_increment = -1;
+        }
+        
+        for (unsigned int i=0; i<n; i+=4)
+        {
+            for (int k=e_start; k!=e_end; k+=e_increment)
+            {
+                std::cout << std::setw(2) << std::setfill('0')
+                          << (int)data[i+k];
+                j++;
+                if (j==16) {
+                    j=0;
+                    std::cout << std::endl;
+                } else {
+                    std::cout << " ";
+                }
+            }
+        }
+    }
+    else
+    {
+        std::cout << "OK: debug transaction didn't give data." << std::endl;
+    }
+    std::cout << std::dec << std::endl;  
+  }
+private:
+  std::pair<dmi_type, bool> mDMIDataReads;
+  std::pair<dmi_type, bool> mDMIDataWrites;
+
+  sc_core::sc_event mEndEvent;
+  unsigned int mNrOfTransactions;
+  unsigned int mBaseAddress;
+  unsigned int mTransactionCount;
+  unsigned int mData;
+};
+
+#endif
diff --git a/src/systemc/tests/include/SimpleLTInitiator3.h b/src/systemc/tests/include/SimpleLTInitiator3.h
new file mode 100644 (file)
index 0000000..d4eb633
--- /dev/null
@@ -0,0 +1,152 @@
+/*****************************************************************************
+
+  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.
+
+ *****************************************************************************/
+
+//====================================================================
+//  Nov 06, 2008
+//
+//  Updated by:
+//    Xiaopeng Qiu, JEDA Technologies, Inc
+//    Email:  qiuxp@jedatechnologies.net
+//
+//  To fix violations of TLM2.0 rules, which are detected by JEDA 
+//  TLM2.0 checker.
+//
+//====================================================================
+
+#ifndef __SIMPLE_LT_INITIATOR3_H__
+#define __SIMPLE_LT_INITIATOR3_H__
+
+#include "tlm.h"
+#include "tlm_utils/simple_initiator_socket.h"
+//#include <systemc>
+#include <cassert>
+//#include <iostream>
+
+class SimpleLTInitiator3 : public sc_core::sc_module
+{
+public:
+  typedef tlm::tlm_generic_payload                  transaction_type;
+  typedef tlm::tlm_phase                            phase_type;
+  typedef tlm::tlm_sync_enum                        sync_enum_type;
+  typedef tlm_utils::simple_initiator_socket<SimpleLTInitiator3> initiator_socket_type;
+
+public:
+  initiator_socket_type socket;
+
+public:
+  SC_HAS_PROCESS(SimpleLTInitiator3);
+  SimpleLTInitiator3(sc_core::sc_module_name name,
+                  unsigned int nrOfTransactions = 0x5,
+                  unsigned int baseAddress = 0x0) :
+    sc_core::sc_module(name),
+    socket("socket"),
+    mNrOfTransactions(nrOfTransactions),
+    mBaseAddress(baseAddress),
+    mTransactionCount(0)
+  {
+    // Initiator thread
+    SC_THREAD(run);
+  }
+
+  bool initTransaction(transaction_type& trans)
+  {
+    if (mTransactionCount < mNrOfTransactions) {
+      trans.set_address(mBaseAddress + 4*mTransactionCount);
+      mData = mTransactionCount;
+      trans.set_command(tlm::TLM_WRITE_COMMAND);
+
+    } else if (mTransactionCount < 2 * mNrOfTransactions) {
+      trans.set_address(mBaseAddress + 4*(mTransactionCount-mNrOfTransactions));
+      mData = 0;
+      trans.set_command(tlm::TLM_READ_COMMAND);
+
+    } else {
+      return false;
+    }
+
+    trans.set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
+    trans.set_data_length(4);
+    trans.set_streaming_width(4);
+    trans.set_dmi_allowed(false);
+    trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
+
+    ++mTransactionCount;
+    return true;
+  }
+
+  void logStartTransation(transaction_type& trans)
+  {
+    if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+      std::cout << name() << ": Send write request: A = 0x"
+                << std::hex << (unsigned int)trans.get_address()
+                << ", D = 0x" << mData << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+      
+    } else {
+      std::cout << name() << ": Send read request: A = 0x"
+                << std::hex << (unsigned int)trans.get_address() << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+    }
+  }
+
+  void logEndTransaction(transaction_type& trans)
+  {
+    if (trans.get_response_status() != tlm::TLM_OK_RESPONSE) {
+      std::cout << name() << ": Received error response @ "
+                << sc_core::sc_time_stamp() << std::endl;
+
+    } else {
+      std::cout << name() <<  ": Received ok response";
+      if (trans.get_command() == tlm::TLM_READ_COMMAND) {
+        std::cout << ": D = 0x" << std::hex << mData << std::dec;
+      }
+      std::cout << " @ " << sc_core::sc_time_stamp() << std::endl;
+    }
+  }
+
+  void run()
+  {
+    transaction_type trans;
+    sc_core::sc_time t;
+    
+    while (initTransaction(trans)) {
+      // Create transaction and initialise t
+      t = sc_core::SC_ZERO_TIME;
+
+      logStartTransation(trans);
+
+      socket->b_transport(trans, t);
+      // Transaction Finished, wait for the returned delay
+      wait(t);
+
+      logEndTransaction(trans);
+    }
+    wait();
+
+  }
+
+private:
+  sc_core::sc_event mEndEvent;
+  unsigned int mNrOfTransactions;
+  unsigned int mBaseAddress;
+  unsigned int mTransactionCount;
+  unsigned int mData;
+};
+
+#endif
diff --git a/src/systemc/tests/include/SimpleLTInitiator3_DMI.h b/src/systemc/tests/include/SimpleLTInitiator3_DMI.h
new file mode 100644 (file)
index 0000000..6453a16
--- /dev/null
@@ -0,0 +1,244 @@
+/*****************************************************************************
+
+  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.
+
+ *****************************************************************************/
+
+//====================================================================
+//  Nov 06, 2008
+//
+//  Updated by:
+//    Xiaopeng Qiu, JEDA Technologies, Inc
+//    Email:  qiuxp@jedatechnologies.net
+//
+//  To fix violations of TLM2.0 rules, which are detected by JEDA 
+//  TLM2.0 checker.
+//
+//====================================================================
+
+#ifndef __SIMPLE_LT_INITIATOR3_DMI_H__
+#define __SIMPLE_LT_INITIATOR3_DMI_H__
+
+#include "tlm.h"
+#include "tlm_utils/simple_initiator_socket.h"
+#include <systemc>
+#include <cassert>
+#include <iostream>
+#include <map>
+
+class SimpleLTInitiator3_dmi : public sc_core::sc_module
+{
+public:
+  typedef tlm::tlm_generic_payload                       transaction_type;
+  typedef tlm::tlm_dmi                                   dmi_type;
+  typedef tlm::tlm_phase                                 phase_type;
+  typedef tlm::tlm_sync_enum                             sync_enum_type;
+  typedef tlm_utils::simple_initiator_socket<SimpleLTInitiator3_dmi>  initiator_socket_type;
+
+public:
+  initiator_socket_type socket;
+
+public:
+  SC_HAS_PROCESS(SimpleLTInitiator3_dmi);
+  SimpleLTInitiator3_dmi(sc_core::sc_module_name name,
+                  unsigned int nrOfTransactions = 0x5,
+                  unsigned int baseAddress = 0x0) :
+    sc_core::sc_module(name),
+    socket("socket"),
+    mNrOfTransactions(nrOfTransactions),
+    mBaseAddress(baseAddress),
+    mTransactionCount(0)
+  {
+    mDMIDataReads.first.set_start_address(1);
+    mDMIDataReads.first.set_end_address(0);
+    mDMIDataWrites.first.set_start_address(1);
+    mDMIDataWrites.first.set_end_address(0);
+
+    socket.register_invalidate_direct_mem_ptr(this, &SimpleLTInitiator3_dmi::invalidate_direct_mem_ptr);
+
+    // Initiator thread
+    SC_THREAD(run);
+  }
+
+  bool initTransaction(transaction_type& trans)
+  {
+    if (mTransactionCount < mNrOfTransactions) {
+      trans.set_address(mBaseAddress + 4*mTransactionCount);
+      mData = mTransactionCount;
+      trans.set_command(tlm::TLM_WRITE_COMMAND);
+
+    } else if (mTransactionCount < 2 * mNrOfTransactions) {
+      trans.set_address(mBaseAddress + 4*(mTransactionCount-mNrOfTransactions));
+      mData = 0;
+      trans.set_command(tlm::TLM_READ_COMMAND);
+
+    } else {
+      return false;
+    }
+
+    trans.set_data_ptr(reinterpret_cast<unsigned char*>(&mData));
+    trans.set_data_length(4);
+    trans.set_streaming_width(4);
+    trans.set_dmi_allowed(false);
+    trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
+
+    ++mTransactionCount;
+    return true;
+  }
+
+  void logStartTransation(transaction_type& trans)
+  {
+    if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+      std::cout << name() << ": Send write request: A = 0x"
+                << std::hex << (unsigned int)trans.get_address()
+                << ", D = 0x" << mData << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+      
+    } else {
+      std::cout << name() << ": Send read request: A = 0x"
+                << std::hex << (unsigned int)trans.get_address() << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+    }
+  }
+
+  void logEndTransaction(transaction_type& trans)
+  {
+    if (trans.get_response_status() != tlm::TLM_OK_RESPONSE) {
+      std::cout << name() << ": Received error response @ "
+                << sc_core::sc_time_stamp() << std::endl;
+
+    } else {
+      std::cout << name() <<  ": Received ok response";
+      if (trans.get_command() == tlm::TLM_READ_COMMAND) {
+        std::cout << ": D = 0x" << std::hex << mData << std::dec;
+      }
+      std::cout << " @ " << sc_core::sc_time_stamp() << std::endl;
+    }
+  }
+
+  std::pair<dmi_type, bool>& getDMIData(const transaction_type& trans)
+  {
+    if (trans.get_command() == tlm::TLM_READ_COMMAND) {
+      return mDMIDataReads;
+
+    } else { // WRITE
+      return mDMIDataWrites;
+    }
+  }
+
+  void run()
+  {
+    transaction_type trans;
+    sc_core::sc_time t;
+    
+    while (initTransaction(trans)) {
+      // Create transaction and initialise t
+      t = sc_core::SC_ZERO_TIME;
+
+      logStartTransation(trans);
+
+      ///////////////////////////////////////////////////////////
+      // DMI handling:
+      // We do *not* use the DMI hint to check if it makes sense to ask for
+      // DMI pointers. So the pattern is:
+      // - if the address is not covered by a DMI region try to acquire DMI
+      //   pointers
+      // - if we have a DMI pointer, do the DMI "transaction"
+      // - otherwise fall back to a normal transaction
+      ///////////////////////////////////////////////////////////
+
+      std::pair<dmi_type, bool>& dmi_data = getDMIData(trans);
+
+      // Check if we need to acquire a DMI pointer
+      if((trans.get_address() < dmi_data.first.get_start_address()) ||
+         (trans.get_address() > dmi_data.first.get_end_address()) )
+      {
+          sc_dt::uint64 address = trans.get_address(); //save original address
+          dmi_data.second =
+            socket->get_direct_mem_ptr(trans,
+                                       dmi_data.first);
+          trans.set_address(address);
+      }
+      // Do DMI "transaction" if we have a valid region
+      if (dmi_data.second &&
+          (trans.get_address() >= dmi_data.first.get_start_address()) &&
+          (trans.get_address() <= dmi_data.first.get_end_address()) )
+      {
+          // We can handle the data here. As the logEndTransaction is assuming
+          // something to happen in the data structure, we really need to
+          // do this:
+          trans.set_response_status(tlm::TLM_OK_RESPONSE);
+
+          sc_dt::uint64 tmp = trans.get_address() - dmi_data.first.get_start_address();
+          if (trans.get_command() == tlm::TLM_WRITE_COMMAND)
+          {
+              *(unsigned int*)&dmi_data.first.get_dmi_ptr()[tmp] = mData;
+          }
+          else
+          {
+              mData = *(unsigned int*)&dmi_data.first.get_dmi_ptr()[tmp];
+          }
+          
+          // Do the wait immediately. Note that doing the wait here eats almost
+          // all the performance anyway, so we only gain something if we're
+          // using temporal decoupling.
+          if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+            wait(dmi_data.first.get_write_latency());
+
+          } else {
+            wait(dmi_data.first.get_read_latency());
+          }
+      }
+      else // we need a full transaction
+      {
+          socket->b_transport(trans, t);
+          // wait for the returned delay
+          wait(t);
+      }
+
+      logEndTransaction(trans);
+    }
+    wait();
+
+  }
+
+  // Invalidate DMI pointer(s)
+  void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
+                                 sc_dt::uint64 end_range)
+  {
+    // FIXME: probably faster to always invalidate everything?
+    if (start_range <= mDMIDataReads.first.get_end_address ()&&
+        end_range >= mDMIDataReads.first.get_start_address()) {
+        mDMIDataReads.second = false;
+    }
+    if (start_range <= mDMIDataWrites.first.get_end_address ()&&
+        end_range >= mDMIDataWrites.first.get_start_address()) {
+      mDMIDataWrites.second = false;
+    }
+  }
+
+private:
+  std::pair<dmi_type, bool> mDMIDataReads;
+  std::pair<dmi_type, bool> mDMIDataWrites;
+  
+  sc_core::sc_event mEndEvent;
+  unsigned int mNrOfTransactions;
+  unsigned int mBaseAddress;
+  unsigned int mTransactionCount;
+  unsigned int mData;
+};
+
+#endif
diff --git a/src/systemc/tests/include/SimpleLTTarget1.h b/src/systemc/tests/include/SimpleLTTarget1.h
new file mode 100644 (file)
index 0000000..37ac19a
--- /dev/null
@@ -0,0 +1,158 @@
+/*****************************************************************************
+
+  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 __SIMPLE_LT_TARGET1_H__
+#define __SIMPLE_LT_TARGET1_H__
+
+#include "tlm.h"
+#include <cassert>
+#include <vector>
+
+class SimpleLTTarget1 :
+  public sc_core::sc_module,
+  public virtual tlm::tlm_fw_transport_if<>
+{
+public:
+  typedef tlm::tlm_generic_payload      transaction_type;
+  typedef tlm::tlm_phase                phase_type;
+  typedef tlm::tlm_sync_enum            sync_enum_type;
+  typedef tlm::tlm_fw_transport_if<>    fw_interface_type;
+  typedef tlm::tlm_bw_transport_if<>    bw_interface_type;
+  typedef tlm::tlm_target_socket<32>    target_socket_type;
+
+public:
+  target_socket_type socket;
+
+public:
+  SC_HAS_PROCESS(SimpleLTTarget1);
+  SimpleLTTarget1(sc_core::sc_module_name name, bool invalidate = false) :
+      sc_core::sc_module(name),
+      socket("socket"),
+      m_invalidate(invalidate)
+  {
+    // Bind this target's interface to the target socket
+    socket(*this);
+    if (invalidate)
+    {
+        SC_METHOD(invalidate_dmi_method);
+        sensitive << m_invalidate_dmi_event;
+        dont_initialize();
+        m_invalidate_dmi_time = sc_core::sc_time(25, sc_core::SC_NS);
+    }
+  }
+
+  sync_enum_type nb_transport_fw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t)
+  {
+    //Target never calls wait, so we can do this
+    b_transport(trans, t);
+
+    return tlm::TLM_COMPLETED;
+  }
+
+  void b_transport(transaction_type& trans, sc_core::sc_time &t)
+  {
+    sc_dt::uint64 address = trans.get_address();
+    assert(address < 400);
+
+    unsigned int& data = *reinterpret_cast<unsigned int*>(trans.get_data_ptr());
+    if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+      std::cout << name() << ": Received write request: A = 0x"
+                << std::hex << (unsigned int)address
+                << ", D = 0x" << data << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+
+      *reinterpret_cast<unsigned int*>(&mMem[address]) = data;
+      t+=  sc_core::sc_time(10, sc_core::SC_NS);
+
+    } else {
+      std::cout << name() << ": Received read request: A = 0x"
+                << std::hex << (unsigned int)address << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+
+      data = *reinterpret_cast<unsigned int*>(&mMem[address]);
+      t += sc_core::sc_time(100, sc_core::SC_NS);
+    }
+
+    trans.set_response_status(tlm::TLM_OK_RESPONSE);
+
+    trans.set_dmi_allowed(true);
+  }
+
+  unsigned int transport_dbg(transaction_type& r)
+  {
+    if (r.get_address() >= 400) return 0;
+
+    unsigned int tmp = (int)r.get_address();
+    unsigned int num_bytes;
+    if (tmp + r.get_data_length() >= 400) {
+      num_bytes = 400 - tmp;
+
+    } else {
+      num_bytes = r.get_data_length();
+    }
+    if (r.is_read()) {
+      for (unsigned int i = 0; i < num_bytes; ++i) {
+        r.get_data_ptr()[i] = mMem[i + tmp];
+      }
+
+    } else {
+      for (unsigned int i = 0; i < num_bytes; ++i) {
+        mMem[i + tmp] = r.get_data_ptr()[i];
+      }
+    }
+    return num_bytes;
+  }
+
+  bool get_direct_mem_ptr(transaction_type& trans,
+                          tlm::tlm_dmi&  dmi_data)
+  {
+    sc_dt::uint64 address = trans.get_address();
+    if (m_invalidate) m_invalidate_dmi_event.notify(m_invalidate_dmi_time);
+    if (address < 400) {
+      dmi_data.allow_read_write();
+      dmi_data.set_start_address(0x0);
+      dmi_data.set_end_address(399);
+      dmi_data.set_dmi_ptr(mMem);
+      dmi_data.set_read_latency(sc_core::sc_time(100, sc_core::SC_NS));
+      dmi_data.set_write_latency(sc_core::sc_time(10, sc_core::SC_NS));
+      return true;
+
+    } else {
+      // should not happen
+      dmi_data.set_start_address(trans.get_address());
+      dmi_data.set_end_address(trans.get_address());
+      return false;
+
+    }
+  }
+
+  void invalidate_dmi_method()
+  {
+      sc_dt::uint64 start_address = 0x0;
+      sc_dt::uint64 end_address = 399;
+      socket->invalidate_direct_mem_ptr(start_address, end_address);
+  }
+private:
+  unsigned char mMem[400];
+  bool              m_invalidate;
+  sc_core::sc_event m_invalidate_dmi_event;
+  sc_core::sc_time  m_invalidate_dmi_time;
+};
+
+#endif
diff --git a/src/systemc/tests/include/SimpleLTTarget2.h b/src/systemc/tests/include/SimpleLTTarget2.h
new file mode 100644 (file)
index 0000000..61558dc
--- /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.
+
+ *****************************************************************************/
+
+#ifndef __SIMPLE_LT_TARGET2_H__
+#define __SIMPLE_LT_TARGET2_H__
+
+#include "tlm.h"
+#include "tlm_utils/passthrough_target_socket.h"
+#include <cassert>
+#include <vector>
+
+class SimpleLTTarget2 : public sc_core::sc_module
+{
+public:
+  typedef tlm::tlm_generic_payload             transaction_type;
+  typedef tlm::tlm_phase                       phase_type;
+  typedef tlm::tlm_sync_enum                   sync_enum_type;
+  typedef tlm_utils::passthrough_target_socket<SimpleLTTarget2> target_socket_type;
+  
+
+public:
+  target_socket_type socket;
+
+public:
+  SimpleLTTarget2(sc_core::sc_module_name name) :
+    sc_core::sc_module(name),
+    socket("socket")
+  {
+    // register nb_transport method
+    socket.register_b_transport(this, &SimpleLTTarget2::myBTransport);
+    socket.register_nb_transport_fw(this, &SimpleLTTarget2::myNBTransport);
+    socket.register_get_direct_mem_ptr(this, &SimpleLTTarget2::myGetDMIPtr);
+
+    // TODO: we don't register the transport_dbg callback here, so we
+    // can test if something bad happens
+    // REGISTER_DEBUGTRANSPORT(socket, transport_dbg, 0);
+  }
+
+  void myBTransport(transaction_type& trans,
+                     sc_core::sc_time& t)
+  {
+    sc_dt::uint64 address = trans.get_address();
+    assert(address < 400);
+
+    unsigned int& data = *reinterpret_cast<unsigned int*>(trans.get_data_ptr());
+    if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
+      std::cout << name() << ": Received write request: A = 0x"
+                << std::hex << (unsigned int)address
+                << ", D = 0x" << data << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+
+      *reinterpret_cast<unsigned int*>(&mMem[address]) = data;
+      t += sc_core::sc_time(10, sc_core::SC_NS);
+
+    } else {
+      std::cout << name() << ": Received read request: A = 0x"
+                << std::hex << (unsigned int)address << std::dec
+                << " @ " << sc_core::sc_time_stamp() << std::endl;
+
+      data = *reinterpret_cast<unsigned int*>(&mMem[address]);
+      t += sc_core::sc_time(100, sc_core::SC_NS);
+    }
+
+    trans.set_response_status(tlm::TLM_OK_RESPONSE);
+
+    trans.set_dmi_allowed(true);
+  }
+
+  sync_enum_type myNBTransport(transaction_type& trans,
+                               phase_type& phase,
+                               sc_core::sc_time& t)
+  {
+    assert(phase == tlm::BEGIN_REQ);
+
+    // Never blocks, so call b_transport implementation
+    myBTransport(trans, t);
+    // LT target
+    // - always return TLM_COMPLETED
+    // - not necessary to update phase (if TLM_COMPLETED is returned)
+    return tlm::TLM_COMPLETED;
+  }
+
+  unsigned int transport_dbg(transaction_type& r)
+  {
+    if (r.get_address() >= 400) return 0;
+
+    unsigned int tmp = (int)r.get_address();
+    unsigned int num_bytes;
+    if (tmp + r.get_data_length() >= 400) {
+      num_bytes = 400 - tmp;
+
+    } else {
+      num_bytes = r.get_data_length();
+    }
+    if (r.is_read()) {
+      for (unsigned int i = 0; i < num_bytes; ++i) {
+        r.get_data_ptr()[i] = mMem[i + tmp];
+      }
+
+    } else {
+      for (unsigned int i = 0; i < num_bytes; ++i) {
+        mMem[i + tmp] = r.get_data_ptr()[i];
+      }
+    }
+    return num_bytes;
+  }
+
+  bool myGetDMIPtr(transaction_type& trans,
+                   tlm::tlm_dmi&  dmi_data)
+  {
+    sc_dt::uint64 address = trans.get_address();
+    if (address < 400) {
+      dmi_data.allow_read_write();
+      dmi_data.set_start_address(0x0);
+      dmi_data.set_end_address(399);
+      dmi_data.set_dmi_ptr(mMem);
+      dmi_data.set_read_latency(sc_core::sc_time(100, sc_core::SC_NS));
+      dmi_data.set_write_latency(sc_core::sc_time(10, sc_core::SC_NS));
+      return true;
+
+    } else {
+      // should not happen
+      dmi_data.set_start_address(address);
+      dmi_data.set_end_address(address);
+      return false;
+
+    }
+  }
+private:
+  unsigned char mMem[400];
+};
+
+#endif
diff --git a/src/systemc/tests/include/specialized_signals/scx_signal_int.h b/src/systemc/tests/include/specialized_signals/scx_signal_int.h
new file mode 100644 (file)
index 0000000..050521d
--- /dev/null
@@ -0,0 +1,1629 @@
+/*****************************************************************************
+
+  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.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  sc_signal_int.cpp -- The sc_signal<sc_dt::sc_int<W> > implementations.
+
+  Original Author: Andy Goodrich, Forte Design Systems, 2002-10-22
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+  changes you are making here.
+
+      Name, Affiliation, Date:
+  Description of Modification:
+
+ *****************************************************************************/
+
+/*
+$Log: scx_signal_int.h,v $
+Revision 1.1  2011/08/15 17:31:11  acg
+ Andy Goodrich: moved specialized signals from examples to this tree.
+
+Revision 1.2  2011/08/15 16:43:24  acg
+ Torsten Maehne: changes to remove unused argument warnings.
+
+Revision 1.1.1.1  2006/12/15 20:20:03  acg
+SystemC 2.3
+
+Revision 1.2  2005/12/26 20:11:14  acg
+Fixed up copyright.
+
+Revision 1.1.1.1  2005/12/19 23:16:42  acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.11  2005/04/11 19:05:36  acg
+Change to sc_clock for Microsoft VCC 6.0. Changes for namespaces
+
+Revision 1.10  2005/04/03 22:52:51  acg
+Namespace changes.
+
+Revision 1.9  2005/03/21 22:31:32  acg
+Changes to sc_core namespace.
+
+Revision 1.8  2004/09/27 21:01:59  acg
+Andy Goodrich - Forte Design Systems, Inc.
+   - This is specialized signal support that allows better use of signals
+     and ports whose target value is a SystemC native type.
+
+*/
+
+
+
+#include <systemc>
+#include <typeinfo>
+
+/*****************************************************************************
+
+  sc_signal_uint.h -- The sc_signal<sc_dt::sc_int<W> > definitions.
+
+  Original Author: Andy Goodrich, Forte Design Systems, 2002-10-22
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+  changes you are making here.
+
+      Name, Affiliation, Date:
+  Description of Modification:
+
+ *****************************************************************************/
+
+/*
+$Log: scx_signal_int.h,v $
+Revision 1.1  2011/08/15 17:31:11  acg
+ Andy Goodrich: moved specialized signals from examples to this tree.
+
+Revision 1.3  2011/08/15 16:43:24  acg
+ Torsten Maehne: changes to remove unused argument warnings.
+
+Revision 1.2  2011/06/28 21:23:02  acg
+ Andy Goodrich: merging of SCV tree.
+
+Revision 1.1.1.1  2006/12/15 20:20:03  acg
+SystemC 2.3
+
+Revision 1.2  2005/12/26 20:11:14  acg
+Fixed up copyright.
+
+Revision 1.1.1.1  2005/12/19 23:16:42  acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.21  2005/03/21 22:31:32  acg
+Changes to sc_core namespace.
+
+Revision 1.20  2005/01/10 17:51:58  acg
+Improvements.
+
+Revision 1.19  2004/11/09 00:11:26  acg
+Added support for sc_generic_base<T> in place of sc_concatref. sc_concatref
+now is derived from sc_generic_base<sc_concatref>.
+
+Revision 1.18  2004/09/27 21:01:59  acg
+Andy Goodrich - Forte Design Systems, Inc.
+   - This is specialized signal support that allows better use of signals
+     and ports whose target value is a SystemC native type.
+
+*/
+
+
+#if !defined(SC_SIGNAL_INT_H)
+#define SC_SIGNAL_INT_H
+
+#if ( !defined(_MSC_VER) || _MSC_VER > 1200 )
+#    define SC_TEMPLATE template<int W>
+#else
+#    define SC_TEMPLATE template<> template<int W>
+#endif
+
+
+// FORWARD REFERENCES AND USINGS:
+
+
+namespace sc_core {
+
+class sc_int_sigref;
+
+//==============================================================================
+// CLASS sc_int_part_if
+//
+// This class provides generic access to part selections for signals whose
+// data type is sc_dt::sc_int<W>. This class serves as the base class for the
+// sc_dt::sc_int<W> specialization of the sc_signal_in_if<T> class. The methods
+// in this class may be over-ridden individually, those that are not overridden
+// will produce an error message when called. The methods are used by the
+// sc_int_sigref class.
+//
+// Notes:
+//   (1) Descriptions of the methods and operators in this class appear with
+//       their implementations in sc_signal<sc_dt::sc_int<W> >.
+//==============================================================================
+class sc_int_part_if : virtual public sc_interface {
+  protected:
+       // constructor:
+       sc_int_part_if() {}
+
+  public:
+    // perform a part read.
+       virtual sc_dt::sc_int_base* part_read_target();
+       virtual sc_dt::uint64 read_part( int left, int right ) const;
+
+    // perform a part write.
+       virtual sc_int_sigref& select_part( int left, int right );
+       virtual void write_part( sc_dt::uint64 v, int left, int right );
+
+  private:
+       sc_int_part_if( const sc_int_part_if& );
+       sc_int_part_if& operator = ( const sc_int_part_if& );
+};
+
+
+//==============================================================================
+// CLASS sc_signal_in_if<sc_dt::sc_int<W> >
+//
+// This is the class specializations for the sc_signal_in_if<T> class to
+// provide additional features for sc_signal instances whose template is
+// sc_dt::sc_int<W>, including part access.
+//
+// Notes:
+//   (1) Descriptions of the methods and operators in this class appear with
+//       their implementations in sc_signal<sc_dt::sc_int<W> >.
+//==============================================================================
+template< int W >
+class sc_signal_in_if<sc_dt::sc_int<W> > : public sc_int_part_if {
+       friend class sc_int_sigref;
+  public:
+    typedef sc_signal_in_if<sc_dt::sc_int<W> > this_type;
+
+    // get the value changed event
+    virtual const sc_event& value_changed_event() const = 0;
+
+
+    // read the current value
+    virtual const sc_dt::sc_int<W>& read() const = 0;
+
+    // get a reference to the current value (for tracing)
+    virtual const sc_dt::sc_int<W>& get_data_ref() const = 0;
+
+
+    // was there a value changed event?
+    virtual bool event() const = 0;
+
+  protected:
+    // constructor
+    sc_signal_in_if()
+    {}
+
+  private: // disabled
+    sc_signal_in_if( const this_type& );
+    this_type& operator = ( const this_type& );
+};
+
+//=============================================================================
+//  CLASS : sc_int_sigref
+//
+//  Proxy class for sc_signal_int bit and part selection.
+//=============================================================================
+class sc_int_sigref : public sc_dt::sc_int_subref_r
+{
+  public:
+    sc_int_sigref() : sc_dt::sc_int_subref_r() {}
+    virtual ~sc_int_sigref() {}
+    virtual void concat_set(sc_dt::int64 src, int low_i);
+    virtual void concat_set(const sc_dt::sc_signed& src, int low_i);
+    virtual void concat_set(const sc_dt::sc_unsigned& src, int low_i);
+    virtual void concat_set(const sc_dt::sc_lv_base& src, int low_i);
+    virtual void concat_set(sc_dt::uint64 src, int low_i);
+
+  public:
+    inline void initialize( sc_int_part_if* if_p, int left_, int right_ );
+
+  public:
+    inline void operator = ( sc_dt::uint64 v );
+    inline void operator = ( const char* v );
+    inline void operator = ( unsigned long v );
+    inline void operator = ( long v );
+    inline void operator = ( unsigned int v );
+    inline void operator = ( int v );
+    inline void operator = ( sc_dt::int64 v );
+    inline void operator = ( double v );
+    inline void operator = ( const sc_int_sigref& v );
+    template<typename T>
+    inline void operator = ( const sc_dt::sc_generic_base<T>& v );
+    inline void operator = ( const sc_dt::sc_signed& v );
+    inline void operator = ( const sc_dt::sc_unsigned& v );
+    inline void operator = ( const sc_dt::sc_bv_base& v );
+    inline void operator = ( const sc_dt::sc_lv_base& v );
+
+  public:
+    static sc_vpool<sc_int_sigref> m_pool; // Pool of objects to use.
+
+  protected:
+    sc_int_part_if*                m_if_p; // Target for selection.
+
+  private:
+
+    // disabled
+    sc_int_sigref( const sc_int_sigref& a );
+};
+
+
+//==============================================================================
+// CLASS sc_signal<sc_dt::sc_int<W> >
+//
+// This class implements a signal whose value acts like an sc_dt::sc_int<W> data
+// value. This class is a specialization of the generic sc_signal class to
+// implement tailored support for the sc_dt::sc_int<W> class.
+//
+// Notes:
+//   (1) Descriptions of the methods and operators in this class appear with
+//       their implementations.
+//==============================================================================
+SC_TEMPLATE
+class sc_signal<sc_dt::sc_int<W> > :
+    public sc_signal_inout_if<sc_dt::sc_int<W> >,
+       public sc_prim_channel,
+    public sc_dt::sc_int<W>
+{
+  public: // typedefs
+    typedef sc_signal<sc_dt::sc_int<W> > this_type;
+
+  public: // constructors and destructor:
+    inline sc_signal();
+    explicit inline sc_signal(const char* name_);
+    virtual inline ~sc_signal();
+
+  public: // base methods:
+    inline bool base_event() const;
+    inline const sc_dt::sc_int<W>& base_read() const;
+    inline const sc_event& base_value_changed_event() const;
+    inline void base_write( sc_dt::int64 value );
+
+  public: // sc_prim_channel virtual methods:
+    virtual inline const char* kind() const;
+    virtual inline void update();
+
+  public: // sc_interface virtual methods:
+    virtual inline const sc_event& default_event() const;
+    virtual inline void register_port(
+               sc_port_base& port_, const char* if_typename_ );
+
+  public: // sc_int_part_if virtual methods:
+    virtual inline sc_dt::sc_int_base* part_read_target();
+    virtual inline sc_dt::uint64 read_part(int left, int right) const;
+       virtual inline sc_int_sigref& select_part(int left, int right);
+       virtual inline void write_part(sc_dt::uint64 v, int left, int right);
+
+  public: // interface virtual methods:
+    virtual inline bool event() const;
+    virtual inline const sc_dt::sc_int<W>& get_data_ref() const;
+    virtual inline sc_signal<sc_dt::sc_int<W> >& get_signal() ;
+    virtual inline const sc_dt::sc_int<W>& read() const;
+    virtual inline const sc_event& value_changed_event() const;
+    virtual inline void write( const sc_in<sc_dt::sc_int<W> >& value );
+    virtual inline void write( const sc_inout<sc_dt::sc_int<W> >& value );
+    virtual inline void write( const sc_dt::sc_int<W>& value );
+
+  public: // part selections:
+       inline sc_int_sigref& operator () ( int left, int right );
+       inline sc_int_sigref& operator [] ( int bit );
+
+  public: // operators:
+    inline void operator = ( const this_type& new_val );
+    inline void operator = ( const char* new_val );
+    inline void operator = ( sc_dt::uint64 new_val );
+    inline void operator = ( sc_dt::int64 new_val );
+    inline void operator = ( int new_val );
+    inline void operator = ( long new_val ) ;
+    inline void operator = ( short new_val ) ;
+    inline void operator = ( unsigned int new_val ) ;
+    inline void operator = ( unsigned long new_val );
+    inline void operator = ( unsigned short new_val );
+    template<typename T>
+    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val );
+    inline void operator = ( const sc_dt::sc_signed& new_val );
+    inline void operator = ( const sc_dt::sc_unsigned& new_val );
+    inline void operator = ( const sc_dt::sc_bv_base& new_val );
+    inline void operator = ( const sc_dt::sc_lv_base& new_val );
+
+    // concatenation methods (we inherit length and gets from sc_dt::sc_int<W>):
+
+    virtual inline void concat_set(sc_dt::int64 src, int low_i);
+    virtual inline void concat_set(const sc_dt::sc_lv_base& src, int low_i);
+    virtual inline void concat_set(const sc_dt::sc_signed& src, int low_i);
+    virtual inline void concat_set(const sc_dt::sc_unsigned& src, int low_i);
+    virtual inline void concat_set(sc_dt::uint64 src, int low_i);
+
+  protected: // debugging methods:
+    // #### void check_port();
+       void check_writer();
+
+  private: // Disabled operations that sc_dt::sc_int<W> supports:
+    sc_signal<sc_dt::sc_int<W> >& operator ++ ();          // prefix
+    const sc_signal<sc_dt::sc_int<W> >& operator ++ (int); // postfix
+    sc_signal<sc_dt::sc_int<W> >& operator -- ();          // prefix
+    const sc_signal<sc_dt::sc_int<W> >& operator -- (int); // postfix
+    sc_signal<sc_dt::sc_int<W> >& operator += (sc_dt::int_type);
+    sc_signal<sc_dt::sc_int<W> >& operator -= (sc_dt::int_type);
+    sc_signal<sc_dt::sc_int<W> >& operator *= (sc_dt::int_type);
+    sc_signal<sc_dt::sc_int<W> >& operator /= (sc_dt::int_type);
+    sc_signal<sc_dt::sc_int<W> >& operator %= (sc_dt::int_type);
+    sc_signal<sc_dt::sc_int<W> >& operator &= (sc_dt::int_type);
+    sc_signal<sc_dt::sc_int<W> >& operator |= (sc_dt::int_type);
+    sc_signal<sc_dt::sc_int<W> >& operator ^= (sc_dt::int_type);
+
+  protected:
+    mutable sc_event* m_changed_event_p; // Value changed event this object.
+    sc_dt::uint64            m_event_delta;     // Delta cycle of last event.
+    sc_dt::int64             m_new_val;         // New value for this object instance.
+    sc_port_base*     m_output_p;        // Single write port verify field.
+    sc_process_b*     m_writer_p;        // Single writer verify field.
+};
+
+
+SC_TEMPLATE // Return true if a changed event happened in the last delta cycle.
+inline bool sc_signal<sc_dt::sc_int<W> >::base_event() const
+{
+    return simcontext()->delta_count() == m_event_delta + 1;
+}
+
+
+SC_TEMPLATE // Return this object's sc_dt::sc_int<W> object instance.
+inline const sc_dt::sc_int<W>& sc_signal<sc_dt::sc_int<W> >::base_read() const
+{
+       return *this;
+}
+
+
+SC_TEMPLATE // Return the value changed event, allocating it if necessary.
+inline const sc_event& sc_signal<sc_dt::sc_int<W> >::base_value_changed_event() const
+{
+    if ( !m_changed_event_p ) m_changed_event_p = new sc_event;
+    return *m_changed_event_p;
+}
+
+
+SC_TEMPLATE // Select a portion of a value.
+inline sc_int_sigref& sc_signal<sc_dt::sc_int<W> >::select_part(int left, int right)
+{
+    sc_int_sigref* result_p = sc_int_sigref::m_pool.allocate();
+    result_p->initialize(this, left, right);
+    return *result_p;
+}
+
+
+SC_TEMPLATE // Write an sc_dt::uint64 value to this object instance.
+inline void sc_signal<sc_dt::sc_int<W> >::base_write( sc_dt::int64 value )
+{
+#   if defined(DEBUG_SYSTEMC)
+        check_writer();
+#   endif
+    m_new_val = value;
+    request_update();
+}
+
+//------------------------------------------------------------------------------
+//"sc_signal<sc_dt::sc_int<W> >::check_writer"
+//
+// This method checks to see if there is more than one writer for this
+// object instance by keeping track of the process performing the write.
+//------------------------------------------------------------------------------
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::check_writer()
+{
+    sc_process_b* writer_p = sc_get_curr_process_handle();
+    if( m_writer_p == 0 )
+    {
+        m_writer_p = writer_p;
+    }
+    else if( m_writer_p != writer_p )
+    {
+        sc_signal_invalid_writer( name(), kind(),
+                                  m_writer_p->name(), writer_p->name() );
+    }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_signal<sc_dt::sc_int<W> >::concat_set"
+//
+// These virtual methods allow value assignments to this object instance
+// from various sources. The position within the supplied source of the
+// low order bit for this object instance's value is low_i.
+//     src   = source value.
+//     low_i = bit within src to serve as low order bit of this object
+//             instance's value.
+//------------------------------------------------------------------------------
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::concat_set(sc_dt::int64 src, int low_i)
+{
+    if ( low_i < 64 )
+    {
+        base_write(src >> low_i);
+    }
+    else
+    {
+        base_write( src >> 63 );
+    }
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::concat_set(const sc_dt::sc_lv_base& src, int low_i)
+{
+    sc_dt::sc_unsigned tmp(src.length());
+    tmp = src >> low_i;
+    base_write( tmp.to_int64() );
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::concat_set(const sc_dt::sc_signed& src, int low_i)
+{
+    base_write( (src >> low_i).to_int64());
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::concat_set(const sc_dt::sc_unsigned& src, int low_i)
+{
+    base_write( (src >> low_i).to_int64());
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::concat_set(sc_dt::uint64 src, int low_i)
+{
+    base_write( ( low_i < 64 ) ? src >> low_i : 0 );
+}
+
+
+
+SC_TEMPLATE // Return the default event for this object instance.
+inline const sc_event& sc_signal<sc_dt::sc_int<W> >::default_event() const
+       { return base_value_changed_event(); }
+
+
+SC_TEMPLATE // Return true if a changed event happened in the last delta cycle.
+inline bool sc_signal<sc_dt::sc_int<W> >::event() const
+       { return base_event(); }
+
+
+SC_TEMPLATE // Return a reference to the value of this object instance.
+inline const sc_dt::sc_int<W>& sc_signal<sc_dt::sc_int<W> >::get_data_ref() const
+       { return *this; }
+
+
+SC_TEMPLATE // Return a pointer to this object instance.
+inline sc_signal<sc_dt::sc_int<W> >& sc_signal<sc_dt::sc_int<W> >::get_signal()
+       { return *this; }
+
+
+SC_TEMPLATE // Return a kind value of "sc_signal".
+inline const char* sc_signal<sc_dt::sc_int<W> >::kind() const
+{
+       return "sc_signal";
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_signal_uint::operator ()
+//
+// This operator returns a part selection of this object instance.
+//     left  = left-hand bit of the selection.
+//     right = right-hand bit of the selection.
+//------------------------------------------------------------------------------
+SC_TEMPLATE
+inline sc_int_sigref& sc_signal<sc_dt::sc_int<W> >::operator () (int left, int right)
+{
+    sc_int_sigref* result_p;   // Value to return.
+
+       result_p = sc_int_sigref::m_pool.allocate();
+       result_p->initialize(this, left, right);
+       return *result_p;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_signal_uint::operator []"
+//
+// This operator returns a bit selection of this object instance.
+//     i = bit to be selected.
+//------------------------------------------------------------------------------
+SC_TEMPLATE
+inline sc_int_sigref& sc_signal<sc_dt::sc_int<W> >::operator [] ( int bit )
+{
+    return operator () (bit,bit);
+}
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const this_type& new_val )
+       { base_write( (sc_dt::int64)new_val ); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const char* new_val )
+       { m_new_val = sc_dt::sc_int<64>(new_val); request_update(); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::operator = ( sc_dt::uint64 new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::operator = ( sc_dt::int64 new_val )
+       { base_write(new_val); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::operator = ( int new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::operator = ( long new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::operator = ( short new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::operator = ( unsigned int new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::operator = ( unsigned long new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::operator = ( unsigned short new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+
+SC_TEMPLATE
+template<typename T>
+inline void sc_signal<sc_dt::sc_int<W> >::operator = (
+       const sc_dt::sc_generic_base<T>& new_val )
+       { base_write(new_val->to_int64()); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const sc_dt::sc_signed& new_val )
+       { base_write(new_val.to_int64()); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const sc_dt::sc_unsigned& new_val )
+       { base_write(new_val.to_int64()); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const sc_dt::sc_bv_base& new_val )
+       { base_write( (sc_dt::sc_int<W>)new_val ); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const sc_dt::sc_lv_base& new_val )
+       { base_write( (sc_dt::sc_int<W>)new_val ); }
+
+
+SC_TEMPLATE
+inline sc_dt::sc_int_base* sc_signal<sc_dt::sc_int<W> >::part_read_target()
+       { return this; }
+
+
+SC_TEMPLATE
+inline const sc_dt::sc_int<W>& sc_signal<sc_dt::sc_int<W> >::read() const
+       { return *this; }
+
+
+SC_TEMPLATE // Read a portion of a value.
+inline sc_dt::uint64 sc_signal<sc_dt::sc_int<W> >::read_part( int left, int right ) const
+{
+       // This pointer required for HP aCC.
+    return (this->m_val & ~sc_dt::mask_int[left][right]) >> right;
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_int<W> >::register_port(
+       sc_port_base& port_, const char* if_typename_ )
+{
+#       ifdef DEBUG_SYSTEMC
+               std::string nm( if_typename_ );
+               if( nm == typeid( sc_signal_inout_if<sc_dt::sc_int<W> > ).name() )
+               {
+                       if( m_output_p != 0 )
+                       {
+                               sc_signal_invalid_writer( name(), kind(),
+                                        m_output_p->name(), port_.name() );
+                       }
+                       m_output_p = &port_;
+               }
+#       else
+            if ( &port_ && if_typename_ ) {} // Silence unused args warning.
+#       endif
+}
+
+
+SC_TEMPLATE // Autogenerated name object instance constructor.
+inline sc_signal<sc_dt::sc_int<W> >::sc_signal() :
+       sc_prim_channel(sc_gen_unique_name( "signal" )),
+       m_changed_event_p(0),
+       m_output_p(0),
+       m_writer_p(0)
+{ }
+
+
+SC_TEMPLATE // Explicitly named object instance constructor.
+inline sc_signal<sc_dt::sc_int<W> >::sc_signal(const char* name_) :
+       sc_prim_channel(name_),
+       m_changed_event_p(0),
+       m_output_p(0),
+       m_writer_p(0)
+{ }
+
+
+SC_TEMPLATE // Object instance destructor.
+inline sc_signal<sc_dt::sc_int<W> >::~sc_signal()
+{
+       if ( m_changed_event_p ) delete m_changed_event_p;
+}
+
+
+SC_TEMPLATE // Update the current value from new value.
+inline void sc_signal<sc_dt::sc_int<W> >::update()
+{
+    if ( m_changed_event_p )
+    {
+               // This pointer required for HP aCC.
+        sc_dt::int64 old_val = this->m_val;
+        sc_dt::sc_int_base::operator = (m_new_val);
+        if ( old_val != this->m_val )
+        {
+            m_changed_event_p->notify_delayed();
+            m_event_delta = simcontext()->delta_count();
+        }
+    }
+    else
+    {
+        sc_dt::sc_int_base::operator = (m_new_val);
+    }
+}
+
+
+SC_TEMPLATE // Return the value changed event.
+inline const sc_event& sc_signal<sc_dt::sc_int<W> >::value_changed_event() const
+       { return base_value_changed_event(); }
+
+
+SC_TEMPLATE // Write a sc_in<sc_dt::sc_int<W> > value to this object instance.
+inline void sc_signal<sc_dt::sc_int<W> >::write( const sc_in<sc_dt::sc_int<W> >& value )
+       { base_write( value.operator sc_dt::int64 () ); }
+
+
+SC_TEMPLATE // Write a sc_inout<sc_dt::sc_int<W> > value to this object instance.
+inline void sc_signal<sc_dt::sc_int<W> >::write( const sc_inout<sc_dt::sc_int<W> >& value )
+       { base_write( value.operator sc_dt::int64 () ); }
+
+
+SC_TEMPLATE // Write a sc_dt::sc_int<W> value to this object instance.
+inline void sc_signal<sc_dt::sc_int<W> >::write( const sc_dt::sc_int<W>& value )
+       { base_write( value); }
+
+
+SC_TEMPLATE // Write a portion of a value. If this is the first write in
+            // a delta cycle we copy the existing value before setting the bits.
+inline void sc_signal<sc_dt::sc_int<W> >::write_part( sc_dt::uint64 v, int left, int right )
+{
+    sc_dt::int64  new_v;   // New value.
+    sc_dt::uint64 keep;    // Keep mask value.
+
+    keep = sc_dt::mask_int[left][right];
+    new_v = (m_new_val & keep) | ((v << right) & ~keep);
+       if ( m_new_val != new_v ) request_update();
+    m_new_val = new_v;
+}
+
+
+//==============================================================================
+// CLASS sc_in<sc_dt::sc_int<W> >
+//
+// This class implements an input port whose target acts like an sc_dt::sc_int<W> data
+// value. This class is a specialization of the generic sc_in class to
+// implement tailored support for the sc_dt::sc_int<W> class.
+//==============================================================================
+SC_TEMPLATE
+class sc_in<sc_dt::sc_int<W> > :
+    public sc_port<sc_signal_in_if<sc_dt::sc_int<W> >, 1>,
+    public sc_dt::sc_value_base
+{
+  public:
+
+    // typedefs
+
+    typedef sc_dt::sc_int<W>                      data_type;
+    typedef sc_signal_in_if<sc_dt::sc_int<W> >    if_type;
+    typedef sc_port<if_type,1>                    base_type;
+    typedef sc_in<sc_dt::sc_int<W> >              this_type;
+
+    typedef if_type                               in_if_type;
+    typedef base_type                             in_port_type;
+    typedef sc_signal_inout_if<sc_dt::sc_int<W> > inout_if_type;
+    typedef sc_inout<sc_dt::sc_int<W> >           inout_port_type;
+
+  public:
+
+    // bind methods and operators:
+
+    void bind( const in_if_type& interface_ )
+        { sc_port_base::bind( const_cast<in_if_type&>( interface_) );}
+    void operator () ( const in_if_type& interface_ )
+        { sc_port_base::bind( const_cast<in_if_type&>( interface_) );}
+    void bind( in_port_type& parent_ )
+        { sc_port_base::bind(parent_);}
+    void operator () ( in_port_type& parent_ )
+        { sc_port_base::bind(parent_);}
+    void bind( inout_port_type& parent_ )
+        { sc_port_base::bind(parent_);}
+    void operator () ( inout_port_type& parent_ )
+        { sc_port_base::bind(parent_);}
+
+  protected:
+    // called by pbind (for internal use only)
+    virtual inline int vbind( sc_interface& interface_ )
+        {
+            return sc_port_b<if_type>::vbind( interface_ );
+        }
+    virtual inline int vbind( sc_port_base& parent_ )
+        {
+            in_port_type* in_parent = dynamic_cast<in_port_type*>( &parent_ );
+            if( in_parent != 0 ) {
+                sc_port_base::bind( *in_parent );
+                return 0;
+            }
+            inout_port_type* inout_parent = dynamic_cast<inout_port_type*>( &parent_ );
+            if( inout_parent != 0 ) {
+                sc_port_base::bind( *inout_parent );
+                return 0;
+            }
+            // type mismatch
+            return 2;
+        }
+
+
+    // constructors
+
+  public:
+    sc_in()
+        : base_type(), m_traces( 0 )
+        {}
+
+    explicit sc_in( const char* name_ )
+        : base_type( name_ ), m_traces( 0 )
+        {}
+
+    explicit sc_in( const in_if_type& interface_ )
+        : base_type( const_cast<in_if_type&>( interface_ ) ), m_traces( 0 )
+        {}
+
+    sc_in( const char* name_, const in_if_type& interface_ )
+        : base_type( name_, const_cast<in_if_type&>( interface_ ) ), m_traces( 0 )
+        {}
+
+    explicit sc_in( in_port_type& parent_ )
+        : base_type( parent_ ), m_traces( 0 )
+        {}
+
+    sc_in( const char* name_, in_port_type& parent_ )
+        : base_type( name_, parent_ ), m_traces( 0 )
+        {}
+
+    explicit sc_in( inout_port_type& parent_ )
+        : base_type(), m_traces( 0 )
+        { sc_port_base::bind( parent_ ); }
+
+    sc_in( const char* name_, inout_port_type& parent_ )
+        : base_type( name_ ), m_traces( 0 )
+        { sc_port_base::bind( parent_ ); }
+
+    sc_in( this_type& parent_ )
+        : base_type( parent_ ), m_traces( 0 )
+        {}
+
+    sc_in( const char* name_, this_type& parent_ )
+        : base_type( name_, parent_ ), m_traces( 0 )
+        {}
+
+
+    // destructor
+
+    virtual inline ~sc_in()
+        {
+            remove_traces();
+        }
+
+    // bit and part selection
+
+    sc_dt::sc_int_bitref_r operator [] ( int i ) const
+        { return (*this)->read()[i]; }
+    sc_dt::sc_int_bitref_r bit( int i ) const
+        { return (*this)->read()[i]; }
+    sc_dt::sc_int_subref_r operator () ( int left, int right ) const
+        { return (*this)->read()(left,right); }
+    sc_dt::sc_int_subref_r range( int left, int right ) const
+        { return (*this)->read()(left,right); }
+
+
+    // interface access shortcut methods
+
+    // get the default event
+
+    const sc_event& default_event() const
+        { return (*this)->value_changed_event(); }
+
+
+    // get the value changed event
+
+    const sc_event& value_changed_event() const
+        { return (*this)->value_changed_event(); }
+
+
+    // read the current value
+
+    const sc_dt::sc_int<W>& read() const
+        { return (*this)->read(); }
+
+       operator sc_dt::int64 () const
+               { return (sc_dt::int64)(*this)->read(); }
+
+    // was there a value changed event?
+
+    bool event() const
+        { return (*this)->event(); }
+
+
+    // (other) event finder method(s)
+
+    sc_event_finder& value_changed() const
+        {
+            return *new sc_event_finder_t<in_if_type>(
+                *this, &in_if_type::value_changed_event );
+        }
+
+
+
+    // reduction methods:
+
+    inline bool and_reduce() const
+        { return (*this)->read().and_reduce(); }
+    inline bool nand_reduce() const
+        { return (*this)->read().nand_reduce(); }
+    inline bool nor_reduce() const
+        { return (*this)->read().nor_reduce(); }
+    inline bool or_reduce() const
+        { return (*this)->read().or_reduce(); }
+    inline bool xnor_reduce() const
+        { return (*this)->read().xnor_reduce(); }
+    inline bool xor_reduce() const
+        { return (*this)->read().xor_reduce(); }
+
+
+    // called when elaboration is done
+    /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+    /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+    virtual inline void end_of_elaboration()
+        {
+            if( m_traces != 0 ) {
+                for( unsigned int i = 0; i < m_traces->size(); ++ i ) {
+                    sc_trace_params* p = (*m_traces)[i];
+                    sc_trace( p->tf, read(), p->name );
+                }
+                remove_traces();
+            }
+        }
+
+    virtual inline const char* kind() const
+        { return "sc_in"; }
+
+
+    // called by sc_trace
+    void add_trace( sc_trace_file* tf_, const std::string& name_ ) const
+        {
+            if( tf_ != 0 ) {
+                if( m_traces == 0 ) {
+                    m_traces = new sc_trace_params_vec;
+                }
+                m_traces->push_back( new sc_trace_params( tf_, name_ ) );
+            }
+        }
+
+
+    // concatenation methods
+
+    virtual inline int concat_length(bool* xz_present_p) const
+        { return (*this)->read().concat_length( xz_present_p ); }
+    virtual inline sc_dt::uint64 concat_get_uint64() const
+        { return (*this)->read().concat_get_uint64(); }
+    virtual
+       inline bool concat_get_ctrl( sc_dt::sc_digit* dst_p, int low_i ) const
+        { return (*this)->read().concat_get_ctrl(dst_p, low_i); }
+    virtual
+       inline bool concat_get_data( sc_dt::sc_digit* dst_p, int low_i ) const
+        { return (*this)->read().concat_get_data(dst_p, low_i); }
+
+  protected:
+    void remove_traces() const
+        {
+            if( m_traces != 0 ) {
+                for( int i = m_traces->size() - 1; i >= 0; -- i ) {
+                    delete (*m_traces)[i];
+                }
+                delete m_traces;
+                m_traces = 0;
+            }
+        }
+
+    mutable sc_trace_params_vec* m_traces;
+
+
+  private:
+
+    // disabled
+    sc_in( const sc_in<sc_dt::sc_int<W> >& );
+    sc_in<sc_dt::sc_int<W> >& operator = ( const sc_in<sc_dt::sc_int<W> >& );
+
+#ifdef __GNUC__
+    // Needed to circumvent a problem in the g++-2.95.2 compiler:
+    // This unused variable forces the compiler to instantiate
+    // an object of T template so an implicit conversion from
+    // read() to a C++ intrinsic data type will work.
+    static data_type dummy;
+#endif
+
+};
+
+
+
+SC_TEMPLATE
+inline std::ostream& operator << (std::ostream& os, const sc_in<sc_dt::sc_int<W> >& a)
+{
+    a.read().print( os );
+    return os;
+}
+
+
+//==============================================================================
+// CLASS sc_inout<sc_dt::sc_int<W> >
+//
+// This class implements an input/output port whose target acts like an
+// sc_dt::sc_int<W> data value. It is derived from the sc_int_in. This class is a
+// specialization of the generic sc_inout class to implement tailored support
+// for the sc_dt::sc_int<W> class.
+//==============================================================================
+SC_TEMPLATE
+class sc_inout<sc_dt::sc_int<W> > :
+    public sc_port<sc_signal_inout_if<sc_dt::sc_int<W> >, 1>,
+    public sc_dt::sc_value_base
+{
+  public:
+
+    // typedefs
+
+    typedef sc_dt::sc_int<W>                    data_type;
+    typedef sc_signal_inout_if<sc_dt::sc_int<W> > if_type;
+    typedef sc_port<if_type,1>              base_type;
+    typedef sc_inout<sc_dt::sc_int<W> >           this_type;
+
+    typedef if_type                         inout_if_type;
+    typedef base_type                       inout_port_type;
+
+  public:
+
+    // bind methods and operators:
+
+    void bind( const inout_if_type& interface_ )
+        { sc_port_base::bind( const_cast<inout_if_type&>( interface_) ); }
+    void operator () ( const inout_if_type& interface_ )
+        { sc_port_base::bind( const_cast<inout_if_type&>( interface_) ); }
+    void bind( inout_port_type& parent_ )
+        { sc_port_base::bind(parent_); }
+    void operator () ( inout_port_type& parent_ )
+        { sc_port_base::bind(parent_); }
+
+  protected:
+    // called by pbind (for internal use only)
+    virtual inline int vbind( sc_interface& interface_ )
+        {
+            return sc_port_b<if_type>::vbind( interface_ );
+        }
+    virtual inline int vbind( sc_port_base& parent_ )
+        {
+            inout_port_type* inout_parent = dynamic_cast<inout_port_type*>( &parent_ );
+            if( inout_parent != 0 ) {
+                sc_port_base::bind( *inout_parent );
+                return 0;
+            }
+            // type mismatch
+            return 2;
+        }
+
+
+    // constructors
+
+  public:
+    sc_inout()
+        : base_type(), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    explicit sc_inout( const char* name_ )
+        : base_type( name_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    explicit sc_inout( inout_if_type& interface_ )
+        : base_type( interface_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    sc_inout( const char* name_, inout_if_type& interface_ )
+        : base_type( name_, interface_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    explicit sc_inout( inout_port_type& parent_ )
+        : base_type( parent_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    sc_inout( const char* name_, inout_port_type& parent_ )
+        : base_type( name_, parent_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    sc_inout( this_type& parent_ )
+        : base_type( parent_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    sc_inout( const char* name_, this_type& parent_ )
+        : base_type( name_, parent_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+
+    // destructor
+
+    virtual inline ~sc_inout()
+        {
+            remove_traces();
+        }
+
+    // bit and part selection
+
+    sc_dt::sc_int_bitref_r operator [] ( int i ) const
+        { return (*this)->read()[i]; }
+    sc_dt::sc_int_bitref_r bit( int i ) const
+        { return (*this)->read()[i]; }
+    sc_int_sigref& operator [] ( int i )
+               { return (*this)->select_part(i,i); }
+    sc_int_sigref& bit( int i )
+               { return (*this)->select_part(i,i); }
+    sc_dt::sc_int_subref_r operator () ( int left, int right ) const
+        { return (*this)->read()(left,right); }
+    sc_dt::sc_int_subref_r range( int left, int right ) const
+        { return (*this)->read()(left,right); }
+    sc_int_sigref& operator () ( int left, int right )
+               { return (*this)->select_part(left,right); }
+    sc_int_sigref& range( int left, int right )
+               { return (*this)->select_part(left,right); }
+
+
+    // interface access shortcut methods
+
+    // get the default event
+
+    const sc_event& default_event() const
+        { return (*this)->value_changed_event(); }
+
+
+    // get the value changed event
+
+    const sc_event& value_changed_event() const
+        { return (*this)->value_changed_event(); }
+
+
+    // read the current value
+
+    const sc_dt::sc_int<W>& read() const
+        { return (*this)->read(); }
+
+       operator sc_dt::int64 () const
+               { return (sc_dt::int64)(*this)->read(); }
+
+    // was there a value changed event?
+
+    bool event() const
+        { return (*this)->event(); }
+
+
+    // (other) event finder method(s)
+
+    sc_event_finder& value_changed() const
+        {
+            return *new sc_event_finder_t<inout_if_type>(
+                *this, &inout_if_type::value_changed_event );
+        }
+
+
+
+    // reduction methods:
+
+    inline bool and_reduce() const
+        { return (*this)->read().and_reduce(); }
+    inline bool nand_reduce() const
+        { return (*this)->read().nand_reduce(); }
+    inline bool nor_reduce() const
+        { return (*this)->read().nor_reduce(); }
+    inline bool or_reduce() const
+        { return (*this)->read().or_reduce(); }
+    inline bool xnor_reduce() const
+        { return (*this)->read().xnor_reduce(); }
+    inline bool xor_reduce() const
+        { return (*this)->read().xor_reduce(); }
+
+
+    // called when elaboration is done
+    /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+    /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+    virtual inline void end_of_elaboration()
+        {
+            if( m_init_val_p != 0 ) {
+                (*this)->write( (sc_dt::int64) *m_init_val_p );
+                delete m_init_val_p;
+                m_init_val_p = 0;
+            }
+            if( m_traces != 0 ) {
+                for( unsigned int i = 0; i < m_traces->size(); ++ i ) {
+                    sc_trace_params* p = (*m_traces)[i];
+                    sc_trace( p->tf, read(), p->name );
+                }
+                remove_traces();
+            }
+        }
+
+    virtual inline const char* kind() const
+        { return "sc_inout"; }
+
+    // value initialization
+
+    inline void initialize( const sc_dt::sc_int<W>& value_ )
+    {
+        inout_if_type* iface = this->get_interface(0);
+        if( iface != 0 ) {
+            iface->write( value_ );
+        } else {
+            if( m_init_val_p == 0 ) {
+                m_init_val_p = new sc_dt::int64;
+            }
+            *m_init_val_p = value_;
+        }
+    }
+
+
+    // called by sc_trace
+    void add_trace( sc_trace_file* tf_, const std::string& name_ ) const
+        {
+            if( tf_ != 0 ) {
+                if( m_traces == 0 ) {
+                    m_traces = new sc_trace_params_vec;
+                }
+                m_traces->push_back( new sc_trace_params( tf_, name_ ) );
+            }
+        }
+
+
+    // concatenation methods
+
+    virtual inline int concat_length(bool* xz_present_p) const
+        { return (*this)->read().concat_length( xz_present_p ); }
+    virtual inline sc_dt::uint64 concat_get_uint64() const
+        { return (*this)->read().concat_get_uint64(); }
+    virtual
+       inline bool concat_get_ctrl( sc_dt::sc_digit* dst_p, int low_i ) const
+        { return (*this)->read().concat_get_ctrl(dst_p, low_i); }
+    virtual
+       inline bool concat_get_data( sc_dt::sc_digit* dst_p, int low_i ) const
+        { return (*this)->read().concat_get_data(dst_p, low_i); }
+    virtual inline void concat_set(sc_dt::int64 src, int low_i)
+        { *this = src >> (( low_i < 64 ) ? low_i : 63); }
+#if 0 // ####
+    virtual inline void concat_set(const sc_dt::sc_lv_base& src, int low_i)
+        { *this = src >> low_i; }
+#endif // 0 ####
+    virtual inline void concat_set(const sc_dt::sc_signed& src, int low_i)
+        { *this = src >> low_i; }
+    virtual inline void concat_set(const sc_dt::sc_unsigned& src, int low_i)
+        { *this = src >> low_i; }
+    virtual inline void concat_set(sc_dt::uint64 src, int low_i)
+        { *this = ( low_i < 64 ) ? src >> low_i : (sc_dt::uint64)0; }
+
+    // assignment operators:
+
+  public:
+       inline void operator = ( const this_type& new_val )
+               { (*this)->write( (sc_dt::int64)new_val ); }
+    inline void operator = ( const char* new_val )
+        { (*this)->write( this_type(new_val) ); }
+    inline void operator = ( sc_dt::uint64 new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( sc_dt::int64 new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( int new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( long new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( short new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned int new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned long new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned short new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    template<typename T>
+    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val )
+        { (*this)->write(new_val->to_uint64()); }
+    inline void operator = ( const sc_dt::sc_signed& new_val )
+        { (*this)->write(new_val.to_uint64()); }
+    inline void operator = ( const sc_dt::sc_unsigned& new_val )
+        { (*this)->write(new_val.to_uint64()); }
+    inline void operator = ( const sc_dt::sc_bv_base& new_val )
+        { (*this)->write((sc_dt::sc_int<W>)new_val); }
+    inline void operator = ( const sc_dt::sc_lv_base& new_val )
+        { (*this)->write((sc_dt::sc_int<W>)new_val); }
+
+    inline void write( const sc_in<sc_dt::sc_int<W> >& new_val )
+        { (*this)->write( (sc_dt::int64)new_val ); }
+
+    inline void write( const sc_inout<sc_dt::sc_int<W> >& new_val )
+        { (*this)->write( (sc_dt::int64)new_val); }
+
+    inline void write( const sc_dt::sc_int<W>& new_val )
+        { (*this)->write( (sc_dt::int64)new_val); }
+
+  protected:
+    void remove_traces() const
+        {
+            if( m_traces != 0 ) {
+                for( int i = m_traces->size() - 1; i >= 0; -- i ) {
+                    delete (*m_traces)[i];
+                }
+                delete m_traces;
+                m_traces = 0;
+            }
+        }
+
+    sc_dt::int64*                      m_init_val_p;
+    mutable sc_trace_params_vec* m_traces;
+
+
+  private:
+
+    // disabled
+    sc_inout( const sc_inout<sc_dt::sc_int<W> >& );
+
+#ifdef __GNUC__
+    // Needed to circumvent a problem in the g++-2.95.2 compiler:
+    // This unused variable forces the compiler to instantiate
+    // an object of T template so an implicit conversion from
+    // read() to a C++ intrinsic data type will work.
+    static data_type dummy;
+#endif
+
+};
+
+
+
+SC_TEMPLATE
+inline std::ostream& operator << (
+       std::ostream& os, const sc_inout<sc_dt::sc_int<W> >& a )
+{
+    a.read().print( os );
+    return os;
+}
+
+
+//==============================================================================
+// CLASS sc_out<sc_dt::sc_int<W> >
+//
+// This class implements an output port whose target acts like an
+// sc_dt::sc_int<W> data value. This class is a derivation of sc_inout, since
+// output ports are really no different from input/output ports.
+//==============================================================================
+SC_TEMPLATE
+class sc_out<sc_dt::sc_int<W> > : public sc_inout<sc_dt::sc_int<W> >
+{
+  public:
+
+    // typedefs
+
+    typedef sc_dt::sc_int<W>                          data_type;
+
+    typedef sc_out<data_type>                   this_type;
+    typedef sc_inout<data_type>                 base_type;
+
+    typedef typename base_type::inout_if_type   inout_if_type;
+    typedef typename base_type::inout_port_type inout_port_type;
+
+    // constructors
+
+    sc_out()
+        : base_type()
+        {}
+
+    explicit sc_out( const char* name_ )
+        : base_type( name_ )
+        {}
+
+    explicit sc_out( inout_if_type& interface_ )
+        : base_type( interface_ )
+        {}
+
+    sc_out( const char* name_, inout_if_type& interface_ )
+        : base_type( name_, interface_ )
+        {}
+
+    explicit sc_out( inout_port_type& parent_ )
+        : base_type( parent_ )
+        {}
+
+    sc_out( const char* name_, inout_port_type& parent_ )
+        : base_type( name_, parent_ )
+        {}
+
+    sc_out( this_type& parent_ )
+        : base_type( parent_ )
+        {}
+
+    sc_out( const char* name_, this_type& parent_ )
+        : base_type( name_, parent_ )
+        {}
+
+
+    // destructor (does nothing)
+
+    virtual inline ~sc_out()
+        {}
+
+
+    // assignment operators:
+
+  public:
+       inline void operator = ( const this_type& new_val )
+               { (*this)->write( (sc_dt::int64)new_val ); }
+    inline void operator = ( const char* new_val )
+               { (*this)->write( this_type(new_val) ); }
+    inline void operator = ( sc_dt::uint64 new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( sc_dt::int64 new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( int new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( long new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( short new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned int new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned long new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned short new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    template<typename T>
+    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val )
+        { (*this)->write(new_val->to_uint64()); }
+    inline void operator = ( const sc_dt::sc_signed& new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( const sc_dt::sc_unsigned& new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( const sc_dt::sc_bv_base& new_val )
+        { (*this)->write((sc_dt::sc_int<W>)new_val); }
+    inline void operator = ( const sc_dt::sc_lv_base& new_val )
+        { (*this)->write((sc_dt::sc_int<W>)new_val); }
+
+  private:
+
+    // disabled
+    sc_out( const this_type& );
+};
+
+
+
+//------------------------------------------------------------------------------
+//"sc_int_sigref::initialize"
+//
+// This method initializes an object instance from the supplied arguments.
+//     if_p  -> access to target of this selection.
+//     left  =  left-most bit in selection.
+//     right =  right-most bit in selection.
+//------------------------------------------------------------------------------
+inline
+void sc_int_sigref::initialize(sc_int_part_if* if_p, int left, int right)
+{
+    m_if_p = if_p;
+    m_left = left;
+    m_right = right;
+       m_obj_p = if_p->part_read_target();
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_int_sigref::operator ="
+//
+// These operators assign a value to the bits associated with this object
+// instance within this object instance's target signal.
+//------------------------------------------------------------------------------
+inline void sc_int_sigref::operator = ( sc_dt::uint64 v )
+{
+       m_if_p->write_part( v, m_left, m_right );
+}
+
+inline void sc_int_sigref::operator = ( const char* /*v*/ )
+{
+}
+
+inline void sc_int_sigref:: operator = ( sc_dt::int64 v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+inline void sc_int_sigref:: operator = ( int v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+inline void sc_int_sigref:: operator = ( long v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+inline void sc_int_sigref:: operator = ( unsigned int v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+inline void sc_int_sigref:: operator = ( unsigned long v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+void sc_int_sigref::operator = ( const sc_int_sigref& v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+template<typename T>
+inline void sc_int_sigref:: operator = ( const sc_dt::sc_generic_base<T>& v )
+{
+    *this = v->to_uint64();
+}
+
+inline void sc_int_sigref:: operator = ( const sc_dt::sc_signed& v )
+{
+    *this = v.to_uint64();
+}
+
+inline void sc_int_sigref:: operator = ( const sc_dt::sc_unsigned& v )
+{
+    *this = v.to_uint64();
+}
+
+#undef SC_TEMPLATE
+#undef TTEST
+} // namespace sc_core
+#endif // !defined(SC_SIGNAL_INT_H)
+
+namespace sc_core {
+
+extern
+void
+sc_signal_invalid_writer( const char* name,
+                          const char* kind,
+                          const char* first_writer,
+                          const char* second_writer );
+
+//------------------------------------------------------------------------------
+// POOL OF TEMPORARY INSTANCES OF sc_int_sigref
+//
+// This allows use to pass const references for part and bit selections
+// on sc_signal_int object instances.
+//------------------------------------------------------------------------------
+sc_vpool<sc_int_sigref> sc_int_sigref::m_pool(8);
+
+
+//------------------------------------------------------------------------------
+//"sc_int_part_if::default methods"
+//
+// These versions just produce errors if they are not overloaded but used.
+//------------------------------------------------------------------------------
+
+sc_dt::sc_int_base* sc_int_part_if::part_read_target()
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+    return 0;
+}
+sc_dt::uint64 sc_int_part_if::read_part( int /*left*/, int /*right*/ ) const
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+    return 0;
+}
+sc_int_sigref& sc_int_part_if::select_part( int /*left*/, int /*right*/ )
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+    return *(sc_int_sigref*)0;
+}
+void sc_int_part_if::write_part( sc_dt::uint64 v, int /*left*/, int /*right*/ )
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_int_sigref::concate_set"
+//
+// These methods assign this object instance's value from the supplied
+// value starting at the supplied bit within that value.
+//     src = value to use to set this object instance's value.
+//     low_i = bit in src that is to be the low order bit of the value to set.
+// #### OPTIMIZE
+//------------------------------------------------------------------------------
+void sc_int_sigref::concat_set(sc_dt::int64 src, int low_i)
+{
+    *this = (low_i < 64) ? src >> low_i : src >> 63;
+}
+
+
+void sc_int_sigref::concat_set(const sc_dt::sc_signed& src, int low_i)
+{
+    if ( low_i < src.length() )
+        *this = src >> low_i;
+    else
+        *this = (src < 0) ? (sc_dt::uint64)-1 : 0;
+}
+
+
+void sc_int_sigref::concat_set(const sc_dt::sc_lv_base& src, int low_i)
+{
+    if ( low_i < src.length() )
+        *this = (src >> low_i).to_uint64();
+    else
+        *this = 0;
+}
+
+
+void sc_int_sigref::concat_set(const sc_dt::sc_unsigned& src, int low_i)
+{
+    if ( low_i < src.length() )
+        *this = src >> low_i;
+    else
+        *this = 0;
+}
+
+
+void sc_int_sigref::concat_set(sc_dt::uint64 src, int low_i)
+{
+    *this = (low_i < 64) ? src >> low_i : 0;
+}
+
+} // namespace sc_core
diff --git a/src/systemc/tests/include/specialized_signals/scx_signal_signed.h b/src/systemc/tests/include/specialized_signals/scx_signal_signed.h
new file mode 100644 (file)
index 0000000..bb48cec
--- /dev/null
@@ -0,0 +1,1833 @@
+/*****************************************************************************
+
+  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.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  sc_signal_signed.cpp -- The sc_signal<sc_bigint<W> > implementations.
+
+  Original Author: Andy Goodrich, Forte Design Systems, 2002-10-22
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+  changes you are making here.
+
+      Name, Affiliation, Date:
+  Description of Modification:
+
+ *****************************************************************************/
+
+/*
+$Log: scx_signal_signed.h,v $
+Revision 1.1  2011/08/15 17:31:11  acg
+ Andy Goodrich: moved specialized signals from examples to this tree.
+
+Revision 1.2  2011/08/15 16:43:24  acg
+ Torsten Maehne: changes to remove unused argument warnings.
+
+Revision 1.1.1.1  2006/12/15 20:20:03  acg
+SystemC 2.3
+
+Revision 1.2  2005/12/26 20:11:14  acg
+Fixed up copyright.
+
+Revision 1.1.1.1  2005/12/19 23:16:42  acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.17  2005/09/15 23:01:52  acg
+Added std:: prefix to appropriate methods and types to get around
+issues with the Edison Front End.
+
+Revision 1.16  2005/05/03 19:52:26  acg
+Get proper header locations on includes.
+
+Revision 1.15  2005/05/03 19:50:20  acg
+Name space version.
+
+Revision 1.12  2005/04/11 19:05:36  acg
+Change to sc_clock for Microsoft VCC 6.0. Changes for namespaces
+
+Revision 1.11  2005/04/03 22:52:52  acg
+Namespace changes.
+
+Revision 1.10  2005/03/21 22:31:32  acg
+Changes to sc_core namespace.
+
+Revision 1.9  2004/09/27 21:01:59  acg
+Andy Goodrich - Forte Design Systems, Inc.
+   - This is specialized signal support that allows better use of signals
+     and ports whose target value is a SystemC native type.
+
+*/
+
+
+
+#include <systemc>
+
+using sc_dt::sc_bigint;
+using sc_dt::sc_bv_base;
+using sc_dt::sc_lv_base;
+using sc_dt::sc_concatref;
+using sc_dt::sc_signed;
+using sc_dt::sc_signed_subref_r;
+using sc_dt::sc_unsigned;
+using sc_dt::uint64;
+
+#include <typeinfo>
+
+/*****************************************************************************
+
+  sc_signal_signed.h -- The sc_signal<sc_dt::sc_bigint<W> > definitions.
+
+  Original Author: Andy Goodrich, Forte Design Systems, 2002-10-22
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+  changes you are making here.
+
+      Name, Affiliation, Date:
+  Description of Modification:
+
+ *****************************************************************************/
+
+/*
+$Log: scx_signal_signed.h,v $
+Revision 1.1  2011/08/15 17:31:11  acg
+ Andy Goodrich: moved specialized signals from examples to this tree.
+
+Revision 1.3  2011/08/15 16:43:24  acg
+ Torsten Maehne: changes to remove unused argument warnings.
+
+Revision 1.2  2011/06/28 21:23:02  acg
+ Andy Goodrich: merging of SCV tree.
+
+Revision 1.1.1.1  2006/12/15 20:20:03  acg
+SystemC 2.3
+
+Revision 1.4  2006/10/23 19:40:35  acg
+ Andy Goodrich: added an explicit dynamic cast to keep gcc 4.x happy.
+
+Revision 1.3  2006/03/21 01:31:48  acg
+ Andy Goodrich: changed over to sc_get_current_process_b() from
+ sc_get_current_process_base() since the function's name changed.
+
+Revision 1.2  2005/12/26 20:11:14  acg
+Fixed up copyright.
+
+Revision 1.1.1.1  2005/12/19 23:16:42  acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.29  2005/09/15 23:01:52  acg
+Added std:: prefix to appropriate methods and types to get around
+issues with the Edison Front End.
+
+Revision 1.28  2005/07/30 03:44:11  acg
+Changes from 2.1.
+
+Revision 1.27  2005/05/09 17:17:12  acg
+Changes from 2.1.
+
+Revision 1.26  2005/05/08 19:04:06  acg
+Fix bug in concat_set(int64,off). Other changes from 2.1 examples usage.
+
+Revision 1.25  2005/05/03 20:05:16  acg
+Prefixed with sc_dt some sc_signed instances that were missed.
+
+Revision 1.24  2005/05/03 19:50:20  acg
+Name space version.
+
+Revision 1.22  2005/03/21 22:31:32  acg
+Changes to sc_core namespace.
+
+Revision 1.21  2005/01/10 17:51:58  acg
+Improvements.
+
+Revision 1.20  2004/11/09 00:11:27  acg
+Added support for sc_generic_base<T> in place of sc_concatref. sc_concatref
+now is derived from sc_generic_base<sc_concatref>.
+
+Revision 1.19  2004/09/27 21:01:59  acg
+Andy Goodrich - Forte Design Systems, Inc.
+   - This is specialized signal support that allows better use of signals
+     and ports whose target value is a SystemC native type.
+
+*/
+
+
+#if !defined(SC_SIGNAL_SIGNED_H)
+#define SC_SIGNAL_SIGNED_H
+
+#if ( !defined(_MSC_VER) || _MSC_VER > 1200 )
+#    define SC_TEMPLATE template<int W>
+#else
+#    define SC_TEMPLATE template<> template<int W>
+#endif
+
+// FORWARD REFERENCES AND USINGS:
+
+using sc_dt::int64;
+
+namespace sc_core {
+
+class sc_signed_sigref;
+
+//==============================================================================
+// CLASS sc_signed_part_if
+//
+// This class provides generic access to part selections for signals whose
+// data type is sc_dt::sc_bigint<W>. This class serves as the base class for the
+// sc_dt::sc_bigint<W> specialization of the sc_signal_in_if<T> class. The methods
+// in this class may be over-ridden individually, those that are not overridden
+// will produce an error message when called. The methods are used by the
+// sc_bigint_sigref class.
+//
+// Notes:
+//   (1) Descriptions of the methods and operators in this class appear with
+//       their implementations in sc_signal<sc_dt::sc_bigint<W> >.
+//==============================================================================
+class sc_signed_part_if : virtual public sc_interface {
+  protected:
+       // constructor:
+       sc_signed_part_if() {}
+
+  public:
+    // perform a part read.
+       virtual sc_dt::sc_signed* part_read_target();
+       virtual sc_dt::sc_signed read_part( int left, int right ) const;
+
+    // perform a part write.
+       virtual sc_signed_sigref& select_part( int left, int right );
+    virtual void write_part( sc_dt::int64 v, int left, int right );
+    virtual void write_part( sc_dt::uint64 v, int left, int right );
+    virtual void write_part( const sc_dt::sc_signed& v, int left, int right );
+    virtual void write_part( const sc_dt::sc_unsigned& v, int left, int right );
+
+
+  private:
+       sc_signed_part_if( const sc_signed_part_if& );
+       sc_signed_part_if& operator = ( const sc_signed_part_if& );
+};
+
+
+//==============================================================================
+// CLASS sc_signal_in_if<sc_dt::sc_bigint<W> >
+//
+// This is the class specializations for the sc_signal_in_if<T> class to
+// provide additional features for sc_signal instances whose template is
+// sc_dt::sc_bigint<W>, including part access.
+//
+// Notes:
+//   (1) Descriptions of the methods and operators in this class appear with
+//       their implementations in sc_signal<sc_dt::sc_bigint<W> >.
+//==============================================================================
+template< int W >
+class sc_signal_in_if<sc_dt::sc_bigint<W> > : public sc_signed_part_if {
+       friend class sc_signed_sigref;
+  public:
+    typedef sc_signal_in_if<sc_dt::sc_bigint<W> > this_type;
+
+    // get the value changed event
+    virtual const sc_event& value_changed_event() const = 0;
+
+
+    // read the current value
+    virtual const sc_dt::sc_bigint<W>& read() const = 0;
+
+    // get a reference to the current value (for tracing)
+    virtual const sc_dt::sc_bigint<W>& get_data_ref() const = 0;
+
+
+    // was there a value changed event?
+    virtual bool event() const = 0;
+
+  protected:
+    // constructor
+    sc_signal_in_if()
+    {}
+
+  private: // disabled
+    sc_signal_in_if( const this_type& );
+    this_type& operator = ( const this_type& );
+};
+
+//=============================================================================
+//  CLASS : sc_signed_sigref
+//
+//  Proxy class for sc_signal_uint bit and part selection.
+//=============================================================================
+class sc_signed_sigref : public sc_dt::sc_signed_subref_r
+{
+  public:
+    sc_signed_sigref() : sc_dt::sc_signed_subref_r() {}
+    virtual ~sc_signed_sigref() {}
+    virtual void concat_set(sc_dt::int64 src, int low_i);
+    virtual void concat_set(const sc_dt::sc_signed& src, int low_i);
+    virtual void concat_set(const sc_dt::sc_unsigned& src, int low_i);
+    virtual void concat_set(const sc_dt::sc_lv_base& src, int low_i);
+    virtual void concat_set(sc_dt::uint64 src, int low_i);
+
+  public:
+    inline void initialize( sc_signed_part_if* if_p, int left_, int right_ );
+
+  public:
+    inline void operator = ( sc_dt::uint64 v );
+    inline void operator = ( const char* v );
+    inline void operator = ( unsigned long v );
+    inline void operator = ( long v );
+    inline void operator = ( unsigned int v );
+    inline void operator = ( int v );
+    inline void operator = ( sc_dt::int64 v );
+    inline void operator = ( double v );
+    inline void operator = ( const sc_signed_sigref& v );
+    template<typename T>
+    inline void operator = ( const sc_dt::sc_generic_base<T>& v );
+    inline void operator = ( const sc_dt::sc_signed& v );
+    inline void operator = ( const sc_dt::sc_unsigned& v );
+    inline void operator = ( const sc_dt::sc_bv_base& v );
+    inline void operator = ( const sc_dt::sc_lv_base& v );
+
+  public:
+    static sc_vpool<sc_signed_sigref> m_pool; // Pool of objects to use.
+
+  protected:
+    sc_signed_part_if*                m_if_p; // Target for selection.
+
+  private:
+
+    // disabled
+    sc_signed_sigref( const sc_signed_sigref& a );
+};
+
+
+//==============================================================================
+// CLASS sc_signal<sc_dt::sc_bigint<W> >
+//
+// This class implements a signal whose value acts like an sc_dt::sc_bigint<W> data
+// value. This class is a specialization of the generic sc_signal class to
+// implement tailored support for the sc_dt::sc_bigint<W> class.
+//
+// Notes:
+//   (1) Descriptions of the methods and operators in this class appear with
+//       their implementations.
+//==============================================================================
+SC_TEMPLATE
+class sc_signal<sc_dt::sc_bigint<W> > :
+    public sc_dt::sc_bigint<W>,
+       public sc_prim_channel,
+    public sc_signal_inout_if<sc_dt::sc_bigint<W> >
+{
+  public: // typedefs
+    typedef sc_signal<sc_dt::sc_bigint<W> > this_type;
+
+  public: // constructors and destructor:
+    inline sc_signal();
+    explicit inline sc_signal(const char* name_);
+    virtual inline ~sc_signal();
+
+  public: // base methods:
+    inline bool base_event() const;
+    inline const sc_dt::sc_bigint<W>& base_read() const;
+    inline const sc_event& base_value_changed_event() const;
+    inline void base_write( sc_dt::int64 value );
+    inline void base_write( sc_dt::uint64 value );
+    inline void base_write( const sc_dt::sc_signed& value );
+    inline void base_write( const sc_dt::sc_unsigned& value );
+
+  public: // sc_prim_channel virtual methods:
+    virtual inline const char* kind() const;
+    virtual inline void update();
+
+  public: // sc_interface virtual methods:
+    virtual inline const sc_event& default_event() const;
+    virtual inline void register_port(
+               sc_port_base& port_, const char* if_typename_ );
+
+  public: // sc_signed_part_if virtual methods:
+    virtual inline sc_dt::sc_signed* part_read_target();
+    virtual inline sc_dt::sc_signed read_part(int left, int right) const;
+       virtual sc_signed_sigref& select_part( int left, int right );
+       virtual inline void write_part( sc_dt::int64 v, int left, int right );
+       virtual inline void write_part( sc_dt::uint64 v, int left, int right );
+       virtual inline void write_part( const sc_dt::sc_signed& v, int left, int right );
+       virtual inline void write_part(const sc_dt::sc_unsigned& v, int left, int right);
+
+  public: // interface virtual methods:
+    virtual inline bool event() const;
+    virtual inline const sc_dt::sc_bigint<W>& get_data_ref() const;
+    virtual inline sc_signal<sc_dt::sc_bigint<W> >& get_signal();
+    virtual inline const sc_dt::sc_bigint<W>& read() const;
+    virtual inline const sc_event& value_changed_event() const;
+    virtual inline void write( const sc_in<sc_dt::sc_bigint<W> >& value );
+    virtual inline void write( const sc_inout<sc_dt::sc_bigint<W> >& value );
+    virtual inline void write( const sc_dt::sc_bigint<W>& value );
+
+  public: // part selections:
+       inline sc_signed_sigref& operator () ( int left, int right );
+       // #### Need to add bit() and range()
+       inline sc_signed_sigref& operator [] ( int bit );
+
+  public: // operators:
+    inline void operator = ( const this_type& new_val );
+    inline void operator = ( const char* new_val );
+    inline void operator = ( sc_dt::uint64 new_val );
+    inline void operator = ( sc_dt::int64 new_val );
+    inline void operator = ( int new_val );
+    inline void operator = ( long new_val );
+    inline void operator = ( short new_val );
+    inline void operator = ( unsigned int new_val );
+    inline void operator = ( unsigned long new_val );
+    inline void operator = ( unsigned short new_val );
+    template<typename T>
+    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val );
+    inline void operator = ( const sc_dt::sc_signed& new_val );
+    inline void operator = ( const sc_dt::sc_unsigned& new_val );
+    inline void operator = ( const sc_dt::sc_bv_base& new_val );
+    inline void operator = ( const sc_dt::sc_lv_base& new_val );
+
+    // concatenation methods (we inherit length and gets from sc_dt::sc_bigint<W>):
+
+    virtual inline void concat_set(sc_dt::int64 src, int low_i);
+    virtual inline void concat_set(const sc_dt::sc_lv_base& src, int low_i);
+    virtual inline void concat_set(const sc_dt::sc_signed& src, int low_i);
+    virtual inline void concat_set(const sc_dt::sc_unsigned& src, int low_i);
+    virtual inline void concat_set(sc_dt::uint64 src, int low_i);
+
+  protected: // debugging methods:
+    // #### void check_port();
+       void check_writer();
+
+  private: // Disabled operations that sc_dt::sc_bigint<W> supports:
+    sc_dt::sc_signed& operator ++ ();          // prefix
+    const sc_dt::sc_signed& operator ++ (int); // postfix
+    sc_dt::sc_signed& operator -- ();          // prefix
+    const sc_dt::sc_signed& operator -- (int); // postfix
+    sc_dt::sc_signed& operator += (const sc_dt::sc_signed&    );
+    sc_dt::sc_signed& operator += (const sc_dt::sc_unsigned&  );
+    sc_dt::sc_signed& operator += (sc_dt::int64               );
+    sc_dt::sc_signed& operator += (sc_dt::uint64              );
+    sc_dt::sc_signed& operator += (long                );
+    sc_dt::sc_signed& operator += (unsigned long       );
+    sc_dt::sc_signed& operator += (int                 );
+    sc_dt::sc_signed& operator += (unsigned int        );
+    sc_dt::sc_signed& operator -= (const sc_dt::sc_signed&    );
+    sc_dt::sc_signed& operator -= (const sc_dt::sc_unsigned&  );
+    sc_dt::sc_signed& operator -= (sc_dt::int64               );
+    sc_dt::sc_signed& operator -= (sc_dt::uint64              );
+    sc_dt::sc_signed& operator -= (long                );
+    sc_dt::sc_signed& operator -= (unsigned long       );
+    sc_dt::sc_signed& operator -= (int                 );
+    sc_dt::sc_signed& operator -= (unsigned int        );
+    sc_dt::sc_signed& operator *= (const sc_dt::sc_signed&    );
+    sc_dt::sc_signed& operator *= (const sc_dt::sc_unsigned&  );
+    sc_dt::sc_signed& operator *= (sc_dt::int64               );
+    sc_dt::sc_signed& operator *= (sc_dt::uint64              );
+    sc_dt::sc_signed& operator *= (long                );
+    sc_dt::sc_signed& operator *= (unsigned long       );
+    sc_dt::sc_signed& operator *= (int                 );
+    sc_dt::sc_signed& operator *= (unsigned int        );
+    sc_dt::sc_signed& operator /= (const sc_dt::sc_signed&    );
+    sc_dt::sc_signed& operator /= (const sc_dt::sc_unsigned&  );
+    sc_dt::sc_signed& operator /= (sc_dt::int64               );
+    sc_dt::sc_signed& operator /= (sc_dt::uint64              );
+    sc_dt::sc_signed& operator /= (long                );
+    sc_dt::sc_signed& operator /= (unsigned long       );
+    sc_dt::sc_signed& operator /= (int                 );
+    sc_dt::sc_signed& operator /= (unsigned int        );
+    sc_dt::sc_signed& operator %= (const sc_dt::sc_signed&    );
+    sc_dt::sc_signed& operator %= (const sc_dt::sc_unsigned&  );
+    sc_dt::sc_signed& operator %= (sc_dt::int64               );
+    sc_dt::sc_signed& operator %= (sc_dt::uint64              );
+    sc_dt::sc_signed& operator %= (long                );
+    sc_dt::sc_signed& operator %= (unsigned long       );
+    sc_dt::sc_signed& operator %= (int                 );
+    sc_dt::sc_signed& operator %= (unsigned int        );
+    sc_dt::sc_signed& operator &= (const sc_dt::sc_signed&    );
+    sc_dt::sc_signed& operator &= (const sc_dt::sc_unsigned&  );
+    sc_dt::sc_signed& operator &= (sc_dt::int64               );
+    sc_dt::sc_signed& operator &= (sc_dt::uint64              );
+    sc_dt::sc_signed& operator &= (long                );
+    sc_dt::sc_signed& operator &= (unsigned long       );
+    sc_dt::sc_signed& operator &= (int                 );
+    sc_dt::sc_signed& operator &= (unsigned int        );
+    sc_dt::sc_signed& operator |= (const sc_dt::sc_signed&    );
+    sc_dt::sc_signed& operator |= (const sc_dt::sc_unsigned&  );
+    sc_dt::sc_signed& operator |= (sc_dt::int64               );
+    sc_dt::sc_signed& operator |= (sc_dt::uint64              );
+    sc_dt::sc_signed& operator |= (long                );
+    sc_dt::sc_signed& operator |= (unsigned long       );
+    sc_dt::sc_signed& operator |= (int                 );
+    sc_dt::sc_signed& operator |= (unsigned int        );
+    sc_dt::sc_signed& operator ^= (const sc_dt::sc_signed&    );
+    sc_dt::sc_signed& operator ^= (const sc_dt::sc_unsigned&  );
+    sc_dt::sc_signed& operator ^= (sc_dt::int64               );
+    sc_dt::sc_signed& operator ^= (sc_dt::uint64              );
+    sc_dt::sc_signed& operator ^= (long                );
+    sc_dt::sc_signed& operator ^= (unsigned long       );
+    sc_dt::sc_signed& operator ^= (int                 );
+    sc_dt::sc_signed& operator ^= (unsigned int        );
+
+  protected:
+    mutable sc_event*  m_changed_event_p; // Value changed event this object.
+    sc_dt::uint64      m_event_delta;     // Delta cycle of last event.
+    sc_dt::sc_signed   m_new_val;         // New value for this object instance.
+    sc_port_base*      m_output_p;        // Single write port verify field.
+    sc_process_b*   m_writer_p;        // Single writer verify field.
+};
+
+
+SC_TEMPLATE // Return true if a changed event happened in the last delta cycle.
+inline bool sc_signal<sc_dt::sc_bigint<W> >::base_event() const
+{
+    return simcontext()->delta_count() == m_event_delta + 1;
+}
+
+
+SC_TEMPLATE // Return this object's sc_dt::sc_bigint<W> object instance.
+inline const sc_dt::sc_bigint<W>& sc_signal<sc_dt::sc_bigint<W> >::base_read() const
+{
+       return *this;
+}
+
+
+SC_TEMPLATE // Return the value changed event, allocating it if necessary.
+inline const sc_event& sc_signal<sc_dt::sc_bigint<W> >::base_value_changed_event() const
+{
+    if ( !m_changed_event_p ) m_changed_event_p = new sc_event;
+    return *m_changed_event_p;
+}
+
+
+SC_TEMPLATE // Write a const sc_dt::sc_signed& value to this object instance.
+inline void sc_signal<sc_dt::sc_bigint<W> >::base_write( const sc_dt::sc_signed& value )
+{
+#   if defined(DEBUG_SYSTEMC)
+        check_writer();
+#   endif
+    m_new_val = value;
+    request_update();
+}
+
+SC_TEMPLATE // Write a const sc_dt::sc_unsigned& value to this object instance.
+inline void sc_signal<sc_dt::sc_bigint<W> >::base_write( const sc_dt::sc_unsigned& value )
+{
+#   if defined(DEBUG_SYSTEMC)
+        check_writer();
+#   endif
+    m_new_val = value;
+    request_update();
+}
+
+SC_TEMPLATE // Write a sc_dt::int64 value to this object instance.
+inline void sc_signal<sc_dt::sc_bigint<W> >::base_write( sc_dt::int64 value )
+{
+#   if defined(DEBUG_SYSTEMC)
+        check_writer();
+#   endif
+    m_new_val = value;
+    request_update();
+}
+
+
+SC_TEMPLATE // Write a sc_dt::uint64 value to this object instance.
+inline void sc_signal<sc_dt::sc_bigint<W> >::base_write( sc_dt::uint64 value )
+{
+#   if defined(DEBUG_SYSTEMC)
+        check_writer();
+#   endif
+    m_new_val = value;
+    request_update();
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_signal<sc_dt::sc_bigint<W> >::check_writer"
+//
+// This method checks to see if there is more than one writer for this
+// object instance by keeping track of the process performing the write.
+//------------------------------------------------------------------------------
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::check_writer()
+{
+    sc_process_b* writer_p = sc_get_current_process_b();
+    if( m_writer_p == 0 )
+    {
+        m_writer_p = writer_p;
+    }
+    else if( m_writer_p != writer_p )
+    {
+        sc_signal_invalid_writer( name(), kind(),
+                                  m_writer_p->name(), writer_p->name() );
+    }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_signal<sc_dt::sc_bigint<W> >::concat_set"
+//
+// These virtual methods allow value assignments to this object instance
+// from various sources. The position within the supplied source of the
+// low order bit for this object instance's value is low_i.
+//     src   = source value.
+//     low_i = bit within src to serve as low order bit of this object
+//             instance's value.
+//------------------------------------------------------------------------------
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::concat_set(sc_dt::int64 src, int low_i)
+{
+    if ( low_i < 64 )
+    {
+        base_write(src >> low_i);
+    }
+    else
+    {
+        base_write( (sc_dt::int64)((src < 0 ) ?  -1 : 0 ));
+    }
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::concat_set(
+       const sc_dt::sc_lv_base& src, int low_i)
+{
+    sc_dt::sc_unsigned tmp(src.length());
+    tmp = src >> low_i;
+    base_write( tmp );
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::concat_set(
+       const sc_dt::sc_signed& src, int low_i)
+{
+    base_write( (src >> low_i) );
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::concat_set(
+       const sc_dt::sc_unsigned& src, int low_i)
+{
+    base_write( (src >> low_i) );
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::concat_set(sc_dt::uint64 src, int low_i)
+{
+       base_write( (sc_dt::uint64)(( low_i < 64 ) ? src >> low_i : 0));
+}
+
+
+
+SC_TEMPLATE // Return the default event for this object instance.
+inline const sc_event& sc_signal<sc_dt::sc_bigint<W> >::default_event() const
+       { return base_value_changed_event(); }
+
+
+SC_TEMPLATE // Return true if a changed event happened in the last delta cycle.
+inline bool sc_signal<sc_dt::sc_bigint<W> >::event() const
+       { return base_event(); }
+
+
+SC_TEMPLATE // Return a reference to the value of this object instance.
+inline const sc_dt::sc_bigint<W>& sc_signal<sc_dt::sc_bigint<W> >::get_data_ref() const
+       { return *this; }
+
+
+SC_TEMPLATE // Return a pointer to this object instance.
+inline sc_signal<sc_dt::sc_bigint<W> >& sc_signal<sc_dt::sc_bigint<W> >::get_signal()
+       { return *this; }
+
+
+SC_TEMPLATE // Return a kind value of "sc_signal".
+inline const char* sc_signal<sc_dt::sc_bigint<W> >::kind() const
+{
+       return "sc_signal";
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_signal<sc_dt::sc_bigint<W> >::operator ()
+//
+// This operator returns a part selection of this object instance.
+//     left  = left-hand bit of the selection.
+//     right = right-hand bit of the selection.
+//------------------------------------------------------------------------------
+SC_TEMPLATE
+inline sc_signed_sigref& sc_signal<sc_dt::sc_bigint<W> >::operator () (int left, int right)
+{
+    sc_signed_sigref* result_p;   // Value to return.
+
+       result_p = sc_signed_sigref::m_pool.allocate();
+       result_p->initialize(this, left, right);
+       return *result_p;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_signal<sc_dt::sc_bigint<W> >::operator []"
+//
+// This operator returns a bit selection of this object instance.
+//     i = bit to be selected.
+//------------------------------------------------------------------------------
+SC_TEMPLATE
+inline sc_signed_sigref& sc_signal<sc_dt::sc_bigint<W> >::operator [] ( int bit )
+{
+    return operator () (bit,bit);
+}
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( const this_type& new_val )
+       { base_write( new_val ); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( const char* new_val )
+       { sc_dt::sc_bigint<W> tmp = new_val; m_new_val = tmp; request_update(); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( sc_dt::uint64 new_val )
+       { base_write(new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( sc_dt::int64 new_val )
+       { base_write(new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( int new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( long new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( short new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( unsigned int new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( unsigned long new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( unsigned short new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+SC_TEMPLATE
+template<typename T>
+inline void sc_signal<sc_dt::sc_bigint<W> >::operator = (
+    const sc_dt::sc_generic_base<T>& new_val )
+{
+    sc_dt::sc_unsigned temp(W);
+    new_val->to_sc_unsigned(temp);
+    base_write(temp);
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( const sc_dt::sc_unsigned& new_val )
+       { base_write(new_val); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( const sc_dt::sc_bv_base& new_val )
+       { base_write( (sc_dt::sc_bigint<W>)new_val ); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( const sc_dt::sc_lv_base& new_val )
+       { base_write( (sc_dt::sc_bigint<W>)new_val ); }
+
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( const sc_dt::sc_signed& new_val )
+       { base_write(new_val); }
+
+
+SC_TEMPLATE // Return a pointer to the read target for part selections.
+inline sc_dt::sc_signed* sc_signal<sc_dt::sc_bigint<W> >::part_read_target()
+       { return this; }
+
+SC_TEMPLATE // Return this object's base value as a const reference.
+inline const sc_dt::sc_bigint<W>& sc_signal<sc_dt::sc_bigint<W> >::read() const
+       { return *this; }
+
+
+SC_TEMPLATE // Read a portion of a value.
+inline sc_dt::sc_signed sc_signal<sc_dt::sc_bigint<W> >::read_part(
+       int left, int right ) const
+{
+    return (sc_dt::sc_signed)sc_dt::sc_signed::operator () (left, right);
+}
+
+SC_TEMPLATE // Register a port for write checking.
+inline void sc_signal<sc_dt::sc_bigint<W> >::register_port(
+       sc_port_base& port_, const char* if_typename_ )
+{
+#       ifdef DEBUG_SYSTEMC
+               std::string nm( if_typename_ );
+               if( nm == typeid( sc_signal_inout_if<sc_dt::sc_bigint<W> > ).name() )
+               {
+                       if( m_output_p != 0 )
+                       {
+                               sc_signal_invalid_writer( name(), kind(),
+                                        m_output_p->name(), port_.name() );
+                       }
+                       m_output_p = &port_;
+               }
+#       else
+            if ( &port_ && if_typename_ ) {} // Silence unused args warning.
+#       endif
+}
+
+
+SC_TEMPLATE // Autogenerated name object instance constructor.
+inline sc_signal<sc_dt::sc_bigint<W> >::sc_signal() :
+       sc_prim_channel(sc_gen_unique_name( "signal" )),
+       m_changed_event_p(0),
+       m_new_val(W),
+       m_output_p(0),
+       m_writer_p(0)
+{ }
+
+
+SC_TEMPLATE // Explicitly named object instance constructor.
+inline sc_signal<sc_dt::sc_bigint<W> >::sc_signal(const char* name_) :
+       sc_prim_channel(name_),
+       m_changed_event_p(0),
+       m_new_val(W),
+       m_output_p(0),
+       m_writer_p(0)
+{ }
+
+
+SC_TEMPLATE // Object instance destructor.
+inline sc_signal<sc_dt::sc_bigint<W> >::~sc_signal()
+{
+       if ( m_changed_event_p ) delete m_changed_event_p;
+}
+
+
+SC_TEMPLATE // Update the current value from new value.
+inline void sc_signal<sc_dt::sc_bigint<W> >::update()
+{
+    if ( m_changed_event_p )
+    {
+        if ( m_new_val != *this )
+        {
+            m_changed_event_p->notify_delayed();
+            m_event_delta = simcontext()->delta_count();
+        }
+    }
+       sc_dt::sc_signed::operator = (m_new_val);
+}
+
+
+SC_TEMPLATE // Return the value changed event.
+inline const sc_event& sc_signal<sc_dt::sc_bigint<W> >::value_changed_event() const
+       { return base_value_changed_event(); }
+
+
+SC_TEMPLATE // Write a sc_in<sc_dt::sc_bigint<W> > value to this object instance.
+inline void sc_signal<sc_dt::sc_bigint<W> >::write( const sc_in<sc_dt::sc_bigint<W> >& value )
+       { base_write( value ); }
+
+
+SC_TEMPLATE // Write a sc_inout<sc_dt::sc_bigint<W> > value to this object instance.
+inline void sc_signal<sc_dt::sc_bigint<W> >::write( const sc_inout<sc_dt::sc_bigint<W> >& value )
+       { base_write( value ); }
+
+
+SC_TEMPLATE // Write a sc_dt::sc_bigint<W> value to this object instance.
+inline void sc_signal<sc_dt::sc_bigint<W> >::write( const sc_dt::sc_bigint<W>& value )
+       { base_write( value); }
+
+
+SC_TEMPLATE // Select a portion of a value.
+inline sc_signed_sigref& sc_signal<sc_dt::sc_bigint<W> >::select_part(
+    int left, int right)
+{
+    sc_signed_sigref* result_p = sc_signed_sigref::m_pool.allocate();
+    result_p->initialize(dynamic_cast<sc_signed_part_if*>(this), left, right);
+    return *result_p;
+}
+
+
+SC_TEMPLATE // Write a portion of a value. If this is the first write in
+            // a delta cycle we copy the existing value before setting the bits.
+inline void sc_signal<sc_dt::sc_bigint<W> >::write_part(sc_dt::int64 v, int left, int right)
+{
+       m_new_val(left, right) = v;
+       request_update();
+}
+
+
+SC_TEMPLATE // Write a portion of a value. If this is the first write in
+            // a delta cycle we copy the existing value before setting the bits.
+inline void sc_signal<sc_dt::sc_bigint<W> >::write_part(sc_dt::uint64 v, int left, int right)
+{
+       m_new_val(left, right) = v;
+       request_update();
+}
+
+
+SC_TEMPLATE // Write a portion of a value. If this is the first write in
+            // a delta cycle we copy the existing value before setting the bits.
+inline void sc_signal<sc_dt::sc_bigint<W> >::write_part(
+       const sc_dt::sc_signed& v, int left, int right )
+{
+       m_new_val(left, right) = v;
+       request_update();
+}
+
+
+SC_TEMPLATE // Write a portion of a value. If this is the first write in
+            // a delta cycle we copy the existing value before setting the bits.
+inline void sc_signal<sc_dt::sc_bigint<W> >::write_part(
+       const sc_dt::sc_unsigned& v, int left, int right )
+{
+       m_new_val(left, right) = v;
+       request_update();
+}
+
+
+//==============================================================================
+// CLASS sc_in<sc_dt::sc_bigint<W> >
+//
+// This class implements an input port whose target acts like an sc_dt::sc_bigint<W> data
+// value. This class is a specialization of the generic sc_in class to
+// implement tailored support for the sc_dt::sc_bigint<W> class.
+//==============================================================================
+SC_TEMPLATE
+class sc_in<sc_dt::sc_bigint<W> > :
+    public sc_port<sc_signal_in_if<sc_dt::sc_bigint<W> >, 1,
+                   SC_ONE_OR_MORE_BOUND>,
+    public sc_dt::sc_value_base
+{
+  public:
+
+    // typedefs
+
+    typedef sc_dt::sc_bigint<W>                      data_type;
+    typedef sc_signal_in_if<sc_dt::sc_bigint<W> >    if_type;
+    typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND>  base_type;
+    typedef sc_in<sc_dt::sc_bigint<W> >              this_type;
+
+    typedef if_type                                  in_if_type;
+    typedef base_type                                in_port_type;
+    typedef sc_signal_inout_if<sc_dt::sc_bigint<W> > inout_if_type;
+    typedef sc_inout<sc_dt::sc_bigint<W> >           inout_port_type;
+
+  public:
+
+    // bind methods and operators:
+
+    void bind( const in_if_type& interface_ )
+        { sc_port_base::bind( const_cast<in_if_type&>( interface_) );}
+    void operator () ( const in_if_type& interface_ )
+        { sc_port_base::bind( const_cast<in_if_type&>( interface_) );}
+    void bind( in_port_type& parent_ )
+        { sc_port_base::bind(parent_);}
+    void operator () ( in_port_type& parent_ )
+        { sc_port_base::bind(parent_);}
+    void bind( inout_port_type& parent_ )
+        { sc_port_base::bind(parent_);}
+    void operator () ( inout_port_type& parent_ )
+        { sc_port_base::bind(parent_);}
+
+  protected:
+    // called by pbind (for internal use only)
+    virtual inline int vbind( sc_interface& interface_ )
+        {
+            return sc_port_b<if_type>::vbind( interface_ );
+        }
+    virtual inline int vbind( sc_port_base& parent_ )
+        {
+            in_port_type* in_parent = dynamic_cast<in_port_type*>( &parent_ );
+            if( in_parent != 0 ) {
+                sc_port_base::bind( *in_parent );
+                return 0;
+            }
+            inout_port_type* inout_parent = dynamic_cast<inout_port_type*>( &parent_ );
+            if( inout_parent != 0 ) {
+                sc_port_base::bind( *inout_parent );
+                return 0;
+            }
+            // type mismatch
+            return 2;
+        }
+
+
+    // constructors
+
+  public:
+    sc_in()
+        : base_type(), m_traces( 0 )
+        {}
+
+    explicit sc_in( const char* name_ )
+        : base_type( name_ ), m_traces( 0 )
+        {}
+
+    explicit sc_in( const in_if_type& interface_ )
+        : base_type( const_cast<in_if_type&>( interface_ ) ), m_traces( 0 )
+        {}
+
+    sc_in( const char* name_, const in_if_type& interface_ )
+        : base_type( name_, const_cast<in_if_type&>( interface_ ) ), m_traces( 0 )
+        {}
+
+    explicit sc_in( in_port_type& parent_ )
+        : base_type( parent_ ), m_traces( 0 )
+        {}
+
+    sc_in( const char* name_, in_port_type& parent_ )
+        : base_type( name_, parent_ ), m_traces( 0 )
+        {}
+
+    explicit sc_in( inout_port_type& parent_ )
+        : base_type(), m_traces( 0 )
+        { sc_port_base::bind( parent_ ); }
+
+    sc_in( const char* name_, inout_port_type& parent_ )
+        : base_type( name_ ), m_traces( 0 )
+        { sc_port_base::bind( parent_ ); }
+
+    sc_in( this_type& parent_ )
+        : base_type( parent_ ), m_traces( 0 )
+        {}
+
+    sc_in( const char* name_, this_type& parent_ )
+        : base_type( name_, parent_ ), m_traces( 0 )
+        {}
+
+
+    // destructor
+
+    virtual inline ~sc_in()
+        {
+            remove_traces();
+        }
+
+    // bit and part selection
+
+    sc_dt::sc_signed_bitref_r operator [] ( int i ) const
+        { return (*this)->read()[i]; }
+    sc_dt::sc_signed_bitref_r bit( int i ) const
+        { return (*this)->read()[i]; }
+    sc_dt::sc_signed_subref_r operator () ( int left, int right ) const
+        { return (*this)->read()(left,right); }
+    sc_dt::sc_signed_subref_r range( int left, int right ) const
+        { return (*this)->read()(left,right); }
+
+
+    // interface access shortcut methods
+
+    // get the default event
+
+    const sc_event& default_event() const
+        { return (*this)->value_changed_event(); }
+
+
+    // get the value changed event
+
+    const sc_event& value_changed_event() const
+        { return (*this)->value_changed_event(); }
+
+
+    // read the current value
+
+    const sc_dt::sc_bigint<W>& read() const
+        { return (*this)->read(); }
+
+    operator const sc_dt::sc_bigint<W>& () const
+        { return (*this)->read(); }
+
+    // was there a value changed event?
+
+    bool event() const
+        { return (*this)->event(); }
+
+
+    // (other) event finder method(s)
+
+    sc_event_finder& value_changed() const
+        {
+            return *new sc_event_finder_t<in_if_type>(
+                *this, &in_if_type::value_changed_event );
+        }
+
+
+
+    // reduction methods:
+
+    inline bool and_reduce() const
+        { return (*this)->read().and_reduce(); }
+    inline bool nand_reduce() const
+        { return (*this)->read().nand_reduce(); }
+    inline bool nor_reduce() const
+        { return (*this)->read().nor_reduce(); }
+    inline bool or_reduce() const
+        { return (*this)->read().or_reduce(); }
+    inline bool xnor_reduce() const
+        { return (*this)->read().xnor_reduce(); }
+    inline bool xor_reduce() const
+        { return (*this)->read().xor_reduce(); }
+
+
+    // called when elaboration is done
+    /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+    /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+    virtual inline void end_of_elaboration()
+        {
+            if( m_traces != 0 ) {
+                for( unsigned int i = 0; i < m_traces->size(); ++ i ) {
+                    sc_trace_params* p = (*m_traces)[i];
+                    sc_trace( p->tf, read(), p->name );
+                }
+                remove_traces();
+            }
+        }
+
+    virtual inline const char* kind() const
+        { return "sc_in"; }
+
+
+    // called by sc_trace
+    void add_trace( sc_trace_file* tf_, const std::string& name_ ) const
+        {
+            if( tf_ != 0 ) {
+                if( m_traces == 0 ) {
+                    m_traces = new sc_trace_params_vec;
+                }
+                m_traces->push_back( new sc_trace_params( tf_, name_ ) );
+            }
+        }
+
+
+    // concatenation methods
+
+    virtual inline int concat_length(bool* xz_present_p) const
+        { return (*this)->read().concat_length( xz_present_p ); }
+    virtual inline sc_dt::uint64 concat_get_uint64() const
+        { return (*this)->read().concat_get_uint64(); }
+    virtual inline bool concat_get_ctrl( sc_dt::sc_digit* dst_p, int low_i ) const
+        { return (*this)->read().concat_get_ctrl(dst_p, low_i); }
+    virtual inline bool concat_get_data( sc_dt::sc_digit* dst_p, int low_i ) const
+        { return (*this)->read().concat_get_data(dst_p, low_i); }
+
+  protected:
+    void remove_traces() const
+        {
+            if( m_traces != 0 ) {
+                for( int i = m_traces->size() - 1; i >= 0; -- i ) {
+                    delete (*m_traces)[i];
+                }
+                delete m_traces;
+                m_traces = 0;
+            }
+        }
+
+    mutable sc_trace_params_vec* m_traces;
+
+
+  private:
+
+    // disabled
+    sc_in( const sc_in<sc_dt::sc_bigint<W> >& );
+    sc_in<sc_dt::sc_bigint<W> >& operator = ( const sc_in<sc_dt::sc_bigint<W> >& );
+
+#ifdef __GNUC__
+    // Needed to circumvent a problem in the g++-2.95.2 compiler:
+    // This unused variable forces the compiler to instantiate
+    // an object of T template so an implicit conversion from
+    // read() to a C++ intrinsic data type will work.
+    static data_type dummy;
+#endif
+
+};
+
+
+
+SC_TEMPLATE
+inline std::ostream& operator << (
+       std::ostream& os, const sc_in<sc_dt::sc_bigint<W> >& a )
+{
+    a.read().print( os );
+    return os;
+}
+
+
+//==============================================================================
+// CLASS sc_inout<sc_dt::sc_bigint<W> >
+//
+// This class implements an input/output port whose target acts like an
+// sc_dt::sc_bigint<W> data value. It is derived from the sc_signed_in. This class is a
+// specialization of the generic sc_inout class to implement tailored support
+// for the sc_dt::sc_bigint<W> class.
+//==============================================================================
+SC_TEMPLATE
+class sc_inout<sc_dt::sc_bigint<W> > :
+    public sc_port<sc_signal_inout_if<sc_dt::sc_bigint<W> >, 1,
+                   SC_ONE_OR_MORE_BOUND>,
+    public sc_dt::sc_value_base
+{
+  public:
+
+    // typedefs
+
+    typedef sc_dt::sc_bigint<W>                      data_type;
+    typedef sc_signal_inout_if<sc_dt::sc_bigint<W> > if_type;
+    typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND>  base_type;
+    typedef sc_inout<sc_dt::sc_bigint<W> >           this_type;
+
+    typedef if_type                                  inout_if_type;
+    typedef base_type                                inout_port_type;
+
+  public:
+
+    // bind methods and operators:
+
+    void bind( const inout_if_type& interface_ )
+        { sc_port_base::bind( const_cast<inout_if_type&>( interface_) ); }
+    void operator () ( const inout_if_type& interface_ )
+        { sc_port_base::bind( const_cast<inout_if_type&>( interface_) ); }
+    void bind( inout_port_type& parent_ )
+        { sc_port_base::bind(parent_); }
+    void operator () ( inout_port_type& parent_ )
+        { sc_port_base::bind(parent_); }
+
+  protected:
+    // called by pbind (for internal use only)
+    virtual inline int vbind( sc_interface& interface_ )
+        {
+            return sc_port_b<if_type>::vbind( interface_ );
+        }
+    virtual inline int vbind( sc_port_base& parent_ )
+        {
+            inout_port_type* inout_parent = dynamic_cast<inout_port_type*>( &parent_ );
+            if( inout_parent != 0 ) {
+                sc_port_base::bind( *inout_parent );
+                return 0;
+            }
+            // type mismatch
+            return 2;
+        }
+
+
+    // constructors
+
+  public:
+    sc_inout()
+        : base_type(), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    explicit sc_inout( const char* name_ )
+        : base_type( name_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    explicit sc_inout( inout_if_type& interface_ )
+        : base_type( interface_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    sc_inout( const char* name_, inout_if_type& interface_ )
+        : base_type( name_, interface_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    explicit sc_inout( inout_port_type& parent_ )
+        : base_type( parent_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    sc_inout( const char* name_, inout_port_type& parent_ )
+        : base_type( name_, parent_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    sc_inout( this_type& parent_ )
+        : base_type( parent_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    sc_inout( const char* name_, this_type& parent_ )
+        : base_type( name_, parent_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+
+    // destructor
+
+    virtual inline ~sc_inout()
+        {
+            remove_traces();
+        }
+
+    // bit and part selection
+
+    sc_dt::sc_signed_bitref_r operator [] ( int i ) const
+        { return (*this)->read()[i]; }
+    sc_dt::sc_signed_bitref_r bit( int i ) const
+        { return (*this)->read()[i]; }
+    sc_signed_sigref& operator [] ( int i )
+               { return (*this)->select_part(i,i); }
+    sc_signed_sigref& bit( int i )
+               { return (*this)->select_part(i,i); }
+    sc_dt::sc_signed_subref_r operator () ( int left, int right ) const
+        { return (*this)->read()(left,right); }
+    sc_dt::sc_signed_subref_r range( int left, int right ) const
+        { return (*this)->read()(left,right); }
+    sc_signed_sigref& operator () ( int left, int right )
+               { return (*this)->select_part(left,right); }
+    sc_signed_sigref& range( int left, int right )
+               { return (*this)->select_part(left,right); }
+
+
+    // interface access shortcut methods
+
+    // get the default event
+
+    const sc_event& default_event() const
+        { return (*this)->value_changed_event(); }
+
+
+    // get the value changed event
+
+    const sc_event& value_changed_event() const
+        { return (*this)->value_changed_event(); }
+
+
+    // read the current value
+
+    const sc_dt::sc_bigint<W>& read() const
+        { return (*this)->read(); }
+
+    operator const sc_dt::sc_bigint<W>& () const
+        { return (*this)->read(); }
+
+    // was there a value changed event?
+
+    bool event() const
+        { return (*this)->event(); }
+
+
+    // (other) event finder method(s)
+
+    sc_event_finder& value_changed() const
+        {
+            return *new sc_event_finder_t<inout_if_type>(
+                *this, &inout_if_type::value_changed_event );
+        }
+
+
+
+    // reduction methods:
+
+    inline bool and_reduce() const
+        { return (*this)->read().and_reduce(); }
+    inline bool nand_reduce() const
+        { return (*this)->read().nand_reduce(); }
+    inline bool nor_reduce() const
+        { return (*this)->read().nor_reduce(); }
+    inline bool or_reduce() const
+        { return (*this)->read().or_reduce(); }
+    inline bool xnor_reduce() const
+        { return (*this)->read().xnor_reduce(); }
+    inline bool xor_reduce() const
+        { return (*this)->read().xor_reduce(); }
+
+
+    // called when elaboration is done
+    /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+    /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+    virtual inline void end_of_elaboration()
+        {
+            if( m_init_val_p != 0 ) {
+                (*this)->write( *m_init_val_p );
+                delete m_init_val_p;
+                m_init_val_p = 0;
+            }
+            if( m_traces != 0 ) {
+                for( unsigned int i = 0; i < m_traces->size(); ++ i ) {
+                    sc_trace_params* p = (*m_traces)[i];
+                    sc_trace( p->tf, read(), p->name );
+                }
+                remove_traces();
+            }
+        }
+
+    virtual inline const char* kind() const
+        { return "sc_inout"; }
+
+    // value initialization
+
+    inline void initialize( const sc_dt::sc_bigint<W>& value_ )
+    {
+        inout_if_type* iface = dynamic_cast<inout_if_type*>( this->get_interface() );
+        if( iface != 0 ) {
+            iface->write( value_ );
+        } else {
+            if( m_init_val_p == 0 ) {
+                m_init_val_p = new sc_dt::sc_bigint<W>;
+            }
+            *m_init_val_p = value_;
+        }
+    }
+
+
+    // called by sc_trace
+    void add_trace( sc_trace_file* tf_, const std::string& name_ ) const
+        {
+            if( tf_ != 0 ) {
+                if( m_traces == 0 ) {
+                    m_traces = new sc_trace_params_vec;
+                }
+                m_traces->push_back( new sc_trace_params( tf_, name_ ) );
+            }
+        }
+
+
+    // concatenation methods
+
+    virtual inline int concat_length(bool* xz_present_p) const
+        { return (*this)->read().concat_length( xz_present_p ); }
+    virtual inline sc_dt::uint64 concat_get_uint64() const
+        { return (*this)->read().concat_get_uint64(); }
+    virtual inline bool concat_get_ctrl( sc_dt::sc_digit* dst_p, int low_i ) const
+        { return (*this)->read().concat_get_ctrl(dst_p, low_i); }
+    virtual inline bool concat_get_data( sc_dt::sc_digit* dst_p, int low_i ) const
+        { return (*this)->read().concat_get_data(dst_p, low_i); }
+    virtual inline void concat_set(sc_dt::int64 src, int low_i)
+               { *this = (src >> ((low_i < 64) ? low_i : 63)); }
+#if 0 // ####
+    virtual inline void concat_set(const sc_dt::sc_lv_base& src, int low_i)
+        { *this = src >> low_i; }
+#endif // 0 ####
+    virtual inline void concat_set(const sc_dt::sc_signed& src, int low_i)
+        { *this = (src >> low_i); }
+    virtual inline void concat_set(const sc_dt::sc_unsigned& src, int low_i)
+        { *this = (src >> low_i); }
+    virtual inline void concat_set(sc_dt::uint64 src, int low_i)
+        { *this = ((low_i < 64) ? (src >> low_i) : (sc_dt::uint64)0); }
+
+
+  public: // assignment operators:
+    inline void operator = ( const this_type& new_val )
+        { (*this)->write( new_val.read() ); }
+    inline void operator = ( const char* new_val )
+        { sc_dt::sc_signed aa(W); aa = new_val; (*this)->write( aa ); }
+    inline void operator = ( sc_dt::uint64 new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( sc_dt::int64 new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( int new_val )
+        { (*this)->write((sc_dt::int64)new_val); }
+    inline void operator = ( long new_val )
+        { (*this)->write((sc_dt::int64)new_val); }
+    inline void operator = ( short new_val )
+        { (*this)->write((sc_dt::int64)new_val); }
+    inline void operator = ( unsigned int new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned long new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned short new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    template<typename T>
+    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val )
+        {
+            sc_dt::sc_unsigned temp(W);
+            new_val->to_sc_unsigned(temp);
+            (*this)->write(temp);
+        }
+    inline void operator = ( const sc_dt::sc_signed& new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( const sc_dt::sc_unsigned& new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( const sc_dt::sc_bv_base& new_val )
+        { (*this)->write((sc_dt::sc_bigint<W>)new_val); }
+    inline void operator = ( const sc_dt::sc_lv_base& new_val )
+        { (*this)->write((sc_dt::sc_bigint<W>)new_val); }
+
+    inline void write( const sc_in<sc_dt::sc_bigint<W> >& new_val )
+        { (*this)->write( new_val.read() ); }
+    inline void write( const sc_inout<sc_dt::sc_bigint<W> >& new_val )
+        { (*this)->write( new_val.read() ); }
+    inline void write( const sc_dt::sc_bigint<W>& new_val )
+        { (*this)->write( new_val); }
+
+  protected:
+    void remove_traces() const
+        {
+            if( m_traces != 0 ) {
+                for( int i = m_traces->size() - 1; i >= 0; -- i ) {
+                    delete (*m_traces)[i];
+                }
+                delete m_traces;
+                m_traces = 0;
+            }
+        }
+
+    sc_dt::sc_bigint<W>*                m_init_val_p;
+    mutable sc_trace_params_vec* m_traces;
+
+
+  private:
+
+    // disabled
+    sc_inout( const sc_inout<sc_dt::sc_bigint<W> >& );
+
+#ifdef __GNUC__
+    // Needed to circumvent a problem in the g++-2.95.2 compiler:
+    // This unused variable forces the compiler to instantiate
+    // an object of T template so an implicit conversion from
+    // read() to a C++ intrinsic data type will work.
+    static data_type dummy;
+#endif
+
+};
+
+
+
+SC_TEMPLATE
+inline std::ostream& operator << (
+       std::ostream& os, const sc_inout<sc_dt::sc_bigint<W> >& a )
+{
+    a.read().print( os );
+    return os;
+}
+
+
+//==============================================================================
+// CLASS sc_out<sc_dt::sc_bigint<W> >
+//
+// This class implements an output port whose target acts like an
+// sc_dt::sc_bigint<W> data value. This class is a derivation of sc_inout, since
+// output ports are really no different from input/output ports.
+//==============================================================================
+SC_TEMPLATE
+class sc_out<sc_dt::sc_bigint<W> > : public sc_inout<sc_dt::sc_bigint<W> >
+{
+  public:
+
+    // typedefs
+
+    typedef sc_dt::sc_bigint<W>                          data_type;
+
+    typedef sc_out<data_type>                   this_type;
+    typedef sc_inout<data_type>                 base_type;
+
+    typedef typename base_type::inout_if_type   inout_if_type;
+    typedef typename base_type::inout_port_type inout_port_type;
+
+    // constructors
+
+    sc_out()
+        : base_type()
+        {}
+
+    explicit sc_out( const char* name_ )
+        : base_type( name_ )
+        {}
+
+    explicit sc_out( inout_if_type& interface_ )
+        : base_type( interface_ )
+        {}
+
+    sc_out( const char* name_, inout_if_type& interface_ )
+        : base_type( name_, interface_ )
+        {}
+
+    explicit sc_out( inout_port_type& parent_ )
+        : base_type( parent_ )
+        {}
+
+    sc_out( const char* name_, inout_port_type& parent_ )
+        : base_type( name_, parent_ )
+        {}
+
+    sc_out( this_type& parent_ )
+        : base_type( parent_ )
+        {}
+
+    sc_out( const char* name_, this_type& parent_ )
+        : base_type( name_, parent_ )
+        {}
+
+
+    // destructor (does nothing)
+
+    virtual inline ~sc_out()
+        {}
+
+
+    // assignment operators:
+
+  public:
+    inline void operator = ( const this_type& new_val )
+        { (*this)->write( (const sc_dt::sc_signed&)new_val ); }
+    inline void operator = ( const char* new_val )
+        { sc_dt::sc_signed aa(W); aa = new_val; (*this)->write( aa ); }
+    inline void operator = ( sc_dt::uint64 new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( sc_dt::int64 new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( int new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( long new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( short new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned int new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned long new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned short new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    template<typename T>
+    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val )
+        {
+            sc_dt::sc_unsigned temp(W);
+            new_val->to_sc_unsigned(temp);
+            (*this)->write(temp);
+        }
+    inline void operator = ( const sc_dt::sc_signed& new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( const sc_dt::sc_unsigned& new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( const sc_dt::sc_bv_base& new_val )
+        { (*this)->write((sc_dt::sc_bigint<W>)new_val); }
+    inline void operator = ( const sc_dt::sc_lv_base& new_val )
+        { (*this)->write((sc_dt::sc_bigint<W>)new_val); }
+
+  private:
+
+    // disabled
+    sc_out( const this_type& );
+};
+
+
+
+//------------------------------------------------------------------------------
+//"sc_signed_sigref::initialize"
+//
+// This method initializes an object instance from the supplied arguments.
+//     if_p   -> target of this selection.
+//     left_  =  left-most bit in selection.
+//     right_ =  right-most bit in selection.
+//------------------------------------------------------------------------------
+inline void sc_signed_sigref::initialize(
+       sc_signed_part_if* if_p, int left_, int right_ )
+{
+    m_if_p = if_p;
+    m_left = left_;
+    m_right = right_;
+       m_obj_p = if_p->part_read_target();
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_signed_sigref::operator ="
+//
+// These operators assign a value to the bits associated with this object
+// instance within this object instance's target signal.
+//------------------------------------------------------------------------------
+inline void sc_signed_sigref::operator = ( sc_dt::uint64 v )
+{
+       m_if_p->write_part( v, m_left, m_right );
+}
+
+inline void sc_signed_sigref::operator = ( const char* v )
+{
+       sc_dt::sc_signed tmp(length()); tmp = v; *this = tmp;
+}
+
+inline void sc_signed_sigref:: operator = ( sc_dt::int64 v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+inline void sc_signed_sigref:: operator = ( int v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+inline void sc_signed_sigref:: operator = ( long v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+inline void sc_signed_sigref:: operator = ( unsigned int v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+inline void sc_signed_sigref:: operator = ( unsigned long v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+template<typename T>
+inline void sc_signed_sigref:: operator = ( const sc_dt::sc_generic_base<T>& v )
+{
+    sc_dt::sc_unsigned temp(m_left-m_right+1);
+    v->to_sc_unsigned(temp);
+    m_if_p->write_part( temp, m_left, m_right );
+}
+
+inline void sc_signed_sigref:: operator = ( const sc_dt::sc_signed& v )
+{
+    m_if_p->write_part( v, m_left, m_right );
+}
+
+inline void sc_signed_sigref:: operator = ( const sc_dt::sc_unsigned& v )
+{
+    m_if_p->write_part( v, m_left, m_right );
+}
+
+void sc_signed_sigref::operator = ( const sc_signed_sigref& v )
+{
+    *this = (sc_dt::sc_unsigned)v;
+}
+
+
+#undef SC_TEMPLATE
+} // namespace sc_core
+#endif // !defined(SC_SIGNAL_SIGNED_H)
+
+namespace sc_core {
+
+extern
+void
+sc_signal_invalid_writer( const char* name,
+                          const char* kind,
+                          const char* first_writer,
+                          const char* second_writer );
+
+//------------------------------------------------------------------------------
+// POOL OF TEMPORARY INSTANCES OF sc_signed_sigref
+//
+// This allows use to pass const references for part and bit selections
+// on sc_signal_signed object instances.
+//------------------------------------------------------------------------------
+sc_vpool<sc_signed_sigref> sc_signed_sigref::m_pool(8);
+
+
+//------------------------------------------------------------------------------
+//"sc_signed_part_if::default methods"
+//
+// These versions just produce errors if they are not overloaded but used.
+//------------------------------------------------------------------------------
+
+sc_signed* sc_signed_part_if::part_read_target()
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+    return 0;
+}
+sc_signed sc_signed_part_if::read_part( int /*left*/, int /*right*/ ) const
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+    return sc_signed(1);
+}
+sc_signed_sigref& sc_signed_part_if::select_part( int /*left*/, int /*right*/ )
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+    return *(sc_signed_sigref*)0;
+}
+void sc_signed_part_if::write_part( int64 v, int /*left*/, int /*right*/ )
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+}
+void sc_signed_part_if::write_part( uint64 v, int /*left*/, int /*right*/ )
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+}
+void sc_signed_part_if::write_part(
+    const sc_signed& v, int /*left*/, int /*right*/ )
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+}
+void sc_signed_part_if::write_part(
+    const sc_unsigned& v, int /*left*/, int /*right*/ )
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_signed_sigref::concate_set"
+//
+// These methods assign this object instance's value from the supplied
+// value starting at the supplied bit within that value.
+//     src = value to use to set this object instance's value.
+//     low_i = bit in src that is to be the low order bit of the value to set.
+// #### OPTIMIZE
+//------------------------------------------------------------------------------
+void sc_signed_sigref::concat_set(sc_dt::int64 src, int low_i)
+{
+       int64 tmp;
+       if ( low_i < 63 )
+               tmp = src >> low_i;
+       else
+               tmp = (src < 0) ? -1 : 0;
+       m_if_p->write_part( tmp, m_left, m_right );
+}
+
+
+void sc_signed_sigref::concat_set(const sc_signed& src, int low_i)
+{
+       m_if_p->write_part( src >> low_i, m_left, m_right );
+}
+
+
+void sc_signed_sigref::concat_set(const sc_lv_base& src, int low_i)
+{
+       sc_unsigned tmp(src.length());
+       tmp = src;
+       m_if_p->write_part( tmp >> low_i, m_left, m_right );
+}
+
+
+void sc_signed_sigref::concat_set(const sc_unsigned& src, int low_i)
+{
+       m_if_p->write_part( src >> low_i, m_left, m_right );
+}
+
+
+void sc_signed_sigref::concat_set(sc_dt::uint64 src, int low_i)
+{
+       uint64 tmp = (low_i < 63) ? (src >> low_i) : 0;
+       m_if_p->write_part( tmp, m_left, m_right );
+}
+
+} // namespace sc_core
diff --git a/src/systemc/tests/include/specialized_signals/scx_signal_uint.h b/src/systemc/tests/include/specialized_signals/scx_signal_uint.h
new file mode 100644 (file)
index 0000000..acc4a42
--- /dev/null
@@ -0,0 +1,1676 @@
+/*****************************************************************************
+
+  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.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  sc_signal_uint.cpp -- The sc_signal<sc_dt::sc_uint<W> > implementations.
+
+  Original Author: Andy Goodrich, Forte Design Systems, 2002-10-22
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+  changes you are making here.
+
+      Name, Affiliation, Date:
+  Description of Modification:
+
+ *****************************************************************************/
+
+/*
+$Log: scx_signal_uint.h,v $
+Revision 1.1  2011/08/15 17:31:11  acg
+ Andy Goodrich: moved specialized signals from examples to this tree.
+
+Revision 1.2  2011/08/15 16:43:24  acg
+ Torsten Maehne: changes to remove unused argument warnings.
+
+Revision 1.1.1.1  2006/12/15 20:20:03  acg
+SystemC 2.3
+
+Revision 1.2  2005/12/26 20:11:14  acg
+Fixed up copyright.
+
+Revision 1.1.1.1  2005/12/19 23:16:42  acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.16  2005/09/15 23:01:52  acg
+Added std:: prefix to appropriate methods and types to get around
+issues with the Edison Front End.
+
+Revision 1.15  2005/05/03 19:52:26  acg
+Get proper header locations on includes.
+
+Revision 1.14  2005/05/03 19:50:20  acg
+Name space version.
+
+Revision 1.11  2005/04/11 19:05:36  acg
+Change to sc_clock for Microsoft VCC 6.0. Changes for namespaces
+
+Revision 1.10  2005/04/03 22:52:52  acg
+Namespace changes.
+
+Revision 1.9  2005/03/21 22:31:32  acg
+Changes to sc_core namespace.
+
+Revision 1.8  2004/09/27 21:01:59  acg
+Andy Goodrich - Forte Design Systems, Inc.
+   - This is specialized signal support that allows better use of signals
+     and ports whose target value is a SystemC native type.
+
+*/
+
+
+
+#include <systemc>
+#include <typeinfo>
+
+/*****************************************************************************
+
+  sc_signal_uint.h -- The sc_signal<sc_uint<W> > definitions.
+
+  Original Author: Andy Goodrich, Forte Design Systems, 2002-10-22
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+  changes you are making here.
+
+      Name, Affiliation, Date:
+  Description of Modification:
+
+ *****************************************************************************/
+
+/*
+$Log: scx_signal_uint.h,v $
+Revision 1.1  2011/08/15 17:31:11  acg
+ Andy Goodrich: moved specialized signals from examples to this tree.
+
+Revision 1.3  2011/08/15 16:43:24  acg
+ Torsten Maehne: changes to remove unused argument warnings.
+
+Revision 1.2  2011/06/28 21:23:02  acg
+ Andy Goodrich: merging of SCV tree.
+
+Revision 1.1.1.1  2006/12/15 20:20:03  acg
+SystemC 2.3
+
+Revision 1.4  2006/04/05 23:47:02  acg
+  Andy Goodrich: changed sc_get_current_process_base calls into
+    sc_get_current_process_b calls.
+
+Revision 1.3  2006/03/21 01:31:48  acg
+ Andy Goodrich: changed over to sc_get_current_process_b() from
+ sc_get_current_process_base() since the function's name changed.
+
+Revision 1.2  2005/12/26 20:11:14  acg
+Fixed up copyright.
+
+Revision 1.1.1.1  2005/12/19 23:16:42  acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.27  2005/09/15 23:01:52  acg
+Added std:: prefix to appropriate methods and types to get around
+issues with the Edison Front End.
+
+Revision 1.26  2005/07/30 03:44:11  acg
+Changes from 2.1.
+
+Revision 1.25  2005/06/10 22:40:55  acg
+Changes from 2.1 for operator << and other iostream stuff.
+
+Revision 1.24  2005/05/09 17:17:12  acg
+Changes from 2.1.
+
+Revision 1.23  2005/05/08 19:04:06  acg
+Fix bug in concat_set(int64,off). Other changes from 2.1 examples usage.
+
+Revision 1.22  2005/05/03 19:50:20  acg
+Name space version.
+
+Revision 1.20  2005/03/21 22:31:32  acg
+Changes to sc_core namespace.
+
+Revision 1.18  2004/11/09 00:11:27  acg
+Added support for sc_generic_base<T> in place of sc_concatref. sc_concatref
+now is derived from sc_generic_base<sc_concatref>.
+
+Revision 1.17  2004/09/27 21:01:59  acg
+Andy Goodrich - Forte Design Systems, Inc.
+   - This is specialized signal support that allows better use of signals
+     and ports whose target value is a SystemC native type.
+
+*/
+
+
+#if !defined(SC_SIGNAL_UINT_H)
+#define SC_SIGNAL_UINT_H
+
+#if ( !defined(_MSC_VER) || _MSC_VER > 1200 )
+#    define SC_TEMPLATE template<int W>
+#else
+#    define SC_TEMPLATE template<> template<int W>
+#endif
+
+// FORWARD REFERENCES AND USINGS:
+
+namespace sc_core {
+
+class sc_uint_sigref;
+
+//==============================================================================
+// CLASS sc_uint_part_if
+//
+// This class provides generic access to part selections for signals whose
+// data type is sc_dt::sc_uint<W>. This class serves as the base class for the
+// sc_dt::sc_uint<W> specialization of the sc_signal_in_if<T> class. The methods
+// in this class may be over-ridden individually, those that are not overridden
+// will produce an error message when called. The methods are used by the
+// sc_uint_sigref class.
+//
+// Notes:
+//   (1) Descriptions of the methods and operators in this class appear with
+//       their implementations in sc_signal<sc_dt::sc_uint<W> >.
+//==============================================================================
+class sc_uint_part_if : virtual public sc_interface {
+  protected:
+       // constructor:
+       sc_uint_part_if() {}
+
+  public:
+    // perform a part read.
+       virtual sc_dt::sc_uint_base* part_read_target();
+       virtual sc_dt::uint64 read_part( int left, int right ) const;
+
+    // perform a part write.
+       virtual sc_uint_sigref& select_part( int left, int right );
+       virtual void write_part( sc_dt::uint64 v, int left, int right );
+
+  private:
+       sc_uint_part_if( const sc_uint_part_if& );
+       sc_uint_part_if& operator = ( const sc_uint_part_if& );
+};
+
+
+//==============================================================================
+// CLASS sc_signal_in_if<sc_dt::sc_uint<W> >
+//
+// This is the class specializations for the sc_signal_in_if<T> class to
+// provide additional features for sc_signal instances whose template is
+// sc_dt::sc_uint<W>, including part access.
+//
+// Notes:
+//   (1) Descriptions of the methods and operators in this class appear with
+//       their implementations in sc_signal<sc_dt::sc_uint<W> >.
+//==============================================================================
+template< int W >
+class sc_signal_in_if<sc_dt::sc_uint<W> > : public sc_uint_part_if {
+       friend class sc_uint_sigref;
+  public:
+    typedef sc_signal_in_if<sc_dt::sc_uint<W> > this_type;
+
+    // get the value changed event
+    virtual const sc_event& value_changed_event() const = 0;
+
+
+    // read the current value
+    virtual const sc_dt::sc_uint<W>& read() const = 0;
+
+    // get a reference to the current value (for tracing)
+    virtual const sc_dt::sc_uint<W>& get_data_ref() const = 0;
+
+
+    // was there a value changed event?
+    virtual bool event() const = 0;
+
+  protected:
+    // constructor
+    sc_signal_in_if()
+    {}
+
+  private: // disabled
+    sc_signal_in_if( const this_type& );
+    this_type& operator = ( const this_type& );
+};
+
+//=============================================================================
+//  CLASS : sc_uint_sigref
+//
+//  Proxy class for sc_signal_uint bit and part selection.
+//=============================================================================
+class sc_uint_sigref : public sc_dt::sc_uint_subref_r
+{
+  public:
+    sc_uint_sigref() : sc_dt::sc_uint_subref_r() {}
+    virtual ~sc_uint_sigref() {}
+    virtual void concat_set(sc_dt::int64 src, int low_i);
+    virtual void concat_set(const sc_dt::sc_signed& src, int low_i);
+    virtual void concat_set(const sc_dt::sc_unsigned& src, int low_i);
+    virtual void concat_set(const sc_dt::sc_lv_base& src, int low_i);
+    virtual void concat_set(sc_dt::uint64 src, int low_i);
+
+  public:
+    inline void initialize( sc_uint_part_if* if_p, int left_, int right_ );
+
+  public:
+    inline void operator = ( sc_dt::uint64 v );
+    inline void operator = ( const char* v );
+    inline void operator = ( unsigned long v );
+    inline void operator = ( long v );
+    inline void operator = ( unsigned int v );
+    inline void operator = ( int v );
+    inline void operator = ( sc_dt::int64 v );
+    inline void operator = ( double v );
+    inline void operator = ( const sc_uint_sigref& v );
+    template<typename T>
+    inline void operator = ( const sc_dt::sc_generic_base<T>& v );
+    inline void operator = ( const sc_dt::sc_signed& v );
+    inline void operator = ( const sc_dt::sc_unsigned& v );
+    inline void operator = ( const sc_dt::sc_bv_base& v );
+    inline void operator = ( const sc_dt::sc_lv_base& v );
+
+  public:
+    static sc_vpool<sc_uint_sigref> m_pool; // Pool of objects to use.
+
+  protected:
+    sc_uint_part_if*                m_if_p; // Target for selection.
+
+  private:
+
+    // disabled
+    sc_uint_sigref( const sc_uint_sigref& a );
+};
+
+
+//==============================================================================
+// CLASS sc_signal<sc_dt::sc_uint<W> >
+//
+// This class implements a signal whose value acts like an sc_dt::sc_uint<W> data
+// value. This class is a specialization of the generic sc_signal class to
+// implement tailored support for the sc_dt::sc_uint<W> class.
+//
+// Notes:
+//   (1) Descriptions of the methods and operators in this class appear with
+//       their implementations.
+//==============================================================================
+SC_TEMPLATE
+class sc_signal<sc_dt::sc_uint<W> > :
+    public sc_signal_inout_if<sc_dt::sc_uint<W> >,
+       public sc_prim_channel,
+    public sc_dt::sc_uint<W>
+{
+  public: // typedefs
+    typedef sc_signal<sc_dt::sc_uint<W> > this_type;
+
+  public: // constructors and destructor:
+    inline sc_signal();
+    explicit inline sc_signal(const char* name_);
+    virtual inline ~sc_signal();
+
+  public: // base methods:
+    inline bool base_event() const;
+    inline const sc_dt::sc_uint<W>& base_read() const;
+    inline const sc_event& base_value_changed_event() const;
+    inline void base_write( sc_dt::uint64 value );
+
+  public: // sc_prim_channel virtual methods:
+    virtual inline const char* kind() const;
+    virtual inline void update();
+
+  public: // sc_interface virtual methods:
+    virtual inline const sc_event& default_event() const;
+    virtual inline void register_port(
+               sc_port_base& port_, const char* if_typename_ );
+
+  public: // sc_uint_channel virtual methods:
+       virtual sc_dt::sc_uint_base* part_read_target();
+    virtual inline sc_dt::uint64 read_part(int left, int right) const;
+       virtual inline sc_uint_sigref& select_part(int left, int right);
+       virtual inline void write_part(sc_dt::uint64 v, int left, int right);
+
+  public: // interface virtual methods:
+    virtual inline bool event() const;
+    virtual inline const sc_dt::sc_uint<W>& get_data_ref() const;
+    // virtual inline sc_signal<sc_dt::sc_uint<W> >& get_signal() ;
+    virtual inline const sc_dt::sc_uint<W>& read() const;
+    virtual inline const sc_event& value_changed_event() const;
+    virtual inline void write( const sc_in<sc_dt::sc_uint<W> >& value );
+    virtual inline void write( const sc_inout<sc_dt::sc_uint<W> >& value );
+    virtual inline void write( const sc_dt::sc_uint<W>& value );
+
+  public: // part selections:
+       inline sc_uint_sigref& operator () ( int left, int right );
+       inline sc_uint_sigref& operator [] ( int bit );
+
+  public: // operators:
+    inline void operator = ( const this_type& new_val );
+    inline void operator = ( const char* new_val );
+    inline void operator = ( sc_dt::uint64 new_val );
+    inline void operator = ( sc_dt::int64 new_val );
+    inline void operator = ( int new_val );
+    inline void operator = ( long new_val ) ;
+    inline void operator = ( short new_val ) ;
+    inline void operator = ( unsigned int new_val ) ;
+    inline void operator = ( unsigned long new_val );
+    inline void operator = ( unsigned short new_val );
+    template<typename T>
+    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val );
+    inline void operator = ( const sc_dt::sc_signed& new_val );
+    inline void operator = ( const sc_dt::sc_unsigned& new_val );
+    inline void operator = ( const sc_dt::sc_bv_base& new_val );
+    inline void operator = ( const sc_dt::sc_lv_base& new_val );
+
+  public: // concatenation methods (we inherit length and gets from sc_dt::sc_uint<W>):
+    virtual inline void concat_set(sc_dt::int64 src, int low_i);
+    virtual inline void concat_set(const sc_dt::sc_lv_base& src, int low_i);
+    virtual inline void concat_set(const sc_dt::sc_signed& src, int low_i);
+    virtual inline void concat_set(const sc_dt::sc_unsigned& src, int low_i);
+    virtual inline void concat_set(sc_dt::uint64 src, int low_i);
+
+  protected: // debugging methods:
+    // #### void check_port();
+       void check_writer();
+
+  private: // Disabled operations that sc_dt::sc_uint<W> supports:
+       sc_signal<sc_dt::sc_uint<W> >& operator ++ ();          // prefix
+       const sc_signal<sc_dt::sc_uint<W> >& operator ++ (int); // postfix
+       sc_signal<sc_dt::sc_uint<W> >& operator -- ();          // prefix
+       const sc_signal<sc_dt::sc_uint<W> >& operator -- (int); // postfix
+    sc_signal<sc_dt::sc_uint<W> >& operator += (sc_dt::uint_type);
+    sc_signal<sc_dt::sc_uint<W> >& operator -= (sc_dt::uint_type);
+    sc_signal<sc_dt::sc_uint<W> >& operator *= (sc_dt::uint_type);
+    sc_signal<sc_dt::sc_uint<W> >& operator /= (sc_dt::uint_type);
+    sc_signal<sc_dt::sc_uint<W> >& operator %= (sc_dt::uint_type);
+    sc_signal<sc_dt::sc_uint<W> >& operator &= (sc_dt::uint_type);
+    sc_signal<sc_dt::sc_uint<W> >& operator |= (sc_dt::uint_type);
+    sc_signal<sc_dt::sc_uint<W> >& operator ^= (sc_dt::uint_type);
+
+  protected:
+    mutable sc_event* m_changed_event_p; // Value changed event this object.
+    sc_dt::uint64     m_event_delta;     // Delta cycle of last event.
+    sc_dt::uint64     m_new_val;         // New value for this object instance.
+    sc_port_base*     m_output_p;        // Single write port verify field.
+    sc_process_b*  m_writer_p;        // Single writer verify field.
+};
+
+
+SC_TEMPLATE // Return true if a changed event happened in the last delta cycle.
+inline bool sc_signal<sc_dt::sc_uint<W> >::base_event() const
+{
+    return simcontext()->delta_count() == m_event_delta + 1;
+}
+
+
+SC_TEMPLATE // Return this object's sc_dt::sc_uint<W> object instance.
+inline const sc_dt::sc_uint<W>& sc_signal<sc_dt::sc_uint<W> >::base_read() const
+{
+       return *this;
+}
+
+
+SC_TEMPLATE // Return the value changed event, allocating it if necessary.
+inline const sc_event& sc_signal<sc_dt::sc_uint<W> >::base_value_changed_event() const
+{
+    if ( !m_changed_event_p ) m_changed_event_p = new sc_event;
+    return *m_changed_event_p;
+}
+
+
+SC_TEMPLATE // Write an sc_dt::uint64 value to this object instance.
+inline void sc_signal<sc_dt::sc_uint<W> >::base_write( sc_dt::uint64 value )
+{
+#   if defined(DEBUG_SYSTEMC)
+        check_writer();
+#   endif
+    m_new_val = value;
+    request_update();
+}
+
+//------------------------------------------------------------------------------
+//"sc_signal<sc_dt::sc_uint<W> >::check_writer"
+//
+// This method checks to see if there is more than one writer for this
+// object instance by keeping track of the process performing the write.
+//------------------------------------------------------------------------------
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::check_writer()
+{
+    sc_process_b* writer_p = sc_get_current_process_b();
+    if( m_writer_p == 0 )
+    {
+        m_writer_p = writer_p;
+    }
+    else if( m_writer_p != writer_p )
+    {
+        sc_signal_invalid_writer( name(), kind(),
+                                  m_writer_p->name(), writer_p->name() );
+    }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_signal<sc_dt::sc_uint<W> >::concat_set"
+//
+// These virtual methods allow value assignments to this object instance
+// from various sources. The position within the supplied source of the
+// low order bit for this object instance's value is low_i.
+//     src   = source value.
+//     low_i = bit within src to serve as low order bit of this object
+//             instance's value.
+//------------------------------------------------------------------------------
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::concat_set(
+    sc_dt::int64 src, int low_i)
+{
+    if ( low_i < 64 )
+    {
+        base_write(src >> low_i);
+    }
+    else
+    {
+        base_write( (src < 0 ) ? src >> 63 : 0 );
+    }
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::concat_set(
+    const sc_dt::sc_lv_base& src, int low_i)
+{
+    sc_dt::sc_unsigned tmp(src.length());
+    tmp = src >> low_i;
+    base_write( tmp.to_uint64() );
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::concat_set(
+    const sc_dt::sc_signed& src, int low_i)
+{
+    base_write( (src >> low_i).to_uint64());
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::concat_set(
+    const sc_dt::sc_unsigned& src, int low_i)
+{
+    base_write( (src >> low_i).to_uint64());
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::concat_set(
+    sc_dt::uint64 src, int low_i)
+{
+    base_write( ( low_i < 64 ) ? src >> low_i : 0 );
+}
+
+
+
+SC_TEMPLATE // Return the default event for this object instance.
+inline const sc_event& sc_signal<sc_dt::sc_uint<W> >::default_event() const
+       { return base_value_changed_event(); }
+
+
+SC_TEMPLATE // Return true if a changed event happened in the last delta cycle.
+inline bool sc_signal<sc_dt::sc_uint<W> >::event() const
+       { return base_event(); }
+
+
+SC_TEMPLATE // Return a reference to the value of this object instance.
+inline const sc_dt::sc_uint<W>&
+sc_signal<sc_dt::sc_uint<W> >::get_data_ref() const
+       { return *this; }
+
+
+#if 0
+SC_TEMPLATE // Return a pointer to this object instance.
+inline sc_signal<sc_dt::sc_uint<W> >& sc_signal<sc_dt::sc_uint<W> >::get_signal()
+       { return *this; }
+#endif // 0
+
+
+SC_TEMPLATE // Return a kind value of "sc_signal".
+inline const char* sc_signal<sc_dt::sc_uint<W> >::kind() const
+{
+       return "sc_signal";
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_signal_uint::operator ()
+//
+// This operator returns a part selection of this object instance.
+//     left  = left-hand bit of the selection.
+//     right = right-hand bit of the selection.
+//------------------------------------------------------------------------------
+SC_TEMPLATE
+inline sc_uint_sigref& sc_signal<sc_dt::sc_uint<W> >::operator ()
+    (int left, int right)
+{
+    sc_uint_sigref* result_p;   // Value to return.
+
+       result_p = sc_uint_sigref::m_pool.allocate();
+       result_p->initialize(this, left, right);
+       return *result_p;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_signal_uint::operator []"
+//
+// This operator returns a bit selection of this object instance.
+//     i = bit to be selected.
+//------------------------------------------------------------------------------
+SC_TEMPLATE
+inline sc_uint_sigref& sc_signal<sc_dt::sc_uint<W> >::operator [] ( int bit )
+{
+    return operator () (bit,bit);
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::operator = (
+    const this_type& new_val )
+       { base_write( (sc_dt::uint64)new_val ); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::operator = ( sc_dt::uint64 new_val )
+       { base_write(new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::operator = ( const char* new_val )
+       { m_new_val = sc_dt::sc_uint<64>(new_val); request_update(); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::operator = ( sc_dt::int64 new_val )
+       { base_write((sc_dt::uint64)new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::operator = ( int new_val )
+       { base_write((sc_dt::uint64)new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::operator = ( long new_val )
+       { base_write((sc_dt::uint64)new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::operator = ( short new_val )
+       { base_write((sc_dt::uint64)new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::operator = ( unsigned int new_val )
+       { base_write((sc_dt::uint64)new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::operator = ( unsigned long new_val )
+       { base_write((sc_dt::uint64)new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::operator = ( unsigned short new_val )
+       { base_write((sc_dt::uint64)new_val); }
+
+
+SC_TEMPLATE
+template<typename T>
+inline void sc_signal<sc_dt::sc_uint<W> >::operator = (
+       const sc_dt::sc_generic_base<T>& new_val )
+       { base_write(new_val->to_uint64()); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::operator = (
+    const sc_dt::sc_signed& new_val )
+       { base_write(new_val.to_uint64()); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::operator = (
+    const sc_dt::sc_unsigned& new_val )
+       { base_write(new_val.to_uint64()); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::operator = (
+    const sc_dt::sc_bv_base& new_val )
+       { base_write( (sc_dt::sc_uint<W>)new_val ); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::operator = (
+    const sc_dt::sc_lv_base& new_val )
+       { base_write( (sc_dt::sc_uint<W>)new_val ); }
+
+
+SC_TEMPLATE
+inline sc_dt::sc_uint_base* sc_signal<sc_dt::sc_uint<W> >::part_read_target()
+    { return this; }
+
+
+SC_TEMPLATE
+inline const sc_dt::sc_uint<W>& sc_signal<sc_dt::sc_uint<W> >::read() const
+       { return *this; }
+
+
+SC_TEMPLATE // Read a portion of a value.
+inline sc_dt::uint64 sc_signal<sc_dt::sc_uint<W> >::read_part( int left, int right ) const
+{
+       // This pointer required for HP aCC.
+    return (this->m_val & ~sc_dt::mask_int[left][right]) >> right;
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_uint<W> >::register_port(
+       sc_port_base& port_, const char* if_typename_ )
+{
+#       ifdef DEBUG_SYSTEMC
+               std::string nm( if_typename_ );
+               if( nm == typeid( sc_signal_inout_if<sc_dt::sc_uint<W> > ).name() )
+               {
+                       if( m_output_p != 0 )
+                       {
+                               sc_signal_invalid_writer( name(), kind(),
+                                        m_output_p->name(), port_.name() );
+                       }
+                       m_output_p = &port_;
+               }
+#       else
+            if ( &port_ && if_typename_ ) {} // Silence unused args warning.
+#       endif
+}
+
+
+SC_TEMPLATE // Autogenerated name object instance constructor.
+inline sc_signal<sc_dt::sc_uint<W> >::sc_signal() :
+       sc_prim_channel(sc_gen_unique_name( "signal" )),
+       m_changed_event_p(0),
+       m_output_p(0),
+       m_writer_p(0)
+{ }
+
+
+SC_TEMPLATE // Explicitly named object instance constructor.
+inline sc_signal<sc_dt::sc_uint<W> >::sc_signal(const char* name_) :
+       sc_prim_channel(name_),
+       m_changed_event_p(0),
+       m_output_p(0),
+       m_writer_p(0)
+{ }
+
+
+SC_TEMPLATE // Object instance destructor.
+inline sc_signal<sc_dt::sc_uint<W> >::~sc_signal()
+{
+       if ( m_changed_event_p ) delete m_changed_event_p;
+}
+
+
+SC_TEMPLATE // Update the current value from new value.
+inline void sc_signal<sc_dt::sc_uint<W> >::update()
+{
+    if ( m_changed_event_p )
+    {
+               // This pointer required for HP aCC.
+        sc_dt::uint64 old_val = this->m_val;
+               sc_dt::sc_uint_base::operator = (m_new_val);
+        if ( old_val != this->m_val )
+        {
+            m_changed_event_p->notify_delayed();
+            m_event_delta = simcontext()->delta_count();
+        }
+    }
+    else
+    {
+               sc_dt::sc_uint_base::operator = (m_new_val);
+    }
+}
+
+
+SC_TEMPLATE // Return the value changed event.
+inline const sc_event& sc_signal<sc_dt::sc_uint<W> >::value_changed_event() const
+       { return base_value_changed_event(); }
+
+
+SC_TEMPLATE // Write a sc_in<sc_dt::sc_uint<W> > value to this object instance.
+inline void sc_signal<sc_dt::sc_uint<W> >::write( const sc_in<sc_dt::sc_uint<W> >& value )
+       { base_write( value.operator sc_dt::uint64 () ); }
+
+
+SC_TEMPLATE // Write a sc_inout<sc_dt::sc_uint<W> > value to this object instance.
+inline void sc_signal<sc_dt::sc_uint<W> >::write( const sc_inout<sc_dt::sc_uint<W> >& value )
+       { base_write( value.operator sc_dt::uint64 () ); }
+
+
+SC_TEMPLATE // Write a sc_dt::sc_uint<W> value to this object instance.
+inline void sc_signal<sc_dt::sc_uint<W> >::write(
+    const sc_dt::sc_uint<W>& value )
+       { base_write( value); }
+
+
+SC_TEMPLATE // Select a portion of a value.
+inline sc_uint_sigref& sc_signal<sc_dt::sc_uint<W> >::select_part(int left, int right)
+{
+       sc_uint_sigref* result_p = sc_uint_sigref::m_pool.allocate();
+       result_p->initialize(this, left, right);
+       return *result_p;
+}
+
+
+SC_TEMPLATE // Write a portion of a value. If this is the first write in
+            // a delta cycle we copy the existing value before setting the bits.
+inline void sc_signal<sc_dt::sc_uint<W> >::write_part( sc_dt::uint64 v, int left, int right )
+{
+    sc_dt::uint64 new_v;   // New value.
+    sc_dt::uint64 keep;    // Keep mask value.
+
+    keep = sc_dt::mask_int[left][right];
+    new_v = (m_new_val & keep) | ((v << right) & ~keep);
+    m_new_val = new_v;
+       request_update();
+}
+
+
+//==============================================================================
+// CLASS sc_in<sc_dt::sc_uint<W> >
+//
+// This class implements an input port whose target acts like an sc_dt::sc_uint<W> data
+// value. This class is a specialization of the generic sc_in class to
+// implement tailored support for the sc_dt::sc_uint<W> class.
+//==============================================================================
+SC_TEMPLATE
+class sc_in<sc_dt::sc_uint<W> > :
+    public sc_port<sc_signal_in_if<sc_dt::sc_uint<W> >, 1,
+                   SC_ONE_OR_MORE_BOUND>,
+    public sc_dt::sc_value_base
+{
+  public:
+
+    // typedefs
+
+    typedef sc_dt::sc_uint<W>                       data_type;
+    typedef sc_signal_in_if<sc_dt::sc_uint<W> >     if_type;
+    typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND> base_type;
+    typedef sc_in<sc_dt::sc_uint<W> >               this_type;
+
+    typedef if_type                                 in_if_type;
+    typedef base_type                               in_port_type;
+    typedef sc_signal_inout_if<sc_dt::sc_uint<W> >  inout_if_type;
+    typedef sc_inout<sc_dt::sc_uint<W> >            inout_port_type;
+
+  public:
+
+    // bind methods and operators:
+
+    void bind( const in_if_type& interface_ )
+        { sc_port_base::bind( const_cast<in_if_type&>( interface_) );}
+    void operator () ( const in_if_type& interface_ )
+        { sc_port_base::bind( const_cast<in_if_type&>( interface_) );}
+    void bind( in_port_type& parent_ )
+        { sc_port_base::bind(parent_);}
+    void operator () ( in_port_type& parent_ )
+        { sc_port_base::bind(parent_);}
+    void bind( inout_port_type& parent_ )
+        { sc_port_base::bind(parent_);}
+    void operator () ( inout_port_type& parent_ )
+        { sc_port_base::bind(parent_);}
+
+  protected:
+    // called by pbind (for internal use only)
+    virtual inline int vbind( sc_interface& interface_ )
+        {
+            return sc_port_b<if_type>::vbind( interface_ );
+        }
+    virtual inline int vbind( sc_port_base& parent_ )
+        {
+            in_port_type* in_parent = dynamic_cast<in_port_type*>( &parent_ );
+            if( in_parent != 0 ) {
+                sc_port_base::bind( *in_parent );
+                return 0;
+            }
+            inout_port_type* inout_parent = dynamic_cast<inout_port_type*>( &parent_ );
+            if( inout_parent != 0 ) {
+                sc_port_base::bind( *inout_parent );
+                return 0;
+            }
+            // type mismatch
+            return 2;
+        }
+
+
+    // constructors
+
+  public:
+    sc_in()
+        : base_type(), m_traces( 0 )
+        {}
+
+    explicit sc_in( const char* name_ )
+        : base_type( name_ ), m_traces( 0 )
+        {}
+
+    explicit sc_in( const in_if_type& interface_ )
+        : base_type( const_cast<in_if_type&>( interface_ ) ), m_traces( 0 )
+        {}
+
+    sc_in( const char* name_, const in_if_type& interface_ )
+        : base_type( name_, const_cast<in_if_type&>( interface_ ) ), m_traces( 0 )
+        {}
+
+    explicit sc_in( in_port_type& parent_ )
+        : base_type( parent_ ), m_traces( 0 )
+        {}
+
+    sc_in( const char* name_, in_port_type& parent_ )
+        : base_type( name_, parent_ ), m_traces( 0 )
+        {}
+
+    explicit sc_in( inout_port_type& parent_ )
+        : base_type(), m_traces( 0 )
+        { sc_port_base::bind( parent_ ); }
+
+    sc_in( const char* name_, inout_port_type& parent_ )
+        : base_type( name_ ), m_traces( 0 )
+        { sc_port_base::bind( parent_ ); }
+
+    sc_in( this_type& parent_ )
+        : base_type( parent_ ), m_traces( 0 )
+        {}
+
+    sc_in( const char* name_, this_type& parent_ )
+        : base_type( name_, parent_ ), m_traces( 0 )
+        {}
+
+
+    // destructor
+
+    virtual inline ~sc_in()
+        {
+            remove_traces();
+        }
+
+    // bit and part selection
+
+    sc_dt::sc_uint_bitref_r operator [] ( int i ) const
+        { return (*this)->read()[i]; }
+    sc_dt::sc_uint_bitref_r bit( int i ) const
+        { return (*this)->read()[i]; }
+    sc_dt::sc_uint_subref_r operator () ( int left, int right ) const
+        { return (*this)->read()(left,right); }
+    sc_dt::sc_uint_subref_r range( int left, int right ) const
+        { return (*this)->read()(left,right); }
+
+
+    // interface access shortcut methods
+
+    // get the default event
+
+    const sc_event& default_event() const
+        { return (*this)->value_changed_event(); }
+
+
+    // get the value changed event
+
+    const sc_event& value_changed_event() const
+        { return (*this)->value_changed_event(); }
+
+
+    // read the current value
+
+    const sc_dt::sc_uint<W>& read() const
+        { return (*this)->read(); }
+
+    operator sc_dt::uint64 () const
+        { return (sc_dt::uint64)(*this)->read(); }
+
+    // was there a value changed event?
+
+    bool event() const
+        { return (*this)->event(); }
+
+
+    // (other) event finder method(s)
+
+    sc_event_finder& value_changed() const
+        {
+            return *new sc_event_finder_t<in_if_type>(
+                *this, &in_if_type::value_changed_event );
+        }
+
+
+
+    // reduction methods:
+
+    inline bool and_reduce() const
+        { return (*this)->read().and_reduce(); }
+    inline bool nand_reduce() const
+        { return (*this)->read().nand_reduce(); }
+    inline bool nor_reduce() const
+        { return (*this)->read().nor_reduce(); }
+    inline bool or_reduce() const
+        { return (*this)->read().or_reduce(); }
+    inline bool xnor_reduce() const
+        { return (*this)->read().xnor_reduce(); }
+    inline bool xor_reduce() const
+        { return (*this)->read().xor_reduce(); }
+
+
+    // called when elaboration is done
+    /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+    /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+    virtual inline void end_of_elaboration()
+        {
+            if( m_traces != 0 ) {
+                for( unsigned int i = 0; i < m_traces->size(); ++ i ) {
+                    sc_trace_params* p = (*m_traces)[i];
+                    sc_trace( p->tf, read(), p->name );
+                }
+                remove_traces();
+            }
+        }
+
+    virtual inline const char* kind() const
+        { return "sc_in"; }
+
+
+    // called by sc_trace
+    void add_trace( sc_trace_file* tf_, const std::string& name_ ) const
+        {
+            if( tf_ != 0 ) {
+                if( m_traces == 0 ) {
+                    m_traces = new sc_trace_params_vec;
+                }
+                m_traces->push_back( new sc_trace_params( tf_, name_ ) );
+            }
+        }
+
+
+    // concatenation methods
+
+    virtual inline int concat_length(bool* xz_present_p) const
+        { return (*this)->read().concat_length( xz_present_p ); }
+    virtual inline sc_dt::uint64 concat_get_uint64() const
+        { return (*this)->read().concat_get_uint64(); }
+    virtual inline bool concat_get_ctrl(
+           sc_dt::sc_digit* dst_p, int low_i ) const
+        { return (*this)->read().concat_get_ctrl(dst_p, low_i); }
+    virtual inline bool concat_get_data(
+           sc_dt::sc_digit* dst_p, int low_i ) const
+        { return (*this)->read().concat_get_data(dst_p, low_i); }
+
+  protected:
+    void remove_traces() const
+        {
+            if( m_traces != 0 ) {
+                for( int i = m_traces->size() - 1; i >= 0; -- i ) {
+                    delete (*m_traces)[i];
+                }
+                delete m_traces;
+                m_traces = 0;
+            }
+        }
+
+    mutable sc_trace_params_vec* m_traces;
+
+
+  private:
+
+    // disabled
+    sc_in( const sc_in<sc_dt::sc_uint<W> >& );
+    sc_in<sc_dt::sc_uint<W> >& operator = ( const sc_in<sc_dt::sc_uint<W> >& );
+
+#ifdef __GNUC__
+    // Needed to circumvent a problem in the g++-2.95.2 compiler:
+    // This unused variable forces the compiler to instantiate
+    // an object of T template so an implicit conversion from
+    // read() to a C++ intrinsic data type will work.
+    static data_type dummy;
+#endif
+
+};
+
+
+
+SC_TEMPLATE
+inline std::ostream& operator << (
+       std::ostream& os, const sc_in<sc_dt::sc_uint<W> >& a )
+{
+    a.read().print( os );
+    return os;
+}
+
+
+//==============================================================================
+// CLASS sc_inout<sc_dt::sc_uint<W> >
+//
+// This class implements an input/output port whose target acts like an
+// sc_dt::sc_uint<W> data value. It is derived from the sc_uint_in. This class is a
+// specialization of the generic sc_inout class to implement tailored support
+// for the sc_dt::sc_uint<W> class.
+//==============================================================================
+SC_TEMPLATE
+class sc_inout<sc_dt::sc_uint<W> > :
+    public sc_port<sc_signal_inout_if<sc_dt::sc_uint<W> >, 1,
+           SC_ONE_OR_MORE_BOUND>,
+    public sc_dt::sc_value_base
+{
+  public:
+
+    // typedefs
+
+    typedef sc_dt::sc_uint<W>                       data_type;
+    typedef sc_signal_inout_if<sc_dt::sc_uint<W> >  if_type;
+    typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND> base_type;
+    typedef sc_inout<sc_dt::sc_uint<W> >            this_type;
+
+    typedef if_type                                 inout_if_type;
+    typedef base_type                               inout_port_type;
+
+  public:
+
+    // bind methods and operators:
+
+    void bind( const inout_if_type& interface_ )
+        { sc_port_base::bind( const_cast<inout_if_type&>( interface_) ); }
+    void operator () ( const inout_if_type& interface_ )
+        { sc_port_base::bind( const_cast<inout_if_type&>( interface_) ); }
+    void bind( inout_port_type& parent_ )
+        { sc_port_base::bind(parent_); }
+    void operator () ( inout_port_type& parent_ )
+        { sc_port_base::bind(parent_); }
+
+  protected:
+    // called by pbind (for internal use only)
+    virtual inline int vbind( sc_interface& interface_ )
+        {
+            return sc_port_b<if_type>::vbind( interface_ );
+        }
+    virtual inline int vbind( sc_port_base& parent_ )
+        {
+            inout_port_type* inout_parent = dynamic_cast<inout_port_type*>( &parent_ );
+            if( inout_parent != 0 ) {
+                sc_port_base::bind( *inout_parent );
+                return 0;
+            }
+            // type mismatch
+            return 2;
+        }
+
+
+    // constructors
+
+  public:
+    sc_inout()
+        : base_type(), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    explicit sc_inout( const char* name_ )
+        : base_type( name_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    explicit sc_inout( inout_if_type& interface_ )
+        : base_type( interface_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    sc_inout( const char* name_, inout_if_type& interface_ )
+        : base_type( name_, interface_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    explicit sc_inout( inout_port_type& parent_ )
+        : base_type( parent_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    sc_inout( const char* name_, inout_port_type& parent_ )
+        : base_type( name_, parent_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    sc_inout( this_type& parent_ )
+        : base_type( parent_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    sc_inout( const char* name_, this_type& parent_ )
+        : base_type( name_, parent_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+
+    // destructor
+
+    virtual inline ~sc_inout()
+        {
+            remove_traces();
+        }
+
+    // bit and part selection
+
+    sc_dt::sc_uint_bitref_r operator [] ( int i ) const
+        { return (*this)->read()[i]; }
+    sc_dt::sc_uint_bitref_r bit( int i ) const
+        { return (*this)->read()[i]; }
+    sc_uint_sigref& operator [] ( int i )
+        { return (*this)->select_part(i,i); }
+    sc_uint_sigref& bit( int i )
+        { return (*this)->select_part(i,i); }
+    sc_dt::sc_uint_subref_r operator () ( int left, int right ) const
+        { return (*this)->read()(left,right); }
+    sc_dt::sc_uint_subref_r range( int left, int right ) const
+        { return (*this)->read()(left,right); }
+    sc_uint_sigref& operator () ( int left, int right )
+        { return (*this)->select_part(left,right); }
+    sc_uint_sigref& range( int left, int right )
+        { return (*this)->select_part(left,right); }
+
+
+    // interface access shortcut methods
+
+    // get the default event
+
+    const sc_event& default_event() const
+        { return (*this)->value_changed_event(); }
+
+
+    // get the value changed event
+
+    const sc_event& value_changed_event() const
+        { return (*this)->value_changed_event(); }
+
+
+    // read the current value
+
+    const sc_dt::sc_uint<W>& read() const
+        { return (*this)->read(); }
+
+    operator sc_dt::uint64 () const
+        { return (sc_dt::uint64)(*this)->read(); }
+
+    // was there a value changed event?
+
+    bool event() const
+        { return (*this)->event(); }
+
+
+    // (other) event finder method(s)
+
+    sc_event_finder& value_changed() const
+        {
+            return *new sc_event_finder_t<inout_if_type>(
+                *this, &inout_if_type::value_changed_event );
+        }
+
+
+
+    // reduction methods:
+
+    inline bool and_reduce() const
+        { return (*this)->read().and_reduce(); }
+    inline bool nand_reduce() const
+        { return (*this)->read().nand_reduce(); }
+    inline bool nor_reduce() const
+        { return (*this)->read().nor_reduce(); }
+    inline bool or_reduce() const
+        { return (*this)->read().or_reduce(); }
+    inline bool xnor_reduce() const
+        { return (*this)->read().xnor_reduce(); }
+    inline bool xor_reduce() const
+        { return (*this)->read().xor_reduce(); }
+
+
+    // called when elaboration is done
+    /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+    /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+    virtual inline void end_of_elaboration()
+        {
+            if( m_init_val_p != 0 ) {
+                               (*this)->write( (sc_dt::uint64) *m_init_val_p );
+                delete m_init_val_p;
+                m_init_val_p = 0;
+            }
+            if( m_traces != 0 ) {
+                for( unsigned int i = 0; i < m_traces->size(); ++ i ) {
+                    sc_trace_params* p = (*m_traces)[i];
+                    sc_trace( p->tf, read(), p->name );
+                }
+                remove_traces();
+            }
+        }
+
+    virtual inline const char* kind() const
+        { return "sc_inout"; }
+
+    // value initialization
+
+    inline void initialize( const sc_dt::sc_uint<W>& value_ )
+    {
+        inout_if_type* iface = this->get_interface(0);
+        if( iface != 0 ) {
+            iface->write( value_ );
+        } else {
+            if( m_init_val_p == 0 ) {
+                m_init_val_p = new sc_dt::uint64;
+            }
+            *m_init_val_p = value_;
+        }
+    }
+
+
+    // called by sc_trace
+    void add_trace( sc_trace_file* tf_, const std::string& name_ ) const
+        {
+            if( tf_ != 0 ) {
+                if( m_traces == 0 ) {
+                    m_traces = new sc_trace_params_vec;
+                }
+                m_traces->push_back( new sc_trace_params( tf_, name_ ) );
+            }
+        }
+
+
+    // concatenation methods
+
+    virtual inline int concat_length(bool* xz_present_p) const
+        { return (*this)->read().concat_length( xz_present_p ); }
+    virtual inline sc_dt::uint64 concat_get_uint64() const
+        { return (*this)->read().concat_get_uint64(); }
+    virtual inline bool concat_get_ctrl(
+           sc_dt::sc_digit* dst_p, int low_i ) const
+        { return (*this)->read().concat_get_ctrl(dst_p, low_i); }
+    virtual inline bool concat_get_data(
+           sc_dt::sc_digit* dst_p, int low_i ) const
+        { return (*this)->read().concat_get_data(dst_p, low_i); }
+    virtual inline void concat_set(sc_dt::int64 src, int low_i)
+        { *this = (src >> ((low_i < 64) ? low_i : 63)); }
+#if 0
+    virtual inline void concat_set(const sc_dt::sc_lv_base& src, int low_i)
+        { if (low_i < 64) *this = src >> low_i; else *this = 0; }
+#endif // 0 ####
+    virtual inline void concat_set(const sc_dt::sc_signed& src, int low_i)
+        { *this = (src >> low_i); }
+    virtual inline void concat_set(const sc_dt::sc_unsigned& src, int low_i)
+        { *this = (src >> low_i); }
+    virtual inline void concat_set(sc_dt::uint64 src, int low_i)
+        { *this = (low_i < 64) ? src >> low_i : (sc_dt::uint64)0; }
+
+    // assignment operators:
+
+  public:
+    inline void operator = ( const this_type& new_val )
+        { (*this)->write( (sc_dt::uint64)new_val ); }
+    inline void operator = ( const char* new_val )
+        { (*this)->write( this_type(new_val) ); }
+    inline void operator = ( sc_dt::uint64 new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( sc_dt::int64 new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( int new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( long new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( short new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned int new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned long new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned short new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    template<typename T>
+    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val )
+        { (*this)->write(new_val->to_uint64()); }
+    inline void operator = ( const sc_dt::sc_signed& new_val )
+        { (*this)->write(new_val.to_uint64()); }
+    inline void operator = ( const sc_dt::sc_unsigned& new_val )
+        { (*this)->write(new_val.to_uint64()); }
+    inline void operator = ( const sc_dt::sc_bv_base& new_val )
+        { (*this)->write((sc_dt::sc_uint<W>)new_val); }
+    inline void operator = ( const sc_dt::sc_lv_base& new_val )
+        { (*this)->write((sc_dt::sc_uint<W>)new_val); }
+
+    inline void write( const sc_in<sc_dt::sc_uint<W> >& new_val )
+        { (*this)->write( (sc_dt::uint64)new_val ); }
+    inline void write( const sc_inout<sc_dt::sc_uint<W> >& new_val )
+        { (*this)->write( (sc_dt::uint64)new_val); }
+    inline void write( const sc_dt::sc_uint<W>& new_val )
+        { (*this)->write( (sc_dt::uint64)new_val); }
+
+  protected:
+    void remove_traces() const
+        {
+            if( m_traces != 0 ) {
+                for( int i = m_traces->size() - 1; i >= 0; -- i ) {
+                    delete (*m_traces)[i];
+                }
+                delete m_traces;
+                m_traces = 0;
+            }
+        }
+
+    sc_dt::uint64*                      m_init_val_p;
+    mutable sc_trace_params_vec* m_traces;
+
+
+  private:
+
+    // disabled
+    sc_inout( const sc_inout<sc_dt::sc_uint<W> >& );
+
+#ifdef __GNUC__
+    // Needed to circumvent a problem in the g++-2.95.2 compiler:
+    // This unused variable forces the compiler to instantiate
+    // an object of T template so an implicit conversion from
+    // read() to a C++ intrinsic data type will work.
+    static data_type dummy;
+#endif
+
+};
+
+
+
+SC_TEMPLATE
+inline std::ostream& operator << (
+    std::ostream& os, const sc_inout<sc_dt::sc_uint<W> >& a )
+{
+    a.read().print( os );
+    return os;
+}
+
+
+//==============================================================================
+// CLASS sc_out<sc_dt::sc_uint<W> >
+//
+// This class implements an output port whose target acts like an
+// sc_dt::sc_uint<W> data value. This class is a derivation of sc_inout, since
+// output ports are really no different from input/output ports.
+//==============================================================================
+SC_TEMPLATE
+class sc_out<sc_dt::sc_uint<W> > : public sc_inout<sc_dt::sc_uint<W> >
+{
+  public:
+
+    // typedefs
+
+    typedef sc_dt::sc_uint<W>                          data_type;
+
+    typedef sc_out<data_type>                   this_type;
+    typedef sc_inout<data_type>                 base_type;
+
+    typedef typename base_type::inout_if_type   inout_if_type;
+    typedef typename base_type::inout_port_type inout_port_type;
+
+    // constructors
+
+    sc_out()
+        : base_type()
+        {}
+
+    explicit sc_out( const char* name_ )
+        : base_type( name_ )
+        {}
+
+    explicit sc_out( inout_if_type& interface_ )
+        : base_type( interface_ )
+        {}
+
+    sc_out( const char* name_, inout_if_type& interface_ )
+        : base_type( name_, interface_ )
+        {}
+
+    explicit sc_out( inout_port_type& parent_ )
+        : base_type( parent_ )
+        {}
+
+    sc_out( const char* name_, inout_port_type& parent_ )
+        : base_type( name_, parent_ )
+        {}
+
+    sc_out( this_type& parent_ )
+        : base_type( parent_ )
+        {}
+
+    sc_out( const char* name_, this_type& parent_ )
+        : base_type( name_, parent_ )
+        {}
+
+
+    // destructor (does nothing)
+
+    virtual inline ~sc_out()
+        {}
+
+
+    // assignment operators:
+
+  public:
+    inline void operator = ( const this_type& new_val )
+        { (*this)->write( (sc_dt::uint64)new_val ); }
+    inline void operator = ( const char* new_val )
+        { (*this)->write( this_type(new_val) ); }
+    inline void operator = ( sc_dt::uint64 new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( sc_dt::int64 new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( int new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( long new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( short new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned int new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned long new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned short new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    template<typename T>
+    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val )
+        { (*this)->write(new_val->to_uint64()); }
+    inline void operator = ( const sc_dt::sc_signed& new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( const sc_dt::sc_unsigned& new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( const sc_dt::sc_bv_base& new_val )
+        { (*this)->write((sc_dt::sc_uint<W>)new_val); }
+    inline void operator = ( const sc_dt::sc_lv_base& new_val )
+        { (*this)->write((sc_dt::sc_uint<W>)new_val); }
+
+  private:
+
+    // disabled
+    sc_out( const this_type& );
+};
+
+
+
+//------------------------------------------------------------------------------
+//"sc_uint_sigref::initialize"
+//
+// This method initializes an object instance from the supplied arguments.
+//     if_p  -> interface for signal to perform writes for this object.
+//     left  =  left-most bit in selection.
+//     right =  right-most bit in selection.
+//------------------------------------------------------------------------------
+inline
+void sc_uint_sigref::initialize(sc_uint_part_if* if_p, int left, int right)
+{
+    m_left = left;
+    m_right = right;
+    m_if_p = if_p;
+       m_obj_p = if_p->part_read_target();
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_uint_sigref::operator ="
+//
+// These operators assign a value to the bits associated with this object
+// instance within this object instance's target signal.
+//------------------------------------------------------------------------------
+inline void sc_uint_sigref::operator = ( sc_dt::uint64 v )
+{
+       m_if_p->write_part( v, m_left, m_right );
+}
+
+inline void sc_uint_sigref::operator = ( const char* /*v*/ )
+{
+}
+
+inline void sc_uint_sigref:: operator = ( sc_dt::int64 v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+inline void sc_uint_sigref:: operator = ( int v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+inline void sc_uint_sigref:: operator = ( long v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+inline void sc_uint_sigref:: operator = ( unsigned int v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+inline void sc_uint_sigref:: operator = ( unsigned long v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+void sc_uint_sigref::operator = ( const sc_uint_sigref& v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+template<typename T>
+inline void sc_uint_sigref:: operator = ( const sc_dt::sc_generic_base<T>& v )
+{
+    *this = v->to_uint64();
+}
+
+inline void sc_uint_sigref:: operator = ( const sc_dt::sc_signed& v )
+{
+    *this = v.to_uint64();
+}
+
+inline void sc_uint_sigref:: operator = ( const sc_dt::sc_unsigned& v )
+{
+    *this = v.to_uint64();
+}
+
+#undef SC_TEMPLATE
+} // namespace sc_core
+#endif // !defined(SC_SIGNAL_UINT_H)
+
+namespace sc_core {
+
+//------------------------------------------------------------------------------
+// POOL OF TEMPORARY INSTANCES OF sc_uint_sigref
+//
+// This allows use to pass const references for part and bit selections
+// on sc_signal<sc_dt::sc_uint<W> > object instances.
+//------------------------------------------------------------------------------
+sc_vpool<sc_uint_sigref> sc_uint_sigref::m_pool(8);
+
+
+//------------------------------------------------------------------------------
+//"sc_uint_part_if::default methods"
+//
+// These versions just produce errors if they are not overloaded but used.
+//------------------------------------------------------------------------------
+
+sc_dt::sc_uint_base* sc_uint_part_if::part_read_target()
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+    return 0;
+}
+sc_dt::uint64 sc_uint_part_if::read_part( int /*left*/, int /*right*/ ) const
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+    return 0;
+}
+sc_uint_sigref& sc_uint_part_if::select_part( int /*left*/, int /*right*/ )
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+    return *(sc_uint_sigref*)0;
+}
+void sc_uint_part_if::write_part( sc_dt::uint64 v, int /*left*/, int /*right*/ )
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+}
+
+//------------------------------------------------------------------------------
+//"sc_uint_sigref::concate_set"
+//
+// These methods assign this object instance's value from the supplied
+// value starting at the supplied bit within that value.
+//     src = value to use to set this object instance's value.
+//     low_i = bit in src that is to be the low order bit of the value to set.
+// #### OPTIMIZE
+//------------------------------------------------------------------------------
+void sc_uint_sigref::concat_set(sc_dt::int64 src, int low_i)
+{
+    *this = (low_i < 64) ? src >> low_i : src >> 63;
+}
+
+
+void sc_uint_sigref::concat_set(const sc_dt::sc_signed& src, int low_i)
+{
+    if ( low_i < src.length() )
+        *this = src >> low_i;
+    else
+        *this = (src < 0) ? (sc_dt::uint64)-1 : 0;
+}
+
+
+void sc_uint_sigref::concat_set(const sc_dt::sc_lv_base& src, int low_i)
+{
+    if ( low_i < src.length() )
+        *this = (src >> low_i).to_uint64();
+    else
+        *this = 0;
+}
+
+
+void sc_uint_sigref::concat_set(const sc_dt::sc_unsigned& src, int low_i)
+{
+    if ( low_i < src.length() )
+        *this = src >> low_i;
+    else
+        *this = 0;
+}
+
+
+void sc_uint_sigref::concat_set(sc_dt::uint64 src, int low_i)
+{
+    *this = (low_i < 64) ? src >> low_i : 0;
+}
+
+} // namespace sc_core
diff --git a/src/systemc/tests/include/specialized_signals/scx_signal_unsigned.h b/src/systemc/tests/include/specialized_signals/scx_signal_unsigned.h
new file mode 100644 (file)
index 0000000..a356d44
--- /dev/null
@@ -0,0 +1,1834 @@
+/*****************************************************************************
+
+  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.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  sc_signal_unsigned.cpp -- The sc_signal<sc_unsigned<W> > implementations.
+
+  Original Author: Andy Goodrich, Forte Design Systems, 2002-10-22
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+  changes you are making here.
+
+      Name, Affiliation, Date:
+  Description of Modification:
+
+ *****************************************************************************/
+
+/*
+$Log: scx_signal_unsigned.h,v $
+Revision 1.1  2011/08/15 17:31:11  acg
+ Andy Goodrich: moved specialized signals from examples to this tree.
+
+Revision 1.2  2011/08/15 16:43:24  acg
+ Torsten Maehne: changes to remove unused argument warnings.
+
+Revision 1.1.1.1  2006/12/15 20:20:03  acg
+SystemC 2.3
+
+Revision 1.2  2005/12/26 20:11:14  acg
+Fixed up copyright.
+
+Revision 1.1.1.1  2005/12/19 23:16:42  acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.17  2005/09/15 23:01:52  acg
+Added std:: prefix to appropriate methods and types to get around
+issues with the Edison Front End.
+
+Revision 1.16  2005/05/03 19:52:26  acg
+Get proper header locations on includes.
+
+Revision 1.15  2005/05/03 19:50:20  acg
+Name space version.
+
+Revision 1.12  2005/04/11 19:05:36  acg
+Change to sc_clock for Microsoft VCC 6.0. Changes for namespaces
+
+Revision 1.11  2005/04/03 22:52:52  acg
+Namespace changes.
+
+Revision 1.10  2005/03/21 22:31:33  acg
+Changes to sc_core namespace.
+
+Revision 1.9  2004/09/27 21:01:59  acg
+Andy Goodrich - Forte Design Systems, Inc.
+   - This is specialized signal support that allows better use of signals
+     and ports whose target value is a SystemC native type.
+
+*/
+
+
+
+#include <systemc>
+#include <typeinfo>
+
+/*****************************************************************************
+
+  sc_signal_unsigned.h -- The sc_signal<sc_dt::sc_biguint<W> > definitions.
+
+  Original Author: Andy Goodrich, Forte Design Systems, 2002-10-22
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+  changes you are making here.
+
+      Name, Affiliation, Date:
+  Description of Modification:
+
+ *****************************************************************************/
+
+/*
+$Log: scx_signal_unsigned.h,v $
+Revision 1.1  2011/08/15 17:31:11  acg
+ Andy Goodrich: moved specialized signals from examples to this tree.
+
+Revision 1.3  2011/08/15 16:43:24  acg
+ Torsten Maehne: changes to remove unused argument warnings.
+
+Revision 1.2  2011/06/28 21:23:02  acg
+ Andy Goodrich: merging of SCV tree.
+
+Revision 1.1.1.1  2006/12/15 20:20:03  acg
+SystemC 2.3
+
+Revision 1.4  2006/10/23 19:40:36  acg
+ Andy Goodrich: added an explicit dynamic cast to keep gcc 4.x happy.
+
+Revision 1.3  2006/03/21 01:31:49  acg
+ Andy Goodrich: changed over to sc_get_current_process_b() from
+ sc_get_current_process_base() since the function's name changed.
+
+Revision 1.2  2005/12/26 20:11:14  acg
+Fixed up copyright.
+
+Revision 1.1.1.1  2005/12/19 23:16:42  acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.28  2005/09/15 23:01:52  acg
+Added std:: prefix to appropriate methods and types to get around
+issues with the Edison Front End.
+
+Revision 1.27  2005/07/30 03:44:11  acg
+Changes from 2.1.
+
+Revision 1.26  2005/05/09 17:17:12  acg
+Changes from 2.1.
+
+Revision 1.25  2005/05/08 19:04:06  acg
+Fix bug in concat_set(int64,off). Other changes from 2.1 examples usage.
+
+Revision 1.24  2005/05/03 19:50:20  acg
+Name space version.
+
+Revision 1.22  2005/03/21 22:31:33  acg
+Changes to sc_core namespace.
+
+Revision 1.21  2005/01/10 17:51:58  acg
+Improvements.
+
+Revision 1.20  2004/11/09 00:11:27  acg
+Added support for sc_generic_base<T> in place of sc_concatref. sc_concatref
+now is derived from sc_generic_base<sc_concatref>.
+
+Revision 1.19  2004/09/27 21:01:59  acg
+Andy Goodrich - Forte Design Systems, Inc.
+   - This is specialized signal support that allows better use of signals
+     and ports whose target value is a SystemC native type.
+
+*/
+
+
+#if !defined(SC_SIGNAL_UNSIGNED_H)
+#define SC_SIGNAL_UNSIGNED_H
+
+#if ( !defined(_MSC_VER) || _MSC_VER > 1200 )
+#    define SC_TEMPLATE template<int W>
+#else
+#    define SC_TEMPLATE template<> template<int W>
+#endif
+
+
+// FORWARD REFERENCES AND USINGS:
+
+using sc_dt::sc_signed;
+using sc_dt::int64;
+using sc_dt::uint64;
+
+namespace sc_core {
+
+class sc_unsigned_sigref;
+
+//==============================================================================
+// CLASS sc_unsigned_part_if
+//
+// This class provides generic access to part selections for signals whose
+// data type is sc_dt::sc_biguint<W>. This class serves as the base class for the
+// sc_dt::sc_biguint<W> specialization of the sc_signal_in_if<T> class. The methods
+// in this class may be over-ridden individually, those that are not overridden
+// will produce an error message when called. The methods are used by the
+// sc_unsigned_sigref class.
+//
+// Notes:
+//   (1) Descriptions of the methods and operators in this class appear with
+//       their implementations in sc_signal<sc_dt::sc_biguint<W> >.
+//==============================================================================
+class sc_unsigned_part_if : virtual public sc_interface {
+  protected:
+       // constructor:
+       sc_unsigned_part_if() {}
+
+  public:
+    // perform a part read.
+       virtual sc_dt::sc_unsigned* part_read_target();
+       virtual sc_dt::sc_unsigned read_part( int left, int right ) const;
+
+    // perform a part write.
+       virtual sc_unsigned_sigref& select_part( int left, int right );
+    virtual void write_part( sc_dt::int64 v, int left, int right );
+    virtual void write_part( sc_dt::uint64 v, int left, int right );
+    virtual void write_part( const sc_dt::sc_signed& v, int left, int right );
+    virtual void write_part( const sc_dt::sc_unsigned& v, int left, int right );
+
+
+  private:
+       sc_unsigned_part_if( const sc_unsigned_part_if& );
+       sc_unsigned_part_if& operator = ( const sc_unsigned_part_if& );
+};
+
+
+//==============================================================================
+// CLASS sc_signal_in_if<sc_dt::sc_biguint<W> >
+//
+// This is the class specializations for the sc_signal_in_if<T> class to
+// provide additional features for sc_signal instances whose template is
+// sc_dt::sc_biguint<W>, including part access.
+//
+// Notes:
+//   (1) Descriptions of the methods and operators in this class appear with
+//       their implementations in sc_signal<sc_dt::sc_biguint<W> >.
+//==============================================================================
+template< int W >
+class sc_signal_in_if<sc_dt::sc_biguint<W> > : public sc_unsigned_part_if {
+       friend class sc_unsigned_sigref;
+  public:
+    typedef sc_signal_in_if<sc_dt::sc_biguint<W> > this_type;
+
+    // get the value changed event
+    virtual const sc_event& value_changed_event() const = 0;
+
+
+    // read the current value
+    virtual const sc_dt::sc_biguint<W>& read() const = 0;
+
+    // get a reference to the current value (for tracing)
+    virtual const sc_dt::sc_biguint<W>& get_data_ref() const = 0;
+
+
+    // was there a value changed event?
+    virtual bool event() const = 0;
+
+  protected:
+    // constructor
+    sc_signal_in_if()
+    {}
+
+  private: // disabled
+    sc_signal_in_if( const this_type& );
+    this_type& operator = ( const this_type& );
+};
+
+//=============================================================================
+//  CLASS : sc_unsigned_sigref
+//
+//  Proxy class for sc_signal_uint bit and part selection.
+//=============================================================================
+class sc_unsigned_sigref : public sc_dt::sc_unsigned_subref_r
+{
+  public:
+    sc_unsigned_sigref() : sc_dt::sc_unsigned_subref_r() {}
+    virtual ~sc_unsigned_sigref() {}
+    virtual void concat_set(sc_dt::int64 src, int low_i);
+    virtual void concat_set(const sc_dt::sc_signed& src, int low_i);
+    virtual void concat_set(const sc_dt::sc_unsigned& src, int low_i);
+    virtual void concat_set(const sc_dt::sc_lv_base& src, int low_i);
+    virtual void concat_set(sc_dt::uint64 src, int low_i);
+
+  public:
+    inline void initialize( sc_unsigned_part_if* if_p, int left_, int right_ );
+
+  public:
+    inline void operator = ( sc_dt::uint64 v );
+    inline void operator = ( const char* v );
+    inline void operator = ( unsigned long v );
+    inline void operator = ( long v );
+    inline void operator = ( unsigned int v );
+    inline void operator = ( int v );
+    inline void operator = ( sc_dt::int64 v );
+    inline void operator = ( double v );
+    inline void operator = ( const sc_unsigned_sigref& v );
+    template<typename T>
+    inline void operator = ( const sc_dt::sc_generic_base<T>& v );
+    inline void operator = ( const sc_dt::sc_signed& v );
+    inline void operator = ( const sc_dt::sc_unsigned& v );
+    inline void operator = ( const sc_dt::sc_bv_base& v );
+    inline void operator = ( const sc_dt::sc_lv_base& v );
+
+  public:
+    static sc_vpool<sc_unsigned_sigref> m_pool; // Pool of objects to use.
+
+  protected:
+    sc_unsigned_part_if*                m_if_p; // Target for selection.
+
+  private:
+
+    // disabled
+    sc_unsigned_sigref( const sc_unsigned_sigref& a );
+};
+
+
+//==============================================================================
+// CLASS sc_signal<sc_dt::sc_biguint<W> >
+//
+// This class implements a signal whose value acts like an sc_dt::sc_biguint<W> data
+// value. This class is a specialization of the generic sc_signal class to
+// implement tailored support for the sc_dt::sc_biguint<W> class.
+//
+// Notes:
+//   (1) Descriptions of the methods and operators in this class appear with
+//       their implementations.
+//==============================================================================
+SC_TEMPLATE
+class sc_signal<sc_dt::sc_biguint<W> > :
+    public sc_dt::sc_biguint<W>,
+       public sc_prim_channel,
+    public sc_signal_inout_if<sc_dt::sc_biguint<W> >
+{
+  public: // typedefs
+    typedef sc_signal<sc_dt::sc_biguint<W> > this_type;
+
+  public: // constructors and destructor:
+    inline sc_signal();
+    explicit inline sc_signal(const char* name_);
+    virtual inline ~sc_signal();
+
+  public: // base methods:
+    inline bool base_event() const;
+    inline const sc_dt::sc_biguint<W>& base_read() const;
+    inline const sc_event& base_value_changed_event() const;
+    inline void base_write( sc_dt::int64 value );
+    inline void base_write( sc_dt::uint64 value );
+    inline void base_write( const sc_dt::sc_signed& value );
+    inline void base_write( const sc_dt::sc_unsigned& value );
+
+  public: // sc_prim_channel virtual methods:
+    virtual inline const char* kind() const;
+    virtual inline void update();
+
+  public: // sc_interface virtual methods:
+    virtual inline const sc_event& default_event() const;
+    virtual inline void register_port(
+               sc_port_base& port_, const char* if_typename_ );
+
+  public: // sc_unsigned_channel virtual methods:
+    virtual inline sc_dt::sc_unsigned* part_read_target();
+    virtual inline sc_dt::sc_unsigned read_part(int left, int right) const;
+       virtual sc_unsigned_sigref& select_part( int left, int right );
+       virtual inline void write_part( sc_dt::int64 v, int left, int right );
+       virtual inline void write_part( sc_dt::uint64 v, int left, int right );
+       virtual inline void write_part( const sc_dt::sc_signed& v, int left, int right );
+       virtual inline void write_part(const sc_dt::sc_unsigned& v, int left, int right);
+
+  public: // interface virtual methods:
+    virtual inline bool event() const;
+    virtual inline const sc_dt::sc_biguint<W>& get_data_ref() const;
+    virtual inline sc_signal<sc_dt::sc_biguint<W> >& get_signal();
+    virtual inline const sc_dt::sc_biguint<W>& read() const;
+    virtual inline const sc_event& value_changed_event() const;
+    virtual inline void write( const sc_in<sc_dt::sc_biguint<W> >& value );
+    virtual inline void write( const sc_inout<sc_dt::sc_biguint<W> >& value );
+    virtual inline void write( const sc_dt::sc_biguint<W>& value );
+
+  public: // part selections:
+       inline sc_unsigned_sigref& operator () ( int left, int right );
+       // #### Need to add range() and bit()!
+       inline sc_unsigned_sigref& operator [] ( int bit );
+
+  public: // operators:
+    inline void operator = ( const this_type& new_val );
+    inline void operator = ( const char* new_val );
+    inline void operator = ( sc_dt::uint64 new_val );
+    inline void operator = ( sc_dt::int64 new_val );
+    inline void operator = ( int new_val );
+    inline void operator = ( long new_val );
+    inline void operator = ( short new_val );
+    inline void operator = ( unsigned int new_val );
+    inline void operator = ( unsigned long new_val );
+    inline void operator = ( unsigned short new_val );
+    template<typename T>
+    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val );
+    inline void operator = ( const sc_dt::sc_signed& new_val );
+    inline void operator = ( const sc_dt::sc_unsigned& new_val );
+    inline void operator = ( const sc_dt::sc_bv_base& new_val );
+    inline void operator = ( const sc_dt::sc_lv_base& new_val );
+
+    // concatenation methods (we inherit length and gets from sc_dt::sc_biguint<W>):
+
+    virtual inline void concat_set(sc_dt::int64 src, int low_i);
+    virtual inline void concat_set(const sc_dt::sc_lv_base& src, int low_i);
+    virtual inline void concat_set(const sc_dt::sc_signed& src, int low_i);
+    virtual inline void concat_set(const sc_dt::sc_unsigned& src, int low_i);
+    virtual inline void concat_set(sc_dt::uint64 src, int low_i);
+
+  protected: // debugging methods:
+    // #### void check_port();
+       void check_writer();
+
+  private: // Disabled operations that sc_dt::sc_biguint<W> supports:
+    sc_dt::sc_unsigned& operator ++ ();          // prefix
+    const sc_dt::sc_unsigned& operator ++ (int); // postfix
+    sc_dt::sc_unsigned& operator -- ();          // prefix
+    const sc_dt::sc_unsigned& operator -- (int); // postfix
+    sc_dt::sc_unsigned& operator += (const sc_dt::sc_signed&    );
+    sc_dt::sc_unsigned& operator += (const sc_dt::sc_unsigned&  );
+    sc_dt::sc_unsigned& operator += (sc_dt::int64               );
+    sc_dt::sc_unsigned& operator += (sc_dt::uint64              );
+    sc_dt::sc_unsigned& operator += (long                );
+    sc_dt::sc_unsigned& operator += (unsigned long       );
+    sc_dt::sc_unsigned& operator += (int                 );
+    sc_dt::sc_unsigned& operator += (unsigned int        );
+    sc_dt::sc_unsigned& operator -= (const sc_dt::sc_signed&    );
+    sc_dt::sc_unsigned& operator -= (const sc_dt::sc_unsigned&  );
+    sc_dt::sc_unsigned& operator -= (sc_dt::int64               );
+    sc_dt::sc_unsigned& operator -= (sc_dt::uint64              );
+    sc_dt::sc_unsigned& operator -= (long                );
+    sc_dt::sc_unsigned& operator -= (unsigned long       );
+    sc_dt::sc_unsigned& operator -= (int                 );
+    sc_dt::sc_unsigned& operator -= (unsigned int        );
+    sc_dt::sc_unsigned& operator *= (const sc_dt::sc_signed&    );
+    sc_dt::sc_unsigned& operator *= (const sc_dt::sc_unsigned&  );
+    sc_dt::sc_unsigned& operator *= (sc_dt::int64               );
+    sc_dt::sc_unsigned& operator *= (sc_dt::uint64              );
+    sc_dt::sc_unsigned& operator *= (long                );
+    sc_dt::sc_unsigned& operator *= (unsigned long       );
+    sc_dt::sc_unsigned& operator *= (int                 );
+    sc_dt::sc_unsigned& operator *= (unsigned int        );
+    sc_dt::sc_unsigned& operator /= (const sc_dt::sc_signed&    );
+    sc_dt::sc_unsigned& operator /= (const sc_dt::sc_unsigned&  );
+    sc_dt::sc_unsigned& operator /= (sc_dt::int64               );
+    sc_dt::sc_unsigned& operator /= (sc_dt::uint64              );
+    sc_dt::sc_unsigned& operator /= (long                );
+    sc_dt::sc_unsigned& operator /= (unsigned long       );
+    sc_dt::sc_unsigned& operator /= (int                 );
+    sc_dt::sc_unsigned& operator /= (unsigned int        );
+    sc_dt::sc_unsigned& operator %= (const sc_dt::sc_signed&    );
+    sc_dt::sc_unsigned& operator %= (const sc_dt::sc_unsigned&  );
+    sc_dt::sc_unsigned& operator %= (sc_dt::int64               );
+    sc_dt::sc_unsigned& operator %= (sc_dt::uint64              );
+    sc_dt::sc_unsigned& operator %= (long                );
+    sc_dt::sc_unsigned& operator %= (unsigned long       );
+    sc_dt::sc_unsigned& operator %= (int                 );
+    sc_dt::sc_unsigned& operator %= (unsigned int        );
+    sc_dt::sc_unsigned& operator &= (const sc_dt::sc_signed&    );
+    sc_dt::sc_unsigned& operator &= (const sc_dt::sc_unsigned&  );
+    sc_dt::sc_unsigned& operator &= (sc_dt::int64               );
+    sc_dt::sc_unsigned& operator &= (sc_dt::uint64              );
+    sc_dt::sc_unsigned& operator &= (long                );
+    sc_dt::sc_unsigned& operator &= (unsigned long       );
+    sc_dt::sc_unsigned& operator &= (int                 );
+    sc_dt::sc_unsigned& operator &= (unsigned int        );
+    sc_dt::sc_unsigned& operator |= (const sc_dt::sc_signed&    );
+    sc_dt::sc_unsigned& operator |= (const sc_dt::sc_unsigned&  );
+    sc_dt::sc_unsigned& operator |= (sc_dt::int64               );
+    sc_dt::sc_unsigned& operator |= (sc_dt::uint64              );
+    sc_dt::sc_unsigned& operator |= (long                );
+    sc_dt::sc_unsigned& operator |= (unsigned long       );
+    sc_dt::sc_unsigned& operator |= (int                 );
+    sc_dt::sc_unsigned& operator |= (unsigned int        );
+    sc_dt::sc_unsigned& operator ^= (const sc_dt::sc_signed&    );
+    sc_dt::sc_unsigned& operator ^= (const sc_dt::sc_unsigned&  );
+    sc_dt::sc_unsigned& operator ^= (sc_dt::int64               );
+    sc_dt::sc_unsigned& operator ^= (sc_dt::uint64              );
+    sc_dt::sc_unsigned& operator ^= (long                );
+    sc_dt::sc_unsigned& operator ^= (unsigned long       );
+    sc_dt::sc_unsigned& operator ^= (int                 );
+    sc_dt::sc_unsigned& operator ^= (unsigned int        );
+
+  protected:
+    mutable sc_event*  m_changed_event_p; // Value changed event this object.
+    sc_dt::uint64      m_event_delta;     // Delta cycle of last event.
+    sc_dt::sc_unsigned m_new_val;         // New value for this object instance.
+    sc_port_base*      m_output_p;        // Single write port verify field.
+    sc_process_b*   m_writer_p;        // Single writer verify field.
+};
+
+
+SC_TEMPLATE // Return true if a changed event happened in the last delta cycle.
+inline bool sc_signal<sc_dt::sc_biguint<W> >::base_event() const
+{
+    return simcontext()->delta_count() == m_event_delta + 1;
+}
+
+
+SC_TEMPLATE // Return this object's sc_dt::sc_biguint<W> object instance.
+inline const sc_dt::sc_biguint<W>& sc_signal<sc_dt::sc_biguint<W> >::base_read() const
+{
+       return *this;
+}
+
+
+SC_TEMPLATE // Return the value changed event, allocating it if necessary.
+inline const sc_event& sc_signal<sc_dt::sc_biguint<W> >::base_value_changed_event() const
+{
+    if ( !m_changed_event_p ) m_changed_event_p = new sc_event;
+    return *m_changed_event_p;
+}
+
+
+SC_TEMPLATE // Write a const sc_dt::sc_signed& value to this object instance.
+inline void sc_signal<sc_dt::sc_biguint<W> >::base_write( const sc_dt::sc_signed& value )
+{
+#   if defined(DEBUG_SYSTEMC)
+        check_writer();
+#   endif
+    m_new_val = value;
+    request_update();
+}
+
+SC_TEMPLATE // Write a const sc_dt::sc_unsigned& value to this object instance.
+inline void sc_signal<sc_dt::sc_biguint<W> >::base_write( const sc_dt::sc_unsigned& value )
+{
+#   if defined(DEBUG_SYSTEMC)
+        check_writer();
+#   endif
+    m_new_val = value;
+    request_update();
+}
+
+SC_TEMPLATE // Write a sc_dt::int64 value to this object instance.
+inline void sc_signal<sc_dt::sc_biguint<W> >::base_write( sc_dt::int64 value )
+{
+#   if defined(DEBUG_SYSTEMC)
+        check_writer();
+#   endif
+    m_new_val = value;
+    request_update();
+}
+
+
+SC_TEMPLATE // Write a sc_dt::uint64 value to this object instance.
+inline void sc_signal<sc_dt::sc_biguint<W> >::base_write( sc_dt::uint64 value )
+{
+#   if defined(DEBUG_SYSTEMC)
+        check_writer();
+#   endif
+    m_new_val = value;
+    request_update();
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_signal<sc_dt::sc_biguint<W> >::check_writer"
+//
+// This method checks to see if there is more than one writer for this
+// object instance by keeping track of the process performing the write.
+//------------------------------------------------------------------------------
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::check_writer()
+{
+    sc_process_b* writer_p = sc_get_current_process_b();
+    if( m_writer_p == 0 )
+    {
+        m_writer_p = writer_p;
+    }
+    else if( m_writer_p != writer_p )
+    {
+        sc_signal_invalid_writer( name(), kind(),
+                                  m_writer_p->name(), writer_p->name() );
+    }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_signal<sc_dt::sc_biguint<W> >::concat_set"
+//
+// These virtual methods allow value assignments to this object instance
+// from various sources. The position within the supplied source of the
+// low order bit for this object instance's value is low_i.
+//     src   = source value.
+//     low_i = bit within src to serve as low order bit of this object
+//             instance's value.
+//------------------------------------------------------------------------------
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::concat_set(sc_dt::int64 src, int low_i)
+{
+    if ( low_i < 64 )
+    {
+        base_write(src >> low_i);
+    }
+    else
+    {
+        base_write( (sc_dt::int64)((src < 0 ) ?  -1 : 0 ));
+    }
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::concat_set(
+       const sc_dt::sc_lv_base& src, int low_i)
+{
+    sc_dt::sc_unsigned tmp(src.length());
+    tmp = src >> low_i;
+    base_write( tmp );
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::concat_set(
+       const sc_dt::sc_signed& src, int low_i)
+{
+    base_write( (src >> low_i) );
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::concat_set(
+       const sc_dt::sc_unsigned& src, int low_i)
+{
+    base_write( (src >> low_i) );
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::concat_set(sc_dt::uint64 src, int low_i)
+{
+       base_write( (sc_dt::uint64)(( low_i < 64 ) ? src >> low_i : 0));
+}
+
+
+
+SC_TEMPLATE // Return the default event for this object instance.
+inline const sc_event& sc_signal<sc_dt::sc_biguint<W> >::default_event() const
+       { return base_value_changed_event(); }
+
+
+SC_TEMPLATE // Return true if a changed event happened in the last delta cycle.
+inline bool sc_signal<sc_dt::sc_biguint<W> >::event() const
+       { return base_event(); }
+
+
+SC_TEMPLATE // Return a reference to the value of this object instance.
+inline const sc_dt::sc_biguint<W>& sc_signal<sc_dt::sc_biguint<W> >::get_data_ref() const
+       { return *this; }
+
+
+SC_TEMPLATE // Return a pointer to this object instance.
+inline sc_signal<sc_dt::sc_biguint<W> >& sc_signal<sc_dt::sc_biguint<W> >::get_signal()
+       { return *this; }
+
+
+SC_TEMPLATE // Return a kind value of "sc_signal".
+inline const char* sc_signal<sc_dt::sc_biguint<W> >::kind() const
+{
+       return "sc_signal";
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_signal_uint::operator ()
+//
+// This operator returns a part selection of this object instance.
+//     left  = left-hand bit of the selection.
+//     right = right-hand bit of the selection.
+//------------------------------------------------------------------------------
+SC_TEMPLATE
+inline sc_unsigned_sigref& sc_signal<sc_dt::sc_biguint<W> >::operator () (int left, int right)
+{
+    sc_unsigned_sigref* result_p;   // Value to return.
+
+       result_p = sc_unsigned_sigref::m_pool.allocate();
+       result_p->initialize(this, left, right);
+       return *result_p;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_signal_uint::operator []"
+//
+// This operator returns a bit selection of this object instance.
+//     i = bit to be selected.
+//------------------------------------------------------------------------------
+SC_TEMPLATE
+inline sc_unsigned_sigref& sc_signal<sc_dt::sc_biguint<W> >::operator [] ( int bit )
+{
+    return operator () (bit,bit);
+}
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::operator = ( const this_type& new_val )
+       { base_write( new_val ); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::operator = ( const char* new_val )
+       { sc_dt::sc_biguint<W> tmp = new_val; m_new_val = tmp; request_update(); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::operator = ( const sc_dt::sc_unsigned& new_val )
+       { base_write(new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::operator = ( sc_dt::uint64 new_val )
+       { base_write(new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::operator = ( sc_dt::int64 new_val )
+       { base_write(new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::operator = ( int new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::operator = ( long new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::operator = ( short new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::operator = ( unsigned int new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::operator = ( unsigned long new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::operator = ( unsigned short new_val )
+       { base_write((sc_dt::int64)new_val); }
+
+
+SC_TEMPLATE
+template<typename T>
+inline void sc_signal<sc_dt::sc_biguint<W> >::operator = (
+       const sc_dt::sc_generic_base<T>& new_val )
+{
+       sc_dt::sc_unsigned temp(W);
+    new_val->to_sc_unsigned(temp);
+    base_write(temp);
+}
+
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::operator = ( const sc_dt::sc_signed& new_val )
+       { base_write(new_val); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::operator = ( const sc_dt::sc_bv_base& new_val )
+       { base_write( (sc_dt::sc_biguint<W>)new_val ); }
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::operator = ( const sc_dt::sc_lv_base& new_val )
+       { base_write( (sc_dt::sc_biguint<W>)new_val ); }
+
+
+SC_TEMPLATE
+inline sc_dt::sc_unsigned* sc_signal<sc_dt::sc_biguint<W> >::part_read_target()
+       { return this; }
+
+
+SC_TEMPLATE
+inline const sc_dt::sc_biguint<W>& sc_signal<sc_dt::sc_biguint<W> >::read() const
+       { return *this; }
+
+
+SC_TEMPLATE // Read a portion of a value.
+inline sc_dt::sc_unsigned sc_signal<sc_dt::sc_biguint<W> >::read_part(
+       int left, int right ) const
+{
+       sc_dt::sc_unsigned tmp(left-right+1);
+       tmp = (*(const sc_dt::sc_biguint<W>*)this)(left,right);
+    return tmp;
+}
+
+SC_TEMPLATE
+inline void sc_signal<sc_dt::sc_biguint<W> >::register_port(
+       sc_port_base& port_, const char* if_typename_ )
+{
+#       ifdef DEBUG_SYSTEMC
+               std::string nm( if_typename_ );
+               if( nm == typeid( sc_signal_inout_if<sc_dt::sc_biguint<W> > ).name() )
+               {
+                       if( m_output_p != 0 )
+                       {
+                               sc_signal_invalid_writer( name(), kind(),
+                                        m_output_p->name(), port_.name() );
+                       }
+                       m_output_p = &port_;
+               }
+#       else
+            if ( &port_ && if_typename_ ) {} // Silence unused args warning.
+#       endif
+}
+
+
+SC_TEMPLATE // Autogenerated name object instance constructor.
+inline sc_signal<sc_dt::sc_biguint<W> >::sc_signal() :
+       sc_prim_channel(sc_gen_unique_name( "signal" )),
+       m_changed_event_p(0),
+       m_new_val(W),
+       m_output_p(0),
+       m_writer_p(0)
+{ }
+
+
+SC_TEMPLATE // Explicitly named object instance constructor.
+inline sc_signal<sc_dt::sc_biguint<W> >::sc_signal(const char* name_) :
+       sc_prim_channel(name_),
+       m_changed_event_p(0),
+       m_new_val(W),
+       m_output_p(0),
+       m_writer_p(0)
+{ }
+
+
+SC_TEMPLATE // Object instance destructor.
+inline sc_signal<sc_dt::sc_biguint<W> >::~sc_signal()
+{
+       if ( m_changed_event_p ) delete m_changed_event_p;
+}
+
+
+SC_TEMPLATE // Update the current value from new value.
+inline void sc_signal<sc_dt::sc_biguint<W> >::update()
+{
+    if ( m_changed_event_p )
+    {
+        if ( m_new_val != *this )
+        {
+            m_changed_event_p->notify_delayed();
+            m_event_delta = simcontext()->delta_count();
+        }
+    }
+       sc_dt::sc_unsigned::operator = (m_new_val);
+}
+
+
+SC_TEMPLATE // Return the value changed event.
+inline const sc_event& sc_signal<sc_dt::sc_biguint<W> >::value_changed_event() const
+       { return base_value_changed_event(); }
+
+
+SC_TEMPLATE // Write a sc_in<sc_dt::sc_biguint<W> > value to this object instance.
+inline void sc_signal<sc_dt::sc_biguint<W> >::write(
+       const sc_in<sc_dt::sc_biguint<W> >& value )
+       { base_write( value ); }
+
+
+SC_TEMPLATE // Write a sc_inout<sc_dt::sc_biguint<W> > value to this object instance.
+inline void sc_signal<sc_dt::sc_biguint<W> >::write(
+       const sc_inout<sc_dt::sc_biguint<W> >& value )
+{ base_write( value ); }
+
+
+SC_TEMPLATE // Write a sc_dt::sc_biguint<W> value to this object instance.
+inline void sc_signal<sc_dt::sc_biguint<W> >::write( const sc_dt::sc_biguint<W>& value )
+       { base_write( value); }
+
+
+SC_TEMPLATE // Write a portion of a value. If this is the first write in
+            // a delta cycle we copy the existing value before setting the bits.
+inline void sc_signal<sc_dt::sc_biguint<W> >::write_part(sc_dt::int64 v, int left, int right)
+{
+       m_new_val(left, right) = v;
+       request_update();
+}
+
+
+SC_TEMPLATE // Select a portion of a value.
+inline sc_unsigned_sigref& sc_signal<sc_dt::sc_biguint<W> >::select_part(
+       int left, int right)
+{
+    sc_unsigned_sigref* result_p = sc_unsigned_sigref::m_pool.allocate();
+    result_p->initialize(dynamic_cast<sc_unsigned_part_if*>(this), left, right);
+    return *result_p;
+}
+
+
+SC_TEMPLATE // Write a portion of a value. If this is the first write in
+            // a delta cycle we copy the existing value before setting the bits.
+inline void sc_signal<sc_dt::sc_biguint<W> >::write_part(sc_dt::uint64 v, int left, int right)
+{
+       m_new_val(left, right) = v;
+       request_update();
+}
+
+
+SC_TEMPLATE // Write a portion of a value. If this is the first write in
+            // a delta cycle we copy the existing value before setting the bits.
+inline void sc_signal<sc_dt::sc_biguint<W> >::write_part(
+       const sc_dt::sc_signed& v, int left, int right )
+{
+       m_new_val(left, right) = v;
+       request_update();
+}
+
+
+SC_TEMPLATE // Write a portion of a value. If this is the first write in
+            // a delta cycle we copy the existing value before setting the bits.
+inline void sc_signal<sc_dt::sc_biguint<W> >::write_part(
+       const sc_dt::sc_unsigned& v, int left, int right )
+{
+       m_new_val(left, right) = v;
+       request_update();
+}
+
+
+//==============================================================================
+// CLASS sc_in<sc_dt::sc_biguint<W> >
+//
+// This class implements an input port whose target acts like an sc_dt::sc_biguint<W> data
+// value. This class is a specialization of the generic sc_in class to
+// implement tailored support for the sc_dt::sc_biguint<W> class.
+//==============================================================================
+SC_TEMPLATE
+class sc_in<sc_dt::sc_biguint<W> > :
+    public sc_port<sc_signal_in_if<sc_dt::sc_biguint<W> >, 1,
+                   SC_ONE_OR_MORE_BOUND>,
+    public sc_dt::sc_value_base
+{
+  public:
+
+    // typedefs
+
+    typedef sc_dt::sc_biguint<W>                      data_type;
+    typedef sc_signal_in_if<sc_dt::sc_biguint<W> >    if_type;
+    typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND>   base_type;
+    typedef sc_in<sc_dt::sc_biguint<W> >              this_type;
+
+    typedef if_type                                   in_if_type;
+    typedef base_type                                 in_port_type;
+    typedef sc_signal_inout_if<sc_dt::sc_biguint<W> > inout_if_type;
+    typedef sc_inout<sc_dt::sc_biguint<W> >           inout_port_type;
+
+  public:
+
+    // bind methods and operators:
+
+    void bind( const in_if_type& interface_ )
+        { sc_port_base::bind( const_cast<in_if_type&>( interface_) );}
+    void operator () ( const in_if_type& interface_ )
+        { sc_port_base::bind( const_cast<in_if_type&>( interface_) );}
+    void bind( in_port_type& parent_ )
+        { sc_port_base::bind(parent_);}
+    void operator () ( in_port_type& parent_ )
+        { sc_port_base::bind(parent_);}
+    void bind( inout_port_type& parent_ )
+        { sc_port_base::bind(parent_);}
+    void operator () ( inout_port_type& parent_ )
+        { sc_port_base::bind(parent_);}
+
+  protected:
+    // called by pbind (for internal use only)
+    virtual inline int vbind( sc_interface& interface_ )
+        {
+            return sc_port_b<if_type>::vbind( interface_ );
+        }
+    virtual inline int vbind( sc_port_base& parent_ )
+        {
+            in_port_type* in_parent = dynamic_cast<in_port_type*>( &parent_ );
+            if( in_parent != 0 ) {
+                sc_port_base::bind( *in_parent );
+                return 0;
+            }
+            inout_port_type* inout_parent = dynamic_cast<inout_port_type*>( &parent_ );
+            if( inout_parent != 0 ) {
+                sc_port_base::bind( *inout_parent );
+                return 0;
+            }
+            // type mismatch
+            return 2;
+        }
+
+
+    // constructors
+
+  public:
+    sc_in()
+        : base_type(), m_traces( 0 )
+        {}
+
+    explicit sc_in( const char* name_ )
+        : base_type( name_ ), m_traces( 0 )
+        {}
+
+    explicit sc_in( const in_if_type& interface_ )
+        : base_type( const_cast<in_if_type&>( interface_ ) ), m_traces( 0 )
+        {}
+
+    sc_in( const char* name_, const in_if_type& interface_ )
+        : base_type( name_, const_cast<in_if_type&>( interface_ ) ), m_traces( 0 )
+        {}
+
+    explicit sc_in( in_port_type& parent_ )
+        : base_type( parent_ ), m_traces( 0 )
+        {}
+
+    sc_in( const char* name_, in_port_type& parent_ )
+        : base_type( name_, parent_ ), m_traces( 0 )
+        {}
+
+    explicit sc_in( inout_port_type& parent_ )
+        : base_type(), m_traces( 0 )
+        { sc_port_base::bind( parent_ ); }
+
+    sc_in( const char* name_, inout_port_type& parent_ )
+        : base_type( name_ ), m_traces( 0 )
+        { sc_port_base::bind( parent_ ); }
+
+    sc_in( this_type& parent_ )
+        : base_type( parent_ ), m_traces( 0 )
+        {}
+
+    sc_in( const char* name_, this_type& parent_ )
+        : base_type( name_, parent_ ), m_traces( 0 )
+        {}
+
+
+    // destructor
+
+    virtual inline ~sc_in()
+        {
+            remove_traces();
+        }
+
+    // bit and part selection
+
+    sc_dt::sc_unsigned_bitref_r operator [] ( int i ) const
+        { return (*this)->read()[i]; }
+    sc_dt::sc_unsigned_bitref_r bit( int i ) const
+        { return (*this)->read()[i]; }
+    sc_dt::sc_unsigned_subref_r operator () ( int left, int right ) const
+        { return (*this)->read()(left,right); }
+    sc_dt::sc_unsigned_subref_r range( int left, int right ) const
+        { return (*this)->read()(left,right); }
+
+
+    // interface access shortcut methods
+
+    // get the default event
+
+    const sc_event& default_event() const
+        { return (*this)->value_changed_event(); }
+
+
+    // get the value changed event
+
+    const sc_event& value_changed_event() const
+        { return (*this)->value_changed_event(); }
+
+
+    // read the current value
+
+    const sc_dt::sc_biguint<W>& read() const
+        { return (*this)->read(); }
+
+    operator const sc_dt::sc_biguint<W>& () const
+        { return (*this)->read(); }
+
+    // was there a value changed event?
+
+    bool event() const
+        { return (*this)->event(); }
+
+
+    // (other) event finder method(s)
+
+    sc_event_finder& value_changed() const
+        {
+            return *new sc_event_finder_t<in_if_type>(
+                *this, &in_if_type::value_changed_event );
+        }
+
+
+
+    // reduction methods:
+
+    inline bool and_reduce() const
+        { return (*this)->read().and_reduce(); }
+    inline bool nand_reduce() const
+        { return (*this)->read().nand_reduce(); }
+    inline bool nor_reduce() const
+        { return (*this)->read().nor_reduce(); }
+    inline bool or_reduce() const
+        { return (*this)->read().or_reduce(); }
+    inline bool xnor_reduce() const
+        { return (*this)->read().xnor_reduce(); }
+    inline bool xor_reduce() const
+        { return (*this)->read().xor_reduce(); }
+
+
+    // called when elaboration is done
+    /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+    /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+    virtual inline void end_of_elaboration()
+        {
+            if( m_traces != 0 ) {
+                for( unsigned int i = 0; i < m_traces->size(); ++ i ) {
+                    sc_trace_params* p = (*m_traces)[i];
+                    sc_trace( p->tf, read(), p->name );
+                }
+                remove_traces();
+            }
+        }
+
+    virtual inline const char* kind() const
+        { return "sc_in"; }
+
+
+    // called by sc_trace
+    void add_trace( sc_trace_file* tf_, const std::string& name_ ) const
+        {
+            if( tf_ != 0 ) {
+                if( m_traces == 0 ) {
+                    m_traces = new sc_trace_params_vec;
+                }
+                m_traces->push_back( new sc_trace_params( tf_, name_ ) );
+            }
+        }
+
+
+    // concatenation methods
+
+    virtual inline int concat_length(bool* xz_present_p) const
+        { return (*this)->read().concat_length( xz_present_p ); }
+    virtual inline sc_dt::uint64 concat_get_uint64() const
+        { return (*this)->read().concat_get_uint64(); }
+    virtual inline bool concat_get_ctrl( sc_dt::sc_digit* dst_p, int low_i ) const
+        { return (*this)->read().concat_get_ctrl(dst_p, low_i); }
+    virtual inline bool concat_get_data( sc_dt::sc_digit* dst_p, int low_i ) const
+        { return (*this)->read().concat_get_data(dst_p, low_i); }
+
+  protected:
+    void remove_traces() const
+        {
+            if( m_traces != 0 ) {
+                for( int i = m_traces->size() - 1; i >= 0; -- i ) {
+                    delete (*m_traces)[i];
+                }
+                delete m_traces;
+                m_traces = 0;
+            }
+        }
+
+    mutable sc_trace_params_vec* m_traces;
+
+
+  private:
+
+    // disabled
+    sc_in( const sc_in<sc_dt::sc_biguint<W> >& );
+    sc_in<sc_dt::sc_biguint<W> >& operator = ( const sc_in<sc_dt::sc_biguint<W> >& );
+
+#ifdef __GNUC__
+    // Needed to circumvent a problem in the g++-2.95.2 compiler:
+    // This unused variable forces the compiler to instantiate
+    // an object of T template so an implicit conversion from
+    // read() to a C++ intrinsic data type will work.
+    static data_type dummy;
+#endif
+
+};
+
+
+
+SC_TEMPLATE
+inline std::ostream& operator << (
+    std::ostream& os, const sc_in<sc_dt::sc_biguint<W> >& a )
+{
+    a.read().print( os );
+    return os;
+}
+
+
+//==============================================================================
+// CLASS sc_inout<sc_dt::sc_biguint<W> >
+//
+// This class implements an input/output port whose target acts like an
+// sc_dt::sc_biguint<W> data value. It is derived from the sc_unsigned_in. This class is a
+// specialization of the generic sc_inout class to implement tailored support
+// for the sc_dt::sc_biguint<W> class.
+//==============================================================================
+SC_TEMPLATE
+class sc_inout<sc_dt::sc_biguint<W> > :
+    public sc_port<sc_signal_inout_if<sc_dt::sc_biguint<W> >, 1,
+                   SC_ONE_OR_MORE_BOUND>,
+    public sc_dt::sc_value_base
+{
+  public:
+
+    // typedefs
+
+    typedef sc_dt::sc_biguint<W>                      data_type;
+    typedef sc_signal_inout_if<sc_dt::sc_biguint<W> > if_type;
+    typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND>   base_type;
+    typedef sc_inout<sc_dt::sc_biguint<W> >           this_type;
+
+    typedef if_type                                   inout_if_type;
+    typedef base_type                                 inout_port_type;
+
+  public:
+
+    // bind methods and operators:
+
+    void bind( const inout_if_type& interface_ )
+        { sc_port_base::bind( const_cast<inout_if_type&>( interface_) ); }
+    void operator () ( const inout_if_type& interface_ )
+        { sc_port_base::bind( const_cast<inout_if_type&>( interface_) ); }
+    void bind( inout_port_type& parent_ )
+        { sc_port_base::bind(parent_); }
+    void operator () ( inout_port_type& parent_ )
+        { sc_port_base::bind(parent_); }
+
+  protected:
+    // called by pbind (for internal use only)
+    virtual inline int vbind( sc_interface& interface_ )
+        {
+            return sc_port_b<if_type>::vbind( interface_ );
+        }
+    virtual inline int vbind( sc_port_base& parent_ )
+        {
+            inout_port_type* inout_parent = dynamic_cast<inout_port_type*>( &parent_ );
+            if( inout_parent != 0 ) {
+                sc_port_base::bind( *inout_parent );
+                return 0;
+            }
+            // type mismatch
+            return 2;
+        }
+
+
+    // constructors
+
+  public:
+    sc_inout()
+        : base_type(), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    explicit sc_inout( const char* name_ )
+        : base_type( name_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    explicit sc_inout( inout_if_type& interface_ )
+        : base_type( interface_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    sc_inout( const char* name_, inout_if_type& interface_ )
+        : base_type( name_, interface_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    explicit sc_inout( inout_port_type& parent_ )
+        : base_type( parent_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    sc_inout( const char* name_, inout_port_type& parent_ )
+        : base_type( name_, parent_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    sc_inout( this_type& parent_ )
+        : base_type( parent_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+    sc_inout( const char* name_, this_type& parent_ )
+        : base_type( name_, parent_ ), m_init_val_p(0), m_traces( 0 )
+        {}
+
+
+    // destructor
+
+    virtual inline ~sc_inout()
+        {
+            remove_traces();
+        }
+
+    // bit and part selection
+
+    sc_dt::sc_unsigned_bitref_r operator [] ( int i ) const
+        { return (*this)->read()[i]; }
+    sc_dt::sc_unsigned_bitref_r bit( int i ) const
+        { return (*this)->read()[i]; }
+    sc_unsigned_sigref& operator [] ( int i )
+        { return (*this)->select_part(i,i); }
+    sc_unsigned_sigref& bit( int i )
+        { return (*this)->select_part(i,i); }
+    sc_dt::sc_unsigned_subref_r operator () ( int left, int right ) const
+        { return (*this)->read()(left,right); }
+    sc_dt::sc_unsigned_subref_r range( int left, int right ) const
+        { return (*this)->read()(left,right); }
+    sc_unsigned_sigref& operator () ( int left, int right )
+        { return (*this)->select_part(left,right); }
+    sc_unsigned_sigref& range( int left, int right )
+        { return (*this)->select_part(left,right); }
+
+
+    // interface access shortcut methods
+
+    // get the default event
+
+    const sc_event& default_event() const
+        { return (*this)->value_changed_event(); }
+
+
+    // get the value changed event
+
+    const sc_event& value_changed_event() const
+        { return (*this)->value_changed_event(); }
+
+
+    // read the current value
+
+    const sc_dt::sc_biguint<W>& read() const
+        { return (*this)->read(); }
+
+    operator const sc_dt::sc_biguint<W>& () const
+        { return (*this)->read(); }
+
+    // was there a value changed event?
+
+    bool event() const
+        { return (*this)->event(); }
+
+
+    // (other) event finder method(s)
+
+    sc_event_finder& value_changed() const
+        {
+            return *new sc_event_finder_t<inout_if_type>(
+                *this, &inout_if_type::value_changed_event );
+        }
+
+
+
+    // reduction methods:
+
+    inline bool and_reduce() const
+        { return (*this)->read().and_reduce(); }
+    inline bool nand_reduce() const
+        { return (*this)->read().nand_reduce(); }
+    inline bool nor_reduce() const
+        { return (*this)->read().nor_reduce(); }
+    inline bool or_reduce() const
+        { return (*this)->read().or_reduce(); }
+    inline bool xnor_reduce() const
+        { return (*this)->read().xnor_reduce(); }
+    inline bool xor_reduce() const
+        { return (*this)->read().xor_reduce(); }
+
+
+    // called when elaboration is done
+    /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+    /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+    virtual inline void end_of_elaboration()
+        {
+            if( m_init_val_p != 0 ) {
+                (*this)->write( *m_init_val_p );
+                delete m_init_val_p;
+                m_init_val_p = 0;
+            }
+            if( m_traces != 0 ) {
+                for( unsigned int i = 0; i < m_traces->size(); ++ i ) {
+                    sc_trace_params* p = (*m_traces)[i];
+                    sc_trace( p->tf, read(), p->name );
+                }
+                remove_traces();
+            }
+        }
+
+    virtual inline const char* kind() const
+        { return "sc_inout"; }
+
+    // value initialization
+
+    inline void initialize( const sc_dt::sc_biguint<W>& value_ )
+    {
+        inout_if_type* iface = dynamic_cast<inout_if_type*>( this->get_interface() );
+        if( iface != 0 ) {
+            iface->write( value_ );
+        } else {
+            if( m_init_val_p == 0 ) {
+                m_init_val_p = new sc_dt::sc_biguint<W>;
+            }
+            *m_init_val_p = value_;
+        }
+    }
+
+
+    // called by sc_trace
+    void add_trace( sc_trace_file* tf_, const std::string& name_ ) const
+        {
+            if( tf_ != 0 ) {
+                if( m_traces == 0 ) {
+                    m_traces = new sc_trace_params_vec;
+                }
+                m_traces->push_back( new sc_trace_params( tf_, name_ ) );
+            }
+        }
+
+
+    // concatenation methods
+
+    virtual inline int concat_length(bool* xz_present_p) const
+        { return (*this)->read().concat_length( xz_present_p ); }
+    virtual inline sc_dt::uint64 concat_get_uint64() const
+        { return (*this)->read().concat_get_uint64(); }
+    virtual inline bool concat_get_ctrl( sc_dt::sc_digit* dst_p, int low_i ) const
+        { return (*this)->read().concat_get_ctrl(dst_p, low_i); }
+    virtual inline bool concat_get_data( sc_dt::sc_digit* dst_p, int low_i ) const
+        { return (*this)->read().concat_get_data(dst_p, low_i); }
+    virtual inline void concat_set(sc_dt::int64 src, int low_i)
+        { *this = (src >> ((low_i < 64) ? low_i : 63)); }
+#if 0 // ####
+    virtual inline void concat_set(const sc_dt::sc_lv_base& src, int low_i)
+        { *this = src >> low_i; }
+#endif // 0 ####
+    virtual inline void concat_set(const sc_dt::sc_signed& src, int low_i)
+        { *this = (src >> low_i); }
+    virtual inline void concat_set(const sc_dt::sc_unsigned& src, int low_i)
+        { *this = (src >> low_i); }
+    virtual inline void concat_set(sc_dt::uint64 src, int low_i)
+        { *this = (low_i < 64 ) ? src >> low_i : (sc_dt::uint64)0; }
+
+    // assignment operators:
+
+  public:
+       inline void operator = ( const this_type& new_val )
+               { (*this)->write( (const sc_dt::sc_unsigned&)new_val ); }
+    inline void operator = ( const char* new_val )
+               { sc_dt::sc_unsigned aa(W); aa = new_val; (*this)->write( aa ); }
+    inline void operator = ( sc_dt::uint64 new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( sc_dt::int64 new_val )
+        { (*this)->write((sc_dt::int64)new_val); }
+    inline void operator = ( int new_val )
+        { (*this)->write((sc_dt::int64)new_val); }
+    inline void operator = ( long new_val )
+        { (*this)->write((sc_dt::int64)new_val); }
+    inline void operator = ( short new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned int new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned long new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned short new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    template<typename T>
+    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val )
+               {
+                       sc_dt::sc_unsigned temp(W);
+                       new_val->to_sc_unsigned(temp);
+            (*this)->write(temp);
+               }
+    inline void operator = ( const sc_dt::sc_signed& new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( const sc_dt::sc_unsigned& new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( const sc_dt::sc_bv_base& new_val )
+        { (*this)->write((sc_dt::sc_biguint<W>)new_val); }
+    inline void operator = ( const sc_dt::sc_lv_base& new_val )
+        { (*this)->write((sc_dt::sc_biguint<W>)new_val); }
+
+    inline void write( const sc_in<sc_dt::sc_biguint<W> >& new_val )
+        { (*this)->write( new_val.read() ); }
+    inline void write( const sc_inout<sc_dt::sc_biguint<W> >& new_val )
+        { (*this)->write( new_val.read() ); }
+    inline void write( const sc_dt::sc_biguint<W>& new_val )
+        { (*this)->write( new_val ); }
+
+  protected:
+    void remove_traces() const
+        {
+            if( m_traces != 0 ) {
+                for( int i = m_traces->size() - 1; i >= 0; -- i ) {
+                    delete (*m_traces)[i];
+                }
+                delete m_traces;
+                m_traces = 0;
+            }
+        }
+
+    sc_dt::sc_biguint<W>*               m_init_val_p;
+    mutable sc_trace_params_vec* m_traces;
+
+
+  private:
+
+    // disabled
+    sc_inout( const sc_inout<sc_dt::sc_biguint<W> >& );
+
+#ifdef __GNUC__
+    // Needed to circumvent a problem in the g++-2.95.2 compiler:
+    // This unused variable forces the compiler to instantiate
+    // an object of T template so an implicit conversion from
+    // read() to a C++ intrinsic data type will work.
+    static data_type dummy;
+#endif
+
+};
+
+
+
+SC_TEMPLATE
+inline std::ostream& operator << (
+    std::ostream& os, const sc_inout<sc_dt::sc_biguint<W> >& a )
+{
+    a.read().print( os );
+    return os;
+}
+
+
+//==============================================================================
+// CLASS sc_out<sc_dt::sc_biguint<W> >
+//
+// This class implements an output port whose target acts like an
+// sc_dt::sc_biguint<W> data value. This class is a derivation of sc_inout, since
+// output ports are really no different from input/output ports.
+//==============================================================================
+SC_TEMPLATE
+class sc_out<sc_dt::sc_biguint<W> > : public sc_inout<sc_dt::sc_biguint<W> >
+{
+  public:
+
+    // typedefs
+
+    typedef sc_dt::sc_biguint<W>                          data_type;
+
+    typedef sc_out<data_type>                   this_type;
+    typedef sc_inout<data_type>                 base_type;
+
+    typedef typename base_type::inout_if_type   inout_if_type;
+    typedef typename base_type::inout_port_type inout_port_type;
+
+    // constructors
+
+    sc_out()
+        : base_type()
+        {}
+
+    explicit sc_out( const char* name_ )
+        : base_type( name_ )
+        {}
+
+    explicit sc_out( inout_if_type& interface_ )
+        : base_type( interface_ )
+        {}
+
+    sc_out( const char* name_, inout_if_type& interface_ )
+        : base_type( name_, interface_ )
+        {}
+
+    explicit sc_out( inout_port_type& parent_ )
+        : base_type( parent_ )
+        {}
+
+    sc_out( const char* name_, inout_port_type& parent_ )
+        : base_type( name_, parent_ )
+        {}
+
+    sc_out( this_type& parent_ )
+        : base_type( parent_ )
+        {}
+
+    sc_out( const char* name_, this_type& parent_ )
+        : base_type( name_, parent_ )
+        {}
+
+
+    // destructor (does nothing)
+
+    virtual inline ~sc_out()
+        {}
+
+
+    // assignment operators:
+
+  public:
+       inline void operator = ( const this_type& new_val )
+               { (*this)->write( (const sc_dt::sc_unsigned&)new_val ); }
+    inline void operator = ( const char* new_val )
+               { sc_dt::sc_unsigned aa(W); aa = new_val; (*this)->write( aa ); }
+    inline void operator = ( sc_dt::uint64 new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( sc_dt::int64 new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( int new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( long new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( short new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned int new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned long new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    inline void operator = ( unsigned short new_val )
+        { (*this)->write((sc_dt::uint64)new_val); }
+    template<typename T>
+    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val )
+               {
+                       sc_dt::sc_unsigned temp(W);
+                       new_val->to_sc_unsigned(temp);
+            (*this)->write(temp);
+               }
+    inline void operator = ( const sc_dt::sc_signed& new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( const sc_dt::sc_unsigned& new_val )
+        { (*this)->write(new_val); }
+    inline void operator = ( const sc_dt::sc_bv_base& new_val )
+        { (*this)->write((sc_dt::sc_biguint<W>)new_val); }
+    inline void operator = ( const sc_dt::sc_lv_base& new_val )
+        { (*this)->write((sc_dt::sc_biguint<W>)new_val); }
+
+  private:
+
+    // disabled
+    sc_out( const this_type& );
+};
+
+
+
+//------------------------------------------------------------------------------
+//"sc_unsigned_sigref::initialize"
+//
+// This method initializes an object instance from the supplied arguments.
+//     if_p   -> target of this selection.
+//     left_  =  left-most bit in selection.
+//     right_ =  right-most bit in selection.
+//------------------------------------------------------------------------------
+inline void sc_unsigned_sigref::initialize(
+       sc_unsigned_part_if* if_p, int left_, int right_ )
+{
+    m_if_p = if_p;
+    m_left = left_;
+    m_right = right_;
+       m_obj_p = if_p->part_read_target();
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_unsigned_sigref::operator ="
+//
+// These operators assign a value to the bits associated with this object
+// instance within this object instance's target signal.
+//------------------------------------------------------------------------------
+inline void sc_unsigned_sigref::operator = ( sc_dt::uint64 v )
+{
+       m_if_p->write_part( v, m_left, m_right );
+}
+
+inline void sc_unsigned_sigref::operator = ( const char* v )
+{
+       sc_dt::sc_unsigned tmp(length());
+       tmp = v;
+       *this = tmp;
+}
+
+inline void sc_unsigned_sigref:: operator = ( sc_dt::int64 v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+inline void sc_unsigned_sigref:: operator = ( int v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+inline void sc_unsigned_sigref:: operator = ( long v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+inline void sc_unsigned_sigref:: operator = ( unsigned int v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+inline void sc_unsigned_sigref:: operator = ( unsigned long v )
+{
+    *this = (sc_dt::uint64)v;
+}
+
+void sc_unsigned_sigref::operator = ( const sc_unsigned_sigref& v )
+{
+    *this = (sc_dt::sc_unsigned)v;
+}
+
+
+inline void sc_unsigned_sigref:: operator = ( const sc_dt::sc_signed& v )
+{
+       m_if_p->write_part( v, m_left, m_right );
+}
+
+inline void sc_unsigned_sigref:: operator = ( const sc_dt::sc_unsigned& v )
+{
+       m_if_p->write_part( v, m_left, m_right );
+}
+
+template<typename T>
+inline void sc_unsigned_sigref:: operator = (
+       const sc_dt::sc_generic_base<T>& v )
+{
+       sc_dt::sc_unsigned temp(m_left-m_right+1);
+    v->to_sc_unsigned(temp);
+       m_if_p->write_part( temp, m_left, m_right );
+}
+
+#undef SC_TEMPLATE
+} // namespace sc_core
+#endif // !defined(SC_SIGNAL_UNSIGNED_H)
+
+namespace sc_core {
+
+extern
+void
+sc_signal_invalid_writer( const char* name,
+                          const char* kind,
+                          const char* first_writer,
+                          const char* second_writer );
+
+//------------------------------------------------------------------------------
+// POOL OF TEMPORARY INSTANCES OF sc_unsigned_sigref
+//
+// This allows use to pass const references for part and bit selections
+// on sc_signal_signed object instances.
+//------------------------------------------------------------------------------
+sc_vpool<sc_unsigned_sigref> sc_unsigned_sigref::m_pool(8);
+
+
+//------------------------------------------------------------------------------
+//"sc_unsigned_part_if::default methods"
+//
+// These versions just produce errors if they are not overloaded but used.
+//------------------------------------------------------------------------------
+sc_dt::sc_unsigned* sc_unsigned_part_if::part_read_target()
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+    return 0;
+}
+sc_dt::sc_unsigned sc_unsigned_part_if::read_part( int /*left*/, int /*right*/ ) const
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+    return sc_dt::sc_unsigned(1);
+}
+sc_unsigned_sigref& sc_unsigned_part_if::select_part(int /*left*/, int /*right*/)
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+    return *(sc_unsigned_sigref*)0;
+}
+void sc_unsigned_part_if::write_part( sc_dt::int64 v, int /*left*/, int /*right*/ )
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+}
+void sc_unsigned_part_if::write_part( sc_dt::uint64 v, int /*left*/, int /*right*/ )
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+}
+void sc_unsigned_part_if::write_part(
+    const sc_dt::sc_signed& v, int /*left*/, int /*right*/ )
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+}
+void sc_unsigned_part_if::write_part(
+    const sc_dt::sc_unsigned& v, int /*left*/, int /*right*/ )
+{
+    SC_REPORT_ERROR( "attempted specalized signal operation on "
+            "non-specialized signal", "int" );
+}
+
+
+
+//------------------------------------------------------------------------------
+//"sc_unsigned_sigref::concate_set"
+//
+// These methods assign this object instance's value from the supplied
+// value starting at the supplied bit within that value.
+//     src = value to use to set this object instance's value.
+//     low_i = bit in src that is to be the low order bit of the value to set.
+// #### OPTIMIZE
+//------------------------------------------------------------------------------
+void sc_unsigned_sigref::concat_set(sc_dt::int64 src, int low_i)
+{
+    sc_dt::int64 tmp;
+    if ( low_i < 63 )
+        tmp = src >> low_i;
+    else
+        tmp = (src < 0) ? -1 : 0;
+    m_if_p->write_part( tmp, m_left, m_right );
+}
+
+
+void sc_unsigned_sigref::concat_set(const sc_dt::sc_signed& src, int low_i)
+{
+    m_if_p->write_part( src >> low_i, m_left, m_right );
+}
+
+
+void sc_unsigned_sigref::concat_set(const sc_dt::sc_lv_base& src, int low_i)
+{
+    sc_dt::sc_unsigned tmp(src.length());
+    tmp = src;
+    m_if_p->write_part( tmp >> low_i, m_left, m_right );
+}
+
+
+void sc_unsigned_sigref::concat_set(const sc_dt::sc_unsigned& src, int low_i)
+{
+    m_if_p->write_part( src >> low_i, m_left, m_right );
+}
+
+
+void sc_unsigned_sigref::concat_set(sc_dt::uint64 src, int low_i)
+{
+    sc_dt::uint64 tmp = (low_i < 63) ? (src >> low_i) : 0;
+    m_if_p->write_part( tmp, m_left, m_right );
+}
+
+
+} // namespace sc_core