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; }
//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); }
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 ); }
// 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 ); }
//============================================================================== // b_transport implementation calls from initiators // //============================================================================= void lt_dmi_target::custom_b_transport ( tlm::tlm_generic_payload &payload // ref to Generic Payload , sc_core::sc_time &delay_time // delay time ) { sc_core::sc_time mem_op_time; std::ostringstream msg; msg.str(""); m_target_memory.operation(payload, mem_op_time); if(m_dmi_enabled) { payload.set_dmi_allowed(true); msg << "Target: " << m_ID << " has set dmi_allowed " << endl << " "; } else { payload.set_dmi_allowed(false); } msg << "Target: " << m_ID << " returned delay of " << delay_time << " + " << m_accept_delay << " + " << mem_op_time; delay_time = delay_time + m_accept_delay + mem_op_time; msg << " = " << delay_time; REPORT_INFO(filename, __FUNCTION__, msg.str()); return; }
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; }
unsigned int ram::debug_transport (tlm::tlm_generic_payload &payload) { sc_core::sc_time mem_op_time; payload.set_dmi_allowed(m_dmi_on); return m_target_memory.debug(payload, mem_op_time); }