SimpleLTTarget2.h revision 12922
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#ifndef __SIMPLE_LT_TARGET2_H__ 21#define __SIMPLE_LT_TARGET2_H__ 22 23#include "tlm.h" 24#include "tlm_utils/passthrough_target_socket.h" 25#include <cassert> 26#include <vector> 27 28class SimpleLTTarget2 : public sc_core::sc_module 29{ 30public: 31 typedef tlm::tlm_generic_payload transaction_type; 32 typedef tlm::tlm_phase phase_type; 33 typedef tlm::tlm_sync_enum sync_enum_type; 34 typedef tlm_utils::passthrough_target_socket<SimpleLTTarget2> target_socket_type; 35 36 37public: 38 target_socket_type socket; 39 40public: 41 SimpleLTTarget2(sc_core::sc_module_name name) : 42 sc_core::sc_module(name), 43 socket("socket") 44 { 45 // register nb_transport method 46 socket.register_b_transport(this, &SimpleLTTarget2::myBTransport); 47 socket.register_nb_transport_fw(this, &SimpleLTTarget2::myNBTransport); 48 socket.register_get_direct_mem_ptr(this, &SimpleLTTarget2::myGetDMIPtr); 49 50 // TODO: we don't register the transport_dbg callback here, so we 51 // can test if something bad happens 52 // REGISTER_DEBUGTRANSPORT(socket, transport_dbg, 0); 53 } 54 55 void myBTransport(transaction_type& trans, 56 sc_core::sc_time& t) 57 { 58 sc_dt::uint64 address = trans.get_address(); 59 assert(address < 400); 60 61 unsigned int& data = *reinterpret_cast<unsigned int*>(trans.get_data_ptr()); 62 if (trans.get_command() == tlm::TLM_WRITE_COMMAND) { 63 std::cout << name() << ": Received write request: A = 0x" 64 << std::hex << (unsigned int)address 65 << ", D = 0x" << data << std::dec 66 << " @ " << sc_core::sc_time_stamp() << std::endl; 67 68 *reinterpret_cast<unsigned int*>(&mMem[address]) = data; 69 t += sc_core::sc_time(10, sc_core::SC_NS); 70 71 } else { 72 std::cout << name() << ": Received read request: A = 0x" 73 << std::hex << (unsigned int)address << std::dec 74 << " @ " << sc_core::sc_time_stamp() << std::endl; 75 76 data = *reinterpret_cast<unsigned int*>(&mMem[address]); 77 t += sc_core::sc_time(100, sc_core::SC_NS); 78 } 79 80 trans.set_response_status(tlm::TLM_OK_RESPONSE); 81 82 trans.set_dmi_allowed(true); 83 } 84 85 sync_enum_type myNBTransport(transaction_type& trans, 86 phase_type& phase, 87 sc_core::sc_time& t) 88 { 89 assert(phase == tlm::BEGIN_REQ); 90 91 // Never blocks, so call b_transport implementation 92 myBTransport(trans, t); 93 // LT target 94 // - always return TLM_COMPLETED 95 // - not necessary to update phase (if TLM_COMPLETED is returned) 96 return tlm::TLM_COMPLETED; 97 } 98 99 unsigned int transport_dbg(transaction_type& r) 100 { 101 if (r.get_address() >= 400) return 0; 102 103 unsigned int tmp = (int)r.get_address(); 104 unsigned int num_bytes; 105 if (tmp + r.get_data_length() >= 400) { 106 num_bytes = 400 - tmp; 107 108 } else { 109 num_bytes = r.get_data_length(); 110 } 111 if (r.is_read()) { 112 for (unsigned int i = 0; i < num_bytes; ++i) { 113 r.get_data_ptr()[i] = mMem[i + tmp]; 114 } 115 116 } else { 117 for (unsigned int i = 0; i < num_bytes; ++i) { 118 mMem[i + tmp] = r.get_data_ptr()[i]; 119 } 120 } 121 return num_bytes; 122 } 123 124 bool myGetDMIPtr(transaction_type& trans, 125 tlm::tlm_dmi& dmi_data) 126 { 127 sc_dt::uint64 address = trans.get_address(); 128 if (address < 400) { 129 dmi_data.allow_read_write(); 130 dmi_data.set_start_address(0x0); 131 dmi_data.set_end_address(399); 132 dmi_data.set_dmi_ptr(mMem); 133 dmi_data.set_read_latency(sc_core::sc_time(100, sc_core::SC_NS)); 134 dmi_data.set_write_latency(sc_core::sc_time(10, sc_core::SC_NS)); 135 return true; 136 137 } else { 138 // should not happen 139 dmi_data.set_start_address(address); 140 dmi_data.set_end_address(address); 141 return false; 142 143 } 144 } 145private: 146 unsigned char mMem[400]; 147}; 148 149#endif 150