Clocking block in UVM TB

I had raised a question in below post regarding clocking block. I got great inputs. I have updated my TB now.
Old post is here:
https://verificationacademy.com/forums/uvm/effect-clocking-block-uvm-driver/monitor
Sorry, now I am kind of stuck with some other issue. I have many other modules to be updated. So wanted to have a clear understanding before making any changes.

interface updn_counter_if(input logic clk, reset, clk_en);
logic [ABSOLUTE_DATA_WIDTH-1:0] count_value;
logic load_counter;
logic up_counter;
logic [1:0] inc;
logic [ABSOLUTE_DATA_WIDTH-1:0] current_value;
logic count_reached;

clocking counter_cb @(posedge clk);
default input #1step output #1;
inout load_counter;
inout count_value;
inout up_counter;
inout inc;
input current_value;
input count_reached;
endclocking
endinterface

DRIVER
virtual task drive();
@( counter_vif.counter_cb);
if (counter_vif.clk_en == 1 && counter_vif.reset) begin
counter_vif.counter_cb.count_value <= req.count_value;
counter_vif.counter_cb.load_counter <= req.load_counter;
counter_vif.counter_cb.up_counter <= req.up_counter;
counter_vif.counter_cb.inc <= req.inc;
end //if
endtask

MONITOR
virtual task run_phase(uvm_phase phase);
super.run_phase(phase);
forever begin
@(counter_vif.counter_cb);
//@(posedge counter_vif.clk);
if (counter_vif.clk_en && counter_vif.reset == 1) begin
seq_item_collected.count_value = counter_vif.count_value;
seq_item_collected.load_counter = counter_vif.load_counter;
seq_item_collected.up_counter = counter_vif.up_counter;
seq_item_collected.inc = counter_vif.inc;

 seq_item_collected.current_value = counter_vif.counter_cb.current_value;
 seq_item_collected.count_reached = counter_vif.counter_cb.count_reached;

 trans_collected_port.write(seq_item_collected);
end  //    

end //forever
endtask : run_phase

If i specify input skew in clocking clock to be zero, my data integrity looks fine. If i specify it to be non-zero, there is an offset of 1 value between RTL and TB.

  1. IS it because the RTL value is sampled just before the clock edge and takes the previous value? Do we update our TB accordingly?
  2. Should things change if input skew is zero amd non-zero? I mean, for non-zero it gets the value from previous clock?
  3. Do we have take any precautions while handling clk_en which is not part of clocking block?
    Please let me know. Thank you!

In reply to uvmsd:

Chapter 14 of the IEEE SystemVerilog Language Standard provides all the information you need:

The clocking_skew determines how many time units away from the clock event a signal is to be sampled or driven. Input skews are implicitly negative, that is, they always refer to a time before the clock, whereas output skews always refer to a time after the clock (see 14.4). When the clocking event specifies a simple edge, instead of a number, the skew can be specified as the specific edge of the signal. A single skew can be specified for the entire block by using a default clocking item.

In reply to cgales:
@cgales

Does “A single skew can be specified for the entire block by using a default clocking item.”
mean, @( counter_vif.counter_cb); would apply to the following driving/sampling instructions, right?
I think, I still need some clarification.
My question was:
Is that expected behavior, if current_value from counter gives previous value when input sklew is non-zero?

With input skew =0, I have no issues.
I am facing data integrity issue in TB with non-zero skew since TB counter increments on every clock and RTL also does the same. But when i sample RTL value, I am getting previous value with non-zero skew.
Do i need to adjust my data integrity checking accordingly? or am i missing something?