@@ -0,0 +1,106 @@ | |||||
class axi_coverage extends uvm_subscriber#(sequence_item); | |||||
`uvm_component_utils(axi_coverage) | |||||
sequence_item txn; | |||||
// Coverpoints for low power interface signals | |||||
covergroup t1; | |||||
coverpoint CSYSACK; | |||||
coverpoint CSYSREQ; | |||||
coverpoint CACTIVE; | |||||
// Cross coverage between low power interface signals | |||||
cross low_power_cross = {CSYSACK, CSYSREQ, CACTIVE}; | |||||
endgroup | |||||
//t2 | |||||
covergroup t2; | |||||
coverpoint awid{ bins ids[] =[1:16]};} | |||||
coverpoint awlen{ bins len _values[] ={[1:16]};} | |||||
cp1: coverpoint awsize | |||||
cp2: coverpoint awaddr { 2^0 to 2^31;} | |||||
cp3:coverpoint awburst{ bins busttype[] = [0:3];} | |||||
endgroup | |||||
//t3 | |||||
covergroup t3; | |||||
coverpoint awlen { bins len_values[] = {[0:16], [17:32], [33:48], [49:64]}; } | |||||
coverpoint wlast; | |||||
// Coverpoints for read data coverpoint arlen { bins len_values[] = {[0:15]}; } | |||||
coverpoint rlast; // Cross coverage between write and read data | |||||
cross w_r_data_cross = {awlen, arlen, wlast, rlast}; | |||||
endgroup | |||||
//t4 | |||||
covergroup t4; | |||||
coverpoint awid{ bins ids[] =[1:16]};} | |||||
coverpoint awlen{ bins len _values[] ={[1:16]};} | |||||
cp1: coverpoint awsize | |||||
cp2: coverpoint awaddr { 2^0 to 2^31;} | |||||
cp3:coverpoint awburst{ bins busttype[] = [0:3];} | |||||
// Coverpoints for address signals | |||||
coverpoint awaddr { bins addr_range[] = {[0:255], [256:511], [512:767], [768:1023]}; | |||||
bins addr_alignment[] = {[0], [4], [8], [12], [16], [20], [24], [28], [32]}; } | |||||
coverpoint araddr { bins addr_range[] = {[0:255], [256:511], [512:767], [768:1023]}; | |||||
bins addr_alignment[] = {[0], [4], [8], [12], [16], [20], [24], [28], [32]}; } | |||||
// Cross coverage between awaddr and araddr | |||||
cross aw_ar_address_cross = {awaddr, araddr}; | |||||
endgroup | |||||
//t5 | |||||
covergroup t5; | |||||
// Coverpoints for read address | |||||
coverpoint araddr { bins addr_range[] = {[0:255], [256:511], [512:767], [768:1023]}; | |||||
bins addr_alignment[] = {[0], [4], [8], [12], [16], [20], [24], [28], [32]}; } | |||||
// Cross coverage between read address and burst length | |||||
cross araddr_arlen_cross = {araddr, arlen}; | |||||
endgroup | |||||
//t6 | |||||
covergroup t6; | |||||
// Coverpoints for read data | |||||
coverpoint rdata { bins data_values[] = {[0:255], [256:511], [512:767], [768:1023]}; } | |||||
coverpoint rvalid; | |||||
// Cross coverage between read data and response | |||||
cross rdata_rresp_cross = {rdata, rresp}; | |||||
cross rdata_rvalid_cross = {rdata, rvalid}; | |||||
endgroup | |||||
//t7 | |||||
covergroup t7; | |||||
// Coverpoints for low power interface signals | |||||
coverpoint CSYSACK; | |||||
coverpoint CSYSREQ; | |||||
coverpoint CACTIVE; | |||||
// Cross coverage between low power interface signals | |||||
cross low_power_cross = {CSYSACK, CSYSREQ, CACTIVE}; | |||||
endgroup | |||||
//t8 | |||||
covergroup t8; | |||||
// Coverpoints for address signals | |||||
coverpoint awaddr { bins addr_range[] = {[0:255], [256:511], [512:767], [768:1023]}; | |||||
bins addr_alignment[] = {[0], [4], [8], [12], [16], [20], [24], [28], [32]}; } | |||||
coverpoint araddr { bins addr_range[] = {[0:255], [256:511], [512:767], [768:1023]}; | |||||
bins addr_alignment[] = {[0], [4], [8], [12], [16], [20], [24], [28], [32]}; } | |||||
// Cross coverage between awaddr and araddr | |||||
cross aw_ar_address_cross = {awaddr, araddr}; | |||||
// Coverpoints for write response | |||||
coverpoint bresp { bins resp_values[] = {[0:1], [2]}; } | |||||
// Coverpoints for read response | |||||
coverpoint rresp { bins resp_values[] = {[0:1], [2]}; } | |||||
// Cross coverage between write and read responses | |||||
cross b_r_resp_cross = {bresp, rresp}; | |||||
endgroup | |||||
function new(string name, uvm_component parent); | |||||
t1=new(); | |||||
t2=new(); | |||||
t3=new(); | |||||
t4=new(); | |||||
t5=new(); | |||||
t8=new(); | |||||
endfunction | |||||
endclass |
@@ -0,0 +1,25 @@ | |||||
//env | |||||
class env extends uvm_env; | |||||
`uvm_component_utils(env) | |||||
agent agnt; | |||||
scoreboard sb; | |||||
function new(string name="env", uvm_component parent); | |||||
super.new(name, parent); | |||||
endfunction | |||||
function void build_phase(uvm_phase phase); | |||||
super.build_phase(phase); | |||||
agnt = agent::type_id::create("agnt", this); | |||||
sb = scoreboard::type_id::create("sb",this); | |||||
endfunction | |||||
function void connect_phase(uvm_phase phase); | |||||
super.connect_phase(phase); | |||||
//connecting montor and scoreboard usig analysis port | |||||
agnt.mon.mon_port.connect(sb.sb_imp_port); | |||||
endfunction | |||||
endclass | |||||
@@ -0,0 +1,144 @@ | |||||
//driver | |||||
class driver extends uvm_driver #(packet); | |||||
`uvm_component_utils(driver) | |||||
virtual axi_if vif; | |||||
packet pkt; | |||||
function new(string name="driver", uvm_component parent=null); | |||||
super.new(name, parent); | |||||
endfunction | |||||
virtual function void build_phase(uvm_phase phase); | |||||
super.build_phase(phase); | |||||
pkt=packet::type_id::create("pkt"); | |||||
if(!uvm_config_db#(virtual axi_if)::get(this,"","vif",vif)) | |||||
`uvm_error("drv","Unable to access Interface"); | |||||
endfunction | |||||
task reset_dut(); | |||||
repeat (2) begin | |||||
//write address channel | |||||
vif.awvalid <= 0; | |||||
vif.awready <= 0; | |||||
vif.awid <= 0; | |||||
vif.awlen <= 0; | |||||
vif.awsize <= 0; | |||||
vif.awaddr <= 0; | |||||
vif.awburst <= 0; | |||||
//write data channel (w) | |||||
vif.wvalid <= 0; | |||||
vif.wready <= 0; | |||||
vif.wid <= 0; | |||||
vif.wdata <= 0; | |||||
vif.wstrb <= 0; | |||||
vif.wlast <= 0; | |||||
//write response channel (b) | |||||
vif.bready <= 0; | |||||
vif.bvalid <= 0; | |||||
vif.bid <= 0; | |||||
vif.bresp <= 0; | |||||
///////////////read address channel (ar) | |||||
vif.arvalid <= 0; | |||||
vif.arready <= 0; | |||||
vif.arid <= 0; | |||||
vif.arlen <= 0; | |||||
vif.arsize <= 0; | |||||
vif.araddr <= 0; | |||||
vif.arburst <= 0; | |||||
/////////// read data channel (r) | |||||
vif.rvalid <= 0; | |||||
vif.rready <= 0; | |||||
vif.rid <= 0; | |||||
vif.rdata <= 0; | |||||
vif.rstrb <= 0; | |||||
vif.rlast <= 0; | |||||
vif.rresp <= 0; | |||||
//1 clk delay | |||||
@(posedge vif.clk); | |||||
`uvm_info(get_type_name(),"*** Reset Applied by driver ***",UVM_MEDIUM) | |||||
end | |||||
endtask | |||||
task write(); | |||||
if(pkt.op==WRITE) | |||||
begin | |||||
//write address channel | |||||
vif.awvalid <= pkt.awvalid ; | |||||
vif.awready <= pkt.awready ; | |||||
vif.awid <= pkt.awid ; | |||||
vif.awlen <= pkt.awlen ; | |||||
vif.awsize <= pkt.awsize ; | |||||
vif.awaddr <= pkt.awaddr ; | |||||
vif.awburst <= pkt.awburst ; | |||||
//write data channel (w) | |||||
vif.wvalid <= pkt.wvalid ; | |||||
vif.wready <= pkt.wready ; | |||||
vif.wid <= pkt.wid ; | |||||
vif.wdata <= pkt.wdata ; | |||||
vif.wstrb <= pkt.wstrb ; | |||||
vif.wlast <= pkt.wlast ; | |||||
//write response channel (b) | |||||
vif.bready <= pkt.bready ; | |||||
vif.bvalid <= pkt.bvalid ; | |||||
vif.bid <= pkt.bid ; | |||||
//1 clk delay | |||||
@(posedge vif.clk); | |||||
`uvm_info(get_type_name(),"*** write signals are drived to DUT ***",UVM_MEDIUM) | |||||
vif.bresp <= pkt.bresp ; end | |||||
endtask | |||||
task read(); | |||||
if(pkt.op == READ)begin | |||||
///////////////read address channar) | |||||
vif.arvalid <= pkt.arvalid ; | |||||
vif.arready <= pkt.arready ; | |||||
vif.arid <= pkt.arid ; | |||||
vif.arlen <= pkt.arlen ; | |||||
vif.arsize <= pkt.arsize ; | |||||
vif.araddr <= pkt.araddr ; | |||||
vif.arburst <= pkt.arburst ; | |||||
/////////// read data channel (r) | |||||
vif.rvalid <= pkt.rvalid ; | |||||
vif.rready <= pkt.rready ; | |||||
vif.rid <= pkt.rid ; | |||||
vif.rdata <= pkt.rdata ; | |||||
vif.rstrb <= pkt.rstrb ; | |||||
vif.rlast <= pkt.rlast ; | |||||
vif.rresp <= pkt.rresp ; | |||||
//1 clk delay | |||||
@(posedge vif.clk); | |||||
`uvm_info(get_type_name(),"*** read signals are drived to DUT ***",UVM_MEDIUM) | |||||
end | |||||
endtask | |||||
virtual task run_phase(uvm_phase phase); | |||||
reset_dut(); | |||||
forever begin | |||||
seq_item_port.get_next_item(pkt); | |||||
`uvm_info(get_type_name(),"*** Driver Received the transaction by sequencer ***",UVM_MEDIUM) | |||||
if(pkt.op==RESET) begin | |||||
reset_dut(); | |||||
end | |||||
//Write operation support | |||||
else if(pkt.op == WRITE) begin | |||||
write(); | |||||
`uvm_info(get_type_name(),"*** WRITE packet is received in driver ***",UVM_MEDIUM) | |||||
end | |||||
else if(pkt.op == READ) begin | |||||
read(); | |||||
`uvm_info(get_type_name(),"*** READ packet is received in driver ***",UVM_MEDIUM) | |||||
end | |||||
//put read drive logic here | |||||
seq_item_port.item_done(); | |||||
end | |||||
endtask | |||||
endclass | |||||
@@ -0,0 +1,96 @@ | |||||
//Base test | |||||
class base_test extends uvm_test; | |||||
`uvm_component_utils(base_test) | |||||
env e; | |||||
reset_sequence reset_seq; | |||||
// read_sequence read_seq; | |||||
// write_sequence write_seq; | |||||
// write_read_sequence write_read_seq; | |||||
// multi_write_multi_read_sequence multi_write_multi_read_seq; | |||||
// slaveerr_sequence slaveerr_seq; | |||||
function new(string name="test", uvm_component parent); | |||||
super.new(name, parent); | |||||
endfunction | |||||
virtual function void build_phase(uvm_phase phase); | |||||
super.build_phase(phase); | |||||
e = env::type_id::create("e", this); | |||||
reset_seq=reset_sequence::type_id::create("reset_seq"); | |||||
// read_seq=read_sequence::type_id::create("read_seq"); | |||||
// write_seq=write_sequence::type_id::create("write_seq"); | |||||
// write_read_seq=write_read_sequence::type_id::create("write_read_seq"); | |||||
//multi_write_multi_read_seq=multi_write_multi_read_sequence::type_id::create("multi_write_multi_read_seq"); | |||||
// slaveerr_seq=slaveerr_sequence::type_id::create("slaveerr_seq"); | |||||
endfunction | |||||
virtual function void start_of_simulation_phase(uvm_phase phase); | |||||
super.start_of_simulation_phase(phase); | |||||
uvm_top.print_topology(); | |||||
endfunction | |||||
virtual function void report_phase(uvm_phase phase); | |||||
uvm_report_server svr; | |||||
super.report_phase(phase); | |||||
svr = uvm_report_server::get_server(); | |||||
if(svr.get_severity_count(UVM_FATAL)+svr.get_severity_count(UVM_ERROR)>0) begin | |||||
`uvm_info(get_type_name(), "---------------------------------------", UVM_NONE) | |||||
`uvm_info(get_type_name(), "---- TEST FAIL ----", UVM_NONE) | |||||
`uvm_info(get_type_name(), "---------------------------------------", UVM_NONE) | |||||
end | |||||
else begin | |||||
`uvm_info(get_type_name(), "---------------------------------------", UVM_NONE) | |||||
`uvm_info(get_type_name(), "---- TEST PASS ----", UVM_NONE) | |||||
`uvm_info(get_type_name(), "---------------------------------------", UVM_NONE) | |||||
end | |||||
endfunction | |||||
endclass | |||||
//multi write read test | |||||
class multi_write_multi_read_test extends base_test; | |||||
`uvm_component_utils(multi_write_multi_read_test) | |||||
function new(string name="multi_write_multi_read_test", uvm_component parent); | |||||
super.new(name, parent); | |||||
endfunction | |||||
virtual function void build_phase(uvm_phase phase); | |||||
super.build_phase(phase); | |||||
endfunction | |||||
virtual task run_phase(uvm_phase phase); | |||||
phase.raise_objection(this); | |||||
`uvm_info(get_type_name(), "*** Starting test ***", UVM_MEDIUM) | |||||
reset_seq.start(e.agnt.sqr); | |||||
`uvm_info(get_type_name(), "*** Ended test ***", UVM_MEDIUM) | |||||
phase.drop_objection(this); | |||||
endtask | |||||
endclass | |||||
/* | |||||
//slave error test | |||||
class slaveerr_test extends base_test; | |||||
`uvm_component_utils(slaveerr_test) | |||||
function new(string name="slaveerr_test", uvm_component parent); | |||||
super.new(name, parent); | |||||
endfunction | |||||
virtual function void build_phase(uvm_phase phase); | |||||
super.build_phase(phase); | |||||
endfunction | |||||
virtual task run_phase(uvm_phase phase); | |||||
phase.raise_objection(this); | |||||
`uvm_info(get_type_name(), "*** Starting test ***", UVM_MEDIUM) | |||||
slaveerr_seq.start(e.agnt.sqr); | |||||
`uvm_info(get_type_name(), "*** Ended test ***", UVM_MEDIUM) | |||||
phase.drop_objection(this); | |||||
endtask | |||||
endclass | |||||
*/ | |||||
@@ -0,0 +1,81 @@ | |||||
`include "uvm_macros.svh" | |||||
import uvm_pkg::*; | |||||
import my_pkg::*; | |||||
`include "design.sv" | |||||
`include "pkg.sv" | |||||
`include "axi_sequence_item.sv" | |||||
`include "axi_sequence.sv" | |||||
`include "axi_sequencer.sv" | |||||
`include "axi_env.sv" | |||||
`include "axi_interface.sv" | |||||
`include "axi_driver.sv" | |||||
`include "axi_test.sv" | |||||
`include "axi_agent.sv" | |||||
module top; | |||||
//interface instance | |||||
axi_if vif (); | |||||
//connecting dut signals with interface and gloable signals | |||||
axi_slave dut(.clk(vif.clk), | |||||
.resetn(vif.resetn), | |||||
///////////////////write address channel | |||||
.awvalid(vif.awvalid), | |||||
.awready(vif.awready), | |||||
.awid(vif.awid), | |||||
.awlen(vif.awlen), | |||||
.awsize(vif.awsize), | |||||
.awaddr(vif.awaddr), | |||||
.awburst(vif.awburst), | |||||
/////////////////////write data channel | |||||
.wvalid(vif.wvalid), | |||||
.wready(vif.wready), | |||||
.wid(vif.wid), | |||||
.wdata(vif.wdata), | |||||
.wstrb(vif.wstrb), | |||||
.wlast(vif.wlast), | |||||
///////////////write response channel | |||||
.bready(vif.bready), | |||||
.bvalid(vif.bvalid), | |||||
.bid(vif.bid), | |||||
.bresp(vif.bresp), | |||||
////////////// read address channel | |||||
.arready(vif.arready), | |||||
.arid(vif.arid), | |||||
.araddr(vif.araddr), | |||||
.arlen(vif.arlen), | |||||
.arsize(vif.arsize), | |||||
.arburst(vif.arburst), | |||||
.arvalid(vif.arvalid), | |||||
///////////////////read data channel | |||||
.rid(vif.rid), | |||||
.rdata(vif.rdata), | |||||
.rresp(vif.rresp), | |||||
.rlast(vif.rlast), | |||||
.rvalid(vif.rvalid), | |||||
.rready(vif.rready)); | |||||
initial begin | |||||
vif.clk <= 0; | |||||
vif.resetn <=0; | |||||
end | |||||
initial begin | |||||
#10 | |||||
vif.resetn <=1; | |||||
end | |||||
//clock generator | |||||
always #5 vif.clk <= ~vif.clk; | |||||
initial begin | |||||
//pass interface to lower hierarchy | |||||
uvm_config_db#(virtual axi_if)::set(null, "*", "vif", vif); | |||||
run_test("give test name please");// need to write UVM_test name | |||||
end | |||||
initial begin | |||||
$dumpfile("dump.vcd"); | |||||
$dumpvars; | |||||
end | |||||
endmodule |
@@ -0,0 +1,19 @@ | |||||
package my_pkg; | |||||
//axi_if vif(); | |||||
typedef enum bit [1:0] {awidle = 2'b00, awstart = 2'b01, awreadys = 2'b10} awstate_type; | |||||
awstate_type awstate, awnext_state; | |||||
typedef enum bit [2:0] {widle = 0, wstart = 1, wreadys = 2, wvalids = 3, waddr_dec = 4} wstate_type; | |||||
wstate_type wstate, wnext_state; | |||||
typedef enum bit [2:0] {ridle = 0, rstart = 1, rwait = 2, rvalids = 3, rerror = 4} rstate_type; | |||||
rstate_type rstate, rnext_state; | |||||
typedef enum bit [1:0] {aridle = 0, arstart = 1, arreadys = 2} arstate_type; | |||||
arstate_type arstate, arnext_state; | |||||
typedef enum bit [1:0] {bidle = 0, bdetect_last = 1, bstart = 2, bwait = 3} bstate_type; | |||||
bstate_type bstate,bnext_state; | |||||
endpackage |