Exemple #1
0
    //Method used for receiving acknowledgements of interrupts; the ack consists of
    //uninteresting data and the address corresponds to the interrupt signal to
    //be lowered
    //As a response, I lower the interrupt by sending a NULL pointer on the init_socket
    void b_transport(tlm::tlm_generic_payload& trans, sc_time& delay) {
        if(this->lastIrq < 0) {
            THROW_EXCEPTION("Error, lowering an interrupt which hasn't been raised yet!!");
        }
        tlm::tlm_command cmd = trans.get_command();
        sc_dt::uint64    adr = trans.get_address();
        unsigned char*   ptr = trans.get_data_ptr();
        if(trans.get_command() == tlm::TLM_READ_COMMAND) {
            THROW_EXCEPTION("Error, the read request is not currently supported by external PINs");
        }
        else if(cmd == tlm::TLM_WRITE_COMMAND) {
            if(this->lastIrq != adr) {
                THROW_EXCEPTION("Error, lowering interrupt " << std::hex << std::showbase << (unsigned)adr << " while " << std::hex << std::showbase << this->lastIrq << " was raised");
            }
            else {
                //finally I can really lower the interrupt: I send 0 on
                //the initSocked
                unsigned char data = 0;
                trans.set_data_ptr(&data);
                trans.set_dmi_allowed(false);
                trans.set_response_status( tlm::TLM_INCOMPLETE_RESPONSE );
                sc_time delay;
                this->init_socket->b_transport(trans, delay);
                if(trans.is_response_error()) {
                    std::string errorStr("Error in b_transport of PIN, response status = " + trans.get_response_string());
                    SC_REPORT_ERROR("TLM-2", errorStr.c_str());
                }

                this->lastIrq = -1;
            }
        }

        trans.set_response_status(tlm::TLM_OK_RESPONSE);
    }
Exemple #2
0
//==============================================================================
bool
dmi_memory::is_address_dmi
(
  tlm::tlm_generic_payload  &gp
)
{
  m_start_address = gp.get_address();
  m_end_address   = m_start_address + gp.get_data_length();

  std::ostringstream  msg;
  msg.str("");
  msg << "Initiator:" << m_ID;
  bool                return_status = false;

  if ( (    ( m_start_address < ( m_dmi_base_address              ) )
         || ( m_end_address   > ( m_dmi_base_address + m_dmi_size ) )
        )
      )
  {
    // address is outside of the DMI boundaries
    msg << " address is not a dmi address";
//    msg << "m_start_address= " << m_start_address << " m_address= " << m_address
//        << endl << "       "
//        << "m_end_address= " << m_end_address << " m_offset= " << m_offset << " m_dmi_size= "<< m_dmi_size;
    REPORT_INFO(filename, __FUNCTION__, msg.str());
  }
  else if (        ( gp.get_command () == tlm::TLM_WRITE_COMMAND        )
          )
       {
        if (  (m_granted_access != tlm::tlm_dmi::DMI_ACCESS_READ )
                && (  m_granted_access != tlm::tlm_dmi::DMI_ACCESS_NONE)){
         msg << " correct address and appropriate access for a GP Write Command "<<endl<<"      ";
         REPORT_INFO(filename, __FUNCTION__, msg.str());
         return_status=true;
         }
       } //end if
  else if (        ( gp.get_command () == tlm::TLM_READ_COMMAND          )
          )
      {
        if ( (m_granted_access != tlm::tlm_dmi::DMI_ACCESS_WRITE  )
                && (  m_granted_access != tlm::tlm_dmi::DMI_ACCESS_NONE)){
        msg << " correct address and appropriate access for a GP Read Command "<<endl<<"      ";
        REPORT_INFO(filename, __FUNCTION__, msg.str());
        return_status=true;
        }
      } //end if
  else {
     // access permission does not match access required for operation
         msg << " Incompatible GP Command for DMI Access Granted ";
     //    msg << " Gp.getcommand()= " << gp.get_command();
         REPORT_INFO(filename, __FUNCTION__, msg.str());
  } //end else

  return return_status;
} // end check is dmi
Exemple #3
0
//======================================================================
/// @fn b_transport
//
/// @brief implementation of the blocking transport for transactions on
///		the SAE memory
//
/// @details IC1 initiators only have write access und  LM only has 
///		read access. This funtion first verifies that the requested 
///		memory access is allowed before executing the operation. <br>
///		
//
//======================================================================
void target_sae::b_transport (	int id,
								tlm::tlm_generic_payload& tObj, 
								sc_core::sc_time& delay				)
{	
	tlm::tlm_command	cmd			= tObj.get_command();

	// control access rights 
	switch(id)
	{
		case 1:					//lmodel
			sae_mem.operation(lmodel_id_nr, tObj, delay);
			break;
		case 0:					//ic1
			if (cmd == tlm::TLM_READ_COMMAND )
			{
				tObj.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE);
				msg << "this component has write-access only!";
				ERROR_LOG(filename, __FUNCTION__ , msg.str());
				return;
			}
			sae_mem.operation(ic1_id_nr, tObj, delay);
			break;
	}
	
}
  virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay )
  {
    tlm::tlm_command cmd = trans.get_command();
    unsigned char*   ptr = trans.get_data_ptr();
    unsigned int     len = trans.get_data_length();
    unsigned char*   byt = trans.get_byte_enable_ptr();
    unsigned int     bel = trans.get_byte_enable_length();

    my_extension* ext;
    trans.get_extension(ext);
    assert( ext );

    assert( len == ext->len );
    assert( bel == ext->bel );
    for (unsigned int i = 0; i < bel; i++)
      assert( byt[i] == ext->byt[i] );
    for (unsigned int i = 0; i < len; i++)
      assert( ptr[i] == ext->ptr[i] );

    if (cmd == tlm::TLM_READ_COMMAND)
    {
      for (unsigned int i = 0; i < len; i++)
      {
        data[i] = rand() % 256;
        ptr[i]  = data[i];
      }
      ext->ptr = data;
    }

    trans.set_dmi_allowed( true );
    trans.set_response_status( tlm::TLM_OK_RESPONSE );
  }
  // TLM-2 blocking transport method
  virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay )
  {
    tlm::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();

    // Obliged to check address range and check for unsupported features,
    //   i.e. byte enables, streaming, and bursts
    // Can ignore DMI hint and extensions
    // Using the SystemC report handler is an acceptable way of signalling an error

    if (adr >= sc_dt::uint64(SIZE) || byt != 0 || len > 4 || wid < len)
      SC_REPORT_ERROR("TLM-2", "Target does not support given generic payload transaction");

    // Obliged to implement read and write commands
    if ( cmd == tlm::TLM_READ_COMMAND ){
      memcpy(ptr, &mem[adr], len);
      cout << "Data: " << dec << mem[adr] << 
              " is read from Address: " << dec << adr << endl;
    }
    else if ( cmd == tlm::TLM_WRITE_COMMAND ){
      memcpy(&mem[adr], ptr, len);
      cout << "Data: " << dec << mem[adr] << 
              " is written into Address: " << dec << adr << endl;
    }

    // Obliged to set response status to indicate successful completion
    trans.set_response_status( tlm::TLM_OK_RESPONSE );
  }
//==============================================================================
//  dbg_transport implementation calls from initiators
//
//=============================================================================
unsigned int model_jxz_tlm::entry_transport_dbg (tlm::tlm_generic_payload &gp)
{
  tlm::tlm_command command = gp.get_command();// memory command
  unsigned char *data = gp.get_data_ptr();// data pointer
  unsigned int length = gp.get_data_length();// data length
  gp.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE);
  return 0;
}
//==============================================================================
//  b_transport implementation calls from initiators
//
//=============================================================================
void model_jxz_tlm::entry_b_transport (tlm::tlm_generic_payload &gp, sc_core::
  sc_time &delay_time)
{
  tlm::tlm_command command = gp.get_command();// memory command
  unsigned char *data = gp.get_data_ptr();// data pointer
  unsigned int length = gp.get_data_length();// data length
  unsigned long timefactor = ((length+BUSWIDTHBYTE-1)/BUSWIDTHBYTE)-1;
  bool write_ok = true;
  gp.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE);
  return;
}
  // TLM-2 blocking transport method
  virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay )
  {
    tlm::tlm_command cmd = trans.get_command();
    sc_dt::uint64    adr = trans.get_address() / 4;
    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();

    // Obliged to check address range and check for unsupported features,
    //   i.e. byte enables, streaming, and bursts
    // Can ignore extensions

    // *********************************************
    // Generate the appropriate error response
    // *********************************************

    if (adr >= sc_dt::uint64(SIZE)) {
      trans.set_response_status( tlm::TLM_ADDRESS_ERROR_RESPONSE );
      return;
    }
    if (byt != 0) {
      trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE );
      return;
    }
    if (len > 4 || wid < len) {
      trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE );
      return;
    }

    // Obliged to implement read and write commands
    if ( cmd == tlm::TLM_READ_COMMAND )
      memcpy(ptr, &mem[adr], len);
    else if ( cmd == tlm::TLM_WRITE_COMMAND )
      memcpy(&mem[adr], ptr, len);

    // Illustrates that b_transport may block
    wait(delay);

    // Reset timing annotation after waiting
    delay = SC_ZERO_TIME;

    // *********************************************
    // Set DMI hint to indicated that DMI is supported
    // *********************************************

    trans.set_dmi_allowed(true);

    // Obliged to set response status to indicate successful completion
    trans.set_response_status( tlm::TLM_OK_RESPONSE );
  }
void memory::operation
(
     tlm::tlm_generic_payload  &gp
   , sc_core::sc_time          &delay_time   ///< transaction delay
) {
    sc_dt::uint64    address   = gp.get_address();     // memory address
    tlm::tlm_command command   = gp.get_command();     // memory command
    unsigned char    *data     = gp.get_data_ptr();    // data pointer
    unsigned  int     length   = gp.get_data_length(); // data length

    tlm::tlm_response_status response_status = check_address(gp)
            ? tlm::TLM_OK_RESPONSE
            : tlm::TLM_ADDRESS_ERROR_RESPONSE;

    if (gp.get_byte_enable_ptr()) {
        gp.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE);
    }
    else if (gp.get_streaming_width() != gp.get_data_length()) {
        gp.set_response_status(tlm::TLM_BURST_ERROR_RESPONSE);
    }
    switch (command)
    {
        default:
        {
            gp.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE);
            break;
        }

        case tlm::TLM_WRITE_COMMAND:
        {
            if (response_status == tlm::TLM_OK_RESPONSE) {
                for (unsigned int i = 0; i < length; i++) {
                    m_memory[address++] = data[i];        // move the data to memory
                }
            }
            break;
        }

        case tlm::TLM_READ_COMMAND: {
            if (response_status == tlm::TLM_OK_RESPONSE) {
                for (unsigned int i = 0; i < length; i++)
                {
                    data[i] = m_memory[address++];         // move the data from memory
                }
            }
            break;
        }
    } // end switch
    gp.set_response_status(response_status);
}
Exemple #10
0
    void peq_cb(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase){
        tlm::tlm_sync_enum status;
        sc_time delay;

        switch (phase){
            case tlm::BEGIN_REQ:
                status = send_end_req(trans);
            break;

            case tlm::END_RESP:
                //std::cerr << "tlm::END_RESP in memory peq_cb" << std::endl;
                this->transactionInProgress = false;
                this->transactionCompleted.notify();
            break;

            case tlm::END_REQ:
            case tlm::BEGIN_RESP:
                SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by target");
            break;

            default:
                if (phase == internal_ph){
                    // Execute the read or write commands
                    tlm::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();

                    if(cmd == tlm::TLM_READ_COMMAND){
                        for(int i = 0; i < len; i++, ptr++)
                            *ptr = this->mem[adr + i];
                    }
                    else if(cmd == tlm::TLM_WRITE_COMMAND){
                        for(int i = 0; i < len; i++, ptr++)
                            this->mem[adr + i] = *ptr;
                    }


                    trans.set_response_status(tlm::TLM_OK_RESPONSE);

                    // Target must honor BEGIN_RESP/END_RESP exclusion rule
                    // i.e. must not send BEGIN_RESP until receiving previous END_RESP or BEGIN_REQ
                    send_response(trans);
                    //std::cerr << "Memory reading address in memory " << std::hex << std::showbase << adr << std::endl;
                }
            break;
        }
    }
Exemple #11
0
// Data interface to functional part of the model
void mmu_cache::exec_data(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay, bool is_dbg) {

  // Vars for payload decoding
  tlm::tlm_command cmd = trans.get_command();
  sc_dt::uint64 addr   = trans.get_address();
  unsigned char * ptr  = trans.get_data_ptr();
  unsigned int len     = trans.get_data_length();

  // Log number of reads and writes for power monitoring
  if (m_pow_mon) {

    if (cmd == tlm::TLM_READ_COMMAND) {

      dyn_reads += (len >> 2) + 1;

    } else {
Exemple #12
0
    virtual unsigned int transport_dbg(tlm::tlm_generic_payload & trans) {
        tlm::tlm_command cmd = trans.get_command();
        sc_dt::uint64 adr = trans.get_address() / 4;
        unsigned char* ptr = trans.get_data_ptr();
        unsigned int len = trans.get_data_length();

        // Calculate the number of bytes to be actually copied
        unsigned int num_bytes = (len < (SIZE - adr) * 4) ? len : (SIZE - adr) * 4;

        if (cmd == tlm::TLM_READ_COMMAND)
            memcpy(ptr, &mem[adr], num_bytes);
        else if (cmd == tlm::TLM_WRITE_COMMAND)
            memcpy(&mem[adr], ptr, num_bytes);

        return num_bytes;
    }
Exemple #13
0
    // TLM-2 debug transaction method
    unsigned int transport_dbg(int tag, tlm::tlm_generic_payload& trans){
        tlm::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();

        if(cmd == tlm::TLM_READ_COMMAND){
            for(int i = 0; i < len; i++, ptr++)
                *ptr = this->mem[adr + i];
        }
        else if(cmd == tlm::TLM_WRITE_COMMAND){
            for(int i = 0; i < len; i++, ptr++)
                this->mem[adr + i] = *ptr;
        }

        return len;
    }
//==============================================================================
///  @fn memory::get_delay
//  
///  @brief Method to "pull" appropriate delay from the gp
// 
///  @details
///    This routine used during several at examples
//   
//==============================================================================
void 
memory::get_delay
( tlm::tlm_generic_payload  &gp           ///< TLM2 GP reference
, sc_core::sc_time          &delay_time   ///< time to be updated
)
{
  /// Access the required attributes from the payload
  tlm::tlm_command command   = gp.get_command();     // memory command
  
  std::ostringstream  msg;   
  msg.str("");
  
  switch (command)
  {
    default:
    {
      if (m_previous_warning == false)
      {
        msg << "Target: " << m_ID 
            << " Unsupport GP command extension";
        REPORT_WARNING(filename, __FUNCTION__, msg.str());
        m_previous_warning = true;
      }
      break;
    }
    
    /// Setup a TLM_WRITE_COMMAND Informational Message and Write the Data from
    /// the Generic Payload Data pointer to Memory
    ///
    case tlm::TLM_WRITE_COMMAND:
    {
      delay_time = delay_time + m_write_delay;
      break;     
    }

    case tlm::TLM_READ_COMMAND:
    {
      delay_time = delay_time + m_read_delay;
      break;
    }
  } // end switch  
  return; 
}
  // Called on receiving BEGIN_RESP or TLM_COMPLETED
  void check_transaction(tlm::tlm_generic_payload& trans)
  {
    if ( trans.is_response_error() )
    {
      char txt[100];
      sprintf(txt, "Transaction returned with error, response status = %s",
                   trans.get_response_string().c_str());
      SC_REPORT_ERROR("TLM-2", txt);
    }

    tlm::tlm_command cmd = trans.get_command();
    sc_dt::uint64    adr = trans.get_address();
    int*             ptr = reinterpret_cast<int*>( trans.get_data_ptr() );

    fout << hex << adr << " " << name() << " check, cmd=" << (cmd ? 'W' : 'R')
         << ", data=" << hex << *ptr << " at time " << sc_time_stamp() << endl;

    // Allow the memory manager to free the transaction object
    trans.release();
  }
Exemple #16
0
  // TLM-2 blocking transport method
  virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay )
  {
    tlm::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();

    // Obliged to check address range and check for unsupported features,
    //   i.e. byte enables, streaming, and bursts
    // Can ignore DMI hint and extensions
    // Using the SystemC report handler is an acceptable way of signalling an error

    if (adr >= sc_dt::uint64(SIZE) * 4 || adr % 4)
    {
      trans.set_response_status( tlm::TLM_ADDRESS_ERROR_RESPONSE );
      return;
    }
    else if (byt != 0)
    {
      trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE );
      return;
    }
    else if (len > 4 || wid < len)
    {
      trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE );
      return;
    }

    // Obliged to implement read and write commands
    if ( cmd == tlm::TLM_READ_COMMAND )
      memcpy(ptr, &mem[adr/4], len);
    else if ( cmd == tlm::TLM_WRITE_COMMAND )
      memcpy(&mem[adr/4], ptr, len);

    // Obliged to set response status to indicate successful completion
    trans.set_response_status( tlm::TLM_OK_RESPONSE );
  }
//! @param payload  The generic TLM payload
//! @param delay    How far the initiator is beyond baseline SystemC time.
//!                 Ignored here.
// ----------------------------------------------------------------------------
void
LoggerSC::loggerReadWrite( tlm::tlm_generic_payload &payload,
			   sc_core::sc_time         &delay )
{
  // Break out the address, mask and data pointer.
  tlm::tlm_command   comm    = payload.get_command();
  sc_dt::uint64      addr    = payload.get_address();
  unsigned char     *maskPtr = payload.get_byte_enable_ptr();
  unsigned char     *dataPtr = payload.get_data_ptr();

  // Record the payload fields (data only if it's a write)
  const char *commStr;

  switch( comm ) {
  case tlm::TLM_READ_COMMAND:   commStr = "Read";            break;
  case tlm::TLM_WRITE_COMMAND:  commStr = "Write";           break;
  case tlm::TLM_IGNORE_COMMAND: commStr = "Ignore";          break;
  default:                      commStr = "Unknown command"; break;
  }

  std::cout << "Logging" << std::endl;
  std::cout << "  Command:      "   << commStr << std::endl;
  std::cout << "  Address:      0x" << std::setw( 8 ) << std::setfill( '0' )
	    <<std::hex << (uint64_t)addr << std::endl;
  std::cout << "  Byte enables: 0x" << std::setw( 8 ) << std::setfill( '0' )
	    <<std::hex << *((uint32_t *)maskPtr) << std::endl;

  if( tlm::TLM_WRITE_COMMAND == comm ) {
    std::cout << "  Data:         0x" << std::setw( 8 ) << std::setfill( '0' )
	      <<std::hex << *((uint32_t *)dataPtr) << std::endl;
  }

  std::cout << std::endl;

  payload.set_response_status( tlm::TLM_OK_RESPONSE );  // Always OK

}	// loggerReadWrite()
unsigned int memory::debug
(
     tlm::tlm_generic_payload  &gp
   , sc_core::sc_time          &delay_time   ///< transaction delay
) {
    sc_dt::uint64    address   = gp.get_address();     // memory address
    tlm::tlm_command command   = gp.get_command();     // memory command
    unsigned char    *data     = gp.get_data_ptr();    // data pointer
    unsigned  int     length   = gp.get_data_length(); // data length
    bool              ok       = check_address(gp);

    if(ok) {
        switch (command)
        {
            case tlm::TLM_WRITE_COMMAND:
                for (unsigned int i = 0; i < length; i++) {
                    m_memory[address++] = data[i];         // move the data to memory
                }
                gp.set_response_status(tlm::TLM_OK_RESPONSE);
                break;

            case tlm::TLM_READ_COMMAND:
                for (unsigned int i = 0; i < length; i++) {
                    data[i] = m_memory[address++];         // move the data from memory
                }
                gp.set_response_status(tlm::TLM_OK_RESPONSE);
                break;

            default:
                ok = 0;
                break;

        }
    } // end switch

    return ok ? length : 0;
}
Exemple #19
0
//=====================================================================
///  @fn dmi_memory::operation
//
///  @brief DMI read and write processing
//
///  @details
///    This routine implements dmi based read and  write operations
//
//=====================================================================
void
dmi_memory::operation
( tlm::tlm_generic_payload  &gp
, sc_core::sc_time          &delay   ///< transaction delay
)
{
  std::ostringstream  msg;
  msg.str("");

  m_address   = gp.get_address();
  m_data      = gp.get_data_ptr();    ///< data pointer
  m_length    = gp.get_data_length(); ///< data length
  m_command   = gp.get_command();
  m_is_dmi_flag = false;
  gp.set_response_status(tlm::TLM_GENERIC_ERROR_RESPONSE);

  if (is_address_dmi(gp) == false )
  {
    msg << "Iniiator:" << m_ID
        << "A GP with an address not in the allowed DMI ranges has been received"
        << endl << "       "
        << "Use check_status before passing a gp to operation";
      REPORT_INFO(filename, __FUNCTION__, msg.str());
      gp.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE); // Need a different error
    }
 else
 {
  m_offset  = m_address - m_dmi_base_address;

  switch (m_command)
  {
    case tlm::TLM_WRITE_COMMAND:
    {
      for (unsigned int i = 0; i < m_length; i++)
       {
          m_dmi_ptr[m_offset + i] = m_data[i];
        }
      gp.set_response_status(tlm::TLM_OK_RESPONSE);

      delay = delay + m_dmi_write_latency;  // update time
      report::print(m_ID, gp, filename);

      break;
    }

    case tlm::TLM_READ_COMMAND:
    {
      // clear read buffer
      for (unsigned int i = 0; i < m_length; i++)
        {
        m_data[i] = m_dmi_ptr [m_offset + i];
        }
      gp.set_response_status(tlm::TLM_OK_RESPONSE);

      delay = delay +  m_dmi_read_latency; // update time
      report::print(m_ID, gp, filename);

      break;
    }

    default:
    {
      msg << "Target: " << m_ID
          << " Unknown GP command that could be ignorable";
      REPORT_WARNING(filename, __FUNCTION__, msg.str());
      gp.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE);
      break;
    }

    }//end switch
  }

  return;

//==============================================================================
} // end memory_operation
  void peq_cb(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase)
  {
    tlm::tlm_sync_enum status;
    sc_time delay;

    switch (phase) {
    case tlm::BEGIN_REQ:

      #ifdef DEBUG
        fout << hex << trans.get_address() << " " << name() << " BEGIN_REQ at " << sc_time_stamp() << endl;
      #endif

      // Increment the transaction reference count
      trans.acquire();

      // Put back-pressure on initiator by deferring END_REQ until pipeline is clear
      if (n_trans == 2)
        end_req_pending = &trans;
      else
      {
        status = send_end_req(trans);
        if (status == tlm::TLM_COMPLETED) // It is questionable whether this is valid
          break;
      }

      break;

    case tlm::END_RESP:
      // On receiving END_RESP, the target can release the transaction
      // and allow other pending transactions to proceed

      #ifdef DEBUG
        fout << hex << trans.get_address() << " " << name() << " END_RESP at " << sc_time_stamp() << endl;
      #endif

      if (!response_in_progress)
        SC_REPORT_FATAL("TLM-2", "Illegal transaction phase END_RESP received by target");

      trans.release();
      n_trans--;

      // Target itself is now clear to issue the next BEGIN_RESP
      response_in_progress = false;
      if (next_response_pending)
      {
        send_response( *next_response_pending );
        next_response_pending = 0;
      }

      // ... and to unblock the initiator by issuing END_REQ
      if (end_req_pending)
      {
        status = send_end_req( *end_req_pending );
        end_req_pending = 0;
      }

      break;

    case tlm::END_REQ:
    case tlm::BEGIN_RESP:
      SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by target");
      break;

    default:
      if (phase == internal_ph)
      {
        // Execute the read or write commands

        tlm::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();

        if ( cmd == tlm::TLM_READ_COMMAND )
        {
          *reinterpret_cast<int*>(ptr) = rand();
          fout << hex << adr << " " << name() << " Execute READ, target = " << name()
               << " data = " << *reinterpret_cast<int*>(ptr) << endl;
        }
        else if ( cmd == tlm::TLM_WRITE_COMMAND )
          fout << hex << adr << " " << name() << " Execute WRITE, target = " << name()
               << " data = " << *reinterpret_cast<int*>(ptr) << endl;

        trans.set_response_status( tlm::TLM_OK_RESPONSE );

        // Target must honor BEGIN_RESP/END_RESP exclusion rule
        // i.e. must not send BEGIN_RESP until receiving previous END_RESP or BEGIN_REQ
        if (response_in_progress)
        {
          // Target allows only two transactions in-flight
          if (next_response_pending)
            SC_REPORT_FATAL("TLM-2", "Attempt to have two pending responses in target");
          next_response_pending = &trans;
        }
        else
          send_response(trans);
        break;
      }
    }
  }
Exemple #21
0
	virtual void b_transport( int id, tlm::tlm_generic_payload& trans, sc_time& delay )
	{
		int target_nr = 0;
		sc_dt::uint64 address = trans.get_address();
		sc_dt::uint64 read_address = 0;
		sc_dt::uint64 write_address = 0 ;
		decode_address( address, read_address, write_address, id, startAdr[id]);

		if(id == 0){//Writer
			writeAllowed = true;
			trans.set_address(write_address);
			(*init_socket[target_nr])->b_transport(trans, delay);

      cout << "\tID is: " << id << " - After calling b_transport in Switch: " << endl;
			if(trans.is_response_ok() && writerCounter < startAdr[id + 1])
				writerCounter = writerCounter + 8;  // Change since now 8-bit words.
			if(trans.is_response_ok() && writerCounter >= startAdr[id + 1]){
				writeAllowed = false;
				mtfAllowed = true;
			}
		}
		else if(id == 1){//mtf
			if(mtfAllowed == true){
				if(trans.get_command() == tlm::TLM_WRITE_COMMAND)
					trans.set_address( write_address );
				if(trans.get_command() == tlm::TLM_READ_COMMAND)
					trans.set_address(read_address);
				(*init_socket[target_nr])->b_transport(trans, delay);

        cout << "\tID is: " << id << " - After calling b_transport in Switch: " << endl;
				if(trans.is_response_ok() && MTFCounter < startAdr[id + 1])
					MTFCounter = MTFCounter + 8;      // Change since now 8-bit words.
				if(trans.is_response_ok() && MTFCounter >= startAdr[id + 1]){
					runAllowed.write(true);
				}
			}
		}
		else if(id == 2){//runL
			if(runAllowed == true){
				if(trans.get_command() == tlm::TLM_WRITE_COMMAND)
					trans.set_address( write_address );
				if(trans.get_command() == tlm::TLM_READ_COMMAND)
					trans.set_address(read_address);

				(*init_socket[target_nr])->b_transport(trans, delay);

        //cout << "\tID is: " << id << " - After calling b_transport in Switch: " << endl;
				if(trans.is_response_ok() && runCounter < startAdr[id + 1])
					runCounter = runCounter + 8;      // Change since now 8-bit words.
				if(trans.is_response_ok() && runCounter >= startAdr[id + 1]- startAdr[id]){
					readAllowed.write(true);
				}
			}
		}
		else if(id == 3){//Reader
			if(readAllowed == true){
				if(trans.get_command() == tlm::TLM_READ_COMMAND)
					trans.set_address(read_address );
				(*init_socket[target_nr])->b_transport(trans, delay);

        //cout << "\tID is: " << id << " - After calling b_transport in Switch: " << endl;
				if(readCounter <= startAdr[id]- startAdr[id - 1]){
					readCounter = readCounter + 8;    // Change since now 8-bit words.
					trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
				}
				else if(readCounter > startAdr[id]- startAdr[id - 1]){
					trans.set_response_status(tlm::TLM_OK_RESPONSE);
				}
			}
			else
				trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
		}

	}
//==============================================================================
///  @fn memory::operation
//  
///  @brief performs read and write
// 
///  @details
///    This routine implements the read and  write operations. including 
///    checking for byte_enable and streaming that are not implemented
//   
//==============================================================================
void 
memory::operation     
( tlm::tlm_generic_payload  &gp     
, sc_core::sc_time          &delay_time   ///< transaction delay 
)    
{
  /// Access the required attributes from the payload
  sc_dt::uint64    address   = gp.get_address();     // memory address
  tlm::tlm_command command   = gp.get_command();     // memory command
  unsigned char    *data     = gp.get_data_ptr();    // data pointer
  unsigned  int     length   = gp.get_data_length(); // data length
  
  std::ostringstream  msg;   
  msg.str("");
  tlm::tlm_response_status response_status = check_address(gp);
  
  if (gp.get_byte_enable_ptr())
  {
    gp.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE);
  }
  else if (gp.get_streaming_width() != gp.get_data_length()) 
  {
    gp.set_response_status(tlm::TLM_BURST_ERROR_RESPONSE);
  }
    
  switch (command)
  {
    default:
    {
      if (m_previous_warning == false)
      {
        msg << "Target: " << m_ID 
            << " Unsupported Command Extension";
        REPORT_INFO(filename, __FUNCTION__, msg.str());
        gp.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE);
        delay_time = sc_core::SC_ZERO_TIME;
        m_previous_warning = true;
      }
      break;
    }
    
    /// Setup a TLM_WRITE_COMMAND Informational Message and Write the Data from
    /// the Generic Payload Data pointer to Memory
    ///
    case tlm::TLM_WRITE_COMMAND:
    {
      if (response_status == tlm::TLM_OK_RESPONSE)
        {
          for (unsigned int i = 0; i < length; i++)
          {
            m_memory[address++] = data[i];     // move the data to memory
          }
          delay_time = delay_time + m_write_delay;
          report::print(m_ID, gp, filename);
        } 
      break;     
    }

    case tlm::TLM_READ_COMMAND:
    {
      if (response_status == tlm::TLM_OK_RESPONSE)
      {
        for (unsigned int i = 0; i < length; i++)
        {
          data[i] = m_memory[address++];         // move the data to memory
        }
        delay_time = delay_time + m_read_delay;
        report::print(m_ID, gp, filename);
      }     
      break;
    }
  } // end switch

  gp.set_response_status(response_status);
  
  return;
} // end memory_operation
Exemple #23
0
// Instruction interface to functional part of the model
void mmu_cache::exec_instr(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay, bool is_dbg) {

  // Vars for payload decoding
  tlm::tlm_command cmd = trans.get_command();
  sc_dt::uint64 addr   = trans.get_address();
  unsigned char * ptr  = trans.get_data_ptr();

  // Log instruction reads for power monitoring
  if (m_pow_mon) {
    dyn_reads += (trans.get_data_length() >> 2) + 1;
  }

  // Extract extension
  icio_payload_extension * iext;
  trans.get_extension(iext);

  unsigned int *debug;
  unsigned int flush;

  // Check/extract instruction payload extension
  if (iext!=NULL) {

    debug = iext->debug;
    flush = iext->flush;

  } else {

    // No iext
    debug = NULL;
    flush = 0;

    v::error << name() << "IEXT Payload extension missing" << v::endl;
  }

  // Flush instruction
  if (flush) {

    v::debug << name() << "Received flush instruction - flushing both caches" << v::endl;

    // Simultaneous flush of both caches
    icache->flush(&delay, debug, is_dbg);
    dcache->flush(&delay, debug, is_dbg);

    trans.set_response_status(tlm::TLM_OK_RESPONSE);

    return;

  }

  if (cmd == tlm::TLM_READ_COMMAND) {

    assert( 1 ); // fix asi -> priv / unpriv

    mmu_cache_base::exec_instr(addr, ptr, 0x8, debug, flush, delay, is_dbg); // ToDo: fix ASI! 0x8 -> unprivileged instruction

    // Set response status
    trans.set_response_status(tlm::TLM_OK_RESPONSE);

  } else {

    v::error << name() << " Command not valid for instruction cache (tlm_write)" << v::endl;
    // Set response status
    trans.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE);

  }
}