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; } } }