111818SChristian.Menard@tu-dresden.de/* 211818SChristian.Menard@tu-dresden.de * Copyright (c) 2015, University of Kaiserslautern 311818SChristian.Menard@tu-dresden.de * All rights reserved. 411818SChristian.Menard@tu-dresden.de * 511818SChristian.Menard@tu-dresden.de * Redistribution and use in source and binary forms, with or without 611818SChristian.Menard@tu-dresden.de * modification, are permitted provided that the following conditions are 711818SChristian.Menard@tu-dresden.de * met: 811818SChristian.Menard@tu-dresden.de * 911818SChristian.Menard@tu-dresden.de * 1. Redistributions of source code must retain the above copyright notice, 1011818SChristian.Menard@tu-dresden.de * this list of conditions and the following disclaimer. 1111818SChristian.Menard@tu-dresden.de * 1211818SChristian.Menard@tu-dresden.de * 2. Redistributions in binary form must reproduce the above copyright 1311818SChristian.Menard@tu-dresden.de * notice, this list of conditions and the following disclaimer in the 1411818SChristian.Menard@tu-dresden.de * documentation and/or other materials provided with the distribution. 1511818SChristian.Menard@tu-dresden.de * 1611818SChristian.Menard@tu-dresden.de * 3. Neither the name of the copyright holder nor the names of its 1711818SChristian.Menard@tu-dresden.de * contributors may be used to endorse or promote products derived from 1811818SChristian.Menard@tu-dresden.de * this software without specific prior written permission. 1911818SChristian.Menard@tu-dresden.de * 2011818SChristian.Menard@tu-dresden.de * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2111818SChristian.Menard@tu-dresden.de * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2211818SChristian.Menard@tu-dresden.de * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2311818SChristian.Menard@tu-dresden.de * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 2411818SChristian.Menard@tu-dresden.de * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2511818SChristian.Menard@tu-dresden.de * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2611818SChristian.Menard@tu-dresden.de * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2711818SChristian.Menard@tu-dresden.de * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 2811818SChristian.Menard@tu-dresden.de * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 2911818SChristian.Menard@tu-dresden.de * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3011818SChristian.Menard@tu-dresden.de * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3111818SChristian.Menard@tu-dresden.de * 3211818SChristian.Menard@tu-dresden.de * Authors: Matthias Jung 3311818SChristian.Menard@tu-dresden.de */ 3411818SChristian.Menard@tu-dresden.de 3511818SChristian.Menard@tu-dresden.de#include "sc_target.hh" 3611818SChristian.Menard@tu-dresden.de 3711818SChristian.Menard@tu-dresden.deusing namespace sc_core; 3811818SChristian.Menard@tu-dresden.deusing namespace std; 3911818SChristian.Menard@tu-dresden.de 4011818SChristian.Menard@tu-dresden.deTarget::Target(sc_core::sc_module_name name, 4111818SChristian.Menard@tu-dresden.de bool debug, 4211818SChristian.Menard@tu-dresden.de unsigned long long int size, 4311818SChristian.Menard@tu-dresden.de unsigned int offset) : 4411818SChristian.Menard@tu-dresden.de socket("socket"), 4511818SChristian.Menard@tu-dresden.de transaction_in_progress(0), 4611818SChristian.Menard@tu-dresden.de response_in_progress(false), 4711818SChristian.Menard@tu-dresden.de next_response_pending(0), 4811818SChristian.Menard@tu-dresden.de end_req_pending(0), 4911818SChristian.Menard@tu-dresden.de m_peq(this, &Target::peq_cb), 5011818SChristian.Menard@tu-dresden.de debug(debug), 5111818SChristian.Menard@tu-dresden.de size(size), 5211818SChristian.Menard@tu-dresden.de offset(offset) 5311818SChristian.Menard@tu-dresden.de{ 5411818SChristian.Menard@tu-dresden.de /* Register tlm transport functions */ 5511818SChristian.Menard@tu-dresden.de socket.register_b_transport(this, &Target::b_transport); 5611818SChristian.Menard@tu-dresden.de socket.register_transport_dbg(this, &Target::transport_dbg); 5711818SChristian.Menard@tu-dresden.de socket.register_nb_transport_fw(this, &Target::nb_transport_fw); 5811818SChristian.Menard@tu-dresden.de 5911818SChristian.Menard@tu-dresden.de 6011818SChristian.Menard@tu-dresden.de /* allocate storage memory */ 6111818SChristian.Menard@tu-dresden.de mem = new unsigned char[size]; 6211818SChristian.Menard@tu-dresden.de 6311818SChristian.Menard@tu-dresden.de SC_METHOD(execute_transaction_process); 6411818SChristian.Menard@tu-dresden.de sensitive << target_done_event; 6511818SChristian.Menard@tu-dresden.de dont_initialize(); 6611818SChristian.Menard@tu-dresden.de} 6711818SChristian.Menard@tu-dresden.de 6811818SChristian.Menard@tu-dresden.devoid 6912048Schristian.menard@tu-dresden.deTarget::check_address(unsigned long long int addr) 7012048Schristian.menard@tu-dresden.de{ 7112048Schristian.menard@tu-dresden.de if (addr < offset || addr >= offset + size) 7212048Schristian.menard@tu-dresden.de SC_REPORT_FATAL("Target", "Address out of range. Did you set an " 7312048Schristian.menard@tu-dresden.de "appropriate size and offset?"); 7412048Schristian.menard@tu-dresden.de} 7512048Schristian.menard@tu-dresden.de 7612048Schristian.menard@tu-dresden.devoid 7711818SChristian.Menard@tu-dresden.deTarget::b_transport(tlm::tlm_generic_payload& trans, sc_time& delay) 7811818SChristian.Menard@tu-dresden.de{ 7911818SChristian.Menard@tu-dresden.de /* Execute the read or write commands */ 8011818SChristian.Menard@tu-dresden.de execute_transaction(trans); 8111818SChristian.Menard@tu-dresden.de} 8211818SChristian.Menard@tu-dresden.de 8311818SChristian.Menard@tu-dresden.deunsigned int 8411818SChristian.Menard@tu-dresden.deTarget::transport_dbg(tlm::tlm_generic_payload& trans) 8511818SChristian.Menard@tu-dresden.de{ 8612048Schristian.menard@tu-dresden.de check_address(trans.get_address()); 8712048Schristian.menard@tu-dresden.de 8811818SChristian.Menard@tu-dresden.de tlm::tlm_command cmd = trans.get_command(); 8911818SChristian.Menard@tu-dresden.de sc_dt::uint64 adr = trans.get_address() - offset; 9011818SChristian.Menard@tu-dresden.de unsigned char* ptr = trans.get_data_ptr(); 9111818SChristian.Menard@tu-dresden.de unsigned int len = trans.get_data_length(); 9211818SChristian.Menard@tu-dresden.de 9311818SChristian.Menard@tu-dresden.de unsigned char *mem_array_ptr = mem + adr; 9411818SChristian.Menard@tu-dresden.de 9511818SChristian.Menard@tu-dresden.de /* Load / Store the access: */ 9611818SChristian.Menard@tu-dresden.de if ( cmd == tlm::TLM_READ_COMMAND ) { 9711818SChristian.Menard@tu-dresden.de if (debug) { 9811818SChristian.Menard@tu-dresden.de SC_REPORT_INFO("target", "tlm::TLM_READ_COMMAND"); 9911818SChristian.Menard@tu-dresden.de } 10011818SChristian.Menard@tu-dresden.de std::memcpy(ptr, mem_array_ptr, len); 10111818SChristian.Menard@tu-dresden.de } else if ( cmd == tlm::TLM_WRITE_COMMAND ) { 10211818SChristian.Menard@tu-dresden.de if (debug) { 10311818SChristian.Menard@tu-dresden.de SC_REPORT_INFO("target", "tlm::TLM_WRITE_COMMAND"); 10411818SChristian.Menard@tu-dresden.de } 10511818SChristian.Menard@tu-dresden.de std::memcpy(mem_array_ptr, ptr, len); 10611818SChristian.Menard@tu-dresden.de } 10711818SChristian.Menard@tu-dresden.de 10811818SChristian.Menard@tu-dresden.de return len; 10911818SChristian.Menard@tu-dresden.de} 11011818SChristian.Menard@tu-dresden.de 11111818SChristian.Menard@tu-dresden.de 11211818SChristian.Menard@tu-dresden.de/* TLM-2 non-blocking transport method */ 11311818SChristian.Menard@tu-dresden.detlm::tlm_sync_enum Target::nb_transport_fw(tlm::tlm_generic_payload& trans, 11411818SChristian.Menard@tu-dresden.de tlm::tlm_phase& phase, 11511818SChristian.Menard@tu-dresden.de sc_time& delay) 11611818SChristian.Menard@tu-dresden.de{ 11711818SChristian.Menard@tu-dresden.de /* Queue the transaction until the annotated time has elapsed */ 11811818SChristian.Menard@tu-dresden.de m_peq.notify(trans, phase, delay); 11911818SChristian.Menard@tu-dresden.de return tlm::TLM_ACCEPTED; 12011818SChristian.Menard@tu-dresden.de} 12111818SChristian.Menard@tu-dresden.de 12211818SChristian.Menard@tu-dresden.devoid 12311818SChristian.Menard@tu-dresden.deTarget::peq_cb(tlm::tlm_generic_payload& trans, 12411818SChristian.Menard@tu-dresden.de const tlm::tlm_phase& phase) 12511818SChristian.Menard@tu-dresden.de{ 12611818SChristian.Menard@tu-dresden.de sc_time delay; 12711818SChristian.Menard@tu-dresden.de 12811818SChristian.Menard@tu-dresden.de if (phase == tlm::BEGIN_REQ) { 12911818SChristian.Menard@tu-dresden.de if (debug) SC_REPORT_INFO("target", "tlm::BEGIN_REQ"); 13011818SChristian.Menard@tu-dresden.de 13111818SChristian.Menard@tu-dresden.de /* Increment the transaction reference count */ 13211818SChristian.Menard@tu-dresden.de trans.acquire(); 13311818SChristian.Menard@tu-dresden.de 13411818SChristian.Menard@tu-dresden.de if ( !transaction_in_progress ) { 13511818SChristian.Menard@tu-dresden.de send_end_req(trans); 13611818SChristian.Menard@tu-dresden.de } else { 13711818SChristian.Menard@tu-dresden.de /* Put back-pressure on initiator by deferring END_REQ until 13811818SChristian.Menard@tu-dresden.de * pipeline is clear */ 13911818SChristian.Menard@tu-dresden.de end_req_pending = &trans; 14011818SChristian.Menard@tu-dresden.de } 14111818SChristian.Menard@tu-dresden.de } else if (phase == tlm::END_RESP) { 14211818SChristian.Menard@tu-dresden.de /* On receiving END_RESP, the target can release the transaction and 14311818SChristian.Menard@tu-dresden.de * allow other pending transactions to proceed */ 14411818SChristian.Menard@tu-dresden.de if (!response_in_progress) { 14511818SChristian.Menard@tu-dresden.de SC_REPORT_FATAL("TLM-2", "Illegal transaction phase END_RESP" 14611818SChristian.Menard@tu-dresden.de "received by target"); 14711818SChristian.Menard@tu-dresden.de } 14811818SChristian.Menard@tu-dresden.de 14911818SChristian.Menard@tu-dresden.de transaction_in_progress = 0; 15011818SChristian.Menard@tu-dresden.de 15111818SChristian.Menard@tu-dresden.de /* Target itself is now clear to issue the next BEGIN_RESP */ 15211818SChristian.Menard@tu-dresden.de response_in_progress = false; 15311818SChristian.Menard@tu-dresden.de if (next_response_pending) { 15411818SChristian.Menard@tu-dresden.de send_response( *next_response_pending ); 15511818SChristian.Menard@tu-dresden.de next_response_pending = 0; 15611818SChristian.Menard@tu-dresden.de } 15711818SChristian.Menard@tu-dresden.de 15811818SChristian.Menard@tu-dresden.de /* ... and to unblock the initiator by issuing END_REQ */ 15911818SChristian.Menard@tu-dresden.de if (end_req_pending) { 16011818SChristian.Menard@tu-dresden.de send_end_req( *end_req_pending ); 16111818SChristian.Menard@tu-dresden.de end_req_pending = 0; 16211818SChristian.Menard@tu-dresden.de } 16311818SChristian.Menard@tu-dresden.de 16411818SChristian.Menard@tu-dresden.de } else /* tlm::END_REQ or tlm::BEGIN_RESP */ { 16511818SChristian.Menard@tu-dresden.de SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by" 16611818SChristian.Menard@tu-dresden.de "target"); 16711818SChristian.Menard@tu-dresden.de } 16811818SChristian.Menard@tu-dresden.de} 16911818SChristian.Menard@tu-dresden.de 17011818SChristian.Menard@tu-dresden.devoid 17111818SChristian.Menard@tu-dresden.deTarget::send_end_req(tlm::tlm_generic_payload& trans) 17211818SChristian.Menard@tu-dresden.de{ 17311818SChristian.Menard@tu-dresden.de tlm::tlm_phase bw_phase; 17411818SChristian.Menard@tu-dresden.de sc_time delay; 17511818SChristian.Menard@tu-dresden.de 17611818SChristian.Menard@tu-dresden.de /* Queue the acceptance and the response with the appropriate latency */ 17711818SChristian.Menard@tu-dresden.de bw_phase = tlm::END_REQ; 17811818SChristian.Menard@tu-dresden.de delay = sc_time(10.0, SC_NS); // Accept delay 17911818SChristian.Menard@tu-dresden.de 18011818SChristian.Menard@tu-dresden.de tlm::tlm_sync_enum status; 18111818SChristian.Menard@tu-dresden.de status = socket->nb_transport_bw(trans, bw_phase, delay); 18211818SChristian.Menard@tu-dresden.de 18311818SChristian.Menard@tu-dresden.de /* Ignore return value; 18411818SChristian.Menard@tu-dresden.de * initiator cannot terminate transaction at this point 18511818SChristian.Menard@tu-dresden.de * Queue internal event to mark beginning of response: */ 18611818SChristian.Menard@tu-dresden.de delay = delay + sc_time(40.0, SC_NS); // Latency 18711818SChristian.Menard@tu-dresden.de target_done_event.notify(delay); 18811818SChristian.Menard@tu-dresden.de 18911818SChristian.Menard@tu-dresden.de assert(transaction_in_progress == 0); 19011818SChristian.Menard@tu-dresden.de transaction_in_progress = &trans; 19111818SChristian.Menard@tu-dresden.de} 19211818SChristian.Menard@tu-dresden.de 19311818SChristian.Menard@tu-dresden.devoid 19411818SChristian.Menard@tu-dresden.deTarget::execute_transaction_process() 19511818SChristian.Menard@tu-dresden.de{ 19611818SChristian.Menard@tu-dresden.de /* Execute the read or write commands */ 19711818SChristian.Menard@tu-dresden.de execute_transaction( *transaction_in_progress ); 19811818SChristian.Menard@tu-dresden.de 19911818SChristian.Menard@tu-dresden.de /* Target must honor BEGIN_RESP/END_RESP exclusion rule; i.e. must not 20011818SChristian.Menard@tu-dresden.de * send BEGIN_RESP until receiving previous END_RESP or BEGIN_REQ */ 20111818SChristian.Menard@tu-dresden.de if (response_in_progress) { 20211818SChristian.Menard@tu-dresden.de /* Target allows only two transactions in-flight */ 20311818SChristian.Menard@tu-dresden.de if (next_response_pending) { 20411818SChristian.Menard@tu-dresden.de SC_REPORT_FATAL("TLM-2", "Attempt to have two pending responses" 20511818SChristian.Menard@tu-dresden.de "in target"); 20611818SChristian.Menard@tu-dresden.de } 20711818SChristian.Menard@tu-dresden.de next_response_pending = transaction_in_progress; 20811818SChristian.Menard@tu-dresden.de } else { 20911818SChristian.Menard@tu-dresden.de send_response( *transaction_in_progress ); 21011818SChristian.Menard@tu-dresden.de } 21111818SChristian.Menard@tu-dresden.de} 21211818SChristian.Menard@tu-dresden.de 21311818SChristian.Menard@tu-dresden.devoid 21411818SChristian.Menard@tu-dresden.deTarget::execute_transaction(tlm::tlm_generic_payload& trans) 21511818SChristian.Menard@tu-dresden.de{ 21612048Schristian.menard@tu-dresden.de check_address(trans.get_address()); 21712048Schristian.menard@tu-dresden.de 21811818SChristian.Menard@tu-dresden.de tlm::tlm_command cmd = trans.get_command(); 21911818SChristian.Menard@tu-dresden.de sc_dt::uint64 adr = trans.get_address() - offset; 22011818SChristian.Menard@tu-dresden.de unsigned char* ptr = trans.get_data_ptr(); 22111818SChristian.Menard@tu-dresden.de unsigned int len = trans.get_data_length(); 22211818SChristian.Menard@tu-dresden.de unsigned char* byt = trans.get_byte_enable_ptr(); 22311818SChristian.Menard@tu-dresden.de unsigned int wid = trans.get_streaming_width(); 22411818SChristian.Menard@tu-dresden.de 22511818SChristian.Menard@tu-dresden.de if ( byt != 0 ) { 22611818SChristian.Menard@tu-dresden.de cout << "Byte Error" << endl; 22711818SChristian.Menard@tu-dresden.de trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE ); 22811818SChristian.Menard@tu-dresden.de return; 22911818SChristian.Menard@tu-dresden.de } 23011818SChristian.Menard@tu-dresden.de 23111818SChristian.Menard@tu-dresden.de //if ( len > 4 || wid < len ) { 23211818SChristian.Menard@tu-dresden.de // cout << "Burst Error len=" << len << " wid=" << wid << endl; 23311818SChristian.Menard@tu-dresden.de // trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE ); 23411818SChristian.Menard@tu-dresden.de // return; 23511818SChristian.Menard@tu-dresden.de //} 23611818SChristian.Menard@tu-dresden.de 23711818SChristian.Menard@tu-dresden.de unsigned char *mem_array_ptr = mem + adr; 23811818SChristian.Menard@tu-dresden.de 23911818SChristian.Menard@tu-dresden.de /* Load / Store the access: */ 24011818SChristian.Menard@tu-dresden.de if ( cmd == tlm::TLM_READ_COMMAND ) { 24111818SChristian.Menard@tu-dresden.de if (debug) { 24211818SChristian.Menard@tu-dresden.de SC_REPORT_INFO("target", "tlm::TLM_READ_COMMAND"); 24311818SChristian.Menard@tu-dresden.de } 24411818SChristian.Menard@tu-dresden.de std::memcpy(ptr, mem_array_ptr, len); 24511818SChristian.Menard@tu-dresden.de } else if ( cmd == tlm::TLM_WRITE_COMMAND ) { 24611818SChristian.Menard@tu-dresden.de if (debug) { 24711818SChristian.Menard@tu-dresden.de SC_REPORT_INFO("target", "tlm::TLM_WRITE_COMMAND"); 24811818SChristian.Menard@tu-dresden.de } 24911818SChristian.Menard@tu-dresden.de std::memcpy(mem_array_ptr, ptr, len); 25011818SChristian.Menard@tu-dresden.de } 25111818SChristian.Menard@tu-dresden.de 25211818SChristian.Menard@tu-dresden.de trans.set_response_status( tlm::TLM_OK_RESPONSE ); 25311818SChristian.Menard@tu-dresden.de} 25411818SChristian.Menard@tu-dresden.de 25511818SChristian.Menard@tu-dresden.devoid 25611818SChristian.Menard@tu-dresden.deTarget::send_response(tlm::tlm_generic_payload& trans) 25711818SChristian.Menard@tu-dresden.de{ 25811818SChristian.Menard@tu-dresden.de tlm::tlm_sync_enum status; 25911818SChristian.Menard@tu-dresden.de tlm::tlm_phase bw_phase; 26011818SChristian.Menard@tu-dresden.de sc_time delay; 26111818SChristian.Menard@tu-dresden.de 26211818SChristian.Menard@tu-dresden.de response_in_progress = true; 26311818SChristian.Menard@tu-dresden.de bw_phase = tlm::BEGIN_RESP; 26411818SChristian.Menard@tu-dresden.de delay = sc_time(10.0, SC_NS); 26511818SChristian.Menard@tu-dresden.de status = socket->nb_transport_bw( trans, bw_phase, delay ); 26611818SChristian.Menard@tu-dresden.de 26711818SChristian.Menard@tu-dresden.de if (status == tlm::TLM_UPDATED) { 26811818SChristian.Menard@tu-dresden.de /* The timing annotation must be honored */ 26911818SChristian.Menard@tu-dresden.de m_peq.notify(trans, bw_phase, delay); 27011818SChristian.Menard@tu-dresden.de } else if (status == tlm::TLM_COMPLETED) { 27111818SChristian.Menard@tu-dresden.de /* The initiator has terminated the transaction */ 27211818SChristian.Menard@tu-dresden.de transaction_in_progress = 0; 27311818SChristian.Menard@tu-dresden.de response_in_progress = false; 27411818SChristian.Menard@tu-dresden.de } 27511818SChristian.Menard@tu-dresden.de trans.release(); 27611818SChristian.Menard@tu-dresden.de} 277