void b_transport(tlm_generic_payload& trans, sc_time& delay){ tlm_command cmd = trans.get_command(); sc_dt::uint64 adr = trans.get_address(); unsigned char* ptr = trans.get_data_ptr(); unsigned int len = trans.get_data_length(); unsigned char* byt = trans.get_byte_enable_ptr(); unsigned int wid = trans.get_streaming_width(); #ifdef DEBUGMODE cerr << sc_time_stamp() << ": " << name() << " - Transaction " << trans.is_write() << " for Address " << adr << " with "; cerr << "data length " << len << " and streaming width " << wid << endl; // ofstream outFile("cache.txt", ios::app); // outFile << sc_time_stamp() << " " << trans.get_address() << " " << trans.get_data_length() << " " << trans.is_write() << endl; #endif unsigned int words = len / sizeof(BUSWIDTH); if (len%sizeof(BUSWIDTH) != 0) words++; if(this->scratchpadEn && adr >= this->scratchStart && adr + len <= (this->scratchStart + this->scratchSize)) { //Using local scratchpad if(this->scratchMemory == NULL){ THROW_EXCEPTION(__PRETTY_FUNCTION__ << ": Trying to access a NULL scratchpad"); } if(cmd == TLM_READ_COMMAND) memcpy(ptr, &scratchMemory[adr - this->scratchStart], len); else if(cmd == TLM_WRITE_COMMAND) memcpy(&scratchMemory[adr - this->scratchStart], ptr, len); else THROW_EXCEPTION(__PRETTY_FUNCTION__ << ": Undefined TLM command"); this->numScratchAcc++; wait(words*this->scratchLatency); trans.set_response_status(TLM_OK_RESPONSE); return; } else if (adr > cacheLimit){ this->initSocket->b_transport(trans,delay); } else { if (cmd == TLM_READ_COMMAND) { this->readFromCache(adr, ptr, len); trans.set_response_status(TLM_OK_RESPONSE); } else if (cmd == TLM_WRITE_COMMAND) { this->writeToCache(adr, ptr, len); if (writePolicy == THROUGH || writePolicy == THROUGH_ALL) { this->initSocket->b_transport(trans,delay); } else trans.set_response_status(TLM_OK_RESPONSE); } else THROW_EXCEPTION(__PRETTY_FUNCTION__ << ": Undefined TLM command"); this->numAccesses++; } #ifdef DEBUGMODE cerr << sc_time_stamp() << ": " << name() << " - Transaction " << trans.is_write() << " for Address " << adr << " completed with data "; if (trans.get_data_length() == 4) cerr << (unsigned int) (*trans.get_data_ptr()) << endl; else cerr << "ND" << endl; #endif trans.set_dmi_allowed(false); // Disables DMI in order to insert the cache latency for each transaction }
tlm_sync_enum port_pcie::nb_transport_fw_switch(tlm_generic_payload& payload, tlm_phase& phase, sc_time& delay_time){ if(phase != BEGIN_REQ){ cout << sc_time_stamp()<<" ERROR: nb_transport_fw call with phase!=BEGIN_REQ" << endl; exit(1); } // npu_header* header; // header = (npu_header*) payload.get_data_ptr(); // cout<<endl<<"port"<<this->port_index<<": got command from switch"<<endl; if(payload.get_command()==TLM_READ_COMMAND){ // to_switch_fifo.nb_read(*header); cout<<endl<<"port"<<this->port_index<<": got read command from switch"<<endl; switch_read_peq.notify(payload, sc_time(10, SC_NS)); payload.set_response_status(TLM_OK_RESPONSE); } else if(payload.get_command()==TLM_WRITE_COMMAND){ // from_switch_fifo.nb_write(*header); cout<<endl<<"port"<<this->port_index<<": got write command from switch"<<endl; switch_write_peq.notify(payload, sc_time(10, SC_NS)); payload.set_response_status(TLM_OK_RESPONSE); } phase = END_REQ; return TLM_UPDATED; }
void b_transport(tlm_generic_payload& trans, sc_time& delay){ tlm_command cmd = trans.get_command(); sc_dt::uint64 adr = trans.get_address(); unsigned char* ptr = trans.get_data_ptr(); unsigned int len = trans.get_data_length(); unsigned char* byt = trans.get_byte_enable_ptr(); unsigned int wid = trans.get_streaming_width(); if(cmd == TLM_WRITE_COMMAND){ status++; std::cout << name() << " status: " << status << "/" << numOfMessages << std::endl; if(status>=numOfMessages) sc_stop(); } else { THROW_EXCEPTION("unknown command"); } //wait(this->latency); trans.set_response_status(TLM_OK_RESPONSE); }
void ahb_slave_if::b_transport(tlm_generic_payload& payload, sc_time& delay) { tlm_command cmd = payload.get_command(); uint32_t addr = (uint32_t)payload.get_address(); uint32_t* data_ptr = (uint32_t*)payload.get_data_ptr(); unsigned int length = payload.get_data_length(); int burst_length = payload.get_streaming_width(); /* if(addr & get_address_mask() >= 0) { payload.set_response_status(TLM_ADDRESS_ERROR_RESPONSE); } else*/ if(length > 4) { std::cout << "length error" << endl; payload.set_response_status(TLM_BURST_ERROR_RESPONSE); } else { bool success; uint32_t data; if(cmd == TLM_READ_COMMAND) { success = local_access(false, addr, data, length, burst_length); printf("read from 0x%X: 0x%X\n", addr, data); if(success) { *data_ptr = data; payload.set_response_status(TLM_OK_RESPONSE); } else { std::cout << "read error" << endl; payload.set_response_status(TLM_GENERIC_ERROR_RESPONSE); } //memcpy(ptr, &mem[adr], len); } else if(cmd == TLM_WRITE_COMMAND) { data = *data_ptr; success = local_access(true, addr, data, length, burst_length); printf("write to 0x%X: 0x%X\n", addr, data); if(success) { payload.set_response_status(TLM_OK_RESPONSE); } else { std::cout << "write error" << endl; payload.set_response_status(TLM_GENERIC_ERROR_RESPONSE); } //memcpy(&mem[adr], ptr, len); } else { std::cout << "no such command" << endl; payload.set_response_status(TLM_COMMAND_ERROR_RESPONSE); } } }
// TLM-2 debug transaction method // It is unuseful to work with caches for DBG methods, since there is no time concept // This method simply forwards the request to the memory unsigned int transport_dbg(tlm_generic_payload& trans){ tlm_command cmd = trans.get_command(); sc_dt::uint64 adr = trans.get_address(); unsigned char* ptr = trans.get_data_ptr(); unsigned int len = trans.get_data_length(); #ifdef DEBUGMODE cerr << sc_time_stamp() << ": " << name() << " - DBG Transaction " << trans.is_write() << " for Address " << adr << " with "; cerr << "data length " << len << endl; #endif // Declaring some support variables... sc_dt::uint64 tag; tlm_generic_payload message; deque<CacheBlock*>::iterator tagIter; bool hit; CacheBlock *curBlock; sc_dt::uint64 curBaseAddress; int cachePointerModifier; unsigned int partLen; unsigned int remLen = len; unsigned char *dataPointer = ptr; if(this->scratchpadEn && adr >= this->scratchStart && adr + len <= (this->scratchStart + this->scratchSize)) { //Using local scratchpad if(this->scratchMemory == NULL){ THROW_EXCEPTION(__PRETTY_FUNCTION__ << ": Trying to access a NULL scratchpad"); } if(cmd == TLM_READ_COMMAND) memcpy(ptr, &scratchMemory[adr - this->scratchStart], len); else if(cmd == TLM_WRITE_COMMAND) memcpy(&scratchMemory[adr - this->scratchStart], ptr, len); else THROW_EXCEPTION(__PRETTY_FUNCTION__ << ": Undefined TLM command"); trans.set_response_status(TLM_OK_RESPONSE); return len; } else if (adr > cacheLimit){ return this->initSocket->transport_dbg(trans); } // else ... // For each block containing part of the requested data... for (curBaseAddress = adr - (adr % this->blockSize); curBaseAddress < adr+len; curBaseAddress += this->blockSize) { // Calculating the TAG associated to the required memory position tag = GET_TAG(curBaseAddress); hit = false; // For each block cached... // N.B. If no blocks are currently cached, cache[tag] is an ampty queue! for (tagIter = this->cache[tag].begin(); tagIter != this->cache[tag].end(); tagIter++) { // If the required block is cached... if ((*tagIter)->base_address == curBaseAddress) { // We have a HIT! #ifdef DEBUGMODE cerr << sc_time_stamp() << ": " << name() << " - DBG Hit! @" << curBaseAddress << endl; #endif hit = true; // We save the current block... curBlock = *(tagIter); // And we upgrade the queue order if we use an LRU policy if (this->removePolicy==LRU) { this->cache[tag].erase(tagIter); this->cache[tag].push_front(curBlock); } break; } } if (!hit) { // We have a MISS... #ifdef DEBUGMODE cerr << sc_time_stamp() << ": " << name() << " - DBG Miss! @ " << curBaseAddress << endl; #endif // We load the block from memory... curBlock = new CacheBlock(); curBlock->block = (unsigned char*) malloc (blockSize*sizeof(unsigned char)); curBlock->base_address = curBaseAddress; message.set_data_length(blockSize); message.set_data_ptr(curBlock->block); message.set_read(); message.set_address(curBlock->base_address); message.set_response_status(TLM_INCOMPLETE_RESPONSE); this->initSocket->transport_dbg(message); if (message.get_response_status() != TLM_OK_RESPONSE) THROW_EXCEPTION(__PRETTY_FUNCTION__ << ": Error while reading from main memory"); } // Finally, we can actually read/write the required data from/to the block... // We calculate the displacement of the data in the cache block... cachePointerModifier = adr - curBlock->base_address; if (cachePointerModifier < 0) cachePointerModifier = 0; // And the length of the data to be read/written partLen = remLen; if (partLen + cachePointerModifier > this->blockSize) partLen = this->blockSize - cachePointerModifier; // We perform the effective read/write... if(cmd == TLM_READ_COMMAND) memcpy(dataPointer, curBlock->block + cachePointerModifier, partLen*sizeof(unsigned char)); else if(cmd == TLM_WRITE_COMMAND) { memcpy(curBlock->block + cachePointerModifier, dataPointer, partLen*sizeof(unsigned char)); message.set_data_length(blockSize); message.set_data_ptr(curBlock->block); message.set_write(); message.set_address(curBlock->base_address); message.set_response_status(TLM_INCOMPLETE_RESPONSE); this->initSocket->transport_dbg(message); if (message.get_response_status() != TLM_OK_RESPONSE) THROW_EXCEPTION(__PRETTY_FUNCTION__ << ": Error while reading from main memory"); } else THROW_EXCEPTION(__PRETTY_FUNCTION__ << ": Undefined TLM command"); if (!hit) delete curBlock; // And we update the pointer to the required data for eventual subsequent reads remLen -= partLen; dataPointer += partLen; } trans.set_response_status(TLM_OK_RESPONSE); #ifdef DEBUGMODE cerr << sc_time_stamp() << ": " << name() << " - DBG Transaction " << trans.is_write() << " for Address " << adr << " completed with data "; if (trans.get_data_length() == 4) cerr << (unsigned int) (*trans.get_data_ptr()) << endl; else cerr << "ND" << endl; #endif return len; }