void peq_cb(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase) { #ifdef DEBUG if (phase == tlm::END_REQ) fout << hex << trans.get_address() << " " << name() << " END_REQ at " << sc_time_stamp() << endl; else if (phase == tlm::BEGIN_RESP) fout << hex << trans.get_address() << " " << name() << " BEGIN_RESP at " << sc_time_stamp() << endl; #endif if (phase == tlm::END_REQ || (&trans == request_in_progress && phase == tlm::BEGIN_RESP)) { // The end of the BEGIN_REQ phase request_in_progress = 0; end_request_event.notify(); } else if (phase == tlm::BEGIN_REQ || phase == tlm::END_RESP) SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by initiator"); if (phase == tlm::BEGIN_RESP) { check_transaction( trans ); // Send final phase transition to target tlm::tlm_phase fw_phase = tlm::END_RESP; sc_time delay = sc_time(rand_ps(), SC_PS); socket->nb_transport_fw( trans, fw_phase, delay ); // Ignore return value } }
virtual void b_transport(int socketId, tlm::tlm_generic_payload& trans, sc_time & delay) { // if the address is in range if (trans.get_address() <= MAX_ADDRESS) { //forward the message (*init_sock[trans.get_address()])->b_transport(trans, delay); } else { //else error status trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE); } }
// Tagged non-blocking transport forward method virtual tlm::tlm_sync_enum nb_transport_fw(int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay) { assert (id < targ_socket.size()); // Forward path m_id_map[ &trans ] = id; sc_dt::uint64 address = trans.get_address(); sc_dt::uint64 masked_address; unsigned int target_nr = decode_address( address, masked_address); if (target_nr < init_socket.size()) { // Modify address within transaction trans.set_address( masked_address ); // Forward transaction to appropriate target tlm::tlm_sync_enum status = init_socket[target_nr]->nb_transport_fw(trans, phase, delay); if (status == tlm::TLM_COMPLETED) // Put back original address trans.set_address( address ); return status; } else return tlm::TLM_COMPLETED; }
// 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; }
//Method used for receiving acknowledgements of interrupts; the ack consists of //uninteresting data and the address corresponds to the interrupt signal to //be lowered //As a response, I lower the interrupt by sending a NULL pointer on the init_socket void b_transport(tlm::tlm_generic_payload& trans, sc_time& delay) { if(this->lastIrq < 0) { THROW_EXCEPTION("Error, lowering an interrupt which hasn't been raised yet!!"); } tlm::tlm_command cmd = trans.get_command(); sc_dt::uint64 adr = trans.get_address(); unsigned char* ptr = trans.get_data_ptr(); if(trans.get_command() == tlm::TLM_READ_COMMAND) { THROW_EXCEPTION("Error, the read request is not currently supported by external PINs"); } else if(cmd == tlm::TLM_WRITE_COMMAND) { if(this->lastIrq != adr) { THROW_EXCEPTION("Error, lowering interrupt " << std::hex << std::showbase << (unsigned)adr << " while " << std::hex << std::showbase << this->lastIrq << " was raised"); } else { //finally I can really lower the interrupt: I send 0 on //the initSocked unsigned char data = 0; trans.set_data_ptr(&data); trans.set_dmi_allowed(false); trans.set_response_status( tlm::TLM_INCOMPLETE_RESPONSE ); sc_time delay; this->init_socket->b_transport(trans, delay); if(trans.is_response_error()) { std::string errorStr("Error in b_transport of PIN, response status = " + trans.get_response_string()); SC_REPORT_ERROR("TLM-2", errorStr.c_str()); } this->lastIrq = -1; } } trans.set_response_status(tlm::TLM_OK_RESPONSE); }
//============================================================================== /// @fn memory::check_address // /// @brief Method to check if the gp is in the address range of this memory // /// @details /// This routine used to check for errors in address space // //============================================================================== tlm::tlm_response_status memory::check_address ( tlm::tlm_generic_payload &gp ) { sc_dt::uint64 address = gp.get_address(); // memory address unsigned int length = gp.get_data_length(); // data length std::ostringstream msg; msg.str(""); if ( address >= m_memory_size ) { msg << "Target: " << m_ID <<" address out-of-range"; REPORT_WARNING(filename, __FUNCTION__, msg.str()); return tlm::TLM_ADDRESS_ERROR_RESPONSE; // operation response } else { if ( (address + length) >= m_memory_size ) { msg << "Target: " << m_ID << " address will go out of bounds"; REPORT_WARNING(filename, __FUNCTION__, msg.str()); return tlm::TLM_ADDRESS_ERROR_RESPONSE; // operation response } return tlm::TLM_OK_RESPONSE; } } // end check address
// 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 {
//============================================================================== bool dmi_memory::is_address_dmi ( tlm::tlm_generic_payload &gp ) { m_start_address = gp.get_address(); m_end_address = m_start_address + gp.get_data_length(); std::ostringstream msg; msg.str(""); msg << "Initiator:" << m_ID; bool return_status = false; if ( ( ( m_start_address < ( m_dmi_base_address ) ) || ( m_end_address > ( m_dmi_base_address + m_dmi_size ) ) ) ) { // address is outside of the DMI boundaries msg << " address is not a dmi address"; // msg << "m_start_address= " << m_start_address << " m_address= " << m_address // << endl << " " // << "m_end_address= " << m_end_address << " m_offset= " << m_offset << " m_dmi_size= "<< m_dmi_size; REPORT_INFO(filename, __FUNCTION__, msg.str()); } else if ( ( gp.get_command () == tlm::TLM_WRITE_COMMAND ) ) { if ( (m_granted_access != tlm::tlm_dmi::DMI_ACCESS_READ ) && ( m_granted_access != tlm::tlm_dmi::DMI_ACCESS_NONE)){ msg << " correct address and appropriate access for a GP Write Command "<<endl<<" "; REPORT_INFO(filename, __FUNCTION__, msg.str()); return_status=true; } } //end if else if ( ( gp.get_command () == tlm::TLM_READ_COMMAND ) ) { if ( (m_granted_access != tlm::tlm_dmi::DMI_ACCESS_WRITE ) && ( m_granted_access != tlm::tlm_dmi::DMI_ACCESS_NONE)){ msg << " correct address and appropriate access for a GP Read Command "<<endl<<" "; REPORT_INFO(filename, __FUNCTION__, msg.str()); return_status=true; } } //end if else { // access permission does not match access required for operation msg << " Incompatible GP Command for DMI Access Granted "; // msg << " Gp.getcommand()= " << gp.get_command(); REPORT_INFO(filename, __FUNCTION__, msg.str()); } //end else return return_status; } // end check is dmi
// Tagged debug transaction method virtual unsigned int transport_dbg(int id, tlm::tlm_generic_payload& trans) { sc_dt::uint64 masked_address; unsigned int target_nr = decode_address( trans.get_address(), masked_address ); if (target_nr >= init_socket.size()) return 0; trans.set_address( masked_address ); // Forward debug transaction to appropriate target return init_socket[target_nr]->transport_dbg( trans ); }
bool IO_t_base::triggerRegistersGotHit(unsigned portIndex, tlm::tlm_generic_payload& trans) { mb::utl::Segment<uint64_t> transactionRange(trans.get_address(), trans.get_address() + trans.get_data_length()); { if (0 == portIndex) { mb::utl::Segment<uint64_t> current((1 + ((0xC % 4) << 3)), (1 + ((0xC % 4) << 3))); mb::utl::Segment<uint64_t> intersect = transactionRange.intersect(current); if (!intersect.empty()) return true; } } { if (0 == portIndex) { mb::utl::Segment<uint64_t> current((1 + ((0x10 % 4) << 3)), (1 + ((0x10 % 4) << 3))); mb::utl::Segment<uint64_t> intersect = transactionRange.intersect(current); if (!intersect.empty()) return true; } } return false; }
void FastBus::b_transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &t) { ensitlm::addr_t a = trans.get_address(); addr_map_t::iterator it = addr_map.find(addr_range(a, a)); if (it == addr_map.end()) { std::cerr << name() << ": no target at address " << std::showbase << std::hex << a << std::endl; trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE); return; } trans.set_address(a - (*it).first.begin); initiator[(*it).second]->b_transport(trans, t); }
// Tagged non-blocking transport backward method virtual tlm::tlm_sync_enum nb_transport_bw(int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay) { assert (id < init_socket.size()); // Backward path // Replace original address sc_dt::uint64 address = trans.get_address(); trans.set_address( compose_address( id, address ) ); return targ_socket[ m_id_map[ &trans ] ]->nb_transport_bw(trans, phase, delay); }
// 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 leon3_funclt_trap::IntrTLMPort_32::b_transport( int tag, tlm::tlm_generic_payload \ & trans, sc_time & delay ){ unsigned char* ptr = trans.get_data_ptr(); sc_dt::uint64 adr = trans.get_address(); if(*ptr == 0){ //Lower the interrupt this->irqSignal = -1; } else{ //Raise the interrupt this->irqSignal = adr; } trans.set_response_status(tlm::TLM_OK_RESPONSE); }
//============================================================================== /// @fn memory::check_address // /// @brief Method to check if the gp is in the address range of this memory // /// @details /// This routine used to check for errors in address space // //============================================================================== bool memory::check_address ( tlm::tlm_generic_payload &gp ) { sc_dt::uint64 address = gp.get_address(); // memory address unsigned int length = gp.get_data_length(); // data length if ( (address < 0) || (address > m_high_address) ) { return 0; } else if ( (address + length-1) > m_high_address ) { return 0; } else { return 1; } } // end check address
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); }
void peq_cb(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase){ tlm::tlm_sync_enum status; sc_time delay; switch (phase){ case tlm::BEGIN_REQ: status = send_end_req(trans); break; case tlm::END_RESP: //std::cerr << "tlm::END_RESP in memory peq_cb" << std::endl; this->transactionInProgress = false; this->transactionCompleted.notify(); break; case tlm::END_REQ: case tlm::BEGIN_RESP: SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by target"); break; default: if (phase == internal_ph){ // Execute the read or write commands 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(); if(cmd == tlm::TLM_READ_COMMAND){ for(int i = 0; i < len; i++, ptr++) *ptr = this->mem[adr + i]; } else if(cmd == tlm::TLM_WRITE_COMMAND){ for(int i = 0; i < len; i++, ptr++) this->mem[adr + i] = *ptr; } trans.set_response_status(tlm::TLM_OK_RESPONSE); // Target must honor BEGIN_RESP/END_RESP exclusion rule // i.e. must not send BEGIN_RESP until receiving previous END_RESP or BEGIN_REQ send_response(trans); //std::cerr << "Memory reading address in memory " << std::hex << std::showbase << adr << std::endl; } break; } }
// Data interface to functional part of the model void mmu_cache::exec_data(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay, bool is_dbg) { // Vars for payload decoding tlm::tlm_command cmd = trans.get_command(); sc_dt::uint64 addr = trans.get_address(); unsigned char * ptr = trans.get_data_ptr(); unsigned int len = trans.get_data_length(); // Log number of reads and writes for power monitoring if (m_pow_mon) { if (cmd == tlm::TLM_READ_COMMAND) { dyn_reads += (len >> 2) + 1; } else {
virtual unsigned int 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; }
void DNP_master_device::master_cb( tlm::tlm_generic_payload &arg_Req, sc_time& delay) { uint32_t addr = (uint32_t) arg_Req.get_address(); uint32_t len = (uint32_t) arg_Req.get_data_length(); uint8_t *data_ptr = (uint8_t *) arg_Req.get_data_ptr(); crt_trans_id ++ ; memset(recvd_data, 0, sizeof(recvd_data)); if (arg_Req.is_read()){ /* * Read command */ DPRINTF("R @ 0x%08x(%d) <%d>\n", addr, len, crt_trans_id); for(uint32_t i = 0; i < len; i+=4){ #ifdef DEBUG_DNP_MASTER uint32_t *p = (uint32_t *)recvd_data; #endif send_req(crt_trans_id, (addr + i), recvd_data, 4, false); wait(rsp_rcvd_ev); memcpy((data_ptr + i), (uint32_t *)recvd_data, 4); DPRINTF("R @ 0x%08x -- %08x \n", (addr + i), *p); } }else{ /* * Write command */ DPRINTF("W @ 0x%08x(%d) <%d>\n", addr, len, crt_trans_id); for (uint32_t i = 0; i < len; i+=4){ #ifdef DEBUG_DNP_MASTER uint32_t *p = (uint32_t *)(data_ptr + i); #endif DPRINTF("W @ 0x%08x -- %08x\n", (addr + i), *p); send_req(crt_trans_id, (addr + i), (data_ptr + i), 4, true); wait(rsp_rcvd_ev); } } arg_Req.set_response_status(tlm::TLM_OK_RESPONSE); }
// TLM-2 debug transaction method unsigned int transport_dbg(int tag, tlm::tlm_generic_payload& trans){ 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(); if(cmd == tlm::TLM_READ_COMMAND){ for(int i = 0; i < len; i++, ptr++) *ptr = this->mem[adr + i]; } else if(cmd == tlm::TLM_WRITE_COMMAND){ for(int i = 0; i < len; i++, ptr++) this->mem[adr + i] = *ptr; } return len; }
bool lt_dmi_target::get_direct_mem_ptr ( tlm::tlm_generic_payload &gp ///< address + extensions , tlm::tlm_dmi &dmi_properties ///< dmi data ) { std::ostringstream msg; msg.str(""); sc_dt::uint64 address = gp.get_address(); // First check to see if we are "open" to a dmi if(!m_dmi_enabled) { msg << "Target: " << m_ID << " DMI not enabled, not expecting call "; REPORT_INFO(filename, __FUNCTION__, msg.str()); } else { // dmi processing if (address < m_end_address+1) // check that address is in our range { // set up dmi properties object ====================================== dmi_properties.allow_read_write ( ); dmi_properties.set_start_address ( m_start_address ); dmi_properties.set_end_address ( m_end_address ); dmi_properties.set_dmi_ptr ( m_target_memory.get_mem_ptr () ); dmi_properties.set_read_latency ( m_read_response_delay ); dmi_properties.set_write_latency ( m_write_response_delay ); msg << "Target: " << m_ID << " passing DMI pointer back to initiator"; REPORT_INFO(filename, __FUNCTION__, msg.str()); return true; } else { msg << "Target: " << m_ID << " DMI pointer request for address= " << address << " max address for this target = " << m_end_address+1; REPORT_INFO(filename, __FUNCTION__, msg.str()); } // end else } // end else return false; } // end get_direct_mem_ptr
// Tagged TLM-2 forward DMI method virtual bool get_direct_mem_ptr(int id, tlm::tlm_generic_payload& trans, tlm::tlm_dmi& dmi_data) { sc_dt::uint64 masked_address; unsigned int target_nr = decode_address( trans.get_address(), masked_address ); if (target_nr >= init_socket.size()) return false; trans.set_address( masked_address ); bool status = init_socket[target_nr]->get_direct_mem_ptr( trans, dmi_data ); // Calculate DMI address of target in system address space dmi_data.set_start_address( compose_address( target_nr, dmi_data.get_start_address() )); dmi_data.set_end_address ( compose_address( target_nr, dmi_data.get_end_address() )); return status; }
bool ram::get_direct_mem_ptr(tlm::tlm_generic_payload &trans, tlm::tlm_dmi &dmi_data) { sc_dt::uint64 address = trans.get_address(); if (address > m_high_address) { // should not happen cerr << "ram::get_direct_mem_ptr: address overflow"; return false; } // if (m_invalidate) m_invalidate_dmi_event.notify(m_invalidate_dmi_time); dmi_data.allow_read_write(); dmi_data.set_start_address(0x0); dmi_data.set_end_address(m_high_address); unsigned char *ptr = m_target_memory.get_mem_ptr(); trans.set_dmi_allowed(m_dmi_on); dmi_data.set_dmi_ptr(ptr); return true; }
// Called on receiving BEGIN_RESP or TLM_COMPLETED void check_transaction(tlm::tlm_generic_payload& trans) { if ( trans.is_response_error() ) { char txt[100]; sprintf(txt, "Transaction returned with error, response status = %s", trans.get_response_string().c_str()); SC_REPORT_ERROR("TLM-2", txt); } tlm::tlm_command cmd = trans.get_command(); sc_dt::uint64 adr = trans.get_address(); int* ptr = reinterpret_cast<int*>( trans.get_data_ptr() ); fout << hex << adr << " " << name() << " check, cmd=" << (cmd ? 'W' : 'R') << ", data=" << hex << *ptr << " at time " << sc_time_stamp() << endl; // Allow the memory manager to free the transaction object trans.release(); }
// Tagged TLM-2 blocking transport method virtual void b_transport( int id, tlm::tlm_generic_payload& trans, sc_time& delay ) { assert (id < targ_socket.size()); // Forward path sc_dt::uint64 address = trans.get_address(); sc_dt::uint64 masked_address; unsigned int target_nr = decode_address( address, masked_address); if (target_nr < init_socket.size()) { // Modify address within transaction trans.set_address( masked_address ); // Forward transaction to appropriate target init_socket[target_nr]->b_transport(trans, delay); // Replace original address trans.set_address( address ); } }
// 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; }
unsigned int memory::debug ( 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 bool ok = check_address(gp); if(ok) { switch (command) { case tlm::TLM_WRITE_COMMAND: for (unsigned int i = 0; i < length; i++) { m_memory[address++] = data[i]; // move the data to memory } gp.set_response_status(tlm::TLM_OK_RESPONSE); break; case tlm::TLM_READ_COMMAND: for (unsigned int i = 0; i < length; i++) { data[i] = m_memory[address++]; // move the data from memory } gp.set_response_status(tlm::TLM_OK_RESPONSE); break; default: ok = 0; break; } } // end switch return ok ? length : 0; }