Pruthvi015 Posted January 2, 2015 Report Posted January 2, 2015 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 Quote
apfitch Posted January 2, 2015 Report Posted January 2, 2015 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 Quote
Pruthvi015 Posted January 3, 2015 Author Report Posted January 3, 2015 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 Quote
apfitch Posted January 3, 2015 Report Posted January 3, 2015 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 Pruthvi015 1 Quote
David Black Posted January 3, 2015 Report Posted January 3, 2015 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. Pruthvi015 1 Quote
Pruthvi015 Posted January 5, 2015 Author Report Posted January 5, 2015 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 Quote
Pruthvi015 Posted January 5, 2015 Author Report Posted January 5, 2015 Hi David, Thanks for technical details . I'm running under loop.How can i reuse the payload(I need serial transmission). Thanks, Pruthvi Quote
howardhsu Posted January 5, 2015 Report Posted January 5, 2015 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. Quote
Pruthvi015 Posted January 5, 2015 Author Report Posted January 5, 2015 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 Quote
apfitch Posted January 5, 2015 Report Posted January 5, 2015 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. Quote
Pruthvi015 Posted January 5, 2015 Author Report Posted January 5, 2015 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 Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.