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);
}
//==============================================================================
///  @fn memory::check_address
//  
///  @brief Method to check if the gp is in the address range of this memory
// 
///  @details
///    This routine used to check for errors in address space
//   
//==============================================================================
tlm::tlm_response_status
memory::check_address
( tlm::tlm_generic_payload  &gp        
)
{
  sc_dt::uint64    address   = gp.get_address();     // memory address
  unsigned  int     length   = gp.get_data_length(); // data length
  
  std::ostringstream  msg;   
  msg.str("");
  
  if ( address >= m_memory_size )
  {
    msg << "Target: " << m_ID 
        <<" address out-of-range";
    REPORT_WARNING(filename, __FUNCTION__, msg.str());
    
    return tlm::TLM_ADDRESS_ERROR_RESPONSE; // operation response
  }
  else
  {
    if ( (address + length) >= m_memory_size )   
    {
      msg << "Target: " << m_ID 
          << " address will go out of bounds";
      REPORT_WARNING(filename, __FUNCTION__, msg.str());
      
      return tlm::TLM_ADDRESS_ERROR_RESPONSE; // operation response
    }
    
  return tlm::TLM_OK_RESPONSE;
  }
} // end check address
  // 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 );
  }
Exemple #4
0
    // TLM-2 non-blocking transport method
    tlm::tlm_sync_enum nb_transport_fw(int tag, tlm::tlm_generic_payload& trans,
                                                tlm::tlm_phase& phase, sc_time& delay){
        sc_dt::uint64    adr = trans.get_address();
        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 the transaction attributes for unsupported features
        // and to generate the appropriate error response
        if (byt != 0){
            trans.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE);
            return tlm::TLM_COMPLETED;
        }
        if(adr > this->size){
            trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
            std::cerr << "Error requesting address " << std::showbase << std::hex << adr << std::dec << std::endl;
            return tlm::TLM_COMPLETED;
        }
        // Now queue the transaction until the annotated time has elapsed
        if(phase == tlm::BEGIN_REQ){
            while(this->transactionInProgress){
                //std::cerr << "waiting for transactionInProgress" << std::endl;
                wait(this->transactionCompleted);
            }
            //std::cerr << "there are no transactionInProgress" << std::endl;
            this->transactionInProgress = true;
        }
        this->transId = tag;
        m_peq.notify(trans, phase, delay);
        trans.set_response_status(tlm::TLM_OK_RESPONSE);
        return tlm::TLM_ACCEPTED;
    }
Exemple #5
0
inline void lt_target::b_transport(tlm::tlm_generic_payload& trans, sc_time& delay){

	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   blen = trans.get_byte_enable_length();
	unsigned int   wid  = trans.get_streaming_width();

	if (adr >= sc_dt::uint64(mem_size) ) {
		trans.set_response_status( tlm::TLM_ADDRESS_ERROR_RESPONSE );
		return;
	}
	if ( wid < len ) {
		trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE );
		return;
	}
	
	if (trans.is_read()) {
		delay += rd_latency;
		if ( byt != 0 ) {
			for ( unsigned int i = 0; i < len; i++ )
				if ( byt[i % blen] == TLM_BYTE_ENABLED ){
					ptr[i] = (mem[adr+i/4] >> ((i&3)*8)) & 0xFF;
				}
		} else {
  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 );
  }
//==============================================================================
//  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;
}
Exemple #8
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
//==============================================================================
//  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 );
  }
//==============================================================================
///  @fn memory::check_address
//
///  @brief Method to check if the gp is in the address range of this memory
//
///  @details
///    This routine used to check for errors in address space
//
//==============================================================================
bool memory::check_address (
    tlm::tlm_generic_payload  &gp
) {
    sc_dt::uint64    address   = gp.get_address();     // memory address
    unsigned  int     length   = gp.get_data_length(); // data length

    if  ( (address < 0) || (address > m_high_address) ) {
        return 0;
    } else if ( (address + length-1) > m_high_address ) {
        return 0;
    } else {
        return 1;
    }
} // end check address
Exemple #12
0
unsigned int leon3_funclt_trap::IntrTLMPort_32::transport_dbg( int tag, tlm::tlm_generic_payload \
    & trans ){
    unsigned char* ptr = trans.get_data_ptr();
    sc_dt::uint64 adr = trans.get_address();
    if(*ptr == 0){
        //Lower the interrupt
        this->irqSignal = -1;
    }
    else{
        //Raise the interrupt
        this->irqSignal = adr;
    }
    trans.set_response_status(tlm::TLM_OK_RESPONSE);
    return trans.get_data_length();
}
Exemple #13
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 #14
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 #15
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;
    }
void DNP_master_device::master_cb( tlm::tlm_generic_payload &arg_Req, sc_time& delay)
{
	uint32_t  addr     = (uint32_t) arg_Req.get_address();
	uint32_t  len      = (uint32_t) arg_Req.get_data_length();
	uint8_t  *data_ptr = (uint8_t *) arg_Req.get_data_ptr();

	crt_trans_id ++ ; 

	memset(recvd_data, 0, sizeof(recvd_data));

	if (arg_Req.is_read()){
		 /*
		  * Read command
		  */
		 DPRINTF("R @ 0x%08x(%d) <%d>\n", addr, len, crt_trans_id);

		 for(uint32_t i = 0; i < len; i+=4){

#ifdef DEBUG_DNP_MASTER
			  uint32_t *p = (uint32_t *)recvd_data;
#endif			  
			  send_req(crt_trans_id, (addr + i), recvd_data, 4, false);
			  
			  wait(rsp_rcvd_ev);
			  memcpy((data_ptr + i), (uint32_t *)recvd_data, 4);

			  DPRINTF("R @ 0x%08x -- %08x \n", (addr + i), *p);
		 }
	}else{
		 /*
		  * Write command
		  */
		 DPRINTF("W @ 0x%08x(%d) <%d>\n", addr, len, crt_trans_id);

		 for (uint32_t i = 0; i < len; i+=4){

#ifdef DEBUG_DNP_MASTER
			  uint32_t *p = (uint32_t *)(data_ptr + i);
#endif
			  DPRINTF("W @ 0x%08x -- %08x\n", (addr + i), *p);
			  
			  send_req(crt_trans_id, (addr + i), (data_ptr + i), 4, true);
			  wait(rsp_rcvd_ev);
		}
	}
	arg_Req.set_response_status(tlm::TLM_OK_RESPONSE);
}
Exemple #17
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;
    }
Exemple #18
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 );
  }
  virtual tlm::tlm_sync_enum nb_transport_fw( tlm::tlm_generic_payload& trans,
                                              tlm::tlm_phase& phase, sc_time& delay )
  {
    sc_dt::uint64    adr = trans.get_address();
    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 the transaction attributes for unsupported features
    // and to generate the appropriate error response
    if (byt != 0) {
      trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE );
      return tlm::TLM_COMPLETED;
    }
    if (len > 4 || wid < len) {
      trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE );
      return tlm::TLM_COMPLETED;
    }

    // Now queue the transaction until the annotated time has elapsed
    m_peq.notify( trans, phase, delay);
    return tlm::TLM_ACCEPTED;
  }
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;
}
bool IO_t_base::triggerRegistersGotHit(unsigned portIndex, tlm::tlm_generic_payload& trans) {
  mb::utl::Segment<uint64_t> transactionRange(trans.get_address(), trans.get_address() + trans.get_data_length());

  {
    if (0 == portIndex) {
      mb::utl::Segment<uint64_t> current((1 + ((0xC % 4) << 3)), (1 + ((0xC % 4) << 3)));
      mb::utl::Segment<uint64_t> intersect = transactionRange.intersect(current);
      if (!intersect.empty())
        return true;
    }
  }
  {
    if (0 == portIndex) {
      mb::utl::Segment<uint64_t> current((1 + ((0x10 % 4) << 3)), (1 + ((0x10 % 4) << 3)));
      mb::utl::Segment<uint64_t> intersect = transactionRange.intersect(current);
      if (!intersect.empty())
        return true;
    }
  }
  return false;
}
Exemple #22
0
////////////////////////////////////////////////////////////////////////////////////
// Interface function used when receiving a VCI command on the target port
// As the dated transactions on the VCI target port are used to update the local
// time when all DMA channels are IDLE, this component requires periodical
// NULL messages from the interconnect. 
////////////////////////////////////////////////////////////////////////////////////
tmpl(tlm::tlm_sync_enum)::nb_transport_fw ( tlm::tlm_generic_payload &payload,
                                            tlm::tlm_phase           &phase, 
                                            sc_core::sc_time         &time)   
{
    size_t  cell;
    size_t  reg;
    size_t  channel;

    soclib_payload_extension* extension_pointer;
    payload.get_extension(extension_pointer);
    
    // Compute global state
    bool all_idle = true;
    for( size_t k = 0 ; k < m_channels ; k++ )
    {
        if( m_state[k] != STATE_IDLE ) all_idle = false;
    }

    // update local time if all channels IDLE 
    if ( all_idle and  (m_pdes_local_time->get().value() < time.value()) )
    {
        m_pdes_local_time->set( time );
    }

    // No other action on NULL messages
    if ( extension_pointer->is_null_message() ) 
    {

#if SOCLIB_MODULE_DEBUG
std::cout << "[" << name() << "] time = "  << time.value() 
          << " Receive NULL message" << std::endl;
#endif
        return tlm::TLM_COMPLETED;
    }

    // address and length checking for a VCI command
    bool	one_flit = (payload.get_data_length() == 4);
    addr_t	address = payload.get_address();

    if ( m_segment.contains(address) && one_flit )
    {
        cell    = (size_t)((address - m_segment.baseAddress()) >> 2);
        reg     = cell % DMA_SPAN;
        channel = cell / DMA_SPAN;

        // checking channel overflow
        if ( channel < m_channels ) payload.set_response_status(tlm::TLM_OK_RESPONSE);
        else             payload.set_response_status(tlm::TLM_GENERIC_ERROR_RESPONSE);

        if ( extension_pointer->get_command() == VCI_READ_COMMAND )
        {

#if SOCLIB_MODULE_DEBUG
std::cout << "[" << name() << "] time = "  << time.value() 
          << " Receive VCI read command : address = " << std::hex << address
          << " / channel = " << std::dec << channel
          << " / reg = "  << reg << std::endl;
#endif
        
            if ( reg == DMA_SRC )
            {
                utoa( m_source[channel], payload.get_data_ptr(), 0 );
            }
            else if ( reg == DMA_DST )
            {
                utoa( m_destination[channel], payload.get_data_ptr(), 0 );
            }
            else if ( reg == DMA_LEN )
            {
                utoa( m_state[channel], payload.get_data_ptr(), 0 );
            }
            else if ( reg == DMA_IRQ_DISABLED ) 
            {
                utoa( (int)(m_irq_disabled[channel]), payload.get_data_ptr(), 0 );
            }
            else    payload.set_response_status(tlm::TLM_GENERIC_ERROR_RESPONSE);
        } // end read

        else if (extension_pointer->get_command() == VCI_WRITE_COMMAND)
        {
            uint32_t data = atou(payload.get_data_ptr(), 0);

#if SOCLIB_MODULE_DEBUG
std::cout << "[" << name() << "] time = "  << time.value() 
          << " Receive VCI write command : address = " << std::hex << address
          << " / channel = " << std::dec << channel
          << " / reg = "  << reg 
          << " / data = " << data << std::endl;
#endif
            // configuration command other than soft reset
            // are ignored when the DMA channel is active
            if ( reg == DMA_RESET )
            {
                m_stop[channel] = true;
            }
            else if ( m_state[channel] != STATE_IDLE )
            {
                if      ( reg == DMA_SRC )  m_source[channel]      = data;
                else if ( reg == DMA_DST )  m_destination[channel] = data;
                else if ( reg == DMA_LEN ) 
                {
                    m_length[channel] = data;
                    m_stop[channel]   = false;
                    m_event.notify();
                }
                else if ( cell == DMA_IRQ_DISABLED )  m_irq_disabled[channel] = (data != 0);
                else    payload.set_response_status(tlm::TLM_GENERIC_ERROR_RESPONSE);
            }
            else
            {
                std::cout << name() 
                << " warning: receiving a new command while busy, ignored" << std::endl;
            }
        } // end if write
        else // illegal command
        {
            payload.set_response_status(tlm::TLM_GENERIC_ERROR_RESPONSE);
        }
    } // end if legal address 
bool pl110_t_base::triggerRegistersGotHit(unsigned portIndex, tlm::tlm_generic_payload& trans) {
  mb::utl::Segment<uint64_t> transactionRange(trans.get_address(), trans.get_address() + trans.get_data_length());

  return false;
}
Exemple #24
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
//==============================================================================
///  @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
  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;
      }
    }
  }
tlm::tlm_sync_enum BridgeClassicToAMBATLM2<BUSWIDTH>::nb_bw_transport(tlm::tlm_generic_payload & trans, tlm::tlm_phase & ph, sc_core::sc_time &delay)
{
//  		std::cout << sc_core::sc_object::name()<< ph << std::endl;
	  	amba::amba_id * m_id;
	  	amba::amba_exclusive * m_exclusive;
	    tlm::tlm_sync_enum returnVal=tlm::TLM_ACCEPTED;
	    std::ostringstream msg;
	    msg.str("");
	    if(ph == amba::BEGIN_LAST_RESP || ph == tlm::BEGIN_RESP)
		{
			//assert(trans.get_command()==tlm::TLM_READ_COMMAND && "Write Command doesn't support the response.");
			master_sock.template get_extension<amba::amba_id>(m_id,trans);
			if (trans.is_write())
			{
//				std::cout << "TLM BEHAVIOR: received BEGIN_RESP at time " << sc_core::sc_time_stamp() << std::endl;
			  assert(ph == tlm::BEGIN_RESP);
			  assert(wr_packets[m_id->value] != NULL);
			  //as per packet.cc:74 writeback never needs a response
			  if (wr_packets[m_id->value]->cmd != MemCmd::Writeback)
			  {
					if (master_sock.template get_extension<amba::amba_exclusive>(m_exclusive,trans))
					{
						if (m_exclusive->value)
						{
							wr_packets[m_id->value]->req->setExtraData(0);
						}
						else
						{
							wr_packets[m_id->value]->req->setExtraData(1);
						}
					}
				  setCurTick(sc_core::sc_time_stamp().value());
                  wr_packets[m_id->value]->busFirstWordDelay = wr_packets[m_id->value]->busLastWordDelay = 0;
				  if (bus_stalling)
					  retryQueue.push(wr_packets[m_id->value]);
				  else if (!slavePort->sendTimingResp(wr_packets[m_id->value]))
				  {
						bus_stalling=true;
						retryQueue.push(wr_packets[m_id->value]);
				  }	
#ifdef DEBUG
				  else if (_trace_transactions)
					std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " sending a WS response to GEM5 with address=0x" << hex << trans.get_address() << dec << " size=" << trans.get_data_length() << std::endl;
#endif
			  }
			  master_sock.release_transaction(&trans); //now we release
			  wr_packets[m_id->value] = NULL;
				if (needWrIdRetry)
				{
					setCurTick(sc_core::sc_time_stamp().value());
					needWrIdRetry=false;
					slavePort->sendRetry();
				}
			}
           else if (ph == amba::BEGIN_LAST_RESP)
           {
//				std::cout << "TLM BEHAVIOR: received BEGIN_LAST_RESP at time " << sc_core::sc_time_stamp() << std::endl;
				assert(rd_packets[m_id->value] != NULL);
				uint8_t * data=trans.get_data_ptr();
				PacketPtr pkt = rd_packets[m_id->value];
				pkt->makeTimingResponse();
				uint32_t shadow_size=pkt->getSize();
				uint64_t shadow_addr=pkt->getAddr();
//				std::cout << sc_core::sc_object::name() << " bridge received read data for address = "  << trans.get_address()-pkt->getAddr() << " at time " << sc_time_stamp() << std::endl;
				memcpy(pkt->getPtr<uint8_t>(),data,pkt->getSize());
//				if (master_sock.template get_extension<amba::amba_exclusive>(m_exclusive,trans))
//				{
//					if (m_exclusive->value)
//						pkt->req->setExtraData(0);
//					else
//						pkt->req->setExtraData(1);
//				}
				setCurTick(sc_core::sc_time_stamp().value());
                pkt->busFirstWordDelay = pkt->busLastWordDelay = 0;
				if (bus_stalling)
					retryQueue.push(pkt);
				else if (!slavePort->sendTimingResp(pkt))
				{
					bus_stalling=true;
					retryQueue.push(pkt);
				}	
#ifdef DEBUG				  						  
				else if (_trace_transactions)
				{
					std::cout << "In " << sc_core::sc_object::name() << " at time " << sc_time_stamp() << " sending a READ response to GEM5 with address=0x" << hex << shadow_addr << dec << " size=" << shadow_size;
					std::cout << hex << " and data= [";
					for(unsigned j=0;j<shadow_size; j++)
						std::cout << "0x" << uint32_t(data[j]) << ",";
					std::cout << "]" << dec << std::endl;
				}
#endif
				rd_packets[m_id->value]=NULL;
				master_sock.release_transaction(&trans);
				if (needRdIdRetry)
				{
					setCurTick(sc_core::sc_time_stamp().value());
					needRdIdRetry=false;
					slavePort->sendRetry();
				}
			}
           else
           {
        	   //received a read data phase
           }
			//always accept directly (cf EagleNest spec)
//			std::cout << "TLM BEHAVIOR: sending  TLM_UPDATED & END_RESP at time " << sc_core::sc_time_stamp() << std::endl;
            ph=tlm::END_RESP;
			return tlm::TLM_UPDATED;
		}
	    else if(ph ==tlm::END_REQ)
	    { 
//			std::cout << "TLM BEHAVIOR: received END_REQ and returning TLM_ACCEPTED at time " << sc_core::sc_time_stamp() << std::endl;
			if (needRetry)
			{
				setCurTick(sc_core::sc_time_stamp().value());
				trans.release();
				needRetry=false;
				slavePort->sendRetry();
			}
	    }
		else if(ph== amba::END_DATA )
		{
//			std::cout << "TLM BEHAVIOR: received END_DATA and returning TLM_ACCEPTED at time " << sc_core::sc_time_stamp() << std::endl;
			if (need_wenable_event)
			{
				need_wenable_event=false;
            	wenable_event.notify();
			}
			return tlm::TLM_ACCEPTED;
		}
		else
				assert("Unexpected phase returned from AXI slave.");	
		return returnVal;
}
Exemple #28
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);

  }
}