Exemplo n.º 1
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 {
Exemplo n.º 2
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);
    }
Exemplo n.º 3
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;
    }
Exemplo n.º 4
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() / 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 );
  }
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
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;
	}
	
}
Exemplo n.º 7
0
  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 );
  }
Exemplo n.º 8
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) || 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 );
  }
Exemplo n.º 9
0
//==============================================================================
//  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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
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);
     }
     
 }
Exemplo n.º 12
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 );
  }
Exemplo n.º 13
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);
}
Exemplo n.º 14
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);
}
Exemplo n.º 15
0
  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;
  }
Exemplo n.º 16
0
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;
}
Exemplo n.º 17
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;
        }
    }
Exemplo n.º 18
0
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);
}
Exemplo n.º 19
0
//! @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()
Exemplo n.º 20
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 
Exemplo n.º 21
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
Exemplo n.º 22
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);
		}

	}
Exemplo n.º 23
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:

      #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;
      }
    }
  }
Exemplo n.º 24
0
//==============================================================================
///  @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
Exemplo n.º 25
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);

  }
}