Jump to content
Pruthvi015

Problem in TLM READ command

Recommended Posts

Hi all,

 

I'm getting problem in TLM read command .Please check the code once is am doing right ?Then why it's not reading correct value's?

 

  In read function.....i'm going through b_transport....

 

    tlm::tlm_generic_payload* trans=new tlm::tlm_generic_payload;
    sc_time delay=sc_time(0,SC_NS);
    trans->set_command(tlm::TLM_READ_COMMAND);
    trans->set_address(addr);
    if((dmi_valid)&&(addr >=dmi_data.get_start_address()) && (addr<=dmi_data.get_end_address())){
        SC_REPORT_INFO_VERB("Traffic_injector","dmi access",2);
    }else {
        SC_REPORT_INFO_VERB("traffic injector","READ:normal access....",2);
        trans->set_data_ptr(reinterpret_cast<unsigned char*>(data));
        trans->set_data_length(length);
        trans->set_byte_enable_ptr(0);
        trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
        initiator_socket->b_transport(*trans,delay);
        if(trans->is_response_error()){
            SC_REPORT_ERROR("TLM-2","response error from b_transport");
        }
        unsigned char* data_ptr=trans->get_data_ptr();

 

 

  In b_transport ....

      tlm::tlm_command cmd=trans.get_command();
      uint8_t addr=trans.get_address();
      unsigned char* data_ptr=trans.get_data_ptr();
      unsigned int len=trans.get_data_length();
        
      if(cmd==tlm::TLM_READ_COMMAND){
        
            bool flag=(bool)((device_rx_data[addr]>>len)& 0x1);

             data_ptr=reinterpret_cast<unsigned char*>(&flag);

      }
 

 

In b_transport it setting correct values to data_ptr (as am checked in debugger).But in read

    unsigned char* data_ptr=trans->get_data_ptr();

am getting always zero...Is am doing right casting ?If not tell correct path?

 

Thanks,

Pruthvi

 

Share this post


Link to post
Share on other sites

I guess my first question is are you using DMI or not? Because you don't seem to have any code to actually implement the DMI.

 

Assuming you're not using DMI (dmi_valid is false), my second question is what is the data type of "data" - int? I assume you're using something like int but treating it as a 4 character array?

 

Thirdly, in b_transport, where are you looking at the contents of data_ptr?

 

In the case of a read command, you seem to be overwriting data_ptr, which is bad. The data_ptr value shouldn't be modified.

 

Using uint8_t for the address is potentially misleading, as the address is 64 bit.

 

What I'd expect is code something like

if(cmd==tlm::TLM_READ_COMMAND){

             data_ptr[0] = device_rx_data[addr]>>len)& 0x1;

}

Though if the original data is something like int, you'll have to think about endianness.

 

regards

Alan

Share this post


Link to post
Share on other sites

Hi Alan,

 

Thanks for replay.

1.I'm not using DMI(dmi_valid=false)

2.datatype of data is bool.

3.I'm reading bit by bit through b_transport.

   In TLM_READ_COMMAND){
        
            bool flag=(bool)((device_rx_data[addr]>>len)& 0x1);

             data_ptr=reinterpret_cast<unsigned char*>(&flag);       }

 

 Above code am converting byte to bit and am setting that bit address to data_ptr.(It is doing correctly as per my need by in other side i.e unsigned char* data_ptr=trans->get_data_ptr() is getting always zero )

 

Thanks,

Pruthvi

Share this post


Link to post
Share on other sites

I don't know how specific compilers implement bool, but the C++ standard says its size is unspecified, so I probably wouldn't rely on bool to carry the data. I would declare a an array of char, e..g

 

unsigned char data[1];

 

The other thing I don't understand is your use of len. The length is the number of characters in the data array, so in your example I would always expect trans->set_data_length(1), since a bool value will fit into 1 character. You seem to be using set_data_length() to specify a bit index. There's no support for bit addressing in the TLM payload.

 

If you want to read a particular bit, you either need to work out the address that contains that bit, retrieve a character, and then mask the value you want; or create an extension to the TLM2 payload to specify the bit you want.

 

Whatever you do, the TLM2 payload always moves an array of characters; and the address in the payload points to a particular character.

 

regards

Alan

Share this post


Link to post
Share on other sites

Not related to your problems, but perhaps important as you continue to devleop...

 

Technical detail - TLM 2.0 requires that you:

1. Prior to sending specify 8 attributes in the payload. You are missing the streaming width and DMI hint.

2. Check to ensure the payload matches the attributes of your target

 

Also,

tlm::tlm_generic_payload* payload_ptr = new tlm::tlm_generic_payload;

is very expensive (computation time), so I would encourage you to reuse the payload object if this code is inside a loop rather than generating a new one each time.

Share this post


Link to post
Share on other sites

Hi Alan,

 

I'm typecasting bool to unsigned char(trans->set_data_ptr(reinterpret_cast<unsigned char*>(data)) data is bool type.

 

And len will increase one every time(0 to 8) reading under loop.I did same thing in write command it's working fine.

 

And i have to read bit by bit as per spec.

 

Thanks,

Pruthvi

Share this post


Link to post
Share on other sites

I think you should assign value to the variable that data pointer in the payload point to, instead to set the data pointer to point to your local variable address. 

 

      if(cmd==tlm::TLM_READ_COMMAND){

        
            bool flag=(bool)((device_rx_data[addr]>>len)& 0x1);

             data_ptr=reinterpret_cast<unsigned char*>(&flag);   //---> *data_ptr =  static_cast<unsigned char>(flag); or something

      }
 

Because the lifetime of "flag" only inside the braces. You shouldn't use its address outside the if statement.

Share this post


Link to post
Share on other sites

Hi all,

 

         if(cmd==tlm::TLM_READ_COMMAND){

 

                   flag=(bool)((device_rx_data[addr]>>len)& 0x1);
                   data_ptr=reinterpret_cast<unsigned char*>(&flag);
                   trans.set_data_ptr(reinterpret_cast<unsigned char*>(*data_ptr));

         }

 

       Right now am getting correct values as per my need .But is this is correct path(setting again data_ptr ) ?

 

Thanks,

Pruthvi

Share this post


Link to post
Share on other sites

It depends what you mean by "correct". The standard says that the target should not modify the data ptr, so you are not following the standard - see Table 54 of 1666-2011.

Also as I said before, you're misusing the length attribute, it indicates the length of the payload in bytes, and in your case should always be 1.

 

You seem to be modelling a bit-addressable bus. TLM2 wasn't designed to do that, it was designed with bus widths that are a multiple of 1 byte.

 

kind regards

 

Alan

 

P.S. I'd also be interested to see a real bus that addresses to the bit level.

Share this post


Link to post
Share on other sites

Hi Alan,

 

That i know i.e not following as per standard.(i tried in one way so it's getting as per my expectation)

 

Second length i need always one.I changed the logic

 

  i.e uint8_t data=(0x01 & (bool)((device_rx_data[addr])& 0x1)).

   

   every time device_rx_data will be shifted by one as per the address.

 

Now am transferring byte type and I'm getting same output (not my expectation)  

 

Thanks,

Pruthvi

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×