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