#include "mem/hmc_controller.hh"

#include "base/random.hh"
#include "base/trace.hh"
#include "debug/HMCController.hh"

namespace gem5
{

HMCController::HMCController(const HMCControllerParams &p) :
    NoncoherentXBar(p),
    numMemSidePorts(p.port_mem_side_ports_connection_count),
    rr_counter(0)
{
    assert(p.port_cpu_side_ports_connection_count == 1);
}

// Since this module is a load distributor, all its request ports have the same
//  range so we should keep only one of the ranges and ignore the others
void HMCController::recvRangeChange(PortID mem_side_port_id)
{
    if (mem_side_port_id == 0)
    {
       gotAllAddrRanges = true;
       BaseXBar::recvRangeChange(mem_side_port_id);
    }
    else
        gotAddrRanges[mem_side_port_id] = true;
}

int HMCController::rotate_counter()
{
    int current_value = rr_counter;
    rr_counter++;
    if (rr_counter == numMemSidePorts)
        rr_counter = 0;
    return current_value;
}

bool HMCController::recvTimingReq(PacketPtr pkt, PortID cpu_side_port_id)
{
    // determine the source port based on the id
    ResponsePort *src_port = cpuSidePorts[cpu_side_port_id];

    // we should never see express snoops on a non-coherent component
    assert(!pkt->isExpressSnoop());

    // For now, this is a simple round robin counter, for distribution the
    //  load among the serial links
    PortID mem_side_port_id = rotate_counter();

    // test if the layer should be considered occupied for the current
    // port
    if (!reqLayers[mem_side_port_id]->tryTiming(src_port)) {
        DPRINTF(HMCController, "recvTimingReq: src %s %s 0x%x BUSY\n",
                src_port->name(), pkt->cmdString(), pkt->getAddr());
        return false;
    }

    DPRINTF(HMCController, "recvTimingReq: src %s %s 0x%x\n",
            src_port->name(), pkt->cmdString(), pkt->getAddr());

    // store size and command as they might be modified when
    // forwarding the packet
    unsigned int pkt_size = pkt->hasData() ? pkt->getSize() : 0;
    unsigned int pkt_cmd = pkt->cmdToIndex();

    // store the old header delay so we can restore it if needed
    Tick old_header_delay = pkt->headerDelay;

    // a request sees the frontend and forward latency
    Tick xbar_delay = (frontendLatency + forwardLatency) * clockPeriod();

    // set the packet header and payload delay
    calcPacketTiming(pkt, xbar_delay);

    // determine how long to be layer is busy
    Tick packetFinishTime = clockEdge(Cycles(1)) + pkt->payloadDelay;

    // before forwarding the packet (and possibly altering it),
    // remember if we are expecting a response
    const bool expect_response = pkt->needsResponse() &&
        !pkt->cacheResponding();

    // since it is a normal request, attempt to send the packet
    bool success = memSidePorts[mem_side_port_id]->sendTimingReq(pkt);

    if (!success)  {
        DPRINTF(HMCController, "recvTimingReq: src %s %s 0x%x RETRY\n",
                src_port->name(), pkt->cmdString(), pkt->getAddr());

        // restore the header delay as it is additive
        pkt->headerDelay = old_header_delay;

        // occupy until the header is sent
        reqLayers[mem_side_port_id]->failedTiming(src_port,
                                                clockEdge(Cycles(1)));

        return false;
    }

    // remember where to route the response to
    if (expect_response) {
        assert(routeTo.find(pkt->req) == routeTo.end());
        routeTo[pkt->req] = cpu_side_port_id;
    }

    reqLayers[mem_side_port_id]->succeededTiming(packetFinishTime);

    // stats updates
    pktCount[cpu_side_port_id][mem_side_port_id]++;
    pktSize[cpu_side_port_id][mem_side_port_id] += pkt_size;
    transDist[pkt_cmd]++;

    return true;
}

} // namespace gem5
