sc_target.cc revision 11818
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 6911818SChristian.Menard@tu-dresden.deTarget::b_transport(tlm::tlm_generic_payload& trans, sc_time& delay) 7011818SChristian.Menard@tu-dresden.de{ 7111818SChristian.Menard@tu-dresden.de /* Execute the read or write commands */ 7211818SChristian.Menard@tu-dresden.de execute_transaction(trans); 7311818SChristian.Menard@tu-dresden.de} 7411818SChristian.Menard@tu-dresden.de 7511818SChristian.Menard@tu-dresden.deunsigned int 7611818SChristian.Menard@tu-dresden.deTarget::transport_dbg(tlm::tlm_generic_payload& trans) 7711818SChristian.Menard@tu-dresden.de{ 7811818SChristian.Menard@tu-dresden.de tlm::tlm_command cmd = trans.get_command(); 7911818SChristian.Menard@tu-dresden.de sc_dt::uint64 adr = trans.get_address() - offset; 8011818SChristian.Menard@tu-dresden.de unsigned char* ptr = trans.get_data_ptr(); 8111818SChristian.Menard@tu-dresden.de unsigned int len = trans.get_data_length(); 8211818SChristian.Menard@tu-dresden.de 8311818SChristian.Menard@tu-dresden.de unsigned char *mem_array_ptr = mem + adr; 8411818SChristian.Menard@tu-dresden.de 8511818SChristian.Menard@tu-dresden.de /* Load / Store the access: */ 8611818SChristian.Menard@tu-dresden.de if ( cmd == tlm::TLM_READ_COMMAND ) { 8711818SChristian.Menard@tu-dresden.de if (debug) { 8811818SChristian.Menard@tu-dresden.de SC_REPORT_INFO("target", "tlm::TLM_READ_COMMAND"); 8911818SChristian.Menard@tu-dresden.de } 9011818SChristian.Menard@tu-dresden.de std::memcpy(ptr, mem_array_ptr, len); 9111818SChristian.Menard@tu-dresden.de } else if ( cmd == tlm::TLM_WRITE_COMMAND ) { 9211818SChristian.Menard@tu-dresden.de if (debug) { 9311818SChristian.Menard@tu-dresden.de SC_REPORT_INFO("target", "tlm::TLM_WRITE_COMMAND"); 9411818SChristian.Menard@tu-dresden.de } 9511818SChristian.Menard@tu-dresden.de std::memcpy(mem_array_ptr, ptr, len); 9611818SChristian.Menard@tu-dresden.de } 9711818SChristian.Menard@tu-dresden.de 9811818SChristian.Menard@tu-dresden.de return len; 9911818SChristian.Menard@tu-dresden.de} 10011818SChristian.Menard@tu-dresden.de 10111818SChristian.Menard@tu-dresden.de 10211818SChristian.Menard@tu-dresden.de/* TLM-2 non-blocking transport method */ 10311818SChristian.Menard@tu-dresden.detlm::tlm_sync_enum Target::nb_transport_fw(tlm::tlm_generic_payload& trans, 10411818SChristian.Menard@tu-dresden.de tlm::tlm_phase& phase, 10511818SChristian.Menard@tu-dresden.de sc_time& delay) 10611818SChristian.Menard@tu-dresden.de{ 10711818SChristian.Menard@tu-dresden.de /* Queue the transaction until the annotated time has elapsed */ 10811818SChristian.Menard@tu-dresden.de m_peq.notify(trans, phase, delay); 10911818SChristian.Menard@tu-dresden.de return tlm::TLM_ACCEPTED; 11011818SChristian.Menard@tu-dresden.de} 11111818SChristian.Menard@tu-dresden.de 11211818SChristian.Menard@tu-dresden.devoid 11311818SChristian.Menard@tu-dresden.deTarget::peq_cb(tlm::tlm_generic_payload& trans, 11411818SChristian.Menard@tu-dresden.de const tlm::tlm_phase& phase) 11511818SChristian.Menard@tu-dresden.de{ 11611818SChristian.Menard@tu-dresden.de sc_time delay; 11711818SChristian.Menard@tu-dresden.de 11811818SChristian.Menard@tu-dresden.de if (phase == tlm::BEGIN_REQ) { 11911818SChristian.Menard@tu-dresden.de if (debug) SC_REPORT_INFO("target", "tlm::BEGIN_REQ"); 12011818SChristian.Menard@tu-dresden.de 12111818SChristian.Menard@tu-dresden.de /* Increment the transaction reference count */ 12211818SChristian.Menard@tu-dresden.de trans.acquire(); 12311818SChristian.Menard@tu-dresden.de 12411818SChristian.Menard@tu-dresden.de if ( !transaction_in_progress ) { 12511818SChristian.Menard@tu-dresden.de send_end_req(trans); 12611818SChristian.Menard@tu-dresden.de } else { 12711818SChristian.Menard@tu-dresden.de /* Put back-pressure on initiator by deferring END_REQ until 12811818SChristian.Menard@tu-dresden.de * pipeline is clear */ 12911818SChristian.Menard@tu-dresden.de end_req_pending = &trans; 13011818SChristian.Menard@tu-dresden.de } 13111818SChristian.Menard@tu-dresden.de } else if (phase == tlm::END_RESP) { 13211818SChristian.Menard@tu-dresden.de /* On receiving END_RESP, the target can release the transaction and 13311818SChristian.Menard@tu-dresden.de * allow other pending transactions to proceed */ 13411818SChristian.Menard@tu-dresden.de if (!response_in_progress) { 13511818SChristian.Menard@tu-dresden.de SC_REPORT_FATAL("TLM-2", "Illegal transaction phase END_RESP" 13611818SChristian.Menard@tu-dresden.de "received by target"); 13711818SChristian.Menard@tu-dresden.de } 13811818SChristian.Menard@tu-dresden.de 13911818SChristian.Menard@tu-dresden.de transaction_in_progress = 0; 14011818SChristian.Menard@tu-dresden.de 14111818SChristian.Menard@tu-dresden.de /* Target itself is now clear to issue the next BEGIN_RESP */ 14211818SChristian.Menard@tu-dresden.de response_in_progress = false; 14311818SChristian.Menard@tu-dresden.de if (next_response_pending) { 14411818SChristian.Menard@tu-dresden.de send_response( *next_response_pending ); 14511818SChristian.Menard@tu-dresden.de next_response_pending = 0; 14611818SChristian.Menard@tu-dresden.de } 14711818SChristian.Menard@tu-dresden.de 14811818SChristian.Menard@tu-dresden.de /* ... and to unblock the initiator by issuing END_REQ */ 14911818SChristian.Menard@tu-dresden.de if (end_req_pending) { 15011818SChristian.Menard@tu-dresden.de send_end_req( *end_req_pending ); 15111818SChristian.Menard@tu-dresden.de end_req_pending = 0; 15211818SChristian.Menard@tu-dresden.de } 15311818SChristian.Menard@tu-dresden.de 15411818SChristian.Menard@tu-dresden.de } else /* tlm::END_REQ or tlm::BEGIN_RESP */ { 15511818SChristian.Menard@tu-dresden.de SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by" 15611818SChristian.Menard@tu-dresden.de "target"); 15711818SChristian.Menard@tu-dresden.de } 15811818SChristian.Menard@tu-dresden.de} 15911818SChristian.Menard@tu-dresden.de 16011818SChristian.Menard@tu-dresden.devoid 16111818SChristian.Menard@tu-dresden.deTarget::send_end_req(tlm::tlm_generic_payload& trans) 16211818SChristian.Menard@tu-dresden.de{ 16311818SChristian.Menard@tu-dresden.de tlm::tlm_phase bw_phase; 16411818SChristian.Menard@tu-dresden.de sc_time delay; 16511818SChristian.Menard@tu-dresden.de 16611818SChristian.Menard@tu-dresden.de /* Queue the acceptance and the response with the appropriate latency */ 16711818SChristian.Menard@tu-dresden.de bw_phase = tlm::END_REQ; 16811818SChristian.Menard@tu-dresden.de delay = sc_time(10.0, SC_NS); // Accept delay 16911818SChristian.Menard@tu-dresden.de 17011818SChristian.Menard@tu-dresden.de tlm::tlm_sync_enum status; 17111818SChristian.Menard@tu-dresden.de status = socket->nb_transport_bw(trans, bw_phase, delay); 17211818SChristian.Menard@tu-dresden.de 17311818SChristian.Menard@tu-dresden.de /* Ignore return value; 17411818SChristian.Menard@tu-dresden.de * initiator cannot terminate transaction at this point 17511818SChristian.Menard@tu-dresden.de * Queue internal event to mark beginning of response: */ 17611818SChristian.Menard@tu-dresden.de delay = delay + sc_time(40.0, SC_NS); // Latency 17711818SChristian.Menard@tu-dresden.de target_done_event.notify(delay); 17811818SChristian.Menard@tu-dresden.de 17911818SChristian.Menard@tu-dresden.de assert(transaction_in_progress == 0); 18011818SChristian.Menard@tu-dresden.de transaction_in_progress = &trans; 18111818SChristian.Menard@tu-dresden.de} 18211818SChristian.Menard@tu-dresden.de 18311818SChristian.Menard@tu-dresden.devoid 18411818SChristian.Menard@tu-dresden.deTarget::execute_transaction_process() 18511818SChristian.Menard@tu-dresden.de{ 18611818SChristian.Menard@tu-dresden.de /* Execute the read or write commands */ 18711818SChristian.Menard@tu-dresden.de execute_transaction( *transaction_in_progress ); 18811818SChristian.Menard@tu-dresden.de 18911818SChristian.Menard@tu-dresden.de /* Target must honor BEGIN_RESP/END_RESP exclusion rule; i.e. must not 19011818SChristian.Menard@tu-dresden.de * send BEGIN_RESP until receiving previous END_RESP or BEGIN_REQ */ 19111818SChristian.Menard@tu-dresden.de if (response_in_progress) { 19211818SChristian.Menard@tu-dresden.de /* Target allows only two transactions in-flight */ 19311818SChristian.Menard@tu-dresden.de if (next_response_pending) { 19411818SChristian.Menard@tu-dresden.de SC_REPORT_FATAL("TLM-2", "Attempt to have two pending responses" 19511818SChristian.Menard@tu-dresden.de "in target"); 19611818SChristian.Menard@tu-dresden.de } 19711818SChristian.Menard@tu-dresden.de next_response_pending = transaction_in_progress; 19811818SChristian.Menard@tu-dresden.de } else { 19911818SChristian.Menard@tu-dresden.de send_response( *transaction_in_progress ); 20011818SChristian.Menard@tu-dresden.de } 20111818SChristian.Menard@tu-dresden.de} 20211818SChristian.Menard@tu-dresden.de 20311818SChristian.Menard@tu-dresden.devoid 20411818SChristian.Menard@tu-dresden.deTarget::execute_transaction(tlm::tlm_generic_payload& trans) 20511818SChristian.Menard@tu-dresden.de{ 20611818SChristian.Menard@tu-dresden.de tlm::tlm_command cmd = trans.get_command(); 20711818SChristian.Menard@tu-dresden.de sc_dt::uint64 adr = trans.get_address() - offset; 20811818SChristian.Menard@tu-dresden.de unsigned char* ptr = trans.get_data_ptr(); 20911818SChristian.Menard@tu-dresden.de unsigned int len = trans.get_data_length(); 21011818SChristian.Menard@tu-dresden.de unsigned char* byt = trans.get_byte_enable_ptr(); 21111818SChristian.Menard@tu-dresden.de unsigned int wid = trans.get_streaming_width(); 21211818SChristian.Menard@tu-dresden.de 21311818SChristian.Menard@tu-dresden.de if ( byt != 0 ) { 21411818SChristian.Menard@tu-dresden.de cout << "Byte Error" << endl; 21511818SChristian.Menard@tu-dresden.de trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE ); 21611818SChristian.Menard@tu-dresden.de return; 21711818SChristian.Menard@tu-dresden.de } 21811818SChristian.Menard@tu-dresden.de 21911818SChristian.Menard@tu-dresden.de //if ( len > 4 || wid < len ) { 22011818SChristian.Menard@tu-dresden.de // cout << "Burst Error len=" << len << " wid=" << wid << endl; 22111818SChristian.Menard@tu-dresden.de // trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE ); 22211818SChristian.Menard@tu-dresden.de // return; 22311818SChristian.Menard@tu-dresden.de //} 22411818SChristian.Menard@tu-dresden.de 22511818SChristian.Menard@tu-dresden.de unsigned char *mem_array_ptr = mem + adr; 22611818SChristian.Menard@tu-dresden.de 22711818SChristian.Menard@tu-dresden.de /* Load / Store the access: */ 22811818SChristian.Menard@tu-dresden.de if ( cmd == tlm::TLM_READ_COMMAND ) { 22911818SChristian.Menard@tu-dresden.de if (debug) { 23011818SChristian.Menard@tu-dresden.de SC_REPORT_INFO("target", "tlm::TLM_READ_COMMAND"); 23111818SChristian.Menard@tu-dresden.de } 23211818SChristian.Menard@tu-dresden.de std::memcpy(ptr, mem_array_ptr, len); 23311818SChristian.Menard@tu-dresden.de } else if ( cmd == tlm::TLM_WRITE_COMMAND ) { 23411818SChristian.Menard@tu-dresden.de if (debug) { 23511818SChristian.Menard@tu-dresden.de SC_REPORT_INFO("target", "tlm::TLM_WRITE_COMMAND"); 23611818SChristian.Menard@tu-dresden.de } 23711818SChristian.Menard@tu-dresden.de std::memcpy(mem_array_ptr, ptr, len); 23811818SChristian.Menard@tu-dresden.de } 23911818SChristian.Menard@tu-dresden.de 24011818SChristian.Menard@tu-dresden.de trans.set_response_status( tlm::TLM_OK_RESPONSE ); 24111818SChristian.Menard@tu-dresden.de} 24211818SChristian.Menard@tu-dresden.de 24311818SChristian.Menard@tu-dresden.devoid 24411818SChristian.Menard@tu-dresden.deTarget::send_response(tlm::tlm_generic_payload& trans) 24511818SChristian.Menard@tu-dresden.de{ 24611818SChristian.Menard@tu-dresden.de tlm::tlm_sync_enum status; 24711818SChristian.Menard@tu-dresden.de tlm::tlm_phase bw_phase; 24811818SChristian.Menard@tu-dresden.de sc_time delay; 24911818SChristian.Menard@tu-dresden.de 25011818SChristian.Menard@tu-dresden.de response_in_progress = true; 25111818SChristian.Menard@tu-dresden.de bw_phase = tlm::BEGIN_RESP; 25211818SChristian.Menard@tu-dresden.de delay = sc_time(10.0, SC_NS); 25311818SChristian.Menard@tu-dresden.de status = socket->nb_transport_bw( trans, bw_phase, delay ); 25411818SChristian.Menard@tu-dresden.de 25511818SChristian.Menard@tu-dresden.de if (status == tlm::TLM_UPDATED) { 25611818SChristian.Menard@tu-dresden.de /* The timing annotation must be honored */ 25711818SChristian.Menard@tu-dresden.de m_peq.notify(trans, bw_phase, delay); 25811818SChristian.Menard@tu-dresden.de } else if (status == tlm::TLM_COMPLETED) { 25911818SChristian.Menard@tu-dresden.de /* The initiator has terminated the transaction */ 26011818SChristian.Menard@tu-dresden.de transaction_in_progress = 0; 26111818SChristian.Menard@tu-dresden.de response_in_progress = false; 26211818SChristian.Menard@tu-dresden.de } 26311818SChristian.Menard@tu-dresden.de trans.release(); 26411818SChristian.Menard@tu-dresden.de} 265