예제 #1
0
tlm_sync_enum Accelerator::nb_transport_fw(tlm_generic_payload& payload,
		tlm_phase& phase, sc_time& delay) {

	if(do_logging & LOG_ACC)
		cout << sc_time_stamp()<<" "<<name() << " received request." << endl;

	// update params
	if (payload.is_write())
		// data amount that has been written determines the delay
		delay += (int)((payload.get_data_length()+bus_width-1)/bus_width)*CLK_CYCLE_BUS;
	else
		delay += CLK_CYCLE_BUS; // one cycle delay to acknowledge request to the bus


	transaction_queue.notify(payload, delay);

	phase = END_REQ; // end of request phase

	if(do_logging & LOG_ACC)
		cout << "\t"<<name()<<": trans " << &payload << "received, phase " << report::print(
		phase) << (payload.is_write()?" Read":" Write") <<", delay " << delay << std::endl;

	return TLM_UPDATED; // parameters modified but transaction not yet finished

}
예제 #2
0
	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
	}
예제 #3
0
/**
 * \brief Receives a transaction from the bus and transform the interface to read/write
 *
 * \param trans The transaction packet
 * \param delay Transaction delay (actually ignored)
 */
void UC_master_slave_base::b_transport(tlm_generic_payload &trans, sc_time &delay) {
	unsigned int addr = trans.get_address();
	DATA data = trans.get_data_ptr();
	unsigned int size = trans.get_data_length();

	int bytes;
	if (trans.is_read() == true) {
		add_read_access (size);
		bytes = this->read(addr, data, size);
	}
	else if (trans.is_write() == true) {
		add_write_access (size);
		bytes = this->write(addr, data, size);
	}
	else {
		cout << "HW error: TLM command unrecognized" << endl;
		bytes = -3;
	}

	switch (bytes) {
		case 0:
			trans.set_response_status(TLM_INCOMPLETE_RESPONSE);
			break;
		case -1:
			trans.set_response_status(TLM_GENERIC_ERROR_RESPONSE);
			break;
		case -2:
			trans.set_response_status(TLM_ADDRESS_ERROR_RESPONSE);
			break;
		case -3:
			trans.set_response_status(TLM_COMMAND_ERROR_RESPONSE);
			break;
		default:
			trans.set_response_status(TLM_OK_RESPONSE);
			break;
	}
}
예제 #4
0
	// 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;
	}