| @@ -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 | |||