SimpleLTTarget_ext.h revision 12855
112027Sjungma@eit.uni-kl.de/*****************************************************************************
212027Sjungma@eit.uni-kl.de
312027Sjungma@eit.uni-kl.de  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412027Sjungma@eit.uni-kl.de  more contributor license agreements.  See the NOTICE file distributed
512027Sjungma@eit.uni-kl.de  with this work for additional information regarding copyright ownership.
612027Sjungma@eit.uni-kl.de  Accellera licenses this file to you under the Apache License, Version 2.0
712027Sjungma@eit.uni-kl.de  (the "License"); you may not use this file except in compliance with the
812027Sjungma@eit.uni-kl.de  License.  You may obtain a copy of the License at
912027Sjungma@eit.uni-kl.de
1012027Sjungma@eit.uni-kl.de    http://www.apache.org/licenses/LICENSE-2.0
1112027Sjungma@eit.uni-kl.de
1212027Sjungma@eit.uni-kl.de  Unless required by applicable law or agreed to in writing, software
1312027Sjungma@eit.uni-kl.de  distributed under the License is distributed on an "AS IS" BASIS,
1412027Sjungma@eit.uni-kl.de  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512027Sjungma@eit.uni-kl.de  implied.  See the License for the specific language governing
1612027Sjungma@eit.uni-kl.de  permissions and limitations under the License.
1712027Sjungma@eit.uni-kl.de
1812027Sjungma@eit.uni-kl.de *****************************************************************************/
1912027Sjungma@eit.uni-kl.de
2012027Sjungma@eit.uni-kl.de#ifndef __SIMPLE_LT_TARGET2_H__
2112027Sjungma@eit.uni-kl.de#define __SIMPLE_LT_TARGET2_H__
2212027Sjungma@eit.uni-kl.de
2312027Sjungma@eit.uni-kl.de#include "tlm.h"
2412027Sjungma@eit.uni-kl.de#include "tlm_utils/simple_target_socket.h"
2512027Sjungma@eit.uni-kl.de#include "my_extension.h"
2612027Sjungma@eit.uni-kl.de
2712027Sjungma@eit.uni-kl.de//#include <systemc>
2812027Sjungma@eit.uni-kl.de#include <cassert>
2912027Sjungma@eit.uni-kl.de#include <vector>
3012027Sjungma@eit.uni-kl.de//#include <iostream>
3112027Sjungma@eit.uni-kl.de
3212027Sjungma@eit.uni-kl.declass SimpleLTTarget_ext : public sc_core::sc_module
3312027Sjungma@eit.uni-kl.de{
3412027Sjungma@eit.uni-kl.depublic:
3512027Sjungma@eit.uni-kl.de  typedef tlm::tlm_generic_payload              transaction_type;
3612027Sjungma@eit.uni-kl.de  typedef tlm::tlm_phase                        phase_type;
3712027Sjungma@eit.uni-kl.de  typedef tlm::tlm_sync_enum                    sync_enum_type;
3812027Sjungma@eit.uni-kl.de  typedef tlm_utils::simple_target_socket<SimpleLTTarget_ext, 32,
3912027Sjungma@eit.uni-kl.de                             my_extended_payload_types> target_socket_type;
4012027Sjungma@eit.uni-kl.de
4112027Sjungma@eit.uni-kl.depublic:
4212027Sjungma@eit.uni-kl.de  target_socket_type socket;
4312027Sjungma@eit.uni-kl.de
4412027Sjungma@eit.uni-kl.depublic:
4512027Sjungma@eit.uni-kl.de  SC_HAS_PROCESS(SimpleLTTarget_ext);
4612027Sjungma@eit.uni-kl.de  SimpleLTTarget_ext(sc_core::sc_module_name name,
4712027Sjungma@eit.uni-kl.de                     sc_core::sc_time invalidate_dmi_time = sc_core::sc_time(25, sc_core::SC_NS)) :
4812027Sjungma@eit.uni-kl.de    sc_core::sc_module(name),
4912027Sjungma@eit.uni-kl.de    socket("socket")
5012027Sjungma@eit.uni-kl.de  {
5112027Sjungma@eit.uni-kl.de    // register nb_transport method
5212027Sjungma@eit.uni-kl.de    socket.register_nb_transport_fw(this, &SimpleLTTarget_ext::myNBTransport);
5312027Sjungma@eit.uni-kl.de    socket.register_get_direct_mem_ptr(this, &SimpleLTTarget_ext::myGetDMIPtr);
5412027Sjungma@eit.uni-kl.de
5512027Sjungma@eit.uni-kl.de    socket.register_transport_dbg(this, &SimpleLTTarget_ext::transport_dbg);
5612027Sjungma@eit.uni-kl.de
5712027Sjungma@eit.uni-kl.de    SC_METHOD(invalidate_dmi_method);
5812027Sjungma@eit.uni-kl.de    sensitive << m_invalidate_dmi_event;
5912027Sjungma@eit.uni-kl.de    dont_initialize();
6012027Sjungma@eit.uni-kl.de    m_invalidate_dmi_time = invalidate_dmi_time;
6112027Sjungma@eit.uni-kl.de  }
6212027Sjungma@eit.uni-kl.de
6312027Sjungma@eit.uni-kl.de  sync_enum_type myNBTransport(transaction_type& trans, phase_type& phase, sc_core::sc_time& t)
6412027Sjungma@eit.uni-kl.de  {
6512027Sjungma@eit.uni-kl.de    sc_assert(phase == tlm::BEGIN_REQ);
6612027Sjungma@eit.uni-kl.de
6712027Sjungma@eit.uni-kl.de    my_extension* tmp_ext;
6812027Sjungma@eit.uni-kl.de    trans.get_extension(tmp_ext);
6912027Sjungma@eit.uni-kl.de    if (!tmp_ext)
7012027Sjungma@eit.uni-kl.de    {
7112027Sjungma@eit.uni-kl.de        std::cout << name() << ": ERROR, extension not present" << std::endl;
7212027Sjungma@eit.uni-kl.de    }
7312027Sjungma@eit.uni-kl.de    else
7412027Sjungma@eit.uni-kl.de    {
7512027Sjungma@eit.uni-kl.de        std::cout << name() << ": OK, extension data = "
7612027Sjungma@eit.uni-kl.de                  << tmp_ext->m_data << std::endl;
7712027Sjungma@eit.uni-kl.de    }
7812027Sjungma@eit.uni-kl.de    sc_dt::uint64 address = trans.get_address();
7912027Sjungma@eit.uni-kl.de    sc_assert(address < 400);
8012027Sjungma@eit.uni-kl.de
8112027Sjungma@eit.uni-kl.de    unsigned int& data = *reinterpret_cast<unsigned int*>(trans.get_data_ptr());
8212027Sjungma@eit.uni-kl.de    if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
8312027Sjungma@eit.uni-kl.de      std::cout << name() << ": Received write request: A = 0x"
8412027Sjungma@eit.uni-kl.de                << std::hex << (unsigned int)address
8512027Sjungma@eit.uni-kl.de                << ", D = 0x" << data << std::dec
8612027Sjungma@eit.uni-kl.de                << " @ " << sc_core::sc_time_stamp() << std::endl;
8712027Sjungma@eit.uni-kl.de
8812027Sjungma@eit.uni-kl.de      *reinterpret_cast<unsigned int*>(&mMem[address]) = data;
8912027Sjungma@eit.uni-kl.de      t += sc_core::sc_time(10, sc_core::SC_NS);
9012027Sjungma@eit.uni-kl.de
9112027Sjungma@eit.uni-kl.de    } else {
9212027Sjungma@eit.uni-kl.de      std::cout << name() << ": Received read request: A = 0x"
9312027Sjungma@eit.uni-kl.de                << std::hex << (unsigned int)address << std::dec
9412027Sjungma@eit.uni-kl.de                << " @ " << sc_core::sc_time_stamp() << std::endl;
9512027Sjungma@eit.uni-kl.de
9612027Sjungma@eit.uni-kl.de      data = *reinterpret_cast<unsigned int*>(&mMem[address]);
9712027Sjungma@eit.uni-kl.de      t += sc_core::sc_time(100, sc_core::SC_NS);
9812027Sjungma@eit.uni-kl.de    }
9912027Sjungma@eit.uni-kl.de
10012027Sjungma@eit.uni-kl.de    trans.set_response_status(tlm::TLM_OK_RESPONSE);
10112027Sjungma@eit.uni-kl.de
10212027Sjungma@eit.uni-kl.de    trans.set_dmi_allowed(true);
10312027Sjungma@eit.uni-kl.de
10412027Sjungma@eit.uni-kl.de    // LT target
10512027Sjungma@eit.uni-kl.de    // - always return true
10612027Sjungma@eit.uni-kl.de    // - not necessary to update phase (if true is returned)
10712027Sjungma@eit.uni-kl.de    return tlm::TLM_COMPLETED;
108  }
109
110  unsigned int transport_dbg(transaction_type& r)
111  {
112    if (r.get_address() >= 400) return 0;
113
114    unsigned int tmp = (int)r.get_address();
115    unsigned int num_bytes;
116    if (tmp + r.get_data_length() >= 400) {
117      num_bytes = 400 - tmp;
118
119    } else {
120      num_bytes = r.get_data_length();
121    }
122    if (r.is_read()) {
123      for (unsigned int i = 0; i < num_bytes; ++i) {
124        r.get_data_ptr()[i] = mMem[i + tmp];
125      }
126
127    } else {
128      for (unsigned int i = 0; i < num_bytes; ++i) {
129        mMem[i + tmp] = r.get_data_ptr()[i];
130      }
131    }
132    return num_bytes;
133  }
134
135  bool myGetDMIPtr(transaction_type& trans,
136                   tlm::tlm_dmi&  dmi_data)
137  {
138      // notify DMI invalidation, just to check if this reaches the
139      // initiators properly
140      m_invalidate_dmi_event.notify(m_invalidate_dmi_time);
141
142      // Check for DMI extension:
143      my_extension * tmp_ext;
144      trans.get_extension(tmp_ext);
145      if (tmp_ext)
146      {
147        std::cout << name() << ": get_direct_mem_ptr OK, extension data = "
148                  <<tmp_ext->m_data << std::endl;
149      }
150      else
151      {
152          std::cout << name() << ", get_direct_mem_ptr ERROR: "
153                    << "didn't get pointer to extension"
154                    << std::endl;
155      }
156      if (trans.get_address() < 400) {
157        dmi_data.allow_read_write();
158        dmi_data.set_start_address(0x0);
159        dmi_data.set_end_address(399);
160        dmi_data.set_dmi_ptr(mMem);
161        dmi_data.set_read_latency(sc_core::sc_time(100, sc_core::SC_NS));
162        dmi_data.set_write_latency(sc_core::sc_time(10, sc_core::SC_NS));
163        return true;
164
165      } else {
166        // should not happen
167        dmi_data.set_start_address(trans.get_address());
168        dmi_data.set_end_address(trans.get_address());
169        return false;
170
171      }
172  }
173
174  void invalidate_dmi_method()
175  {
176      sc_dt::uint64 start_address = 0x0;
177      sc_dt::uint64 end_address = 399;
178      socket->invalidate_direct_mem_ptr(start_address, end_address);
179  }
180private:
181  unsigned char mMem[400];
182  sc_core::sc_event m_invalidate_dmi_event;
183  sc_core::sc_time  m_invalidate_dmi_time;
184};
185
186#endif
187