Search the Community
Showing results for tags 'uvm_field'.
Found 1 result
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