예제 #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;
}
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();
		}
	}
}