Interface and driver component of Dual Port RAM is not working properly

Hi All,
I want to make an UVM environment of Dual Port RAM.As Design of Dual port RAM contains bi-directional data signal I have defined internal reg and then assign value of this reg to inout signal.Here is my interface and driver of code:

1)Interface Code:

interface dpram_if(input logic clk);


  wire [7:0] data_0;
  wire [7:0] data_1;

  logic [7:0] data0;
  logic [7:0] data1;
 

  logic [7:0] address_0;
  logic cs_0;
  logic we_0;
  logic oe_0;
  logic [7:0] address_1;
  logic cs_1;
  logic we_1;
  logic oe_1;


 
 always@(posedge clk) begin
   if(we_0)
     force tbench_top.DUT.data_0 = data0;
     else 
     release tbench_top.DUT.data_0;
   if(we_1)
     force tbench_top.DUT.data_1 = data1;
     else
     release tbench_top.DUT.data_1;
 end
     
modport DRIVER (output address_0,cs_0,we_0,oe_0,address_1,cs_1,we_1,oe_1,data0,data1,input clk,inout data_0,data_1);


modport MONITOR (input address_0,cs_0,we_0,oe_0,address_1,cs_1,we_1,oe_1,data_0,data_1,data0,data1,clk);

endinterface:dpram_if

  1. Driver Code:



`define DRV_IF vif.DRIVER

class dpram_driver extends uvm_driver #(dpram_seq_item);




  virtual dpram_if vif;


  `uvm_component_utils(dpram_driver)


  function new(string name = "dpram_driver",uvm_component parent);
    super.new(name,parent);
  endfunction:new


  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    if(!uvm_config_db#(virtual dpram_if)::get(this,"","vif",vif))
      `uvm_fatal("NO_VIF",{"virtual interface must be set for:",get_full_name(),".vif"});
  endfunction:build_phase

  virtual task run_phase(uvm_phase phase);
    dpram_seq_item req_rand; 
      forever begin
        seq_item_port.get_next_item(req_rand);
        `DRV_IF.data_0 = req_rand.we_0 ? req_rand.data0 : 8'bz;
        `DRV_IF.data_1 = req_rand.we_1 ? req_rand.data1 : 8'bz;
        @(posedge vif.clk);
        `DRV_IF.address_0  = req_rand.address_0;
        `DRV_IF.cs_0       = req_rand.cs_0;
        `DRV_IF.we_0       = req_rand.we_0;
        `DRV_IF.oe_0       = req_rand.oe_0;
        `DRV_IF.data0      = req_rand.data0;
        `DRV_IF.address_1  = req_rand.address_1;
        `DRV_IF.cs_1       = req_rand.cs_1;
        `DRV_IF.we_1       = req_rand.we_1;
        `DRV_IF.oe_1       = req_rand.oe_1;
        `DRV_IF.data1      = req_rand.data1; 
        seq_item_port.item_done();
        $display("Here are the randomized values at driver\n");
        req_rand.print();
        $display("Value of data_0 = %0h",`DRV_IF.data_0);
        $display("Value of data_0 = %0h",req_rand.data0);
     end
  endtask:run_phase
endclass:dpram_driver

Here,The internal reg data0 and data1 are randomized but the value of data0 and data2 is not assigned to inout signal(Which are data_0 and data_1).Also there is no interface value come on monitor.

In reply to ASHISH PATEL:

I would use the following for the data outputs:


assign data_0 = (we_0) ? data0 : `bz;
assign data_1 = (we_1) ? data1 : `bz;

In reply to cgales:

Thanks cgales,
Thanks for your reply.I have done what you have mentioned in interface but still I am not gating the data_0 and data_1 value.It should be the same value as of data0 and data1,but I am not getting any value.

In reply to ASHISH PATEL:

Did you put my code change into the interface, replacing the always() block? In the driver, you want to do simple assignments to the interface logic variables.


  virtual task run_phase(uvm_phase phase);
    dpram_seq_item req_rand; 
      forever begin
        seq_item_port.get_next_item(req_rand);
        `DRV_IF.address_0  = req_rand.address_0;
        `DRV_IF.cs_0       = req_rand.cs_0;
        `DRV_IF.we_0       = req_rand.we_0;
        `DRV_IF.oe_0       = req_rand.oe_0;
        `DRV_IF.data0      = req_rand.data0;
        `DRV_IF.address_1  = req_rand.address_1;
        `DRV_IF.cs_1       = req_rand.cs_1;
        `DRV_IF.we_1       = req_rand.we_1;
        `DRV_IF.oe_1       = req_rand.oe_1;
        `DRV_IF.data1      = req_rand.data1;
        @posedge(`DRV_IF.clk); 
        seq_item_port.item_done();
        $display("Here are the randomized values at driver\n");
        req_rand.print();
        $display("Value of data_0 = %0h",`DRV_IF.data_0);
        $display("Value of data_0 = %0h",req_rand.data0);
     end
  endtask:run_phase

In reply to cgales:

You are working with a macro for the vitual interface modport, but you are syncronizing directly on the clk in the virtual interface.

In reply to chr_sue:

Thanks. I fixed it. I didn’t catch that from what was previously posted.

In reply to cgales:

Thanks cgales,
It is working.But for a strange reason,to see the updated values of data_0 and data_1,I have to use $display statements.I can’t see the updated values of data_0 and data_1 by using print() method of uvm.
I am sharing links of screenshots of my output.Please follow it through 1 to 3:

1)Dropbox - 1.PNG - Simplify your life

2)Dropbox - 2.PNG - Simplify your life

3)Dropbox - 3.PNG - Simplify your life

In reply to ASHISH PATEL:

The question is still why you are doing these strange things with the force Statements.
You can do this from the driver side with the seq_item data.