//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); }
//============================================================================== 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
//====================================================================== /// @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; } }
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(); 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 ); }
//============================================================================== // 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; }
//============================================================================== // 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; }
// 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); }
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; }
// 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; }
//============================================================================== /// @fn memory::get_delay // /// @brief Method to "pull" appropriate delay from the gp // /// @details /// This routine used during several at examples // //============================================================================== void memory::get_delay ( tlm::tlm_generic_payload &gp ///< TLM2 GP reference , sc_core::sc_time &delay_time ///< time to be updated ) { /// Access the required attributes from the payload tlm::tlm_command command = gp.get_command(); // memory command std::ostringstream msg; msg.str(""); switch (command) { default: { if (m_previous_warning == false) { msg << "Target: " << m_ID << " Unsupport GP command extension"; REPORT_WARNING(filename, __FUNCTION__, msg.str()); 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: { delay_time = delay_time + m_write_delay; break; } case tlm::TLM_READ_COMMAND: { delay_time = delay_time + m_read_delay; break; } } // end switch return; }
// 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(); }
// 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 ); }
//! @param payload The generic TLM payload //! @param delay How far the initiator is beyond baseline SystemC time. //! Ignored here. // ---------------------------------------------------------------------------- void LoggerSC::loggerReadWrite( tlm::tlm_generic_payload &payload, sc_core::sc_time &delay ) { // Break out the address, mask and data pointer. tlm::tlm_command comm = payload.get_command(); sc_dt::uint64 addr = payload.get_address(); unsigned char *maskPtr = payload.get_byte_enable_ptr(); unsigned char *dataPtr = payload.get_data_ptr(); // Record the payload fields (data only if it's a write) const char *commStr; switch( comm ) { case tlm::TLM_READ_COMMAND: commStr = "Read"; break; case tlm::TLM_WRITE_COMMAND: commStr = "Write"; break; case tlm::TLM_IGNORE_COMMAND: commStr = "Ignore"; break; default: commStr = "Unknown command"; break; } std::cout << "Logging" << std::endl; std::cout << " Command: " << commStr << std::endl; std::cout << " Address: 0x" << std::setw( 8 ) << std::setfill( '0' ) <<std::hex << (uint64_t)addr << std::endl; std::cout << " Byte enables: 0x" << std::setw( 8 ) << std::setfill( '0' ) <<std::hex << *((uint32_t *)maskPtr) << std::endl; if( tlm::TLM_WRITE_COMMAND == comm ) { std::cout << " Data: 0x" << std::setw( 8 ) << std::setfill( '0' ) <<std::hex << *((uint32_t *)dataPtr) << std::endl; } std::cout << std::endl; payload.set_response_status( tlm::TLM_OK_RESPONSE ); // Always OK } // loggerReadWrite()
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; }
//===================================================================== /// @fn dmi_memory::operation // /// @brief DMI read and write processing // /// @details /// This routine implements dmi based read and write operations // //===================================================================== void dmi_memory::operation ( tlm::tlm_generic_payload &gp , sc_core::sc_time &delay ///< transaction delay ) { std::ostringstream msg; msg.str(""); m_address = gp.get_address(); m_data = gp.get_data_ptr(); ///< data pointer m_length = gp.get_data_length(); ///< data length m_command = gp.get_command(); m_is_dmi_flag = false; gp.set_response_status(tlm::TLM_GENERIC_ERROR_RESPONSE); if (is_address_dmi(gp) == false ) { msg << "Iniiator:" << m_ID << "A GP with an address not in the allowed DMI ranges has been received" << endl << " " << "Use check_status before passing a gp to operation"; REPORT_INFO(filename, __FUNCTION__, msg.str()); gp.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE); // Need a different error } else { m_offset = m_address - m_dmi_base_address; switch (m_command) { case tlm::TLM_WRITE_COMMAND: { for (unsigned int i = 0; i < m_length; i++) { m_dmi_ptr[m_offset + i] = m_data[i]; } gp.set_response_status(tlm::TLM_OK_RESPONSE); delay = delay + m_dmi_write_latency; // update time report::print(m_ID, gp, filename); break; } case tlm::TLM_READ_COMMAND: { // clear read buffer for (unsigned int i = 0; i < m_length; i++) { m_data[i] = m_dmi_ptr [m_offset + i]; } gp.set_response_status(tlm::TLM_OK_RESPONSE); delay = delay + m_dmi_read_latency; // update time report::print(m_ID, gp, filename); break; } default: { msg << "Target: " << m_ID << " Unknown GP command that could be ignorable"; REPORT_WARNING(filename, __FUNCTION__, msg.str()); gp.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE); break; } }//end switch } return; //============================================================================== } // end memory_operation
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: #ifdef DEBUG fout << hex << trans.get_address() << " " << name() << " BEGIN_REQ at " << sc_time_stamp() << endl; #endif // Increment the transaction reference count trans.acquire(); // Put back-pressure on initiator by deferring END_REQ until pipeline is clear if (n_trans == 2) end_req_pending = &trans; else { status = send_end_req(trans); if (status == tlm::TLM_COMPLETED) // It is questionable whether this is valid break; } break; case tlm::END_RESP: // On receiving END_RESP, the target can release the transaction // and allow other pending transactions to proceed #ifdef DEBUG fout << hex << trans.get_address() << " " << name() << " END_RESP at " << sc_time_stamp() << endl; #endif if (!response_in_progress) SC_REPORT_FATAL("TLM-2", "Illegal transaction phase END_RESP received by target"); trans.release(); n_trans--; // Target itself is now clear to issue the next BEGIN_RESP response_in_progress = false; if (next_response_pending) { send_response( *next_response_pending ); next_response_pending = 0; } // ... and to unblock the initiator by issuing END_REQ if (end_req_pending) { status = send_end_req( *end_req_pending ); end_req_pending = 0; } 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 ) { *reinterpret_cast<int*>(ptr) = rand(); fout << hex << adr << " " << name() << " Execute READ, target = " << name() << " data = " << *reinterpret_cast<int*>(ptr) << endl; } else if ( cmd == tlm::TLM_WRITE_COMMAND ) fout << hex << adr << " " << name() << " Execute WRITE, target = " << name() << " data = " << *reinterpret_cast<int*>(ptr) << endl; 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 if (response_in_progress) { // Target allows only two transactions in-flight if (next_response_pending) SC_REPORT_FATAL("TLM-2", "Attempt to have two pending responses in target"); next_response_pending = &trans; } else send_response(trans); break; } } }
virtual void b_transport( int id, tlm::tlm_generic_payload& trans, sc_time& delay ) { int target_nr = 0; sc_dt::uint64 address = trans.get_address(); sc_dt::uint64 read_address = 0; sc_dt::uint64 write_address = 0 ; decode_address( address, read_address, write_address, id, startAdr[id]); if(id == 0){//Writer writeAllowed = true; trans.set_address(write_address); (*init_socket[target_nr])->b_transport(trans, delay); cout << "\tID is: " << id << " - After calling b_transport in Switch: " << endl; if(trans.is_response_ok() && writerCounter < startAdr[id + 1]) writerCounter = writerCounter + 8; // Change since now 8-bit words. if(trans.is_response_ok() && writerCounter >= startAdr[id + 1]){ writeAllowed = false; mtfAllowed = true; } } else if(id == 1){//mtf if(mtfAllowed == true){ if(trans.get_command() == tlm::TLM_WRITE_COMMAND) trans.set_address( write_address ); if(trans.get_command() == tlm::TLM_READ_COMMAND) trans.set_address(read_address); (*init_socket[target_nr])->b_transport(trans, delay); cout << "\tID is: " << id << " - After calling b_transport in Switch: " << endl; if(trans.is_response_ok() && MTFCounter < startAdr[id + 1]) MTFCounter = MTFCounter + 8; // Change since now 8-bit words. if(trans.is_response_ok() && MTFCounter >= startAdr[id + 1]){ runAllowed.write(true); } } } else if(id == 2){//runL if(runAllowed == true){ if(trans.get_command() == tlm::TLM_WRITE_COMMAND) trans.set_address( write_address ); if(trans.get_command() == tlm::TLM_READ_COMMAND) trans.set_address(read_address); (*init_socket[target_nr])->b_transport(trans, delay); //cout << "\tID is: " << id << " - After calling b_transport in Switch: " << endl; if(trans.is_response_ok() && runCounter < startAdr[id + 1]) runCounter = runCounter + 8; // Change since now 8-bit words. if(trans.is_response_ok() && runCounter >= startAdr[id + 1]- startAdr[id]){ readAllowed.write(true); } } } else if(id == 3){//Reader if(readAllowed == true){ if(trans.get_command() == tlm::TLM_READ_COMMAND) trans.set_address(read_address ); (*init_socket[target_nr])->b_transport(trans, delay); //cout << "\tID is: " << id << " - After calling b_transport in Switch: " << endl; if(readCounter <= startAdr[id]- startAdr[id - 1]){ readCounter = readCounter + 8; // Change since now 8-bit words. trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); } else if(readCounter > startAdr[id]- startAdr[id - 1]){ trans.set_response_status(tlm::TLM_OK_RESPONSE); } } else trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); } }
//============================================================================== /// @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
// Instruction interface to functional part of the model void mmu_cache::exec_instr(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(); // Log instruction reads for power monitoring if (m_pow_mon) { dyn_reads += (trans.get_data_length() >> 2) + 1; } // Extract extension icio_payload_extension * iext; trans.get_extension(iext); unsigned int *debug; unsigned int flush; // Check/extract instruction payload extension if (iext!=NULL) { debug = iext->debug; flush = iext->flush; } else { // No iext debug = NULL; flush = 0; v::error << name() << "IEXT Payload extension missing" << v::endl; } // Flush instruction if (flush) { v::debug << name() << "Received flush instruction - flushing both caches" << v::endl; // Simultaneous flush of both caches icache->flush(&delay, debug, is_dbg); dcache->flush(&delay, debug, is_dbg); trans.set_response_status(tlm::TLM_OK_RESPONSE); return; } if (cmd == tlm::TLM_READ_COMMAND) { assert( 1 ); // fix asi -> priv / unpriv mmu_cache_base::exec_instr(addr, ptr, 0x8, debug, flush, delay, is_dbg); // ToDo: fix ASI! 0x8 -> unprivileged instruction // Set response status trans.set_response_status(tlm::TLM_OK_RESPONSE); } else { v::error << name() << " Command not valid for instruction cache (tlm_write)" << v::endl; // Set response status trans.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE); } }