I am a relatively newbie to UVM coding. I am aware of overall flow. I have a question here.
I am writing UVM testbench for BRAM :
RTL is:
// Write logic
always @(posedge clk)
if(wr_en)
mem[wr_addr] <= wr_data;
//Read logic
always @(posedge clk)
rd_data = mem[rd_addr];
i.e rd_data is available in next clock cycle for the given read_addr continuously.
But when i try to sample this rd_data in monitor, I may lose data on some clocks.
Here is my seq_item and UVM monitor code:
class ram_seq_item extends uvm_sequence_item;
//data and control fields
rand bit wr_en;
rand bit [ADDR-1:0] wr_addr;
rand bit [DATA-1:0] wr_data;
rand bit [ADDR-1:0] rd_addr;
bit [DATA-1:0] rd_data;
:
:
:
endclass
class ram_monitor extends uvm_monitor;
uvm_analysis_port #(ram_seq_item) sampled_collect_port;
virtual ram_if vif;
ram_seq_item trans_collected;
:
:
:
virtual task run_phase(uvm_phase phase);
forever begin
@(posedge vif.MONITOR.clk);
// write transaction
if(vif.monitor_cb.wr_en) begin
trans_collected.wr_addr = vif.monitor_cb.wr_addr;
trans_collected.wr_en = vif.monitor_cb.wr_en;
trans_collected.wr_data = vif.monitor_cb.wr_data;
end
//read transaction
trans_collected.rd_addr = vif.monitor_cb.rd_addr;
@(posedge vif.MONITOR.clk);
trans_collected.rd_data = vif.monitor_cb.rd_data;
end
sampled_collect_port.write(trans_collected);
end
endtask : run_phase
In above case, when i wait for 1 clock to collect rd_data from DUT, i might miss read sampling for that clock cycle, right? Though, I can take care of write transaction easily, thinking about read transaction.
How do i overcome that?
can’t we do continuous reads? i think, this shouldn’t be the case.
Any lead to solve above problem would be appreciated.
Thanks in advance