UVM - Vishal VK
UVM - Vishal VK
9] Sequencer Page 1
1] uvm_sequence_item
15 April 2023 11:57
Class properties
1] verification guide
https://verificationguide.com/uvm/uvm-sequence/
A sequence generates a series of sequence_item’s and sends it to the driver via sequencer, Sequence is
written by extending the uvm_sequence.
⚫ UVM Sequencer
https://vlsiverify.com/uvm/uvm-sequencer?utm_content=vc-true
The sequencer is a mediator who establishes a connection between sequence and driver. Ultimately, it passes
transactions or sequence items to the driver so that they can be driven to the DUT.
A user-defined sequencer is recommended to extend from the parameterized base class “uvm_sequencer” which
is parameterized by request (REQ) and response (RSP) item types. Response item usage is optional. So, mostly
sequencer class is extended from a base class that has only a REQ item.
TLM interface is used by sequencer and driver to pass transactions. seq_item_export and
seq_item_port TLM connect methods are defined in uvm_sequencer and uvm_driver class.
1]An agent is a container that holds and connects the driver, monitor, and sequencer instances. The agent develops a
structured hierarchy based on the protocol or interface requirement.
2] In the build_phase, instantiate driver, monitor, and sequencer if it is an active agent. Instantiate monitor alone if it is a
passive agent.
Types of Agent
1] Active Agent
An Active agent drives stimulus to the DUT. It instantiates all three components driver, monitor, and sequencer.
2] Passive Agent
A passive agent does not drive stimulus to the DUT. It instantiates only a monitor component. It is used as a sample
interface for coverage and checker purposes.
Based on the protocol interface, the stimulus has to be driven to the DUT. So, the agent provides flexibility to build a
structural hierarchy by having different agents for different protocol interfaces.
For example:
1] If you use get_type_name() then it will return only the class name irrespective of hierarchy.
endclass
Output:
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.e.p1.sp [subproducer] inside the main phase of producer value of
data send =12
2] If you use get_full_name() then it will show the complete hierarchical path starting from tb_top.test.env.... and so
on till your object type in the output LOG file.
class subproducer extends uvm_component;
`uvm_component_utils(subproducer);
int data =12;
uvm_blocking_put_port #(int) subpro;
endclass
Output:
1]
https://learnuvmverification.com/index.php/2015/07/29/uvm-sequences-and-transactions-application/
Uvm_sequecne_item
Projects Page 12
In sequence flow of task body
Projects Page 13
Seq_item_port.get_next_item(trans) ----> drive data to dut through virtual interface ----->
seq_item_port.next_item();
Projects Page 14
Projects Page 15
Projects Page 16
Projects Page 17
2] Verification of adder kumar khandale
06 July 2023 08:55
1]
Design.sv
module add(
input [3:0] a,b,
output [4:0] y
);
assign y = a + b;
endmodule
////////////////////////////////////////////////////////////
interface add_if();
logic [3:0] a;
logic [3:0] b;
logic [4:0] y;
endinterface
Testbench.sv
////////////////////////// Testbench Code
/////////////////////////Transaction
`include "uvm_macros.svh"
import uvm_pkg::*;
Projects Page 18
function new(input string path = "transaction");
super.new(path);
endfunction
`uvm_object_utils_begin(transaction)
`uvm_field_int(a, UVM_DEFAULT)
`uvm_field_int(b, UVM_DEFAULT)
`uvm_field_int(y, UVM_DEFAULT)
`uvm_object_utils_end
endclass
//////////////////////////////////////////////////////////////
class generator extends uvm_sequence #(transaction);
`uvm_object_utils(generator)
transaction t;
integer i;
endclass
////////////////////////////////////////////////////////////////////
transaction tc;
virtual add_if aif;
Projects Page 19
if(!uvm_config_db #(virtual add_if)::get(this,"","aif",aif))
`uvm_error("DRV","Unable to access uvm_config_db");
endfunction
seq_item_port.get_next_item(tc);
aif.a <= tc.a;
aif.b <= tc.b;
`uvm_info("DRV", $sformatf("Trigger DUT a: %0d ,b : %0d",tc.a, tc.b), UVM_NONE);
seq_item_port.item_done();
#10;
end
endtask
endclass
////////////////////////////////////////////////////////////////////////
class monitor extends uvm_monitor;
`uvm_component_utils(monitor)
transaction t;
virtual add_if aif;
///////////////////////////////////////////////////////////////////////
class scoreboard extends uvm_scoreboard;
`uvm_component_utils(scoreboard)
Projects Page 20
`uvm_component_utils(scoreboard)
transaction tr;
endclass
////////////////////////////////////////////////
monitor m;
driver d;
uvm_sequencer #(transaction) seqr;
Projects Page 21
endfunction
endclass
/////////////////////////////////////////////////////
scoreboard s;
agent a;
endclass
////////////////////////////////////////////
generator gen;
env e;
Projects Page 22
endclass
//////////////////////////////////////
module add_tb();
add_if aif();
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
initial begin
uvm_config_db #(virtual add_if)::set(null, "uvm_test_top.e.a*", "aif", aif);
run_test("test");
end
endmodule
Projects Page 23
3] Four Bit Multiplier Kumar khandale
06 July 2023 08:40
Design.sv
module mul(
input [3:0] a,b,
output [7:0] y
);
assign y = a * b;
endmodule
///////////////////////////////////////////
interface mul_if;
logic [3:0] a;
logic [3:0] b;
logic [7:0] y;
endinterface
Testbench.sv
`include "uvm_macros.svh"
import uvm_pkg::*;
////////////////////////////////////////////////////////////
class transaction extends uvm_sequence_item;
Projects Page 24
class transaction extends uvm_sequence_item;
`uvm_object_utils(transaction)
endclass
////////////////////////////////////////////////////////////////////////
transaction tr;
endclass
//////////////////////////////////////////////////////////////////////////////
transaction tr;
virtual mul_if mif;
Projects Page 25
endfunction
endclass
//////////////////////////////////////////////////////////////////////////
class mon extends uvm_monitor;
`uvm_component_utils(mon)
uvm_analysis_port#(transaction) send;
transaction tr;
virtual mul_if mif;
Projects Page 26
endtask
endclass
/////////////////////////////////////////////////////////////////////////
class sco extends uvm_scoreboard;
`uvm_component_utils(sco)
uvm_analysis_imp#(transaction,sco) recv;
$display("----------------------------------------------------------------");
endfunction
endclass
///////////////////////////////////////////////////////////////////////////
drv d;
uvm_sequencer#(transaction) seqr;
mon m;
Projects Page 27
virtual function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
d.seq_item_port.connect(seqr.seq_item_export);
endfunction
endclass
///////////////////////////////////////////////////////////////////////
agent a;
sco s;
endclass
//////////////////////////////////////////////////////////////////
class test extends uvm_test;
`uvm_component_utils(test)
env e;
generator gen;
Projects Page 28
phase.raise_objection(this);
gen.start(e.a.seqr);
#20;
phase.drop_objection(this);
endtask
endclass
////////////////////////////////////////////////////////////////////
module tb;
mul_if mif();
initial
begin
uvm_config_db #(virtual mul_if)::set(null, "*", "mif", mif);
run_test("test");
end
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
endmodule
Projects Page 29
4] D flip Flop kumar khandale
06 July 2023 08:43
1]
Design.sv
module dff(
input clk,
input rst,
input din,
output reg dout
);
always@(posedge clk)
begin
if(rst)
dout <= 1'b0;
else
dout <= din;
end
endmodule
//////////////////////////////////////////////////
interface dff_if;
logic clk;
logic rst;
logic din;
logic dout;
endinterface
Testbench.sv
Projects Page 30
`include "uvm_macros.svh"
import uvm_pkg::*;
//////////////////////////////////////////////////////////////
endclass
////////////////////////////////////////////////////////////
class transaction extends uvm_sequence_item;
`uvm_object_utils(transaction)
endclass
////////////////////////////////////////////////////////////////////////
transaction tr;
Projects Page 31
begin
tr = transaction::type_id::create("tr");
start_item(tr);
assert(tr.randomize());
tr.rst = 1'b0;
`uvm_info("SEQ", $sformatf("rst : %0b din : %0b dout : %0b", tr.rst, tr.din, tr.dout), UVM_NONE);
finish_item(tr);
end
endtask
endclass
//////////////////////////////////////////////////////////////////////////////
class rst_dff extends uvm_sequence#(transaction);
`uvm_object_utils(rst_dff)
transaction tr;
endclass
//////////////////////////////////////////////////////////////////////////////
class rand_din_rst extends uvm_sequence#(transaction);
`uvm_object_utils(rand_din_rst)
transaction tr;
Projects Page 32
assert(tr.randomize());
`uvm_info("SEQ", $sformatf("rst : %0b din : %0b dout : %0b", tr.rst, tr.din, tr.dout), UVM_NONE);
finish_item(tr);
end
endtask
endclass
//////////////////////////////////////////////////////////////////////////////
class drv extends uvm_driver#(transaction);
`uvm_component_utils(drv)
transaction tr;
virtual dff_if dif;
endclass
//////////////////////////////////////////////////////////////////////////
class mon extends uvm_monitor;
`uvm_component_utils(mon)
uvm_analysis_port#(transaction) send;
transaction tr;
virtual dff_if dif;
Projects Page 33
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
tr = transaction::type_id::create("tr");
send = new("send", this);
if(!uvm_config_db#(virtual dff_if)::get(this,"","dif",dif))//uvm_test_top.env.agent.drv.aif
`uvm_error("drv","Unable to access Interface");
endfunction
endclass
/////////////////////////////////////////////////////////////////////////
class sco extends uvm_scoreboard;
`uvm_component_utils(sco)
uvm_analysis_imp#(transaction,sco) recv;
$display("----------------------------------------------------------------");
endfunction
endclass
Projects Page 34
endclass
///////////////////////////////////////////////////////////////////////////
drv d;
uvm_sequencer#(transaction) seqr;
mon m;
///////////////////
config_dff cfg;
m = mon::type_id::create("m",this);
cfg = config_dff::type_id::create("cfg");
////////////////////////////////////////////////////////////
if(!uvm_config_db#(config_dff)::get(this, "", "cfg", cfg))
`uvm_error("AGENT", "FAILED TO ACCESS CONFIG");
if(cfg.agent_type == UVM_ACTIVE)
begin
d = drv::type_id::create("d",this);
seqr = uvm_sequencer#(transaction)::type_id::create("seqr", this);
end
endfunction
endclass
///////////////////////////////////////////////////////////////////////
Projects Page 35
agent a;
sco s;
config_dff cfg;
endclass
//////////////////////////////////////////////////////////////////
class test extends uvm_test;
`uvm_component_utils(test)
env e;
valid_din vdin;
rst_dff rff;
rand_din_rst rdin;
Projects Page 36
phase.drop_objection(this);
endtask
endclass
////////////////////////////////////////////////////////////////////
module tb;
dff_if dif();
initial
begin
uvm_config_db #(virtual dff_if)::set(null, "*", "dif", dif);
run_test("test");
end
initial begin
dif.clk = 0;
end
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
endmodule
Projects Page 37
5] Verification of UART kumar Khandale
06 July 2023 08:47
Design.sv
`timescale 1ns / 1ps
/////////////////////////////////////////////////
///////////////clock generator
module clk_gen(
input clk, rst,
input [16:0] baud,
output reg tx_clk, rx_clk
);
Projects Page 38
tx_max <=14'd1302;
end
57600 : begin
rx_max <=11'd54;
tx_max <=14'd868;
end
115200: begin
rx_max <=11'd27;
tx_max <=14'd434;
end
128000: begin
rx_max <=11'd24;
tx_max <=14'd392;
end
default: begin
rx_max <=11'd325;
tx_max <=14'd5208;
end
endcase
end
end
///////////////////////////////////////////
always@(posedge clk)
begin
if(rst)
begin
rx_max <= 0;
rx_count <= 0;
rx_clk <= 0;
end
else
begin
if(rx_count <= rx_max)
begin
rx_count <= rx_count + 1;
end
else
begin
rx_clk <= ~rx_clk;
rx_count <= 0;
end
end
end
////////////////////////////////////////////////////////////
always@(posedge clk)
begin
if(rst)
begin
tx_max <= 0;
tx_count <= 0;
tx_clk <= 0;
end
else
begin
if(tx_count <= tx_max)
Projects Page 39
if(tx_count <= tx_max)
begin
tx_count <= tx_count + 1;
end
else
begin
tx_clk <= ~tx_clk;
tx_count <= 0;
end
end
end
/////////////////////////////////////////////////////
endmodule
//////////////////////////////////////////////////
module uart_tx(
input tx_clk,tx_start,
input rst,
input [7:0] tx_data,
input [3:0] length,
input parity_type,parity_en,
input stop2,
output reg tx, tx_done, tx_err
);
logic start_b = 0;
logic stop_b = 1;
logic parity_bit = 0;
integer count = 0;
////////////////////parity generator
always@(posedge tx_clk)
begin
if(parity_type == 1'b1) ///odd
begin
case(length)
4'd5 : parity_bit = ^(tx_data[4:0]); //xor
4'd6 : parity_bit = ^(tx_data[5:0]);
4'd7 : parity_bit = ^(tx_data[6:0]);
4'd8 : parity_bit = ^(tx_data[7:0]);
default : parity_bit = 1'b0;
endcase
end
else
begin
case(length)
Projects Page 40
case(length)
4'd5 : parity_bit = ~^(tx_data[4:0]);//xnor
4'd6 : parity_bit = ~^(tx_data[5:0]);
4'd7 : parity_bit = ~^(tx_data[6:0]);
4'd8 : parity_bit = ~^(tx_data[7:0]);
default : parity_bit = 1'b0;
endcase
end
end
always@(*)
begin
case(state)
idle :
begin
tx_done = 1'b0;
tx = 1'b1;
tx_reg = {(8){1'b0}};
tx_err = 0;
if(tx_start)
next_state = start_bit;
else
next_state = idle;
end
////////////////////////
start_bit :
begin
tx_reg = tx_data;
tx = start_b;
next_state = send_data;
end
///////////////////////////
send_data:
begin
if(count < (length - 1))
begin
next_state = send_data;
tx = tx_reg[count];
end
else if (parity_en)
begin
tx = tx_reg[count];
next_state = send_parity;
Projects Page 41
next_state = send_parity;
end
else
begin
tx = tx_reg[count];
next_state = send_first_stop;
end
end
////////////////////////////////////////////////
send_parity:
begin
tx = parity_bit;
next_state = send_first_stop;
end
///////////////////////////////////////////////////
send_first_stop :
begin
tx = stop_b;
if(stop2)
next_state = send_sec_stop;
else
next_state = done;
end
////////////////////////////////////
send_sec_stop :
begin
tx = stop_b;
next_state = done;
end
////////////////////////////////
done :
begin
tx_done = 1'b1;
next_state = idle;
end
//////////////////////////////////////////////////
default : next_state = idle;
endcase
end
///////////////////////////////////////////////////////////////////////////////////////////////////////////
always@(posedge tx_clk)
begin
case(state)
idle : begin
count <= 0;
end
start_bit : begin
count <= 0;
Projects Page 42
count <= 0;
end
send_data: begin
count <= count + 1;
end
send_parity: begin
count <= 0;
end
send_first_stop : begin
count <= 0;
end
send_sec_stop : begin
count <= 0;
end
done : begin
count <= 0;
end
endcase
end
////////////////////////////////////////////////////////////////////
endmodule
///////////////////////////////////////////////////UART RX
module uart_rx(
input rx_clk,rx_start,
input rst, rx,
input [3:0] length,
input parity_type,parity_en,
input stop2,
output reg [7:0] rx_out,
output logic rx_done, rx_error
);
logic parity = 0;
logic [7:0] datard = 0;
int count = 0;
int bit_count = 0;
Projects Page 43
if(rst)
state <= idle;
else
state <= next_state;
end
/////////////////////////////////////////////////////////
///////////////////next_State decoder + output
end
////////////////////////////////////////////////
start_bit:
begin
if(count == 7 && rx)
begin
next_state = idle;
end
else if (count == 15)
begin
next_state = recv_data;
end
else
begin
next_state = start_bit;
end
end
//////////////////////////////////////////////////////////////////
recv_data: begin
if(count == 7)
begin
datard[7:0] = {rx,datard[7:1]};
end
else if(count == 15 && bit_count == (length - 1))
begin
case(length)
Projects Page 44
case(length)
5: rx_out = datard[7:3];
6: rx_out = datard[7:2];
7: rx_out = datard[7:1];
8: rx_out = datard[7:0];
default : rx_out = 8'h00;
endcase
//////////////////////////////////
if(parity_type)
parity = ^datard;
else
parity = ~^datard;
////////////////////////////////////////////
if(parity_en)
next_state = check_parity;
else
next_state = check_first_stop;
/////////////////////////////////////////
end
else
next_state = recv_data;
end
//////////////////////////////////////////////////
check_parity: begin
if(count == 7)
begin
if(rx == parity)
rx_error = 1'b0;
else
rx_error = 1'b1;
end
else if (count == 15)
begin
next_state = check_first_stop;
end
else
begin
next_state = check_parity;
end
end
////////////////////////////////////////////////////////////////////////////
check_first_stop :
begin
if(count == 7)
begin
if(rx != 1'b1)
rx_error = 1'b1;
else
rx_error = 1'b0;
Projects Page 45
rx_error = 1'b0;
end
else if (count == 15)
begin
if(stop2)
next_state = check_sec_stop;
else
next_state = done;
end
end
////////////////////////////////////////////////////////////////////////////////
check_sec_stop: begin
if(count == 7)
begin
if(rx != 1'b1)
rx_error = 1'b1;
else
rx_error = 1'b0;
end
else if (count == 15)
begin
next_state = done;
end
end
/////////////////////////////////////////////////////////////////////////
done : begin
rx_done = 1'b1;
next_state = idle;
rx_error = 1'b0;
end
endcase
end
///////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////
start_bit:
begin
if(count < 15)
count <= count + 1;
else
count <= 0;
end
Projects Page 46
end
//////////////////////////////////////////////////////////////////
recv_data: begin
if(count < 15)
count <= count + 1;
else begin
count <= 0;
bit_count <= bit_count + 1;
end
end
//////////////////////////////////////////////////
check_parity: begin
if(count < 15)
count <= count + 1;
else
count <= 0;
end
////////////////////////////////////////////////////////////////////////////
check_first_stop :
begin
if(count < 15)
count <= count + 1;
else
count <= 0;
end
////////////////////////////////////////////////////////////////////////////////
check_sec_stop: begin
if(count < 15)
count <= count + 1;
else
count <= 0;
end
/////////////////////////////////////////////////////////////////////////
done : begin
count <= 0;
bit_count <= 0;
end
endcase
end
endmodule
///////////////////////////////////////////////////////////////////
Projects Page 47
/////////////////////////////////
module uart_top
(
input clk, rst,
input tx_start, rx_start,
input [7:0] tx_data,
input [16:0] baud,
input [3:0] length,
input parity_type, parity_en,
input stop2,
output tx_done,rx_done, tx_err,rx_err,
output [7:0] rx_out
);
endmodule
/////////////////////////////////////////////////////////////////////
interface uart_if;
logic clk, rst;
logic tx_start, rx_start;
logic [7:0] tx_data;
logic [16:0] baud;
logic [3:0] length;
logic parity_type, parity_en;
logic stop2;
logic tx_done,rx_done, tx_err,rx_err;
logic [7:0] rx_out;
endinterface
Testbench.sv
`include "uvm_macros.svh"
import uvm_pkg::*;
Projects Page 48
/////////////build the seq for random length with and without priority
////////////////////////////////////////////////////////////////////////////////////
class uart_config extends uvm_object; /////configuration of env
`uvm_object_utils(uart_config)
endclass
//////////////////////////////////////////////////////////
endclass : transaction
///////////////////////////////////////////////////////////////////////
///////////////////random baud - fixed length = 8 - parity enable - parity type : random - single stop
class rand_baud extends uvm_sequence#(transaction);
`uvm_object_utils(rand_baud)
transaction tr;
Projects Page 49
function new(string name = "rand_baud");
super.new(name);
endfunction
endclass
////////////////////random baud - fixed length = 8 - parity enable - parity type : random - two stop
//////////////////////////////////////////////////////////
class rand_baud_with_stop extends uvm_sequence#(transaction);
`uvm_object_utils(rand_baud_with_stop)
transaction tr;
endclass
//////////////////////////////////////////////////////////
Projects Page 50
//////////////////////////////////////////////////////////
////////////////////fixed length = 5 - variable baud - with parity
class rand_baud_len5p extends uvm_sequence#(transaction);
`uvm_object_utils(rand_baud_len5p)
transaction tr;
endclass
//////////////////////////////////////////////////////////
////////////////////fixed length = 6 - variable baud - with parity
class rand_baud_len6p extends uvm_sequence#(transaction);
`uvm_object_utils(rand_baud_len6p)
transaction tr;
Projects Page 51
tr.rx_start = 1'b1;
tr.parity_en = 1'b1;
tr.stop2 = 1'b0;
finish_item(tr);
end
endtask
endclass
//////////////////////////////////////////////////////////
////////////////////fixed length = 7 - variable baud - with parity
class rand_baud_len7p extends uvm_sequence#(transaction);
`uvm_object_utils(rand_baud_len7p)
transaction tr;
endclass
//////////////////////////////////////////////////////////
////////////////////fixed length = 8 - variable baud - with parity
class rand_baud_len8p extends uvm_sequence#(transaction);
`uvm_object_utils(rand_baud_len8p)
transaction tr;
Projects Page 52
tr = transaction::type_id::create("tr");
start_item(tr);
assert(tr.randomize);
tr.op = length8wp;
tr.rst = 1'b0;
tr.length = 8;
tr.tx_data = tr.tx_data[7:0];
tr.tx_start = 1'b1;
tr.rx_start = 1'b1;
tr.parity_en = 1'b1;
tr.stop2 = 1'b0;
finish_item(tr);
end
endtask
endclass
//////////////////////////////////////////////////////////
////////////////////fixed length = 5 - variable baud - without parity
class rand_baud_len5 extends uvm_sequence#(transaction);
`uvm_object_utils(rand_baud_len5)
transaction tr;
endclass
//////////////////////////////////////////////////////////
////////////////////fixed length = 6- variable baud - without parity
class rand_baud_len6 extends uvm_sequence#(transaction);
`uvm_object_utils(rand_baud_len6)
transaction tr;
Projects Page 53
transaction tr;
endclass
//////////////////////////////////////////////////////////
////////////////////fixed length = 7- variable baud - without parity
class rand_baud_len7 extends uvm_sequence#(transaction);
`uvm_object_utils(rand_baud_len7)
transaction tr;
Projects Page 54
endclass
//////////////////////////////////////////////////////////
////////////////////fixed length = 8 - variable baud - without parity
class rand_baud_len8 extends uvm_sequence#(transaction);
`uvm_object_utils(rand_baud_len8)
transaction tr;
endclass
///////////////////////////////////////////////////////////////////////////////////////
if(!uvm_config_db#(virtual uart_if)::get(this,"","vif",vif))
Projects Page 55
if(!uvm_config_db#(virtual uart_if)::get(this,"","vif",vif))
`uvm_error("drv","Unable to access Interface");
endfunction
task reset_dut();
repeat(5)
begin
vif.rst <= 1'b1; ///active high reset
vif.tx_start <= 1'b0;
vif.rx_start <= 1'b0;
vif.tx_data <= 8'h00;
vif.baud <= 16'h0;
vif.length <= 4'h0;
vif.parity_type <= 1'b0;
vif.parity_en <= 1'b0;
vif.stop2 <= 1'b0;
`uvm_info("DRV", "System Reset : Start of Simulation", UVM_MEDIUM);
@(posedge vif.clk);
end
endtask
task drive();
reset_dut();
forever begin
seq_item_port.get_next_item(tr);
seq_item_port.item_done();
end
endtask
Projects Page 56
endclass
//////////////////////////////////////////////////////////////////////////////////////////////
uvm_analysis_port#(transaction) send;
transaction tr;
virtual uart_if vif;
tr.rx_out = vif.rx_out;
`uvm_info("MON", $sformatf("BAUD:%0d LEN:%0d PAR_T:%0d PAR_EN:%0d STOP:%0d TX_DATA:%0d
RX_DATA:%0d", tr.baud, tr.length, tr.parity_type, tr.parity_en, tr.stop2, tr.tx_data, tr.rx_out), UVM_NONE);
send.write(tr);
end
end
Projects Page 57
end
endtask
endclass
//////////////////////////////////////////////////////////////////////////////////////////////////
uvm_analysis_imp#(transaction,sco) recv;
bit [31:0] arr[32] = '{default:0};
bit [31:0] addr = 0;
bit [31:0] data_rd = 0;
endclass
//////////////////////////////////////////////////////////////////////////////////////////////
uart_config cfg;
driver d;
uvm_sequencer#(transaction) seqr;
mon m;
Projects Page 58
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
cfg = uart_config::type_id::create("cfg");
m = mon::type_id::create("m",this);
if(cfg.is_active == UVM_ACTIVE)
begin
d = driver::type_id::create("d",this);
seqr = uvm_sequencer#(transaction)::type_id::create("seqr", this);
end
endfunction
endclass
//////////////////////////////////////////////////////////////////////////////////
agent a;
sco s;
endclass
//////////////////////////////////////////////////////////////////////////
Projects Page 59
super.new(inst,c);
endfunction
env e;
rand_baud rb;
rand_baud_with_stop rbs;
rand_baud_len5p rb5l;
rand_baud_len6p rb6l;
rand_baud_len7p rb7l;
rand_baud_len8p rb8l;
///////////////////////
rand_baud_len5 rb5lwop;
rand_baud_len6 rb6lwop;
rand_baud_len7 rb7lwop;
rand_baud_len8 rb8lwop;
endfunction
//////////////////////////////////////////////////////////////////////
module tb;
uart_if vif();
uart_top dut
Projects Page 60
uart_top dut
(.clk(vif.clk), .rst(vif.rst), .tx_start(vif.tx_start), .rx_start(vif.rx_start), .tx_data(vif.tx_data), .baud(vif.baud), .length(
vif.length), .parity_type(vif.parity_type), .parity_en(vif.parity_en),.stop2(vif.stop2),.tx_done(vif.tx_done), .rx_done
(vif.rx_done), .tx_err(vif.tx_err), .rx_err(vif.rx_err), .rx_out(vif.rx_out));
initial begin
vif.clk <= 0;
end
initial begin
uvm_config_db#(virtual uart_if)::set(null, "*", "vif", vif);
run_test("test");
end
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
endmodule
Projects Page 61
6] Verification of SPI kumar Khandale
06 July 2023 09:02
Design.sv
module spi_mem(
input clk, rst, cs, miso,
output reg ready, mosi, op_done
);
typedef enum bit [2:0] {idle = 0, detect = 1, store = 2, send_addr = 3, send_data = 4, temp_del = 5} state_type;
state_type state = idle;
always@(posedge clk)
begin
if(rst)
begin
state <= idle;
count <= 0;
mosi <= 0;
ready <= 0;
op_done <= 0;
end
else
begin
case(state)
idle: begin
count <= 0;
mosi <= 0;
ready <= 0;
op_done <= 0;
datain <= 0;
if(!cs)
state <= detect;
else
state <= idle;
end
detect: begin
if(miso)
Projects Page 62
if(miso)
state <= store; ///write
else
state <= send_addr; ///read
end
store: begin
if(count <= 15) begin
datain[count] <= miso;
count <= count + 1;
state <= store;
end
else
begin
mem[datain[7:0]] <= datain[15:8];
state <= idle;
count <= 0;
op_done <= 1'b1;
end
end
send_addr: begin
if(count <= 7) begin
count <= count + 1;
datain[count] <= miso;
state <= send_addr;
end
else begin
count <= 0;
state <= temp_del;
ready <= 1'b0;
dataout <= mem[datain];
end
end
temp_del : begin
state <= send_data;
ready <= 1'b1;
count <= 1;
mosi <= dataout[0];
end
send_data: begin
if(count <= 7)
begin
count <= count + 1;
mosi <= dataout[count];
state <= send_data;
end
else
begin
count <= 0;
state <= idle;
op_done <= 1'b1;
Projects Page 63
op_done <= 1'b1;
end
end
endcase
end
end
endmodule
////////////////////////////////////////////////////////////
interface spi_i;
endinterface
Testbench.sv
`include "uvm_macros.svh"
import uvm_pkg::*;
////////////////////////////////////////////////////////////////////////////////////
class spi_config extends uvm_object; /////configuration of env
`uvm_object_utils(spi_config)
endclass
//////////////////////////////////////////////////////////
Projects Page 64
typedef enum bit [1:0] {readd = 0, writed = 1, rstdut = 2} oper_mode;
`uvm_object_utils_begin(transaction)
`uvm_field_int (addr,UVM_ALL_ON)
`uvm_field_int (din,UVM_ALL_ON)
`uvm_field_int (dout,UVM_ALL_ON)
`uvm_field_int (ready,UVM_ALL_ON)
`uvm_field_int (rst,UVM_ALL_ON)
`uvm_field_int (done,UVM_ALL_ON)
`uvm_field_int (miso,UVM_ALL_ON)
`uvm_field_int (mosi,UVM_ALL_ON)
`uvm_field_int (cs,UVM_ALL_ON)
`uvm_field_int (err,UVM_ALL_ON)
`uvm_field_enum(oper_mode, op, UVM_DEFAULT)
`uvm_object_utils_end
endclass : transaction
///////////////////////////////////////////////////////////////////////
///////////////////write seq
class write_data extends uvm_sequence#(transaction);
`uvm_object_utils(write_data)
transaction tr;
Projects Page 65
assert(tr.randomize);
tr.op = writed;
finish_item(tr);
end
endtask
endclass
//////////////////////////////////////////////////////////
transaction tr;
endclass
/////////////////////////////////////////////////////////////////////
transaction tr;
endclass
////////////////////////////////////////////////////////////
Projects Page 66
class writeb_readb extends uvm_sequence#(transaction);
`uvm_object_utils(writeb_readb)
transaction tr;
repeat(10)
begin
tr = transaction::type_id::create("tr");
tr.addr_c.constraint_mode(1);
start_item(tr);
assert(tr.randomize);
tr.op = writed;
finish_item(tr);
end
repeat(10)
begin
tr = transaction::type_id::create("tr");
tr.addr_c.constraint_mode(1);
start_item(tr);
assert(tr.randomize);
tr.op = readd;
finish_item(tr);
end
endtask
endclass
////////////////////////////////////////////////////////////
class driver extends uvm_driver #(transaction);
`uvm_component_utils(driver)
if(!uvm_config_db#(virtual spi_i)::get(this,"","vif",vif))//uvm_test_top.env.agent.drv.aif
`uvm_error("drv","Unable to access Interface");
Projects Page 67
`uvm_error("drv","Unable to access Interface");
endfunction
////////////////////reset task
task reset_dut();
begin
vif.rst <= 1'b1; ///active high reset
vif.miso <= 1'b0;
vif.cs <= 1'b1;
`uvm_info("DRV", "System Reset", UVM_MEDIUM);
@(posedge vif.clk);
end
endtask
///////////////////////write
task write_d();
////start of transaction
vif.rst <= 1'b0;
vif.cs <= 1'b0;
vif.miso <= 1'b0;
data = {tr.din, tr.addr};
`uvm_info("DRV", $sformatf("DATA WRITE addr : %0d din : %0d",tr.addr, tr.din), UVM_MEDIUM);
@(posedge vif.clk);
vif.miso <= 1'b1; ///write operation
@(posedge vif.clk);
@(posedge vif.op_done);
endtask
//////////////////read operation
task read_d();
////start of transaction
vif.rst <= 1'b0;
vif.cs <= 1'b0;
vif.miso <= 1'b0;
data = {8'h00, tr.addr};
@(posedge vif.clk);
vif.miso <= 1'b0; ///read operation
@(posedge vif.clk);
////send addr
for(int i = 0; i < 8 ; i++)
begin
vif.miso <= data[i];
@(posedge vif.clk);
end
Projects Page 68
for(int i = 0; i < 8 ; i++)
begin
@(posedge vif.clk);
datard[i] = vif.mosi;
end
`uvm_info("DRV", $sformatf("DATA READ addr : %0d dout : %0d",tr.addr,datard), UVM_MEDIUM);
@(posedge vif.op_done);
endtask
//////////////////////////
seq_item_port.get_next_item(tr);
if(tr.op == rstdut)
begin
reset_dut();
end
seq_item_port.item_done();
end
endtask
endclass
//////////////////////////////////////////////////////////////////////////////////////////////
uvm_analysis_port#(transaction) send;
transaction tr;
virtual spi_i vif;
logic [15:0] din;
logic [7:0] dout;
Projects Page 69
send = new("send", this);
if(!uvm_config_db#(virtual spi_i)::get(this,"","vif",vif))//uvm_test_top.env.agent.drv.aif
`uvm_error("MON","Unable to access Interface");
endfunction
if(vif.rst)
begin
tr.op = rstdut;
`uvm_info("MON", "SYSTEM RESET DETECTED", UVM_NONE);
send.write(tr);
end
else begin
@(posedge vif.clk);
if(vif.miso && !vif.cs)
begin
tr.op = writed;
@(posedge vif.clk);
tr.addr = din[7:0];
tr.din = din[15:8];
@(posedge vif.op_done);
`uvm_info("MON", $sformatf("DATA WRITE addr:%0d data:%0d",din[7:0],din[15:8]), UVM_NONE);
send.write(tr);
end
else if (!vif.miso && !vif.cs)
begin
tr.op = readd;
@(posedge vif.clk);
@(posedge vif.ready);
Projects Page 70
send.write(tr);
end
end
end
endtask
endclass
//////////////////////////////////////////////////////////////////////////////////////////////////
uvm_analysis_imp#(transaction,sco) recv;
bit [31:0] arr[32] = '{default:0};
bit [31:0] addr = 0;
bit [31:0] data_rd = 0;
$display("----------------------------------------------------------------");
endfunction
endclass
//////////////////////////////////////////////////////////////////////////////////////////////
Projects Page 71
class agent extends uvm_agent;
`uvm_component_utils(agent)
spi_config cfg;
driver d;
uvm_sequencer#(transaction) seqr;
mon m;
if(cfg.is_active == UVM_ACTIVE)
begin
d = driver::type_id::create("d",this);
seqr = uvm_sequencer#(transaction)::type_id::create("seqr", this);
end
endfunction
endclass
//////////////////////////////////////////////////////////////////////////////////
agent a;
sco s;
Projects Page 72
endclass
//////////////////////////////////////////////////////////////////////////
env e;
write_data wdata;
read_data rdata;
writeb_readb wrrdb;
reset_dut rstdut;
phase.drop_objection(this);
endtask
endclass
//////////////////////////////////////////////////////////////////////
module tb;
spi_i vif();
initial begin
vif.clk <= 0;
end
initial begin
uvm_config_db#(virtual spi_i)::set(null, "*", "vif", vif);
run_test("test");
end
initial begin
$dumpfile("dump.vcd");
Projects Page 73
$dumpfile("dump.vcd");
$dumpvars;
end
endmodule
Projects Page 74
7] Verification of I2C kumar Khandale
06 July 2023 09:05
Design.sv
module i2c_mem
(
input clk, rst, wr,
input [6:0] addr,
input [7:0] din,
output [7:0] datard,
output reg done
);
////////////////////////////
wire sda;
reg scl;
reg [7:0] addrt;
reg [7:0] temprd;
reg en;
reg sdat;
integer count = 0;
///////////////////////////////////////
typedef enum bit [3:0] {idle = 0, start = 1, send_addr = 2, get_ack1 = 3, send_data = 4, get_ack2= 5, read_data = 6,
complete = 7, get_addr = 8, send_ack1 = 9, get_data = 10, send_ack2 = 11 } state_type;
state_type state, nstate;
/////////////////////////////////////
always@(posedge clk)
begin
if(rst)
begin
addrt <= 0;
temprd <= 0;
en <= 0;
sdat <= 0;
count <= 0;
end
else begin
case(state)
idle: begin
en <= 1'b1;
scl <= 1'b1;
sdat <= 1'b1;
state <= start;
count <= 0;
done <= 1'b0;
Projects Page 75
done <= 1'b0;
temprd <= 0;
end
start: begin
sdat <= 1'b0;
addrt <= {addr,wr};
state <= send_addr;
end
send_addr: begin
if(count <= 7) begin
sdat <= addrt[count];
count <= count + 1;
end
else
begin
state <= get_ack1;
count <= 0;
en <= 1'b0;
end
end
get_ack1: begin
if(sda == 1'b0)
begin
if(wr == 1'b1)
begin
state <= send_data;
en <= 1'b1;
end
else if (wr == 1'b0 )
begin
state <= read_data;
en <= 1'b0;
end
end
else
state <= get_ack1;
end
send_data: begin
if(count <= 7) begin
sdat <= din[count];
count <= count + 1;
end
else
begin
state <= get_ack2;
count <= 0;
en <= 1'b0;
end
end
get_ack2: begin
if(sda == 1'b0)
state <= complete;
else
Projects Page 76
else
state <= get_ack2;
end
read_data: begin
if(count <= 9) begin
//temprd[count] <= sda;
temprd[7:0] <= {sda,temprd[7:1]};
count <= count + 1;
end
else
begin
state <= complete;
count <= 0;
end
end
complete: begin
if(update) begin
done <= 1'b1;
state <= idle;
end
else
state <= complete;
end
end
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
always@(posedge clk)
begin
if(rst)
begin
for(int i = 0; i< 128; i++)
begin
mem[i] <= 0;
end
addrn <= 0;
datan <= 0;
update <= 0;
end
else
begin
case(nstate)
idle: begin
addrn <= 0;
Projects Page 77
addrn <= 0;
datan <= 0;
update <= 0;
data_rd <= 0;
start: begin
if(scl && !sdat)
nstate <= get_addr;
else
nstate <= start;
end
get_addr: begin
if(countn <= 7) begin
addrn[countn] <= sdat;
countn <= countn + 1;
end
else
begin
nstate <= send_ack1;
countn <= 0;
if(addrn[0] == 1'b0)
begin
data_rd <= mem[addrn[7:1]];
end
end
end
send_ack1:begin
sdan <= 1'b0;
if(addrn[0] == 1'b1 && state == send_data)
begin
nstate <= get_data;
end
else if(addrn[0] == 1'b0 && state == read_data)
nstate <= send_data;
else
nstate <= send_ack1;
end
get_data: begin
if(countn <= 7) begin
datan[countn] <= sdat;
countn <= countn + 1;
end
else
begin
nstate <= send_ack2;
countn <= 0;
mem[addrn[7:1]] <= datan;
Projects Page 78
mem[addrn[7:1]] <= datan;
end
end
send_ack2:begin
sdan <= 1'b0;
nstate <= complete;
end
send_data: begin
if(countn <= 7) begin
sdan <= data_rd[countn];
countn <= countn + 1;
end
else
begin
nstate <= complete;
countn <= 0;
end
end
complete : begin
update <= 1'b1;
nstate <= idle;
end
////////////////////////////////////////////////////////////////////////////////
interface i2c_i;
endinterface
Projects Page 79
Testbench.sv
`include "uvm_macros.svh"
import uvm_pkg::*;
//////////////////////////////////////////////////////////
oper_mode op;
logic wr;
randc logic [6:0] addr;
rand logic [7:0] din;
logic [7:0] datard;
logic done;
endclass : transaction
///////////////////////////////////////////////////////////////////////
///////////////////write seq
class write_data extends uvm_sequence#(transaction);
`uvm_object_utils(write_data)
transaction tr;
Projects Page 80
assert(tr.randomize);
tr.op = writed;
`uvm_info("SEQ", $sformatf("MODE : WRITE DIN : %0d ADDR : %0d ", tr.din, tr.addr), UVM_NONE);
finish_item(tr);
end
endtask
endclass
//////////////////////////////////////////////////////////
transaction tr;
endclass
/////////////////////////////////////////////////////////////////////
transaction tr;
Projects Page 81
endclass
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
class driver extends uvm_driver #(transaction);
`uvm_component_utils(driver)
if(!uvm_config_db#(virtual i2c_i)::get(this,"","vif",vif))//uvm_test_top.env.agent.drv.aif
`uvm_error("drv","Unable to access Interface");
endfunction
////////////////////reset task
task reset_dut();
begin
`uvm_info("DRV", "System Reset", UVM_MEDIUM);
vif.rst <= 1'b1; ///active high reset
vif.addr <= 0;
vif.din <= 0;
vif.wr <= 0;
@(posedge vif.clk);
end
endtask
///////////////////////write
task write_d();
`uvm_info("DRV", $sformatf("mode : WRITE addr : %0d din : %0d", tr.addr, tr.din), UVM_NONE);
vif.rst <= 1'b0;
vif.wr <= 1'b1;
vif.addr <= tr.addr;
vif.din <= tr.din;
@(posedge vif.done);
endtask
task read_d();
`uvm_info("DRV", $sformatf("mode : READ addr : %0d din : %0d", tr.addr, tr.din), UVM_NONE);
vif.rst <= 1'b0;
vif.wr <= 1'b0;
vif.addr <= tr.addr;
vif.din <= 0;
Projects Page 82
vif.din <= 0;
@(posedge vif.done);
endtask
seq_item_port.get_next_item(tr);
if(tr.op == rstdut)
begin
reset_dut();
end
seq_item_port.item_done();
end
endtask
endclass
//////////////////////////////////////////////////////////////////////////////////////////////
uvm_analysis_port#(transaction) send;
transaction tr;
virtual i2c_i vif;
logic [15:0] din;
logic [7:0] dout;
Projects Page 83
endfunction
if(vif.rst)
begin
tr.op = rstdut;
`uvm_info("MON", "SYSTEM RESET DETECTED", UVM_NONE);
send.write(tr);
end
else begin
if(vif.wr)
begin
tr.op = writed;
tr.addr = vif.addr;
tr.wr = 1;
tr.din = vif.din;
@(posedge vif.done);
`uvm_info("MON", $sformatf("DATA WRITE addr:%0d data:%0d",tr.addr,tr.din), UVM_NONE);
send.write(tr);
end
else if (!vif.wr)
begin
tr.op = readd;
tr.addr = vif.addr;
tr.wr = 0;
tr.din = vif.din;
@(posedge vif.done);
tr.datard = vif.datard;
`uvm_info("MON", $sformatf("DATA READ addr:%0d data:%0d ",tr.addr,tr.datard), UVM_NONE);
send.write(tr);
end
end
end
endtask
endclass
//////////////////////////////////////////////////////////////////////////////////////////////////
uvm_analysis_imp#(transaction,sco) recv;
bit [7:0] arr[128] = '{default:0};
bit [7:0] data_rd = 0;
Projects Page 84
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
recv = new("recv", this);
endfunction
$display("----------------------------------------------------------------");
endfunction
endclass
//////////////////////////////////////////////////////////////////////////////////////////////
driver d;
uvm_sequencer#(transaction) seqr;
mon m;
Projects Page 85
m = mon::type_id::create("m",this);
d = driver::type_id::create("d",this);
seqr = uvm_sequencer#(transaction)::type_id::create("seqr", this);
endfunction
endclass
//////////////////////////////////////////////////////////////////////////////////
agent a;
sco s;
endclass
//////////////////////////////////////////////////////////////////////////
env e;
write_data wdata;
read_data rdata;
reset_dut rstdut;
Projects Page 86
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
e = env::type_id::create("env",this);
wdata = write_data::type_id::create("wdata");
rdata = read_data::type_id::create("rdata");
rstdut = reset_dut::type_id::create("rstdut");
endfunction
wdata.start(e.a.seqr);
rdata.start(e.a.seqr);
phase.drop_objection(this);
endtask
endclass
//////////////////////////////////////////////////////////////////////
module tb;
i2c_i vif();
initial begin
vif.clk <= 0;
end
initial begin
uvm_config_db#(virtual i2c_i)::set(null, "*", "vif", vif);
run_test("test");
end
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
endmodule
Projects Page 87
8] Verification of APB_RAM kumar Khandale
06 July 2023 09:08
Design.sv
// Code your design here
module apb_ram (
input presetn,
input pclk,
input psel,
input penable,
input pwrite,
input [31:0] paddr, pwdata,
output reg [31:0] prdata,
output reg pready, pslverr
);
always@(posedge pclk)
begin
if(presetn == 1'b0) //active low
begin
state <= idle;
prdata <= 32'h00000000;
pready <= 1'b0;
pslverr <= 1'b0;
end
else
begin
case(state)
idle :
begin
prdata <= 32'h00000000;
pready <= 1'b0;
pslverr <= 1'b0;
state <= setup;
end
Projects Page 88
end
end
access:
begin
if(pwrite && penable)
begin
if(paddr < 32)
begin
mem[paddr] <= pwdata;
state <= transfer;
pslverr <= 1'b0;
pready <= 1'b1;
end
else
begin
state <= transfer;
pready <= 1'b1;
pslverr <= 1'b1;
end
end
else if (!pwrite && penable)
begin
if(paddr < 32)
begin
prdata <= mem[paddr];
state <= transfer;
pready <= 1'b1;
pslverr <= 1'b0;
end
else
begin
state <= transfer;
pready <= 1'b1;
pslverr <= 1'b1;
prdata <= 32'hxxxxxxxx;
end
end
else
state <= setup;
end
transfer: begin
state <= setup;
pready <= 1'b0;
pslverr <= 1'b0;
end
Projects Page 89
default : state <= idle;
endcase
end
end
endmodule
//////////////////////////////////////////////////
interface apb_if ();
// Signals
logic pclk;
logic presetn;
logic [31:0] paddr;
logic pwrite;
logic [31:0] pwdata;
logic penable;
logic psel;
logic [31:0] prdata;
logic pslverr;
logic pready;
endinterface : apb_if
Projects Page 90
Testbench.sv
`timescale 1ns / 1ps
/*
module tb();
reg presetn = 0;
reg pclk = 0;
reg psel = 0;
reg penable = 0 ;
reg pwrite = 0;
reg [31:0] paddr = 0, pwdata = 0;
wire [31:0] prdata;
wire pready, pslverr;
apb_ram dut (presetn, pclk, psel, penable, pwrite, paddr, pwdata, prdata, pready, pslverr);
initial begin
presetn = 0;
repeat(5) @(posedge pclk);
presetn = 1;
psel = 1;
pwrite = 1;
paddr = 12;
pwdata = 35;
@(posedge pclk);
penable = 1;
@(posedge pready);
psel = 0;
penable = 0;
@(posedge pclk);
psel = 1;
pwrite = 1'b0;
paddr = 12;
pwdata = 35;
@(posedge pclk);
penable = 1'b1;
@(posedge pready);
psel = 0;
penable = 0;
@(posedge pclk);
psel = 1;
pwrite = 1;
paddr = 45;
pwdata = 35;
@(posedge pclk);
penable = 1;
@(posedge pready);
Projects Page 91
@(posedge pready);
psel = 0;
penable = 0;
@(posedge pclk);
psel = 1;
pwrite = 0;
paddr = 45;
pwdata = 35;
@(posedge pclk);
penable = 1;
@(posedge pready);
@(posedge pclk);
$stop();
end
endmodule
*/
`include "uvm_macros.svh"
import uvm_pkg::*;
////////////////////////////////////////////////////////////////////////////////////
class abp_config extends uvm_object; /////configuration of env
`uvm_object_utils(abp_config)
endclass
///////////////////////////////////////////////////////
Projects Page 92
logic PSLVERR;
logic [31: 0] PRDATA;
`uvm_object_utils_begin(transaction)
`uvm_field_int (PWRITE,UVM_ALL_ON)
`uvm_field_int (PWDATA,UVM_ALL_ON)
`uvm_field_int (PADDR,UVM_ALL_ON)
`uvm_field_int (PREADY,UVM_ALL_ON)
`uvm_field_int (PSLVERR,UVM_ALL_ON)
`uvm_field_int (PRDATA,UVM_ALL_ON)
`uvm_field_enum(oper_mode, op, UVM_DEFAULT)
`uvm_object_utils_end
endclass : transaction
///////////////////////////////////////////////////////////////
/*
module tb;
transaction tr;
initial begin
tr = transaction::type_id::create("tr");
tr.randomize();
tr.print();
end
endmodule
*/
//////////////////////////////////////////////////////////////////
///////////////////write seq
class write_data extends uvm_sequence#(transaction);
`uvm_object_utils(write_data)
transaction tr;
Projects Page 93
finish_item(tr);
end
endtask
endclass
//////////////////////////////////////////////////////////
////////////////////////read seq
class read_data extends uvm_sequence#(transaction);
`uvm_object_utils(read_data)
transaction tr;
endclass
/////////////////////////////////////////////
transaction tr;
start_item(tr);
assert(tr.randomize);
tr.op = writed;
finish_item(tr);
Projects Page 94
start_item(tr);
assert(tr.randomize);
tr.op = readd;
finish_item(tr);
end
endtask
endclass
///////////////////////////////////////////////////////
///////////////write bulk read bulk
class writeb_readb extends uvm_sequence#(transaction);
`uvm_object_utils(writeb_readb)
transaction tr;
repeat(15) begin
tr = transaction::type_id::create("tr");
tr.addr_c.constraint_mode(1);
tr.addr_c_err.constraint_mode(0);
start_item(tr);
assert(tr.randomize);
tr.op = writed;
finish_item(tr);
end
repeat(15) begin
tr = transaction::type_id::create("tr");
tr.addr_c.constraint_mode(1);
tr.addr_c_err.constraint_mode(0);
start_item(tr);
assert(tr.randomize);
tr.op = readd;
finish_item(tr);
end
endtask
endclass
/////////////////////////////////////////////////////////////////
//////////////////////slv_error_write
class write_err extends uvm_sequence#(transaction);
`uvm_object_utils(write_err)
Projects Page 95
`uvm_object_utils(write_err)
transaction tr;
start_item(tr);
assert(tr.randomize);
tr.op = writed;
finish_item(tr);
end
endtask
endclass
///////////////////////////////////////////////////////////////
/////////////////////////read err
transaction tr;
start_item(tr);
assert(tr.randomize);
tr.op = readd;
finish_item(tr);
end
endtask
endclass
///////////////////////////////////////////////////////////////
Projects Page 96
`uvm_object_utils(reset_dut)
transaction tr;
start_item(tr);
assert(tr.randomize);
tr.op = rst;
finish_item(tr);
end
endtask
endclass
////////////////////////////////////////////////////////////
class driver extends uvm_driver #(transaction);
`uvm_component_utils(driver)
if(!uvm_config_db#(virtual apb_if)::get(this,"","vif",vif))//uvm_test_top.env.agent.drv.aif
`uvm_error("drv","Unable to access Interface");
endfunction
task reset_dut();
repeat(5)
begin
vif.presetn <= 1'b0;
vif.paddr <= 'h0;
vif.pwdata <= 'h0;
vif.pwrite <= 'b0;
vif.psel <= 'b0;
Projects Page 97
vif.psel <= 'b0;
vif.penable <= 'b0;
`uvm_info("DRV", "System Reset : Start of Simulation", UVM_MEDIUM);
@(posedge vif.pclk);
end
endtask
task drive();
reset_dut();
forever begin
seq_item_port.get_next_item(tr);
if(tr.op == rst)
begin
vif.presetn <= 1'b0;
vif.paddr <= 'h0;
vif.pwdata <= 'h0;
vif.pwrite <= 'b0;
vif.psel <= 'b0;
vif.penable <= 'b0;
@(posedge vif.pclk);
end
end
else if(tr.op == readd)
begin
vif.psel <= 1'b1;
vif.paddr <= tr.PADDR;
vif.presetn <= 1'b1;
vif.pwrite <= 1'b0;
@(posedge vif.pclk);
vif.penable <= 1'b1;
`uvm_info("DRV", $sformatf("mode:%0s, addr:%0d, wdata:%0d, rdata:%0d, slverr:%
0d",tr.op.name(),tr.PADDR,tr.PWDATA,tr.PRDATA,tr.PSLVERR), UVM_NONE);
@(negedge vif.pready);
vif.penable <= 1'b0;
tr.PRDATA = vif.prdata;
tr.PSLVERR = vif.pslverr;
end
seq_item_port.item_done();
Projects Page 98
end
endtask
endclass
//////////////////////////////////////////////////////////////////
uvm_analysis_port#(transaction) send;
transaction tr;
virtual apb_if vif;
Projects Page 99
tr.PADDR = vif.paddr;
tr.PRDATA = vif.prdata;
tr.PSLVERR = vif.pslverr;
`uvm_info("MON", $sformatf("DATA READ addr:%0d data:%0d slverr:%0d",tr.PADDR,
tr.PRDATA,tr.PSLVERR), UVM_NONE);
send.write(tr);
end
end
endtask
endclass
/////////////////////////////////////////////////////////////////////
uvm_analysis_imp#(transaction,sco) recv;
bit [31:0] arr[32] = '{default:0};
bit [31:0] addr = 0;
bit [31:0] data_rd = 0;
end
$display("----------------------------------------------------------------");
endfunction
endclass
/////////////////////////////////////////////////////////////////////
abp_config cfg;
driver d;
uvm_sequencer#(transaction) seqr;
mon m;
if(cfg.is_active == UVM_ACTIVE)
begin
d = driver::type_id::create("d",this);
seqr = uvm_sequencer#(transaction)::type_id::create("seqr", this);
end
endfunction
endclass
//////////////////////////////////////////////////////////////////////////////////
agent a;
sco s;
endclass
//////////////////////////////////////////////////////////////////////////
env e;
write_read wrrd;
writeb_readb wrrdb;
write_data wdata;
read_data rdata;
write_err werr;
read_err rerr;
reset_dut rstdut;
//////////////////////////////////////////////////////////////////////
module tb;
apb_if vif();
apb_ram dut
(.presetn(vif.presetn), .pclk(vif.pclk), .psel(vif.psel), .penable(vif.penable), .pwrite(vif.pwrite), .paddr(vif.paddr),
.pwdata(vif.pwdata), .prdata(vif.prdata), .pready(vif.pready), .pslverr(vif.pslverr));
initial begin
vif.pclk <= 0;
end
initial begin
uvm_config_db#(virtual apb_if)::set(null, "*", "vif", vif);
run_test("test");
end
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
endmodule
Design.sv
///////////////////////////////////////////////
module axi_slave(
////////////////global control signals
input clk,
input resetn,
);
//axi_if vif();
typedef enum bit [1:0] {awidle = 2'b00, awstart = 2'b01, awreadys = 2'b10} awstate_type;
awstate_type awstate, awnext_state;
//////reset decoder
always_ff@(posedge clk , negedge resetn)
begin
if(!resetn) begin
awstate <= awidle; ///idle state for write address FSM
wstate <= widle; ///idle state for write data fsm
bstate <= bidle; ///// idle state for write response fsm
end
else
begin
awstate <= awnext_state;
wstate <= wnext_state;
bstate <= bnext_state;
end
end
awstart:
begin
if(awvalid)
begin
awnext_state = awreadys;
awaddrt = awaddr; ////storing address
end
else
awnext_state = awstart;
end
awreadys:
begin
awready = 1'b1;
if(wstate == wreadys)
awnext_state = awidle;
else
awnext_state = awreadys;
end
endcase
end
4'b0010: begin
mem[awaddrt] = wdatat[15:8];
end
4'b0011: begin
mem[awaddrt] = wdatat[7:0];
mem[awaddrt + 1] = wdatat[15:8];
end
4'b0100: begin
mem[awaddrt] = wdatat[23:16];
end
4'b0101: begin
mem[awaddrt] = wdatat[7:0];
mem[awaddrt + 1] = wdatat[23:16];
end
4'b0110: begin
mem[awaddrt] = wdatat[15:8];
mem[awaddrt + 1] = wdatat[23:16];
end
4'b0111: begin
mem[awaddrt] = wdatat[7:0];
mem[awaddrt + 1] = wdatat[15:8];
mem[awaddrt + 2] = wdatat[23:16];
end
4'b1000: begin
mem[awaddrt] = wdatat[31:24];
end
4'b1001: begin
mem[awaddrt] = wdatat[7:0];
mem[awaddrt + 1] = wdatat[31:24];
end
4'b1011: begin
mem[awaddrt] = wdatat[7:0];
mem[awaddrt + 1] = wdatat[15:8];
mem[awaddrt + 2] = wdatat[31:24];
end
4'b1100: begin
mem[awaddrt] = wdatat[23:16];
mem[awaddrt + 1] = wdatat[31:24];
end
4'b1101: begin
mem[awaddrt] = wdatat[7:0];
mem[awaddrt + 1] = wdatat[23:16];
mem[awaddrt + 2] = wdatat[31:24];
end
4'b1110: begin
mem[awaddrt] = wdatat[15:8];
mem[awaddrt + 1] = wdatat[23:16];
mem[awaddrt + 2] = wdatat[31:24];
end
4'b1111: begin
mem[awaddrt] = wdatat[7:0];
mem[awaddrt + 1] = wdatat[15:8];
mem[awaddrt + 2] = wdatat[23:16];
mem[awaddrt + 3] = wdatat[31:24];
end
endcase
return awaddrt;
endfunction
4'b0010: begin
mem[awaddrt] = wdatat[15:8];
addr = awaddrt + 1;
end
4'b0011: begin
mem[awaddrt] = wdatat[7:0];
mem[awaddrt + 1] = wdatat[15:8];
addr = awaddrt + 2;
4'b0100: begin
mem[awaddrt] = wdatat[23:16];
addr = awaddrt + 1;
end
4'b0101: begin
mem[awaddrt] = wdatat[7:0];
mem[awaddrt + 1] = wdatat[23:16];
addr = awaddrt + 2;
end
4'b0110: begin
mem[awaddrt] = wdatat[15:8];
mem[awaddrt + 1] = wdatat[23:16];
addr = awaddrt + 2;
end
4'b0111: begin
mem[awaddrt] = wdatat[7:0];
mem[awaddrt + 1] = wdatat[15:8];
mem[awaddrt + 2] = wdatat[23:16];
addr = awaddrt + 3;
end
4'b1000: begin
mem[awaddrt] = wdatat[31:24];
addr = awaddrt + 1;
end
4'b1001: begin
mem[awaddrt] = wdatat[7:0];
mem[awaddrt + 1] = wdatat[31:24];
addr = awaddrt + 2;
end
4'b1010: begin
mem[awaddrt] = wdatat[15:8];
mem[awaddrt + 1] = wdatat[31:24];
addr = awaddrt + 2;
end
4'b1011: begin
mem[awaddrt] = wdatat[7:0];
mem[awaddrt + 1] = wdatat[15:8];
mem[awaddrt + 2] = wdatat[31:24];
addr = awaddrt + 3;
end
4'b1100: begin
mem[awaddrt] = wdatat[23:16];
mem[awaddrt + 1] = wdatat[31:24];
addr = awaddrt + 2;
end
4'b1101: begin
mem[awaddrt] = wdatat[7:0];
4'b1110: begin
mem[awaddrt] = wdatat[15:8];
mem[awaddrt + 1] = wdatat[23:16];
mem[awaddrt + 2] = wdatat[31:24];
addr = awaddrt + 3;
end
4'b1111: begin
mem[awaddrt] = wdatat[7:0];
mem[awaddrt + 1] = wdatat[15:8];
mem[awaddrt + 2] = wdatat[23:16];
mem[awaddrt + 3] = wdatat[31:24];
addr = awaddrt + 4;
end
endcase
return addr;
endfunction
function bit [7:0] wrap_boundary (input bit [3:0] awlen,input bit[2:0] awsize);
bit [7:0] boundary;
unique case(awlen)
4'b0001:
begin
unique case(awsize)
3'b000: begin
boundary = 2 * 1;
end
3'b001: begin
boundary = 2 * 2;
end
3'b010: begin
boundary = 2 * 4;
end
endcase
end
4'b0011:
begin
unique case(awsize)
3'b000: begin
boundary = 4 * 1;
end
3'b001: begin
boundary = 4 * 2;
end
3'b010: begin
boundary = 4 * 4;
end
endcase
4'b0111:
begin
unique case(awsize)
3'b000: begin
boundary = 8 * 1;
end
3'b001: begin
boundary = 8 * 2;
end
3'b010: begin
boundary = 8 * 4;
end
endcase
end
4'b1111:
begin
unique case(awsize)
3'b000: begin
boundary = 16 * 1;
end
3'b001: begin
boundary = 16 * 2;
end
3'b010: begin
boundary = 16 * 4;
end
endcase
end
endcase
return boundary;
endfunction
//////////////////////////////////////////////////////////////
function bit[31:0] data_wr_wrap (input [3:0] wstrb, input [31:0] awaddrt, input [7:0] wboundary);
/////////////////////////////////////////////////
4'b0001: begin
mem[awaddrt] = wdatat[7:0];
if((awaddrt + 1) % wboundary == 0)
addr1 = (awaddrt + 1) - wboundary;
else
addr1 = awaddrt + 1;
return addr1;
/////////////////////////////////////////////////
4'b0010: begin
mem[awaddrt] = wdatat[15:8];
if((awaddrt + 1) % wboundary == 0)
addr1 = (awaddrt + 1) - wboundary;
else
addr1 = awaddrt + 1;
return addr1;
end
///////////////////////////////////////////////////
4'b0011: begin
mem[awaddrt] = wdatat[7:0];
if((awaddrt + 1) % wboundary == 0)
addr1 = (awaddrt + 1) - wboundary;
else
addr1 = awaddrt + 1;
mem[addr1] = wdatat[15:8];
if((addr1 + 1) % wboundary == 0)
addr2 = (addr1 + 1) - wboundary;
else
addr2 = addr1 + 1;
return addr2;
end
///////////////////////////////////////////////
4'b0100: begin
mem[awaddrt] = wdatat[23:16];
if((awaddrt + 1) % wboundary == 0)
addr1 = (awaddrt + 1) - wboundary;
else
addr1 = awaddrt + 1;
return addr1;
end
//////////////////////////////////////////////
4'b0101: begin
mem[awaddrt] = wdatat[7:0];
if((awaddrt + 1) % wboundary == 0)
addr1 = (awaddrt + 1) - wboundary;
else
addr1 = awaddrt + 1;
mem[addr1] = wdatat[23:16];
if((addr1 + 1) % wboundary == 0)
addr2 = (addr1 + 1) - wboundary;
else
addr2 = addr1 + 1;
return addr2;
end
///////////////////////////////////////////////////
4'b0110: begin
mem[awaddrt] = wdatat[15:8];
if((awaddrt + 1) % wboundary == 0)
addr1 = (awaddrt + 1) - wboundary;
else
addr1 = awaddrt + 1;
mem[addr1] = wdatat[23:16];
if((addr1 + 1) % wboundary == 0)
addr2 = (addr1 + 1) - wboundary;
else
addr2 = addr1 + 1;
return addr2;
end
//////////////////////////////////////////////////////////////
4'b0111: begin
mem[awaddrt] = wdatat[7:0];
if((awaddrt + 1) % wboundary == 0)
addr1 = (awaddrt + 1) - wboundary;
else
addr1 = awaddrt + 1;
mem[addr1] = wdatat[15:8];
if((addr1 + 1) % wboundary == 0)
addr2 = (addr1 + 1) - wboundary;
else
addr2 = addr1 + 1;
mem[addr2] = wdatat[23:16];
if((addr2 + 1) % wboundary == 0)
addr3 = (addr2 + 1) - wboundary;
else
addr3 = addr2 + 1;
return addr3;
end
4'b1000: begin
mem[awaddrt] = wdatat[31:24];
if((awaddrt + 1) % wboundary == 0)
return addr1;
end
4'b1001: begin
mem[awaddrt] = wdatat[7:0];
if((awaddrt + 1) % wboundary == 0)
addr1 = (awaddrt + 1) - wboundary;
else
addr1 = awaddrt + 1;
mem[addr1] = wdatat[31:24];
if((addr1 + 1) % wboundary == 0)
addr2 = (addr1 + 1) - wboundary;
else
addr2 = addr1 + 1;
return addr2;
end
4'b1010: begin
mem[awaddrt] = wdatat[15:8];
if((awaddrt + 1) % wboundary == 0)
addr1 = (awaddrt + 1) - wboundary;
else
addr1 = awaddrt + 1;
mem[addr1] = wdatat[31:24];
if((addr1 + 1) % wboundary == 0)
addr2 = (addr1 + 1) - wboundary;
else
addr2 = addr1 + 1;
return addr2;
end
4'b1011: begin
mem[awaddrt] = wdatat[7:0];
if((awaddrt + 1) % wboundary == 0)
addr1 = (awaddrt + 1) - wboundary;
else
addr1 = awaddrt + 1;
mem[addr1] = wdatat[15:8];
if((addr1 + 1) % wboundary == 0)
addr2 = (addr1 + 1) - wboundary;
else
addr2 = addr1 + 1;
mem[addr2] = wdatat[31:24];
if((addr2 + 1) % wboundary == 0)
addr3 = (addr2 + 1) - wboundary;
else
addr3 = addr2 + 1;
return addr3;
end
4'b1100: begin
mem[awaddrt] = wdatat[23:16];
if((awaddrt + 1) % wboundary == 0)
addr1 = (awaddrt + 1) - wboundary;
else
addr1 = awaddrt + 1;
mem[addr1] = wdatat[31:24];
if((addr1 + 1) % wboundary == 0)
addr2 = (addr1 + 1) - wboundary;
else
addr2 = addr1 + 1;
return addr2;
end
4'b1101: begin
mem[awaddrt] = wdatat[7:0];
if((awaddrt + 1) % wboundary == 0)
addr1 = (awaddrt + 1) - wboundary;
else
addr1 = awaddrt + 1;
mem[addr1] = wdatat[23:16];
if((addr1 + 1) % wboundary == 0)
addr2 = (addr1 + 1) - wboundary;
else
addr2 = addr1 + 1;
mem[addr2] = wdatat[31:24];
if((addr2 + 1) % wboundary == 0)
addr3 = (addr2 + 1) - wboundary;
else
addr3 = addr2 + 1;
return addr3;
end
4'b1110: begin
mem[awaddrt] = wdatat[15:8];
if((awaddrt + 1) % wboundary == 0)
addr1 = (awaddrt + 1) - wboundary;
mem[addr1] = wdatat[23:16];
if((addr1 + 1) % wboundary == 0)
addr2 = (addr1 + 1) - wboundary;
else
addr2 = addr1 + 1;
mem[addr2] = wdatat[31:24];
if((addr2 + 1) % wboundary == 0)
addr3 = (addr2 + 1) - wboundary;
else
addr3 = addr2 + 1;
return addr3;
end
4'b1111: begin
mem[awaddrt] = wdatat[7:0];
if((awaddrt + 1) % wboundary == 0)
addr1 = (awaddrt + 1) - wboundary;
else
addr1 = awaddrt + 1;
mem[addr1] = wdatat[15:8];
if((addr1 + 1) % wboundary == 0)
addr2 = (addr1 + 1) - wboundary;
else
addr2 = addr1 + 1;
mem[addr2] = wdatat[23:16];
if((addr2 + 1) % wboundary == 0)
addr3 = (addr2 + 1) - wboundary;
else
addr3 = addr2 + 1;
mem[addr3] = wdatat[31:24];
if((addr3 + 1) % wboundary == 0)
addr4 = (addr3 + 1) - wboundary;
else
addr4 = addr3 + 1;
return addr4;
end
endcase
endfunction
typedef enum bit [2:0] {widle = 0, wstart = 1, wreadys = 2, wvalids = 3, waddr_dec = 4} wstate_type;
wstate_type wstate, wnext_state;
always_comb
begin
case(wstate)
widle: begin
wready = 1'b0;
wnext_state = wstart;
first = 1'b0;
wlen_count = 0;
end
wstart: begin
if(wvalid)
begin
wnext_state = waddr_dec;
wdatat = wdata;
end
else
begin
wnext_state = wstart;
end
end
waddr_dec: begin
wnext_state = wreadys;
if(first == 0) begin
nextaddr = awaddr;
first = 1'b1;
wlen_count = 0;
end
else if (wlen_count < (awlen + 1 ))
begin
nextaddr = retaddr;
end
else
begin
nextaddr = awaddr;
end
end
wreadys: begin
case(awburst)
2'b00: ////Fixed Mode
begin
retaddr = data_wr_fixed(wstrb, awaddr); ///fixed
end
wvalids: begin
wready = 1'b0;
wnext_state = wstart;
end
endcase
end
always_comb
begin
case(bstate)
bidle: begin
bid = 1'b0;
bresp = 1'b0;
bvalid = 1'b0;
bnext_state = bdetect_last;
end
bdetect_last: begin
bstart: begin
bid = awid;
bvalid = 1'b1;
bnext_state = bwait;
if( (awaddr < 128 ) && (awsize <= 3'b010) )
bresp = 2'b00; ///okay
else if (awsize > 3'b010)
bresp = 2'b10; /////slverr
else
bresp = 2'b11; ///no slave address
end
bwait: begin
if(bready == 1'b1)
bnext_state = bidle;
else
bnext_state = bwait;
end
endcase
end
always_comb
begin
case(arstate)
aridle: begin
arready = 1'b0;
arnext_state = arstart;
end
arstart: begin
if(arvalid == 1'b1) begin
arnext_state = arreadys;
arreadys: begin
arnext_state = aridle;
arready = 1'b1;
end
endcase
end
3'b001: begin
rdata[7:0] = mem[addr];
rdata[15:8] = mem[addr + 1];
end
3'b010: begin
rdata[7:0] = mem[addr];
rdata[15:8] = mem[addr + 1];
rdata[23:16] = mem[addr + 2];
rdata[31:24] = mem[addr + 3];
end
endcase
endfunction
//////////////////////////end of function
//////////////////////////// read data in INCR Mode
function bit [31:0] read_data_incr (input [31:0] addr, input [2:0] arsize);
bit [31:0] nextaddr;
unique case(arsize)
3'b000: begin
rdata[7:0] = mem[addr];
nextaddr = addr + 1;
end
3'b001: begin
rdata[7:0] = mem[addr];
rdata[15:8] = mem[addr + 1];
nextaddr = addr + 2;
end
3'b010: begin
rdata[7:0] = mem[addr];
rdata[15:8] = mem[addr + 1];
rdata[23:16] = mem[addr + 2];
rdata[31:24] = mem[addr + 3];
nextaddr = addr + 4;
end
endcase
return nextaddr;
endfunction
///////////////////////////////////////////end of function
function bit [31:0] read_data_wrap (input bit [31:0] addr, input bit [2:0] rsize, input [7:0] rboundary);
bit [31:0] addr1,addr2,addr3,addr4;
if(((addr + 1) % rboundary ) == 0)
addr1 = (addr + 1) - rboundary;
else
addr1 = (addr + 1);
return addr1;
end
3'b001: begin
rdata[7:0] = mem[addr];
if(((addr + 1) % rboundary ) == 0)
addr1 = (addr + 1) - rboundary;
else
addr1 = (addr + 1);
rdata[15:8] = mem[addr1];
if(((addr1 + 1) % rboundary ) == 0)
addr2 = (addr1 + 1) - rboundary;
else
addr2 = (addr1 + 1);
return addr2;
end
3'b010: begin
rdata[7:0] = mem[addr];
if(((addr + 1) % rboundary ) == 0)
addr1 = (addr + 1) - rboundary;
else
addr1 = (addr + 1);
rdata[15:8] = mem[addr1];
if(((addr1 + 1) % rboundary ) == 0)
addr2 = (addr1 + 1) - rboundary;
else
addr2 = (addr1 + 1);
rdata[23:16] = mem[addr2];
if(((addr2 + 1) % rboundary ) == 0)
addr3 = (addr2 + 1) - rboundary;
else
addr3 = (addr2 + 1);
rdata[31:24] = mem[addr3];
if(((addr3 + 1) % rboundary ) == 0)
addr4 = (addr3 + 1) - rboundary;
else
addr4 = (addr3 + 1);
return addr4;
end
endcase
endfunction
///////////////////////////////////////
reg rdfirst;
bit [31:0] rdnextaddr, rdretaddr;
reg [3:0] len_count;
reg [7:0] rdboundary;
typedef enum bit [2:0] {ridle = 0, rstart = 1, rwait = 2, rvalids = 3, rerror = 4} rstate_type;
rstate_type rstate, rnext_state;
/////////////////////////////////
always_comb
begin
case(rstate)
ridle: begin
rid = 0;
rdfirst = 0;
rdata = 0;
rresp = 0;
rlast = 0;
rvalid = 0;
len_count = 0;
if(arvalid)
rnext_state = rstart;
else
rnext_state = ridle;
end
rstart: begin
if ((araddrt < 128) && (arsize <= 3'b010) ) begin
rid = arid;
rvalid = 1'b1;
rnext_state = rwait;
rresp = 2'b00;
unique case(arburst)
////////////////////fixed
2'b00: begin
if(rdfirst == 0) begin
rdnextaddr = araddr;
rdfirst = 1'b1;
len_count = 0;
end
else if (len_count != (arlen + 1))
begin
read_data_fixed(araddrt, arsize);
end
//////////////////////end of fixed
////////////////////start of incr
2'b01: begin
if(rdfirst == 0) begin
rdnextaddr = araddr;
rdfirst = 1'b1;
len_count = 0;
end
else if (len_count != (arlen + 1))
begin
rdnextaddr = rdretaddr;
end
end
rwait: begin
rvalid = 1'b0;
if(rready == 1'b1)
rnext_state = rvalids;
else
rnext_state = rwait;
end
rvalids: begin
len_count = len_count + 1;
rerror : begin
rvalid = 1'b0;
//////////////////////////////////////////////
interface axi_if();
////////////////
logic clk;
logic resetn;
//////////////////
logic [31:0] next_addrwr;
logic [31:0] next_addrrd;
endinterface
Testbench.sv
`include "uvm_macros.svh"
import uvm_pkg::*;
typedef enum bit [2:0] {wrrdfixed = 0, wrrdincr = 1, wrrdwrap = 2, wrrderrfix = 3, rstdut = 4 } oper_mode;
int len = 0;
rand bit [3:0] id;
oper_mode op;
rand bit awvalid;
bit awready;
bit [3:0] awid;
rand bit [3:0] awlen;
rand bit [2:0] awsize; //4byte =010
rand bit [31:0] awaddr;
rand bit [1:0] awburst;
bit wvalid;
bit wready;
bit [3:0] wid;
rand bit [31:0] wdata;
rand bit [3:0] wstrb;
bit wlast;
bit bready;
bit bvalid;
bit [3:0] bid;
bit [1:0] bresp;
endclass : transaction
////////////////////////////////////////////////////////////////////////////////
transaction tr;
endclass
///////////////////////////////////////////////////////////////////////
transaction tr;
tr = transaction::type_id::create("tr");
$display("------------------------------");
`uvm_info("SEQ", "Sending Fixed mode Transaction to DRV", UVM_NONE);
start_item(tr);
assert(tr.randomize);
tr.op = wrrdfixed;
tr.awlen = 7;
tr.awburst = 0;
tr.awsize = 2;
finish_item(tr);
endtask
endclass
////////////////////////////////////////////////////////////
transaction tr;
finish_item(tr);
endtask
endclass
///////////////////////////////////////////////////////////
transaction tr;
finish_item(tr);
endtask
endclass
/////////////////////////////////////////////////////////////////////////////////
transaction tr;
endclass
/////////////////////////////////////////////////////////////
class driver extends uvm_driver #(transaction);
`uvm_component_utils(driver)
if(!uvm_config_db#(virtual axi_if)::get(this,"","vif",vif))
`uvm_error("drv","Unable to access Interface");
endfunction
task reset_dut();
begin
`uvm_info("DRV", "System Reset : Start of Simulation", UVM_MEDIUM);
vif.resetn <= 1'b0; ///active high reset
vif.awvalid <= 1'b0;
vif.awid <= 1'b0;
vif.awlen <= 0;
vif.awsize <= 0;
vif.awaddr <= 0;
vif.awburst <= 0;
vif.bready <= 0;
vif.rready <= 0;
@(posedge vif.clk);
end
endtask
task wrrd_fixed_wr();
`uvm_info("DRV", "Fixed Mode Write Transaction Started", UVM_NONE);
/////////////////////////write logic
vif.resetn <= 1'b1;
vif.awvalid <= 1'b1;
vif.awid <= tr.id;
vif.awlen <= 7;
vif.awsize <= 2;
vif.awaddr <= 5;
vif.awburst <= 0;
@(posedge vif.wready);
@(posedge vif.clk);
task wrrd_fixed_rd();
`uvm_info("DRV", "Fixed Mode Read Transaction Started", UVM_NONE);
@(posedge vif.clk);
@(negedge vif.rlast);
vif.arvalid <= 1'b0;
vif.rready <= 1'b0;
endtask
//////////////////////////////////////////////////////////////////////
task wrrd_incr_wr();
/////////////////////////write logic
`uvm_info("DRV", "INCR Mode Write Transaction Started", UVM_NONE);
vif.resetn <= 1'b1;
vif.awvalid <= 1'b1;
vif.awid <= tr.id;
vif.awlen <= 7;
vif.awsize <= 2;
vif.awaddr <= 5;
vif.awburst <= 1;
@(posedge vif.wready);
@(posedge vif.clk);
endtask
@(negedge vif.rlast);
vif.arvalid <= 1'b0;
vif.rready <= 1'b0;
endtask
//////////////////////////////////////////////////////////////////////////////
task wrrd_wrap_wr();
`uvm_info("DRV", "WRAP Mode Write Transaction Started", UVM_NONE);
/////////////////////////write logic
vif.resetn <= 1'b1;
vif.awvalid <= 1'b1;
vif.awid <= tr.id;
vif.awlen <= 7;
vif.awsize <= 2;
vif.awaddr <= 5;
vif.awburst <= 2;
@(posedge vif.wready);
@(posedge vif.clk);
@(negedge vif.bvalid);
vif.bready <= 1'b0;
vif.wlast <= 1'b0;
endtask
@(negedge vif.rlast);
vif.arvalid <= 1'b0;
vif.rready <= 1'b0;
endtask
//////////////////////////////////////////////////////////////////////////
task err_wr();
`uvm_info("DRV", "Error Write Transaction Started", UVM_NONE);
/////////////////////////write logic
@(posedge vif.wready);
@(posedge vif.clk);
@(negedge vif.bvalid);
vif.bready <= 1'b0;
vif.wlast <= 1'b0;
endtask
endtask
////////////////////////////////////////////////////////////////////////
seq_item_port.get_next_item(tr);
if(tr.op == rstdut)
reset_dut();
else if (tr.op == wrrdfixed)
begin
`uvm_info("DRV", $sformatf("Fixed Mode Write -> Read WLEN:%0d WSIZE:%0d",tr.awlen+1,tr.awsize),
UVM_MEDIUM);
wrrd_fixed_wr();
wrrd_fixed_rd();
end
else if (tr.op == wrrdincr)
begin
`uvm_info("DRV", $sformatf("INCR Mode Write -> Read WLEN:%0d WSIZE:%0d",tr.awlen+1,tr.awsize),
UVM_MEDIUM);
wrrd_incr_wr();
wrrd_incr_rd();
end
else if (tr.op == wrrdwrap)
begin
`uvm_info("DRV", $sformatf("WRAP Mode Write -> Read WLEN:%0d WSIZE:%0d",tr.awlen+1,tr.awsize),
UVM_MEDIUM);
wrrd_wrap_wr();
wrrd_wrap_rd();
end
else if (tr.op == wrrderrfix)
begin
`uvm_info("DRV", $sformatf("Error Transaction Mode WLEN:%0d WSIZE:%0d",tr.awlen+1,tr.awsize), UVM_MEDIUM);
err_wr();
err_rd();
end
seq_item_port.item_done();
end
endtask
endclass
///////////////////////////////////////////////////////////////////////
transaction tr;
virtual axi_if vif;
logic resp;
int err = 0;
/////////////////////////////////////////////////////////////////////////
task compare();
if(err == 0 && rdresp == 0 && wrresp == 0 )
begin
`uvm_info("MON", $sformatf("Test Passed err :%0d wrresp :%0d rdresp :%0d ", err, rdresp, wrresp), UVM_MEDIUM);
err = 0;
end
else
begin
`uvm_info("MON", $sformatf("Test Failed err :%0d wrresp :%0d rdresp :%0d ", err, rdresp, wrresp), UVM_MEDIUM);
err = 0;
end
endtask
///////////////////////////////////////////////////////////////////////
virtual task run_phase(uvm_phase phase);
forever begin
@(posedge vif.clk);
if(!vif.resetn)
begin
`uvm_info("MON", "System Reset Detected", UVM_MEDIUM);
end
wait(vif.awvalid == 1'b1);
// @(negedge vif.wlast);
@(posedge vif.bvalid);
wrresp = vif.bresp;///0
//////////////////////////////////////////////////////
wait(vif.arvalid == 1'b1);
@(posedge vif.rlast);
rdresp = vif.rresp;
compare();
$display("------------------------------");
end
@(posedge vif.bvalid);
wrresp = vif.bresp;
wait(vif.arvalid == 1'b1);
@(posedge vif.rlast);
rdresp = vif.rresp;
compare();
$display("------------------------------");
end
end
endtask
endclass
///////////////////////////////////////////////////////////
class agent extends uvm_agent;
`uvm_component_utils(agent)
driver d;
uvm_sequencer#(transaction) seqr;
mon m;
endfunction
endclass
////////////////////////////////////////////////////////////////////////////////
agent a;
endfunction
endclass
//////////////////////////////////////////////////
class test extends uvm_test;
`uvm_component_utils(test)
env e;
valid_wrrd_fixed vwrrdfx;
valid_wrrd_incr vwrrdincr;
valid_wrrd_wrap vwrrdwrap;
err_wrrd_fix errwrrdfix;
phase.drop_objection(this);
endtask
endclass
/////////////////////////////////////////////////////////////////////
module tb;
axi_if vif();
axi_slave dut (vif.clk, vif.resetn, vif.awvalid, vif.awready, vif.awid, vif.awlen, vif.awsize, vif.awaddr, vif.awburst, vif.wvalid,
vif.wready, vif.wid, vif.wdata, vif.wstrb, vif.wlast, vif.bready, vif.bvalid, vif.bid, vif.bresp , vif.arready, vif.arid, vif.araddr,
vif.arlen, vif.arsize, vif.arburst, vif.arvalid, vif.rid, vif.rdata, vif.rresp,vif.rlast, vif.rvalid, vif.rready);
initial begin
vif.clk <= 0;
end
initial begin
uvm_config_db#(virtual axi_if)::set(null, "*", "vif", vif);
run_test("test");
end
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
endmodule
https://verificationguide.com/systemverilog-examples/systemverilog-testbench-example-with-scb/
https://www.edaplayground.com/x/bZG
1]
1]
Video 2 Part1 :
UVM Environment
UVM Agent
UVM Hierarchy
Video 2 Part2 :
MV Video Screenshot Page 146
Object is used for stimulus generation purpose
1] Factory Registration
3] Registering object
4] Default Constructor
UVM_TOP Ha UVM_ROOT cha pointer aahe manje. UVM_TOP ha UVM_ROOT la point out karto.
Jenva aapan run_test() call karto tenva to test class ha null la point karto manje
UVM_TOP la jaate
uvm_top chya khali UVM_TEST_TOP create hoto. Nanter env create karat karat to khali jaato.
Create method ha type_id chya class madhe jaato and tithe jo construct aahe tyla call karto.
Jar aapan new method cha use kela tar te fkt class handle chya construct madhe jaato. Overridding saathi factory cha
use kela jaato.
2] Factory override method madhe type id nusar hote. Factroy override kartana nehami tychya hierchay madhe je
kahi component aahe tycha varti class madhe define karave overide method.
3]
Factory Overideing
Virtual sequence
https://verificationacademy.com/cookbook/sequences/virtual
The UVM factory is used to create UVM objects and components. This is commonly known as factory registration. The factory
registration for UVM objects and components are lightweight proxies to the actual objects and components.
<instance_name> = <type>::<type_id>::create("<name>")
Example :
class env extends uvm_env;
`uvm_component_utils(env)
mycomponent compA;
param_component #(.WIDTH(8), .ID(1)) compB;
// object creation
seqA = mysequence::type_id::create("seqA");
seqB = param_sequence #(8,1)::type_id::create("seqB");
...
...
endtask
endclass
https://www.linkedin.com/pulse/uvm-factory-overrides-sanjana-pisal/
Based on the requirement, the behavior of the testbench can be changed by substituting one class with another when it
is constructed. This facility of the uvm factory allows users to override the class without editing or recompiling the code.
2] Using the polymorphism concept, the factory override mechanism returns a derived type handle using a base type
handle. This means when the create method is being called for the base class type, uvm_factory will return a pointer to
an object of a derived class type.
Note: The factory override ways are applicable for both uvm components and
uvm objects.
In a type override, a substitute component class type is created instead of an original component class in the testbench
hierarchy. This applies to all instances of that component type.
Syntax :
Code 1 :
`define RAM_WIDTH 8
`define ADDR_SIZE 4
`uvm_object_utils_begin(parent)
`uvm_field_int(din,UVM_ALL_ON +UVM_DEC)
`uvm_field_int(addr,UVM_ALL_ON +UVM_DEC)
`uvm_field_int(er_enb,UVM_ALL_ON +UVM_DEC)
`uvm_object_utils_end
}
endclass
module tb();
parent p;
function void build();
p=parent::type_id::create("p");
p.randomize();
p.print();
endfunction
uvm_factory factory=uvm_factory::get(); // from uvm 1.2 version we need to use it
initial
begin
// repeat(5)
build();
factory.set_type_override_by_type (parent::get_type(),child::get_type());
//repeat(5)
build();
end
endmodule
Output:
-------------------------------
Name Type Size Value
-------------------------------
p parent - @336
din integral 8 'd16
addr integral 4 'd5
er_enb integral 1 1
-------------------------------
-------------------------------
Name Type Size Value
-------------------------------
p child - @340
din integral 8 'd12
addr integral 4 10
Some changes:
Code:
`include "uvm_macros.svh";
import uvm_pkg::*;
`define RAM_WIDTH 8
`define ADDR_SIZE 4
module tb();
child p;
function void build();
p=child::type_id::create("p");
p.randomize();
p.print();
endfunction
uvm_factory factory=uvm_factory::get(); // from uvm 1.2 version we need to use it
initial
begin
build();
factory.set_type_override_by_type (child::get_type(),parent::get_type());
build();
end
endmodule
Code 2 :
`include "uvm_macros.svh"
import uvm_pkg::*;
function display();
`uvm_info(get_type_name(), "inside component_B", UVM_LOW);
endfunction
endclass
set_type_override_by_type(component_A::get_type(), component_B::get_type());
comp_A = component_A::type_id::create("comp_A", this);
factory.print();
endfunction
module tb_top;
initial begin
run_test("my_test");
end
endmodule
Output:
UVM_INFO @ 0: reporter [UVMTOP] UVM testbench topology:
# --------------------------------------
# Name Type Size Value
# --------------------------------------
# uvm_test_top my_test - @466
# comp_A component_B - @473
# --------------------------------------
#
# UVM_INFO first.sv(24) @ 0: uvm_test_top.comp_A [component_B] inside component_B
#
# --- UVM Report Summary ---
#
# ** Report counts by severity
# UVM_INFO : 5
# UVM_WARNING : 0
# UVM_ERROR : 0
# UVM_FATAL : 0
# ** Report counts by id
# [Questa UVM] 2
# [RNTST] 1
# [UVMTOP] 1
# [component_B] 1
# ** Note: $finish : C:/questasim64_10.7c/win64/../verilog_src/uvm-1.1d/src/base/uvm_root.svh(430)
# Time: 0 ns Iteration: 215 Instance: /tb_top
#1
# Break in Task uvm_pkg/uvm_root::run_test at C:/questasim64_
10.7c/win64/../verilog_src/uvm-1.1d/src/base/uvm_root.svh line 430
# quit -sim
# End time: 12:54:44 on Jun 01,2023, Elapsed time: 0:00:52
Code :
`include "uvm_macros.svh"
function display();
`uvm_info(get_type_name(), "inside component_B", UVM_LOW);
endfunction
endclass
set_inst_override_by_type("comp_A",component_A::get_type(), component_B::get_type());
comp_A = component_A::type_id::create("comp_A", this);
factory.print();
endfunction
module tb_top;
initial begin
run_test("my_test");
end
endmodule
Output:
####
#
# UVM_INFO @ 0: reporter [UVMTOP] UVM testbench topology:
# --------------------------------------
# Name Type Size Value
# --------------------------------------
# uvm_test_top my_test - @466
# comp_A component_B - @473
# --------------------------------------
#
# UVM_INFO first.sv(24) @ 0: uvm_test_top.comp_A [component_B] inside component_B
#
# --- UVM Report Summary ---
Munsif Example
`include "uvm_macros.svh";
import uvm_pkg::*;
`define RAM_WIDTH 8
`define ADDR_SIZE 4
`uvm_object_utils_begin(parent)
`uvm_field_int(din,UVM_ALL_ON +UVM_DEC)
`uvm_field_int(addr,UVM_ALL_ON +UVM_DEC)
`uvm_field_int(er_enb,UVM_ALL_ON +UVM_DEC)
`uvm_object_utils_end
}
endclass
module tb();
parent p;
function void build();
p=parent::type_id::create("p");
p.randomize();
p.print();
endfunction
initial
begin
repeat(2)
build();
factory.set_type_override_by_type (parent::get_type(),child::get_type());
repeat(2)
build();
end
endmodule
Output:
• Severity
○ Severity indicates importance
○ Examples are Fatal, Error, Warning & Info
• Verbosity
○ Verbosity indicates filter level
○ Examples are None, Low, Medium, High, Full & Debug
• Simulation Handling Behavior
○ Simulation handling behavior controls simulator behavior
○ Examples are Exit, Count, Display, Log, Call Hook & No Action
UVM Reporting provides Macros to embed report messages. Followings are the UVM Macros to be used:
From the syntax of the above mentioned Macros it is very well evident how we can embed the message of our choice with
a particular macro. The provided message ID helps in easy search, e.g. grep, in the simulation log. In addition, total
count of a particular severity can also be seen using message ID at the end of the simulation log.
Keypoints:
1) Verilog $display does not provide a Filtering facility whereas UVM provides the Message filtering capabilities to notify
only important messages to the User.
2) Verbosity level is used for filtering the message so the `uvm_info messages which possess verbosity level less than or
equal to the current configure verbosity level will be sent to the Console.
3) UVM reporting Services are built-in for all the components hence can be utilized in any UVM component. They are
derived from UVM_REPORT_OBJECT class.
4) string id is used for filtering. The UVM reporting macros API's (`uvm_info, `uvm_warning, etc.) are recommended over
default Messaging API's (`uvm_report_info) because macro API first perform verbosity level check before working on the
String messages.
5) `uvm_warning, `uvm_error, and `uvm_fatal have default Verbosity hence will always be displayed on the console to
notify bugs inside the design. The verbosity level of warning,error,fatal is UVM_NONE.
6) Default Verbosity level of `uvm_info is UVM_MEDIUM. But most of the time we use the UVM_NONE verbosity to print
all message.
Code1 :
import uvm_pkg::*;
`include "uvm_macros.svh"
module tb;
initial
begin
`uvm_info("MOD","the info statement 1",UVM_NONE);
`uvm_warning("MOD","the warning statement");
`uvm_error("MOD","the error statement");
`uvm_fatal("MOD","the fatal error statement");
`uvm_info("MOD","the info statement 2",UVM_NONE);
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Without uvm_fatal:
A class library consists of a collection of classes to allow the implementation of the entire testbench
environment.uvm_pkg is the library file consisting of all the UVM files required to perform Formal Verification in the
Single System Verilog Package file. Users need to compile the package file outside the module.
Vivado comes with the precompiled UVM version 1.2 library hence we need not include or compile
`include "uvm_pkg.svh"
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
task runp();
`uvm_info("verobosity1",$sformatf("class member execution 1"),UVM_LOW);
`uvm_info("verobosity2",$sformatf("class member execution 2"),UVM_HIGH);
endtask
endclass
module tb();
verbosity v;
initial
begin
v=new("DIS",null);
v.set_report_verbosity_level(UVM_FULL);
v.runp();
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Note:
Ethe
UVM_INFO testbench.sv(12) @ 0: DIS [verobosity1] class member execution 1
ha aapan jenva object create karto tenva takle jaate.
Some Changes:
module tb();
verbosity v;
initial
begin
v=new("DIS",null);
v.set_report_verbosity_level(UVM_MEDIUM);
v.runp();
end
endmodule
Output :
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Ethe aata `uvm_info("verobosity2",$sformatf("class member execution 2"),UVM_HIGH); he line print nahi zali aahe
karan aapan aata verbosity level ha UVM_MEDIUM kele aahe .
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
task runp();
`uvm_info("verobosity1",$sformatf("class member execution 1"),UVM_LOW);
`uvm_info("verobosity2",$sformatf("class member execution 2"),UVM_HIGH);
endtask
endclass
module tb();
verbosity v;
int a;
initial
begin
v=new("DIS");
v.set_report_verbosity_level(UVM_MEDIUM);
v.runp();
a=v.get_report_verbosity_level();
`uvm_info("MOD",$sformatf("value of verbosity =%0d",a),UVM_NONE);
end
endmodule
Output :
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Note:
ethe class che verbosity milte. Tymule aapan get method cha use kela aahe.
Code :
`uvm_object_utils_begin(dis)
`uvm_field_int(din, UVM_DEFAULT);
`uvm_object_utils_end
task run();
`uvm_info("DIS", $sformatf("Value of DIN : %0d",din),UVM_NONE);
endtask
endclass
module tb;
dis d1;
integer level;
initial begin
d1 = new("DIS");
level = d1.get_report_verbosity_level;
`uvm_info("INFO",$sformatf("Ver Level : %0d",level),UVM_NONE);
d1.randomize;
d1.run;
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
module tb();
int a;
initial
begin
#45;
`uvm_info("TB","hello word in uvm_info statement",UVM_NONE);
$display("hello word in display statement");
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Output madhe kontya file madhun uvm_info print zale aahe te kalte ex. Testbench.sv(10)
Output madhe konty time la uvm_info print zale te kalte : ex .45
String ID cha message print hoto.
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
module tb();
initial
begin
`uvm_info("TB","inside the uvm_none",UVM_NONE);
`uvm_info("TB","inside the uvm_low",UVM_LOW);
`uvm_info("TB","inside the uvm_medium",UVM_MEDIUM);
`uvm_info("TB","inside the uvm_high",UVM_HIGH);
`uvm_info("TB","inside the uvm_full",UVM_FULL);
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Note:
1] Ethe uvm_info print hotana default verbosity hi uvm_medium aahe. Tymule uvm_medium chya khaleche serve print
hotata manje UVM_LOW, UVM_NONE, UVM_MEDIUM print hotat.
2] Ethe aata uvm_HIGH,UVM_FULL print nahi hote. Karan aapan ethe verbosity level set nahi kele aahe.
Some changes:
1] initial
begin
uvm_top.set_report_verbosity_level(UVM_FULL);
end
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Note : ethe uvm_top ghetale aahe karan aapan set module tb saathi karat aahot tymule. Uvm_top ha uvm_root cha
handle aahe.
2] Run option madhe +UVM_VERBOSITY=UVM_FULL ya switch cha use karava. Ya switch cha use kela ne jevdhe kahi
UVM_INFO statement aahe tyche verbosity level change hote
module tb();
initial
begin
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Note:
1] Ethe aapan +UVM_VERBOSITY=UVM_FULL ya switch cha use kela tymule ethe serve print zale aahe
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
task run();
`uvm_info("drv1"," info 1",UVM_NONE);
`uvm_info("drv1"," info 2",UVM_MEDIUM);
`uvm_info("drv2"," info 3",UVM_MEDIUM);
`uvm_info("drv2"," info 4",UVM_HIGH);
endtask
endclass
module tb();
driver d;
initial
begin
d=new("driver1",null);
d.set_report_id_verbosity("drv1",UVM_LOW);
d.run();
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Note:
1] varti je output aahe tithe string drv1 che fkt one statement che print zale aahe. Karan tithe drv1 che verbosity level
change kele aahe
Code :
`include "uvm_macros.svh"
import uvm_pkg::*;
/////////////////////////////////////////////////
class driver extends uvm_monitor;
`uvm_component_utils(driver);
task run();
`uvm_info("DRV","driver code executed",UVM_HIGH);
endtask
endclass
/////////////////////////////////////////////////
class monitor extends uvm_monitor;
`uvm_component_utils(monitor);
task run();
`uvm_info("MON","monitor code executed",UVM_NONE);
endtask
endclass
driver drv;
monitor mon;
task run();
drv=new("drv",this);
mon=new("mon",this);
drv.run();
mon.run();
module tb();
env e;
Output:
UVM_INFO testbench.sv(13) @ 0: env.drv [DRV] driver code executed
UVM_INFO testbench.sv(26) @ 0: env.mon [MON] monitor code executed
UVM_INFO testbench.sv(46) @ 0: env [ENV] envirnment class executed
VCS Simulation Report
Time: 0 ns
Code :
`include "uvm_macros.svh"
import uvm_pkg::*;
class driver extends uvm_monitor;
`uvm_component_utils(driver);
task run();
`uvm_info("drv","uvm_info print",UVM_NONE);
`uvm_warning("drv","uvm_warning print");
`uvm_error("drv","uvm_error print");
`uvm_fatal("drv","uvm_fatal print");
endtask
endclass
module tb();
driver d;
initial
begin
d=new("env",null);
d.set_report_severity_override(UVM_FATAL,UVM_ERROR);
d.run();
end
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Some changes:
Code :
module tb();
int a;
driver d1;
initial
begin
d1=new("drivernew",null);
d1.set_report_verbosity_level(UVM_LOW);
d1.set_report_severity_override(UVM_FATAL,UVM_INFO);
d1.rund();
a=d1.get_report_verbosity_level();
$display("value of verbosity level=%0d",a);
end
endmodule
Output:
UVM_INFO testbench.sv(13) @ 10: drivernew [drv] inside the info driver 1
UVM_ERROR testbench.sv(14) @ 10: drivernew [drv] inside the error driver1
UVM_WARNING testbench.sv(15) @ 10: drivernew [drv] inside the warning driver1
UVM_INFO testbench.sv(16) @ 10: drivernew [drv1] inside the fatal driver1
value of verbosity level=100
VCS Simulation Report
Time: 10 ns
CPU Time: 0.820 seconds; Data structure size: 0.1Mb
Mon Feb 20 22:52:03 2023
Note:
1] Jar aapan class cha verbosity change keli pan tycha kahi effect nahi zala UVM_FATAL ----> UVM_INFO kartana
2] UVM_FATAL che UVM_INFO zale tar tyche default verbosity hi UVM_MEDIUM aasayela pahije pan tase hote nahi. Te
direct print karte class cha verbosity pahat nahi.
Code
`include "uvm_macros.svh";
import uvm_pkg::*;
task run();
`uvm_info("drv","inside the info",UVM_NONE);
`uvm_warning("drv","inside the warning");
`uvm_fatal("drv","inside the fatal drv");
`uvm_error("drv","inside the error");
`uvm_fatal("drv1","inside the fatal in drv1");
endtask
endclass
module tb();
driver d;
initial
begin
d=new("DRV",null);
d.set_report_severity_id_override(UVM_FATAL,"drv",UVM_ERROR); // tag ha drv aahe titche fkt apply karta yeto
d.run();
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
set_report_max_quit_count(3) . Ya function cha use hote uvm_error count karnyasaathi. Ethe aapan bracket madhe
uvm_error count chi limit set karu shakto.
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
task run();
`uvm_info("drv","inside the info",UVM_NONE);
`uvm_warning("drv","inside the warning");
`uvm_error("drv","inside the error1");
`uvm_error("drv","inside the error2");
`uvm_error("drv","inside the error3");
`uvm_error("drv","inside the error4");
`uvm_error("drv","inside the error5");
endtask
endclass
module tb();
driver d;
initial
begin
d=new("DRV",null);
d.set_report_max_quit_count(3);
d.run();
end
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
UVM Classes=Low
1] jn uvm che object nehami use kele jatat tyna aapan uvm_component manto . Tyche nature he statsic aaste.
Je object jenva kaam padle tenvache use kele jatat tyna aapan uvm_object aase manto. Tyche nature he dynamic aaste.
Flow of execaution
1] Jar aapan uvm filed macro use nahi kela uvm object madhe tar aaapn print() sarkhe core method cha use nahi karu
shakat .
1] Introduction
2]
Jar field macros ne che jar aapan object la define kela tar che aapan print,compare,copy method cha use karta yeto
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
module tb();
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
value of a=1
----------------------------
Name Type Size Value
----------------------------
object object1 - @336 /////////// value he different aahe.
----------------------------
VCS Simulation Report
Time: 0 ns
CPU Time: 0.800 seconds; Data structure size: 0.1Mb
Fri Jan 6 23:49:28 2023
2] code for uvm_object regsistration with field macro in factory using begin end
(maximum time uvm_object saathiche use karave)
https://verificationacademy.com/verification-methodology-reference/uvm/docs_1.1c/html/files/macros/uvm_object_defines-
svh.html
module tb();
object1 obj;
initial
begin
obj=new("object");
obj.randomize();
$display("value of a=%0d",obj.a);
obj.print();
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
value of a=1
-----------------------------
Name Type Size Value
-----------------------------
object object1 - @336
a integral 3 'h1 ////// value same aahe karan object field macro ne define kela aahe
-----------------------------
VCS Simulation Report
Time: 0 ns
CPU Time: 0.720 seconds; Data structure size: 0.1Mb
Fri Jan 6 23:45:28 2023
3] code for ENUM,Real,String data type object print using field macro
Code :
`include "uvm_macros.svh"
import uvm_pkg::*;
`uvm_object_utils_begin(obj)
`uvm_field_enum(state_type, state, UVM_DEFAULT); // two time define karave legel variable
`uvm_field_string(str,UVM_DEFAULT);
`uvm_field_real(temp, UVM_DEFAULT);
`uvm_object_utils_end
endclass
module tb;
obj o;
initial begin
o = new("obj");
o.randomize();
o.print;
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
------------------------------------
Name Type Size Value
------------------------------------
obj obj - @336
state state_type 4 s1
str string 3 UVM
temp real 64 12.340000
------------------------------------
VCS Simulation Report
Time: 0 ns
CPU Time: 0.540 seconds; Data structure size: 0.1Mb
Sat Jan 7 00:36:47 2023
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
module tb();
object1 obj;
int i;
initial
begin
obj=new("object");
obj.randomize();
$display("value of a=%0d",obj.a[i]);
obj.print();
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
value of a=163
----------------------------------
Name Type Size Value
Code :
`include "uvm_macros.svh"
import uvm_pkg::*;
////////static array
int arr1[3] = {1,2,3};
///////Dynamic array
int arr2[];
///////Queue
int arr3[$];
////////Associative array
int arr4[int];
`uvm_object_utils_begin(array)
`uvm_field_sarray_int(arr1, UVM_DEFAULT);
`uvm_field_array_int(arr2, UVM_DEFAULT);
`uvm_field_queue_int(arr3, UVM_DEFAULT);
`uvm_field_aa_int_int(arr4, UVM_DEFAULT);
`uvm_object_utils_end
task run();
///////////////////Queue
////////////////////Associative arrays
arr4[1] = 4;
arr4[2] = 4;
arr4[3] = 4;
arr4[4] = 4;
endtask
endclass
////////////////////////////////////////////
module tb;
array a;
initial begin
a = new("array");
a.run();
a.print();
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
# with `UVM_OBJECT_MUST_HAVE_CONSTRUCTOR undefined.
# See http://www.eda.org/svdb/view.php?id=3770 for more details.
#
# (Specify +UVM_NO_RELNOTES to turn off this notice)
#
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(215) @ 0: reporter [Questa UVM]
QUESTA_UVM-1.2.3
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(216) @ 0: reporter [Questa UVM]
questa_uvm::init(+struct)
# ----------------------------------
# Name Type Size Value
# ----------------------------------
# array array - @466
# arr1 sa(integral) 3 -
# [0] integral 32 'h1
# [1] integral 32 'h2
# [2] integral 32 'h3
# arr2 da(integral) 3 -
# [0] integral 32 'h2
# [1] integral 32 'h2
# [2] integral 32 'h2
# arr3 da(integral) 2 -
# [0] integral 32 'h3
# [1] integral 32 'h3
# arr4 aa(int,int) 4 -
# [1] integral 32 'h4
# [2] integral 32 'h4
# [3] integral 32 'h4
# [4] integral 32 'h4
# ----------------------------------
a] Copy Method
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
module tb();
object1 first;
object1 second;
initial
begin
first=new("first");
second=new("second"); // ye method madhe aapan new data cha memory create keli .
first.randomize();
first.print();
second.copy(first); // target.copy(start)
second.print(); /aapan field macros che copy method ne first madhla data second madhe copy kela
first.print();
end
endmodule
Output :
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
----------------------------
Name Type Size Value
----------------------------
first object1 - @336
a integral 8 'hb9
----------------------------
-----------------------------
Name Type Size Value
-----------------------------
second object1 - @337
a integral 8 'hb9
-----------------------------
----------------------------
Name Type Size Value
----------------------------
first object1 - @336
a integral 8 'hb9
----------------------------
VCS Simulation Report
Time: 0 ns
CPU Time: 0.840 seconds; Data structure size: 0.1Mb
Sat Jan 7 01:02:00 2023
b] Compare Method
Target.compare(start);
`uvm_object_utils_begin(trial)
`uvm_field_int(a,UVM_DEFAULT)
`uvm_object_utils_end
task runt();
`uvm_info("class","inside the class",UVM_NONE);
endtask
endclass
module tb();
int status;
trial t1;
trial t2;
initial
begin
t1=new("trial1new");
t2=new("trial2new");
t1.randomize();
t2.randomize();
t1.print();
t2.print();
status=t2.compare(t1); // ethe status dhalvale jaate jar same asel tar output 1 nahir zero(0)
$display("value of status=%0d",status);
t1.runt();
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
# with `UVM_OBJECT_MUST_HAVE_CONSTRUCTOR undefined.
# See http://www.eda.org/svdb/view.php?id=3770 for more details.
#
# (Specify +UVM_NO_RELNOTES to turn off this notice)
#
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(215) @ 0: reporter [Questa UVM]
QUESTA_UVM-1.2.3
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(216) @ 0: reporter [Questa UVM]
questa_uvm::init(+struct)
# --------------------------------
# Name Type Size Value
# --------------------------------
# trial1new trial - @466
# a integral 5 'h17
# --------------------------------
Some changes:
class trial extends uvm_object;
bit[4:0] a=12;
`uvm_object_utils_begin(trial)
`uvm_field_int(a,UVM_DEFAULT)
`uvm_object_utils_end
module tb();
int status;
trial t1;
trial t2;
initial
begin
t1=new("trial1new");
t2=new("trial2new");
t1.print();
t2.print();
status=t2.compare(t1);
$display("value of status=%0d",status);
t1.runt();
end
Output:
You are using a version of the UVM library that has been compiled
# with `UVM_OBJECT_MUST_HAVE_CONSTRUCTOR undefined.
# See http://www.eda.org/svdb/view.php?id=3770 for more details.
#
# (Specify +UVM_NO_RELNOTES to turn off this notice)
#
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(215) @ 0: reporter [Questa UVM]
QUESTA_UVM-1.2.3
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(216) @ 0: reporter [Questa UVM]
questa_uvm::init(+struct)
# --------------------------------
# Name Type Size Value
# --------------------------------
# trial1new trial - @466
# a integral 5 'hc
# --------------------------------
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
`uvm_object_utils_begin(first);
`uvm_field_int(data, UVM_DEFAULT);
`uvm_object_utils_end
`uvm_object_utils_begin(new_first);
`uvm_field_int(ack,UVM_DEFAULT);
`uvm_object_utils_end
Output:
You are using a version of the UVM library that has been compiled
# with `UVM_OBJECT_MUST_HAVE_CONSTRUCTOR undefined.
# See http://www.eda.org/svdb/view.php?id=3770 for more details.
#
# (Specify +UVM_NO_RELNOTES to turn off this notice)
#
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(215) @ 0: reporter [Questa UVM]
QUESTA_UVM-1.2.3
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(216) @ 0: reporter [Questa UVM]
questa_uvm::init(+struct)
# ------------------------------
# Name Type Size Value
# ------------------------------
#f new_first - @473
# data integral 4 'h9 // old and new data print hoto ethe
# ack integral 4 'h4 //new data pan print hoto ethe
# ------------------------------
# quit -sim
# End time: 17:08:00 on Feb 22,2023, Elapsed time: 0:00:06
# Errors: 0, Warnings: 1
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
`uvm_object_utils_begin(first);
`uvm_field_int(data, UVM_DEFAULT);
`uvm_object_utils_end
`uvm_object_utils_begin(new_first);
`uvm_field_int(ack,UVM_DEFAULT);
`uvm_object_utils_end
module tb();
comp c;
initial
begin
c.set_type_override_by_type(first::get_type,new_first::get_type);
c=new("comp",null);
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
# with `UVM_OBJECT_MUST_HAVE_CONSTRUCTOR undefined.
# See http://www.eda.org/svdb/view.php?id=3770 for more details.
#
# (Specify +UVM_NO_RELNOTES to turn off this notice)
#
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(215) @ 0: reporter [Questa UVM]
QUESTA_UVM-1.2.3
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(216) @ 0: reporter [Questa UVM]
questa_uvm::init(+struct)
# -----------------------------
# Name Type Size Value
# -----------------------------
#f first - @473
# data integral 4 'h9 // new data print hote nahi new method ne
# -----------------------------
# quit -sim
# End time: 17:14:15 on Feb 22,2023, Elapsed time: 0:00:07
# Errors: 0, Warnings: 1
2] Clone method
a] Casting in systemverilog
Static casting
• SystemVerilog static casting is not applicable to OOP
• Static casting converts one data type to another compatible data types (example string to int)
• As the name says ‘Static’, the conversion data type is fixed
• Static casting will be checked during compilation, so there won’t be run-time checking and error reporting
• Casting is applicable to value, variable or to an expression
• A data type can be changed by using a cast ( ‘ ) operation
• The vale/variable/expression to be cast must be enclosed in parentheses or within concatenation or replication braces
Code :
module casting;
real r_a;
int i_a;
initial begin
r_a = (2.1 * 3.2);
//real to integer conversion
i_a = int'(2.1 * 3.2); //or i_a = int'(r_a);
Output:
CPU time: .424 seconds to compile + .551 seconds to elab + .728 seconds to link
Chronologic VCS simulator copyright 1991-2021
Contains Synopsys proprietary information.
Compiler version S-2021.09; Runtime version S-2021.09; Jan 7 01:28 2023
real value is 6.720000
int value is 7
VCS Simulation Report
Time: 0 ns
CPU Time: 0.700 seconds; Data structure size: 0.0Mb
Sat Jan 7 01:28:19 2023
Dynamic casting
• Dynamic casting is used to, safely cast a super-class pointer (reference) into a subclass pointer (reference) in a class
However, it is legal to assign a super-class (parent class) handle to a subclass (child class) variable if the super-class (parent
class) handle refers to an object of the given subclass(child class).
parent_class = child_class ;
child_class = parent_class; //allowed because parent_class is pointing to child_class.
Though parent_class is pointing to the child_class, we will get a compilation error saying its not compatible type for the
assignment.
This we can over come by make use of $cast method, i.e,
$cast(child_class,parent_class);
class parent_class;
int data;
function display();
$display("value of data=%0d",data);
endfunction
endclass
function display();
super.display();
$display("value of addr=%0d",addr);
endfunction
endclass
module tb();
parent_class p=new();
child_class c=new();
initial
begin
c.data=20;
c.addr=30;
c.display();
end
endmodule
Output:
3] UVM Object LOW Page 223
Output:
Contains Synopsys proprietary information.
Compiler version S-2021.09; Runtime version S-2021.09; Jan 7 01:38 2023
value of data=20
value of addr=30
VCS Simulation Report
Time: 0 ns
CPU Time: 0.660 seconds; Data structure size: 0.0Mb
Sat Jan 7 01:38:33 2023
Some changes:
1]
2] Clone method
a] Casting in systemverilog
Casting is a process of converting from one data type into another data type for compatibility
In Manufacturing, Casting is a process in which liquid metal is converted into the desired object. Similarly,
SystemVerilog casting means the conversion of one data type to another datatype. During value or variable assignment to
a variable, it is required to assign value or variable of the same data type. Some situations need assignment of different
data type, in such situations, it is necessary to convert data type and assign. Otherwise, the assignment of different data
type results in a compilation error. The method of data type conversion is called casting.
In systemVerilog, there are two types of casting,
• Static casting
• Dynamic casting
Static casting
• SystemVerilog static casting is not applicable to OOP
• Static casting converts one data type to another compatible data types (example string to int)
• As the name says ‘Static’, the conversion data type is fixed
• Static casting will be checked during compilation, so there won’t be run-time checking and error reporting
• Casting is applicable to value, variable or to an expression
• A data type can be changed by using a cast ( ‘ ) operation
• The vale/variable/expression to be cast must be enclosed in parentheses or within concatenation or replication braces
Code :
real r_a;
int i_a;
initial begin
Output:
Compiler version S-2021.09; Runtime version S-2021.09; Nov 19 23:36 2022
real value is 6.720000
int value is 7
VCS Simulation Report
Time: 0 ns
CPU Time: 0.740 seconds; Data structure size: 0.0Mb
Sat Nov 19 23:36:30 2022
Dynamic casting
• Dynamic casting is used to, safely cast a super-class pointer (reference) into a subclass pointer (reference) in a class
hierarchy
• Dynamic casting will be checked during run time, an attempt to cast an object to an incompatible object will result
in a run-time error
• Dynamic casting is done using the $cast(destination, source) method
• With $cast compatibility of the assignment will not be checked during compile time, it will be checked during run-
time
However, it is legal to assign a super-class (parent class) handle to a subclass (child class) variable if the super-class (parent
class) handle refers to an object of the given subclass(child class).
parent_class = child_class ;
child_class = parent_class; //allowed because parent_class is pointing to child_class.
Though parent_class is pointing to the child_class, we will get a compilation error saying its not compatible type for the
assignment.
This we can over come by make use of $cast method, i.e,
$cast(child_class,parent_class);
class parent_class;
bit [31:0] addr;
function display();
function display();
super.display();
$display("Data = %0d",data);
endfunction
endclass
module inheritence;
initial begin
parent_class p=new();
child_class c=new();
c.addr = 10;
c.data = 20;
p = c; //assigning child class handle to parent class handle
c.display();
end
Endmodule
Output:
class parent_class;
bit [31:0] addr;
function display();
$display("Addr = %0d",addr);
endfunction
endclass
function display();
super.display();
$display("Data = %0d",data);
endfunction
endclass
module inheritence;
initial begin
parent_class p=new();
child_class c=new();
c.addr = 10;
c.data = 20;
c = p; //assigning child class handle to parent class handle
c.display();
end
endmodule
2 warnings
1 error
CPU time: .194 seconds to compile
Exit code expected: 0, received: 1
class parent_class;
bit [31:0] addr;
function display();
$display("Addr = %0d",addr);
endfunction
endclass
function display();
super.display();
$display("Data = %0d",data);
endfunction
endclass
module inheritence;
initial begin
parent_class p;
child_class c=new();
child_class c1;
c.addr = 10;
c.data = 20;
p = c; //p is pointing to child class handle c.
c1 = p; //type check fails during compile time.
c1.display();
end
endmodule
Output:
Error-[SV-ICA] Illegal class assignment
testbench.sv, 29
"c1 = p;"
Expression 'p' on rhs is not a class or a compatible class and hence cannot
be assigned to a class handle on lhs.
Source type: class $unit::parent_class
Target type: class $unit::child_class
Please make sure that the lhs and rhs expressions are compatible.
2 warnings
1 error
CPU time: .288 seconds to compile
Exit code expected: 0, received: 1
Code :
class parent_class;
bit [31:0] addr;
function display();
$display("Addr = %0d",addr);
endfunction
endclass
function display();
super.display();
$display("Data = %0d",data);
endfunction
endclass
module inheritence;
initial begin
parent_class p;
child_class c=new();
child_class c1;
c.addr = 10;
c.data = 20;
p = c; //p is pointing to child class handle c.
$cast(c1,p); //with the use of $cast, type chek will occur during runtime
c1.display();
end
endmodule
Output:
CPU time: .432 seconds to compile + .456 seconds to elab + .813 seconds to link
Chronologic VCS simulator copyright 1991-2021
Contains Synopsys proprietary information.
Compiler version S-2021.09; Runtime version S-2021.09; Nov 19 23:53 2022
Addr = 10
Data = 20
VCS Simulation Report
Time: 0 ns
CPU Time: 0.800 seconds; Data structure size: 0.0Mb
Sat Nov 19 23:53:10 2022
`include "uvm_macros.svh"
import uvm_pkg::*;
`uvm_object_utils_begin(first)
`uvm_field_int(data, UVM_DEFAULT);
`uvm_object_utils_end
endclass
initial begin
f = new("first");
f.randomize();
$cast(s, f.clone()); $cast cha use karun ethe clone method cha use kela aahe
f.print();
s.print();
end
endmodule
Output :
See http://www.eda.org/svdb/view.php?id=3770 for more details.
-----------------------------
Name Type Size Value
-----------------------------
first first - @336
data integral 4 'h9
-----------------------------
-----------------------------
Name Type Size Value
-----------------------------
first first - @337
data integral 4 'h9
-----------------------------
VCS Simulation Report
Time: 0 ns
CPU Time: 0.500 seconds; Data structure size: 0.1Mb
Set(context +instance_name+key+value)
Context,instance name,key value je aahet set an get same aasave kenva pan
Ethe set and get method che instance_name and key same aahe.
Jar component stastic asel tar ----------> null cha use karava EX. Module and endmodule cha part ha stastic aasto. Tithe context ha null cha use karto.
B] Instance name :
Ha instance name ha same aasla pahije set and get method cha
3] Key
Name of variable which value of we are sharing. Jo data aahe tychi
4] Value
Ethe variable che value lihavi kinva name of data where we hold the value.
1] set and get method che instance name same aasave. Instance name kahi pan thevu shakto aapan.
Uvm_config_db # (int) :: set(context,instance name in double code, key value in double coat,source of data)
Key value he generaaly variable che naav detat.
module top;
import uvm_pkg::*;
`include "uvm_macros.svh"
//AGENT
class agent extends uvm_component;
`uvm_component_utils(agent)
string s="default";
if(!uvm_config_db#(string)::get(this,"","NAME",s))
begin
`uvm_error(this.get_full_name(),"cant get the value in agent");
end
`uvm_info(this.get_full_name(),$psprintf("NAME:%s",s),UVM_LOW);
endfunction
endclass
//ENV
class env extends uvm_component;
`uvm_component_utils(env)
string m="default";
agent agent1,agent2;
agent1=agent::type_id::create("agent1",this);
agent2=agent::type_id::create("agent2",this);
`uvm_info(this.get_full_name(),$psprintf("NAME:%s",m),UVM_LOW);
endfunction
endclass
//Test Class
class my_test extends uvm_test;
`uvm_component_utils(my_test)
//creating ENV
env_h=env::type_id::create("env_h",this);
uvm_config_db#(string)::set(this,"env_h*","NAME","Rajat_Jain");
endfunction
endclass
initial
begin
run_test("my_test");
end
endmodule
endclass
endclass
module tb();
initial
begin
run_test("test");
end
endmodule
Output:
UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(215) @ 0: reporter [Questa UVM] QUESTA_UVM-1.2.3
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(216) @ 0: reporter [Questa UVM] questa_uvm::init(+struct)
# UVM_INFO @ 0: reporter [RNTST] Running test test...
# UVM_INFO first.sv(14) @ 0: uvm_test_top.env1 [env] inside the db and value of data=15
#
# --- UVM Report Summary ---
#
# ** Report counts by severity
# UVM_INFO : 4
# UVM_WARNING : 0
# UVM_ERROR : 0
# UVM_FATAL : 0
# ** Report counts by id
# [Questa UVM] 2
# [RNTST] 1
# [env] 1
# ** Note: $finish : C:/questasim64_10.7c/win64/../verilog_src/uvm-1.1d/src/base/uvm_root.svh(430)
# Time: 0 ns Iteration: 215 Instance: /tb
#1
# Break in Task uvm_pkg/uvm_root::run_test at C:/questasim64_10.7c/win64/../verilog_src/uvm-1.1d/src/base/uvm_root.svh line 430
# quit -sim
# End time: 15:42:21 on Mar 14,2023, Elapsed time: 0:08:12
# Errors: 0, Warnings: 0
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
class env extends uvm_env;
`uvm_component_utils(env);
int data;
endclass
endclass
module tb();
initial
begin
run_test("test");
end
endmodule
Output:
# (Specify +UVM_NO_RELNOTES to turn off this notice)
#
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(277) @ 0: reporter [Questa UVM] QUESTA_UVM-1.2.3
Some changes :
Code :
class test extends uvm_test;
`uvm_component_utils(test);
env e;
int send=15;
endclass
Output:
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(277) @ 0: reporter [Questa UVM] QUESTA_UVM-1.2.3
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(278) @ 0: reporter [Questa UVM] questa_uvm::init(+struct)
# UVM_INFO @ 0: reporter [RNTST] Running test test...
# UVM_INFO testbench.sv(37) @ 0: uvm_test_top [env] send value send=15
# UVM_ERROR testbench.sv(16) @ 0: uvm_test_top.env1 [env] else part and config db is not work
# UVM_FATAL @ 0: reporter [BUILDERR] stopping due to build errors
# UVM_INFO verilog_src/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]
# --- UVM Report Summary ---
#
# ** Report counts by severity
All UVM_Phase are used for class which is derived from UVM_COMPONENT.
UVM_PHASE is not applicable for UVM_OBJECT
The phases are an important concept in uvm that applies to all testbench components.
1] Each testbench component is derived from uvm_component that has predefined phases . They are represented as
callback methods. Hence, the user may implement these callbacks.
2] Each component can not move to the next phase unless the current phase execution is completed for all the components.
This provides proper synchronization between all the components.
3] UVM phases are executed in a certain order and all are virtual methods.
Few phases that consume simulation time for execution are implemented as tasks and other phases that do not consume
any simulation time are implemented as functions.
1] Build phases
To construct a testbench, it is necessary to build component objects first and then are connected to form a hierarchy, The
build phase category consists
connect_phase Connect different testbench component using the TLM port mechanism Bottom to top
end_of_elaborati Before simulation starts, this phase is used to make any final adjustment to the Bottom to top
on_phase structure, configuration, or connectivity of the testbench. It also displays UVM topology.
3] Clean up phases
The clean-up phases are used to collect information from functional coverage monitors and scoreboards to see whether the
coverage goal has been reached or the test case has passed. The cleanup phases will start once the run phases are
completed. They are implemented as functions and work from the bottom to the top of the component hierarchy. The
extract, check, and report phase may be used by analysis components.
check Checks DUT behaviour and identity for any error that occurred during the execution of the testbench. Bottom to
top
report Used to display simulation results. It can also write results to the file Bottom to
top
final Used to complete any outstanding actions that are yet to be completed in the testbench. Top to
down
2] Raise objection
Code 1:
`include "uvm_macros.svh";
import uvm_pkg::*;
`uvm_info("drv","reset_phase started",UVM_NONE);
#100;
`uvm_info("drv","reset_phase completed",UVM_NONE);
endtask
endclass
module tb();
initial
begin
run_test("driver");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
aapan aata raise and drop objection cha use kela aahe tymule aata aapan simulation to time delay gheto. To time delay
sampla ki next phase madhe entry gheto
Code 2:
`include "uvm_macros.svh";
import uvm_pkg::*;
`uvm_info("drv","reset_phase started",UVM_NONE);
#100;
`uvm_info("drv","reset_phase completed",UVM_NONE);
phase.drop_objection(this);
endtask
endclass
module tb();
initial
begin
run_test("driver");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
module tb();
initial
Result:
You are using a version of the UVM library that has been compiled
# with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
# See http://www.eda.org/svdb/view.php?id=3770 for more details.
#
# (Specify +UVM_NO_RELNOTES to turn off this notice)
#
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(277) @ 0: reporter [Questa UVM]
QUESTA_UVM-1.2.3
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(278) @ 0: reporter [Questa UVM]
questa_uvm::init(+struct)
# UVM_INFO @ 0: reporter [RNTST] Running test driver...
# UVM_INFO testbench.sv(13) @ 0: uvm_test_top [drv] reset phase started
# UVM_INFO testbench.sv(15) @ 10: uvm_test_top [drv] reset phase completed
# UVM_INFO testbench.sv(21) @ 10: uvm_test_top [drv] main phase started
# UVM_INFO testbench.sv(23) @ 110: uvm_test_top [drv] main phase complete
# UVM_INFO verilog_src/uvm-1.2/src/base/uvm_report_server.svh(847) @ 110: reporter [UVM/REPORT/SERVER]
# --- UVM Report Summary ---
#
# ** Report counts by severity
# UVM_INFO : 8
# UVM_WARNING : 0
# UVM_ERROR : 0
# UVM_FATAL : 0
# ** Report counts by id
# [Questa UVM] 2
# [RNTST] 1
# [UVM/RELNOTES] 1
# [drv] 4
#
# ** Note: $finish : /usr/share/questa/questasim/linux_x86_64/../verilog_src/uvm -1.2/src/base/uvm_root.svh(517)
# Time: 110 ns Iteration: 120 Instance: /tb
# End time: 04:01:25 on Dec 21,2022, Elapsed time: 0:00:08
# Errors: 0, Warnings: 2
Done
4] Ethe reset phase nanter che main phase start hote imp
Code 4:
`include "uvm_macros.svh";
import uvm_pkg::*;
///////////////////////////////////////////////////////////////
endclass
///////////////////////////////////////////////////////////////
endclass
////////////////////////////////////////////////////////////////////////////////////
driver d;
monitor m;
endclass
////////////////////////////////////////////////////////////////////////////////////////
env e;
endclass
///////////////////////////////////////////////////////////////////////////
module tb;
initial begin
run_test("test");
end
endmodule
Result:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Ethe serve reset phase end zala ki tenva serve main phase start zala aahe.Time delay varun paha.
`include "uvm_macros.svh";
import uvm_pkg::*;
endclass
module tb();
initial
begin
run_test("test");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
endclass
module tb();
initial
begin
run_test("test");
end
endmodule
Output
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Eteh aapan pahile aahe .phases he one bye one run hotat. Tymule aapan kothe pan define kele tar kahi hote nahi.
7] Timeout no use
Code :
`include "uvm_macros.svh"
import uvm_pkg::*;
///default : 9200sec
endclass
///////////////////////////////////////////////////////////////////////////
module tb;
initial begin
uvm_top.set_timeout(100ns, 0);
run_test("comp");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_NO_DEPRECATED undefined.
See http://www.eda.org/svdb/view.php?id=3313 for more details.
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Ethe total time ha 110 hote aahe pan ethe timeout 100ns cha takla aahe tymule ethe fatal error yeto.
Another approach supported by UVM is setting the drain time for the simulation environment. Drain time concept is related
to the extra time allocated to the UVM environment to process the left over activities e.g. last packet analysis & comparison
etc after all the stimulus is applied & processed
While selecting the drain time value, some random time value may not be sufficient for all the Tests, hence it is necessary to
study the requirements in detail and have good understanding of the scenarios which require extra time to complete the
processing. Choosing the worst case time can be a good strategy so that all other scenarios could be covered with -in that
time frame.
Code :
`include "uvm_macros.svh"
import uvm_pkg::*;
/////Default Timeout = 9200sec
endclass
///////////////////////////////////////////////////////////////////////////
module tb;
initial begin
run_test("comp");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
9] Phase Debug
In run option use the +UVM_PHASE_TRACE phase debug switch. Tenva aaplya te phase che serve kahi information bhetel and debug
saathi sope jail
Code :
`include "uvm_macros.svh"
import uvm_pkg::*;
///default : 9200sec
endclass
///////////////////////////////////////////////////////////////////////////
module tb;
initial begin
run_test("comp");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
Code :
`include "uvm_macros.svh"
import uvm_pkg::*;
///default : 9200sec
endclass
///////////////////////////////////////////////////////////////////////////
module tb;
initial begin
run_test("comp");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
1]
`include "uvm_macros.svh";
import uvm_pkg::*;
int data=12;
uvm_blocking_put_port#(int) send;
uvm_blocking_put_export#(int) recv;
module tb;
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Ethe aapan port and export ghetale aahe fkt. Kenva communication cha end point ha export port nasto. Communication cha end point ha
implemention port assto. Tymule varti error aale aahe.
Code 2:
`include "uvm_macros.svh";
import uvm_pkg::*;
int data=12;
uvm_blocking_put_port#(int) send;
uvm_blocking_put_export#(int) recv;
uvm_blocking_put_imp #(int,consumer) implement;
module tb;
initial
begin
run_test("test");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
From <https://www.edaplayground.com/x/JqH8>
implementation Port : uvm_blocking_put_imp#(type of data communication, implementation of put method class name) class name ;
Ex. uvm_blocking_put_imp#(int,consumer) cons;
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
uvm_blocking_put_port#(int) prod;
endclass
uvm_blocking_put_imp#(int,consumer) cons;
endclass
endfunction
endclass
module tb();
initial
begin
run_test("test");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
`include "uvm_macros.svh";
import uvm_pkg::*;
int data1=15;
endclass
endclass
uvm_blocking_put_imp#(int,consumer)cons1;
endclass
endclass
endclass
module tb();
initial
begin
run_test("test");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
`include "uvm_macros.svh";
import uvm_pkg::*;
uvm_blocking_put_port#(int) prod1;
uvm_blocking_put_imp#(int,subconsumer) subcons1;
uvm_blocking_put_export#(int) cons1;
endclass
endclass
module tb();
initial
begin
run_test("test");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Get port is used to retrive the data from consumer producer <<------------------ consumer
Get method madhe aapan producer pasun request send hote pan ya time la consumer kadhun data ghyecha aasto tymule aapan get cha use
kela jaato
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
int data1=0;
uvm_blocking_get_port#(int) prod1;
int data2=30;
uvm_blocking_get_imp#(int,consumer) cons1;
consumer c1;
producer p1;
endclass
endclass
module tb();
initial
begin
run_test("test");
end
endmodule
9] Transport Port
Ya madhe two side ne data transfer hoto. Two way communication is possible In transport port
Uvm_blocking_transport_port#(producer to conumser transfer data type , consumer to producer data type received ); --->
producer class
Uvm_blocking_transport_port#(producer to conumser transfer data type , consumer to producer data type received , class
name of consumer part ); ---> producer class
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
int datas=30;
int datar=0;
uvm_blocking_transport_port#(int,int) prod1;
int datas=30;
int datar=0;
prod1.transport(datas,datar);
`uvm_info("prod",$sformatf("value of data send=%0d and data recived=%0d",datas,datar),UVM_NONE);
phase.drop_objection(this);
endtask
endclass
int datas=45;
int datar=0;
uvm_blocking_transport_imp#(int,int,consumer) cons1;
virtual task transport(input int datar,output int datas); /// ethe producer and consumer cha data name same aasla pahije
datas=this.datas;
`uvm_info("cons",$sformatf(" value of data send =%0d and received data =%0d",datas,datar),UVM_NONE);
endtask // first recived data la input consider kela aahe ethe manun datar la first lihale aahe
endclass
producer p1;
consumer c1;
endclass
module tb();
initial
begin
run_test("test");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
From <https://www.edaplayground.com/>
9] Analysis Port
Uvm_analysis_imp#(consumer to producer retrive data type, class name of consumer part) tlm class name;
1]
https://www.theartofverification.com/uvm-tlm-concepts/
Communication cha end point ha nehami implementation port aasto
int data=12;
uvm_blocking_put_port #(int) send;
env e;
function new(string path="test",uvm_component parent=null);
super.new(path,parent);
endfunction
endclass
module tb();
initial
begin
run_test("test");
end
endmodule
Output:
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(277) @ 0: reporter [Questa UVM]
QUESTA_UVM-1.2.3
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(278) @ 0: reporter [Questa UVM]
questa_uvm::init(+struct)
# UVM_INFO @ 0: reporter [RNTST] Running test test...
# UVM_ERROR @ 0: uvm_test_top.e.c1.recv [Connection Error] connection count of 0 does not meet required
minimum of 1
# UVM_ERROR @ 0: uvm_test_top.e.p1.send [Connection Error] connection count of 0 does not meet required
minimum of 1
# UVM_FATAL @ 0: reporter [BUILDERR] stopping due to build errors
# UVM_INFO verilog_src/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]
# --- UVM Report Summary ---
#
# ** Report counts by severity
# UVM_INFO : 4
# UVM_WARNING : 0
# UVM_ERROR : 2
# UVM_FATAL : 1
# ** Report counts by id
# [BUILDERR] 1
# [Connection Error] 2
# [Questa UVM] 2
# [RNTST] 1
# [UVM/RELNOTES] 1
Note:
1] Ethe aapan port and export ghetale aahe fkt. Kenva communication cha end point ha export
port nasto. Communication cha end point ha implemention port assto. Tymule varti error aale
aahe.
Code :
import uvm_pkg::*;
`include "uvm_macros.svh";
int data=12;
uvm_blocking_put_port #(int) send;
endfunction
endclass
function void put(int datar); // receiver side la collect karat aahe put ne
`uvm_info("cons",$sformatf("value of data received =%0d",datar),UVM_NONE);
endfunction
endclass
env e;
function new(string path="test",uvm_component parent=null);
super.new(path,parent);
endfunction
endclass
module tb();
initial
begin
run_test("test");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Note:
1] Ethe jenva aapan producer madhe put cha use karto. Tenva consumer side la function ne define karava lagto
Code :
import uvm_pkg::*;
`include "uvm_macros.svh";
endclass
//////////////////////////////////
subproducer sp;
uvm_blocking_put_port #(int) send;
endfunction
endclass
endfunction
imprecv=new("imprecv",this);
endfunction
endclass
env e;
function new(string path="test",uvm_component parent=null);
super.new(path,parent);
endfunction
endclass
module tb();
initial
begin
run_test("test");
end
endmodule
Output:
UVM_INFO @ 0: reporter [RNTST] Running test test...
UVM_INFO testbench.sv(21) @ 0: uvm_test_top.e.p1.sp [PROD] inside the main phase of producer value of data
send =12
UVM_INFO testbench.sv(71) @ 0: uvm_test_top.e.c1 [cons] value of data received =12
UVM_INFO /apps/vcsmx/vcs/S-2021.09//etc/uvm-1.2/src/base/uvm_report_server.svh(904) @ 0: reporter
[UVM/REPORT/SERVER]
--- UVM Report Summary ---
2] Get Port
Put Port is send transition from producer ---------------> consumer
Get port is used to retrive the data from consumer producer <<------------------ consumer
Get method madhe aapan producer pasun request send hote pan ya time la consumer kadhun data ghyecha aasto tymule
aapan get cha use kela jaato
`include "uvm_macros.svh";
import uvm_pkg::*;
int data1=0;
uvm_blocking_get_port#(int) prod1;
int data2=30;
uvm_blocking_get_imp#(int,consumer) cons1;
consumer c1;
producer p1;
endclass
endclass
module tb();
initial
begin
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Valid Connections:
a. port to port
b. port to export
c. port to imp
d. export to export
e. export to imp
A] uvm_analysis_port example
Uvm_analysis_imp#(consumer to producer retrive data type, class name of consumer part) tlm class name;
Example : uvm_analysis_imp #(transaction,consumer) analysis_imp;
Code :
endclass
endclass
endfunction
module tb_top;
initial begin
run_test("test");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Some Changes :
Code :
`include "uvm_macros.svh"
import uvm_pkg::*;
endfunction
endfunction
/* no need to write the code for write method because we use the export port. Write method need to write in
implementation part
virtual function void write(transaction trans);
endclass
endfunction
endclass
module tb_top;
initial begin
run_test("test");
end
Endmodule
# You are using a version of the UVM library that has been compiled
# with `UVM_OBJECT_MUST_HAVE_CONSTRUCTOR undefined.
# See http://www.eda.org/svdb/view.php?id=3770 for more details.
#
# (Specify +UVM_NO_RELNOTES to turn off this notice)
#
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(215) @ 0: reporter [Questa UVM]
QUESTA_UVM-1.2.3
# UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(216) @ 0: reporter [Questa UVM]
questa_uvm::init(+struct)
# UVM_INFO @ 0: reporter [RNTST] Running test test...
# UVM_INFO first.sv(25) @ 0: uvm_test_top.e.p [producer] send value of addr=8
# UVM_INFO first.sv(69) @ 0: uvm_test_top.e.c1 [consumer1] received value of addr=8
# UVM_INFO verilog_src/uvm-1.1d/src/base/uvm_objection.svh(1267) @ 50: reporter [TEST_DONE] 'run' phase is
ready to proceed to the 'extract' phase
#
# --- UVM Report Summary ---
#
# ** Report counts by severity
# UVM_INFO : 6
# UVM_WARNING : 0
# UVM_ERROR : 0
# UVM_FATAL : 0
# ** Report counts by id
# [Questa UVM] 2
# [RNTST] 1
# [TEST_DONE] 1
# [consumer1] 1
# [producer] 1
# ** Note: $finish : C:/questasim64_10.7c/win64/../verilog_src/uvm-1.1d/src/base/uvm_root.svh(430)
# Time: 50 ns Iteration: 54 Instance: /tb_top
#1
1] The TLM FIFO provides storage for the transactions between two independently running processes. We have seen
put and get methods to operate with only one outstanding transaction at a time i.e it is allowed to send the
transaction Only after consumption of the previously sent transaction, in this case, the sender and receiver must be
in sync else lead to blocking in one of the components. What if the case where the sender needs not wait for the
receiver acknowledgment, it just wants to store it in memory and the receiver can consume it whenever required.
Thus, sender and receiver needs not to be in sync. TLM FIFO makes it possible.
2] As we have seen in blocking methods, producers need to wait for acknowledgment from the consumer to send
the next item.
3] What if the producer is not a testbench component? Consider an example where DUT is sent information packets
through some protocol and TB can take more time to operate on that packet. So, there can be chances that DUT can
send multiple packets in the meantime. TLM FIFO stores such incoming transaction from DUT and testbench can
operate independently
From <https://vlsiverify.com/uvm/tlm/tlm-fifo>
More Information
https://vlsiverify.com/uvm/tlm/tlm-fifo?expand_article=1
1]
UVM Sequencer
The sequencer is a mediator who establishes a connection between sequence and driver. Ultimately, it passes
transactions or sequence items to the driver so that they can be driven to the DUT.
TLM (Transaction Level Modelling) interface is used by sequencer and driver to pass transactions. seq_item_export and
seq_item_port TLM connect methods are defined in uvm_sequencer and uvm_driver class.
Sequence-Driver-Sequencer communication in
UVM
https://www.chipverify.com/uvm/uvm-using-get-next-item
Based on the varieties of methods available with sequence and driver, all combinations are explained further.
Approach A: Using get_next_item and item_done methods in the driver
Approach B: Using get and put methods in driver
2. The wait_for_grant issues request to the sequencer and wait for the grant from the sequencer. It returns when
the sequencer has granted the sequence.
3. Randomize the sequence item and send it to the sequencer using send_request call. There should not be any
simulation time delay between wait_for_grant and send_request method call. The sequencer forwards the
sequence item to the driver with the help of REQ FIFO. This unblocks the get_next_item() call and the driver
receives the sequence item.
4. The wait_for_item_done() call from sequence gets blocked until the driver responds back.
5. In the meantime, the driver drives the sequence item to the DUT using a virtual interface handle. Once it is
completed, the item_done method is called. This unblocks the wait_for_item_done method from the sequence.
6. If a response has to be sent from the driver to the sequence, item_done(RSP) is called with the RSP item as an
argument. The RSP item is communicated to the sequence by a sequencer with help of RSP FIFO. It is
important to call the get_response method to get the response. This step is optional and not required if the RSP
item is not sent by the DUT.
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
`uvm_object_utils_begin(transaction)
`uvm_field_int(a,UVM_DEFAULT)
`uvm_field_int(b,UVM_DEFAULT)
`uvm_field_int(y,UVM_DEFAULT)
`uvm_object_utils_end
endclass
endclass
endclass
env e;
sequence1 seq1;
endclass
module tb();
initial
begin
run_test("test");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
`uvm_object_utils_begin(transaction)
`uvm_field_int(a,UVM_DEFAULT)
`uvm_field_int(b,UVM_DEFAULT)
`uvm_field_int(y,UVM_DEFAULT)
`uvm_object_utils_end
class sequence1 extends uvm_sequence; // ethe aapan uvm_phase cha use nahi karat karan ha UVM_object pasun derived
zale la aahe.
`uvm_object_utils(sequence1);
transaction trans;
driver d;
uvm_sequencer#(transaction) vishal;
module tb();
initial
begin
run_test("test");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
1] uvm_sequence macros
1.1] UVM_DO
Syntax:
`uvm_do (uvm_sequence handle/uvm_sequence_item handle)
This macro takes seq_item or sequence as argument. On calling `uvm_do() the above-defined 6 steps will be executed. On
calling this macro, create, randomize and send to the driver will be executed
Example :
`uvm_object_utils_begin(transaction)
`uvm_field_int(a,UVM_DEFAULT)
First method madhe aapan jo data randomized kela aahe tymadhe aapan changes nahi karu shakat.
Second method madhe aapan jo data randomized kela aahe tyla aapan change karu shakto.
`include "uvm_macros.svh";
import uvm_pkg::*;
`uvm_object_utils_begin(transaction)
`uvm_field_int(a,UVM_DEFAULT)
`uvm_field_int(b,UVM_DEFAULT)
`uvm_field_int(y,UVM_DEFAULT)
`uvm_object_utils_end
class sequence1 extends uvm_sequence; // ethe aapan uvm_phase cha use nahi karat karan ha UVM_object pasun derived
zale la aahe.
`uvm_object_utils(sequence1);
transaction trans;
driver d;
uvm_sequencer#(transaction) vishal;
module tb();
initial
begin
run_test("test");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Code:
`include "uvm_macros.svh";
import uvm_pkg::*;
`uvm_object_utils_begin(transaction)
`uvm_field_int(a,UVM_DEFAULT)
`uvm_field_int(b,UVM_DEFAULT)
`uvm_field_int(y,UVM_DEFAULT)
`uvm_object_utils_end
endfunction
endclass
endclass
module tb();
initial
begin
run_test("test");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Note:
1] Ethe seq1 and seq2 start ekdache hotat. Pan te parally execute hotat. First seq1 end hoto nanater seq2 end hoto. Ethe
FIFO sarkhe kaam chalte.
2] set_arbitration(UVM_SEQ_ARB_WEIGHTED);
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
`uvm_object_utils_begin(transaction)
`uvm_field_int(a,UVM_DEFAULT)
`uvm_field_int(b,UVM_DEFAULT)
`uvm_field_int(y,UVM_DEFAULT)
`uvm_object_utils_end
trans=transaction::type_id::create("trans");
`uvm_info("SEQ1","SEQ1 start",UVM_NONE);
start_item(trans);
assert(trans.randomize);
finish_item(trans);
`uvm_info("SEQ1","SEQ1 end",UVM_NONE);
end
endtask
endclass
driver d;
uvm_sequencer#(transaction) sequencerhandle;
endfunction
endclass
e.a.sequencerhandle.set_arbitration(UVM_SEQ_ARB_WEIGHTED);
fork
seq1.start(e.a.sequencerhandle,null,100); ///(sequencer,parent sequence value, priority )
seq2.start(e.a.sequencerhandle,null,200);
join
phase.drop_objection(this);
endtask
endclass
module tb();
initial
begin
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Some changes:
1] Use of UVM_SEQ_ARB_RANDOM ethe randomly sequence end hoto.Weight la importance dile nahi det
e.a.sequencerhandle.set_arbitration(UVM_SEQ_ARB_RANDOM);
fork
seq1.start(e.a.sequencerhandle,null,100); ///sequencer,parent sequence value, priority
seq2.start(e.a.sequencerhandle,null,200);
join
phase.drop_objection(this);
endtask
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
e.a.sequencerhandle.set_arbitration(UVM_SEQ_ARB_STRICT_FIFO);
fork
seq1.start(e.a.sequencerhandle,null,100); ///sequencer,parent sequence value, priority
seq2.start(e.a.sequencerhandle,null,200);
join
phase.drop_objection(this);
endtask
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Note:
1] Ethe first weight la importance dile jaate. Jar weight same asel tar fifo method cha use kela jaato
e.a.sequencerhandle.set_arbitration(UVM_SEQ_ARB_STRICT_RANDOM);
fork
seq1.start(e.a.sequencerhandle,null,100); ///sequencer,parent sequence value, priority
seq2.start(e.a.sequencerhandle,null,200);
join
phase.drop_objection(this);
endtask
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Note:
1] Ethe first weight la importance dile jaate. Jar weight same asel tar random method cha use kela jaato
The UVM sequencer provides the facility to have exclusive access for the sequence to a driver via a sequencer using a
locking mechanism. This locking mechanism is implemented using lock and grab methods.
Example: In controller or microprocessor, internal core services interrupt handling along with other operations. Sometimes,
if a particular interrupt is raised by the device which needs immediate attention and stops ongoing process execution. Once
this high-priority interrupt is serviced by the core, the previous process can be resumed.
Lock method
On calling the lock method from a sequence, the sequencer will grant the sequence exclusive access to the
driver when the sequence gets the next available slot via a sequencer arbitration mechanism. Until the
sequence calls the unlock method, no other sequence will have access to the driver. On calling unlock method,
Ethe : lock(m_sequencer) unlock(m_sequencer) -------->ethe jar m_sequencer sodun dusara konta pan variable
ghetala tar error yeto
Code :
`include "uvm_macros.svh";
import uvm_pkg::*;
`uvm_object_utils_begin(transaction)
`uvm_field_int(a,UVM_DEFAULT)
`uvm_field_int(b,UVM_DEFAULT)
`uvm_field_int(y,UVM_DEFAULT)
`uvm_object_utils_end
trans=transaction::type_id::create("trans");
`uvm_info("SEQ1","SEQ1 start",UVM_NONE);
start_item(trans);
assert(trans.randomize);
finish_item(trans);
`uvm_info("SEQ1","SEQ1 end",UVM_NONE);
end
unlock(m_sequencer);
endtask
endclass
driver d;
uvm_sequencer#(transaction) sequencerhandle;
endfunction
endclass
fork
seq1.start(e.a.sequencerhandle,null,100); ///sequencer,parent sequence value, priority
seq2.start(e.a.sequencerhandle,null,200);
join
phase.drop_objection(this);
endtask
endclass
module tb();
initial
begin
Output :
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Some changes:
Ethe : lock(m_sequencer) unlock(m_sequencer) -------->ethe jar m_sequencer sodun dusara konta pan variable
ghetala tar error yeto
Code :
trans=transaction::type_id::create("trans");
`uvm_info("SEQ1","SEQ1 start",UVM_NONE);
start_item(trans);
assert(trans.randomize);
finish_item(trans);
`uvm_info("SEQ1","SEQ1 end",UVM_NONE);
end
unlock(kshetry);
endtask
endclass
Output:
4 errors
CPU time: 2.433 seconds to compile
Exit code expected: 0, received: 1
Done
class my_driver extends uvm_driver #(my_data); `uvm_component_utils (my_driver) virtual task run_phase(uvm_phase
phase); super.run_phase(phase); // 1. This task will get an item from the sequencer using get_next_item() `uvm_info
("DRIVER", $sformatf ("Waiting for data from sequencer"), UVM_MEDIUM) seq_item_port.get_next_item(req); // 2. For
simplicity, lets just assume the driver drives the received packet // during this time and consumes 20ns to complete driving
the transaction `uvm_info ("DRIVER", $sformatf ("Start driving tx addr=0x%0h data=0x%0h", req.addr, req.data), #20; // 3.
After driver has finished the transaction, it has to let the sequencer know // by calling item_done() `uvm_info ("DRIVER",
$sformatf ("Finish driving tx addr=0x%0h data=0x%0h", req.addr, req.data) seq_item_port.item_done(); endtask
1]
https://verificationguide.com/uvm/uvm-sequence/
UVM Sequencer
The sequencer is a mediator who establishes a connection between sequence and driver. Ultimately, it passes
transactions or sequence items to the driver so that they can be driven to the DUT.
A user-defined sequencer is recommended to extend from the parameterized base class “uvm_sequencer” which is
parameterized by request (REQ) and response (RSP) item types. Response item usage is optional. So, mostly
sequencer class is extended from a base class that has only a REQ item.
TLM (Transaction Level Modelling) interface is used by sequencer and driver to pass transactions. seq_item_export
and seq_item_port TLM connect methods are defined in uvm_sequencer and uvm_driver class.
1] First method madhe aapan jo data randomized kela aahe tymadhe aapan changes nahi karu shakat.
2] Second method madhe aapan jo data randomized kela aahe tyla aapan change karu shakto.
3] Third method madhe aapan khoop long way data transfer kele jaato
Second method madhe third method madhla wait_for_item_done ha remove kela aahe. Second method madhe
finish_item(tr) zale ki te tr ha data driver kadhe send kela jaato. Aata te next item saathi ready hoto.
`uvm_object_utils_begin(transaction)
`uvm_field_int(a,UVM_DEFAULT)
`uvm_field_int(b,UVM_DEFAULT)
`uvm_field_int(y,UVM_DEFAULT)
`uvm_object_utils_end
endclass
////////////////////////////////////////////
class sequence1 extends uvm_sequence#(transaction);
`uvm_object_utils(sequence1)
transaction trans;
endtask
endclass
//////////////////////////////////////////////////////
uvm_sequencer#(transaction) seqr;
driver d;
endclass
//////////////////////////////////////////////////////
//////////////////////running sequence with start method approach 1
agent a;
sequence1 s1;
endclass
///////////////////////////////////////////////
env e;
endclass
//////////////////////////////////////////////////////////////
module tb;
initial begin
run_test("test");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
Code :
`include "uvm_macros.svh"
import uvm_pkg::*;
////////////////////////////////////////////
`uvm_object_utils_begin(transaction)
`uvm_field_int(a,UVM_DEFAULT)
`uvm_field_int(b,UVM_DEFAULT)
`uvm_field_int(y,UVM_DEFAULT)
`uvm_object_utils_end
endclass
////////////////////////////////////////////
class sequence1 extends uvm_sequence#(transaction);
`uvm_object_utils(sequence1)
transaction trans;
endtask
endclass
///////////////////////////////////////////////
endtask
endclass
//////////////////////////////////////////////////////
uvm_sequencer#(transaction) seqr;
driver d;
endclass
//////////////////////////////////////////////////////
//////////////////////running sequence with start method approach 1
agent a;
sequence1 s1;
endclass
///////////////////////////////////////////////
env e;
endclass
//////////////////////////////////////////////////////////////
module tb;
initial begin
run_test("test");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_NO_DEPRECATED undefined.
See http://www.eda.org/svdb/view.php?id=3313 for more details.
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
`uvm_object_utils_begin(transaction)
`uvm_field_int(a,UVM_DEFAULT)
`uvm_field_int(b,UVM_DEFAULT)
`uvm_field_int(y,UVM_DEFAULT)
`uvm_object_utils_end
endclass
////////////////////////////////////////////
class sequence1 extends uvm_sequence#(transaction);
`uvm_object_utils(sequence1)
transaction trans;
trans = transaction::type_id::create("trans");
`uvm_info("SEQ1", "Waiting for Grant from Driver" , UVM_NONE);
wait_for_grant();
`uvm_info("SEQ1", "Rcvd Grant..Randomizing Data" , UVM_NONE);
assert(trans.randomize());
`uvm_info("SEQ1", "Randomization Done -> Sent Req to Drv" , UVM_NONE);
send_request(trans);
`uvm_info("SEQ1", "Waiting for Item Done Resp from Driver" , UVM_NONE);
wait_for_item_done();
`uvm_info("SEQ1", "SEQ1 Ended" , UVM_NONE);
`uvm_info("SEQ", $sformatf("a : %0d b:%0d", trans.a, trans.b), UVM_NONE);
endtask
endclass
///////////////////////////////////////////////
endtask
endclass
//////////////////////////////////////////////////////
uvm_sequencer#(transaction) seqr;
driver d;
endclass
//////////////////////////////////////////////////////
//////////////////////running sequence with start method approach 1
agent a;
sequence1 s1;
endclass
///////////////////////////////////////////////
env e;
endclass
//////////////////////////////////////////////////////////////
module tb;
initial begin
run_test("test");
end
endmodule
Output:
You are using a version of the UVM library that has been compiled
with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined.
See http://www.eda.org/svdb/view.php?id=3770 for more details.
3] Using get_next_item()
https://www.chipverify.com/uvm/uvm-using-get-next-item
1] uvm_driver is a child of uvm_component that has a TLM port to communicate with the sequencer.
2] The driver is a parameterized class with the type of request and response sequence items. This allows the driver to
send back a different sequence_item type back to the sequencer as the response.
3] However, most drivers use a response object of the same type as the request sequence item. The uvm_driver gets
request sequence items (REQ) from the sequencer FIFO using a handshake mechanism and optionally returns a
response sequence item (RSP) back to the sequencer response FIFO.
1] in a driver In this case, the driver requests for a sequence item from the sequencer using the get_next_item
method through the seq_item_port TLM handle.
2] Since the implementation of this port is defined in the sequencer, the function call makes the sequencer to pop an
item from its internal FIFO and provide it to the driver via the argument provided in get_next_item method
Driver code :
// 1. Get the next available item from the sequencer. If none exists, then wait until
next item is available -> this is blocking in nature. This task will get an item from the sequencer using get_next_item()
`uvm_info ("DRIVER", $sformatf ("Waiting for data from sequencer"), UVM_MEDIUM)
seq_item_port.get_next_item(req);
// 2. For simplicity, lets just assume the driver drives the received packet
// during this time and consumes 20ns to complete driving the transaction
`uvm_info ("DRIVER", $sformatf ("Start driving tx addr=0x%0h data=0x%0h", req.addr, req.data),;
#20;
// 3. After driver has finished the transaction, it has to let the sequencer know
// by calling item_done()
`uvm_info ("DRIVER", $sformatf ("Finish driving tx addr=0x%0h data=0x%0h", req.addr, req.data)
Once driver gets the next item, it can drive the data in the received sequence item to the DUT via a virtual interface
handle. After the driver has finished driving the item, it has to let the sequencer know that the process has finished
using item_done method.
Sequence code :
class my_sequence extends uvm_sequence;
`uvm_object_utils (my_sequence)
// 2. Call the start_item() task which will send this object to the driver
start_item(tx);
`uvm_info ("SEQ", $sformatf("start_item() fn call done"), UVM_MEDIUM)
// 3. Because the class handle passed to the driver points to the same object,
// we can do late randomization
tx.randomize();
`uvm_info ("SEQ", $sformatf("tx randomized with addr=0x%0h data=0x%0h", tx.addr, tx.data), UVM_ MEDIUM)
// 4. Call finish_item method so that the sequence waits until the driver lets the
// sequencer know that this item has finished
finish_item(tx);
`uvm_info ("SEQ", $sformatf("finish_item() fn call done"), UVM_MEDIUM)
endtask
endclass
1] In UVM, there is a mechanism to be followed when we want to send the transactions from the sequencer to the
Driver in order to provide stimulus to the DUT. Since we know that the whole intelligence of different type of
transactions is imbibed into the sequences and Sequencers are being used as the physical component to execute
those Sequences.
2] A particular Sequence is directed to run on a Sequencer which in turns further breaks down into a series of
transaction items and these transaction items are needs to be transferred to the Driver where these transaction items
are converted into cycle based signal/pin level transitions.
Note: Transaction is a class of data members to be sent to the DUT, control knobs & constraints information.
Transaction item is the object of type Transaction class.
Having said that, sending a transaction/sequence_item from a Sequencer to a Driver is a 4 step process which is listed
below:
2] Calling “start_item(<transaction_item_handle>)“. This call blocks the Sequencer till it grants the Sequence and
transaction access to the Driver.
3] Randomizing the transaction OR randomizing the transaction with in-line constraints. Now the transaction is ready
to be used by the Driver.
4] Calling “finish_item(<transaction_item_handle>)“. This call which is blocking in nature waits till Driver transfer the
protocol related transaction data.
These are the operational steps from a Sequence which we want to execute using a Sequencer that is connected to a
Driver inside an “Agent”. Whole of this process is shown in the Figure 1 & Figure 2 below:
If we talk about the actions taken by the Driver, then the following steps are made by the Driver in order to
complete the communication with Sequencer(Sequence):
3] Next, Driver completes its side protocol transfer while working with the virtual interface.
4] Calling the “item_done()” OR “item_done(rsp)“. It indicates to the sequencer the completion of the
process. “item_done” is a non-blocking call & can be processed with an argument or without an argument. If a
response is expected by the Sequencer/Sequence then item_done(rsp) is called. It results in Sequencer response FIFO
is updated with the “rsp” object handle.
2] Combine existing sequences to create new ones - perform reset sequence followed by register read/writes followed
by FSM state change sequence
3] Pull random sequences from the sequence library and execute them on the DUT
2] “Transaction” is a primitive level unit (OOPs Class) in a UVM based Verification Environment ‘Testbench’ which
defines following items as part of it:
A] The data members which stimulates the DUT ports. Pass the values to the DUT ports & receive the response values
from the DUT ports.
B] Some items which controls the temporal behavior & control the dependencies of these data members on each
other to create required verification scenarios. These items we may call as the ‘control knobs’.
3] Constraints applied on the data members & control knobs are also used to be part of a “Transactions”. These
constraints act as the default constraints which anyways can be over-written, if required, by the in-line constraints
defined during Sequence activation and Transaction randomization. Most of the data members & control knobs
(declared using ‘rand’ or ‘randc’ type) are defined as of random in nature to apply the SystemVerilog randomization
capability to the Testbench.
Lets have a look at the example of a “Transaction”.
1]
https://www.linkedin.com/pulse/difference-between-psequnecer-msequencer-uvm-raghuraj-s-
bhat/
https://verificationguide.com/uvm/m_sequencer-and-p_sequencer/
https://www.theartofverification.com/m_sequencer-vs-p_sequencer/
https://asic4u.wordpress.com/2015/12/31/m_sequencer-p_sequencer-difference/
https://www.quora.com/What-is-a-p_sequencer-and-an-m_sequencer-in-UVM
https://vlsiverify.com/uvm/uvm-sequencer
http://verificationexcellence.in/uvm_sequence-m_sequencer-p_sequencer/