This commit is contained in:
2026-06-12 07:53:32 +02:00
commit 59e71f3297
259 changed files with 29010 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
/****************************************************************************
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
|F|u|n|c|t|i|o|n|a|l| |V|e|r|i|f|i|c|a|t|i|o|n| |o|f| |H|a|r|d|w|a|r|e|
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
FILE apb_master_agent.sv
DESCRIPTION master agent
****************************************************************************/
`ifndef APB_MASTER_AGENT_SV
`define APB_MASTER_AGENT_SV
/**
* Class: apb_master_agent
*/
class apb_master_agent extends uvm_agent;
// configuration object
apb_config cfg;
// components
apb_master_driver drv;
apb_master_sequencer seqr;
apb_master_monitor mon;
// UVM factory registration
`uvm_component_utils_begin(apb_master_agent)
`uvm_field_object(cfg, UVM_DEFAULT | UVM_REFERENCE)
`uvm_component_utils_end
// new - constructor
function new(string name = "apb_master_agent", uvm_component parent = null);
super.new(name, parent);
endfunction : new
// UVM build_phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
// get configuration object from db
if(!uvm_config_db#(apb_config)::get(this, "", "apb_config", cfg))
`uvm_fatal("NOCONFIG",{"Config object must be set for: ",get_full_name(),".cfg"})
// create driver and sequencer if agent is active
if(cfg.master_cfg.is_active == UVM_ACTIVE) begin
seqr = apb_master_sequencer::type_id::create("seqr", this);
drv = apb_master_driver::type_id::create("drv", this);
end
// always create monitor
mon = apb_master_monitor::type_id::create("mon", this);
endfunction : build_phase
// UVM connect_phase
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
// connect driver and sequencer if agent is active
if(cfg.master_cfg.is_active == UVM_ACTIVE) begin
drv.seq_item_port.connect(seqr.seq_item_export);
end
endfunction : connect_phase
endclass : apb_master_agent
`endif

View File

@@ -0,0 +1,41 @@
/****************************************************************************
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
|F|u|n|c|t|i|o|n|a|l| |V|e|r|i|f|i|c|a|t|i|o|n| |o|f| |H|a|r|d|w|a|r|e|
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
FILE apb_master_config.sv
DESCRIPTION master configuration object
****************************************************************************/
`ifndef APB_MASTER_CONFIG_SV
`define APB_MASTER_CONFIG_SV
/**
* Class: apb_master_config
*/
class apb_master_config extends uvm_object;
// is agent active or passive
uvm_active_passive_enum is_active = UVM_ACTIVE;
// checks and coverage control
bit has_checks = 1;
bit has_coverage = 1;
// UVM factory registration
`uvm_object_utils_begin(apb_master_config)
`uvm_field_enum(uvm_active_passive_enum, is_active, UVM_DEFAULT)
`uvm_field_int(has_checks, UVM_DEFAULT)
`uvm_field_int(has_coverage, UVM_DEFAULT)
`uvm_object_utils_end
// new - constructor
function new(string name = "apb_master_config");
super.new(name);
endfunction : new
endclass : apb_master_config
`endif

View File

@@ -0,0 +1,132 @@
/****************************************************************************
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
|F|u|n|c|t|i|o|n|a|l| |V|e|r|i|f|i|c|a|t|i|o|n| |o|f| |H|a|r|d|w|a|r|e|
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
FILE apb_master_driver.sv
DESCRIPTION
****************************************************************************/
`ifndef APB_MASTER_DRIVER_SV
`define APB_MASTER_DRIVER_SV
/**
* Class: apb_master_driver
*/
class apb_master_driver extends uvm_driver #(apb_transaction, apb_transaction);
// apb virtual interface
virtual apb_if vif;
// configuration
apb_config cfg;
// UVM factory registration
`uvm_component_utils_begin(apb_master_driver)
`uvm_field_object(cfg, UVM_DEFAULT | UVM_REFERENCE)
`uvm_component_utils_end
// new - constructor
function new(string name = "apb_master_driver", uvm_component parent = null);
super.new(name, parent);
endfunction : new
// UVM build_phase
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
// get configuration object from db
if(!uvm_config_db#(apb_config)::get(this, "*", "apb_config", cfg))
`uvm_fatal("NOCONFIG",{"Config object must be set for: ",get_full_name(),".cfg"})
endfunction: build_phase
// UVM connect_phase
virtual function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
// get interface from db
if(!uvm_config_db#(virtual apb_if)::get(this, "", "apb_if", vif))
`uvm_fatal("NOVIF",{"virtual interface must be set for: ",get_full_name(),".vif"})
endfunction : connect_phase
// additional class methods
extern virtual task run_phase(uvm_phase phase);
extern virtual task get_and_drive();
extern virtual task reset();
extern virtual task drive_tr (apb_transaction tr);
endclass : apb_master_driver
// UVM run_phase
task apb_master_driver::run_phase(uvm_phase phase);
reset(); // init.
forever begin
fork
get_and_drive(); // thread killed at reset
@(negedge vif.presetn); // reset is active low
join_any
disable fork;
reset();
end
endtask : run_phase
// reset signals
task apb_master_driver::reset();
`uvm_info(get_type_name(), "Reset observed", UVM_MEDIUM)
vif.paddr <= {ADDR_WIDTH {1'b0}};
vif.pwdata <= {WDATA_WIDTH {1'b0}};
vif.pwrite <= 1'b0;
vif.psel <= {SLV_NUM {1'b0}};
vif.penable <= 1'b0;
@(posedge vif.presetn); // reset dropped
endtask : reset
// sequencer/driver handshake
task apb_master_driver::get_and_drive();
forever begin
seq_item_port.get_next_item(req);
drive_tr(req);
seq_item_port.item_done();
end
endtask : get_and_drive
// drive transaction
task apb_master_driver::drive_tr (apb_transaction tr);
int unsigned slave_index;
// delay
@(posedge vif.pclk);
if (tr.delay > 0) begin
repeat(tr.delay) @(posedge vif.pclk);
end
// address phase
slave_index = cfg.get_slave_psel_by_addr(tr.addr);
if(slave_index == 0) begin
`uvm_warning(get_type_name(), "No slave with choosed address")
return;
end
vif.paddr <= tr.addr;
vif.psel <= (1 << (slave_index - 1));
vif.penable <= 0;
vif.pwrite <= apb_direction_enum'(tr.dir);
if (tr.dir == APB_WRITE) begin
vif.pwdata <= tr.wdata;
end
// data phase
@(posedge vif.pclk);
vif.penable <= 1;
@(posedge vif.pclk iff vif.pready);
tr.error = vif.pslverr;
if (tr.dir == APB_READ) begin
tr.rdata = vif.prdata;
end
vif.penable <= 0;
vif.psel <= 0;
`uvm_info(get_type_name(), $sformatf("APB Finished Driving tr \n%s", tr.sprint()), UVM_HIGH)
endtask : drive_tr
`endif

View File

@@ -0,0 +1,140 @@
/****************************************************************************
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
|F|u|n|c|t|i|o|n|a|l| |V|e|r|i|f|i|c|a|t|i|o|n| |o|f| |H|a|r|d|w|a|r|e|
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
FILE apb_master_monitor.sv
DESCRIPTION
****************************************************************************/
`ifndef APB_MASTER_MONITOR_SV
`define APB_MASTER_MONITOR_SV
/**
* Class: apb_master_monitor
*/
class apb_master_monitor extends uvm_monitor;
// apb virtual interface
virtual apb_if vif;
// configuration
apb_config cfg;
// TLM - from monitor to other components
uvm_analysis_port #(apb_transaction) item_collected_port;
// keep track of number of transactions
int unsigned num_transactions = 0;
// current transaction
apb_transaction tr_collected;
// UVM factory registration
`uvm_component_utils_begin(apb_master_monitor)
`uvm_field_object(cfg, UVM_DEFAULT | UVM_REFERENCE)
`uvm_component_utils_end
// coverage
covergroup cg_apb_master;
// cover direction - read or write
cp_direction : coverpoint tr_collected.dir {
bins write = {APB_WRITE};
bins read = {APB_READ};
}
// cover delay - zero or more
cp_delay : coverpoint tr_collected.delay {
bins zero = {0};
bins other = default;
}
// TODO : add others
endgroup : cg_apb_master;
// new - constructor
function new(string name = "apb_master_monitor", uvm_component parent = null);
super.new(name, parent);
item_collected_port = new("item_collected_port", this);
cg_apb_master = new();
endfunction : new
// UVM build_phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
// get configuration object from db
if(!uvm_config_db#(apb_config)::get(this, "", "apb_config", cfg))
`uvm_fatal("NOCONFIG",{"Config object must be set for: ",get_full_name(),".cfg"})
endfunction: build_phase
// UVM connect_phase
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
// get interface from db
if(!uvm_config_db#(virtual apb_if)::get(this, "", "apb_if", vif))
`uvm_fatal("NOVIF",{"virtual interface must be set for: ",get_full_name(),".vif"})
endfunction : connect_phase
// additional class methods
extern virtual task run_phase(uvm_phase phase);
extern virtual task collect_transactions();
extern virtual function void report_phase(uvm_phase phase);
endclass : apb_master_monitor
// UVM run_phase
task apb_master_monitor::run_phase(uvm_phase phase);
forever begin
@(posedge vif.presetn); // reset dropped
`uvm_info(get_type_name(), "Reset dropped", UVM_MEDIUM)
fork
collect_transactions(); // thread killed at reset
@(negedge vif.presetn); // reset is active low
join_any
disable fork;
end
endtask : run_phase
// monitor apb interface and collect transactions
task apb_master_monitor::collect_transactions();
forever begin
tr_collected = apb_transaction::type_id::create("tr_collected");
// wait for valid transaction
@(posedge vif.pclk iff (vif.psel != 0));
tr_collected.addr = vif.paddr;
tr_collected.dir = apb_direction_enum'(vif.pwrite);
if(tr_collected.dir == APB_WRITE)
tr_collected.wdata = vif.pwdata;
@(posedge vif.pclk); // enable
@(posedge vif.pclk); // ready
while (vif.pready !== 1'b1) begin
@(posedge vif.pclk);
tr_collected.delay++;
end
if(tr_collected.dir == APB_READ) begin
tr_collected.rdata = vif.prdata;
tr_collected.error = vif.pslverr;
end
item_collected_port.write(tr_collected); // TLM
// collect coverage if enabled
if(cfg.has_coverage == 1) begin
cg_apb_master.sample();
end
`uvm_info(get_type_name(), $sformatf("Tr collected :\n%s", tr_collected.sprint()), UVM_MEDIUM)
num_transactions++;
end // forever
endtask : collect_transactions
// UVM report_phase
function void apb_master_monitor::report_phase(uvm_phase phase);
// final report
`uvm_info(get_type_name(), $sformatf("Report: APB monitor collected %0d transfers", num_transactions), UVM_LOW);
endfunction : report_phase
`endif

View File

@@ -0,0 +1,44 @@
/****************************************************************************
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
|F|u|n|c|t|i|o|n|a|l| |V|e|r|i|f|i|c|a|t|i|o|n| |o|f| |H|a|r|d|w|a|r|e|
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
FILE apb_master_sequencer.sv
DESCRIPTION
****************************************************************************/
`ifndef APB_MASTER_SEQUENCER_SV
`define APB_MASTER_SEQUENCER_SV
/**
* Class: apb_master_sequencer
*/
class apb_master_sequencer extends uvm_sequencer #(apb_transaction, apb_transaction);
// configuration
apb_config cfg;
// UVM factory registration
`uvm_component_utils_begin(apb_master_sequencer)
`uvm_field_object(cfg, UVM_DEFAULT | UVM_REFERENCE)
`uvm_component_utils_end
// new - constructor
function new(string name = "apb_master_sequencer", uvm_component parent = null);
super.new(name, parent);
endfunction : new
// UVM build_phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
// get configuration object from db
if(!uvm_config_db#(apb_config)::get(this, "", "apb_config", cfg))
`uvm_fatal("NOCONFIG",{"Config object must be set for: ",get_full_name(),".cfg"})
endfunction: build_phase
endclass : apb_master_sequencer
`endif

View File

@@ -0,0 +1,33 @@
/****************************************************************************
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
|F|u|n|c|t|i|o|n|a|l| |V|e|r|i|f|i|c|a|t|i|o|n| |o|f| |H|a|r|d|w|a|r|e|
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
FILE apb_master_base_seq.sv
DESCRIPTION base sequence to be extended by other sequences
****************************************************************************/
`ifndef APB_MASTER_BASE_SEQ_SV
`define APB_MASTER_BASE_SEQ_SV
/**
* Class: apb_master_base_seq
*/
class apb_master_base_seq extends uvm_sequence #(apb_transaction, apb_transaction);
// p_sequencer for APB master sequences
`uvm_declare_p_sequencer(apb_master_sequencer)
// UVM factory registration
`uvm_object_utils(apb_master_base_seq)
// new - constructor
function new(string name = "apb_master_base_seq");
super.new(name);
endfunction : new
endclass : apb_master_base_seq
`endif

View File

@@ -0,0 +1,50 @@
/****************************************************************************
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
|F|u|n|c|t|i|o|n|a|l| |V|e|r|i|f|i|c|a|t|i|o|n| |o|f| |H|a|r|d|w|a|r|e|
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
FILE apb_master_read_after_write_seq.sv
DESCRIPTION sequence for writing and reading from one address
****************************************************************************/
`ifndef APB_MASTER_READ_AFTER_WRITE_SEQ_SV
`define APB_MASTER_READ_AFTER_WRITE_SEQ_SV
/**
* Class: apb_master_read_after_write_seq
*/
class apb_master_read_after_write_seq extends apb_master_base_seq;
rand int unsigned delay; // transaction delay
rand bit [ADDR_WIDTH - 1 : 0] addr; // address to write/read
// constraints
constraint delay_cst { delay inside {[1 : 10]};}
// UVM factory registration
`uvm_object_utils(apb_master_read_after_write_seq)
// new - constructor
function new(string name = "apb_master_read_after_write_seq");
super.new(name);
endfunction : new
// sequence generation logic in body
virtual task body();
// write
`uvm_do_with( req,
{req.addr == addr;
req.dir == APB_READ;
req.delay == delay;})
// read
`uvm_do_with( req,
{req.addr == addr;
req.dir == APB_READ;
req.delay == delay;})
endtask : body
endclass : apb_master_read_after_write_seq
`endif

View File

@@ -0,0 +1,50 @@
/****************************************************************************
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
|F|u|n|c|t|i|o|n|a|l| |V|e|r|i|f|i|c|a|t|i|o|n| |o|f| |H|a|r|d|w|a|r|e|
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
FILE apb_master_read_all_seq.sv
DESCRIPTION sequence for reading from all valid addresses
****************************************************************************/
`ifndef APB_MASTER_READ_ALL_SEQ_SV
`define APB_MASTER_READ_ALL_SEQ_SV
/**
* Class: apb_master_read_all_seq
*/
class apb_master_read_all_seq extends apb_master_base_seq;
// UVM factory registration
`uvm_object_utils(apb_master_read_all_seq)
// new - constructor
function new(string name = "apb_master_read_all_seq");
super.new(name);
endfunction : new
// sequence generation logic in body
virtual task body();
bit [ADDR_WIDTH - 1 : 0] end_addr, curr_addr;
// read from all addresses in all slaves
foreach (p_sequencer.cfg.slave_cfg_queue[i]) begin
curr_addr = p_sequencer.cfg.slave_cfg_queue[i].start_address;
end_addr = p_sequencer.cfg.slave_cfg_queue[i].end_address;
while (curr_addr != end_addr) begin
`uvm_do_with( req, {
req.addr == curr_addr;
req.dir == APB_READ;})
curr_addr++;
end
end
endtask : body
endclass : apb_master_read_all_seq
`endif

View File

@@ -0,0 +1,44 @@
/****************************************************************************
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
|F|u|n|c|t|i|o|n|a|l| |V|e|r|i|f|i|c|a|t|i|o|n| |o|f| |H|a|r|d|w|a|r|e|
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
FILE apb_master_read_seq.sv
DESCRIPTION sequence for reading from one address
****************************************************************************/
`ifndef APB_MASTER_READ_SEQ_SV
`define APB_MASTER_READ_SEQ_SV
/**
* Class: apb_master_read_seq
*/
class apb_master_read_seq extends apb_master_base_seq;
rand int unsigned delay; // transaction delay
rand bit [ADDR_WIDTH - 1 : 0] addr; // address to read
// constraints
constraint delay_cst { delay inside {[1 : 10]};}
// UVM factory registration
`uvm_object_utils(apb_master_read_seq)
// new - constructor
function new(string name = "apb_master_read_seq");
super.new(name);
endfunction : new
// sequence generation logic in body
virtual task body();
`uvm_do_with( req,
{req.addr == addr;
req.dir == APB_READ;
req.delay == delay;})
endtask : body
endclass : apb_master_read_seq
`endif

View File

@@ -0,0 +1,23 @@
/****************************************************************************
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
|F|u|n|c|t|i|o|n|a|l| |V|e|r|i|f|i|c|a|t|i|o|n| |o|f| |H|a|r|d|w|a|r|e|
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
FILE apb_master_seq_lib.sv
DESCRIPTION sequence includes
****************************************************************************/
`ifndef APB_MASTER_SEQ_LIB_SV
`define APB_MASTER_SEQ_LIB_SV
`include "master/sequences/apb_master_base_seq.sv"
`include "master/sequences/apb_master_simple_seq.sv"
`include "master/sequences/apb_master_read_seq.sv"
`include "master/sequences/apb_master_write_seq.sv"
`include "master/sequences/apb_master_read_all_seq.sv"
`include "master/sequences/apb_master_write_all_seq.sv"
`include "master/sequences/apb_master_read_after_write_seq.sv"
`endif

View File

@@ -0,0 +1,42 @@
/****************************************************************************
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
|F|u|n|c|t|i|o|n|a|l| |V|e|r|i|f|i|c|a|t|i|o|n| |o|f| |H|a|r|d|w|a|r|e|
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
FILE apb_master_simple_seq.sv
DESCRIPTION simple sequence; random transactions
****************************************************************************/
`ifndef APB_MASTER_SIMPLE_SEQ_SV
`define APB_MASTER_SIMPLE_SEQ_SV
/**
* Class: apb_master_simple_seq
*/
class apb_master_simple_seq extends apb_master_base_seq;
rand int unsigned num_of_tr;
// constraints
constraint num_of_tr_cst { num_of_tr inside {[1 : 10]};}
// UVM factory registration
`uvm_object_utils(apb_master_simple_seq)
// new - constructor
function new(string name = "apb_master_simple_seq");
super.new(name);
endfunction : new
// sequence generation logic in body
virtual task body();
repeat(num_of_tr) begin
`uvm_do(req)
end
endtask : body
endclass : apb_master_simple_seq
`endif

View File

@@ -0,0 +1,64 @@
/****************************************************************************
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
|F|u|n|c|t|i|o|n|a|l| |V|e|r|i|f|i|c|a|t|i|o|n| |o|f| |H|a|r|d|w|a|r|e|
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
FILE apb_master_write_all_seq.sv
DESCRIPTION sequence for writing to all valid addresses
****************************************************************************/
`ifndef APB_MASTER_WRITE_ALL_SEQ_SV
`define APB_MASTER_WRITE_ALL_SEQ_SV
/**
* Class: apb_master_write_all_seq
*/
class apb_master_write_all_seq extends apb_master_base_seq;
bit data_is_rand = 1; // 1 = data will be randomly chosen for every write
// 0 = used data from "data_to_write" field
bit [WDATA_WIDTH - 1 : 0] data_to_write;
rand bit [WDATA_WIDTH - 1 : 0] data;
// UVM factory registration
`uvm_object_utils(apb_master_write_all_seq)
// new - constructor
function new(string name = "apb_master_write_all_seq");
super.new(name);
endfunction : new
// sequence generation logic in body
virtual task body();
bit [ADDR_WIDTH - 1 : 0] end_addr, curr_addr;
// write to all addresses in all slaves
foreach (p_sequencer.cfg.slave_cfg_queue[i]) begin
curr_addr = p_sequencer.cfg.slave_cfg_queue[i].start_address;
end_addr = p_sequencer.cfg.slave_cfg_queue[i].end_address;
while (curr_addr != end_addr) begin
if (data_is_rand) begin
assert(this.randomize());
end
else begin
data = data_to_write;
end
`uvm_do_with( req, {
req.addr == curr_addr;
req.wdata == data;
req.dir == APB_WRITE;})
curr_addr++;
end
end
endtask : body
endclass : apb_master_write_all_seq
`endif

View File

@@ -0,0 +1,47 @@
/****************************************************************************
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
|F|u|n|c|t|i|o|n|a|l| |V|e|r|i|f|i|c|a|t|i|o|n| |o|f| |H|a|r|d|w|a|r|e|
+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+ +-+-+-+-+-+-+-+-+
FILE apb_master_write_seq.sv
DESCRIPTION sequence for writing to one address
****************************************************************************/
`ifndef APB_MASTER_WRITE_SEQ_SV
`define APB_MASTER_WRITE_SEQ_SV
/**
* Class: apb_master_write_seq
*/
class apb_master_write_seq extends apb_master_base_seq;
rand int unsigned delay; // transaction delay
rand bit [ADDR_WIDTH - 1 : 0] addr; // address to write
rand bit [WDATA_WIDTH - 1 : 0] data; // data to write
// constraints
constraint delay_cst { delay inside {[1 : 10]};}
// UVM factory registration
`uvm_object_utils(apb_master_write_seq)
// new - constructor
function new(string name = "apb_master_write_seq");
super.new(name);
endfunction : new
// sequence generation logic in body
virtual task body();
`uvm_do_with( req, {
req.addr == addr;
req.dir == APB_WRITE;
req.wdata == data;
req.delay == delay;})
endtask : body
endclass : apb_master_write_seq
`endif