| @@ -0,0 +1,73 @@ | |||||
| class axi_env extends uvm_env; | |||||
| axi_env_config env_cfg_h; | |||||
| master_agent_top mst_agt_top; | |||||
| slave_agent_top slv_agt_top; | |||||
| virtual_sequencer vseqr_h; | |||||
| scoreboard sb; | |||||
| extern function new(string name="axi_env",uvm_component parent); | |||||
| extern function void build_phase(uvm_phase phase); | |||||
| extern function void connect_phase(uvm_phase phase); | |||||
| `uvm_component_utils(axi_env) | |||||
| endclass | |||||
| function axi_env::new(string name="axi_env",uvm_component parent); | |||||
| super.new(name,parent); | |||||
| endfunction | |||||
| function void axi_env::build_phase(uvm_phase phase); | |||||
| if(!uvm_config_db#(axi_env_config)::get(this,"","axi_env_config",env_cfg_h)) | |||||
| `uvm_fatal("AXI Env","Unable to get axi env config, have you set it in test?") | |||||
| if(env_cfg_h.has_master_agent) | |||||
| begin | |||||
| uvm_config_db#(master_config)::set(this,"mst_agt_top*","master_config",env_cfg_h.mst_cfg_h); | |||||
| mst_agt_top=master_agent_top::type_id::create("mst_agt_top",this); | |||||
| end | |||||
| if(env_cfg_h.has_slave_agent) | |||||
| begin | |||||
| uvm_config_db#(slave_config)::set(this,"slv_agt_top*","slave_config",env_cfg_h.slv_cfg_h); | |||||
| slv_agt_top=slave_agent_top::type_id::create("slv_agt_top",this); | |||||
| end | |||||
| if(env_cfg_h.has_virtual_sequencer) | |||||
| begin | |||||
| vseqr_h=virtual_sequencer::type_id::create("vseqr_h",this); | |||||
| end | |||||
| if(env_cfg_h.has_scoreboard) | |||||
| sb=scoreboard::type_id::create("sb",this); | |||||
| super.build_phase(phase); | |||||
| endfunction | |||||
| function void axi_env::connect_phase(uvm_phase phase); | |||||
| if(env_cfg_h.has_virtual_sequencer) | |||||
| begin | |||||
| if(env_cfg_h.has_master_agent) | |||||
| begin | |||||
| foreach(mst_agt_top.mst_agt_h[i]) | |||||
| vseqr_h.mst_seqr_h[i]=mst_agt_top.mst_agt_h[i].mst_seqr_h; | |||||
| end | |||||
| if(env_cfg_h.has_slave_agent) | |||||
| begin | |||||
| foreach(slv_agt_top.slv_agt_h[i]) | |||||
| vseqr_h.slv_seqr_h[i]=slv_agt_top.slv_agt_h[i].slv_seqr_h; | |||||
| end | |||||
| end | |||||
| if(env_cfg_h.has_scoreboard) | |||||
| begin | |||||
| foreach(mst_agt_top.mst_agt_h[i]) | |||||
| mst_agt_top.mst_agt_h[i].mst_mon_h.mst_mon_port.connect(sb.mst_fifo_h[i].analysis_export); | |||||
| foreach(slv_agt_top.slv_agt_h[i]) | |||||
| slv_agt_top.slv_agt_h[i].slv_mon_h.slv_mon_port.connect(sb.slv_fifo_h[i].analysis_export); | |||||
| end | |||||
| endfunction | |||||
| @@ -0,0 +1,21 @@ | |||||
| class axi_env_config extends uvm_object; | |||||
| `uvm_object_utils(axi_env_config); | |||||
| bit has_scoreboard=1; | |||||
| bit has_virtual_sequencer=1; | |||||
| bit has_slave_agent=1; | |||||
| bit has_master_agent=1; | |||||
| int no_of_master=1; | |||||
| int no_of_slave=1; | |||||
| master_config mst_cfg_h; | |||||
| slave_config slv_cfg_h; | |||||
| function new(string name="axi_env_config"); | |||||
| super.new(name); | |||||
| endfunction : new | |||||
| endclass : axi_env_config | |||||
| @@ -0,0 +1,140 @@ | |||||
| interface axi_if(input bit CLK); | |||||
| //Declaration of Write Address Channel Signals | |||||
| logic ARESETn; | |||||
| logic [3:0] AWID; | |||||
| logic [31:0] AWADDR; | |||||
| logic [7:0] AWLEN; | |||||
| logic [2:0] AWSIZE; | |||||
| logic [1:0] AWBURST; | |||||
| logic AWVALID; | |||||
| logic AWREADY; | |||||
| //Declaration of Write Data Channel Signals | |||||
| logic [3:0] WID; | |||||
| logic [31:0] WDATA; | |||||
| logic [3:0] WSTRB; | |||||
| logic WLAST; | |||||
| logic WVALID; | |||||
| logic WREADY; | |||||
| //Declaration of Write Response Channel Signals | |||||
| logic [3:0] BID; | |||||
| logic [1:0] BRESP; | |||||
| logic BVALID; | |||||
| logic BREADY; | |||||
| //Declaration of Read Address Channel Signals | |||||
| logic [3:0] ARID; | |||||
| logic [31:0] ARADDR; | |||||
| logic [7:0] ARLEN; | |||||
| logic [2:0] ARSIZE; | |||||
| logic [1:0] ARBURST; | |||||
| logic ARVALID; | |||||
| logic ARREADY; | |||||
| //Declaration of Read Data Channel Signals | |||||
| logic [3:0] RID; | |||||
| logic [31:0] RDATA; | |||||
| logic [1:0] RRESP; | |||||
| logic RLAST; | |||||
| logic RVALID; | |||||
| logic RREADY; | |||||
| //Master Driver Clocking Block | |||||
| clocking mst_drv_cb@(posedge CLK); | |||||
| default input #1 output #1; | |||||
| //input signals from Write Address Channel | |||||
| input AWREADY; | |||||
| //input signals from Write Data Channel | |||||
| input WREADY; | |||||
| //input signals from Write Response Channel | |||||
| input BID,BRESP,BVALID; | |||||
| //input signals from Read Address Channel | |||||
| input ARREADY; | |||||
| //input signals from Read Data Channel | |||||
| input RID,RDATA,RRESP,RLAST,RVALID; | |||||
| //output from Write Address Channel | |||||
| output ARESETn, AWID,AWADDR,AWLEN,AWSIZE,AWBURST,AWVALID; | |||||
| //ouput from Write Data Channel | |||||
| output WID,WDATA,WSTRB,WLAST,WVALID; | |||||
| //output from Write Response Channel | |||||
| output BREADY; | |||||
| //output from Read Address Channel | |||||
| output ARID,ARADDR,ARLEN,ARSIZE,ARBURST,ARVALID; | |||||
| //output from Read Data Channel | |||||
| output RREADY; | |||||
| endclocking | |||||
| //Master Monitor Clocking Block | |||||
| clocking mst_mon_cb@(posedge CLK); | |||||
| default input #1 output #1; | |||||
| //input signals from Write Address Channel | |||||
| input ARESETn, AWID,AWADDR,AWLEN,AWSIZE,AWBURST,AWVALID,AWREADY; | |||||
| //input signals from Write Data Channel | |||||
| input WID,WDATA,WSTRB,WLAST,WVALID,WREADY; | |||||
| //input signals from Write Response Channel | |||||
| input BID,BRESP,BVALID,BREADY; | |||||
| //input signals from Read Address Channel | |||||
| input ARID,ARADDR,ARLEN,ARSIZE,ARBURST,ARVALID,ARREADY; | |||||
| //input signals from Read Data Channel | |||||
| input RID,RDATA,RRESP,RLAST,RVALID,RREADY; | |||||
| endclocking | |||||
| //Slave Driver Clocking Block | |||||
| clocking slv_drv_cb@(posedge CLK); | |||||
| default input #1 output #1; | |||||
| //input from Write Address Channel | |||||
| input ARESETn, AWID,AWADDR,AWLEN,AWSIZE,AWBURST,AWVALID; | |||||
| //ouput from Write Data Channel | |||||
| input WID,WDATA,WSTRB,WLAST,WVALID; | |||||
| //input from Write Response Channel | |||||
| input BREADY; | |||||
| //input from Read Address Channel | |||||
| input ARID,ARADDR,ARLEN,ARSIZE,ARBURST,ARVALID; | |||||
| //input from Read Data Channel | |||||
| input RREADY; | |||||
| //output signals from Write Address Channel | |||||
| output AWREADY; | |||||
| //output signals from Write Data Channel | |||||
| output WREADY; | |||||
| //output signals from Write Response Channel | |||||
| output BID,BRESP,BVALID; | |||||
| //output signals from Read Address Channel | |||||
| output ARREADY; | |||||
| //output signals from Read Data Channel | |||||
| output RID,RDATA,RRESP,RLAST,RVALID; | |||||
| endclocking | |||||
| //Slave Monitor Clocking Block | |||||
| clocking slv_mon_cb@(posedge CLK); | |||||
| default input #1 output #1; | |||||
| //input signals from Write Address Channel | |||||
| input ARESETn, AWID,AWADDR,AWLEN,AWSIZE,AWBURST,AWVALID,AWREADY; | |||||
| //input signals from Write Data Channel | |||||
| input WID,WDATA,WSTRB,WLAST,WVALID,WREADY; | |||||
| //input signals from Write Response Channel | |||||
| input BID,BRESP,BVALID,BREADY; | |||||
| //input signals from Read Address Channel | |||||
| input ARID,ARADDR,ARLEN,ARSIZE,ARBURST,ARVALID,ARREADY; | |||||
| //input signals from Read Data Channel | |||||
| input RID,RDATA,RRESP,RLAST,RVALID,RREADY; | |||||
| endclocking | |||||
| modport MST_DRV(clocking mst_drv_cb); | |||||
| modport MST_MON(clocking mst_mon_cb); | |||||
| modport SLV_DRV(clocking slv_drv_cb); | |||||
| modport SLV_MON(clocking slv_mon_cb); | |||||
| endinterface | |||||
| @@ -0,0 +1,123 @@ | |||||
| class scoreboard extends uvm_scoreboard; | |||||
| `uvm_component_utils(scoreboard) | |||||
| uvm_tlm_analysis_fifo#(axi_xtn) mst_fifo_h[]; | |||||
| uvm_tlm_analysis_fifo#(axi_xtn) slv_fifo_h[]; | |||||
| axi_env_config env_cfg_h; | |||||
| axi_xtn wr_xtn,rd_xtn; | |||||
| axi_xtn mst_xtn,slv_xtn; | |||||
| static int pkt_rcvd,pkt_cmprd; | |||||
| covergroup write_cg; | |||||
| option.per_instance=1; | |||||
| awaddr_cp: coverpoint wr_xtn.AWADDR{bins awaddr_bin={[0:'hffff_ffff]};} | |||||
| awburst_cp: coverpoint wr_xtn.AWBURST{bins awburst_bin[]={[0:2]};} | |||||
| awsize_cp : coverpoint wr_xtn.AWSIZE{bins awsize_bin[]={[0:2]};} | |||||
| awlen_cp : coverpoint wr_xtn.AWLEN{bins awlen_bin={[0:11]};} | |||||
| bresp_cp : coverpoint wr_xtn.BRESP{bins bresp_bin={0};} | |||||
| WRITE_ADDR_CROSS: cross awburst_cp,awsize_cp,awlen_cp; | |||||
| endgroup | |||||
| covergroup write_cg1 with function sample(int i); | |||||
| option.per_instance=1; | |||||
| wdata_cp : coverpoint wr_xtn.WDATA[i]{bins wdata_bin={[0:'hffff_ffff]};} | |||||
| wstrb_cp : coverpoint wr_xtn.WSTRB[i]{bins wstrobe_bin0={4'b1111}; | |||||
| bins wstrobe_bin1={4'b1100}; | |||||
| bins wstrobe_bin2={4'b0011}; | |||||
| bins wstrobe_bin3={4'b1000}; | |||||
| bins wstrobe_bin4={4'b0100}; | |||||
| bins wstrobe_bin5={4'b0010}; | |||||
| bins wstrobe_bin6={4'b0001}; | |||||
| bins wstrobe_bin7={4'b1110}; | |||||
| } | |||||
| WRITE_DATA_CROSS: cross wdata_cp,wstrb_cp; | |||||
| endgroup | |||||
| covergroup read_cg; | |||||
| option.per_instance=1; | |||||
| araddr_cp: coverpoint rd_xtn.ARADDR{bins araddr_bin={[0:'hffff_ffff]};} | |||||
| arburst_cp: coverpoint rd_xtn.ARBURST{bins arburst_bin[]={[0:2]};} | |||||
| arsize_cp : coverpoint rd_xtn.ARSIZE{bins arsize_bin[]={[0:2]};} | |||||
| arlen_cp : coverpoint rd_xtn.ARLEN{bins arlen_bin={[0:11]};} | |||||
| READ_ADDR_CROSS: cross arburst_cp,arsize_cp,arlen_cp; | |||||
| endgroup | |||||
| covergroup read_cg1 with function sample(int i); | |||||
| option.per_instance=1; | |||||
| rdata_cp : coverpoint rd_xtn.RDATA[i]{bins rdata_bin={[0:'hffff_ffff]};} | |||||
| rresp_cp : coverpoint rd_xtn.RRESP[i]{bins rresp_bin={0};} | |||||
| endgroup | |||||
| extern function new(string name="scoreboard",uvm_component parent); | |||||
| extern function void build_phase(uvm_phase phase); | |||||
| extern task run_phase(uvm_phase); | |||||
| extern function void report_phase(uvm_phase phase); | |||||
| endclass | |||||
| function scoreboard::new(string name="scoreboard",uvm_component parent); | |||||
| super.new(name,parent); | |||||
| write_cg=new(); | |||||
| write_cg1=new(); | |||||
| read_cg=new(); | |||||
| read_cg1=new(); | |||||
| endfunction | |||||
| function void scoreboard::build_phase(uvm_phase phase); | |||||
| if(!uvm_config_db #(axi_env_config)::get(this,"","axi_env_config",env_cfg_h)) | |||||
| `uvm_fatal("Scoreboard","cannot get env config, have you set it?"); | |||||
| mst_fifo_h=new[env_cfg_h.no_of_master]; | |||||
| slv_fifo_h=new[env_cfg_h.no_of_slave]; | |||||
| foreach(mst_fifo_h[i]) | |||||
| mst_fifo_h[i]=new($sformatf("mst_fifo_h[%0d]",i),this); | |||||
| foreach(slv_fifo_h[i]) | |||||
| slv_fifo_h[i]=new($sformatf("slv_fifo_h[%0d]",i),this); | |||||
| super.build_phase(phase); | |||||
| endfunction | |||||
| task scoreboard::run_phase(uvm_phase phase); | |||||
| forever | |||||
| begin | |||||
| mst_fifo_h[0].get(mst_xtn); | |||||
| slv_fifo_h[0].get(slv_xtn); | |||||
| pkt_rcvd++; | |||||
| if(mst_xtn.compare(slv_xtn)) | |||||
| begin | |||||
| wr_xtn=mst_xtn; | |||||
| rd_xtn=mst_xtn; | |||||
| pkt_cmprd++; | |||||
| write_cg.sample(); | |||||
| read_cg.sample(); | |||||
| if(mst_xtn.WVALID) | |||||
| begin | |||||
| foreach(mst_xtn.WDATA[i]) | |||||
| begin | |||||
| write_cg1.sample(i); | |||||
| end | |||||
| end | |||||
| if(mst_xtn.RVALID) | |||||
| begin | |||||
| foreach(mst_xtn.RDATA[i]) | |||||
| begin | |||||
| read_cg1.sample(i); | |||||
| end | |||||
| end | |||||
| end | |||||
| else | |||||
| `uvm_error("Scoreboard","Master and Slave Packet Mismatch"); | |||||
| end | |||||
| endtask | |||||
| function void scoreboard::report_phase(uvm_phase phase); | |||||
| `uvm_info("SCOREBOARD",$sformatf("No. of packets received:%0d",pkt_rcvd),UVM_LOW); | |||||
| `uvm_info("SCOREBOARD",$sformatf("No. of packets compared:%0d",pkt_cmprd),UVM_LOW); | |||||
| endfunction | |||||
| @@ -0,0 +1,32 @@ | |||||
| package axi_test_pkg; | |||||
| import uvm_pkg::*; | |||||
| `include "uvm_macros.svh" | |||||
| `include "axi_xtn.sv" | |||||
| `include "mstr_agt_config.sv" | |||||
| `include "slv_agt_config.sv" | |||||
| `include "axi_env_config.sv" | |||||
| `include "mstr_driver.sv" | |||||
| `include "mstr_monitor.sv" | |||||
| `include "mstr_sequencer.sv" | |||||
| `include "mstr_agent.sv" | |||||
| `include "mstr_agt_top.sv" | |||||
| `include "mstr_seqs.sv" | |||||
| `include "slv_driver.sv" | |||||
| `include "slv_monitor.sv" | |||||
| `include "slv_sequencer.sv" | |||||
| `include "slv_agent.sv" | |||||
| `include "slv_agt_top.sv" | |||||
| `include "slv_seqs.sv" | |||||
| `include "axi_virtual_sequencer.sv" | |||||
| `include "virtual_seqs.sv" | |||||
| `include "axi_scoreboard.sv" | |||||
| `include "axi_env.sv" | |||||
| `include "vtestlib.sv" | |||||
| endpackage | |||||