Jump to content

Register Bus adapter: UVM_BURST_WRITE


Recommended Posts

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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..

Link to comment
Share on other sites

  • 2 weeks later...

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;

Link to comment
Share on other sites

  • 4 weeks later...

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...