0% found this document useful (0 votes)
3 views

final report verification

The document outlines the implementation of a UVM (Universal Verification Methodology) testbench for a memory interface, detailing the creation of various components such as interfaces, sequence items, drivers, monitors, agents, scoreboards, and subscribers. Each class is defined with specific functionalities, including transaction randomization, signal driving, and data monitoring. The overall structure aims to facilitate the verification of memory operations through systematic transaction handling and analysis.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

final report verification

The document outlines the implementation of a UVM (Universal Verification Methodology) testbench for a memory interface, detailing the creation of various components such as interfaces, sequence items, drivers, monitors, agents, scoreboards, and subscribers. Each class is defined with specific functionalities, including transaction randomization, signal driving, and data monitoring. The overall structure aims to facilitate the verification of memory operations through systematic transaction handling and analysis.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

Serajeldeen Mohamed

DM memory full report

interface DMem_if;
logic clk;
logic RW = 0;
logic [31:0] DataW = 0;
logic [31:0] DataR;
logic [31:0] addr = 0;
endinterface

In this part, we define the interface of the UVM.

RW: Read and Write signals


DataW: data to be written.
DataR: data read from memory.
addr: memory address.

…………………………………………….
The second step is to define the package and the package container by using:
package pack1;

import uvm_pkg ::* ;

`inclcreaude "uvm_macros.svh"

………………………………………………………………………………………………

Then, we create the sequence item class that represents a single transaction with
the constraints of randomization.
class my_sequence_item extends uvm_sequence_item;

rand logic clk; // This should ideally be removed, as clock is global

rand logic RW;

rand logic [31:0] DataW;

logic [31:0] DataR; // Should NOT be rand


rand logic [31:0] addr;

`uvm_object_utils(my_sequence_item);

function new(string name = "my_sequence_item");

super.new(name);

endfunction

constraint addr_range { addr inside {[0:255]}; }

constraint rw_range { RW inside {0,1}; }

constraint data_range { DataW inside {[0:100]}; }

endclass

……………………………………………………………………

The next step is to generate a sequence of transactions using body() and pre_body()
class my_sequence extends uvm_sequence;

my_sequence_item sequence_item;

`uvm_object_utils(my_sequence);

task pre_body();

sequence_item = my_sequence_item::type_id::create("sequence_item");

endtask

task body();

for (int i = 0; i < 10; i++) begin

start_item(sequence_item);

if (!sequence_item.randomize())

`uvm_error("SEQ", "Randomization failed");

finish_item(sequence_item);

end

Endtask
The next step is to create the driver class which is used to drive the interface
signals based on the sequence items received from the sequencer.

Using build phase() Retrieves the virtual interface (vif) from the configuration database.

And run_phase() gets sequence items and drives the interface signals.

class my_driver extends uvm_driver#(my_sequence_item);

virtual DMem_if vif;

my_sequence_item sequence_item;

`uvm_component_utils(my_driver);

// ...

function void build_phase(uvm_phase phase);

// ... Gets the interface from the configuration database

endfunction

task run_phase(uvm_phase phase);

forever begin

@(posedge vif.clk);

seq_item_port.get_next_item(sequence_item);

vif.RW <= sequence_item.RW;

vif.DataW <= sequence_item.DataW;

vif.addr <= sequence_item.addr;

$display("[my_driver] ...", vif.RW, vif.addr, vif.DataW);

seq_item_port.item_done();

end

endtask

Endclass
………………………………………………………………………………………………………..

The next step is to create the monitor class that is used to monitor the interface and
collect transactions.
class my_monitor extends uvm_monitor;

virtual DMem_if vif;

my_sequence_item sequence_item;

`uvm_component_utils(my_monitor);

uvm_analysis_port#(my_sequence_item) analysis_port;

function void build_phase(uvm_phase phase);

// ... Gets the interface from the configuration database

analysis_port = new("analysis_port", this);

endfunction

task run_phase(uvm_phase phase);

forever begin

@(posedge vif.clk); // IMPORTANT: Sample AFTER the write (or after a delay)

sequence_item.RW <= vif.RW;

sequence_item.DataW <= vif.DataW;

sequence_item.addr <= vif.addr;

sequence_item.DataR <= vif.DataR; // Captures DataR

$display("[my_monitor] ...", vif.RW, vif.addr, vif.DataW, vif.DataR);

analysis_port.write(sequence_item);

end

endtask

endclass
The next step is to create the agent class that contains the driver, monitor and the
sequencer and connects the monitor’s analysis port.
class my_agent extends uvm_agent;

my_driver driver;

my_monitor monitor;

my_sequencer sequencer;

virtual DMem_if vif;

`uvm_component_utils(my_agent);

// ...

function void build_phase(uvm_phase phase);

// ... Creates driver, monitor, and sequencer

// ... Gets interface and sets it in the config DB for driver and monitor

endfunction

function void connect_phase(uvm_phase phase);

monitor.analysis_port.connect(analysis_port_agent);

driver.seq_item_port.connect(sequencer.seq_item_export);

endfunction

endclass

……………………………………………………………………………….

The next step is to create the scoreboard class to receive the transactions from the
monitor via FIFO.
class my_scoreboard extends uvm_scoreboard;

// ...

uvm_tlm_analysis_fifo #(my_sequence_item) scoreboard_fifo;

uvm_analysis_export #(my_sequence_item) my_analysis_export;

// ...
function void build_phase(uvm_phase phase);

// ... Creates fifo and analysis export

endfunction

function void connect_phase(uvm_phase phase);

my_analysis_export.connect(scoreboard_fifo.analysis_export);

endfunction

task run_phase(uvm_phase phase);

forever begin // Important: Add a loop here!

scoreboard_fifo.get(sequence_item);

// *** Add your checking logic here ***

// Example: if (sequence_item.RW == 0) begin ... compare DataR with expected value ... end

end

endtask

endclass

………………………………………………………………………..

And finally we create the subscriber class in order to serve coverage collection and
performing, custom analysis, and basic checks.

class my_subscriber extends uvm_subscriber#(my_sequence_item);

// ...

covergroup g1;

coverpoint sequence_item.RW { /* ... */ };

coverpoint sequence_item.addr {

You might also like