AHB_SRAM UVM验证(3)完善interface以及transaction

完善interface以及transaction

在上一节以及搭建好了整个uvm的验证环境,添加了base的test以及base的virtual sequence。

  • 完善lvc_ahb_if:定义的信号与dut的接口信号一致。下方的时钟块是为了与组件匹配,确定信号的传输方向。master与slave的驱动方向相反。是为了驱动和采集interface的信号。对于monitor而言,需要采集所有的信号。
`ifndef LVC_AHB_IF_SV
`define LVC_AHB_IF_SV
 
interface lvc_ahb_if;
`include "lvc_ahb_defines.svh"
import lvc_ahb_pkg::*;

	logic 									hclk;
	logic    								hresetn;	
	logic 									hgrant;	
	logic [(`LVC_AHB_MAX_DATA_WIDTH-1):0]	hrdata;
	logic 									hready;
	logic [1:0] 							hresp;
	logic [(`LVC_AHB_MAX_ADDR_WIDTH-1):0]	haddr;
	logic [2:0] 							hburst;
	logic 									hbusreq;
	logic 									hlock;
	logic [3:0] 							hprot;
	logic [2:0] 							hsize;
	logic [1:0] 							htrans;
	logic [(`LVC_AHB_MAX_DATA_WIDTH-1):0]	hwdata;
	logic 									hwrite;

	// debug 
	response_type_enum       debug_hresp;
	trans_type_enum          debug_htrans;
	burst_size_enum 		 debug_size;
	burst_type_enum 		 debug_hburst;
	xact_type_enum 			 debug_xact;
	status_enum 			 debug_status;


	// debug signals assignment
	assign debug_hresp    = response_type_enum'(hresp);
	assign debug_htrans   = trans_type_enum'(htrans);
	assign debug_hsize    = burst_size_enum'(hsize);
	assign debug_hburst   = burst_type_enum'(hburst);
	// the below signals to be assigned by monitor
	// debug_xact ..
	// debug_status ..


	// clk block
	clocking cb_mst @(posedge hclk);
	// USER: Add clocking block detail
		default input #1ps output #1ps;
		output haddr, hburst, hbusreq, hlock, hprot, hsize, htrans, hwdata, hwrite;
		input  hready, hgrant, hrdata, hresp;
	endclocking : cb_mst

	clocking cb_slv @(posedge hclk);
	// USER: Add clocking block detail
		default input #1ps output #1ps;
		input   haddr, hburst, hbusreq, hlock, hprot, hsize, htrans, hwdata, hwrite;
		output  hready, hgrant, hrdata, hresp;		
	endclocking : cb_slv

	clocking cb_mon @(posedge hclk);
	// USER: Add clocking block detail
		default input #1ps output #1ps;
		input  haddr, hburst, hbusreq, hlock, hprot, hsize, htrans, hwdata, hwrite;
		input  hready, hgrant, hrdata, hresp;
	
	endclocking : cb_mon

endinterface
`endif
  • 完善了lvc的interface文件后需要完善在tb中与dut的连接:
  • 可以看出lvc的interface中的rstn信号是来自与rkv_ahbram的interface的。
 
module rkv_ahbram_tb;
  import uvm_pkg::*;
  `include "uvm_macros.svh"
  import rkv_ahbram_pkg::*;

	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)
  );

    // clk from tb rstn from ahbram_if
	lvc_ahb_if ahb_if();
	assign ahb_if.hclk = clk;
	assign ahb_if.hresetn = rstn;
	assign ahb_if.hgrant = 1'b1; // select


	rkv_ahbram_if ahbram_if();
	assign ahbram_if.clk = clk;
	assign rstn           = ahbram_if.rstn;



  initial begin
    run_test();
  end  
endmodule
  • rstn的信号在rkv_ahbram_if中完善:
`ifndef RKV_AHBRAM_IF_SV
`define RKV_AHBRAM_IF_SV
 
interface rkv_ahbram_if;

  logic clk;
  logic rstn;
	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
endinterface
`endif

interface连接好之后,需要制作dut的sequence,首先制作好transaction,因为他就是seq在发的,驱动到dut上的内容。AHB总线协议有很多规定的内容,例如trans_type代表其状态,00代表空闲、01代表在忙、10 NSEQ代表在传数据的第一个数据,SEQ代表在传数据的其余拍等等。所以需要对其的值提前按照协议定义好,在第一节中已经提到过lvc的架构需要lvc_ahb_types,存放的就是与AHB协议相关的定义:

`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 

  • 定义好AHB相关的协议之后,完善transaction
`ifndef LVC_AHB_TRANSACTION_SV
`define LVC_AHB_TRANSACTION_SV
class lvc_ahb_transaction extends uvm_sequence_item;

	// wdata or rdata from bus 32bit
	rand bit [`LVC_AHB_MAX_DATA_WIDTH-1:0] data[];
	rand bit [`LVC_AHB_MAX_ADDR_WIDTH-1:0] addr = 0;

    rand xact_type_enum xact_type = IDLE_XACT;

	// represents the burst size of a transaction
	rand burst_size_enum burst_size = BURST_SIZE_8BIT; // one data width

	// transaction type
	rand burst_type_enum burst_type = SINGLE; // ccm

	// response from 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_field_array_int(data, UVM_ALL_ON)
     	`uvm_field_int(addr, UVM_ALL_ON)
     	`uvm_field_enum(burst_size_enum, burst_size, UVM_ALL_ON)
     	`uvm_field_enum(burst_type_enum, burst_type, UVM_ALL_ON)
     	`uvm_field_enum(xact_type_enum, xact_type, UVM_ALL_ON)
     	`uvm_field_enum(response_type_enum, response_type, UVM_ALL_ON)
     	`uvm_field_enum(trans_type_enum, trans_type, UVM_ALL_ON)
     	`uvm_field_array_enum(response_type_enum, all_beat_response, UVM_ALL_ON)
     	`uvm_field_int(current_data_beat_num, UVM_ALL_ON)
     	`uvm_field_enum(status_enum, status, UVM_ALL_ON)
 	`uvm_object_utils_end
	

	function new(string name = "lvc_ahb_transaction");
		super.new(name);
	endfunction

endclass

`endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值