Incorrect function bus2reg for UART

I tried to write function bus2reg for UART For write data to register i should receive 3 transactions

1 transaction - write(0x1)/read(0x1).
2 transaction - address.
3 transaction - data.

my function bus2reg


function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);

  uart_item uart_item_reg;

  if(!$cast(uart_item_reg, bus_item))
  `uvm_fatal(get_name(), "$cast is failed")
  
  case ({first_step,second_step})
    2'b11: begin
              rw.data = uart_item_reg.data;
              rw.addr = tx_addr;

              second_step = 0;
              first_step  = 0;
          end

    2'b10: begin
              tx_addr = uart_item_reg.data;
              second_step = 1;
    end

    default: begin
             if(uart_item_reg.data==1) begin // read transaction
              first_step = 1;
             end
    end
    endcase 

endfunction

IN this case when i do two actions write to registers


ral_model.r1.write (status, 'hFF);
ral_model.r2.write (status, 'hFF);

When i use function get_mirrored_value() i see next →


UVM_INFO uart_test.sv(118) @ 3828: uvm_test_top [uvm_test_top] ral_model.r2.get_mirrored_value(): FF
UVM_INFO uart_test.sv(119) @ 3828: uvm_test_top [uvm_test_top] ral_model.r1.get_mirrored_value(): 0

I think it’s because inside function bus2reg i rewrite value register r1 after first transaction (for register r2)

i did next logic in my project for resolve this problem but i think it is not correct


// ----------------------------------------------------------------------------
// function bus2reg
// ----------------------------------------------------------------------------
function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);

  uart_item uart_item_reg;

  if(!$cast(uart_item_reg, bus_item))
  `uvm_fatal(get_name(), "$cast is failed")
  
  **rw.status = UVM_NOT_OK;**
  case ({first_step,second_step})
    2'b11: begin
              rw.data = uart_item_reg.data;
              rw.status = UVM_IS_OK;
              rw.addr = tx_addr;
              second_step = 0;
              first_step  = 0;
          end

    2'b10: begin
              tx_addr = uart_item_reg.data;
              second_step = 1;
    end

    default: begin
             if(uart_item_reg.data==1) begin
              first_step = 1;
             end
    end
    endcase 

    **if(rw.status != UVM_IS_OK) begin
      rw.addr = 'hFF;
      rw.data = 'h00;
    end**
endfunction

After this logic i see next


UVM_INFO uart_test.sv(118) @ 3828: uvm_test_top [uvm_test_top] ral_model.r2.get_mirrored_value(): FF
UVM_INFO uart_test.sv(119) @ 3828: uvm_test_top [uvm_test_top] ral_model.r1.get_mirrored_value(): FF

Could you help me - is it correct for function bus2reg?


**if(rw.status != UVM_IS_OK) begin
  rw.addr = 'hFF;
  rw.data = 'h00;
end**

Project in EDA UART_UVM_2.1_frondoor_seq - EDA Playground

In reply to kkurenkov:

It’s not really clear what you are trying to accomplish.

It appears that you are trying to read/write registers using 3 individual UART transactions. Is this correct?

If this is the case, then you want to look at using layered sequences to translate an individual register read/write into the required UART transactions. You will then implement the register adapter for the higher level sequence item and not the low-level UART sequence items.

In reply to cgales:

Yes, you understand me correct - i try to read/write registers using 3 individual UART transactions.

Thank you for advice about layered sequences.