示例#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 
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;
        }
    }
}
示例#3
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);
  }
示例#4
0
void test_a_conversion(char cmd, tlm_generic_payload &txn, std::ifstream & fin) {

  if(cmd == 'R') txn.set_read();
  else txn.set_write();

  fin.ignore(10000,'=');
  uint64 a;
  fin >> a;
  txn.set_address(a);

  fin.ignore(10000,'=');
  int l;
  fin >> l;
  txn.set_data_length(l);

  int bus_width;
  fin.ignore(10000,'=');  fin >> bus_width;

  int data_width;
  fin.ignore(10000,'=');  fin >> data_width;

  int initiator_offset;
  fin.ignore(10000,'=');  fin >> initiator_offset;

  unsigned char *original_byte_enable = 0;
  unsigned char *byte_enable_legible =
    new unsigned char[txn.get_data_length() + 1];
  memset(byte_enable_legible, 0, txn.get_data_length() + 1);
  fin.ignore(10000,'=');
  for(unsigned b=0; b<txn.get_data_length(); b++) {
    char tmp; fin >> tmp;
    if((tmp=='0')||(tmp=='1')||(tmp=='x')) byte_enable_legible[b]=tmp;
    else break;
  }
  if((byte_enable_legible[0] == '1') || (byte_enable_legible[0] == '0')) {
    txn.set_byte_enable_ptr(new unsigned char[txn.get_data_length()]);
    txn.set_byte_enable_length(txn.get_data_length());
    original_byte_enable = txn.get_byte_enable_ptr();
    for(unsigned int i=0; i<txn.get_data_length(); i++) {
      if(byte_enable_legible[i] == '0') {
        txn.get_byte_enable_ptr()[i] = TLM_BYTE_DISABLED;
      } else if(byte_enable_legible[i] == '1') {
        txn.get_byte_enable_ptr()[i] = TLM_BYTE_ENABLED;
      } else {
        // not enough byte enables
        txn.set_byte_enable_length(i);
        break;
      }
    }
  } else {
    txn.set_byte_enable_ptr(0);
    txn.set_byte_enable_length(0);
  }

  int stream_width;
  fin.ignore(10000,'=');  fin >> stream_width;
  txn.set_streaming_width(stream_width);

  cout << "enter initiator memory state = ("<< BUFFER_SIZE << " characters)\n";
  unsigned char initiator_mem[BUFFER_SIZE+1];
  memset(initiator_mem, 0, BUFFER_SIZE+1);
  fin.ignore(10000,'=');  fin >> initiator_mem;

  txn.set_data_ptr(initiator_mem + initiator_offset);

  cout << "enter target memory state = ("<< BUFFER_SIZE << " characters)\n";
  unsigned char target_mem[BUFFER_SIZE+1];
  memset(target_mem, 0, BUFFER_SIZE+1);
  fin.ignore(10000,'=');  fin >> target_mem;

  cout << "enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single)\n";
  int converter;
  fin.ignore(10000,'=');  fin >> converter;

  cout << "Initiator Intent\n";
  cout << "  Cmd = " << cmd << endl;
  cout << "  Addr = " << txn.get_address() << endl;
  cout << "  Len = " << txn.get_data_length() << endl;
  cout << "  Bus Width = " << bus_width << endl;
  cout << "  Data Word = " << data_width << endl;
#ifdef VERBOSE
  cout << "  Initiator offset and txn data pointer = " << initiator_offset << ", " << int(txn.get_data_ptr()) << endl;
  cout << "  Byte enables and byte enable pointer = " << byte_enable_legible << ", " << int(txn.get_byte_enable_ptr()) << endl;
#else
  cout << "  Initiator offset = " << initiator_offset << endl;
  cout << "  Byte enables = " << byte_enable_legible << endl;
#endif
  cout << "  Byte enable length = " << txn.get_byte_enable_length() << endl;
  cout << "  Streaming width = " << txn.get_streaming_width() << endl;
  cout << "  Initiator memory = " << initiator_mem << endl;
  cout << "  Target memory = " << target_mem << endl;
  cout << "  Converter = " << converter << endl << endl;

  // initiator //
  switch(converter) {
    case 0:  convert(tlm_to_hostendian_generic); break;
    case 1:  convert(tlm_to_hostendian_word); break;
    case 2:  convert(tlm_to_hostendian_aligned); break;
    case 3:  convert(tlm_to_hostendian_single); break;
    case 4:  convert(local_single_tohe); break;
    default:  cout << "no such converter as " << converter << endl;
    exit(1);
  }

  cout << "Converted Transaction\n";
  cout << "  Addr = " << txn.get_address() << endl;
  cout << "  Len = " << txn.get_data_length() << endl;
#ifdef VERBOSE
  cout << "  Txn data pointer = " << int(txn.get_data_ptr()) << endl;
  if(txn.get_byte_enable_ptr() != 0) {
    cout << "  Byte enables and byte enable pointer = ";
    for(unsigned int i=0; i<txn.get_data_length(); i++)
      cout << (txn.get_byte_enable_ptr()[i] ? '1' : '0');
    cout << ", " << int(txn.get_byte_enable_ptr()) << endl;
  }
#else
  cout << "  Txn data pointer = " <<
    (txn.get_data_ptr() == initiator_mem+initiator_offset ? "unchanged" : "changed") << endl;
  if(txn.get_byte_enable_ptr() != 0) {
    cout << "  Byte enables and byte enable pointer = ";
    for(unsigned int i=0; i<txn.get_data_length(); i++)
      cout << (txn.get_byte_enable_ptr()[i] ? '1' : '0');
    cout << ", " <<
     (txn.get_byte_enable_ptr() == original_byte_enable ? "unchanged" : "changed") << endl;
  }
#endif
  cout << "  Byte enable length = " << txn.get_byte_enable_length() << endl;
  cout << "  Streaming width = " << txn.get_streaming_width() << endl;
  cout << endl;

  // target //
  int sw = txn.get_streaming_width();
  if((txn.get_data_length()/sw)*sw != txn.get_data_length()) {
    cout << "ERROR: Data length not a multiple of streaming width\n";
    exit(1);
  }
  for(unsigned int ss = 0; ss < txn.get_data_length(); ss += sw) {
    if(txn.get_byte_enable_ptr() == 0) {
      // simple transaction can be processed by mem-copy
      if(txn.is_read())
        memcpy(ss+txn.get_data_ptr(), target_mem+txn.get_address(), sw);
      else
        memcpy(target_mem+txn.get_address(), ss+txn.get_data_ptr(), sw);
    } else {
      // complex transaction, byte enables, maybe shorter than data
      int bel = txn.get_byte_enable_length();
      if(txn.is_read()) {
        for(int j=0; j<sw; j++) {
          if(txn.get_byte_enable_ptr()[(ss+j) % bel])
            (txn.get_data_ptr())[ss+j] = target_mem[j+txn.get_address()];
        }
      } else {
        for(int j=0; j<sw; j++) {
          if(txn.get_byte_enable_ptr()[(ss+j) % bel])
            target_mem[j+txn.get_address()] = (txn.get_data_ptr())[ss+j];
        }
      }
    }
  }

  // initiator again //
  if((rand() & 0x100) && (converter < 4)) {
#ifdef VERBOSE
    cout << "using single entry point for response\n";
#endif
    tlm_from_hostendian(&txn);
  } else {
#ifdef VERBOSE
    cout << "using specific entry point for response\n";
#endif
    switch(converter) {
      case 0:  convert(tlm_from_hostendian_generic); break;
      case 1:  convert(tlm_from_hostendian_word); break;
      case 2:  convert(tlm_from_hostendian_aligned); break;
      case 3:  convert(tlm_from_hostendian_single); break;
      case 4:  convert(local_single_fromhe); break;
      default:  cout << "no such converter as " << converter << endl;
      exit(1);
    }
  }

  // print the results //
  cout << "Memory States after Transaction\n";
  cout << "  initiator = " << initiator_mem << endl;
  cout << "  target = " << target_mem << endl << endl;

  // clean up
  delete [] byte_enable_legible;
  if(original_byte_enable != 0) delete [] original_byte_enable;
}