summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-06-15 20:02:54 -0700
committerGabe Black <gabeblack@google.com>2018-08-28 21:16:31 +0000
commiteba0ab506bfa33e7810163bc255d0af4a14ac8db (patch)
treec269137367fb7a66d1377909be06f6c883f368d9 /src
parentdc0b98dcdcc8f3665eac4d924060a51493862f2e (diff)
downloadgem5-eba0ab506bfa33e7810163bc255d0af4a14ac8db.tar.xz
systemc: Add some common test include files.
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>
Diffstat (limited to 'src')
-rw-r--r--src/systemc/tests/SConscript2
-rw-r--r--src/systemc/tests/include/CoreDecouplingLTInitiator.h166
-rw-r--r--src/systemc/tests/include/ExplicitATTarget.h176
-rw-r--r--src/systemc/tests/include/ExplicitLTTarget.h124
-rw-r--r--src/systemc/tests/include/README.txt92
-rw-r--r--src/systemc/tests/include/SimpleATInitiator1.h333
-rw-r--r--src/systemc/tests/include/SimpleATInitiator2.h306
-rw-r--r--src/systemc/tests/include/SimpleATTarget1.h211
-rw-r--r--src/systemc/tests/include/SimpleATTarget2.h178
-rw-r--r--src/systemc/tests/include/SimpleBusAT.h378
-rw-r--r--src/systemc/tests/include/SimpleBusLT.h193
-rw-r--r--src/systemc/tests/include/SimpleLTInitiator1.h162
-rw-r--r--src/systemc/tests/include/SimpleLTInitiator1_DMI.h305
-rw-r--r--src/systemc/tests/include/SimpleLTInitiator2.h151
-rw-r--r--src/systemc/tests/include/SimpleLTInitiator2_DMI.h299
-rw-r--r--src/systemc/tests/include/SimpleLTInitiator3.h152
-rw-r--r--src/systemc/tests/include/SimpleLTInitiator3_DMI.h244
-rw-r--r--src/systemc/tests/include/SimpleLTTarget1.h158
-rw-r--r--src/systemc/tests/include/SimpleLTTarget2.h149
-rw-r--r--src/systemc/tests/include/specialized_signals/scx_signal_int.h1629
-rw-r--r--src/systemc/tests/include/specialized_signals/scx_signal_signed.h1833
-rw-r--r--src/systemc/tests/include/specialized_signals/scx_signal_uint.h1676
-rw-r--r--src/systemc/tests/include/specialized_signals/scx_signal_unsigned.h1834
23 files changed, 10751 insertions, 0 deletions
diff --git a/src/systemc/tests/SConscript b/src/systemc/tests/SConscript
index 81f122dab..086ffee26 100644
--- a/src/systemc/tests/SConscript
+++ b/src/systemc/tests/SConscript
@@ -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
index 000000000..b3c0e43fc
--- /dev/null
+++ b/src/systemc/tests/include/CoreDecouplingLTInitiator.h
@@ -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
index 000000000..ccde70a0e
--- /dev/null
+++ b/src/systemc/tests/include/ExplicitATTarget.h
@@ -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
index 000000000..2c308d966
--- /dev/null
+++ b/src/systemc/tests/include/ExplicitLTTarget.h
@@ -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
index 000000000..2636918b5
--- /dev/null
+++ b/src/systemc/tests/include/README.txt
@@ -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
index 000000000..8becbb9b6
--- /dev/null
+++ b/src/systemc/tests/include/SimpleATInitiator1.h
@@ -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
index 000000000..6decf11fa
--- /dev/null
+++ b/src/systemc/tests/include/SimpleATInitiator2.h
@@ -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
index 000000000..d99ec3bdd
--- /dev/null
+++ b/src/systemc/tests/include/SimpleATTarget1.h
@@ -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
index 000000000..d4f2ae7e2
--- /dev/null
+++ b/src/systemc/tests/include/SimpleATTarget2.h
@@ -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
index 000000000..db680338c
--- /dev/null
+++ b/src/systemc/tests/include/SimpleBusAT.h
@@ -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
index 000000000..a2e71d866
--- /dev/null
+++ b/src/systemc/tests/include/SimpleBusLT.h
@@ -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
index 000000000..6f1271278
--- /dev/null
+++ b/src/systemc/tests/include/SimpleLTInitiator1.h
@@ -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
index 000000000..4d982261f
--- /dev/null
+++ b/src/systemc/tests/include/SimpleLTInitiator1_DMI.h
@@ -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
index 000000000..ee0118a21
--- /dev/null
+++ b/src/systemc/tests/include/SimpleLTInitiator2.h
@@ -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
index 000000000..39fb76b1e
--- /dev/null
+++ b/src/systemc/tests/include/SimpleLTInitiator2_DMI.h
@@ -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
index 000000000..d4eb63338
--- /dev/null
+++ b/src/systemc/tests/include/SimpleLTInitiator3.h
@@ -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
index 000000000..6453a16a9
--- /dev/null
+++ b/src/systemc/tests/include/SimpleLTInitiator3_DMI.h
@@ -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
index 000000000..37ac19a21
--- /dev/null
+++ b/src/systemc/tests/include/SimpleLTTarget1.h
@@ -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
index 000000000..61558dc56
--- /dev/null
+++ b/src/systemc/tests/include/SimpleLTTarget2.h
@@ -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
index 000000000..050521de0
--- /dev/null
+++ b/src/systemc/tests/include/specialized_signals/scx_signal_int.h
@@ -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
index 000000000..bb48cecb3
--- /dev/null
+++ b/src/systemc/tests/include/specialized_signals/scx_signal_signed.h
@@ -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
index 000000000..acc4a4219
--- /dev/null
+++ b/src/systemc/tests/include/specialized_signals/scx_signal_uint.h
@@ -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
index 000000000..a356d44bd
--- /dev/null
+++ b/src/systemc/tests/include/specialized_signals/scx_signal_unsigned.h
@@ -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