I am working on a module level UVM TB for an up/down counter.
Counter is loaded on clk if load_counter=1. But the counter is incremented/decremented on run_counter(clk_en). Clk_en is derived from clk.
On TB side, i need to validate DUT outputs, count_reached(generated on clk) and current_value(generated on run_counter).
I have a clocking block that works on clk. Since scoreboard needs run_counter(clk_en) input to run a local counter, i have passed clk_en(as run_counter) through virtual interface in driver.
The issue i observe here is:
There is an offset of 1 clk between run_counter seen by TB(print statements in monitor) and RTL.
The first run_counter(==1) seen by RTL is at 45ps where as TB debug message shows it to be at 55ps. Because of this, I see counter value mismatch .
Please let me know, what could be the issue here.
P.S: clk_en is generated in CLK_EN module on negedge of clk. I have tried to change the module locally to generate clk_en on posedge and have not seen any difference with run_counter(clk_en) on TB/RTL side.
Below is my DRIVER code:
virtual task drive();
@( counter_vif.counter_cb);
if (counter_vif.reset ==1) begin
counter_vif.counter_cb.load_counter <= req.load_counter;
counter_vif.counter_cb.count_value <= req.count_value;
counter_vif.counter_cb.up_counter <= req.up_counter;
counter_vif.counter_cb.inc <= req.inc;
counter_vif.counter_cb.run_counter <= counter_vif.clk_en;
end //if
Endtask
Here is the MONITOR code:
virtual task run_phase(uvm_phase phase);
super.run_phase(phase);
forever begin
wait(counter_vif.reset == 1);
if (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.run_counter = counter_vif.run_counter;
`uvm_info("MONITOR DEBUG2",$sformatf("counter_vif.load_counter = %b, counter_vif.run_counter=%b",counter_vif.load_counter, counter_vif.run_counter), UVM_LOW)
// sample the signals
@(counter_vif.counter_cb);
// checkon run_counter-----------
if (counter_vif.run_counter)
seq_item_collected.current_value = counter_vif.counter_cb.current_value;
// --- check on every clock-----
seq_item_collected.count_reached = counter_vif.counter_cb.count_reached;
trans_collected_port.write(seq_item_collected);
end // reset
end //forever
endtask : run_phase
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 run_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 run_counter;
inout inc;
input current_value;
input count_reached;
endclocking
endinterface