bool PHXSimWrap::recvTiming(PacketPtr pkt) { uint64_t addr = pkt->getAddr(); PRINTFN("%s: %s %#lx\n", __func__, pkt->cmdString().c_str(), (long)addr); pkt->dram_enter_time = curTick(); if ( pkt->isRead() ) { bool ret = m_memorySystem->AddTransaction( false, addr, 0 ); if ( ! ret ) return false; assert(m_rd_pktMap.find( addr ) == m_rd_pktMap.end()); m_rd_pktMap[ addr ] = pkt; } else if ( pkt->isWrite() ) { bool ret = m_memorySystem->AddTransaction( true, addr, 0 ); if ( ! ret ) return false; std::multimap< uint64_t, PacketPtr >::iterator it; it = m_wr_pktMap.find( addr ); assert( it == m_wr_pktMap.end()); m_wr_pktMap.insert( pair<uint64_t, PacketPtr>(addr, pkt) ); } else { if ( pkt->needsResponse() ) { pkt->makeTimingResponse(); m_readyQ.push_back( pkt ); } else { delete pkt; } } return true; }
tlm::tlm_sync_enum BridgeClassicToAMBATLM2<BUSWIDTH>::nb_bw_transport(tlm::tlm_generic_payload & trans, tlm::tlm_phase & ph, sc_core::sc_time &delay) { // std::cout << sc_core::sc_object::name()<< ph << std::endl; amba::amba_id * m_id; amba::amba_exclusive * m_exclusive; tlm::tlm_sync_enum returnVal=tlm::TLM_ACCEPTED; std::ostringstream msg; msg.str(""); if(ph == amba::BEGIN_LAST_RESP || ph == tlm::BEGIN_RESP) { //assert(trans.get_command()==tlm::TLM_READ_COMMAND && "Write Command doesn't support the response."); master_sock.template get_extension<amba::amba_id>(m_id,trans); if (trans.is_write()) { // std::cout << "TLM BEHAVIOR: received BEGIN_RESP at time " << sc_core::sc_time_stamp() << std::endl; assert(ph == tlm::BEGIN_RESP); assert(wr_packets[m_id->value] != NULL); //as per packet.cc:74 writeback never needs a response if (wr_packets[m_id->value]->cmd != MemCmd::Writeback) { if (master_sock.template get_extension<amba::amba_exclusive>(m_exclusive,trans)) { if (m_exclusive->value) { wr_packets[m_id->value]->req->setExtraData(0); } else { wr_packets[m_id->value]->req->setExtraData(1); } } setCurTick(sc_core::sc_time_stamp().value()); wr_packets[m_id->value]->busFirstWordDelay = wr_packets[m_id->value]->busLastWordDelay = 0; if (bus_stalling) retryQueue.push(wr_packets[m_id->value]); else if (!slavePort->sendTimingResp(wr_packets[m_id->value])) { bus_stalling=true; retryQueue.push(wr_packets[m_id->value]); } #ifdef DEBUG else if (_trace_transactions) std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " sending a WS response to GEM5 with address=0x" << hex << trans.get_address() << dec << " size=" << trans.get_data_length() << std::endl; #endif } master_sock.release_transaction(&trans); //now we release wr_packets[m_id->value] = NULL; if (needWrIdRetry) { setCurTick(sc_core::sc_time_stamp().value()); needWrIdRetry=false; slavePort->sendRetry(); } } else if (ph == amba::BEGIN_LAST_RESP) { // std::cout << "TLM BEHAVIOR: received BEGIN_LAST_RESP at time " << sc_core::sc_time_stamp() << std::endl; assert(rd_packets[m_id->value] != NULL); uint8_t * data=trans.get_data_ptr(); PacketPtr pkt = rd_packets[m_id->value]; pkt->makeTimingResponse(); uint32_t shadow_size=pkt->getSize(); uint64_t shadow_addr=pkt->getAddr(); // std::cout << sc_core::sc_object::name() << " bridge received read data for address = " << trans.get_address()-pkt->getAddr() << " at time " << sc_time_stamp() << std::endl; memcpy(pkt->getPtr<uint8_t>(),data,pkt->getSize()); // if (master_sock.template get_extension<amba::amba_exclusive>(m_exclusive,trans)) // { // if (m_exclusive->value) // pkt->req->setExtraData(0); // else // pkt->req->setExtraData(1); // } setCurTick(sc_core::sc_time_stamp().value()); pkt->busFirstWordDelay = pkt->busLastWordDelay = 0; if (bus_stalling) retryQueue.push(pkt); else if (!slavePort->sendTimingResp(pkt)) { bus_stalling=true; retryQueue.push(pkt); } #ifdef DEBUG else if (_trace_transactions) { std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " sending a READ response to GEM5 with address=0x" << hex << shadow_addr << dec << " size=" << shadow_size; std::cout << hex << " and data= ["; for(unsigned j=0;j<shadow_size; j++) std::cout << "0x" << uint32_t(data[j]) << ","; std::cout << "]" << dec << std::endl; } #endif rd_packets[m_id->value]=NULL; master_sock.release_transaction(&trans); if (needRdIdRetry) { setCurTick(sc_core::sc_time_stamp().value()); needRdIdRetry=false; slavePort->sendRetry(); } } else { //received a read data phase } //always accept directly (cf EagleNest spec) // std::cout << "TLM BEHAVIOR: sending TLM_UPDATED & END_RESP at time " << sc_core::sc_time_stamp() << std::endl; ph=tlm::END_RESP; return tlm::TLM_UPDATED; } else if(ph ==tlm::END_REQ) { // std::cout << "TLM BEHAVIOR: received END_REQ and returning TLM_ACCEPTED at time " << sc_core::sc_time_stamp() << std::endl; if (needRetry) { setCurTick(sc_core::sc_time_stamp().value()); trans.release(); needRetry=false; slavePort->sendRetry(); } } else if(ph== amba::END_DATA ) { // std::cout << "TLM BEHAVIOR: received END_DATA and returning TLM_ACCEPTED at time " << sc_core::sc_time_stamp() << std::endl; if (need_wenable_event) { need_wenable_event=false; wenable_event.notify(); } return tlm::TLM_ACCEPTED; } else assert("Unexpected phase returned from AXI slave."); return returnVal; }
void BridgeClassicToAMBATLM2<BUSWIDTH>::sendWriteData() { PacketPtr pkt; sc_core::sc_time delay= sc_core::SC_ZERO_TIME; uint32_t width=(BUSWIDTH/8); uint32_t burstLen=0; uint32_t count=0; uint32_t id = 0; uint32_t dp_size = 0; uint64_t address; tlm::tlm_generic_payload* _trans; tlm::tlm_phase ph; amba::amba_id * m_id; bool last=false; while(true) { id = writeDataQueue.read(); pkt=wr_packets[id]; _trans=master_sock.get_transaction(); master_sock.reserve_data_size(*_trans, pkt->getSize()); //reserve the requested amount of data array bytes _trans->set_command(tlm::TLM_WRITE_COMMAND); address=pkt->getAddr(); burstLen = uint32_t(ceil(double_t(pkt->getSize()+address%width)/double_t(width))); master_sock.template get_extension<amba::amba_id>(m_id,*_trans); m_id->value=id; master_sock.template validate_extension<amba::amba_id>(*_trans); count=0; memcpy(_trans->get_data_ptr(),pkt->getPtr<uint8_t>(),pkt->getSize()); dp_size=std::min(width-uint32_t(address%width),pkt->getSize()); uint32_t bytes_left=pkt->getSize(); // hanle the case where first dataphase is not aligned if((address%width) != 0) { _trans->set_address(address); _trans->set_data_length(dp_size); if (burstLen == 1) { // std::cout << "TLM BEHAVIOR: TLM_WRITE_COMMAND & BEGIN_LAST_DATA 1 at time " << sc_core::sc_time_stamp() << "count= " << count << " burstLen=" << burstLen << std::endl; ph= amba::BEGIN_LAST_DATA; last=true; } else { // std::cout << "TLM BEHAVIOR: TLM_WRITE_COMMAND & BEGIN_DATA 1 at time " << sc_core::sc_time_stamp() << std::endl; ph = amba::BEGIN_DATA; last=false; } switch(master_sock->nb_transport_fw(*_trans,ph,delay)) { case tlm::TLM_ACCEPTED: // std::cout << "TLM BEHAVIOR: response=TLM_ACCEPTED at time " << sc_core::sc_time_stamp() << std::endl; need_wenable_event=true; wait(wenable_event); break; case tlm::TLM_UPDATED: // std::cout << "TLM BEHAVIOR: response=TLM_UPDATED & END_DATA at time " << sc_core::sc_time_stamp() << std::endl; assert(ph == amba::END_DATA); break; case tlm::TLM_COMPLETED: // std::cout << "TLM BEHAVIOR: response=TLM_COMPLETED at time " << sc_core::sc_time_stamp() << std::endl; abort(); break; default: abort(); break; } bytes_left -= dp_size; count++; address += dp_size; //as per packet.cc:74 writeback never needs a response if (last && (pkt->cmd != MemCmd::Writeback)) pkt->makeTimingResponse(); } while(count<burstLen) { _trans->set_address(address); if(count+1 >= burstLen) { // std::cout << "TLM BEHAVIOR: TLM_WRITE_COMMAND & BEGIN_LAST_DATA 2 at time " << sc_core::sc_time_stamp() << "count= " << count << " burstLen=" << burstLen << std::endl; _trans->set_data_length(bytes_left); ph= amba::BEGIN_LAST_DATA; last=true; } else { // std::cout << "TLM BEHAVIOR: TLM_WRITE_COMMAND & BEGIN_DATA 2 at time " << sc_core::sc_time_stamp() << std::endl; _trans->set_data_length(width); last=false; ph =amba::BEGIN_DATA; } // std::cout << sc_core::sc_object::name() <<" Sending the write transaction data, at time " << sc_core::sc_time_stamp() <<" BURST-COUNT="<< (count+1)<<std::endl; switch(master_sock->nb_transport_fw(*_trans,ph,delay)) { case tlm::TLM_ACCEPTED: // std::cout << "TLM BEHAVIOR: received TLM_ACCEPTED at time " << sc_core::sc_time_stamp() << std::endl; need_wenable_event=true; wait(wenable_event); /*count++; address += width; if (!last) bytes_left -= width; //as per packet.cc:74 writeback never needs a response if (last && (pkt->cmd != MemCmd::Writeback)) pkt->makeTimingResponse();*/ break; case tlm::TLM_UPDATED: // std::cout << "TLM BEHAVIOR: received TLM_UPDATED & END_DATA at time " << sc_core::sc_time_stamp() << std::endl; assert(ph == amba::END_DATA); count++; address += width; if (!last) bytes_left -= width; //as per packet.cc:74 writeback never needs a response if (last && (pkt->cmd != MemCmd::Writeback)) pkt->makeTimingResponse(); break; case tlm::TLM_COMPLETED: // std::cout << "TLM BEHAVIOR: received TLM_COMPLETED at time " << sc_core::sc_time_stamp() << std::endl; abort(); } wait(clk_period); } if (needWrRetry) { setCurTick(sc_core::sc_time_stamp().value()); needWrRetry=false; slavePort->sendRetry(); } } }