/* * target.cpp * * Created on: 02.12.2018 * Author: eyck */ #include "target.h" void Memory::b_transport(tlm::tlm_generic_payload& trans, sc_time& delay) { tlm::tlm_command cmd = trans.get_command(); sc_dt::uint64 adr = trans.get_address() / 4; unsigned char* ptr = trans.get_data_ptr(); unsigned int len = trans.get_data_length(); unsigned char* byt = trans.get_byte_enable_ptr(); unsigned int wid = trans.get_streaming_width(); // Obliged to check address range and check for unsupported features, // i.e. byte enables, streaming, and bursts // Can ignore extensions // Generate the appropriate error response if (adr >= SIZE) { trans.set_response_status( tlm::TLM_ADDRESS_ERROR_RESPONSE ); return; } if (byt != 0) { trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE ); return; } if (len > 4 || wid < len) { trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE ); return; } wait(delay); delay = SC_ZERO_TIME; // Obliged to implement read and write commands if ( cmd == tlm::TLM_READ_COMMAND ) memcpy(ptr, &mem[adr], len); else if ( cmd == tlm::TLM_WRITE_COMMAND ) memcpy(&mem[adr], ptr, len); // Set DMI hint to indicated that DMI is supported trans.set_dmi_allowed(true); // Obliged to set response status to indicate successful completion trans.set_response_status( tlm::TLM_OK_RESPONSE ); } bool Memory::get_direct_mem_ptr(tlm::tlm_generic_payload& trans, tlm::tlm_dmi& dmi_data) { // Permit read and write access dmi_data.allow_read_write(); // Set other details of DMI region dmi_data.set_dmi_ptr( reinterpret_cast( &mem[0] ) ); dmi_data.set_start_address( 0 ); dmi_data.set_end_address( SIZE*4-1 ); dmi_data.set_read_latency( LATENCY ); dmi_data.set_write_latency( LATENCY ); return true; } Memory::Memory(sc_core::sc_module_name nm) : socket("socket") , clk_i("clk_i") , reset_i("reset_i") , LATENCY(10, SC_NS) { // Register callbacks for incoming interface method calls socket.register_b_transport( this, &Memory::b_transport); socket.register_get_direct_mem_ptr(this, &Memory::get_direct_mem_ptr); socket.register_transport_dbg( this, &Memory::transport_dbg); // Initialize memory with random data for (int i = 0; i < SIZE; i++) mem[i] = 0xAA000000 | (mem_nr << 20) | (rand() % 256); ++mem_nr; } // TLM-2 debug transaction method unsigned int Memory::transport_dbg(tlm::tlm_generic_payload& trans) { tlm::tlm_command cmd = trans.get_command(); sc_dt::uint64 adr = trans.get_address() / 4; unsigned char* ptr = trans.get_data_ptr(); unsigned int len = trans.get_data_length(); // Calculate the number of bytes to be actually copied unsigned int num_bytes = (len < (SIZE - adr) * 4) ? len : (SIZE - adr) * 4; if ( cmd == tlm::TLM_READ_COMMAND ) memcpy(ptr, &mem[adr], num_bytes); else if ( cmd == tlm::TLM_WRITE_COMMAND ) memcpy(&mem[adr], ptr, num_bytes); return num_bytes; }