SimpleLTTarget1.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_TARGET1_H__ 21#define __SIMPLE_LT_TARGET1_H__ 22 23#include "tlm.h" 24#include <cassert> 25#include <vector> 26 27class SimpleLTTarget1 : 28 public sc_core::sc_module, 29 public virtual tlm::tlm_fw_transport_if<> 30{ 31public: 32 typedef tlm::tlm_generic_payload transaction_type; 33 typedef tlm::tlm_phase phase_type; 34 typedef tlm::tlm_sync_enum sync_enum_type; 35 typedef tlm::tlm_fw_transport_if<> fw_interface_type; 36 typedef tlm::tlm_bw_transport_if<> bw_interface_type; 37 typedef tlm::tlm_target_socket<32> target_socket_type; 38 39public: 40 target_socket_type socket; 41 42public: 43 SC_HAS_PROCESS(SimpleLTTarget1); 44 SimpleLTTarget1(sc_core::sc_module_name name, bool invalidate = false) : 45 sc_core::sc_module(name), 46 socket("socket"), 47 m_invalidate(invalidate) 48 { 49 // Bind this target's interface to the target socket 50 socket(*this); 51 if (invalidate) 52 { 53 SC_METHOD(invalidate_dmi_method); 54 sensitive << m_invalidate_dmi_event; 55 dont_initialize(); 56 m_invalidate_dmi_time = sc_core::sc_time(25, sc_core::SC_NS); 57 } 58 } 59 60 sync_enum_type nb_transport_fw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) 61 { 62 //Target never calls wait, so we can do this 63 b_transport(trans, t); 64 65 return tlm::TLM_COMPLETED; 66 } 67 68 void b_transport(transaction_type& trans, sc_core::sc_time &t) 69 { 70 sc_dt::uint64 address = trans.get_address(); 71 assert(address < 400); 72 73 unsigned int& data = *reinterpret_cast<unsigned int*>(trans.get_data_ptr()); 74 if (trans.get_command() == tlm::TLM_WRITE_COMMAND) { 75 std::cout << name() << ": Received write request: A = 0x" 76 << std::hex << (unsigned int)address 77 << ", D = 0x" << data << std::dec 78 << " @ " << sc_core::sc_time_stamp() << std::endl; 79 80 *reinterpret_cast<unsigned int*>(&mMem[address]) = data; 81 t+= sc_core::sc_time(10, sc_core::SC_NS); 82 83 } else { 84 std::cout << name() << ": Received read request: A = 0x" 85 << std::hex << (unsigned int)address << std::dec 86 << " @ " << sc_core::sc_time_stamp() << std::endl; 87 88 data = *reinterpret_cast<unsigned int*>(&mMem[address]); 89 t += sc_core::sc_time(100, sc_core::SC_NS); 90 } 91 92 trans.set_response_status(tlm::TLM_OK_RESPONSE); 93 94 trans.set_dmi_allowed(true); 95 } 96 97 unsigned int transport_dbg(transaction_type& r) 98 { 99 if (r.get_address() >= 400) return 0; 100 101 unsigned int tmp = (int)r.get_address(); 102 unsigned int num_bytes; 103 if (tmp + r.get_data_length() >= 400) { 104 num_bytes = 400 - tmp; 105 106 } else { 107 num_bytes = r.get_data_length(); 108 } 109 if (r.is_read()) { 110 for (unsigned int i = 0; i < num_bytes; ++i) { 111 r.get_data_ptr()[i] = mMem[i + tmp]; 112 } 113 114 } else { 115 for (unsigned int i = 0; i < num_bytes; ++i) { 116 mMem[i + tmp] = r.get_data_ptr()[i]; 117 } 118 } 119 return num_bytes; 120 } 121 122 bool get_direct_mem_ptr(transaction_type& trans, 123 tlm::tlm_dmi& dmi_data) 124 { 125 sc_dt::uint64 address = trans.get_address(); 126 if (m_invalidate) m_invalidate_dmi_event.notify(m_invalidate_dmi_time); 127 if (address < 400) { 128 dmi_data.allow_read_write(); 129 dmi_data.set_start_address(0x0); 130 dmi_data.set_end_address(399); 131 dmi_data.set_dmi_ptr(mMem); 132 dmi_data.set_read_latency(sc_core::sc_time(100, sc_core::SC_NS)); 133 dmi_data.set_write_latency(sc_core::sc_time(10, sc_core::SC_NS)); 134 return true; 135 136 } else { 137 // should not happen 138 dmi_data.set_start_address(trans.get_address()); 139 dmi_data.set_end_address(trans.get_address()); 140 return false; 141 142 } 143 } 144 145 void invalidate_dmi_method() 146 { 147 sc_dt::uint64 start_address = 0x0; 148 sc_dt::uint64 end_address = 399; 149 socket->invalidate_direct_mem_ptr(start_address, end_address); 150 } 151private: 152 unsigned char mMem[400]; 153 bool m_invalidate; 154 sc_core::sc_event m_invalidate_dmi_event; 155 sc_core::sc_time m_invalidate_dmi_time; 156}; 157 158#endif 159