示例#1
0
bool quad::clock(Cycle_t currentCycle) {
    SST::Event* ev = NULL;

    // Check for events from LogicLayer
    while(ev=toLogicLayer->recv()) {
        MemEvent *event  = dynamic_cast<MemEvent*>(ev);
        if (NULL == event)
            dbg.fatal(CALL_INFO, -1, "Quad%d got bad event\n", quadID);
        dbg.debug(_L5_, "Quad%d got req for %p (%" PRIu64 " %d) @%" PRIu64 "\n", quadID, (void*)event->getAddr(), event->getID().first, event->getID().second, currentCycle);
        statTotalTransactionsRecv->addData(1);

        unsigned int evQuadID = (event->getAddr() >>  quadIDAddressShift) & quadIDAddressMask;

        // if event Quad ID matches Quad ID send it
        if (evQuadID == quadID) {
            dbg.debug(_L5_, "Quad%d %p with quadID %u matches quad ID @ %" PRIu64 "\n", quadID, (void*)event->getAddr(), evQuadID, currentCycle);
            unsigned int sendID = (event->getAddr() >>  sendAddressShift) & sendAddressMask;
            outChans[sendID]->send(event);
            dbg.debug(_L5_, "Quad%d sends %p to vault%u(%u) @ %" PRIu64 "\n", quadID, (void*)event->getAddr(), sendID+(quadID*numVaultPerQuad), sendID, currentCycle);
        }

        // event Quad ID not matching Quad ID, send it to Xbar
        else {
示例#2
0
void logicLayer::init(unsigned int phase) {
    // tell the bus (or whaterver) that we are here. only the first one
    // in the chain should report, so every one sends towards the cpu,
    // but only the first one will arrive.
    if ( !phase ) {
        toCPU->sendInitData(new SST::Interfaces::StringEvent("SST::MemHierarchy::MemEvent"));
    }
    
    // rec data events from the direction of the cpu
    SST::Event *ev = NULL;
    while ( (ev = toCPU->recvInitData()) != NULL ) {
        MemEvent *me = dynamic_cast<MemEvent*>(ev);
        if ( me ) {
            /* Push data to memory */
	  if ( me->isWriteback() || me->getCmd() == GetX) {
	         //printf("Memory received Init Command: of size 0x%x at addr 0x%lx\n", me->getSize(), me->getAddr() );
                uint32_t chunkSize = (1 << VAULT_SHIFT);
                if (me->getSize() > chunkSize) {
                    // may need to break request up in to 256 byte chunks (minimal
                    // vault width)
                    int numNewEv = (me->getSize() / chunkSize) + 1;
                    uint8_t *inData = &(me->getPayload()[0]);
                    SST::MemHierarchy::Addr addr = me->getAddr();
                    for (int i = 0; i < numNewEv; ++i) {
                        // make new event
                        MemEvent *newEv = new MemEvent(this, addr, 
                                                       me->getBaseAddr(), 
                                                       me->getCmd());
                        // set size and payload
                        if (i != (numNewEv - 1)) {
                            newEv->setSize(chunkSize);
                            newEv->setPayload(chunkSize, inData);
                            inData += chunkSize;
                            addr += chunkSize;
                        } else {
                            uint32_t remain = me->getSize() - (chunkSize * (numNewEv - 1));
                            newEv->setSize(remain);
                            newEv->setPayload(remain, inData);
                        }
                        // sent to where it needs to go
                        if (isOurs(newEv->getAddr())) {
                            // send to the vault
                            unsigned int vaultID = 
                                (newEv->getAddr() >> VAULT_SHIFT) % m_memChans.size();
                            m_memChans[vaultID]->sendInitData(newEv);      
                        } else {
                            // send down the chain
                            toMem->sendInitData(newEv);
                        }
                    }
                    delete ev;
                } else {