mbowler Posted November 22, 2011 Report Posted November 22, 2011 So my register to bus adapter came across an unexpected value in the uvm_reg_bus_op::kind field... UVM_BURST_WRITE. According to the class reference the uvm_access_e enumeration only has two values (UVM_READ and UVM_WRITE). What is to be done with this value? If I treat it the same as UVM_WRITE I get an interesting sequence of transactions which are generated by a uvm_mem::burst_write() call which is trying to burst 6 32-bit words, offset 0x388 on a memory mapped at 0xc4000. //My data array to be bursted. 525705 TESTCASE: reg_data[0] = 0x0000000029f79058 525705 TESTCASE: reg_data[1] = 0x00000000982bcf4c 525705 TESTCASE: reg_data[2] = 0x00000000031101fe 525705 TESTCASE: reg_data[3] = 0x000000007f494bbb 525705 TESTCASE: reg_data[4] = 0x00000000f268f9cf 525705 TESTCASE: reg_data[5] = 0x000000007414996a //The six uvm_reg_bus_op transactions that the uvm_reg_adapter::reg2bus method sees: 525705 EB_REG_ADAPT: TESTCASE: UVM_BURST_WRITE addr=0x00000000000c4388, data=0x0000000029f79058, n_bits=32 525725 EB_REG_ADAPT: TESTCASE: UVM_BURST_WRITE addr=0x00000000000c438c, data=0x0000000000000000, n_bits=0 525745 EB_REG_ADAPT: TESTCASE: UVM_BURST_WRITE addr=0x00000000000c4390, data=0x0000000000000000, n_bits=32 525765 EB_REG_ADAPT: TESTCASE: UVM_BURST_WRITE addr=0x00000000000c4394, data=0x0000000000000000, n_bits=32 525785 EB_REG_ADAPT: TESTCASE: UVM_BURST_WRITE addr=0x00000000000c4398, data=0x0000000000000000, n_bits=32 525805 EB_REG_ADAPT: TESTCASE: UVM_BURST_WRITE addr=0x00000000000c439c, data=0x0000000000000000, n_bits=32 All have the expected addresses. I like the first transaction. The second one has n_bits set to 0 which is unexpected. The third through 6th have n_bits back at 32, but the data field is full of zeros in each case. What is the register adapter supposed to do with a uvm_reg_bus_op::kind of UVM_BURST_WRITE? I cannot find any examples of this in the 1.1 reference implementation. Thanks, Michael Quote
mbowler Posted November 30, 2011 Author Report Posted November 30, 2011 Bumping this thread. There is either a bug in the base class library itself or the documentation, as this value is outside of the documented set. Which is it? Quote
uwes Posted December 1, 2011 Report Posted December 1, 2011 hi, can you supply a testcase or state your memory configuration? Quote
amitshere Posted December 2, 2011 Report Posted December 2, 2011 Are you sure you didn't call a mem.burst_write(...) anywhere in the code Quote
mbowler Posted December 8, 2011 Author Report Posted December 8, 2011 Actually I did call mem.burst_write() as per the original post. According to the class reference manual (v1.1) page 486, uvm_kind_e has two values (READ and WRITE). According to the source code (v1.1): typedef enum { UVM_READ, UVM_WRITE, UVM_BURST_READ, UVM_BURST_WRITE } uvm_access_e; So either the source code is incorrect, or the document is incorrect. I assume it is the documentation. I am looking for a description (or example) of what the other two values mean and what the intended behaviour a register adapter is supposed to follow when seeing these two undocumented values. Quote
amitshere Posted December 9, 2011 Report Posted December 9, 2011 Yes, I guess it should have gone to the documentation; But again I wouldn't think that the adapter would need to do anything different for a UVM_BURST_WRITE vis-a-vis a UVM_WRITE.. I Whenever you have a mem.burst_write(), the base class infrastructure ensures that as many regular writes that are required are scheduled.. The Adapter would know that the current transaction would be part of a memory burst.. It might addtionally want to set specific properties in the host transaction item.. Quote
amitshere Posted December 12, 2011 Report Posted December 12, 2011 The adapter should translate it to a burst-write protocol-specific transaction whenever it sees a UVM_BURST_READ/WRITE If the protocol does not support burst operations, you would have to use the layering approach and execute it in terms of individual transactions. Quote
mbowler Posted December 23, 2011 Author Report Posted December 23, 2011 I dove into the UVM code, and found what I believe are issues with the uvm_reg_map::do_bus_write method. Essentially two variable are not being initialized properly on entry to the uvm_reg_map::do_bus_write::foreach_addr loop (n_bits and curr_byte), so that any burst with more than one element in the data array fails with the bizarre behaviour I was observing. The following patch seems to fix it, and now things seem to be working how I would expect. (It is hard to tell though because the documentation is so sparse on this I do not know what the design intention is). diff uvm_reg_map.svh 1794a1795 > int n_bits_init; 1800c1801 < Xget_bus_infoX(rw, map_info, n_bits, lsb, skip); --- > Xget_bus_infoX(rw, map_info, n_bits_init, lsb, skip); 1817c1818 < n_access = n_access_extra + n_bits; --- > n_access = n_access_extra + n_bits_init; 1824c1825 < temp_be += n_bits; --- > temp_be += n_bits_init; 1832c1833 < while (addrs.size() > (n_bits/(bus_width*8) + 1)) --- > while (addrs.size() > (n_bits_init/(bus_width*8) + 1)) 1835a1837,1838 > curr_byte = 0; > n_bits = n_bits_init; Quote
clacasse Posted January 17, 2012 Report Posted January 17, 2012 Hi mbowler, I have experienced the same data oddities as you, and posted with example code in August 2011 Posting. I came to the same conclusion as you with a very similar patch and everything has been working for months now. Maybe with more attention this bug will be fixed. Good luck, Chris 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.