interface intf1
#(
parameter ADDR_WIDTH = 32,
parameter DATA_WIDTH = 32,
parameter DEPTH = 32
)
(input logic clk);
timeunit 1ns;
timeprecision 1ns;
logic rst_n;
logic en;
logic wr;
bit [ADDR_WIDTH-1:0] addr;
bit [DATA_WIDTH-1:0] data_in;
logic [DATA_WIDTH-1:0] data_out;
logic valid_out;
endinterface
package pack1;
`include "uvm_macros.svh"
import uvm_pkg::*;
class my_sequence_item extends uvm_sequence_item;
rand bit data_in;
rand bit addr;
logic rst_n;
logic en;
logic wr;
logic data_out;
logic valid_out;
constraint addr_constrians{addr inside {[0:31]};};
constraint data_constrians{data_in inside {[0:31]};};
`uvm_object_utils_begin(my_sequence_item)
`uvm_field_int(addr,UVM_ALL_ON)
`uvm_field_int(data_in,UVM_ALL_ON)
`uvm_field_int(wr,UVM_ALL_ON)
`uvm_field_int(rst_n,UVM_ALL_ON)
`uvm_field_int(en,UVM_ALL_ON)
`uvm_field_int(data_out,UVM_ALL_ON)
`uvm_field_int(valid_out,UVM_ALL_ON)
`uvm_object_utils_end
function new (string name = "my_sequence_item");
super.new(name);
endfunction
endclass
//=========================================================================
class my_sequence extends uvm_sequence #(my_sequence_item);
rand int count=3;
my_sequence_item s_item;
constraint c1 { count >0; count <50; }
`uvm_object_utils(my_sequence);
function new(string name = "my_sequence", uvm_component parent = null);
super.new(name);
endfunction
task body();
repeat (count);
// Example of using convenience macro to execute the item
//`uvm_do (req)
s_item= my_sequence_item::type_id::create("s_item");
wait_for_grant();
if (!s_item.randomize()) begin
`uvm_warning("randomization failure", "RANDOMIZATION FAILED")
end
send_request(s_item);
wait_for_item_done();
endtask
endclass
//=========================================================================
class my_sequencer extends uvm_sequencer #(my_sequence_item);
`uvm_component_utils(my_sequencer);
function new(string name = "my_sequencer", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase (phase);
$display("sequencer build phase is there\n");
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase (phase);
$display("sequencer connect phase is there\n");
endfunction
task run_phase(uvm_phase phase);
super.run_phase (phase);
$display("sequencer run phase is there\n");
endtask
endclass
class my_scoreboard extends uvm_scoreboard;
`uvm_component_utils(my_scoreboard);
//used to count the number of transactions
int no_transactions;
// declaring pkt_qu to store the pkt's recived from monitor
my_sequence_item queue[$];
//array to use as local memory
bit [31:0] mem[32];
uvm_analysis_imp #(my_sequence_item, my_scoreboard) item_collected_export;
function new(string name = "my_scoreboard", uvm_component parent = null);
super.new(name, parent);
foreach(mem[i]) mem[i] = 32'hFF;
endfunction
function void build_phase(uvm_phase phase);
super.build_phase (phase);
item_collected_export = new("item_collected_export", this);
$display("scoreboard build phase is there\n");
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase (phase);
$display("scoreboard connect phase is there\n");
endfunction
task run_phase(uvm_phase phase);
super.run_phase (phase);
forever begin
wait((queue.size() != 0));
checking();
end
$display("scoreboard run phase is there\n");
endtask
function void write(my_sequence_item item);
queue.push_back(item);
endfunction : write
task checking;
my_sequence_item trans_collected;
forever begin
trans_collected = queue.pop_front();
if(trans_collected.wr) begin
mem[trans_collected.addr] = trans_collected.data_in;
`uvm_info(get_type_name(),$sformatf("------ :: WRITE DATA :: ------"),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("Addr: %0h",trans_collected.addr),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("Data: %0h",trans_collected.data_in),UVM_LOW)
`uvm_info(get_type_name(),"------------------------------------",UVM_LOW)
end
else if(trans_collected.en) begin
if(mem[trans_collected.addr] == trans_collected.data_out) begin
`uvm_info(get_type_name(),$sformatf("------ :: READ DATA Match :: ------"),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("Addr: %0h",trans_collected.addr),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("Expected Data: %0h Actual Data: %0h",mem[trans_collected.addr],trans_collected.data_out),UVM_LOW)
`uvm_info(get_type_name(),"------------------------------------",UVM_LOW)
end
else begin
`uvm_error(get_type_name(),"------ :: READ DATA MisMatch :: ------")
`uvm_info(get_type_name(),$sformatf("Addr: %0h",trans_collected.addr),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("Expected Data: %0h Actual Data: %0h",mem[trans_collected.addr],trans_collected.data_out),UVM_LOW)
`uvm_info(get_type_name(),"------------------------------------",UVM_LOW)
end
end
end
endtask
endclass
class my_subscriber extends uvm_subscriber #(my_sequence_item);
`uvm_component_utils(my_subscriber);
function new(string name = "my_subscriber", uvm_component parent = null);
super.new(name, parent);
endfunction
function void write (my_sequence_item t);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase (phase);
$display("subscriber build phase is there\n");
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase (phase);
$display("subscriber connect phase is there\n");
endfunction
task run_phase(uvm_phase phase);
super.run_phase (phase);
$display("subscriber run phase is there\n");
endtask
endclass
class my_driver extends uvm_driver #(my_sequence_item);
my_sequence_item s_item;
`uvm_component_utils(my_driver);
virtual intf1 config_virtual;
function new(string name = "my_driver", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
string inst_name;
super.build_phase (phase);
if (!uvm_config_db#(virtual intf1)::get(this,"","vif",config_virtual))
`uvm_fatal("NOVIF",{"virtual interface must be set for: ",get_full_name(),".vif"});
$display("driver build phase is there\n");
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase (phase);
$display("driver connect phase is there\n");
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
forever begin
s_item = my_sequence_item::type_id::create("s_item");
seq_item_port.get_next_item(s_item);
drive_item(s_item);
seq_item_port.item_done();
$display("driver run phase is there\n");
end
endtask
task drive_item (input my_sequence_item item);
config_virtual.data_in=item.data_in;
config_virtual.addr=item.addr;
item.wr=1;
endtask
endclass
class my_monitor extends uvm_monitor;
virtual intf1 xmi; // SystemVerilog virtual interface
bit checks_enable = 1; // Control checking in monitor and interface.
bit coverage_enable = 1; // Control coverage in monitor and interface.
uvm_analysis_port # (my_sequence_item) item_collected_port;
event cov_transaction; // Events needed to trigger covergroups
protected my_sequence_item trans_collected;
//my_sequence_item item;
`uvm_component_utils_begin (my_monitor)
`uvm_field_int (checks_enable, UVM_ALL_ON)
`uvm_field_int (coverage_enable, UVM_ALL_ON)
`uvm_component_utils_end
covergroup cov_trans @cov_transaction;
option.per_instance = 1;
data_in_3_bins : coverpoint xmi.data_in
{
bins low ={[0:127]};
bins high ={[128:255]};
bins a=default;
}
endgroup : cov_trans
function new(string name = "my_monitor", uvm_component parent = null);
super.new(name, parent);
cov_trans = new();
cov_trans.set_inst_name ({get_full_name(), ".cov_trans"});
trans_collected = new();
item_collected_port = new("item_collected_port", this);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase (phase);
$display("monitor build phase is there\n");
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase (phase);
$display("monitor connect phase is there\n");
endfunction
task run_phase(uvm_phase phase);
super.run_phase (phase);
trans_collected = my_sequence_item::type_id::create("trans_collected");
collect_transactions(trans_collected); // collector task.
$display("monitor run phase is there\n");
endtask
task collect_transactions(my_sequence_item item);
forever begin
//------------------------Error line--------------------------------------//
//------------------------------------------------------------------------//
@(posedge xmi.clk); //--------------------------------------------//
wait(xmi.en || xmi.wr);
item.addr=xmi.addr;
item.wr=xmi.wr;
item.en=xmi.en;
item.data_in=xmi.data_in;
item.rst_n=xmi.rst_n;
if(xmi.en && xmi.valid_out ) begin
@(posedge xmi.clk);
@(posedge xmi.clk);
item.data_out=xmi.data_out;
item.valid_out=xmi.valid_out;
end
if (checks_enable)
perform_transfer_checks ();
if (coverage_enable)
perform_transfer_coverage();
item_collected_port.write (trans_collected);
end
endtask: collect_transactions
virtual protected function void perform_transfer_coverage ();
->cov_transaction;
endfunction: perform_transfer_coverage
virtual protected function void perform_transfer_checks ();
// Perform data checks on trans_collected.
endfunction : perform_transfer_checks
endclass: my_monitor
class my_agent extends uvm_agent;
`uvm_component_utils(my_agent);
my_sequencer sequencer;
my_driver driver;
my_monitor monitor;
virtual intf1 config_virtual;
virtual intf1 local_virtual;
function new(string name = "my_agent", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase (phase);
uvm_config_db#(virtual intf1)::get(this,"","vif",config_virtual);
local_virtual=config_virtual;
uvm_config_db#(virtual intf1)::set(this,"my_driver","vif",local_virtual);
monitor = my_monitor::type_id::create("monitor", this);
if (is_active == UVM_ACTIVE)
begin
sequencer = my_sequencer::type_id::create("sequencer", this);
driver = my_driver::type_id::create("driver", this);
end
$display("agent build phase is there\n");
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase (phase);
if (is_active == UVM_ACTIVE)
begin
driver.seq_item_port.connect(sequencer.seq_item_export);
end
$display("agent connect phase is there\n");
endfunction
task run_phase(uvm_phase phase);
super.run_phase (phase);
$display("agent run phase is there\n");
endtask
endclass: my_agent
class my_env extends uvm_env;
`uvm_component_utils(my_env);
virtual intf1 config_virtual;
virtual intf1 local_virtual;
my_agent agent;
my_scoreboard scoreboard;
my_subscriber subscriber;
function new(string name = "my_env", uvm_component parent = null);
super.new(name, parent);
uvm_config_db#(virtual intf1)::get(this,"","vif",config_virtual);
local_virtual=config_virtual;
uvm_config_db#(virtual intf1)::set(this,"my_agent","vif",local_virtual);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase (phase);
agent = my_agent::type_id::create("agent", this);
scoreboard = my_scoreboard::type_id::create("scoreboard", this);
subscriber = my_subscriber::type_id::create("subscriber", this);
$display("environment build phase is there\n");
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase (phase);
agent.monitor.item_collected_port.connect(scoreboard.item_collected_export);
// agent.item_collected_port.connect(scoreboard.item_collected_export);
$display("environment connect phase is there\n");
endfunction
task run_phase(uvm_phase phase);
super.run_phase (phase);
$display("environment run phase is there\n");
endtask
endclass
class my_test extends uvm_test;
`uvm_component_utils(my_test);
virtual intf1 config_virtual;
virtual intf1 local_virtual;
my_env env;
my_sequence seq;
function new(string name = "my_test", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase (phase);
env = my_env::type_id::create("env", this);
uvm_config_db#(virtual intf1)::get(this,"","vif",config_virtual);
local_virtual=config_virtual;
uvm_config_db#(virtual intf1)::set(this,"my_env","vif",local_virtual);
$display("test build phase is there\n");
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase (phase);
$display("test connect phase is there\n");
endfunction
task run_phase(uvm_phase phase);
super.run_phase (phase);
$display("test run phase is there\n");
endtask
endclass
endpackage
module top();
timeunit 1ns;
timeprecision 1ns;
import uvm_pkg::*;
import pack1::*;
localparam time PERIOD = 10;
localparam int unsigned DWIDTH = 8;
localparam int unsigned AWIDTH = 5;
logic clk;
always #5 clk = ~clk;
intf1 intf2(clk);
//---------------------------------------
//DUT instance
//---------------------------------------
memory DUT (
.clk(intf2.clk),
.rst_n(intf2.rst_n),
.addr(intf2.addr),
.wr(intf2.wr),
.en(intf2.en),
.data_in(intf2.data_in),
.data_out(intf2.data_out)
);
virtual intf1 vif1;
initial begin
clk=0;
vif1=intf2;
uvm_config_db#(virtual intf1)::set(null,"*","vif",vif1);
// uvm_config_db#(virtual interface intf1)::set(null,"my_test","vif",vif1);
run_test("my_test");
$stop;
end
endmodule //top