112922Sgabeblack@google.com/***************************************************************************** 212922Sgabeblack@google.com 312922Sgabeblack@google.com Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 412922Sgabeblack@google.com more contributor license agreements. See the NOTICE file distributed 512922Sgabeblack@google.com with this work for additional information regarding copyright ownership. 612922Sgabeblack@google.com Accellera licenses this file to you under the Apache License, Version 2.0 712922Sgabeblack@google.com (the "License"); you may not use this file except in compliance with the 812922Sgabeblack@google.com License. You may obtain a copy of the License at 912922Sgabeblack@google.com 1012922Sgabeblack@google.com http://www.apache.org/licenses/LICENSE-2.0 1112922Sgabeblack@google.com 1212922Sgabeblack@google.com Unless required by applicable law or agreed to in writing, software 1312922Sgabeblack@google.com distributed under the License is distributed on an "AS IS" BASIS, 1412922Sgabeblack@google.com WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1512922Sgabeblack@google.com implied. See the License for the specific language governing 1612922Sgabeblack@google.com permissions and limitations under the License. 1712922Sgabeblack@google.com 1812922Sgabeblack@google.com *****************************************************************************/ 1912922Sgabeblack@google.com 2012922Sgabeblack@google.com//==================================================================== 2112922Sgabeblack@google.com// Nov 06, 2008 2212922Sgabeblack@google.com// 2312922Sgabeblack@google.com// Updated by: 2412922Sgabeblack@google.com// Xiaopeng Qiu, JEDA Technologies, Inc 2512922Sgabeblack@google.com// Email: qiuxp@jedatechnologies.net 2612922Sgabeblack@google.com// 2712922Sgabeblack@google.com// To fix violations of TLM2.0 rules, which are detected by JEDA 2812922Sgabeblack@google.com// TLM2.0 checker. 2912922Sgabeblack@google.com// 3012922Sgabeblack@google.com//==================================================================== 3112922Sgabeblack@google.com 3212922Sgabeblack@google.com#ifndef __SIMPLE_AT_INITIATOR2_H__ 3312922Sgabeblack@google.com#define __SIMPLE_AT_INITIATOR2_H__ 3412922Sgabeblack@google.com 3512922Sgabeblack@google.com#include "tlm.h" 3612922Sgabeblack@google.com#include "tlm_utils/simple_initiator_socket.h" 3712922Sgabeblack@google.com//#include <systemc> 3812922Sgabeblack@google.com#include <cassert> 3912922Sgabeblack@google.com#include <queue> 4012922Sgabeblack@google.com//#include <iostream> 4112922Sgabeblack@google.com 4212922Sgabeblack@google.comclass SimpleATInitiator2 : public sc_core::sc_module 4312922Sgabeblack@google.com{ 4412922Sgabeblack@google.compublic: 4512922Sgabeblack@google.com typedef tlm::tlm_generic_payload transaction_type; 4612922Sgabeblack@google.com typedef tlm::tlm_phase phase_type; 4712922Sgabeblack@google.com typedef tlm::tlm_sync_enum sync_enum_type; 4812922Sgabeblack@google.com typedef tlm_utils::simple_initiator_socket<SimpleATInitiator2> initiator_socket_type; 4912922Sgabeblack@google.com 5012922Sgabeblack@google.compublic: 5112922Sgabeblack@google.com // extended transaction, holds tlm_generic_payload + data storage 5212922Sgabeblack@google.com template <typename DT> 5312922Sgabeblack@google.com class MyTransaction : public transaction_type 5412922Sgabeblack@google.com { 5512922Sgabeblack@google.com public: 5612922Sgabeblack@google.com MyTransaction() 5712922Sgabeblack@google.com { 5812922Sgabeblack@google.com this->set_data_ptr(reinterpret_cast<unsigned char*>(&mData)); 5912922Sgabeblack@google.com } 6012922Sgabeblack@google.com MyTransaction(tlm::tlm_mm_interface* mm) : transaction_type(mm) 6112922Sgabeblack@google.com { 6212922Sgabeblack@google.com this->set_data_ptr(reinterpret_cast<unsigned char*>(&mData)); 6312922Sgabeblack@google.com } 6412922Sgabeblack@google.com 6512922Sgabeblack@google.com void setData(DT& data) { mData = data; } 6612922Sgabeblack@google.com DT getData() const { return mData; } 6712922Sgabeblack@google.com 6812922Sgabeblack@google.com private: 6912922Sgabeblack@google.com DT mData; 7012922Sgabeblack@google.com }; 7112922Sgabeblack@google.com typedef MyTransaction<unsigned int> mytransaction_type; 7212922Sgabeblack@google.com 7312922Sgabeblack@google.com // Dummy Transaction Pool 7412922Sgabeblack@google.com class SimplePool : public tlm::tlm_mm_interface 7512922Sgabeblack@google.com { 7612922Sgabeblack@google.com public: 7712922Sgabeblack@google.com SimplePool() {} 7812922Sgabeblack@google.com mytransaction_type* claim() 7912922Sgabeblack@google.com { 8012922Sgabeblack@google.com mytransaction_type* t = new mytransaction_type(this); 8112922Sgabeblack@google.com t->acquire(); 8212922Sgabeblack@google.com return t; 8312922Sgabeblack@google.com } 8412922Sgabeblack@google.com void release(mytransaction_type* t) 8512922Sgabeblack@google.com { 8612922Sgabeblack@google.com t->release(); 8712922Sgabeblack@google.com } 8812922Sgabeblack@google.com void free(tlm::tlm_generic_payload* t) 8912922Sgabeblack@google.com { 9012922Sgabeblack@google.com t->reset(); 9112922Sgabeblack@google.com delete t; 9212922Sgabeblack@google.com } 9312922Sgabeblack@google.com }; 9412922Sgabeblack@google.com 9512922Sgabeblack@google.compublic: 9612922Sgabeblack@google.com initiator_socket_type socket; 9712922Sgabeblack@google.com 9812922Sgabeblack@google.compublic: 9912922Sgabeblack@google.com SC_HAS_PROCESS(SimpleATInitiator2); 10012922Sgabeblack@google.com SimpleATInitiator2(sc_core::sc_module_name name, 10112922Sgabeblack@google.com unsigned int nrOfTransactions = 0x5, 10212922Sgabeblack@google.com unsigned int baseAddress = 0) : 10312922Sgabeblack@google.com sc_core::sc_module(name), 10412922Sgabeblack@google.com socket("socket"), 10512922Sgabeblack@google.com ACCEPT_DELAY(10, sc_core::SC_NS), 10612922Sgabeblack@google.com mNrOfTransactions(nrOfTransactions), 10712922Sgabeblack@google.com mBaseAddress(baseAddress), 10812922Sgabeblack@google.com mTransactionCount(0), 10912922Sgabeblack@google.com mCurrentTransaction(0) 11012922Sgabeblack@google.com { 11112922Sgabeblack@google.com // register nb_transport method 11212922Sgabeblack@google.com socket.register_nb_transport_bw(this, &SimpleATInitiator2::myNBTransport); 11312922Sgabeblack@google.com 11412922Sgabeblack@google.com // Initiator thread 11512922Sgabeblack@google.com SC_THREAD(run); 11612922Sgabeblack@google.com } 11712922Sgabeblack@google.com 11812922Sgabeblack@google.com bool initTransaction(mytransaction_type*& trans) 11912922Sgabeblack@google.com { 12012922Sgabeblack@google.com if (mTransactionCount < mNrOfTransactions) { 12112922Sgabeblack@google.com trans = transPool.claim(); 12212922Sgabeblack@google.com trans->set_address(mBaseAddress + 4*mTransactionCount); 12312922Sgabeblack@google.com trans->setData(mTransactionCount); 12412922Sgabeblack@google.com trans->set_command(tlm::TLM_WRITE_COMMAND); 12512922Sgabeblack@google.com 12612922Sgabeblack@google.com } else if (mTransactionCount < 2 * mNrOfTransactions) { 12712922Sgabeblack@google.com trans = transPool.claim(); 12812922Sgabeblack@google.com trans->set_address(mBaseAddress + 4*(mTransactionCount - mNrOfTransactions)); 12912922Sgabeblack@google.com trans->set_command(tlm::TLM_READ_COMMAND); 13012922Sgabeblack@google.com 13112922Sgabeblack@google.com } else { 13212922Sgabeblack@google.com return false; 13312922Sgabeblack@google.com } 13412922Sgabeblack@google.com 13512922Sgabeblack@google.com trans->set_data_length(4); 13612922Sgabeblack@google.com trans->set_streaming_width(4); 13712922Sgabeblack@google.com 13812922Sgabeblack@google.com ++mTransactionCount; 13912922Sgabeblack@google.com return true; 14012922Sgabeblack@google.com } 14112922Sgabeblack@google.com 14212922Sgabeblack@google.com void logStartTransation(mytransaction_type& trans) 14312922Sgabeblack@google.com { 14412922Sgabeblack@google.com if (trans.get_command() == tlm::TLM_WRITE_COMMAND) { 14512922Sgabeblack@google.com std::cout << name() << ": Send write request: A = 0x" 14612922Sgabeblack@google.com << std::hex << (unsigned int)trans.get_address() 14712922Sgabeblack@google.com << ", D = 0x" << trans.getData() << std::dec 14812922Sgabeblack@google.com << " @ " << sc_core::sc_time_stamp() << std::endl; 14912922Sgabeblack@google.com 15012922Sgabeblack@google.com } else { 15112922Sgabeblack@google.com std::cout << name() << ": Send read request: A = 0x" 15212922Sgabeblack@google.com << std::hex << (unsigned int)trans.get_address() << std::dec 15312922Sgabeblack@google.com << " @ " << sc_core::sc_time_stamp() << std::endl; 15412922Sgabeblack@google.com } 15512922Sgabeblack@google.com } 15612922Sgabeblack@google.com 15712922Sgabeblack@google.com void logEndTransaction(mytransaction_type& trans) 15812922Sgabeblack@google.com { 15912922Sgabeblack@google.com if (trans.get_response_status() != tlm::TLM_OK_RESPONSE) { 16012922Sgabeblack@google.com std::cout << name() << ": Received error response @ " 16112922Sgabeblack@google.com << sc_core::sc_time_stamp() << std::endl; 16212922Sgabeblack@google.com 16312922Sgabeblack@google.com } else { 16412922Sgabeblack@google.com std::cout << name() << ": Received ok response"; 16512922Sgabeblack@google.com if (trans.get_command() == tlm::TLM_READ_COMMAND) { 16612922Sgabeblack@google.com std::cout << ": D = 0x" << std::hex << trans.getData() << std::dec; 16712922Sgabeblack@google.com } 16812922Sgabeblack@google.com std::cout << " @ " << sc_core::sc_time_stamp() << std::endl; 16912922Sgabeblack@google.com } 17012922Sgabeblack@google.com } 17112922Sgabeblack@google.com 17212922Sgabeblack@google.com // 17312922Sgabeblack@google.com // Simple AT Initiator 17412922Sgabeblack@google.com // - Request must be accepted by the target before the next request can be 17512922Sgabeblack@google.com // send 17612922Sgabeblack@google.com // - Responses can come out of order 17712922Sgabeblack@google.com // - Responses will be accepted after fixed delay 17812922Sgabeblack@google.com // 17912922Sgabeblack@google.com void run() 18012922Sgabeblack@google.com { 18112922Sgabeblack@google.com phase_type phase; 18212922Sgabeblack@google.com sc_core::sc_time t; 18312922Sgabeblack@google.com 18412922Sgabeblack@google.com mytransaction_type* ptrans; 18512922Sgabeblack@google.com while (initTransaction(ptrans)) { 18612922Sgabeblack@google.com // Create transaction and initialise phase and t 18712922Sgabeblack@google.com mytransaction_type& trans = *ptrans; 18812922Sgabeblack@google.com phase = tlm::BEGIN_REQ; 18912922Sgabeblack@google.com t = sc_core::SC_ZERO_TIME; 19012922Sgabeblack@google.com 19112922Sgabeblack@google.com logStartTransation(trans); 19212922Sgabeblack@google.com 19312922Sgabeblack@google.com switch (socket->nb_transport_fw(trans, phase, t)) { 19412922Sgabeblack@google.com case tlm::TLM_COMPLETED: 19512922Sgabeblack@google.com // Transaction Finished, wait for the returned delay 19612922Sgabeblack@google.com wait(t); 19712922Sgabeblack@google.com logEndTransaction(trans); 19812922Sgabeblack@google.com transPool.release(&trans); 19912922Sgabeblack@google.com break; 20012922Sgabeblack@google.com 20112922Sgabeblack@google.com case tlm::TLM_ACCEPTED: 20212922Sgabeblack@google.com case tlm::TLM_UPDATED: 20312922Sgabeblack@google.com switch (phase) { 20412922Sgabeblack@google.com case tlm::BEGIN_REQ: 20512922Sgabeblack@google.com // Request phase not yet finished 20612922Sgabeblack@google.com // Wait until end of request phase before sending new request 20712922Sgabeblack@google.com 20812922Sgabeblack@google.com // FIXME 20912922Sgabeblack@google.com mCurrentTransaction = &trans; 21012922Sgabeblack@google.com wait(mEndRequestPhase); 21112922Sgabeblack@google.com mCurrentTransaction = 0; 21212922Sgabeblack@google.com break; 21312922Sgabeblack@google.com 21412922Sgabeblack@google.com case tlm::END_REQ: 21512922Sgabeblack@google.com // Request phase ended 21612922Sgabeblack@google.com if (t != sc_core::SC_ZERO_TIME) { 21712922Sgabeblack@google.com // Wait until end of request time before sending new request 21812922Sgabeblack@google.com wait(t); 21912922Sgabeblack@google.com } 22012922Sgabeblack@google.com break; 22112922Sgabeblack@google.com 22212922Sgabeblack@google.com case tlm::BEGIN_RESP: 22312922Sgabeblack@google.com // Request phase ended and response phase already started 22412922Sgabeblack@google.com if (t != sc_core::SC_ZERO_TIME) { 22512922Sgabeblack@google.com // Wait until end of request time before sending new request 22612922Sgabeblack@google.com wait(t); 22712922Sgabeblack@google.com } 22812922Sgabeblack@google.com // Notify end of response phase after ACCEPT delay 22912922Sgabeblack@google.com t += ACCEPT_DELAY; 23012922Sgabeblack@google.com phase = tlm::END_RESP; 23112922Sgabeblack@google.com socket->nb_transport_fw(trans, phase, t); 23212922Sgabeblack@google.com logEndTransaction(trans); 23312922Sgabeblack@google.com transPool.release(&trans); 23412922Sgabeblack@google.com break; 23512922Sgabeblack@google.com 23612922Sgabeblack@google.com case tlm::END_RESP: // fall-through 23712922Sgabeblack@google.com default: 23812922Sgabeblack@google.com // A target should never return with these phases 23912922Sgabeblack@google.com // If phase == END_RESP, nb_transport should have returned true 24012922Sgabeblack@google.com assert(0); exit(1); 24112922Sgabeblack@google.com break; 24212922Sgabeblack@google.com } 24312922Sgabeblack@google.com break; 24412922Sgabeblack@google.com 24512922Sgabeblack@google.com default: 24612922Sgabeblack@google.com assert(0); exit(1); 24712922Sgabeblack@google.com }; 24812922Sgabeblack@google.com } 24912922Sgabeblack@google.com wait(); 25012922Sgabeblack@google.com 25112922Sgabeblack@google.com } 25212922Sgabeblack@google.com 25312922Sgabeblack@google.com sync_enum_type myNBTransport(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) 25412922Sgabeblack@google.com { 25512922Sgabeblack@google.com switch (phase) { 25612922Sgabeblack@google.com case tlm::END_REQ: 25712922Sgabeblack@google.com assert(t == sc_core::SC_ZERO_TIME); // FIXME: can t != 0? 25812922Sgabeblack@google.com // Request phase ended 25912922Sgabeblack@google.com mEndRequestPhase.notify(sc_core::SC_ZERO_TIME); 26012922Sgabeblack@google.com return tlm::TLM_ACCEPTED; 26112922Sgabeblack@google.com 26212922Sgabeblack@google.com case tlm::BEGIN_RESP: 26312922Sgabeblack@google.com { 26412922Sgabeblack@google.com assert(t == sc_core::SC_ZERO_TIME); // FIXME: can t != 0? 26512922Sgabeblack@google.com 26612922Sgabeblack@google.com // Notify end of request phase if run thread is waiting for it 26712922Sgabeblack@google.com // FIXME 26812922Sgabeblack@google.com if (&trans == mCurrentTransaction) { 26912922Sgabeblack@google.com mEndRequestPhase.notify(sc_core::SC_ZERO_TIME); 27012922Sgabeblack@google.com } 27112922Sgabeblack@google.com 27212922Sgabeblack@google.com assert(dynamic_cast<mytransaction_type*>(&trans)); 27312922Sgabeblack@google.com mytransaction_type* myTrans = static_cast<mytransaction_type*>(&trans); 27412922Sgabeblack@google.com assert(myTrans); 27512922Sgabeblack@google.com 27612922Sgabeblack@google.com // Notify end of response phase after ACCEPT delay 27712922Sgabeblack@google.com t += ACCEPT_DELAY; 27812922Sgabeblack@google.com phase = tlm::END_RESP; 27912922Sgabeblack@google.com logEndTransaction(*myTrans); 28012922Sgabeblack@google.com transPool.release(myTrans); 28112922Sgabeblack@google.com 28212922Sgabeblack@google.com return tlm::TLM_COMPLETED; 28312922Sgabeblack@google.com } 28412922Sgabeblack@google.com 28512922Sgabeblack@google.com case tlm::BEGIN_REQ: // fall-through 28612922Sgabeblack@google.com case tlm::END_RESP: // fall-through 28712922Sgabeblack@google.com default: 28812922Sgabeblack@google.com // A target should never call nb_transport with these phases 28912922Sgabeblack@google.com assert(0); exit(1); 29012922Sgabeblack@google.com// return tlm::TLM_COMPLETED; //unreachable code 29112922Sgabeblack@google.com }; 29212922Sgabeblack@google.com } 29312922Sgabeblack@google.com 29412922Sgabeblack@google.comprivate: 29512922Sgabeblack@google.com const sc_core::sc_time ACCEPT_DELAY; 29612922Sgabeblack@google.com 29712922Sgabeblack@google.comprivate: 29812922Sgabeblack@google.com unsigned int mNrOfTransactions; 29912922Sgabeblack@google.com unsigned int mBaseAddress; 30012922Sgabeblack@google.com SimplePool transPool; 30112922Sgabeblack@google.com unsigned int mTransactionCount; 30212922Sgabeblack@google.com sc_core::sc_event mEndRequestPhase; 30312922Sgabeblack@google.com transaction_type* mCurrentTransaction; 30412922Sgabeblack@google.com}; 30512922Sgabeblack@google.com 30612922Sgabeblack@google.com#endif 307