shivakanta_kondapalli пре 4 месеци
родитељ
комит
01e5bdf713
4 измењених фајлова са 454 додато и 125 уклоњено
  1. +42
    -0
      axi_tb_top.sv
  2. +166
    -0
      axi_test.sv
  3. +185
    -125
      axi_transaction.sv
  4. +61
    -0
      axi_write_seq.sv

+ 42
- 0
axi_tb_top.sv Прегледај датотеку

@@ -0,0 +1,42 @@
// `include "uvm_pkg.sv"
import uvm_pkg::*;
`include "uvm_macros.svh"
`include "axi_config_objs.svh"
`include "axi_interface.sv"
`include "axi_transaction.sv"
`include "axi_write_seq.sv"
`include "axi_read_seq.sv"
`include "axi_m_driver.sv"
`include "axi_m_monitor.sv"
`include "axi_master_agent.sv"
`include "axi_s_driver.sv"
`include "axi_s_monitor.sv"
`include "axi_slave_agent.sv"
`include "axi_scoreboard.sv"
`include "axi_env.sv"
`include "axi_test.sv"
`include "uvm_pkg.sv"
// parameter A_WIDTH = 8; // Address bus width
// parameter D_WIDTH = 128; // Data bus width
module top;
bit clk, rstn;
always #5 clk = ~clk;
initial rstn = 1;
axi_intf#(.A_WIDTH(A_WIDTH), .D_WIDTH(D_WIDTH)) intf(clk, rstn);
env_config env_cfg;
initial begin
env_cfg = new();
env_cfg.intf = intf;
uvm_config_db#(env_config)::set(null, "uvm_test_top", "config", env_cfg);
uvm_config_db#(env_config)::set(null, "uvm_test_top.env.master", "config", env_cfg);
uvm_config_db#(env_config)::set(null, "uvm_test_top.env.slave", "config", env_cfg);
run_test("axi_base_test");
end
endmodule

+ 166
- 0
axi_test.sv Прегледај датотеку

@@ -0,0 +1,166 @@
class axi_base_test extends uvm_test;
`uvm_component_utils(axi_base_test)
// Components
axi_env env;
axi_write_seq#(.D_WIDTH(D_WIDTH), .A_WIDTH(A_WIDTH)) wr_seq;
axi_read_seq#(.D_WIDTH(D_WIDTH), .A_WIDTH(A_WIDTH)) rd_seq;
// variables
env_config env_cfg;
test_config test_cfg;
function new(string name, uvm_component parent);
super.new(name, parent);
test_cfg = new("test_cfg");
test_cfg.no_write_cases = 1;
test_cfg.no_read_cases = 1;
endfunction //new()
// Function: build_phase
extern function void build_phase(uvm_phase phase);
// Function: end_of_elaboration_phase
extern function void end_of_elaboration_phase(uvm_phase phase);
// Function: run_phase
extern task run_phase(uvm_phase phase);
endclass //axi_base_test extends uvm_test
function void axi_base_test::build_phase(uvm_phase phase);
test_cfg.burst_type = 2;
uvm_config_db#(test_config)::set(null, "uvm_test_top.seq", "config", test_cfg);
wr_seq = new("wr_seq");
rd_seq = new("rd_seq");
env = axi_env::type_id::create("env", this);
endfunction: build_phase
function void axi_base_test::end_of_elaboration_phase(uvm_phase phase);
super.end_of_elaboration_phase(phase);
uvm_top.print_topology();
endfunction: end_of_elaboration_phase
task axi_base_test::run_phase(uvm_phase phase);
phase.raise_objection(this);
fork
wr_seq.start(env.master.w_seqr);
#200
rd_seq.start(env.master.r_seqr);
// end
join
phase.drop_objection(this);
endtask: run_phase
// ****************************************************************************************
// Directed Test Cases
// ****************************************************************************************
class axi_write_test extends axi_base_test;
`uvm_component_utils(axi_write_test)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction //new()
function void build_phase(uvm_phase phase);
super.build_phase(phase);
endfunction: build_phase
function void end_of_elaboration_phase(uvm_phase phase);
super.end_of_elaboration_phase(phase);
endfunction: end_of_elaboration_phase
task run_phase(uvm_phase phase);
phase.raise_objection(this);
wr_seq.start(env.master.w_seqr);
phase.drop_objection(this);
endtask: run_phase
endclass //write_test extends axi_base_test
class axi_read_test extends axi_base_test;
`uvm_component_utils(axi_read_test)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction //new()
function void build_phase(uvm_phase phase);
super.build_phase(phase);
endfunction: build_phase
function void end_of_elaboration_phase(uvm_phase phase);
super.end_of_elaboration_phase(phase);
endfunction: end_of_elaboration_phase
task run_phase(uvm_phase phase);
phase.raise_objection(this);
wr_seq.start(env.master.w_seqr);
// rd_seq.start(env.master.r_seqr);
phase.drop_objection(this);
endtask: run_phase
endclass //write_test extends axi_base_test
class axi_fixed_test extends axi_base_test;
`uvm_component_utils(axi_fixed_test)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction //new()
function void build_phase(uvm_phase phase);
test_cfg.burst_type = 0;
uvm_config_db#(test_config)::set(null, "uvm_test_top.seq", "config", test_cfg);
wr_seq = new("wr_seq");
rd_seq = new("rd_seq");
env = axi_env::type_id::create("env", this);
endfunction: build_phase
task run_phase(uvm_phase phase);
super.run_phase(phase);
endtask: run_phase
endclass //axi_fixed_test extends axi_base_test
class axi_incr_test extends axi_base_test;
`uvm_component_utils(axi_incr_test)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction //new()
function void build_phase(uvm_phase phase);
test_cfg.burst_type = 1;
uvm_config_db#(test_config)::set(null, "uvm_test_top.seq", "config", test_cfg);
wr_seq = new("wr_seq");
rd_seq = new("rd_seq");
env = axi_env::type_id::create("env", this);
endfunction: build_phase
task run_phase(uvm_phase phase);
super.run_phase(phase);
endtask: run_phase
endclass //axi_fixed_test extends axi_base_test
class axi_wrap_test extends axi_base_test;
`uvm_component_utils(axi_wrap_test)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction //new()
function void build_phase(uvm_phase phase);
test_cfg.burst_type = 2;
uvm_config_db#(test_config)::set(null, "uvm_test_top.seq", "config", test_cfg);
wr_seq = new("wr_seq");
rd_seq = new("rd_seq");
env = axi_env::type_id::create("env", this);
endfunction: build_phase
task run_phase(uvm_phase phase);
super.run_phase(phase);
endtask: run_phase
endclass //axi_fixed_test extends axi_base_test

+ 185
- 125
axi_transaction.sv Прегледај датотеку

@@ -1,125 +1,185 @@
`include "uvm_macros.svh"
import uvm_pkg::*;

class axi_seq_item extends uvm_seq_item;
//'uvm_object_utils(axi_seq_item);

function new(string name="axi_seq_item")
super.new(name);
endfunction
//write adress channel signals

rand bit wr_rd;

rand bit [3:0] awid;
rand logic[31:0] awaddr;
rand logic[2:0] awsize;
rand logic[3:0] awlen;
rand logic[1:0] awburst;
rand logic[1:0] awlock;

logic awvalid;
logic awready;


//write data channel

rand bit [3:0] wid;
rand logic[31:0] wdata[][];
logic[3:0] wstrb;
logic wlast;
logic wvalid;
logic wready;

// write response channel
rand bit []3:0]bid;
logic[1:0] bresp;

logic bvalid;
logic bready;
// read adress channel

rand bit [3:0] arid;

rand logic[31:0] araddr;
rand logic[2:0] arsize;
rand logic[3:0] arlen;
rand logic[1:0] arburst;
rand logic[1:0] arlock;
logic arvalid;
logic arready;
// read data channel


rand bit [3:0] rid;
logic[31:0] rdata;
logic[3:0]rresp;
logic rlast;
logic rvalid;
logic rready;


`uvm_object_utils_begin(axi_seq_item)

`uvm_field_int(awid,UVM_ALL_ON)
`uvm_field_int(awaddr,UVM_ALL_ON)
`uvm_field_int(awsize,UVM_ALL_ON)
`uvm_field_int(awlen,UVM_ALL_ON)
`uvm_field_int(awburst,UVM_ALL_ON)
`uvm_field_int(awlock,UVM_ALL_ON)
`uvm_field_int(awvalid,UVM_ALL_ON)
`uvm_field_int(awready,UVM_ALL_ON)

`uvm_field_int(wid,UVM_ALL_ON)
`uvm_field_int(wdata,UVM_ALL_ON)
`uvm_field_int(wlast,UVM_ALL_ON)
`uvm_field_int(wstrb,UVM_ALL_ON)
`uvm_field_int(wvalid,UVM_ALL_ON)
`uvm_field_int(wready,UVM_ALL_ON)

`uvm_field_int(bid,UVM_ALL_ON)
`uvm_field_int(bresp,UVM_ALL_ON)
`uvm_field_int(bvalid,UVM_ALL_ON)
`uvm_field_int(bready,UVM_ALL_ON)

`uvm_field_int(arid,UVM_ALL_ON)
`uvm_field_int(araddr,UVM_ALL_ON)
`uvm_field_int(arsize,UVM_ALL_ON)
`uvm_field_int(arlen,UVM_ALL_ON)
`uvm_field_int(arsize,UVM_ALL_ON)
`uvm_field_int(arburst,UVM_ALL_ON)
`uvm_field_int(arlock,UVM_ALL_ON)
`uvm_field_int(arvalid,UVM_ALL_ON)
`uvm_field_int(arready,UVM_ALL_ON)

`uvm_field_int(rid,UVM_ALL_ON)
`uvm_field_int(rdata,UVM_ALL_ON)
`uvm_field_int(rlast,UVM_ALL_ON)
`uvm_field_int(rresp,UVM_ALL_ON)
`uvm_field_int(rvalid,UVM_ALL_ON)
`uvm_field_int(rready,UVM_ALL_ON)

`uvm_object_utils_end

//constraints for axi

constraint aligned_addr{awadd%2**awsize==0;}

constraint wrap_addr{solve awburst before awlen
if(awburst==2'b 10)
awlen inside{1,3,7,15};}

constraint wid_sig{awid==wid;}

constraint rid_sig{arid==rid;}

constraint axi_4kb{awaddr%4096+(2**awsize*(awlen+1))<=4096;}



//:constrain
endclass:axi_seq_item


import uvm_pkg::*;
typedef enum bit[1:0] { FIXED, INCR, WRAP } B_TYPE;
// Class: axi_transaction
//
class axi_transaction#(d_width = 16, a_width = 16) extends uvm_sequence_item;
typedef axi_transaction#(d_width, a_width) this_type_t;
`uvm_object_param_utils(axi_transaction#(d_width, a_width));
// Group: Variables
bit [8:0] id;
rand bit [a_width-1:0] addr;
rand bit write;
rand bit [7:0] data [][];
rand bit [2:0] b_size;
rand bit [3:0] b_len;
rand B_TYPE b_type;
bit b_last;
bit [1:0] b_resp;
bit [1:0] r_resp [];
// Group: Constraints
constraint b_size_val { 8*(2**b_size) <= d_width; }
constraint data_size {
/* solve order constraints */
solve b_len before data;
solve b_size before data;
/* rand variable constraints */
data.size() == b_len+1;
foreach (data[i] )
data[i].size() == 2**b_size;
}
constraint b_len_val {
/* solve order constraints */
solve b_type before b_len;
/* rand variable constraints */
if(b_type == FIXED)
b_len inside { 0, 1 };
else if(b_type == WRAP)
b_len inside { 1, 3, 7, 15 };
}
constraint addr_val {
/* solve order constraints */
solve b_type before addr;
solve b_size before addr;
/* rand variable constraints */
if(b_type == WRAP)
addr == int'(addr/2**b_size) * 2**b_size;
}
constraint addr_val_align {
/* solve order constraints */
solve b_size before addr;
/* rand variable constraints */
addr == int'(addr/2**b_size) * 2**b_size;
}
constraint addr_val_unalign {
/* solve order constraints */
solve b_size before addr;
/* rand variable constraints */
addr != int'(addr/2**b_size) * 2**b_size;
}
// Constructor: new
function new(string name = "axi_transaction");
super.new(name);
endfunction: new
// Function: do_copy
extern function void do_copy(uvm_object rhs);
// Function: do_compare
extern function bit do_compare(uvm_object rhs, uvm_comparer comparer);
// Function: convert2string
extern function string convert2string();
// Function: do_print
extern function void do_print(uvm_printer printer);
// Function: do_record
// extern function void do_record(uvm_recorder recorder);
// Function: do_pack
// extern function void do_pack();
// Function: do_unpack
// extern function void do_unpack();
endclass: axi_transaction
/*----------------------------------------------------------------------------*/
/* Functions */
/*----------------------------------------------------------------------------*/
function void axi_transaction::do_print(uvm_printer printer);
/* chain the print with parent classes */
super.do_print(printer);
/* list of local properties to be printed: */
printer.print_field("ID", id, $bits(id), UVM_UNSIGNED);
printer.print_field("Addr", addr, $bits(addr), UVM_HEX);
printer.print_generic("Data", "dynamic array", 8*2**b_size*(b_len+1), $sformatf("%u", data));
printer.print_field("Burst Size", b_size, $bits(b_size), UVM_UNSIGNED);
printer.print_field("Burst Length", b_len+1, $bits(b_len), UVM_UNSIGNED);
printer.print_generic("Burst Type", "B_TYPE", $bits(b_len), b_type.name());
endfunction: do_print
function string axi_transaction::convert2string();
string s;
/* chain the convert2string with parent classes */
s = super.convert2string();
/* list of local properties to be printed: */
// guide 0---4---8--12--16--20--24--28--32--36--40--44--48--
s = {s, $sformatf("ID : %0d\n", id)};
s = {s, $sformatf("Addr : 0x%0h\n", addr)};
s = {s, $sformatf("Data : 0x%0u\n", data)};
s = {s, $sformatf("Busrt Type : %s\n", b_type.name())};
s = {s, $sformatf("Burst Size : %0d\n", b_size)};
s = {s, $sformatf("Busrt Length : %0d\n", b_len+1)};
s = {s, $sformatf("Busrt resp : 0x%0h\n", b_resp)};
s = {s, $sformatf("Read resp : %0u\n", r_resp)};
return s;
endfunction: convert2string
function void axi_transaction::do_copy(uvm_object rhs);
this_type_t rhs_;
if (!$cast(rhs_, rhs)) begin
`uvm_error({this.get_name(), ".do_copy()"}, "Cast failed!");
return;
end
// `uvm_info({this.get_name(), ".do_copy()"}, "Cast succeded.", UVM_HIGH);
/* chain the copy with parent classes */
super.do_copy(rhs);
/* list of local properties to be copied */
this.id = rhs_.id;
this.addr = rhs_.addr;
this.data = rhs_.data;
this.b_type = rhs_.b_type;
this.b_size = rhs_.b_size;
this.b_len = rhs_.b_len;
this.b_resp = rhs_.b_resp;
this.r_resp = rhs_.r_resp;
endfunction: do_copy
function bit axi_transaction::do_compare(uvm_object rhs, uvm_comparer comparer);
this_type_t rhs_;
if (!$cast(rhs_, rhs)) begin
`uvm_error({this.get_name(), ".do_compare()"}, "Cast failed!");
return 0;
end
// `uvm_info({this.get_name(), ".do_compare()"}, "Cast succeded.", UVM_HIGH);
/* chain the compare with parent classes */
do_compare = super.do_compare(rhs, comparer);
/* list of local properties to be compared: */
do_compare &= (
this.id == rhs_.id &&
this.addr == rhs_.addr &&
this.b_type == rhs_.b_type &&
this.b_size == rhs_.b_size &&
this.b_len == rhs_.b_len &&
this.b_resp == rhs_.b_resp
);
foreach(data[i,j]) begin
do_compare &= this.data[i][j] == rhs_.data[i][j];
end
foreach ( r_resp[i] ) begin
do_compare &= this.r_resp[i] == rhs_.r_resp[i];
end
endfunction: do_compare

+ 61
- 0
axi_write_seq.sv Прегледај датотеку

@@ -0,0 +1,61 @@
// Class: axi_write_seq
//
class axi_write_seq#(D_WIDTH = 16, int A_WIDTH = 16) extends uvm_sequence;
`uvm_object_param_utils(axi_write_seq#(D_WIDTH, A_WIDTH));
// Group: Variables
const int no_of_trans;
bit[7:0] id;
axi_transaction#(D_WIDTH, A_WIDTH) trans;
test_config test_cfg;
// Constructor: new
function new(string name = "axi_write_seq");
super.new(name);
test_cfg = new("test_cfg");
if(!uvm_config_db#(test_config)::get(null, "uvm_test_top.seq", "config", test_cfg))
`uvm_fatal(get_name(), "config cannot be found in ConfigDB!")
no_of_trans = test_cfg.no_write_cases;
endfunction: new
// Task: body
// This is the user-defined task where the main sequence code resides.
extern virtual task body();
endclass: axi_write_seq
task axi_write_seq::body();
repeat(no_of_trans) begin
id++;
trans = axi_transaction#(D_WIDTH, A_WIDTH)::type_id::create("trans");
if(test_cfg.isAligned) begin
trans.addr_val_align.constraint_mode(1);
trans.addr_val_unalign.constraint_mode(0);
trans.addr_val.constraint_mode(0);
end
else if (!test_cfg.isAligned) begin
trans.addr_val_align.constraint_mode(0);
trans.addr_val_unalign.constraint_mode(1);
trans.addr_val.constraint_mode(0);
end
else begin
trans.addr_val_align.constraint_mode(0);
trans.addr_val_unalign.constraint_mode(0);
trans.addr_val.constraint_mode(1);
end
start_item(trans);
if(test_cfg.burst_type == 0)
assert(trans.randomize() with { b_type == FIXED; });
else if(test_cfg.burst_type == 1)
assert(trans.randomize() with { b_type == INCR; });
else if(test_cfg.burst_type == 2)
assert(trans.randomize() with { b_type == WRAP; addr==16'h80c6;write==1;});
else
assert(trans.randomize());
trans.id = {1'b0, id};
finish_item(trans);
trans.print();
#10;
end
endtask: body

Loading…
Откажи
Сачувај