// TLM-2 blocking transport method virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) { tlm::tlm_command cmd = trans.get_command(); sc_dt::uint64 adr = trans.get_address(); 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 DMI hint and extensions // Using the SystemC report handler is an acceptable way of signalling an error if (adr >= sc_dt::uint64(SIZE) || byt != 0 || len > 4 || wid < len) SC_REPORT_ERROR("TLM-2", "Target does not support given generic payload transaction"); // Obliged to implement read and write commands if ( cmd == tlm::TLM_READ_COMMAND ){ memcpy(ptr, &mem[adr], len); cout << "Data: " << dec << mem[adr] << " is read from Address: " << dec << adr << endl; } else if ( cmd == tlm::TLM_WRITE_COMMAND ){ memcpy(&mem[adr], ptr, len); cout << "Data: " << dec << mem[adr] << " is written into Address: " << dec << adr << endl; } // Obliged to set response status to indicate successful completion trans.set_response_status( tlm::TLM_OK_RESPONSE ); }
inline void lt_target::b_transport(tlm::tlm_generic_payload& trans, sc_time& delay){ 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 blen = trans.get_byte_enable_length(); unsigned int wid = trans.get_streaming_width(); if (adr >= sc_dt::uint64(mem_size) ) { trans.set_response_status( tlm::TLM_ADDRESS_ERROR_RESPONSE ); return; } if ( wid < len ) { trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE ); return; } if (trans.is_read()) { delay += rd_latency; if ( byt != 0 ) { for ( unsigned int i = 0; i < len; i++ ) if ( byt[i % blen] == TLM_BYTE_ENABLED ){ ptr[i] = (mem[adr+i/4] >> ((i&3)*8)) & 0xFF; } } else {
// TLM-2 non-blocking transport method tlm::tlm_sync_enum nb_transport_fw(int tag, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay){ sc_dt::uint64 adr = trans.get_address(); 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 the transaction attributes for unsupported features // and to generate the appropriate error response if (byt != 0){ trans.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE); return tlm::TLM_COMPLETED; } if(adr > this->size){ trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE); std::cerr << "Error requesting address " << std::showbase << std::hex << adr << std::dec << std::endl; return tlm::TLM_COMPLETED; } // Now queue the transaction until the annotated time has elapsed if(phase == tlm::BEGIN_REQ){ while(this->transactionInProgress){ //std::cerr << "waiting for transactionInProgress" << std::endl; wait(this->transactionCompleted); } //std::cerr << "there are no transactionInProgress" << std::endl; this->transactionInProgress = true; } this->transId = tag; m_peq.notify(trans, phase, delay); trans.set_response_status(tlm::TLM_OK_RESPONSE); return tlm::TLM_ACCEPTED; }
// TLM-2 blocking transport method virtual void 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 >= sc_dt::uint64(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; } // 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); // Illustrates that b_transport may block wait(delay); // Reset timing annotation after waiting delay = SC_ZERO_TIME; // ********************************************* // 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 ); }
void memory::operation ( tlm::tlm_generic_payload &gp , sc_core::sc_time &delay_time ///< transaction delay ) { sc_dt::uint64 address = gp.get_address(); // memory address tlm::tlm_command command = gp.get_command(); // memory command unsigned char *data = gp.get_data_ptr(); // data pointer unsigned int length = gp.get_data_length(); // data length tlm::tlm_response_status response_status = check_address(gp) ? tlm::TLM_OK_RESPONSE : tlm::TLM_ADDRESS_ERROR_RESPONSE; if (gp.get_byte_enable_ptr()) { gp.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE); } else if (gp.get_streaming_width() != gp.get_data_length()) { gp.set_response_status(tlm::TLM_BURST_ERROR_RESPONSE); } switch (command) { default: { gp.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE); break; } case tlm::TLM_WRITE_COMMAND: { if (response_status == tlm::TLM_OK_RESPONSE) { for (unsigned int i = 0; i < length; i++) { m_memory[address++] = data[i]; // move the data to memory } } break; } case tlm::TLM_READ_COMMAND: { if (response_status == tlm::TLM_OK_RESPONSE) { for (unsigned int i = 0; i < length; i++) { data[i] = m_memory[address++]; // move the data from memory } } break; } } // end switch gp.set_response_status(response_status); }
// TLM-2 blocking transport method virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) { tlm::tlm_command cmd = trans.get_command(); sc_dt::uint64 adr = trans.get_address(); 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 DMI hint and extensions // Using the SystemC report handler is an acceptable way of signalling an error if (adr >= sc_dt::uint64(SIZE) * 4 || adr % 4) { trans.set_response_status( tlm::TLM_ADDRESS_ERROR_RESPONSE ); return; } else if (byt != 0) { trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE ); return; } else if (len > 4 || wid < len) { trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE ); return; } // Obliged to implement read and write commands if ( cmd == tlm::TLM_READ_COMMAND ) memcpy(ptr, &mem[adr/4], len); else if ( cmd == tlm::TLM_WRITE_COMMAND ) memcpy(&mem[adr/4], ptr, len); // Obliged to set response status to indicate successful completion trans.set_response_status( tlm::TLM_OK_RESPONSE ); }
virtual tlm::tlm_sync_enum nb_transport_fw( tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay ) { sc_dt::uint64 adr = trans.get_address(); 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 the transaction attributes for unsupported features // and to generate the appropriate error response if (byt != 0) { trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE ); return tlm::TLM_COMPLETED; } if (len > 4 || wid < len) { trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE ); return tlm::TLM_COMPLETED; } // Now queue the transaction until the annotated time has elapsed m_peq.notify( trans, phase, delay); return tlm::TLM_ACCEPTED; }
//============================================================================== /// @fn memory::operation // /// @brief performs read and write // /// @details /// This routine implements the read and write operations. including /// checking for byte_enable and streaming that are not implemented // //============================================================================== void memory::operation ( tlm::tlm_generic_payload &gp , sc_core::sc_time &delay_time ///< transaction delay ) { /// Access the required attributes from the payload sc_dt::uint64 address = gp.get_address(); // memory address tlm::tlm_command command = gp.get_command(); // memory command unsigned char *data = gp.get_data_ptr(); // data pointer unsigned int length = gp.get_data_length(); // data length std::ostringstream msg; msg.str(""); tlm::tlm_response_status response_status = check_address(gp); if (gp.get_byte_enable_ptr()) { gp.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE); } else if (gp.get_streaming_width() != gp.get_data_length()) { gp.set_response_status(tlm::TLM_BURST_ERROR_RESPONSE); } switch (command) { default: { if (m_previous_warning == false) { msg << "Target: " << m_ID << " Unsupported Command Extension"; REPORT_INFO(filename, __FUNCTION__, msg.str()); gp.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE); delay_time = sc_core::SC_ZERO_TIME; m_previous_warning = true; } break; } /// Setup a TLM_WRITE_COMMAND Informational Message and Write the Data from /// the Generic Payload Data pointer to Memory /// case tlm::TLM_WRITE_COMMAND: { if (response_status == tlm::TLM_OK_RESPONSE) { for (unsigned int i = 0; i < length; i++) { m_memory[address++] = data[i]; // move the data to memory } delay_time = delay_time + m_write_delay; report::print(m_ID, gp, filename); } break; } case tlm::TLM_READ_COMMAND: { if (response_status == tlm::TLM_OK_RESPONSE) { for (unsigned int i = 0; i < length; i++) { data[i] = m_memory[address++]; // move the data to memory } delay_time = delay_time + m_read_delay; report::print(m_ID, gp, filename); } break; } } // end switch gp.set_response_status(response_status); return; } // end memory_operation