SimpleATTarget2.h revision 12922
12SN/A/*****************************************************************************
21762SN/A
37897Shestness@cs.utexas.edu  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
42SN/A  more contributor license agreements.  See the NOTICE file distributed
52SN/A  with this work for additional information regarding copyright ownership.
62SN/A  Accellera licenses this file to you under the Apache License, Version 2.0
72SN/A  (the "License"); you may not use this file except in compliance with the
82SN/A  License.  You may obtain a copy of the License at
92SN/A
102SN/A    http://www.apache.org/licenses/LICENSE-2.0
112SN/A
122SN/A  Unless required by applicable law or agreed to in writing, software
132SN/A  distributed under the License is distributed on an "AS IS" BASIS,
142SN/A  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
152SN/A  implied.  See the License for the specific language governing
162SN/A  permissions and limitations under the License.
172SN/A
182SN/A *****************************************************************************/
192SN/A
202SN/A#ifndef __SIMPLE_AT_TARGET2_H__
212SN/A#define __SIMPLE_AT_TARGET2_H__
222SN/A
232SN/A#include "tlm.h"
242SN/A#include "tlm_utils/simple_target_socket.h"
252SN/A//#include <systemc>
262SN/A#include <cassert>
272SN/A#include <vector>
282665Ssaidi@eecs.umich.edu#include <queue>
292665Ssaidi@eecs.umich.edu//#include <iostream>
302665Ssaidi@eecs.umich.edu
317897Shestness@cs.utexas.educlass SimpleATTarget2 : public sc_core::sc_module
322SN/A{
332SN/Apublic:
341388SN/A  typedef tlm::tlm_generic_payload            transaction_type;
358229Snate@binkert.org  typedef tlm::tlm_phase                      phase_type;
362SN/A  typedef tlm::tlm_sync_enum                  sync_enum_type;
372SN/A  typedef tlm_utils::simple_target_socket<SimpleATTarget2> target_socket_type;
387781SAli.Saidi@ARM.com
398229Snate@binkert.orgpublic:
401191SN/A  target_socket_type socket;
411191SN/A
421388SN/Apublic:
435529Snate@binkert.org  SC_HAS_PROCESS(SimpleATTarget2);
441717SN/A  SimpleATTarget2(sc_core::sc_module_name name) :
452651Ssaidi@eecs.umich.edu    sc_core::sc_module(name),
468229Snate@binkert.org    socket("socket"),
472680Sktlim@umich.edu    ACCEPT_DELAY(25, sc_core::SC_NS),
488232Snate@binkert.org    RESPONSE_DELAY(100, sc_core::SC_NS)
495529Snate@binkert.org  {
508779Sgblack@eecs.umich.edu    // register nb_transport method
512190SN/A    socket.register_nb_transport_fw(this, &SimpleATTarget2::myNBTransport);
5256SN/A
538229Snate@binkert.org    SC_METHOD(beginResponse)
542190SN/A    sensitive << mBeginResponseEvent;
552SN/A    dont_initialize();
562359SN/A
572359SN/A    SC_METHOD(endResponse)
582359SN/A    sensitive << mEndResponseEvent;
592SN/A    dont_initialize();
602SN/A  }
612SN/A
622SN/A  //
632SN/A  // Simple AT-TA target
642SN/A  // - Request is accepted after fixed delay (relative to end of prev request
652SN/A  //   phase)
662SN/A  // - Response is started after fixed delay (relative to end of prev resp
672SN/A  //   phase)
685606Snate@binkert.org  //
696144Sksewell@umich.edu  sync_enum_type myNBTransport(transaction_type& trans,
706144Sksewell@umich.edu                               phase_type& phase,
713126Sktlim@umich.edu                               sc_core::sc_time& t)
726144Sksewell@umich.edu  {
737823Ssteve.reinhardt@amd.com    if (phase == tlm::BEGIN_REQ) {
743126Sktlim@umich.edu      // transactions may be kept in queue after the initiator has send END_REQ
753126Sktlim@umich.edu      trans.acquire();
762356SN/A
772356SN/A      sc_dt::uint64 address = trans.get_address();
782356SN/A      assert(address < 400);
792367SN/A
802356SN/A      unsigned int& data = *reinterpret_cast<unsigned int*>(trans.get_data_ptr());
816144Sksewell@umich.edu      if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {
822367SN/A        std::cout << name() << ": Received write request: A = 0x"
836144Sksewell@umich.edu                  << std::hex << (unsigned int)address << ", D = 0x" << data
846144Sksewell@umich.edu                  << std::dec << " @ " << sc_core::sc_time_stamp()
856144Sksewell@umich.edu                  << std::endl;
862356SN/A
872367SN/A        *reinterpret_cast<unsigned int*>(&mMem[address]) = data;
886144Sksewell@umich.edu
897823Ssteve.reinhardt@amd.com      } else {
906144Sksewell@umich.edu        std::cout << name() << ": Received read request: A = 0x"
912367SN/A                  << std::hex << (unsigned int)address
922356SN/A                  << std::dec << " @ " << sc_core::sc_time_stamp()
936144Sksewell@umich.edu                  << std::endl;
946144Sksewell@umich.edu
957823Ssteve.reinhardt@amd.com        data = *reinterpret_cast<unsigned int*>(&mMem[address]);
962356SN/A      }
972356SN/A
982356SN/A      // End request phase after accept delay
995336Shines@cs.fsu.edu      t += ACCEPT_DELAY;
1002356SN/A      phase = tlm::END_REQ;
1014873Sstever@eecs.umich.edu
1022356SN/A      if (mResponseQueue.empty()) {
1032356SN/A        // Start processing transaction after accept delay
1041400SN/A        // Notify begin of response phase after accept delay + response delay
1055712Shsul@eecs.umich.edu        mBeginResponseEvent.notify(t + RESPONSE_DELAY);
1065712Shsul@eecs.umich.edu      }
1076221Snate@binkert.org      mResponseQueue.push(&trans);
1083661Srdreslin@umich.edu
1092SN/A      // AT-noTA target
1107823Ssteve.reinhardt@amd.com      // - always return false
1111062SN/A      // - immediately return delay to indicate end of phase
1125712Shsul@eecs.umich.edu      return tlm::TLM_UPDATED;
1135712Shsul@eecs.umich.edu
1145712Shsul@eecs.umich.edu    } else if (phase == tlm::END_RESP) {
1155712Shsul@eecs.umich.edu
1165712Shsul@eecs.umich.edu      // response phase ends after t
1172SN/A      mEndResponseEvent.notify(t);
1182SN/A
1192SN/A      return tlm::TLM_COMPLETED;
1205712Shsul@eecs.umich.edu    }
1215712Shsul@eecs.umich.edu
1226221Snate@binkert.org    // Not possible
1236221Snate@binkert.org    assert(0); exit(1);
1242SN/A//    return tlm::TLM_COMPLETED;  //unreachable code
1252SN/A  }
1266221Snate@binkert.org
1276221Snate@binkert.org  void beginResponse()
1286221Snate@binkert.org  {
1296221Snate@binkert.org    assert(!mResponseQueue.empty());
1302SN/A    // start response phase of oldest transaction
1312SN/A    phase_type phase = tlm::BEGIN_RESP;
1322SN/A    sc_core::sc_time t = sc_core::SC_ZERO_TIME;
1332SN/A    transaction_type* trans = mResponseQueue.front();
1345606Snate@binkert.org    assert(trans);
1355606Snate@binkert.org
1366221Snate@binkert.org    // Set response data
1375606Snate@binkert.org    trans->set_response_status(tlm::TLM_OK_RESPONSE);
1386221Snate@binkert.org    if (trans->get_command() == tlm::TLM_READ_COMMAND) {
1395606Snate@binkert.org       sc_dt::uint64 address = trans->get_address();
1405606Snate@binkert.org       assert(address < 400);
1412SN/A      *reinterpret_cast<unsigned int*>(trans->get_data_ptr()) =
1421400SN/A        *reinterpret_cast<unsigned int*>(&mMem[address]);
1435606Snate@binkert.org    }
1445606Snate@binkert.org
1452SN/A    if (socket->nb_transport_bw(*trans, phase, t) == tlm::TLM_COMPLETED) {
1462SN/A      // response phase ends after t
1472SN/A      mEndResponseEvent.notify(t);
1482SN/A
1496221Snate@binkert.org    } else {
1506221Snate@binkert.org      // initiator will call nb_transport to indicate end of response phase
1515606Snate@binkert.org    }
1526670Shsul@eecs.umich.edu  }
1535606Snate@binkert.org
1542SN/A  void endResponse()
1552SN/A  {
156124SN/A    assert(!mResponseQueue.empty());
1576221Snate@binkert.org    mResponseQueue.front()->release();
1586221Snate@binkert.org    mResponseQueue.pop();
1596221Snate@binkert.org
160124SN/A    // Start processing next transaction when previous response is accepted.
161124SN/A    // Notify begin of response phase after RESPONSE delay
162124SN/A    if (!mResponseQueue.empty()) {
163124SN/A      mBeginResponseEvent.notify(RESPONSE_DELAY);
1645606Snate@binkert.org    }
1655606Snate@binkert.org  }
1666221Snate@binkert.org
1675606Snate@binkert.orgprivate:
1686221Snate@binkert.org  const sc_core::sc_time ACCEPT_DELAY;
1695606Snate@binkert.org  const sc_core::sc_time RESPONSE_DELAY;
1705606Snate@binkert.org
171124SN/Aprivate:
1721400SN/A  unsigned char mMem[400];
1735606Snate@binkert.org  std::queue<transaction_type*> mResponseQueue;
174124SN/A  sc_core::sc_event mBeginResponseEvent;
175124SN/A  sc_core::sc_event mEndResponseEvent;
176124SN/A};
177124SN/A
1786221Snate@binkert.org#endif
1796221Snate@binkert.org