SimpleATTarget1.h revision 12922:a4f51f3405ac
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_AT_TARGET1_H__ 2112027Sjungma@eit.uni-kl.de#define __SIMPLE_AT_TARGET1_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 <systemc> 2612027Sjungma@eit.uni-kl.de#include <cassert> 2712027Sjungma@eit.uni-kl.de#include <vector> 2812027Sjungma@eit.uni-kl.de#include <queue> 2912027Sjungma@eit.uni-kl.de//#include <iostream> 3012027Sjungma@eit.uni-kl.de 3112027Sjungma@eit.uni-kl.declass SimpleATTarget1 : public sc_core::sc_module 3212027Sjungma@eit.uni-kl.de{ 3312027Sjungma@eit.uni-kl.depublic: 3412027Sjungma@eit.uni-kl.de typedef tlm::tlm_generic_payload transaction_type; 3512027Sjungma@eit.uni-kl.de typedef tlm::tlm_phase phase_type; 3612027Sjungma@eit.uni-kl.de typedef tlm::tlm_sync_enum sync_enum_type; 3712027Sjungma@eit.uni-kl.de typedef tlm_utils::simple_target_socket<SimpleATTarget1> target_socket_type; 3812027Sjungma@eit.uni-kl.de 3912027Sjungma@eit.uni-kl.depublic: 4012027Sjungma@eit.uni-kl.de target_socket_type socket; 4112027Sjungma@eit.uni-kl.de 4212027Sjungma@eit.uni-kl.depublic: 4312027Sjungma@eit.uni-kl.de SC_HAS_PROCESS(SimpleATTarget1); 4412027Sjungma@eit.uni-kl.de SimpleATTarget1(sc_core::sc_module_name name) : 4512027Sjungma@eit.uni-kl.de sc_core::sc_module(name), 4612027Sjungma@eit.uni-kl.de socket("socket"), 4712027Sjungma@eit.uni-kl.de ACCEPT_DELAY(25, sc_core::SC_NS), 4812027Sjungma@eit.uni-kl.de RESPONSE_DELAY(100, sc_core::SC_NS) 4912027Sjungma@eit.uni-kl.de { 5012027Sjungma@eit.uni-kl.de // register nb_transport method 5112027Sjungma@eit.uni-kl.de socket.register_nb_transport_fw(this, &SimpleATTarget1::myNBTransport); 5212027Sjungma@eit.uni-kl.de 5312027Sjungma@eit.uni-kl.de SC_METHOD(endRequest) 5412027Sjungma@eit.uni-kl.de sensitive << mEndRequestEvent; 5512027Sjungma@eit.uni-kl.de dont_initialize(); 5612027Sjungma@eit.uni-kl.de 5712027Sjungma@eit.uni-kl.de SC_METHOD(beginResponse) 5812027Sjungma@eit.uni-kl.de sensitive << mBeginResponseEvent; 5912027Sjungma@eit.uni-kl.de dont_initialize(); 6012027Sjungma@eit.uni-kl.de 6112027Sjungma@eit.uni-kl.de SC_METHOD(endResponse) 6212027Sjungma@eit.uni-kl.de sensitive << mEndResponseEvent; 6312027Sjungma@eit.uni-kl.de dont_initialize(); 6412027Sjungma@eit.uni-kl.de } 6512027Sjungma@eit.uni-kl.de 6612027Sjungma@eit.uni-kl.de // 6712027Sjungma@eit.uni-kl.de // Simple AT target 6812027Sjungma@eit.uni-kl.de // - Request is accepted after ACCEPT delay (relative to end of prev request 6912027Sjungma@eit.uni-kl.de // phase) 7012027Sjungma@eit.uni-kl.de // - Response is started after RESPONSE delay (relative to end of prev resp 7112027Sjungma@eit.uni-kl.de // phase) 7212027Sjungma@eit.uni-kl.de // 7312027Sjungma@eit.uni-kl.de sync_enum_type myNBTransport(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) 7412027Sjungma@eit.uni-kl.de { 7512027Sjungma@eit.uni-kl.de if (phase == tlm::BEGIN_REQ) { 7612027Sjungma@eit.uni-kl.de // transactions may be kept in queue after the initiator has send END_REQ 7712027Sjungma@eit.uni-kl.de trans.acquire(); 7812027Sjungma@eit.uni-kl.de 7912027Sjungma@eit.uni-kl.de sc_dt::uint64 address = trans.get_address(); 8012027Sjungma@eit.uni-kl.de assert(address < 400); 8112027Sjungma@eit.uni-kl.de 8212027Sjungma@eit.uni-kl.de unsigned int& data = *reinterpret_cast<unsigned int*>(trans.get_data_ptr()); 8312027Sjungma@eit.uni-kl.de if (trans.get_command() == tlm::TLM_WRITE_COMMAND) { 8412027Sjungma@eit.uni-kl.de std::cout << name() << ": Received write request: A = 0x" 8512027Sjungma@eit.uni-kl.de << std::hex << (unsigned int)address << ", D = 0x" 8612027Sjungma@eit.uni-kl.de << data << std::dec 8712027Sjungma@eit.uni-kl.de << " @ " << sc_core::sc_time_stamp() << std::endl; 8812027Sjungma@eit.uni-kl.de 8912027Sjungma@eit.uni-kl.de *reinterpret_cast<unsigned int*>(&mMem[address]) = data; 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 } 9812027Sjungma@eit.uni-kl.de 9912027Sjungma@eit.uni-kl.de // Notify end of request phase after ACCEPT delay 10012027Sjungma@eit.uni-kl.de if (mEndRequestQueue.empty()) { 10112027Sjungma@eit.uni-kl.de mEndRequestEvent.notify(t + ACCEPT_DELAY); 10212027Sjungma@eit.uni-kl.de } 10312027Sjungma@eit.uni-kl.de mEndRequestQueue.push(&trans); 10412027Sjungma@eit.uni-kl.de 10512027Sjungma@eit.uni-kl.de // AT-noTA target 10612027Sjungma@eit.uni-kl.de // - always return false 10712027Sjungma@eit.uni-kl.de // - seperate call to indicate end of phase (do not update phase or t) 10812027Sjungma@eit.uni-kl.de return tlm::TLM_ACCEPTED; 10912027Sjungma@eit.uni-kl.de 11012027Sjungma@eit.uni-kl.de } else if (phase == tlm::END_RESP) { 11112027Sjungma@eit.uni-kl.de 11212027Sjungma@eit.uni-kl.de // response phase ends after t 11312027Sjungma@eit.uni-kl.de mEndResponseEvent.notify(t); 11412027Sjungma@eit.uni-kl.de 11512027Sjungma@eit.uni-kl.de return tlm::TLM_COMPLETED; 11612027Sjungma@eit.uni-kl.de } 11712027Sjungma@eit.uni-kl.de 11812027Sjungma@eit.uni-kl.de // Not possible 11912027Sjungma@eit.uni-kl.de assert(0); exit(1); 12012027Sjungma@eit.uni-kl.de// return tlm::TLM_COMPLETED; //unreachable code 12112027Sjungma@eit.uni-kl.de } 12212027Sjungma@eit.uni-kl.de 12312027Sjungma@eit.uni-kl.de void endRequest() 12412027Sjungma@eit.uni-kl.de { 12512027Sjungma@eit.uni-kl.de assert(!mEndRequestQueue.empty()); 12612027Sjungma@eit.uni-kl.de // end request phase of oldest transaction 12712027Sjungma@eit.uni-kl.de phase_type phase = tlm::END_REQ; 12812027Sjungma@eit.uni-kl.de sc_core::sc_time t = sc_core::SC_ZERO_TIME; 12912027Sjungma@eit.uni-kl.de transaction_type* trans = mEndRequestQueue.front(); 13012027Sjungma@eit.uni-kl.de assert(trans); 13112027Sjungma@eit.uni-kl.de mEndRequestQueue.pop(); 13212027Sjungma@eit.uni-kl.de #if ( ! NDEBUG ) 13312027Sjungma@eit.uni-kl.de sync_enum_type r = socket->nb_transport_bw(*trans, phase, t); 13412027Sjungma@eit.uni-kl.de #endif /* ! NDEBUG */ 13512027Sjungma@eit.uni-kl.de assert(r == tlm::TLM_ACCEPTED); // FIXME: initiator should return TLM_ACCEPTED? 13612027Sjungma@eit.uni-kl.de assert(t == sc_core::SC_ZERO_TIME); // t must be SC_ZERO_TIME 13712027Sjungma@eit.uni-kl.de 13812027Sjungma@eit.uni-kl.de // Notify end of request phase for next transaction after ACCEPT delay 13912027Sjungma@eit.uni-kl.de if (!mEndRequestQueue.empty()) { 14012027Sjungma@eit.uni-kl.de mEndRequestEvent.notify(ACCEPT_DELAY); 14112027Sjungma@eit.uni-kl.de } 14212027Sjungma@eit.uni-kl.de 14312027Sjungma@eit.uni-kl.de if (mResponseQueue.empty()) { 14412027Sjungma@eit.uni-kl.de // Start processing transaction 14512027Sjungma@eit.uni-kl.de // Notify begin of response phase after RESPONSE delay 14612027Sjungma@eit.uni-kl.de mBeginResponseEvent.notify(RESPONSE_DELAY); 14712027Sjungma@eit.uni-kl.de } 14812027Sjungma@eit.uni-kl.de mResponseQueue.push(trans); 14912027Sjungma@eit.uni-kl.de } 15012027Sjungma@eit.uni-kl.de 15112027Sjungma@eit.uni-kl.de void beginResponse() 15212027Sjungma@eit.uni-kl.de { 15312027Sjungma@eit.uni-kl.de assert(!mResponseQueue.empty()); 15412027Sjungma@eit.uni-kl.de // start response phase of oldest transaction 15512027Sjungma@eit.uni-kl.de phase_type phase = tlm::BEGIN_RESP; 15612027Sjungma@eit.uni-kl.de sc_core::sc_time t = sc_core::SC_ZERO_TIME; 15712027Sjungma@eit.uni-kl.de transaction_type* trans = mResponseQueue.front(); 15812027Sjungma@eit.uni-kl.de assert(trans); 15912027Sjungma@eit.uni-kl.de 16012027Sjungma@eit.uni-kl.de // Set response data 16112027Sjungma@eit.uni-kl.de trans->set_response_status(tlm::TLM_OK_RESPONSE); 16212027Sjungma@eit.uni-kl.de if (trans->get_command() == tlm::TLM_READ_COMMAND) { 16312027Sjungma@eit.uni-kl.de sc_dt::uint64 address = trans->get_address(); 16412027Sjungma@eit.uni-kl.de assert(address < 400); 16512027Sjungma@eit.uni-kl.de *reinterpret_cast<unsigned int*>(trans->get_data_ptr()) = 16612027Sjungma@eit.uni-kl.de *reinterpret_cast<unsigned int*>(&mMem[address]); 16712027Sjungma@eit.uni-kl.de } 16812027Sjungma@eit.uni-kl.de 16912027Sjungma@eit.uni-kl.de switch (socket->nb_transport_bw(*trans, phase, t)) { 17012027Sjungma@eit.uni-kl.de case tlm::TLM_COMPLETED: 17112027Sjungma@eit.uni-kl.de // response phase ends after t 17212027Sjungma@eit.uni-kl.de mEndResponseEvent.notify(t); 17312027Sjungma@eit.uni-kl.de break; 17412027Sjungma@eit.uni-kl.de 17512027Sjungma@eit.uni-kl.de case tlm::TLM_ACCEPTED: 17612027Sjungma@eit.uni-kl.de case tlm::TLM_UPDATED: 17712027Sjungma@eit.uni-kl.de // initiator will call nb_transport to indicate end of response phase 17812027Sjungma@eit.uni-kl.de break; 17912027Sjungma@eit.uni-kl.de 18012027Sjungma@eit.uni-kl.de default: 18112027Sjungma@eit.uni-kl.de assert(0); exit(1); 18212027Sjungma@eit.uni-kl.de }; 18312027Sjungma@eit.uni-kl.de } 18412027Sjungma@eit.uni-kl.de 18512027Sjungma@eit.uni-kl.de void endResponse() 18612027Sjungma@eit.uni-kl.de { 18712027Sjungma@eit.uni-kl.de assert(!mResponseQueue.empty()); 18812027Sjungma@eit.uni-kl.de mResponseQueue.front()->release(); 18912027Sjungma@eit.uni-kl.de mResponseQueue.pop(); 19012027Sjungma@eit.uni-kl.de 19112027Sjungma@eit.uni-kl.de if (!mResponseQueue.empty()) { 19212027Sjungma@eit.uni-kl.de // Start processing next transaction 19312027Sjungma@eit.uni-kl.de // Notify begin of response phase after RESPONSE delay 19412027Sjungma@eit.uni-kl.de mBeginResponseEvent.notify(RESPONSE_DELAY); 19512027Sjungma@eit.uni-kl.de } 19612027Sjungma@eit.uni-kl.de } 19712027Sjungma@eit.uni-kl.de 19812027Sjungma@eit.uni-kl.deprivate: 19912027Sjungma@eit.uni-kl.de const sc_core::sc_time ACCEPT_DELAY; 20012027Sjungma@eit.uni-kl.de const sc_core::sc_time RESPONSE_DELAY; 20112027Sjungma@eit.uni-kl.de 20212027Sjungma@eit.uni-kl.deprivate: 20312027Sjungma@eit.uni-kl.de unsigned char mMem[400]; 20412027Sjungma@eit.uni-kl.de std::queue<transaction_type*> mEndRequestQueue; 20512027Sjungma@eit.uni-kl.de sc_core::sc_event mEndRequestEvent; 20612027Sjungma@eit.uni-kl.de std::queue<transaction_type*> mResponseQueue; 20712027Sjungma@eit.uni-kl.de sc_core::sc_event mBeginResponseEvent; 20812027Sjungma@eit.uni-kl.de sc_core::sc_event mEndResponseEvent; 20912027Sjungma@eit.uni-kl.de}; 21012027Sjungma@eit.uni-kl.de 21112027Sjungma@eit.uni-kl.de#endif 21212027Sjungma@eit.uni-kl.de