UVM验证平台搭建五: spi sequences
一、概述
sequence总体上分为两大部分,一部分是用来控制dut,一部分是用来控制vip的。在spi模块中,通过apb总线来读写寄存器来配置spi dut的配置,实现不同的功能。
二、spi dut sequence
2.1 spi sequence base
`ifndef SEQ_BASE_SVH
`define SEQ_BASE_SVH
class seq_base extends uvm_sequence;
`uvm_object_utils(seq_base)
`uvm_declare_p_sequencer(spi_vsqr)
//register model variables
uvm_status_e status;
//spi reg
bit [15:0] spi_cr1;
bit [15:0] spi_cr2;
bit [15:0] spi_sr;
bit [15:0] spi_dr;
bit [15:0] spi_crcpr;
bit [15:0] spi_rxcrcr;
bit [15:0] spi_txcrcr;
bit [15:0] spi_i2scfgr;
//spi cr1 bits
bit cpha;
bit cpol;
bit mstr;
bit [2:0] br;
bit spe;
bit lsbfirst;
bit ssi;
bit ssm;
bit rxonly;
bit dff;
bit crcnext;
bit crcen;
bit bidioe;
bit bidimode;
//spi cr2 bits
bit rxdmaen;
bit txdmaen;
bit ssoe;
bit nssp;
bit frf;
bit errie;
bit rxneie;
bit txeie;
bit [3:0] ds;
bit frxth;
bit ldma_rx;
bit ldma_tx;
//spi sr bits
bit rxne;
bit txe;
bit chside;
bit udr;
bit crcerr;
bit modf;
bit ovr;
bit bsy;
bit fre;
bit [1:0] frlvl;
bit [1:0] ftlvl;
//spi dr bits
randc bit [15:0] dr;
//spi crcpr bits
bit [15:0] crcpoly;
//spi rxcrcr bits
bit [15:0] rxcrc;
//spi txcrcr bits
bit [15:0] txcrc;
//spi_i2scfgr
bit i2smod;
bit i2se;
bit [1:0] i2scfg;
bit pcmsync;
bit [1:0] i2sstd;
bit ckpol;
bit [1:0] datlen;
bit chlen;
//spi_i2spr
bit mckoe;
bit odd;
bit [7:0] i2sdiv;
function new(string name = "seq_base");
super.new(name);
endfunction
virtual task body();
spi_cr1 = {bidimode, bidioe, crcen, crcnext, dff, rxonly, ssm, ssi, lsbfirst, spe, br, mstr, cpol, cpha};
spi_cr2 = {1'b0, ldma_tx, ldma_rx, frxth, ds, txeie, rxneie, errie, frf, nssp, ssoe, txdmaen, rxdmaen};
spi_sr = {3'b0, ftlvl, frlvl, fre, bsy, ovr, modf, crcerr, udr, chside, txe, rxne};
spi_dr = {dr};
spi_crcpr = {crcpoly};
spi_rxcrcr = {rxcrc};
spi_txcrcr = {txcrc};
spi_i2scfgr = {4'b0, i2smod, i2se, i2scfg, pcmsync, 1'b0, i2sstd, ckpol, datlen, chlen};
spi_i2spr = {6'b0, mckoe, odd, i2sdiv};
endtask
endclass
`endif //SEQ_BASE_SVH
2.2 spi spe enable sequence
class spi_spe_enable_seq extend seq_base;
`uvm_object_utils(spi_spe_enable_seq)
function new(string name = "spi_spe_enable_seq")
supre.new(name);
endfunction
task body();
super.body();
p_sequencer.p_rm.spi_cr1.read(status,spi_cr1,UVM_FRONTDOOR);
p_sequencer.p_rm.spi_cr1.write(status,(spi_cr1|32'h40),UVM_FRONTDOOR);
endtask
endclass: spi_spe_enable_seq
2.3 spi write txdata sequence
`ifndef SPI_WR_DATA_SEQ_SVH
`define SPI_WR_DATA_SEQ_SVH
class spi_wr_data_seq extends seq_base;
`uvm_object_utils(spi_wr_data_seq)
function new(string name = "spi_wr_data_seq");
super.new(name);
endfunction
p_sequencer.p_rm.spi_sr.read(status,spi_sr,UVM_FRONTDOOR);
while(~spi_sr[1])
p_sequencer.p_rm.spi_sr.read(status,spi_sr,UVM_FRONTDOOR);
p_sequencer.p_rm.spi_dr.write(status,spi_dr,UVM_FRONTDOOR);
endclass
`endif //SPI_WR_DATA_SEQ_SVH
…
…
三、spi vip sequence
3.1 spi vip base sequence
`ifndef VIP_BASE_SEQ_SVH
`define VIP_BASE_SEQ_SVH
class vip_base_seq extends uvm_sequence;
`uvm_object_utils(vip_base_seq)
spi_slv_transaction slv_tr;
spi_mst_transaction mst_tr;
randc bit [15:0] vip_txdata;
randc bit [15:0] vip_rxdata;
function new(string name = "vip_base_seq");
super.new(name);
endfunction
enclass: vip_base_seq
`endif //VIP_BASE_SEQ_SVH
3.2 spi vip mst sequence
`ifndef VIP_MST_SEQ_SVH
`define VIP_MST_SEQ_SVH
class vip_mst_seq extends vip_base_seq;
`uvm_object_utils(vip_mst_seq)
function new(string name = "vip_mst_seq");
supre.new(name);
endfunction
task body();
super.body();
`uvm_do_with(mst_tr,{mst_tr.txdata == vip_txdata;})
endtask
endclass
`endif //VIP_MST_SEQ_SVH
3.3 spi vip slv sequence
`ifndef VIP_MST_SEQ_SVH
`define VIP_MST_SEQ_SVH
class vip_mst_seq extends vip_base_seq;
`uvm_object_utils(vip_mst_seq)
function new(string name = "vip_mst_seq");
super.new(name);
endfunction
task body();
super.body();
`uvm_do_with(mst_tr,{mst_tr.txdata == vip_txdata;})
endtask
endclass: vip_mst_seq
`endif //VIP_MST_SEQ_SVH