예제 #1
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
	}
예제 #2
0
void Or1ksimJtagSC::jtagHandler(tlm_generic_payload & inpPayload,
		sc_time & inpDelay) {
	// Retrieve the extension.
	JtagExtensionSC * localJtagExtension;
	inpPayload.get_extension(localJtagExtension);

	// Check if the extension exists. Set up the access type and bit size as
	// appropriate.
	JtagExtensionSC::AccessType localAccessType;
	int localBitSize;

	if(NULL == localJtagExtension) {
		unsigned int addr = static_cast<unsigned int>(inpPayload.get_address());

		localAccessType = ((ADDR_SHIFT_IR == addr) ? JtagExtensionSC::SHIFT_IR :
				(ADDR_SHIFT_DR == addr) ? JtagExtensionSC::SHIFT_DR :
						JtagExtensionSC::RESET);
		localBitSize = 8 * static_cast<int>(inpPayload.get_data_length());
	}
	else {
		localAccessType = localJtagExtension->getType();
		localBitSize = localJtagExtension->getBitSize();
	}

	// Behavior depends on the type
	switch (localAccessType) {
		case JtagExtensionSC::RESET:
			myOr1ksimMutex.lock();
				inpDelay += sc_time(or1ksim_jtag_reset(), SC_SEC);
			myOr1ksimMutex.unlock();
			inpPayload.set_response_status(tlm::TLM_OK_RESPONSE);

			return;

		case JtagExtensionSC::SHIFT_IR:
			myOr1ksimMutex.lock();
				inpDelay += sc_time (or1ksim_jtag_shift_ir(inpPayload.
						get_data_ptr(), localBitSize), SC_SEC);
			myOr1ksimMutex.unlock();
			inpPayload.set_response_status(tlm::TLM_OK_RESPONSE);

			return;

		case JtagExtensionSC::SHIFT_DR:
			myOr1ksimMutex.lock ();
				inpDelay += sc_time(or1ksim_jtag_shift_dr(
						inpPayload.get_data_ptr(), localBitSize), SC_SEC);
			myOr1ksimMutex.unlock ();
			inpPayload.set_response_status (tlm::TLM_OK_RESPONSE);

			return;

		default:
			cerr << "ERROR: Unrecognized JTAG transaction type." << endl;
			inpPayload.set_response_status(tlm::TLM_GENERIC_ERROR_RESPONSE);

			return;
	}
}
예제 #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
파일: port.cpp 프로젝트: hooman91/HIWI
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;
}
예제 #5
0
tlm_sync_enum LisNoCAdapter::nb_transport_bw(tlm_generic_payload &trans, tlm_phase &phase, sc_time &delay) {
    LISNoCExtension *ext;
    ext = new LISNoCExtension();
    trans.get_extension(ext);
#ifdef DEBUG
    cout << sc_time_stamp() << " Node:" << local_id << " VC0=" << virtual_channel[0] << " VC1=" << virtual_channel[1] << endl;
#endif
    virtual_channel[ext->get_vchannel()] = false;
#ifdef DEBUG
    cout << sc_time_stamp() << " Node:" << local_id << " VC0=" << virtual_channel[0] << " VC1=" << virtual_channel[1] << endl;
#endif
    can_send.notify(SC_ZERO_TIME);

    phase = END_REQ;
    trans.set_response_status(TLM_OK_RESPONSE);
    return TLM_COMPLETED;
}
예제 #6
0
/* ------------------------------------------------------------------------- */
void 
Slave::my_b_transport(tlm_generic_payload &trans, sc_time &local_time)
{
    sc_assert((BUS_WIDTH % 32) == 0);
    unsigned int length = trans.get_data_length();
    unsigned int address = trans.get_address();

    //some checks and error responses to unsupported features
    if (trans.get_byte_enable_ptr()){
        // not supporting byte enable
        trans.set_response_status(TLM_BYTE_ENABLE_ERROR_RESPONSE);
    } else if (trans.get_streaming_width() < length) {
        // not supporting streaming
        trans.set_response_status(TLM_BURST_ERROR_RESPONSE);
    } else if ((length%bus_width_in_bytes) || (address%bus_width_in_bytes)){
        // not supporting unaligned access 
        trans.set_response_status(TLM_ADDRESS_ERROR_RESPONSE);
    } else {
        trans.set_response_status(TLM_OK_RESPONSE);
        if (trans.is_read()) { // only allow reading from result register
            if (address == REG_RESULT && (length == bus_width_in_bytes)) {
                unsigned int *data_ptr = (unsigned int *) trans.get_data_ptr();
                *data_ptr= sum_;
            } else {
                trans.set_response_status(TLM_ADDRESS_ERROR_RESPONSE);
            }
            local_time += (SLAVE_READ_DELAY+(length/bus_width_in_bytes)) 
                * bus_clock_period;
        } else {
            // write
            // only on the terms, burst access is taken into account
            if ((address == REG_START) && (length == bus_width_in_bytes)) {
                run_event_.notify(local_time+SLAVE_WRITE_DELAY*bus_clock_period);
            } else if ((address < REG_OFFSET_TERMS) 
                    || (address >= REG_OFFSET_TERMS+sizeof(int)*NR_TERMS)) {
                trans.set_response_status(TLM_ADDRESS_ERROR_RESPONSE);
            } else {
                unsigned int index = (address - REG_OFFSET_TERMS)/sizeof(int);
                unsigned int remaining = (NR_TERMS-index)*sizeof(int);
                const void *data_ptr = (const void *) trans.get_data_ptr();
                if (length<= remaining) {
                    memcpy((void *) &terms_[index], data_ptr, length);
                } else {
                    memcpy((void *) &terms_[index], data_ptr, remaining);
                }
            }
            local_time += (SLAVE_WRITE_DELAY+(length/bus_width_in_bytes)) 
                * bus_clock_period;
        }
    }
}
예제 #7
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();

    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);
  }
예제 #8
0
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);
        }
    }
}
예제 #9
0
tlm_sync_enum LisNoCAdapter::nb_transport_fw(tlm_generic_payload &trans, tlm_phase &phase, sc_time &delay) {
    m_peq.notify(trans, SC_ZERO_TIME);
    trans.set_response_status(TLM_OK_RESPONSE);
    phase = END_REQ;
    return TLM_UPDATED;
}
예제 #10
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;
	}