jordan Posted June 30, 2015 Report Share Posted June 30, 2015 Hi, While debugging a prediction error returned by "Bit Bashing Test Sequence", I came to read the uvm_reg_map::do_bus_read/do_bus_write methods which seems incorrect when it comes to computing the "byte enable" for the bus accesses (ie data member "byte_en" of the object of type uvm_bus_reg_op created by those functions) I'm explain the issue that I think I found here-below, can you please give me your feedback (Am i wrong or not?) My understanding about "uvm_reg_map::do_bus_read/do_bus_write" methods about is that these methods are called when I request a frontdoor read/write access and I don't supply a user frontdoor sequence. these methods aimed at splitting the high level object uvm_reg_item into as many uvm_bus_reg_op as need on the real bus. part of their role is to compute bus lane "byte enable" based on length and base address for a UVM_REG and length, base address and field offset in the reg for a UVM_FIELD The "uvm_reg_map::do_bus_read/do_bus_write" code extract I'm interested in here given here below with focus on bus byte enable (rw_access.byte_en) computation: task uvm_reg_map::do_bus_write (uvm_reg_item rw, uvm_sequencer_base sequencer, uvm_reg_adapter adapter); [...] uvm_reg_byte_en_t byte_en = -1; // <= here the default value of byte_en is set to 'all ones' [...] foreach (rw.value[val_idx]) begin: foreach_value [...] /* calculate byte_enables */ if (rw.element_kind == UVM_FIELD) begin // <= here byte_en is re-computed for UVM_FIELD only, not for UVM_REG [...] end [...] foreach(addrs[i]) begin: foreach_addr [...] uvm_reg_bus_op rw_access; [...] if (rw.element_kind == UVM_FIELD) begin // <= here the slice of the computed byte_en corresponding to // the current bus address is applied to the bus (rw_access.byte_en) // for UVM_FIELD only, not for UVM_REG for (int z=0;z<bus_width;z++) rw_access.byte_en[z] = byte_en[curr_byte+z]; end [...] rw_access.byte_en = byte_en; // <= here for UVM_REG, the default 'all ones' byte_en value is applied // and for UVM_REG, the correct value of rw_access.byte_en assigned above is // erroneously overwritten [...] end: foreach_addr [...] end: foreach_value endtask: do_bus_write But the extract of code here-below shows two issues: for a read/write to a UVM_REG, the byte_en is hard coded to "all ones" which seems incorrect to me in at least 2 cases: if the bus is 4-Byte wide, a register R1 to write is 1-Byte wide and at address 1 and another register R0 is also 1-Byte wide and located at address 0, then trying to write R1, will also write R0. if the bus is 4-Byte wide, a register R0 to write is 6-Byte wide and at address 0 and another register R1 is 1-Byte wide and located at address 6, then trying to write R0, will also write R1. for a read/write to a UVM_FIELD, there's a complex computation of byte_en for the whole field , then another computation to extract the correct bus byte enable from the whole field byte_enable. Those 2 computations seems correct to me but the last assignemnt "rw_access.byte_en = byte_en;" breaks everything by systematically setting the same bus byte enables value. For a field spanning several bus addresses this is correct/acceptable for the first bus access but this incorrect for the other bus accesses. Any feedback welcome, thank you Jordan Quote Link to comment Share on other sites More sharing options...
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.