1/***************************************************************************** 2 3 Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 more contributor license agreements. See the NOTICE file distributed 5 with this work for additional information regarding copyright ownership. 6 Accellera licenses this file to you under the Apache License, Version 2.0 7 (the "License"); you may not use this file except in compliance with the 8 License. You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 implied. See the License for the specific language governing 16 permissions and limitations under the License. 17 18 *****************************************************************************/ 19 20//==================================================================== 21// Nov 06, 2008 22// 23// Updated by: 24// Xiaopeng Qiu, JEDA Technologies, Inc 25// Email: qiuxp@jedatechnologies.net 26// 27// To fix violations of TLM2.0 rules, which are detected by JEDA 28// TLM2.0 checker. 29// 30//==================================================================== 31 32#ifndef __CORE_DECOUPLING_LT_INITIATOR_H__ 33#define __CORE_DECOUPLING_LT_INITIATOR_H__ 34 35#include "tlm.h" 36#include "tlm_utils/simple_initiator_socket.h" 37#include "tlm_utils/tlm_quantumkeeper.h" 38//#include <systemc> 39#include <cassert> 40//#include <iostream> 41 42class CoreDecouplingLTInitiator : public sc_core::sc_module 43{ 44public: 45 typedef tlm::tlm_generic_payload transaction_type; 46 typedef tlm_utils::simple_initiator_socket<CoreDecouplingLTInitiator> initiator_socket_type; 47 48public: 49 initiator_socket_type socket; 50 51public: 52 SC_HAS_PROCESS(CoreDecouplingLTInitiator); 53 CoreDecouplingLTInitiator(sc_core::sc_module_name name, 54 unsigned int nrOfTransactions = 0x5, 55 unsigned int baseAddress = 0) : 56 sc_core::sc_module(name), 57 socket("socket"), 58 mNrOfTransactions(nrOfTransactions), 59 mBaseAddress(baseAddress), 60 mTransactionCount(0) 61 { 62 tlm_utils::tlm_quantumkeeper::set_global_quantum(sc_core::sc_time(500, sc_core::SC_NS)); 63 mQuantumKeeper.reset(); 64 65 // Initiator thread 66 SC_THREAD(run); 67 } 68 69 bool initTransaction(transaction_type& trans) 70 { 71 if (mTransactionCount < mNrOfTransactions) { 72 trans.set_address(mBaseAddress + 4*mTransactionCount); 73 mData = mTransactionCount; 74 trans.set_command(tlm::TLM_WRITE_COMMAND); 75 76 } else if (mTransactionCount < 2 * mNrOfTransactions) { 77 trans.set_address(mBaseAddress + 4*(mTransactionCount - mNrOfTransactions)); 78 mData = 0; 79 trans.set_command(tlm::TLM_READ_COMMAND); 80 81 } else { 82 return false; 83 } 84 85 trans.set_data_ptr(reinterpret_cast<unsigned char*>(&mData)); 86 trans.set_data_length(4); 87 trans.set_streaming_width(4); 88 trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); 89 90 ++mTransactionCount; 91 return true; 92 } 93 94 void logStartTransation(transaction_type& trans) 95 { 96 if (trans.get_command() == tlm::TLM_WRITE_COMMAND) { 97 std::cout << name() << ": Send write request: A = 0x" 98 << std::hex << (unsigned int)trans.get_address() 99 << ", D = 0x" << mData << std::dec 100 << " @ " << mQuantumKeeper.get_current_time() 101 << " (" << sc_core::sc_time_stamp() << " + " 102 << mQuantumKeeper.get_local_time() << ")" 103 << std::endl; 104 105 } else { 106 std::cout << name() << ": Send read request: A = 0x" 107 << std::hex << (unsigned int)trans.get_address() 108 << " @ " << mQuantumKeeper.get_current_time() 109 << " (" << sc_core::sc_time_stamp() << " + " 110 << mQuantumKeeper.get_local_time() << ")" 111 << std::endl; 112 } 113 } 114 115 void logEndTransaction(transaction_type& trans) 116 { 117 if (trans.get_response_status() != tlm::TLM_OK_RESPONSE) { 118 std::cout << name() << ": Received error response @ " 119 << mQuantumKeeper.get_current_time() 120 << " (" << sc_core::sc_time_stamp() << " + " 121 << mQuantumKeeper.get_local_time() << ")" 122 << std::endl; 123 124 } else { 125 std::cout << name() << ": Received ok response"; 126 if (trans.get_command() == tlm::TLM_READ_COMMAND) { 127 std::cout << ": D = 0x" << std::hex << mData << std::dec; 128 } 129 std::cout << " @ " << mQuantumKeeper.get_current_time() 130 << " (" << sc_core::sc_time_stamp() << " + " 131 << mQuantumKeeper.get_local_time() << ")" 132 << std::endl; 133 } 134 } 135 136 void run() 137 { 138 transaction_type trans; 139 140 while (initTransaction(trans)) { 141 logStartTransation(trans); 142 143 // exec instr 144 sc_core::sc_time t = mQuantumKeeper.get_local_time(); 145 socket->b_transport(trans, t); 146 mQuantumKeeper.set(t); 147 // Target may have added a delay to the quantum -> sync if needed 148 if (mQuantumKeeper.need_sync()) { 149 std::cout << "Sync'ing..." << std::endl; 150 mQuantumKeeper.sync(); 151 } 152 153 logEndTransaction(trans); 154 } 155 wait(); 156 } 157 158private: 159 unsigned int mNrOfTransactions; 160 unsigned int mBaseAddress; 161 unsigned int mTransactionCount; 162 unsigned int mData; 163 tlm_utils::tlm_quantumkeeper mQuantumKeeper; 164}; 165 166#endif 167