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