使用DVT看一下目前结构:
完善lvc_ahb_if:
`ifndef LVC_AHB_IF_SV
`define LVC_AHB_IF_SV
interface lvc_ahb_if;
logic hclk;
logic hresetn;
logic hgrant;
logic [(`LVC_AHB_MAX_DATA_WIDTH - 1):0] hrdata;
logic hready;
logic [1:0] hresp;//response
logic [(`LVC_AHB_MAX_ADDR_WIDTH - 1):0] haddr;
logic [2:0] hburst;
logic hbusreq;
logic hlock;
logic [3:0] hprot;//protect
logic [2:0] hsize;
logic [1:0] htrans;
logic [(`LVC_AHB_MAX_DATA_WIDTH - 1):0] hwdata;
logic hwrite;
endinterface
`endif // LVC_AHB_IF_SV
defines文件:定义vif中需要的宏
`ifndef LVC_AHB_DEFINES_SVH
`define LVC_AHB_DEFINES_SVH
`define LVC_AHB_MAX_DATA_WIDTH 64//最长的数据和地址宽度
`define LVC_AHB_MAX_ADDR_WIDTH 32
`endif // LVC_AHB_DEFINES_SVH
补充上DUT与vif在tb中的连接、时钟、复位信号:clk在tb中做,rstn在ahbram_if中做
logic clk;
logic rstn;
initial begin : clk_gen
clk = 0;
forever #2ns clk = !clk;
end
ahb_blockram_32 #(.ADDRESSWIDTH(16)) dut(
.HCLK(ahb_if.hclk)
,.HRESETn(ahb_if.hresetn)
,.HSELBRAM(1'b1)
,.HREADY(ahb_if.hready)
,.HTRANS(ahb_if.htrans)
,.HSIZE(ahb_if.hsize)
,.HWRITE(ahb_if.hwrite)
,.HADDR(ahb_if.haddr)
,.HWDATA(ahb_if.hwdata)
,.HREADYOUT(ahb_if.hready)
,.HRESP(ahb_if.hresp)
,.HRDATA(ahb_if.hrdata)
);
lvc_ahb_if ahb_if();
assign ahb_if.hclk = clk;
assign ahb_if.hresetn = rstn;
assign ahb_if.hgrant = 1'b1;
rkv_ahbram_if ahbram_if();
assign ahbram_if.clk = clk;
assign rstn = ahbram_if.rstn;
rstn复位信号从ahbram_if中给出:rstn的task没有放tb里面做,方便以后的调用
initial begin : rstn_gen
assert_reset(10);
end
task automatic assert_reset(int nclks = 1, int delay = 0);
#(delay * 1ns);
repeat(nclks) @(posedge clk);
rstn <= 0;
repeat(5) @(posedge clk);
rstn <= 1;
endtask
----------------------------------------扩充driver先完善trans------------------------------------
根据AHB协议,完善types文件
`ifndef LVC_AHB_TYPES_SV
`define LVC_AHB_TYPES_SV
typedef enum bit[1:0] {
OKAY = 2'b00, /**< OKAY response */
ERROR = 2'b01, /**< ERROR response */
RETRY = 2'b10, /**< RETRY response */
SPLIT = 2'b11 /**< SPLIT response */
} response_type_enum;
typedef enum bit[1:0] {
IDLE = 2'b00, /**< IDLE transaction */
BUSY = 2'b01, /**< BUSY transaction */
NSEQ = 2'b10, /**< NONSEQUENTIAL transaction */
SEQ = 2'b11 /**< SEQUENTIAL transaction */
} trans_type_enum;
typedef enum bit[2:0] {
BURST_SIZE_8BIT = 3'b000, /**< 8-bits transfer size */
BURST_SIZE_16BIT = 3'b001, /**< 16-bits transfer size */
BURST_SIZE_32BIT = 3'b010, /**< 32-bits transfer size */
BURST_SIZE_64BIT = 3'b011, /**< 64-bits transfer size */
BURST_SIZE_128BIT = 3'b100, /**< 128-bits transfer size */
BURST_SIZE_256BIT = 3'b101, /**< 256-bits transfer size */
BURST_SIZE_512BIT = 3'b110, /**< 512-bits transfer size */
BURST_SIZE_1024BIT = 3'b111 /**< 1024-bits transfer size */
} burst_size_enum;
typedef enum bit[2:0] {
SINGLE = 3'b000, /**< SINGLE Burst type */
INCR = 3'b001, /**< INCR Burst type */
WRAP4 = 3'b010, /**< 4-beat WRAP Burst type */
INCR4 = 3'b011, /**< 4-beat INCR Burst type */
WRAP8 = 3'b100, /**< 8-beat WRAP Burst type */
INCR8 = 3'b101, /**< 8-beat INCR Burst type */
WRAP16 = 3'b110, /**< 16-beat WRAP Burst type */
INCR16 = 3'b111 /**< 16-beat INCR Burst type */
} burst_type_enum;
typedef enum bit[1:0] {
READ = 2'b00, /**< Read transaction. */
WRITE = 2'b01, /**< Write transaction. */
IDLE_XACT = 2'b10 /**< Idle transaction. In case of active Master:
all the control signals except hlock(always zero) can be controlled
through respective transaction attributes
(similar to READ or WRITE transaction types);
the value of hwrite signal can be controlled through
lvc_ahb_transaction::idle_xact_hwrite. */
} xact_type_enum;
typedef enum bit[1:0] {
INITIAL ='b00, // Indicates the default state of the flag. It gets
// updated once the beat level transfer begins
PARTIAL_ACCEPT ='b01, // The status changes from INITIAL to PARTIAL_ACCEPT
// once the address of each beat is accepted by slave
ACCEPT ='b10, // The status changes to ACCEPT once the beat level
// data is accepted by the slave
ABORTED ='b11 // The status changes to ABORT in case the transaction
// is ABORTED due to ERROR/SPLIT or RETRY response from
// the slave or in case of EBT
} status_enum;
`endif
更新transcation:
`ifndef LVC_AHB_TRANSACTION_SV
`define LVC_AHB_TRANSACTION_SV
class lvc_ahb_transaction extends uvm_sequence_item;
// wdata or rdata from bus
rand bit [`LVC_AHB_MAX_DATA_WIDTH - 1:0] data[];
rand bit [`LVC_AHB_MAX_ADDR_WIDTH - 1 : 0] addr = 0;
// Represents the burst size of a transaction
rand burst_size_enum burst_size = BURST_SIZE_8BIT;//一个数据的位宽
// Represents the transaction type of a transaction
rand burst_type_enum burst_type = SINGLE ;//连续发送的模式
// Response from the slave.
rand response_type_enum response_type = OKAY;
//************************************************
// NOTE:: members possibly to be applied later可能后期使用
//************************************************
// Indicates the type of the current transfer, which can be
trans_type_enum trans_type;
// This array variable stores the responses for all the completed beats of transaction. Following are the possible response types
response_type_enum all_beat_response[];
// Indicates the beat number of the current transfer当前传输节拍数
int current_data_beat_num;
// Represents the current status of the transaction表示当前的事务状态
status_enum status = INITIAL;
// aborted_xact_status_enum aborted_xact_status = NOT_ABORTED;
// Represents the hwrite signal value when
rand bit idle_xact_hwrite = 1;//附一个默认值
`uvm_object_utils_begin(lvc_ahb_transaction)
`uvm_object_utils_end
function new(string name = "lvc_ahb_transaction");
super.new(name);
endfunction
endclass
`endif // LVC_AHB_TRANSACTION_SV