//============================================================================== /// @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
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 } }
// 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; }
//====================================================================== /// @fn b_transport // /// @brief implementation of the blocking transport for transactions on /// the SAE memory // /// @details IC1 initiators only have write access und LM only has /// read access. This funtion first verifies that the requested /// memory access is allowed before executing the operation. <br> /// // //====================================================================== void target_sae::b_transport ( int id, tlm::tlm_generic_payload& tObj, sc_core::sc_time& delay ) { tlm::tlm_command cmd = tObj.get_command(); // control access rights switch(id) { case 1: //lmodel sae_mem.operation(lmodel_id_nr, tObj, delay); break; case 0: //ic1 if (cmd == tlm::TLM_READ_COMMAND ) { tObj.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE); msg << "this component has write-access only!"; ERROR_LOG(filename, __FUNCTION__ , msg.str()); return; } sae_mem.operation(ic1_id_nr, tObj, delay); break; } }
void leon3_funcat_trap::TLMMemory::peq_cb( tlm::tlm_generic_payload & trans, const \ tlm::tlm_phase & phase ){ // Payload event queue callback to handle transactions from target // Transaction could have arrived through return path or backward path if (phase == tlm::END_REQ || (&trans == request_in_progress && phase == tlm::BEGIN_RESP)){ // The end of the BEGIN_REQ phase request_in_progress = NULL; 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){ if (trans.is_response_error()){ SC_REPORT_ERROR("TLM-2", ("Transaction returned with error, response status = " + \ trans.get_response_string()).c_str()); } // Send final phase transition to target tlm::tlm_phase fw_phase = tlm::END_RESP; sc_time delay = SC_ZERO_TIME; initSocket->nb_transport_fw(trans, fw_phase, delay); if (trans.is_response_error()){ SC_REPORT_ERROR("TLM-2", ("Transaction returned with error, response status = " + \ trans.get_response_string()).c_str()); } this->end_response_event.notify(delay); } }
//============================================================================== // dbg_transport implementation calls from initiators // //============================================================================= unsigned int model_jxz_tlm::entry_transport_dbg (tlm::tlm_generic_payload &gp) { 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 gp.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE); return 0; }
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
//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); }
//============================================================================== // b_transport implementation calls from initiators // //============================================================================= void model_jxz_tlm::entry_b_transport (tlm::tlm_generic_payload &gp, sc_core:: sc_time &delay_time) { 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 unsigned long timefactor = ((length+BUSWIDTHBYTE-1)/BUSWIDTHBYTE)-1; bool write_ok = true; gp.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE); return; }
// 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 ); }
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); } }
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); }
virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) { unsigned int bel = trans.get_byte_enable_length(); trans2.set_data_ptr( data ); if (bel) trans2.set_byte_enable_ptr( byte_enable ); trans2.deep_copy_from(trans); init_socket->b_transport( trans2, delay ); trans.update_original_from( trans2 ); }
virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) { tlm::tlm_command cmd = trans.get_command(); unsigned char* ptr = trans.get_data_ptr(); unsigned int len = trans.get_data_length(); unsigned char* byt = trans.get_byte_enable_ptr(); unsigned int bel = trans.get_byte_enable_length(); my_extension* ext; trans.get_extension(ext); assert( ext ); assert( len == ext->len ); assert( bel == ext->bel ); for (unsigned int i = 0; i < bel; i++) assert( byt[i] == ext->byt[i] ); for (unsigned int i = 0; i < len; i++) assert( ptr[i] == ext->ptr[i] ); if (cmd == tlm::TLM_READ_COMMAND) { for (unsigned int i = 0; i < len; i++) { data[i] = rand() % 256; ptr[i] = data[i]; } ext->ptr = data; } trans.set_dmi_allowed( true ); 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 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; } }
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; }
///////////////////////////////////////////////////////////////////////////////////// // Interface function executed when receiving a response from VCI target[id]. // It directly routes the response to the proper VCI initiator (no time filtering). ///////////////////////////////////////////////////////////////////////////////////// tmpl(tlm::tlm_sync_enum)::nb_transport_bw( int id, tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, sc_core::sc_time &time) { // get message SRCID soclib_payload_extension *resp_extension_ptr; payload.get_extension(resp_extension_ptr); unsigned int srcid = resp_extension_ptr->get_src_id(); #ifdef SOCLIB_MODULE_DEBUG printf(" [%s] receive VCI RESPONSE from target %d for init %d / time = %d\n", name(), id, srcid, (int)time.value() ); #endif // get destination // unsigned int dest = m_rsp_routing_table[srcid]; unsigned int dest = srcid; // update the transaction time time = time + (m_latency*UNIT_TIME); #ifdef SOCLIB_MODULE_DEBUG printf(" [%s] send VCI RESPONSE on port %d / time = %d\n", name(), dest, (int)time.value() ); #endif (*p_to_initiator[dest])->nb_transport_bw( payload, phase, time); return tlm::TLM_COMPLETED; } // end nb_transport_bw
// 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 {
tlm::tlm_sync_enum send_end_req(tlm::tlm_generic_payload& trans) { tlm::tlm_sync_enum status; tlm::tlm_phase bw_phase; tlm::tlm_phase int_phase = internal_ph; sc_time delay; // Queue the acceptance and the response with the appropriate latency bw_phase = tlm::END_REQ; delay = sc_time(rand_ps(), SC_PS); // Accept delay status = socket->nb_transport_bw( trans, bw_phase, delay ); if (status == tlm::TLM_COMPLETED) { // Transaction aborted by the initiator // (TLM_UPDATED cannot occur at this point in the base protocol, so need not be checked) trans.release(); return status; } // Queue internal event to mark beginning of response delay = delay + sc_time(rand_ps(), SC_PS); // Latency m_peq.notify( trans, int_phase, delay ); n_trans++; return status; }
///////////////////////////////////////////////////////////////////////////////////// // Interface function executed when receiving a response on the VCI initiator port // If it is a VCI response, the Boolean associated to the channel is set. ///////////////////////////////////////////////////////////////////////////////////// tmpl(tlm::tlm_sync_enum)::nb_transport_bw ( tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, sc_core::sc_time &time) { // update local time and notify if( time.value() > m_pdes_local_time->get().value()) m_pdes_local_time->set(time); // test transaction type soclib_payload_extension *extension_pointer; payload.get_extension(extension_pointer); if( extension_pointer->is_read() or extension_pointer->is_write() ) { // get channel index size_t channel = extension_pointer->get_trd_id(); // set signal response received assert( ((m_state[channel] == STATE_READ_RSP) or (m_state[channel] == STATE_WRITE_RSP)) and "ERROR in VCI_MULTI_DMA : unexpected response received"); m_rsp_received[channel] = true; } return tlm::TLM_COMPLETED; }
///////////////////////////////////////////////////////////////////////////////////// // Interface function called when receiving a VCI response ///////////////////////////////////////////////////////////////////////////////////// tmpl (tlm::tlm_sync_enum)::nb_transport_bw ( tlm::tlm_generic_payload &payload, // payload tlm::tlm_phase &phase, // phase sc_core::sc_time &time) // time { #ifdef SOCLIB_MODULE_DEBUG std::cout << name() << " Receive response time = " << time.value() << std::endl; #endif //update local time if the command message is different to write soclib_payload_extension *extension_ptr; payload.get_extension(extension_ptr); if(!extension_ptr->is_null_message()){ m_rsp_time = time; if(!extension_ptr->is_write()){ update_time(time); } } m_rsp_received.notify (sc_core::SC_ZERO_TIME); return tlm::TLM_COMPLETED; }
void ram::custom_b_transport( tlm::tlm_generic_payload &payload, sc_core::sc_time &delay_time) { sc_core::sc_time mem_op_time; payload.set_dmi_allowed(m_dmi_on); m_target_memory.operation(payload, mem_op_time); return; }
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; }
// 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 ); }
// 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; }