LAB/GEM5

GEM5, NVMain V.20.0.3에 맞게 수정

RyoTTa 2021. 8. 27. 12:07
반응형

NVMain은 GEM5의 오래된 버전에 맞게 정의되어있다. 이를 그나마 최신버전 GEM5에 맞도록 수정한다.

 

NVmain/Simulators/gem5/nvmain_mem.cc

void
NVMainMemory::SetRequestData(NVMainRequest *request, PacketPtr pkt)
{
    uint8_t *hostAddr;

    request->data.SetSize( pkt->getSize() );
    request->oldData.SetSize( pkt->getSize() );

    if (pkt->isRead())
    {
        Request *dataReq = new Request(pkt->getAddr(), pkt->getSize(), 0, Request::funcMasterId);
        Packet *dataPkt = new Packet(dataReq, MemCmd::ReadReq);
        dataPkt->allocate();
        doFunctionalAccess(dataPkt);

        hostAddr = new uint8_t[ pkt->getSize() ];
        memcpy( hostAddr, dataPkt->getPtr<uint8_t>(), pkt->getSize() );

        for(int i = 0; i < pkt->getSize(); i++ )
        {
            request->oldData.SetByte(i, *(hostAddr + i));
            request->data.SetByte(i, *(hostAddr + i));
        }

        delete dataPkt;
        delete dataReq;
        delete [] hostAddr;
    }
    else
    {
        Request *dataReq = new Request(pkt->getAddr(), pkt->getSize(), 0, Request::funcMasterId);
        Packet *dataPkt = new Packet(dataReq, MemCmd::ReadReq);
        dataPkt->allocate();
        doFunctionalAccess(dataPkt);

        uint8_t *hostAddrT = new uint8_t[ pkt->getSize() ];
        memcpy( hostAddrT, dataPkt->getPtr<uint8_t>(), pkt->getSize() );

        hostAddr = new uint8_t[ pkt->getSize() ];
        memcpy( hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize() );

        for(int i = 0; i < pkt->getSize(); i++ )
        {
            request->oldData.SetByte(i, *(hostAddrT + i));
            request->data.SetByte(i, *(hostAddr + i));
        }

        delete dataPkt;
        delete dataReq;
        delete [] hostAddrT;
        delete [] hostAddr;
    }
}

위의 코드를 아래와 같이 수정한다.

void
NVMainMemory::SetRequestData(NVMainRequest *request, PacketPtr pkt)
{
    uint8_t *hostAddr;

    request->data.SetSize( pkt->getSize() );
    request->oldData.SetSize( pkt->getSize() );

    if (pkt->isRead())
    {
        RequestPtr dataReq = std::make_shared<Request>(pkt->getAddr(), pkt->getSize(), 0, Request::funcMasterId);
        Packet *dataPkt = new Packet(dataReq, MemCmd::ReadReq);
        dataPkt->allocate();
        doFunctionalAccess(dataPkt);

        hostAddr = new uint8_t[ pkt->getSize() ];
        memcpy( hostAddr, dataPkt->getPtr<uint8_t>(), pkt->getSize() );

        for(int i = 0; i < pkt->getSize(); i++ )
        {
            request->oldData.SetByte(i, *(hostAddr + i));
            request->data.SetByte(i, *(hostAddr + i));
        }

        delete dataPkt;
        //delete dataReq;
        delete [] hostAddr;
    }
    else
    {
        RequestPtr dataReq = std::make_shared<Request>(pkt->getAddr(), pkt->getSize(), 0, Request::funcMasterId);
        Packet *dataPkt = new Packet(dataReq, MemCmd::ReadReq);
        dataPkt->allocate();
        doFunctionalAccess(dataPkt);

        uint8_t *hostAddrT = new uint8_t[ pkt->getSize() ];
        memcpy( hostAddrT, dataPkt->getPtr<uint8_t>(), pkt->getSize() );

        hostAddr = new uint8_t[ pkt->getSize() ];
        memcpy( hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize() );

        for(int i = 0; i < pkt->getSize(); i++ )
        {
            request->oldData.SetByte(i, *(hostAddrT + i));
            request->data.SetByte(i, *(hostAddr + i));
        }

        delete dataPkt;
        //delete dataReq;
        delete [] hostAddrT;
        delete [] hostAddr;
    }
}

BaseSlavePort &
NVMainMemory::getSlavePort(const std::string& if_name, PortID idx)
{
    if (if_name != "port") {
        return MemObject::getSlavePort(if_name, idx);
    } else {
        return port;
    }
}

위의 코드를 아래와 같이 수정한다.

Port &
NVMainMemory::getPort(const std::string& if_name, PortID idx)
{
    if (if_name != "port") {
        return ClockedObject::getPort(if_name, idx);
    } else {
        return port;
    }
}

헤더 파일도 이와같이 수정한다.


void
NVMainMemory::MemoryPort::recvFunctional(PacketPtr pkt)
{
    pkt->pushLabel(memory.name());

    memory.doFunctionalAccess(pkt);

    for( std::deque<PacketPtr>::iterator i = memory.responseQueue.begin();
         i != memory.responseQueue.end(); ++i )
        pkt->checkFunctional(*i);

    pkt->popLabel();
}

위의 코드를 아래와 같이 수정한다.

void
NVMainMemory::MemoryPort::recvFunctional(PacketPtr pkt)
{
    pkt->pushLabel(memory.name());

    memory.doFunctionalAccess(pkt);

    for( std::deque<PacketPtr>::iterator i = memory.responseQueue.begin();
         i != memory.responseQueue.end(); ++i )
        pkt->trySatisfyFunctional(*i);

    pkt->popLabel();
}

 

 

위와 같은 방법으로 GEM5 V.20.0.3 까지 연동 가능하다.

반응형