void peq_cb(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase)
  {
    #ifdef DEBUG
      if (phase == tlm::END_REQ)
        fout << hex << trans.get_address() << " " << name() << " END_REQ at " << sc_time_stamp() << endl;
      else if (phase == tlm::BEGIN_RESP)
        fout << hex << trans.get_address() << " " << name() << " BEGIN_RESP at " << sc_time_stamp() << endl;
    #endif

    if (phase == tlm::END_REQ || (&trans == request_in_progress && phase == tlm::BEGIN_RESP))
    {
      // The end of the BEGIN_REQ phase
      request_in_progress = 0;
      end_request_event.notify();
    }
    else if (phase == tlm::BEGIN_REQ || phase == tlm::END_RESP)
      SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by initiator");

    if (phase == tlm::BEGIN_RESP)
    {
      check_transaction( trans );

      // Send final phase transition to target
      tlm::tlm_phase fw_phase = tlm::END_RESP;
      sc_time delay = sc_time(rand_ps(), SC_PS);
      socket->nb_transport_fw( trans, fw_phase, delay );
      // Ignore return value
    }
  }
Exemple #2
0
 virtual void b_transport(int socketId, tlm::tlm_generic_payload& trans, sc_time & delay) {
     // if the address is in range
     if (trans.get_address() <= MAX_ADDRESS) {
         //forward the message
       (*init_sock[trans.get_address()])->b_transport(trans, delay);
   
     } else {
         //else error status
         trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
     }
     
 }
  // Tagged non-blocking transport forward method
  virtual tlm::tlm_sync_enum nb_transport_fw(int id,
      tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay)
  {
    assert (id < targ_socket.size());

    // Forward path
    m_id_map[ &trans ] = id;

    sc_dt::uint64 address = trans.get_address();
    sc_dt::uint64 masked_address;
    unsigned int target_nr = decode_address( address, masked_address);

    if (target_nr < init_socket.size())
    {
      // Modify address within transaction
      trans.set_address( masked_address );

      // Forward transaction to appropriate target
      tlm::tlm_sync_enum status = init_socket[target_nr]->nb_transport_fw(trans, phase, delay);

      if (status == tlm::TLM_COMPLETED)
        // Put back original address
        trans.set_address( address );
      return status;
    }
    else
      return tlm::TLM_COMPLETED;
  }
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
    //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);
    }
//==============================================================================
///  @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 #8
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 {
Exemple #9
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
  // Tagged debug transaction method
  virtual unsigned int transport_dbg(int id, tlm::tlm_generic_payload& trans)
  {
    sc_dt::uint64 masked_address;
    unsigned int target_nr = decode_address( trans.get_address(), masked_address );
    if (target_nr >= init_socket.size())
      return 0;
    trans.set_address( masked_address );

    // Forward debug transaction to appropriate target
    return init_socket[target_nr]->transport_dbg( trans );
  }
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 #12
0
void FastBus::b_transport(tlm::tlm_generic_payload &trans,
                          sc_core::sc_time &t) {
	ensitlm::addr_t a = trans.get_address();
	addr_map_t::iterator it = addr_map.find(addr_range(a, a));
	if (it == addr_map.end()) {
		std::cerr << name() << ": no target at address "
		          << std::showbase << std::hex << a << std::endl;
		trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
		return;
	}
	trans.set_address(a - (*it).first.begin);
	initiator[(*it).second]->b_transport(trans, t);
}
  // Tagged non-blocking transport backward method
  virtual tlm::tlm_sync_enum nb_transport_bw(int id,
      tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay)
  {
    assert (id < init_socket.size());

    // Backward path

    // Replace original address
    sc_dt::uint64 address = trans.get_address();
    trans.set_address( compose_address( id, address ) );

    return targ_socket[ m_id_map[ &trans ] ]->nb_transport_bw(trans, phase, delay);
  }
  // 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 );
  }
Exemple #15
0
void leon3_funclt_trap::IntrTLMPort_32::b_transport( int tag, tlm::tlm_generic_payload \
    & trans, sc_time & delay ){
    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);
}
//==============================================================================
///  @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
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 #18
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 #19
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 #20
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 #22
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;
    }
bool                                            
lt_dmi_target::get_direct_mem_ptr    
( tlm::tlm_generic_payload   &gp              ///< address + extensions
, tlm::tlm_dmi               &dmi_properties  ///< dmi data
)
{
  std::ostringstream  msg;
  msg.str("");
  sc_dt::uint64 address = gp.get_address();
  
  // First check to see if we are "open" to a dmi
  if(!m_dmi_enabled)
  {
    msg << "Target: " << m_ID
        << " DMI not enabled, not expecting call ";
    REPORT_INFO(filename, __FUNCTION__, msg.str());
  }
  else
  {                                  // dmi processing
    if (address < m_end_address+1)   // check that address is in our range              
    {
      // set up dmi properties object ======================================
      dmi_properties.allow_read_write   (                                );
      dmi_properties.set_start_address  ( m_start_address                );
      dmi_properties.set_end_address    ( m_end_address                  );
      dmi_properties.set_dmi_ptr        ( m_target_memory.get_mem_ptr () );
      dmi_properties.set_read_latency   ( m_read_response_delay          );
      dmi_properties.set_write_latency  ( m_write_response_delay         );

      msg << "Target: " << m_ID
          << " passing DMI pointer back to initiator";
      REPORT_INFO(filename, __FUNCTION__, msg.str());
      return true;
    }
    else
    {
      msg << "Target: " << m_ID
          << " DMI pointer request for address= " << address
          << " max address for this target = " << m_end_address+1;
      REPORT_INFO(filename, __FUNCTION__, msg.str());
    } // end else
  } // end else
  
  return false; 
} // end get_direct_mem_ptr
  // Tagged TLM-2 forward DMI method
  virtual bool get_direct_mem_ptr(int id,
                                  tlm::tlm_generic_payload& trans,
                                  tlm::tlm_dmi&  dmi_data)
  {
    sc_dt::uint64 masked_address;
    unsigned int target_nr = decode_address( trans.get_address(), masked_address );
    if (target_nr >= init_socket.size())
      return false;

    trans.set_address( masked_address );

    bool status = init_socket[target_nr]->get_direct_mem_ptr( trans, dmi_data );

    // Calculate DMI address of target in system address space
    dmi_data.set_start_address( compose_address( target_nr, dmi_data.get_start_address() ));
    dmi_data.set_end_address  ( compose_address( target_nr, dmi_data.get_end_address() ));

    return status;
  }
bool ram::get_direct_mem_ptr(tlm::tlm_generic_payload &trans, tlm::tlm_dmi &dmi_data)
{
    sc_dt::uint64 address = trans.get_address();
    if (address > m_high_address) {
        // should not happen
        cerr << "ram::get_direct_mem_ptr: address overflow";
        return false;
    }

    // if (m_invalidate) m_invalidate_dmi_event.notify(m_invalidate_dmi_time);
    dmi_data.allow_read_write();
    dmi_data.set_start_address(0x0);
    dmi_data.set_end_address(m_high_address);

    unsigned char *ptr = m_target_memory.get_mem_ptr();
    trans.set_dmi_allowed(m_dmi_on);
    dmi_data.set_dmi_ptr(ptr);
    return true;
}
  // 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();
  }
  // Tagged TLM-2 blocking transport method
  virtual void b_transport( int id, tlm::tlm_generic_payload& trans, sc_time& delay )
  {
    assert (id < targ_socket.size());

    // Forward path
    sc_dt::uint64 address = trans.get_address();
    sc_dt::uint64 masked_address;
    unsigned int target_nr = decode_address( address, masked_address);

    if (target_nr < init_socket.size())
    {
      // Modify address within transaction
      trans.set_address( masked_address );

      // Forward transaction to appropriate target
      init_socket[target_nr]->b_transport(trans, delay);

      // Replace original address
      trans.set_address( address );
    }
  }
Exemple #28
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;
}