SimpleLTTarget_ext.h revision 12855:588919e0e4aa
16691SN/A/*****************************************************************************
26691SN/A
36691SN/A  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
46691SN/A  more contributor license agreements.  See the NOTICE file distributed
56691SN/A  with this work for additional information regarding copyright ownership.
66691SN/A  Accellera licenses this file to you under the Apache License, Version 2.0
76691SN/A  (the "License"); you may not use this file except in compliance with the
86691SN/A  License.  You may obtain a copy of the License at
96691SN/A
106691SN/A    http://www.apache.org/licenses/LICENSE-2.0
116691SN/A
126691SN/A  Unless required by applicable law or agreed to in writing, software
136691SN/A  distributed under the License is distributed on an "AS IS" BASIS,
146691SN/A  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
156691SN/A  implied.  See the License for the specific language governing
166691SN/A  permissions and limitations under the License.
176691SN/A
186691SN/A *****************************************************************************/
196691SN/A
206691SN/A#ifndef __SIMPLE_LT_TARGET2_H__
216691SN/A#define __SIMPLE_LT_TARGET2_H__
226691SN/A
236691SN/A#include "tlm.h"
246691SN/A#include "tlm_utils/simple_target_socket.h"
256691SN/A#include "my_extension.h"
266691SN/A
276691SN/A//#include <systemc>
286691SN/A#include <cassert>
296691SN/A#include <vector>
306691SN/A//#include <iostream>
316691SN/A
326691SN/Aclass SimpleLTTarget_ext : public sc_core::sc_module
336691SN/A{
346691SN/Apublic:
358105Sgblack@eecs.umich.edu  typedef tlm::tlm_generic_payload              transaction_type;
368105Sgblack@eecs.umich.edu  typedef tlm::tlm_phase                        phase_type;
376691SN/A  typedef tlm::tlm_sync_enum                    sync_enum_type;
386691SN/A  typedef tlm_utils::simple_target_socket<SimpleLTTarget_ext, 32,
396691SN/A                             my_extended_payload_types> target_socket_type;
406691SN/A
416691SN/Apublic:
426691SN/A  target_socket_type socket;
436691SN/A
449897Sandreas@sandberg.pp.sepublic:
456691SN/A  SC_HAS_PROCESS(SimpleLTTarget_ext);
466691SN/A  SimpleLTTarget_ext(sc_core::sc_module_name name,
476691SN/A                     sc_core::sc_time invalidate_dmi_time = sc_core::sc_time(25, sc_core::SC_NS)) :
486691SN/A    sc_core::sc_module(name),
496691SN/A    socket("socket")
509897Sandreas@sandberg.pp.se  {
519897Sandreas@sandberg.pp.se    // register nb_transport method
527811SN/A    socket.register_nb_transport_fw(this, &SimpleLTTarget_ext::myNBTransport);
536691SN/A    socket.register_get_direct_mem_ptr(this, &SimpleLTTarget_ext::myGetDMIPtr);
548105Sgblack@eecs.umich.edu
55    socket.register_transport_dbg(this, &SimpleLTTarget_ext::transport_dbg);
56
57    SC_METHOD(invalidate_dmi_method);
58    sensitive << m_invalidate_dmi_event;
59    dont_initialize();
60    m_invalidate_dmi_time = invalidate_dmi_time;
61  }
62
63  sync_enum_type myNBTransport(transaction_type& trans, phase_type& phase, sc_core::sc_time& t)
64  {
65    sc_assert(phase == tlm::BEGIN_REQ);
66
67    my_extension* tmp_ext;
68    trans.get_extension(tmp_ext);
69    if (!tmp_ext)
70    {
71        std::cout << name() << ": ERROR, extension not present" << std::endl;
72    }
73    else
74    {
75        std::cout << name() << ": OK, extension data = "
76                  << tmp_ext->m_data << std::endl;
77    }
78    sc_dt::uint64 address = trans.get_address();
79    sc_assert(address < 400);
80
81    unsigned int& data = *reinterpret_cast<unsigned int*>(trans.get_data_ptr());
82    if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
83      std::cout << name() << ": Received write request: A = 0x"
84                << std::hex << (unsigned int)address
85                << ", D = 0x" << data << std::dec
86                << " @ " << sc_core::sc_time_stamp() << std::endl;
87
88      *reinterpret_cast<unsigned int*>(&mMem[address]) = data;
89      t += sc_core::sc_time(10, sc_core::SC_NS);
90
91    } else {
92      std::cout << name() << ": Received read request: A = 0x"
93                << std::hex << (unsigned int)address << std::dec
94                << " @ " << sc_core::sc_time_stamp() << std::endl;
95
96      data = *reinterpret_cast<unsigned int*>(&mMem[address]);
97      t += sc_core::sc_time(100, sc_core::SC_NS);
98    }
99
100    trans.set_response_status(tlm::TLM_OK_RESPONSE);
101
102    trans.set_dmi_allowed(true);
103
104    // LT target
105    // - always return true
106    // - not necessary to update phase (if true is returned)
107    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