core-v-verif系列之lib<18>

UVM环境介绍
HEAD commitID: 1f968ef

1. core-v-verif/lib/uvm_agents/uvma_axi/src/uvma_axi_ar_assert.sv

// Copyright 2022 Thales DIS SAS
//
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
// You may obtain a copy of the License at https://solderpad.org/licenses/
//
// Original Author: Alae Eddine EZ ZEJJARI (alae-eddine.ez-zejjari@external.thalesgroup.com)
// Co-Author: Abdelaali Khardazi

// *************************** READ ADDRESS CHANNEL ************************** //

module  uvma_axi_ar_assert (uvma_axi_intf.passive axi_assert, input bit clk, input rst_n);

   import uvm_pkg::*;


// *************************** Check if control information Signals are not equal to X or Z when ARVALID is HIGH (Section A3.2.2) ************************** //

   property AXI4_ARID_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!$isunknown(axi_assert.psv_axi_cb.ar_id));
   endproperty

   property AXI4_ARADDR_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!$isunknown(axi_assert.psv_axi_cb.ar_addr));
   endproperty

   property AXI4_ARLEN_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!$isunknown(axi_assert.psv_axi_cb.ar_len));
   endproperty

   property AXI4_ARSIZE_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!$isunknown(axi_assert.psv_axi_cb.ar_size));
   endproperty

   property AXI4_ARBURST_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!$isunknown(axi_assert.psv_axi_cb.ar_burst));
   endproperty

   property AXI4_ARLOCK_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!$isunknown(axi_assert.psv_axi_cb.ar_lock));
   endproperty

   property AXI4_ARCACHE_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!$isunknown(axi_assert.psv_axi_cb.ar_cache));
   endproperty

   property AXI4_ARPROT_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!$isunknown(axi_assert.psv_axi_cb.ar_prot));
   endproperty

   property AXI4_ARUSER_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!$isunknown(axi_assert.psv_axi_cb.ar_user));
   endproperty

   property AXI4_ARQOS_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!$isunknown(axi_assert.psv_axi_cb.ar_qos));
   endproperty

   property AXI4_ARREGION_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!$isunknown(axi_assert.psv_axi_cb.ar_region));
   endproperty

   // A value of X on ARVALID is not permitted when not in reset (Section A3.1.2)
   property AXI4_ARVALID_X;
      @(posedge clk) disable iff (!rst_n) (!$isunknown(axi_assert.psv_axi_cb.ar_valid));
   endproperty

   // A value of X on ARREADY is not permitted when not in reset (Section A3.1.2)
   property AXI4_ARREADY_X;
      @(posedge clk) disable iff (!rst_n) (!$isunknown(axi_assert.psv_axi_cb.ar_ready));
   endproperty

// *************************** Check if control information Signals are stable when ARVALID is HIGH (Section A3.2.1) ************************** //

   property AXI4_ARID_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!axi_assert.psv_axi_cb.ar_ready |=> ($stable(axi_assert.psv_axi_cb.ar_id)));
   endproperty

   property AXI4_ARADDR_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!axi_assert.psv_axi_cb.ar_ready |=> ($stable(axi_assert.psv_axi_cb.ar_addr)));
   endproperty

   property AXI4_ARLEN_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!axi_assert.psv_axi_cb.ar_ready |=> ($stable(axi_assert.psv_axi_cb.ar_len)));
   endproperty

   property AXI4_ARSIZE_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!axi_assert.psv_axi_cb.ar_ready |=> ($stable(axi_assert.psv_axi_cb.ar_size)));
   endproperty

   property AXI4_ARBURST_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!axi_assert.psv_axi_cb.ar_ready |=> ($stable(axi_assert.psv_axi_cb.ar_burst)));
   endproperty

   property AXI4_ARLOCK_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!axi_assert.psv_axi_cb.ar_ready |=> ($stable(axi_assert.psv_axi_cb.ar_lock)));
   endproperty

   property AXI4_ARCACHE_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!axi_assert.psv_axi_cb.ar_ready |=> ($stable(axi_assert.psv_axi_cb.ar_cache)));
   endproperty

   property AXI4_ARPROT_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!axi_assert.psv_axi_cb.ar_ready |=> ($stable(axi_assert.psv_axi_cb.ar_prot)));
   endproperty

   property AXI4_ARUSER_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!axi_assert.psv_axi_cb.ar_ready |=> ($stable(axi_assert.psv_axi_cb.ar_user)));
   endproperty

   property AXI4_ARQOS_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!axi_assert.psv_axi_cb.ar_ready |=> ($stable(axi_assert.psv_axi_cb.ar_qos)));
   endproperty

   property AXI4_ARREGION_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!axi_assert.psv_axi_cb.ar_ready |=> ($stable(axi_assert.psv_axi_cb.ar_region)));
   endproperty

   // Check if, Once asserted, ar_valid must remain asserted until ar_ready is HIGH (Section A3.2.1)
   property AXI4_AR_VALID_READY ;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (axi_assert.psv_axi_cb.ar_valid throughout (axi_assert.psv_axi_cb.ar_ready [->1]));
   endproperty

   // check if a read transaction with burst type WRAP has an aligned address (Section A3.4.1)
   property AXI_ARADDR_WRAP_ALIGN;
      @(posedge clk) disable iff (!rst_n) (axi_assert.psv_axi_cb.ar_valid && axi_assert.psv_axi_cb.ar_burst == 2'b10) |-> !((axi_assert.psv_axi_cb.ar_addr) % (2**axi_assert.psv_axi_cb.ar_size));
   endproperty

   // check if The size of a read transfer does not exceed the width of the data interface (Section A3.4.1)
   property AXI_ERRM_ARSIZE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid  |-> (8*(2**axi_assert.psv_axi_cb.ar_size) <= `UVMA_AXI_DATA_MAX_WIDTH);
   endproperty

   // check if burst crosses 4KB boundaries (Section A3.4.1)
   property AXI4_ERRM_ARADDR_BOUNDARY;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (((axi_assert.psv_axi_cb.ar_addr + (axi_assert.psv_axi_cb.ar_len + 1)*(2**axi_assert.psv_axi_cb.ar_size)) % 4096) > (axi_assert.psv_axi_cb.ar_addr % 4096)) || !((axi_assert.psv_axi_cb.ar_addr+(axi_assert.psv_axi_cb.ar_len + 1) * (2**axi_assert.psv_axi_cb.ar_size)) % 4096) ;
   endproperty

   // Check if the burst length equal to 2, 4, 8, or 16, for wrapping bursts (Section A3.4.1)
   property AXI_ARLEN_WRAPP_BURST;
      @(posedge clk) disable iff (!rst_n) (axi_assert.psv_axi_cb.ar_valid && axi_assert.psv_axi_cb.ar_burst == 2'b10) |-> (axi_assert.psv_axi_cb.ar_len == 1) || (axi_assert.psv_axi_cb.ar_len == 3) || (axi_assert.psv_axi_cb.ar_len == 7) || (axi_assert.psv_axi_cb.ar_len == 15);
   endproperty

   // Check if ar_burst can’t be 2’b11 (Table A3-3)
   property AXI4_AR_BURST_CANT_2b11;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (axi_assert.psv_axi_cb.ar_burst != 2'b11);
   endproperty

   // Check if ARVALID is LOW for the first cycle after ARESETn goes HIGH (Figure A3-1)
   property AXI4_ARVALID_RESET;
      @(posedge clk) $rose(rst_n) |=> !(axi_assert.psv_axi_cb.ar_valid);
   endproperty

   // Check if the length of an exclusive access transaction don't  pass 16 beats (Section A7.2.4)
   property AXI4_ARLEN_LOCK;
      @(posedge clk)  disable iff (!rst_n) axi_assert.psv_axi_cb.ar_lock |-> (signed' (axi_assert.psv_axi_cb.ar_len)) <= 16;
   endproperty

   // Check if ARCACHE[3:2] are  LOW, When ARVALID is HIGH and ARCACHE[1] is LOW (Table A4-5)
   property AXI4_ARCACHE_LOW;
      @(posedge clk)  disable iff (!rst_n) (axi_assert.psv_axi_cb.ar_valid) && !(axi_assert.psv_axi_cb.ar_cache[1]) |-> !(axi_assert.psv_axi_cb.ar_cache[3:2]);
   endproperty

   // Check if a transactions of burst type FIXED don't have a length greater than 16 beats (Section A3.4.1)
   property AXI4_ARLEN_FIXED;
      @(posedge clk)  disable iff (!rst_n) (axi_assert.psv_axi_cb.ar_burst == 2'b00) |-> (axi_assert.psv_axi_cb.ar_len <= 15);
   endproperty

/********************************************** Assert Property ******************************************************/

   ar_valid_ready            : assert property (AXI4_AR_VALID_READY)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AR_VALID_READY");

   arlen_wrapp_burst         : assert property (AXI_ARLEN_WRAPP_BURST)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI_ARLEN_WRAPP_BURST");

   araddr_wrap_align         : assert property (AXI_ARADDR_WRAP_ALIGN)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI_ARADDR_WRAP_ALIGN");

   assert_arsize             : assert property (AXI_ERRM_ARSIZE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI_ERRM_ARSIZE");

   ar_burst_cant_2b11        : assert property (AXI4_AR_BURST_CANT_2b11)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AR_BURST_CANT_2b11");

   araddr_boundary           : assert property (AXI4_ERRM_ARADDR_BOUNDARY)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ERRM_ARADDR_BOUNDARY");

   arvalid_reset             : assert property (AXI4_ARVALID_RESET)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARVALID_RESET");

   arlen_lock                : assert property (AXI4_ARLEN_LOCK)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARLEN_LOCK");

   arcahce_low               : assert property (AXI4_ARCACHE_LOW)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARCACHE_LOW");

   arlen_fixed               : assert property (AXI4_ARLEN_FIXED)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARLEN_FIXED");

   arid_x                    : assert property (AXI4_ARID_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARID_X");

   araddr_x                  : assert property (AXI4_ARADDR_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARADDR_X");

   arlen_x                   : assert property (AXI4_ARLEN_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARLEN_X");

   arsize_x                  : assert property (AXI4_ARSIZE_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARSIZE_X");

   arburst_x                 : assert property (AXI4_ARBURST_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARBURST_X");

   arlock_x                  : assert property (AXI4_ARLOCK_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARLOCK_X");

   arcache_x                 : assert property (AXI4_ARCACHE_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARCACHE_X");

   arprot_x                  : assert property (AXI4_ARPROT_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARPROT_X");

   arqos_x                   : assert property (AXI4_ARQOS_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARQOS_X");

   arregion_x                : assert property (AXI4_ARREGION_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARREGION_X");

   arvalid_x                 : assert property (AXI4_ARVALID_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARVALID_X");

   arready_x                 : assert property (AXI4_ARREADY_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARREADY_X");

   arid_stable               : assert property (AXI4_ARID_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARID_STABLE");

   araddr_stable             : assert property (AXI4_ARADDR_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARADDR_STABLE");

   arlen_stable              : assert property (AXI4_ARLEN_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARLEN_STABLE");

   arsize_stable             : assert property (AXI4_ARSIZE_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARSIZE_STABLE");

   arburst_stable            : assert property (AXI4_ARBURST_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARBURST_STABLE");

   arlock_stable             : assert property (AXI4_ARLOCK_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARLOCK_STABLE");

   arcache_stable            : assert property (AXI4_ARCACHE_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARCACHE_STABLE");

   arprot_stable             : assert property (AXI4_ARPROT_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARPROT_STABLE");

   aruser_stable             : assert property (AXI4_ARUSER_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARUSER_STABLE");

   arqos_stable              : assert property (AXI4_ARQOS_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARQOS_STABLE");

   arregion_stable           : assert property (AXI4_ARREGION_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ARREGION_STABLE");

/********************************************** Cover Property ******************************************************/

   cov_ar_valid_ar_ready       : cover property(AXI4_AR_VALID_READY);

   cov_araddr_wrap_align       : cover property(AXI_ARADDR_WRAP_ALIGN);

   cov_arlen_wrapp_burst       : cover property(AXI_ARLEN_WRAPP_BURST);

   cov_arsize                  : cover property(AXI_ERRM_ARSIZE);

   cov_arvalid_reset           : cover property(AXI4_ARVALID_RESET);

   cov_ar_burst_cant_2b11      : cover property(AXI4_AR_BURST_CANT_2b11);

   cov_errm_ARaddr_boundary    : cover property(AXI4_ERRM_ARADDR_BOUNDARY);

   cov_arlen_lock              : cover property(AXI4_ARLEN_LOCK);

   cov_arcache_low             : cover property(AXI4_ARCACHE_LOW);

   cov_arlen_fixed             : cover property(AXI4_ARLEN_FIXED);

   cov_arid_stable             : cover property(AXI4_ARID_STABLE);

   cov_araddr_stable           : cover property(AXI4_ARADDR_STABLE);

   cov_arlen_stable            : cover property(AXI4_ARLEN_STABLE);

   cov_arsize_stable           : cover property(AXI4_ARSIZE_STABLE);

   cov_arburst_stable          : cover property(AXI4_ARBURST_STABLE);

   cov_arlock_stable           : cover property(AXI4_ARLOCK_STABLE);

   cov_arcache_stable          : cover property(AXI4_ARCACHE_STABLE);

   cov_arprot_stable           : cover property(AXI4_ARPROT_STABLE);

   cov_aruser_stable           : cover property(AXI4_ARUSER_STABLE);

   cov_arqos_stable            : cover property(AXI4_ARQOS_STABLE);

   cov_arregion_stable         : cover property(AXI4_ARREGION_STABLE);


endmodule : uvma_axi_ar_assert

1. 简要介绍

uvma_axi_ar_assert.sv 文件定义了一个名为 uvma_axi_ar_assert 的模块,该模块主要用于对 AXI4 协议读地址通道(AR 通道)的各种规则进行属性检查和断言验证。通过一系列的 SystemVerilog 属性(SVA),对 AR 通道信号的合法性、稳定性等规则进行检查,当违反规则时使用 UVM 宏输出错误信息,同时还设置了一些覆盖属性用于覆盖率统计。

2. 接口介绍

module  uvma_axi_ar_assert (uvma_axi_intf.passive axi_assert, input bit clk, input rst_n);

代码分析

  • module uvma_axi_ar_assert:定义一个名为 uvma_axi_ar_assert 的模块。
  • uvma_axi_intf.passive axi_assert:一个被动接口类型的端口,uvma_axi_intf 应该是自定义的接口类型,passive 表示该接口以被动模式使用,用于接收 AXI 接口的信号。
  • input bit clk:输入端口,数据类型为 bit,用于提供时钟信号,属性检查在时钟的上升沿触发。
  • input rst_n:输入端口,数据类型为 bit,表示异步复位信号,低电平有效,用于在复位期间禁用属性检查。

3. 参数介绍

此模块中无显式的 parameterlocalparam 定义的参数。

4. 模块实现介绍

4.1 包导入
import uvm_pkg::*;

代码分析:导入 UVM 包中的所有内容,以便后续使用 UVM 的宏(如 uvm_error)进行错误信息输出。

4.2 属性定义

AXI4_ARID_X 属性为例:

property AXI4_ARID_X;
    @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.ar_valid |-> (!$isunknown(axi_assert.psv_axi_cb.ar_id));
endproperty

代码分析

  • property AXI4_ARID_X;:定义一个名为 AXI4_ARID_X 的属性。
  • @(posedge clk):指定属性检查在时钟 clk 的上升沿触发。
  • disable iff (!rst_n):当复位信号 rst_n 为低电平时,禁用该属性检查。
  • axi_assert.psv_axi_cb.ar_valid |-> (!$isunknown(axi_assert.psv_axi_cb.ar_id)):当 ar_valid 信号为高电平时,断言 ar_id 信号的值不为 XZ|-> 是蕴含操作符,表示前提条件成立时,后续条件也必须成立。

类似地,模块中定义了多个属性,分别检查 AR 通道不同信号的合法性、稳定性等规则。

4.3 断言语句

ar_valid_ready 断言为例:

ar_valid_ready : assert property (AXI4_AR_VALID_READY)
                     else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AR_VALID_READY");

代码分析

  • ar_valid_ready:断言的名称。
  • assert property (AXI4_AR_VALID_READY):对 AXI4_AR_VALID_READY 属性进行断言检查。
  • else uvm_error (" AXI4 protocol checks assertion ", “Violation of AXI4_AR_VALID_READY”);:如果属性检查失败,使用 UVM 的 uvm_error宏输出错误信息,提示违反了AXI4_AR_VALID_READY` 属性。
4.4 覆盖属性

cov_ar_valid_ar_ready 覆盖属性为例:

cov_ar_valid_ar_ready : cover property(AXI4_AR_VALID_READY);

代码分析

  • cov_ar_valid_ar_ready:覆盖属性的名称。
  • cover property(AXI4_AR_VALID_READY):对 AXI4_AR_VALID_READY 属性进行覆盖率统计,当该属性被触发时,覆盖率工具会记录相应的覆盖点。

5. 总结

uvma_axi_ar_assert.sv 模块通过 SystemVerilog 属性验证和 UVM 宏的结合,对 AXI4 协议读地址通道的各种规则进行了全面的检查和验证。属性定义部分详细描述了各种协议规则,断言语句在规则违反时输出错误信息,帮助开发者快速定位问题。覆盖属性则用于统计验证的覆盖率,确保验证的完整性。该模块在 AXI4 协议的验证工作中起到了重要的作用,提高了验证的效率和准确性。

2. core-v-verif/lib/uvm_agents/uvma_axi/src/uvma_axi_aw_assert.sv

// Copyright 2022 Thales DIS SAS
//
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
// You may obtain a copy of the License at https://solderpad.org/licenses/
//
// Original Author: Alae Eddine EZ ZEJJARI (alae-eddine.ez-zejjari@external.thalesgroup.com)
// Co-Author: Abdelaali Khardazi

// ***************************WRITE ADDRESS CHANNEL ************************** //

module  uvma_axi_aw_assert (uvma_axi_intf.passive axi_assert, input bit clk, input rst_n);

   import uvm_pkg::*;

// *************************** Check if control information Signals are not equal to X or Z when WVALID is HIGH (Section A3.2.2) ************************** //

   property AXI4_AWID_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!$isunknown(axi_assert.psv_axi_cb.aw_id));
   endproperty

   property AXI4_AWADDR_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!$isunknown(axi_assert.psv_axi_cb.aw_addr));
   endproperty

   property AXI4_AWLEN_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!$isunknown(axi_assert.psv_axi_cb.aw_len));
   endproperty

   property AXI4_AWSIZE_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!$isunknown(axi_assert.psv_axi_cb.aw_size));
   endproperty

   property AXI4_AWBURST_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!$isunknown(axi_assert.psv_axi_cb.aw_burst));
   endproperty

   property AXI4_AWLOCK_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!$isunknown(axi_assert.psv_axi_cb.aw_lock));
   endproperty

   property AXI4_AWCACHE_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!$isunknown(axi_assert.psv_axi_cb.aw_cache));
   endproperty

   property AXI4_AWPROT_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!$isunknown(axi_assert.psv_axi_cb.aw_prot));
   endproperty

   property AXI4_AWUSER_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!$isunknown(axi_assert.psv_axi_cb.aw_user));
   endproperty

   property AXI4_AWQOS_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!$isunknown(axi_assert.psv_axi_cb.aw_qos));
   endproperty

   property AXI4_AWREGION_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!$isunknown(axi_assert.psv_axi_cb.aw_region));
   endproperty

   // A value of X on AWVALID is not permitted when not in reset (Section A3.1.2)
   property AXI4_AWVALID_X;
      @(posedge clk) disable iff (!rst_n) (!$isunknown(axi_assert.psv_axi_cb.aw_valid));
   endproperty

   // A value of X on AWREADY is not permitted when not in reset (Section A3.1.2)
   property AXI4_AWREADY_X;
      @(posedge clk) disable iff (!rst_n) (!$isunknown(axi_assert.psv_axi_cb.aw_ready));
   endproperty

// *************************** Check if control information Signals are stable when AWVALID is HIGH (Section A3.2.1) ************************** //

   property AXI4_AWID_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!axi_assert.psv_axi_cb.aw_ready |=> ($stable(axi_assert.psv_axi_cb.aw_id)));
   endproperty

   property AXI4_AWADDR_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!axi_assert.psv_axi_cb.aw_ready |=> ($stable(axi_assert.psv_axi_cb.aw_addr)));
   endproperty

   property AXI4_AWLEN_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!axi_assert.psv_axi_cb.aw_ready |=> ($stable(axi_assert.psv_axi_cb.aw_len)));
   endproperty

   property AXI4_AWSIZE_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!axi_assert.psv_axi_cb.aw_ready |=> ($stable(axi_assert.psv_axi_cb.aw_size)));
   endproperty

   property AXI4_AWBURST_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!axi_assert.psv_axi_cb.aw_ready |=> ($stable(axi_assert.psv_axi_cb.aw_burst)));
   endproperty

   property AXI4_AWLOCK_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!axi_assert.psv_axi_cb.aw_ready |=> ($stable(axi_assert.psv_axi_cb.aw_lock)));
   endproperty

   property AXI4_AWCACHE_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!axi_assert.psv_axi_cb.aw_ready |=> ($stable(axi_assert.psv_axi_cb.aw_cache)));
   endproperty

   property AXI4_AWPROT_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!axi_assert.psv_axi_cb.aw_ready |=> ($stable(axi_assert.psv_axi_cb.aw_prot)));
   endproperty

   property AXI4_AWUSER_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!axi_assert.psv_axi_cb.aw_ready |=> ($stable(axi_assert.psv_axi_cb.aw_user)));
   endproperty

   property AXI4_AWQOS_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!axi_assert.psv_axi_cb.aw_ready |=> ($stable(axi_assert.psv_axi_cb.aw_qos)));
   endproperty

   property AXI4_AWREGION_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!axi_assert.psv_axi_cb.aw_ready |=> ($stable(axi_assert.psv_axi_cb.aw_region)));
   endproperty

   // Check if, Once asserted, aw_valid must remain asserted until aw_ready is HIGH (Section A3.2.1)
   property AXI4_AW_VALID_READY;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> ( axi_assert.psv_axi_cb.aw_valid throughout (axi_assert.psv_axi_cb.aw_ready [->1]));
   endproperty

   // check if a write transaction with burst type WRAP has an aligned address (Section A3.4.1)
   property AXI_AWADDR_WRAP_ALIGN;
      @(posedge clk) disable iff (!rst_n) (axi_assert.psv_axi_cb.aw_valid && axi_assert.psv_axi_cb.aw_burst == 2'b10) |-> !((axi_assert.psv_axi_cb.aw_addr) % (2**axi_assert.psv_axi_cb.aw_size));
   endproperty

   // check if The size of a write transfer does not exceed the width of the data interface (Section A3.4.1)
   property AXI_ERRM_AWSIZE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid  |-> (8 * (2**axi_assert.psv_axi_cb.aw_size) <= `UVMA_AXI_DATA_MAX_WIDTH);
   endproperty

   // check if burst crosses 4KB boundaries (Section A3.4.1)
   property AXI4_ERRM_AWADDR_BOUNDARY;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (((axi_assert.psv_axi_cb.aw_addr + (axi_assert.psv_axi_cb.aw_len + 1) * (2**axi_assert.psv_axi_cb.aw_size)) % 4096) > (axi_assert.psv_axi_cb.aw_addr % 4096)) || !((axi_assert.psv_axi_cb.aw_addr + (axi_assert.psv_axi_cb.aw_len + 1) * (2**axi_assert.psv_axi_cb.aw_size)) % 4096);
   endproperty

   // Check if the burst length equal to 2, 4, 8, or 16, for wrapping bursts (Section A3.4.1)
   property AXI_AWLEN_WRAPP_BURST;
      @(posedge clk) disable iff (!rst_n) (axi_assert.psv_axi_cb.aw_valid && axi_assert.psv_axi_cb.aw_burst == 2'b10) |-> (axi_assert.psv_axi_cb.aw_len == 1) || (axi_assert.psv_axi_cb.aw_len == 3) || (axi_assert.psv_axi_cb.aw_len == 7) || (axi_assert.psv_axi_cb.aw_len == 15);
   endproperty

   // Check if aw_burst can’t be 2’b11 (Table A3-3)
   property AXI4_AW_BURST_CANT_2b11;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (axi_assert.psv_axi_cb.aw_burst != 2'b11);
   endproperty

   // Check if AWVALID is LOW for the first cycle after ARESETn goes HIGH (Figure A3-1)
   property AXI4_AWVALID_RESET;
      @(posedge clk) $rose(rst_n) |=> !(axi_assert.psv_axi_cb.aw_valid);
   endproperty

   // Check if the length of an exclusive access transaction don't  pass 16 beats (Section A7.2.4)
   property AXI4_AWLEN_LOCK;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_lock |-> (signed'(axi_assert.psv_axi_cb.aw_len)) <= 16;
   endproperty

   // Check if AWCACHE[3:2] are  LOW, When AWVALID is HIGH and AWCACHE[1] is LOW (Table A4-5)
   property AXI4_AWCACHE_LOW;
      @(posedge clk) disable iff (!rst_n) (axi_assert.psv_axi_cb.aw_valid) && !(axi_assert.psv_axi_cb.aw_cache[1]) |-> !(axi_assert.psv_axi_cb.aw_cache[3:2]);
   endproperty

   // Check if a transactions of burst type FIXED don't have a length greater than 16 beats (Section A3.4.1)
   property AXI4_AWLEN_FIXED;
      @(posedge clk) disable iff (!rst_n) (axi_assert.psv_axi_cb.aw_burst == 2'b00) |-> (axi_assert.psv_axi_cb.aw_len <= 15);
   endproperty

/********************************************** Assert Property ******************************************************/

   aw_valid_aw_ready         : assert property (AXI4_AW_VALID_READY)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AW_VALID_READY");

   awaddr_wrap_align         : assert property (AXI_AWADDR_WRAP_ALIGN)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI_AWADDR_WRAP_ALIGN");

   assert_awsize             : assert property (AXI_ERRM_AWSIZE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI_ERRM_AWSIZE");

   awlen_wrapp_burst         : assert property (AXI_AWLEN_WRAPP_BURST)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI_AWLEN_WRAPP_BURST");

   aw_burst_cant_2b11        : assert property (AXI4_AW_BURST_CANT_2b11)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AW_BURST_CANT_2b11");

   errm_awaddr_boundary      : assert property (AXI4_ERRM_AWADDR_BOUNDARY)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_ERRM_AWADDR_BOUNDARY");

   awvalid_reset             : assert property (AXI4_AWVALID_RESET)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWVALID_RESET");

   awlen_lock                : assert property (AXI4_AWLEN_LOCK)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWLEN_LOCK");

   awcahce_low               : assert property (AXI4_AWCACHE_LOW)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWCACHE_LOW");

   awlen_fixed               : assert property (AXI4_AWLEN_FIXED)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWLEN_FIXED");

   awid_x                    : assert property (AXI4_AWID_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWID_X");

   awaddr_x                  : assert property (AXI4_AWADDR_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWADDR_X");

   awlen_x                   : assert property (AXI4_AWLEN_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWLEN_X");

   awsize_x                  : assert property (AXI4_AWSIZE_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWSIZE_X");

   awburst_x                 : assert property (AXI4_AWBURST_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWBURST_X");

   awlock_x                  : assert property (AXI4_AWLOCK_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWLOCK_X");

   awcache_x                 : assert property (AXI4_AWCACHE_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWCACHE_X");

   awprot_x                  : assert property (AXI4_AWPROT_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWPROT_X");

   awuser_x                  : assert property (AXI4_AWUSER_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWUSER_X");

   awqos_x                   : assert property (AXI4_AWQOS_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWQOS_X");

   awregion_x                : assert property (AXI4_AWREGION_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWREGION_X");

   awvalid_x                 : assert property (AXI4_AWVALID_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWVALID_X");

   awready_x                 : assert property (AXI4_AWREADY_X)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWREADY_X");

   awid_stable               : assert property (AXI4_AWID_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWID_STABLE");

   awaddr_stable             : assert property (AXI4_AWADDR_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWADDR_STABLE");

   awlen_stable              : assert property (AXI4_AWLEN_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWLEN_STABLE");

   awsize_stable             : assert property (AXI4_AWSIZE_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWSIZE_STABLE");

   awburst_stable            : assert property (AXI4_AWBURST_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWBURST_STABLE");

   awlock_stable             : assert property (AXI4_AWLOCK_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWLOCK_STABLE");

   awcache_stable            : assert property (AXI4_AWCACHE_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWCACHE_STABLE");

   awprot_stable             : assert property (AXI4_AWPROT_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWPROT_STABLE");

   awuser_stable             : assert property (AXI4_AWUSER_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWUSER_STABLE");

   awqos_stable              : assert property (AXI4_AWQOS_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWQOS_STABLE");

   awregion_stable           : assert property (AXI4_AWREGION_STABLE)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AWREGION_STABLE");

/********************************************** Cover Property ******************************************************/

   cov_aw_valid_aw_ready       : cover property(AXI4_AW_VALID_READY);

   cov_awaddr_wrap_align       : cover property(AXI_AWADDR_WRAP_ALIGN);

   cov_awsize                  : cover property(AXI_ERRM_AWSIZE);

   cov_awvalid_reset           : cover property(AXI4_AWVALID_RESET);

   cov_awlen_wrapp_burst       : cover property(AXI_AWLEN_WRAPP_BURST);

   cov_aw_burst_cant_2b11      : cover property(AXI4_AW_BURST_CANT_2b11);

   cov_errm_awaddr_boundary    : cover property(AXI4_ERRM_AWADDR_BOUNDARY);

   cov_awlen_lock              : cover property(AXI4_AWLEN_LOCK);

   cov_awcache_low             : cover property(AXI4_AWCACHE_LOW);

   cov_awlen_fixed             : cover property(AXI4_AWLEN_FIXED);

   cov_awid_stable             : cover property(AXI4_AWID_STABLE);

   cov_awaddr_stable           : cover property(AXI4_AWADDR_STABLE);

   cov_awlen_stable            : cover property(AXI4_AWLEN_STABLE);

   cov_awsize_stable           : cover property(AXI4_AWSIZE_STABLE);

   cov_awburst_stable          : cover property(AXI4_AWBURST_STABLE);

   cov_awlock_stable           : cover property(AXI4_AWLOCK_STABLE);

   cov_awcache_stable          : cover property(AXI4_AWCACHE_STABLE);

   cov_awprot_stable           : cover property(AXI4_AWPROT_STABLE);

   cov_awuser_stable           : cover property(AXI4_AWUSER_STABLE);

   cov_awqos_stable            : cover property(AXI4_AWQOS_STABLE);

   cov_awregion_stable         : cover property(AXI4_AWREGION_STABLE);


endmodule : uvma_axi_aw_assert

1. 简要介绍

uvma_axi_aw_assert.sv 文件定义了一个名为 uvma_axi_aw_assert 的模块,该模块用于对 AXI4 协议写地址通道(AW 通道)的信号进行协议规则检查。借助 SystemVerilog 属性(SVA)定义各种检查规则,通过断言语句在规则被违反时输出错误信息,同时使用覆盖属性进行覆盖率统计,以确保 AXI4 协议在写地址通道上的正确实现。

2. 接口介绍

module  uvma_axi_aw_assert (uvma_axi_intf.passive axi_assert, input bit clk, input rst_n);

代码分析

  • module uvma_axi_aw_assert:声明模块名为 uvma_axi_aw_assert
  • uvma_axi_intf.passive axi_assert:一个被动接口类型的端口,uvma_axi_intf 应该是自定义的接口类型,passive 表明该接口以被动模式工作,用于接收 AXI 接口的信号,以便对写地址通道信号进行监控和检查。
  • input bit clk:输入端口,数据类型为 bit,提供时钟信号。所有的属性检查都在时钟的上升沿触发,确保时序一致性。
  • input rst_n:输入端口,数据类型为 bit,表示异步复位信号,低电平有效。在复位期间,大部分属性检查会被禁用。

3. 参数介绍

此模块中没有显式使用 parameterlocalparam 定义的参数。

4. 模块实现介绍

4.1 包导入
import uvm_pkg::*;

代码分析:导入 UVM(通用验证方法学)包中的所有内容,目的是后续可以使用 UVM 提供的宏,如 uvm_error 来输出错误信息,方便在验证环境中进行错误报告。

4.2 属性定义

AXI4_AWID_X 属性为例:

property AXI4_AWID_X;
    @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.aw_valid |-> (!$isunknown(axi_assert.psv_axi_cb.aw_id));
endproperty

代码分析

  • property AXI4_AWID_X;:定义一个名为 AXI4_AWID_X 的属性,用于检查写地址通道的 aw_id 信号。
  • @(posedge clk):指定属性检查在时钟 clk 的上升沿触发。
  • disable iff (!rst_n):当复位信号 rst_n 为低电平时,禁用该属性检查,即复位期间不进行检查。
  • axi_assert.psv_axi_cb.aw_valid |-> (!$isunknown(axi_assert.psv_axi_cb.aw_id)):当 aw_valid 信号为高电平时,通过蕴含操作符 |-> 断言 aw_id 信号的值不为 XZ

模块中定义了一系列类似的属性,分别对写地址通道的不同信号进行合法性、稳定性等方面的检查。

4.3 断言语句

aw_valid_aw_ready 断言为例:

aw_valid_aw_ready         : assert property (AXI4_AW_VALID_READY)
                         else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_AW_VALID_READY");

代码分析

  • aw_valid_aw_ready:断言的名称,用于标识该断言。
  • assert property (AXI4_AW_VALID_READY):对 AXI4_AW_VALID_READY 属性进行断言检查。
  • else uvm_error (" AXI4 protocol checks assertion ", “Violation of AXI4_AW_VALID_READY”);:如果属性检查失败,使用 UVM 的 uvm_error宏输出错误信息,告知违反了AXI4_AW_VALID_READY` 属性。
4.4 覆盖属性

cov_aw_valid_aw_ready 覆盖属性为例:

cov_aw_valid_aw_ready       : cover property(AXI4_AW_VALID_READY);

代码分析

  • cov_aw_valid_aw_ready:覆盖属性的名称。
  • cover property(AXI4_AW_VALID_READY):对 AXI4_AW_VALID_READY 属性进行覆盖率统计。当该属性的条件被满足时,覆盖率工具会记录相应的覆盖点,帮助验证人员评估验证的完备性。

5. 总结

uvma_axi_aw_assert.sv 模块在 AXI4 协议的验证工作中起着关键作用。它通过定义多种 SystemVerilog 属性,全面检查写地址通道的信号是否符合 AXI4 协议规范。断言语句在协议规则被违反时及时输出错误信息,便于开发人员快速定位问题。覆盖属性则为验证人员提供了覆盖率数据,确保验证的完整性。整体而言,该模块提高了 AXI4 协议验证的效率和准确性,有助于保证设计的正确性。

3. core-v-verif/lib/uvm_agents/uvma_axi/src/uvma_axi_b_assert.sv

// Copyright 2022 Thales DIS SAS
//
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
// You may obtain a copy of the License at https://solderpad.org/licenses/
//
// Original Author: Alae Eddine EZ ZEJJARI (alae-eddine.ez-zejjari@external.thalesgroup.com)
// Co-Author: Abdelaali Khardazi

// *************************** Write response CHANNEL ************************** //

module  uvma_axi_b_assert (uvma_axi_intf.passive axi_assert, input bit clk, input rst_n);

   import uvm_pkg::*;

// *************************** Check if Write Response Signals are not equal to X or Z when WVALID is HIGH (Section A3.2.2) ************************** //

   property AXI4_BID_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.b_valid |-> (!$isunknown(axi_assert.psv_axi_cb.b_id));
   endproperty

   property AXI4_BRESP_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.b_valid |-> (!$isunknown(axi_assert.psv_axi_cb.b_resp));
   endproperty

   property AXI4_BUSER_X;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.b_valid |-> (!$isunknown(axi_assert.psv_axi_cb.b_user));
   endproperty

   // A value of X on BVALID is not permitted when not in reset (Section A3.2.2)
   property AXI4_BVALID_X;
      @(posedge clk) disable iff (!rst_n) (!$isunknown(axi_assert.psv_axi_cb.b_valid));
   endproperty

   // A value of X on BVALID is not permitted when not in reset (Section A3.1.2)
   property AXI4_BREADY_X;
      @(posedge clk) disable iff (!rst_n) (!$isunknown(axi_assert.psv_axi_cb.b_ready));
   endproperty

// *************************** Check if Write Response Signals are stable when AWVALID is HIGH (Section A3.2.1) ************************** //

   property AXI4_BID_STABLE ;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.b_valid |-> (!axi_assert.psv_axi_cb.b_ready |=> ($stable(axi_assert.psv_axi_cb.b_id)));
   endproperty

   property AXI4_BRESP_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.b_valid |-> (!axi_assert.psv_axi_cb.b_ready |=> ($stable(axi_assert.psv_axi_cb.b_resp)));
   endproperty

   property AXI4_BUSER_STABLE;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.b_valid |-> (!axi_assert.psv_axi_cb.b_ready |=> ($stable(axi_assert.psv_axi_cb.b_user)));
   endproperty

   // Check if, Once asserted, r_valid must remain asserted until r_ready is HIGH (Section A3.2.2)
   property AXI4_BVALID_STABLE ;
      @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.b_valid |-> ( axi_assert.psv_axi_cb.b_valid throughout (axi_assert.psv_axi_cb.b_ready [->1]));
   endproperty

   // Check if RVALID is LOW for the first cycle after ARESETn goes HIGH (Figure A3-1)
   property AXI4_BVALID_RESET;
      @(posedge clk) $rose(rst_n) |=> !(axi_assert.psv_axi_cb.b_valid);
   endproperty

/********************************************** Assert Property ******************************************************/

   rvalid_reset          : assert property (AXI4_BVALID_RESET)
                         else `uvm_error (" AXI4 protocol ckecks assertion ", "Violation of AXI4_BVALID_RESET");

   bid_x                 : assert property (AXI4_BID_X)
                         else `uvm_error (" AXI4 protocol ckecks assertion ", "Violation of AXI4_BID_X");

   bresp_x               : assert property (AXI4_BRESP_X)
                         else `uvm_error (" AXI4 protocol ckecks assertion ", "Violation of AXI4_BRESP_X");

   buser_x               : assert property (AXI4_BUSER_X)
                         else `uvm_error (" AXI4 protocol ckecks assertion ", "Violation of AXI4_BUSER_X");

   bvalid_x              : assert property (AXI4_BVALID_X)
                         else `uvm_error (" AXI4 protocol ckecks assertion ", "Violation of AXI4_BVALID_X");

   bready_x              : assert property (AXI4_BREADY_X)
                         else `uvm_error (" AXI4 protocol ckecks assertion ", "Violation of AXI4_BREADY_X");

   bvalid_stable         : assert property (AXI4_BVALID_STABLE)
                         else `uvm_error (" AXI4 protocol ckecks assertion ", "Violation of AXI4_BVALID_STABLE");

   bid_stable            : assert property (AXI4_BID_STABLE)
                         else `uvm_error (" AXI4 protocol ckecks assertion ", "Violation of AXI4_BID_STABLE");

   bresp_stable          : assert property (AXI4_BRESP_STABLE)
                         else `uvm_error (" AXI4 protocol ckecks assertion ", "Violation of AXI4_BRESP_STABLE");

   buser_stable          : assert property (AXI4_BUSER_STABLE)
                         else `uvm_error (" AXI4 protocol ckecks assertion ", "Violation of AXI4_BUSER_STABLE");

/********************************************** Cover Property ******************************************************/

   cov_bvalid_reset           : cover property(AXI4_BVALID_RESET);

   cov_bvalid_stable          : cover property(AXI4_BVALID_STABLE);

   cov_bid_stable             : cover property(AXI4_BID_STABLE);

   cov_bresp_stable           : cover property(AXI4_BRESP_STABLE);

   cov_buser_stable           : cover property(AXI4_BUSER_STABLE);

endmodule : uvma_axi_b_assert

1. 简要介绍

uvma_axi_b_assert.sv 文件定义了一个名为 uvma_axi_b_assert 的模块,其主要功能是对 AXI4 协议中写响应通道(B 通道)的信号进行验证。该模块利用 SystemVerilog 属性(SVA)定义了一系列规则,用于检查信号的合法性、稳定性等,同时通过断言语句在规则被违反时输出错误信息,还使用覆盖属性来统计验证的覆盖率。

2. 接口介绍

module  uvma_axi_b_assert (uvma_axi_intf.passive axi_assert, input bit clk, input rst_n);

代码分析

  • module uvma_axi_b_assert:声明模块名为 uvma_axi_b_assert
  • uvma_axi_intf.passive axi_assert:这是一个被动接口类型的端口,uvma_axi_intf 应是自定义的接口类型,passive 表明该接口以被动模式工作,用于接收 AXI 接口的信号,以便对写响应通道的信号进行监控和验证。
  • input bit clk:输入端口,数据类型为 bit,提供时钟信号。所有的属性检查都在时钟的上升沿触发,保证时序同步。
  • input rst_n:输入端口,数据类型为 bit,表示异步复位信号,低电平有效。在复位期间,属性检查会被禁用。

3. 参数介绍

该模块中未显式定义 parameterlocalparam 类型的参数。

4. 模块实现介绍

4.1 包导入
import uvm_pkg::*;

代码分析:导入 UVM(通用验证方法学)包中的所有内容,目的是后续可以使用 UVM 提供的宏,如 uvm_error 来输出错误信息,方便在验证环境中进行错误报告。

4.2 属性定义

AXI4_BID_X 属性为例:

property AXI4_BID_X;
    @(posedge clk) disable iff (!rst_n) axi_assert.psv_axi_cb.b_valid |-> (!$isunknown(axi_assert.psv_axi_cb.b_id));
endproperty

代码分析

  • property AXI4_BID_X;:定义一个名为 AXI4_BID_X 的属性,用于检查写响应通道的 b_id 信号。
  • @(posedge clk):指定属性检查在时钟 clk 的上升沿触发。
  • disable iff (!rst_n):当复位信号 rst_n 为低电平时,禁用该属性检查,即复位期间不进行检查。
  • axi_assert.psv_axi_cb.b_valid |-> (!$isunknown(axi_assert.psv_axi_cb.b_id)):当 b_valid 信号为高电平时,通过蕴含操作符 |-> 断言 b_id 信号的值不为 XZ

模块中定义了多个类似属性,分别对写响应通道的不同信号(如 b_respb_userb_validb_ready 等)进行合法性和稳定性检查。

4.3 断言语句

bid_x 断言为例:

bid_x                 : assert property (AXI4_BID_X)
                      else `uvm_error (" AXI4 protocol ckecks assertion ", "Violation of AXI4_BID_X");

代码分析

  • bid_x:断言的名称,用于标识该断言。
  • assert property (AXI4_BID_X):对 AXI4_BID_X 属性进行断言检查。
  • else uvm_error (" AXI4 protocol ckecks assertion ", “Violation of AXI4_BID_X”);:如果属性检查失败,使用 UVM 的 uvm_error宏输出错误信息,提示违反了AXI4_BID_X` 属性。
4.4 覆盖属性

cov_bvalid_reset 覆盖属性为例:

cov_bvalid_reset           : cover property(AXI4_BVALID_RESET);

代码分析

  • cov_bvalid_reset:覆盖属性的名称。
  • cover property(AXI4_BVALID_RESET):对 AXI4_BVALID_RESET 属性进行覆盖率统计。当该属性的条件被满足时,覆盖率工具会记录相应的覆盖点,帮助验证人员评估验证的完整性。

5. 总结

uvma_axi_b_assert.sv 模块是 AXI4 协议验证中重要的一部分,专注于写响应通道的信号验证。通过定义丰富的 SystemVerilog 属性,全面检查写响应通道信号的合法性和稳定性,确保协议的正确实现。断言语句在规则违反时能及时反馈错误信息,有助于开发人员快速定位问题。覆盖属性则为验证人员提供覆盖率数据,保证验证工作的完备性。整体上,该模块提高了 AXI4 协议验证的效率和准确性。

4. core-v-verif/lib/uvm_agents/uvma_axi/src/uvma_axi_intf.sv

// Copyright 2022 Thales DIS SAS
//
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
// You may obtain a copy of the License at https://solderpad.org/licenses/
//
// Original Author: Alae Eddine EZ ZEJJARI (alae-eddine.ez-zejjari@external.thalesgroup.com)
// Co-Author: Abdelaali Khardazi

/**** AXI4 interface with parametrized :  ****/

interface uvma_axi_intf #(
   parameter AXI_ADDR_WIDTH      = `UVMA_AXI_ADDR_MAX_WIDTH,
   parameter AXI_DATA_WIDTH      = `UVMA_AXI_DATA_MAX_WIDTH,
   parameter AXI_USER_WIDTH      = `UVMA_AXI_USER_MAX_WIDTH,
   parameter AXI_ID_WIDTH        = `UVMA_AXI_ID_MAX_WIDTH
) (input bit clk, bit rst_n);

   // AXI4 signals
   // Write Address channel
   logic    [AXI_ID_WIDTH-1:0]       aw_id;
   logic    [AXI_ADDR_WIDTH-1:0]     aw_addr;
   logic    [AXI_USER_WIDTH-1:0]     aw_user;
   logic    [7:0]                    aw_len;
   logic    [2:0]                    aw_size;
   logic    [1:0]                    aw_burst;
   logic                             aw_lock;
   logic    [3:0]                    aw_cache;
   logic    [2:0]                    aw_prot;
   logic    [3:0]                    aw_qos;
   logic    [3:0]                    aw_region;
   logic                             aw_valid;
   logic                             aw_ready;
   logic    [5:0]                    aw_atop;

   //write data channel
   logic    [AXI_DATA_WIDTH-1:0]     w_data;
   logic    [AXI_DATA_WIDTH/8-1:0]   w_strb;
   logic    [AXI_USER_WIDTH-1:0]     w_user;
   logic                             w_last;
   logic                             w_valid;
   logic                             w_ready;

   // write response channel
   logic    [AXI_ID_WIDTH-1:0]       b_id;
   logic    [AXI_USER_WIDTH-1:0]     b_user;
   logic    [1:0]                    b_resp;
   logic                             b_valid;
   logic                             b_ready;

   // read address channel
   logic    [AXI_ID_WIDTH-1:0]       ar_id;
   logic    [AXI_ADDR_WIDTH-1:0]     ar_addr;
   logic    [AXI_USER_WIDTH-1:0]     ar_user;
   logic    [7:0]                    ar_len;
   logic    [2:0]                    ar_size;
   logic    [1:0]                    ar_burst;
   logic                             ar_lock;
   logic    [3:0]                    ar_cache;
   logic    [2:0]                    ar_prot;
   logic    [3:0]                    ar_qos;
   logic    [3:0]                    ar_region;
   logic                             ar_valid;
   logic                             ar_ready;

   //read data channel
   logic    [AXI_ID_WIDTH-1:0]       r_id;
   logic    [AXI_DATA_WIDTH-1:0]     r_data;
   logic    [AXI_USER_WIDTH-1:0]     r_user;
   logic    [1:0]                    r_resp;
   logic                             r_last;
   logic                             r_valid;
   logic                             r_ready;



   clocking slv_axi_cb @(posedge clk or rst_n);
      output   ar_ready,
               r_id, r_data, r_resp, r_last, r_valid, r_user,
               aw_ready,
               w_ready,
               b_id, b_resp, b_user, b_valid;
      input    ar_id, ar_addr, ar_user, ar_len, ar_size, ar_burst, ar_lock, ar_cache, ar_prot, ar_qos, ar_region, ar_valid,
               r_ready,
               aw_id, aw_addr, aw_user, aw_len, aw_size, aw_burst, aw_lock, aw_cache, aw_prot, aw_qos, aw_region, aw_valid, aw_atop,
               w_data, w_strb, w_last, w_user, w_valid,
               b_ready;
   endclocking: slv_axi_cb

   clocking psv_axi_cb @(posedge clk or rst_n);
      input    ar_id, ar_addr, ar_user, ar_len, ar_size, ar_burst, ar_lock, ar_cache, ar_prot, ar_qos, ar_region, ar_valid, ar_ready,
               r_ready, r_id, r_data, r_resp, r_user, r_last, r_valid,
               aw_id, aw_addr, aw_user, aw_len, aw_size, aw_burst, aw_lock, aw_cache, aw_prot, aw_qos, aw_region, aw_valid, aw_atop, aw_ready,
               w_data, w_strb, w_last, w_user, w_valid, w_ready,
               b_id, b_resp, b_user, b_valid, b_ready;
   endclocking: psv_axi_cb

   modport slave (clocking slv_axi_cb);
   modport passive (clocking psv_axi_cb);

endinterface : uvma_axi_intf

1. 简要介绍

uvma_axi_intf.sv 定义了一个参数化的 AXI4 接口 uvma_axi_intf。该接口用于在不同模块间传递 AXI4 协议相关的信号,支持对地址宽度、数据宽度、用户信号宽度和 ID 宽度等参数进行配置,同时定义了两种不同的时钟块和对应的端口模式,方便在不同场景下使用。

2. 接口介绍

interface uvma_axi_intf #(
   parameter AXI_ADDR_WIDTH      = `UVMA_AXI_ADDR_MAX_WIDTH,
   parameter AXI_DATA_WIDTH      = `UVMA_AXI_DATA_MAX_WIDTH,
   parameter AXI_USER_WIDTH      = `UVMA_AXI_USER_MAX_WIDTH,
   parameter AXI_ID_WIDTH        = `UVMA_AXI_ID_MAX_WIDTH
) (input bit clk, bit rst_n);

代码分析

  • interface uvma_axi_intf:声明一个名为 uvma_axi_intf 的接口。
  • #(:开始参数列表,用于定义接口的可配置参数。
    • parameter AXI_ADDR_WIDTH = UVMA_AXI_ADDR_MAX_WIDTH:定义地址宽度参数,默认值为 UVMA_AXI_ADDR_MAX_WIDTH` 宏的值。
    • parameter AXI_DATA_WIDTH = UVMA_AXI_DATA_MAX_WIDTH:定义数据宽度参数,默认值为 UVMA_AXI_DATA_MAX_WIDTH` 宏的值。
    • parameter AXI_USER_WIDTH = UVMA_AXI_USER_MAX_WIDTH:定义用户信号宽度参数,默认值为 UVMA_AXI_USER_MAX_WIDTH` 宏的值。
    • parameter AXI_ID_WIDTH = UVMA_AXI_ID_MAX_WIDTH:定义 ID 宽度参数,默认值为 UVMA_AXI_ID_MAX_WIDTH` 宏的值。
  • ):结束参数列表。
  • (input bit clk, bit rst_n):定义接口的端口,clk 是时钟信号,rst_n 是复位信号,低电平有效。

3. 参数介绍

parameter AXI_ADDR_WIDTH      = `UVMA_AXI_ADDR_MAX_WIDTH,
parameter AXI_DATA_WIDTH      = `UVMA_AXI_DATA_MAX_WIDTH,
parameter AXI_USER_WIDTH      = `UVMA_AXI_USER_MAX_WIDTH,
parameter AXI_ID_WIDTH        = `UVMA_AXI_ID_MAX_WIDTH

代码分析

  • AXI_ADDR_WIDTH:用于指定 AXI4 协议中地址信号的宽度,默认值由 UVMA_AXI_ADDR_MAX_WIDTH 宏决定。
  • AXI_DATA_WIDTH:用于指定 AXI4 协议中数据信号的宽度,默认值由 UVMA_AXI_DATA_MAX_WIDTH 宏决定。
  • AXI_USER_WIDTH:用于指定 AXI4 协议中用户自定义信号的宽度,默认值由 UVMA_AXI_USER_MAX_WIDTH 宏决定。
  • AXI_ID_WIDTH:用于指定 AXI4 协议中 ID 信号的宽度,默认值由 UVMA_AXI_ID_MAX_WIDTH 宏决定。

4. 模块实现介绍

4.1 AXI4 信号定义
// Write Address channel
logic    [AXI_ID_WIDTH-1:0]       aw_id;
logic    [AXI_ADDR_WIDTH-1:0]     aw_addr;
// ... 其他信号定义 ...

代码分析:按照 AXI4 协议规范,定义了写地址通道、写数据通道、写响应通道、读地址通道和读数据通道的所有信号。信号的宽度根据前面定义的参数进行设置。

4.2 时钟块定义
clocking slv_axi_cb @(posedge clk or rst_n);
   output   ar_ready,
            r_id, r_data, r_resp, r_last, r_valid, r_user,
            aw_ready,
            w_ready,
            b_id, b_resp, b_user, b_valid;
   input    ar_id, ar_addr, ar_user, ar_len, ar_size, ar_burst, ar_lock, ar_cache, ar_prot, ar_qos, ar_region, ar_valid,
            r_ready,
            aw_id, aw_addr, aw_user, aw_len, aw_size, aw_burst, aw_lock, aw_cache, aw_prot, aw_qos, aw_region, aw_valid, aw_atop,
            w_data, w_strb, w_last, w_user, w_valid,
            b_ready;
endclocking: slv_axi_cb

clocking psv_axi_cb @(posedge clk or rst_n);
   input    ar_id, ar_addr, ar_user, ar_len, ar_size, ar_burst, ar_lock, ar_cache, ar_prot, ar_qos, ar_region, ar_valid, ar_ready,
            r_ready, r_id, r_data, r_resp, r_user, r_last, r_valid,
            aw_id, aw_addr, aw_user, aw_len, aw_size, aw_burst, aw_lock, aw_cache, aw_prot, aw_qos, aw_region, aw_valid, aw_atop, aw_ready,
            w_data, w_strb, w_last, w_user, w_valid, w_ready,
            b_id, b_resp, b_user, b_valid, b_ready;
endclocking: psv_axi_cb

代码分析

  • clocking slv_axi_cb @(posedge clk or rst_n):定义一个名为 slv_axi_cb 的时钟块,在时钟上升沿或复位信号变化时触发。output 部分定义了该时钟块输出的信号,input 部分定义了输入的信号,通常用于从设备的接口操作。
  • clocking psv_axi_cb @(posedge clk or rst_n):定义一个名为 psv_axi_cb 的时钟块,同样在时钟上升沿或复位信号变化时触发,所有信号都定义为输入,通常用于被动监控接口信号。
4.3 端口模式定义
modport slave (clocking slv_axi_cb);
modport passive (clocking psv_axi_cb);

代码分析

  • modport slave (clocking slv_axi_cb):定义一个名为 slave 的端口模式,使用 slv_axi_cb 时钟块,用于从设备连接。
  • modport passive (clocking psv_axi_cb):定义一个名为 passive 的端口模式,使用 psv_axi_cb 时钟块,用于被动监控接口信号。

5. 总结

uvma_axi_intf.sv 实现了一个灵活的 AXI4 接口,通过参数化设计,可以根据不同的需求调整地址、数据、用户和 ID 信号的宽度。时钟块和端口模式的定义使得该接口可以在不同的场景下使用,如从设备接口和被动监控。该接口为 AXI4 协议相关的设计和验证提供了基础框架,提高了代码的复用性和可维护性。

5. core-v-verif/lib/uvm_agents/uvma_axi/src/uvma_axi_macros.sv

// Copyright 2022 Thales DIS SAS
//
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
// You may obtain a copy of the License at https://solderpad.org/licenses/
//
// Original Author: Alae Eddine EZ ZEJJARI (alae-eddine.ez-zejjari@external.thalesgroup.com)
// Co-Author: Abdelaali Khardazi

`ifndef __UVMA_AXI_MACROS_SV__
`define __UVMA_AXI_MACROS_SV__

   parameter Nr_Slaves      = 2;  // actually masters, but slaves on the crossbar
   parameter Id_Width       = 4;  // 4 is recommended by AXI standard, so lets stick to it, do not change
   parameter Id_Width_Slave = Id_Width + $clog2(Nr_Slaves);

   `define UVMA_AXI_ADDR_MAX_WIDTH           64
   `define UVMA_AXI_DATA_MAX_WIDTH           64
   `define UVMA_AXI_USER_MAX_WIDTH            1
   `define UVMA_AXI_ID_MAX_WIDTH              Id_Width_Slave
   `define UVMA_AXI_STRB_MAX_WIDTH            8

   `define per_instance_fcov `ifndef DSIM option.per_instance = 1; `endif

`endif // __UVMA_AXI_MACROS_SV__

1. 简要介绍

uvma_axi_macros.sv 文件主要用于定义 AXI 相关的参数和宏,这些参数和宏会在 AXI 验证环境里被复用。文件通过条件编译确保只被编译一次,定义了与 AXI 总线的从机数量、ID 宽度、地址宽度、数据宽度等相关的参数和宏,同时还包含一个与覆盖率选项有关的宏定义。

2. 接口介绍

此文件无传统意义上的接口,它主要是定义参数和宏,为其他模块或文件提供配置信息。

3. 参数介绍

parameter Nr_Slaves      = 2;  // actually masters, but slaves on the crossbar
parameter Id_Width       = 4;  // 4 is recommended by AXI standard, so lets stick to it, do not change
parameter Id_Width_Slave = Id_Width + $clog2(Nr_Slaves);
  • Nr_Slaves
    • 代码行parameter Nr_Slaves = 2; // actually masters, but slaves on the crossbar
    • 介绍:定义从机的数量,注释表明实际是主机,但在交叉开关上作为从机。
    • 逻辑分析:将从机数量初始化为 2,后续可根据实际需求修改该值。
  • Id_Width
    • 代码行parameter Id_Width = 4; // 4 is recommended by AXI standard, so lets stick to it, do not change
    • 介绍:定义 ID 的宽度,根据 AXI 标准推荐值设为 4,注释建议不要修改。
    • 逻辑分析:遵循 AXI 标准,将 ID 宽度固定为 4,保证符合协议规范。
  • Id_Width_Slave
    • 代码行parameter Id_Width_Slave = Id_Width + $clog2(Nr_Slaves);
    • 介绍:计算从机 ID 的宽度,其值为 Id_Width 加上 Nr_Slaves 以 2 为底的对数。
    • 逻辑分析:根据从机数量动态计算从机 ID 的宽度,确保有足够的位宽来唯一标识每个从机。

4. 模块实现介绍

4.1 条件编译
`ifndef __UVMA_AXI_MACROS_SV__
`define __UVMA_AXI_MACROS_SV__

// ... 中间代码 ...

`endif // __UVMA_AXI_MACROS_SV__
  • 代码行ifndef __UVMA_AXI_MACROS_SV__define __UVMA_AXI_MACROS_SV__endif // __UVMA_AXI_MACROS_SV__
  • 介绍:使用条件编译指令防止文件被重复编译。如果 __UVMA_AXI_MACROS_SV__ 宏未定义,则定义该宏并编译中间代码;若已定义,则跳过中间代码。
  • 逻辑分析:保证文件在整个编译过程中只被编译一次,避免重复定义带来的错误。
4.2 宏定义
`define UVMA_AXI_ADDR_MAX_WIDTH           64
`define UVMA_AXI_DATA_MAX_WIDTH           64
`define UVMA_AXI_USER_MAX_WIDTH            1
`define UVMA_AXI_ID_MAX_WIDTH              Id_Width_Slave
`define UVMA_AXI_STRB_MAX_WIDTH            8
  • UVMA_AXI_ADDR_MAX_WIDTH:定义 AXI 地址的最大宽度为 64 位。
  • UVMA_AXI_DATA_MAX_WIDTH:定义 AXI 数据的最大宽度为 64 位。
  • UVMA_AXI_USER_MAX_WIDTH:定义 AXI 用户信号的最大宽度为 1 位。
  • UVMA_AXI_ID_MAX_WIDTH:定义 AXI ID 的最大宽度为 Id_Width_Slave 的值。
  • UVMA_AXI_STRB_MAX_WIDTH:定义 AXI 字节选通信号的最大宽度为 8 位。
4.3 覆盖率选项宏
`define per_instance_fcov `ifndef DSIM option.per_instance = 1; `endif
  • 代码行define per_instance_fcov ifndef DSIM option.per_instance = 1; endif
  • 介绍:定义一个名为 per_instance_fcov 的宏,当 DSIM 未定义时,设置覆盖率选项 option.per_instance 为 1。
  • 逻辑分析:根据编译环境是否定义 DSIM 来决定是否设置覆盖率选项,用于控制覆盖率统计的方式。

5. 总结

uvma_axi_macros.sv 文件通过参数和宏的定义,为 AXI 验证环境提供了统一的配置信息。条件编译确保文件不会被重复编译,参数和宏的设置遵循 AXI 标准并考虑了一定的灵活性,如从机 ID 宽度的动态计算。覆盖率选项宏则为验证过程中的覆盖率统计提供了控制手段,整体上提高了代码的可维护性和复用性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值