Exemplo n.º 1
0
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;
}
void BridgeClassicToAMBATLM2<BUSWIDTH>::recvFunctional(PacketPtr pkt)
{
//	std::cout << "Called recvFunctional" << std::endl;
    tlm::tlm_generic_payload trans;
	if (pkt->isRead())
		trans.set_read();
	else if (pkt->isWrite())
		trans.set_write();
	trans.set_address(pkt->getAddr());
	trans.set_data_length(pkt->getSize());
//	trans.set_streaming_width(TBD);
	trans.set_data_ptr(pkt->getPtr<unsigned char>());
	debug_port->transport_dbg(static_cast<tlm::tlm_generic_payload &>(trans));

}
Tick BridgeClassicToAMBATLM2<BUSWIDTH>::recvAtomic(PacketPtr pkt)
{
    tlm::tlm_generic_payload trans;

//    std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " request from GEM5 with address=0x" << hex << pkt->getAddr() << dec << " size=" << pkt->getSize() << std::endl;
    if (pkt->memInhibitAsserted()) {
        return 0;
    }
    if (pkt->cmd == MemCmd::SwapReq)
    {
    	panic("SwapReq not supported\n");
    }
    else if (pkt->isRead())
    {
        assert(!pkt->isWrite());
        if (pkt->isLLSC()) {
            trackLoadLocked(pkt);
        }

//        if (pkt->isLLSC())
//        {
//        	panic("isLLSC not yet supported for atomic\n");
//        }
   		trans.set_read();
    	trans.set_address(pkt->getAddr());
    	trans.set_data_length(pkt->getSize());
    	trans.set_data_ptr(pkt->getPtr<unsigned char>());
    	debug_port->transport_dbg(static_cast<tlm::tlm_generic_payload &>(trans));
    	unsigned char * data = pkt->getPtr<unsigned char>();
//		std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " sending a READ response to GEM5 with address=0x" << hex << pkt->getAddr() << dec << " size=" << pkt->getSize();
//		std::cout << hex << " and data= [";
//		for(unsigned j=0;j<pkt->getSize(); j++)
//			std::cout << "0x" << uint32_t(data[j]) << ",";
//		std::cout << "]" << dec << std::endl;

    }
    else if (pkt->isWrite())
    {
//    	std::cout << "isWrite " << std::endl;
    	if (writeOK(pkt))
    	{
			trans.set_write();
			/*if (writeOK(pkt)) {
				if (pmemAddr)
					memcpy(hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize());
				assert(!pkt->req->isInstFetch());
			}*/
			trans.set_address(pkt->getAddr());
			trans.set_data_length(pkt->getSize());
			trans.set_data_ptr(pkt->getPtr<unsigned char>());
			debug_port->transport_dbg(static_cast<tlm::tlm_generic_payload &>(trans));
    	}
    	else
        	std::cout << "recvAtomic !writeOK " << hex << pkt->getAddr() << dec << std::endl;
    }
    else if (pkt->isInvalidate())
    {
        //upgrade or invalidate
        if (pkt->needsResponse())
        {
            pkt->makeAtomicResponse();
        }
    }
    else
    {
        panic("unimplemented");
    }

    if (pkt->needsResponse())
    {
        pkt->makeAtomicResponse();
    }
    return 1000;
}
	bool BridgeClassicToAMBATLM2<BUSWIDTH>::recvTimingReq(PacketPtr pkt)
	{
		amba::amba_id * m_id;
		amba::amba_burst_size * m_burst_size;
		amba::amba_exclusive * m_exclusive;
		sc_core::sc_time delay= sc_core::SC_ZERO_TIME;
		std::ostringstream msg;
		msg.str("");
		tlm::tlm_generic_payload* current_trans;
		//DPRINTF(BusBridge, "recvTiming: src %d dest %d addr 0x%x\n",pkt->getSrc(), pkt->getDest(), pkt->getAddr());	
#ifdef DEBUG
		if (_trace_transactions)
		{
			if (pkt->cmd == MemCmd::ReadReq)
				std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " received a READ request from GEM5 with address=0x" << hex << pkt->getAddr() << dec << " size=" << pkt->getSize() << std::endl;
			else if (pkt->cmd == MemCmd::ReadExReq)
				std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " received a READ EXCLUSIVE request from GEM5 with address=0x" << hex << pkt->getAddr() << dec << " size=" << pkt->getSize() << std::endl;
			else if (pkt->cmd == MemCmd::WriteReq)
			{
				std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " received a WRITE request from GEM5 with address=0x" << hex << pkt->getAddr() << dec << " size=" << pkt->getSize();
				std::cout << hex << " and data= [";
				for(unsigned j=0;j<pkt->getSize(); j++)
					std::cout << "0x" << uint32_t(pkt->getPtr<uint8_t>()[j]) << ",";
				std::cout << "]" << dec << std::endl;
			}
			else if (pkt->cmd == MemCmd::Writeback)
			{
				std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " received a WRITEBACK request from GEM5  with address=0x" << hex << pkt->getAddr() << dec << " size=" << pkt->getSize();
				std::cout << hex << " and data= [";
				for(unsigned j=0;j<pkt->getSize(); j++)
					std::cout << "0x" << uint32_t(pkt->getPtr<uint8_t>()[j]) << ",";
				std::cout << "]" << dec << std::endl;
			}
			else if ((pkt->cmd == MemCmd::UpgradeReq) || (pkt->cmd == MemCmd::SCUpgradeReq))
			{
				std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " received an UPGRADE request from GEM5  with address=0x" << hex << pkt->getAddr() << dec << " size=" << pkt->getSize() << std::endl;
			}
			else if (pkt->cmd == MemCmd::SwapReq)
			{
				std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " received a SWAP request from GEM5  with address=0x" << hex << pkt->getAddr() << dec << " size=" << pkt->getSize() << std::endl;
			}
			else if (pkt->cmd == MemCmd::LoadLockedReq)
			{
				std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " received an exclusive LOAD request from GEM5  with address=0x" << hex << pkt->getAddr() << dec << " size=" << pkt->getSize() << std::endl;
			}
			else if (pkt->cmd == MemCmd::StoreCondReq)
			{
				std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " received a STORE CONDITIONAL request from GEM5  with address=0x" << hex << pkt->getAddr() << dec << " size=" << pkt->getSize() << std::endl;
			}
			else if (pkt->cmd == MemCmd::SwapReq)
			{
				std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " received a SWAP request from GEM5  with address=0x" << hex << pkt->getAddr() << dec << " size=" << pkt->getSize() << std::endl;
			}
			else
			{
				std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " received an UNKNOWN request from GEM5  with address=0x" << hex << pkt->getAddr() << dec << " size=" << pkt->getSize() << std::endl;
			}
			if (pkt->memInhibitAsserted())
			{
				std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " request from GEM5 was inhibited" << std::endl;
			}
		}
#endif
	    if (pkt->memInhibitAsserted())
	    {
	    	return true;
	    }
		if (pkt->cmd == MemCmd::ReadReq || pkt->cmd == MemCmd::ReadExReq || pkt->cmd == MemCmd::WriteReq || pkt->cmd == MemCmd::Writeback || pkt->cmd == MemCmd::LoadLockedReq || pkt->cmd == MemCmd::StoreCondReq)
		{
			if (pkt->isWrite() && (writeDataQueue.num_free() == 0))
			{
				needWrRetry=true;
				return false;
			}
			// find a free id
			uint32_t id=10000;
			uint32_t mstid;
			if (pkt->req->hasContextId())
			{
				mstid=pkt->req->contextId();
			}
			else
			{
				mstid=0; //  Eagle L2 Buffer and ACP requests alias to CPU0 since there are only 4 mstids allocated to Eagle
			}
			if (pkt->isRead())
			{
				for (uint32_t i=(mstid*16);i<(mstid*16)+16;i++)
				{
					if (rd_packets[i] == NULL)
					{
						id=i;
						break;
					}
				}
				if (id == 10000)
				{
					needRdIdRetry=true;
					return false;
				}
			}
			else
			{
				for (uint32_t i=(mstid*16);i<(mstid*16)+16;i++)
				{
					if (wr_packets[i] == NULL)
					{
						id=i;
						break;
					}
				}
				if (id == 10000)
				{
					needWrIdRetry=true;
					return false;					
				}
			}

			current_trans =master_sock.get_transaction(); //get a memory managed transaction from the pool.
			current_trans->set_address(pkt->getAddr());
			current_trans->set_data_length(pkt->getSize());
			master_sock.reserve_data_size(*current_trans, pkt->getSize()); //reserve the requested amount of data array bytes
			current_trans->set_streaming_width(BUSWIDTH-(pkt->getAddr()%BUSWIDTH));
			current_trans->set_command(pkt->isRead()?tlm::TLM_READ_COMMAND:tlm::TLM_WRITE_COMMAND);
			if (pkt->cmd == MemCmd::LoadLockedReq || pkt->cmd == MemCmd::StoreCondReq)
			{
				master_sock.template get_extension<amba::amba_exclusive>(m_exclusive,*current_trans);
				m_exclusive->value=false;
				master_sock.template validate_extension<amba::amba_exclusive>(*current_trans);
			}
			if (pkt->req->isUncacheable())
				master_sock.template invalidate_extension<amba::amba_cacheable>(*current_trans);
			else
				master_sock.template validate_extension<amba::amba_cacheable>(*current_trans);

			if (pkt->req->isInstFetch()) master_sock.template validate_extension<amba::amba_instruction>(*current_trans);

			master_sock.template get_extension<amba::amba_burst_size>(m_burst_size,*current_trans);
			m_burst_size->value=(BUSWIDTH/8); //buswidth is in bits
			master_sock.template validate_extension<amba::amba_burst_size>(*current_trans);
			master_sock.template get_extension<amba::amba_id>(m_id,*current_trans);

			tlm::tlm_phase ph= tlm::BEGIN_REQ;
			m_id->value=id;
			master_sock.template validate_extension<amba::amba_id>(*current_trans);
			
//			if (pkt->isRead())
//				std::cout << "TLM BEHAVIOR: sending TLM_READ_COMMAND & BEGIN_REQ at time " << sc_core::sc_time_stamp() << std::endl;
//			else
//				std::cout << "TLM BEHAVIOR: sending TLM_WRITE_COMMAND & BEGIN_REQ at time " << sc_core::sc_time_stamp() << std::endl;

			tlm::tlm_sync_enum retval= master_sock->nb_transport_fw(*current_trans,ph,delay);
			if((retval==tlm::TLM_UPDATED) && (ph == tlm::END_REQ)) // request accepted by Eagle Nest
			{
//				std::cout << "TLM BEHAVIOR: received TLM_UPDATED & END_REQ at time " << sc_core::sc_time_stamp() << std::endl;
				if (pkt->isRead())
				{
					rd_packets[id]=pkt;
				}
				else
				{
					wr_packets[id]=pkt;
					writeDataQueue.write(id);
				}
				return true;
			}
			else if(retval== tlm::TLM_ACCEPTED) // request blocked till END_REQ received
			{
//				std::cout << "TLM BEHAVIOR: received TLM_ACCEPTED at time " << sc_core::sc_time_stamp() << std::endl;
				needRetry=true;
				return false;
			}
		}
		else if ((pkt->cmd == MemCmd::UpgradeReq) || (pkt->cmd == MemCmd::SCUpgradeReq))
		{
			// It's a transition from S->E.
            // The cache has a block in a shared state and requires an exclusive copy so it can write to it.
			// ignore as no L3$ so far
			dummy_pkt.push(pkt);
			send_dummy_response_event.notify(clk_period);
		}
		else if (pkt->cmd == MemCmd::SwapReq)
		{
			std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " received a SWAP request from GEM5  with address=0x" << hex << pkt->getAddr() << dec << " size=" << pkt->getSize() << "-----> what should I do boss?" << std::endl;			
		}
		else
		{
			std::cout << "ERROR: In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " received an UNKNOWN request from GEM5  with address=0x" << hex << pkt->getAddr() << dec << " size=" << pkt->getSize() << std::endl;
			if (pkt->cmd == MemCmd::InvalidCmd)
			{
				std::cout << "InvalidCmd" << std::endl;
			}
			else if (pkt->cmd == MemCmd::SoftPFReq)
			{
				std::cout << "SoftPFReq" << std::endl;
			}
			else if (pkt->cmd == MemCmd::HardPFReq)
			{
				std::cout << "HardPFReq" << std::endl;
			}
			else if (pkt->cmd == MemCmd::WriteInvalidateReq)
			{
				std::cout << "WriteInvalidateReq" << std::endl;
			}
			else if (pkt->cmd == MemCmd::SCUpgradeFailReq)
			{
				std::cout << "SCUpgradeFailReq" << std::endl;
			}
			else if (pkt->cmd == MemCmd::StoreCondFailReq)
			{
				std::cout << "StoreCondFailReq" << std::endl;
			}
			else if (pkt->cmd == MemCmd::MessageReq)
			{
				std::cout << "MessageReq" << std::endl;
			}
			else if (pkt->cmd == MemCmd::InvalidDestError)
			{
				std::cout << "InvalidDestError" << std::endl;
			}
			else if (pkt->cmd == MemCmd::BadAddressError)
			{
				std::cout << "BadAddressError" << std::endl;
			}
			else if (pkt->cmd == MemCmd::FunctionalReadError)
			{
				std::cout << "FunctionalReadError" << std::endl;
			}
			else if (pkt->cmd == MemCmd::FunctionalWriteError)
			{
				std::cout << "FunctionalWriteError" << std::endl;
			}
			else if (pkt->cmd == MemCmd::PrintReq)
			{
				std::cout << "PrintReq" << std::endl;
			}
			else if (pkt->cmd == MemCmd::FlushReq)
			{
				std::cout << "FlushReq" << std::endl;
			}
			else
			{
				std::cout << "Unkwon" << std::endl;
			}
			//sc_core::sc_stop();
		}
		return true;
	}