当前位置: 首页 > article >正文

15. 示例:创建AXI-Lite事务类(addr/data/rw)

文章目录

  • 前言
  • 示例一: AXI-Lite事务类
    • 1. xrun仿真指令
    • 2. 代码解析
    • 3. 常见误区与解决方法
    • 4. 应用场景扩展
  • 示例二:AXI-Lite事务类实现
    • 1. AXI-Lite事务类实现(SystemVerilog)
    • 2. 测试平台示例
    • 3. xSim仿真指令
    • 4. 关键实现说明:
  • 示例三:AXI-Lite事务类实现与仿真示例‌
    • 1. AXI-Lite事务类定义‌
    • 2. Driver与Monitor实现‌
    • 3. 仿真环境与测试用例‌
    • 4. xrun仿真指令‌
    • 5. 关键实现说明‌
  • 示例四: AXI-Lite事务类
    • 1. AXI-Lite事务类定义(`axi_lite_transaction.sv`)
    • 2. 测试平台示例(`axi_lite_tb.sv`)
    • 3. xrun仿真指令
    • 4. 关键设计点说明
    • 5. 示例输出


前言

以下是一个完整的SystemVerilog示例,实现AXI-Lite事务类(包含地址、数据和读写类型),并提供xrun仿真指令:


示例一: AXI-Lite事务类

// ======================= AXI-Lite事务类定义 =======================
class axi_lite_transaction;
    // 枚举类型定义读写操作
    typedef enum {READ, WRITE} rw_type;
    
    // 随机化字段
    rand bit [31:0]   addr;  // 32位地址
    rand bit [31:0]   data;  // 32位数据
    rand rw_type      rw;    // 读/写操作
    
    // 地址对齐约束(AXI-Lite要求地址按数据宽度对齐)
    constraint addr_alignment {
        addr % 4 == 0;  // 4字节对齐
    }
    
    // 数据范围约束
    constraint data_range {
        data inside {[0:32'hFFFF_FFFF]};
    }
    
    // 读写操作分布约束
    constraint rw_dist {
        rw dist {READ := 40, WRITE := 60};  // 60%写操作,40%读操作
    }
    
    // 打印事务内容
    function void print();
        string operation;
        operation = (rw == WRITE) ? "WRITE" : "READ";
        $display("[AXI-Lite] %s @ 0x%08h : 0x%08h", 
                operation, addr, data);
    endfunction
    
    // 将事务打包为字节数组(用于驱动信号)
    function byte unsigned[] pack();
        byte unsigned bytes[];
        bytes = new[8];  // 4字节地址 + 4字节数据
        {>>{bytes}} = {<<byte{addr, data}};  // 小端序打包
        return bytes;
    endfunction
endclass

// ======================= 测试平台 =======================
module tb;
    axi_lite_transaction tr;
    
    initial begin
        tr = new();  // 创建事务对象
        
        $display("========== AXI-Lite事务测试 ==========");
        repeat(5) begin
            // 随机化事务
            if (!tr.randomize()) begin
                $error("Randomization failed!");
                $finish;
            end
            
            // 打印事务内容
            tr.print();
            
            // 打包并显示字节流
            begin
                byte unsigned packet[];
                packet = tr.pack();
                $write("Packet Bytes: ");
                foreach(packet[i]) $write("%02h ", packet[i]);
                $display("\n");
            end
            
            #10;  // 模拟时间推进
        end
        $display("========== 测试完成 ==========");
        $finish;
    end
endmodule

1. xrun仿真指令

xrun -sv -64bit -access +rw axi_lite_tb.sv

仿真输出示例

========== AXI-Lite事务测试 ==========
[AXI-Lite] WRITE @ 0x00001230 : 0x89abcdef
Packet Bytes: 30 12 00 00 ef cd ab 89 

[AXI-Lite] READ @ 0x0000fffc : 0x12345678  
Packet Bytes: fc ff 00 00 78 56 34 12 

[AXI-Lite] WRITE @ 0x00003c00 : 0xdeadbeef
Packet Bytes: 00 3c 00 00 ef be ad de 

[AXI-Lite] READ @ 0x00002400 : 0x55aa55aa
Packet Bytes: 00 24 00 00 aa 55 aa 55 

[AXI-Lite] WRITE @ 0x00001800 : 0x11223344
Packet Bytes: 00 18 00 00 44 33 22 11 

========== 测试完成 ==========

2. 代码解析

  1. 事务类结构

    • addr:32位对齐地址(addr % 4 == 0
    • data:32位数据
    • rw:读写类型枚举(READ/WRITE)
  2. 约束特性

    • 地址必须4字节对齐(AXI-Lite协议要求)
    • 数据范围覆盖全32位
    • 读写操作加权分布(60%写操作)
  3. 实用方法

    • print():格式化打印事务内容
    • pack():将地址和数据打包为小端字节序
  4. 测试平台

    • 生成5个随机事务
    • 显示事务内容和打包后的字节流

3. 常见误区与解决方法

  1. 地址未对齐错误

    • 现象:协议违反导致DUT错误
    • 解决:确保约束addr % 4 == 0
  2. 枚举类型未正确使用

   // 错误写法
   tr.rw = 1;  
   // 正确写法
   tr.rw = axi_lite_transaction::WRITE;
  1. 内存泄漏
    • 现象:重复new()未释放
    • 解决:使用automatic存储类或显式销毁对象
     automatic axi_lite_transaction tr = new();

4. 应用场景扩展

  1. 验证场景

    • 正常操作:读写寄存器验证
    • 边界测试:地址=0x00000000/0xFFFFFFFC
    • 错误注入:临时关闭约束测试协议错误
  2. 功能覆盖

   covergroup axi_cov;
       addr_range: coverpoint tr.addr {
           bins low  = {[0:32'h0000_FFFF]};
           bins mid  = {[32'h0001_0000:32'hFFFF_0000]};
           bins high = {[32'hFFFF_0001:32'hFFFF_FFFF]};
       }
       rw_type: coverpoint tr.rw;
   endgroup

通过这个示例,您可以快速上手AXI-Lite事务建模,并基于此扩展构建完整的验证环境。

示例二:AXI-Lite事务类实现

1. AXI-Lite事务类实现(SystemVerilog)

// 定义AXI-Lite事务类
class axi_lite_transaction;
    // 地址/数据位宽(默认32位)
    rand logic [31:0] addr;
    rand logic [31:0] data;
    rand enum { READ, WRITE } rw;

    // 地址对齐约束(4字节对齐)
    constraint addr_alignment {
        addr[1:0] == 2'b00;  // AXI-Lite要求地址按4字节对齐
    }

    // 数据范围约束(可选)
    constraint data_range {
        data inside {[0:32'hFFFF_FFFF]};  // 根据需求调整范围
    }

    // 读写操作比例约束(默认1:1)
    constraint rw_ratio {
        rw dist { READ := 50, WRITE := 50 };
    }

    // 打印事务内容
    function void display();
        $display("[%0t] AXI-Lite %s: addr=0x%8h, data=0x%8h", 
                $time, rw.name(), addr, data);
    endfunction
endclass

2. 测试平台示例

module tb_axi_lite;
    // AXI-Lite接口信号声明
    logic        aclk;
    logic        aresetn;
    logic [31:0] awaddr;
    logic        awvalid;
    logic        awready;
    logic [31:0] wdata;
    logic        wvalid;
    logic        wready;
    // ...其他信号省略...

    // 事务生成器
    initial begin
        axi_lite_transaction tr = new();
        repeat(10) begin
            assert(tr.randomize());  // 随机生成事务
            tr.display();
            case(tr.rw)
                axi_lite_transaction::WRITE: drive_write(tr);
                axi_lite_transaction::READ:  drive_read(tr);
            endcase
            #10;
        end
        $finish;
    end

    // 写事务驱动任务
    task drive_write(axi_lite_transaction tr);
        // 驱动写地址通道
        awaddr  = tr.addr;
        awvalid = 1'b1;
        @(posedge aclk iff awready);
        awvalid = 1'b0;

        // 驱动写数据通道
        wdata  = tr.data;
        wvalid = 1'b1;
        @(posedge aclk iff wready);
        wvalid = 1'b0;
    endtask

    // 读事务驱动任务(类似实现)
    // ...省略...
endmodule

3. xSim仿真指令

# 编译命令
xrun -sv \
     -access +rwc \
     -incdir ./include \
     -define AXI_DATA_WIDTH=32 \
     axi_lite_transaction.sv \
     tb_axi_lite.sv \
     axi_lite_slave_model.sv

# 仿真运行(带波形输出)
xrun -input waves.tcl \
     -coverage all \
     -uvmhome $UVM_HOME  # 若集成UVM可添加

4. 关键实现说明:

  1. 事务类设计

    • 使用rand修饰符实现随机化生成
    • 通过约束保证地址对齐(AXI-Lite强制要求)
    • 内置显示函数用于调试跟踪
  2. 接口驱动

    • 采用任务(task)分离读写操作流程
    • 基于握手信号(valid/ready)实现协议时序
  3. 仿真配置

    • -access +rwc启用信号访问跟踪
    • -coverage all启用功能覆盖率收集
    • 可搭配波形文件(waves.tcl)进行可视化调试

示例三:AXI-Lite事务类实现与仿真示例‌

1. AXI-Lite事务类定义‌

// 定义事务类(继承uvm_sequence_item)
class axi_lite_transaction extends uvm_sequence_item;
  // 字段定义
  rand logic [31:0] addr;  // 32位地址(对齐到4字节)‌:ml-citation{ref="2,4" data="citationList"}
  rand logic [31:0] data;  // 32位数据‌:ml-citation{ref="2,4" data="citationList"}
  rand enum {READ, WRITE} rw;  // 读写方向‌:ml-citation{ref="2,4" data="citationList"}
  
  // 约束条件
  constraint addr_alignment { addr[1:0] == 0; }  // AXI-Lite地址对齐规则‌:ml-citation{ref="2,4" data="citationList"}
  constraint data_range     { data inside {[0:32'hFFFF_FFFF]}; }  
  constraint rw_dist       { rw dist { READ := 30, WRITE := 70 }; }  // 操作类型分布‌:ml-citation{ref="3,4" data="citationList"}
  
  // UVM自动化注册
  `uvm_object_utils_begin(axi_lite_transaction)
    `uvm_field_int(addr, UVM_ALL_ON)
    `uvm_field_int(data, UVM_ALL_ON)
    `uvm_field_enum(enum {READ, WRITE}, rw, UVM_ALL_ON)
  `uvm_object_utils_end
  
  function new(string name = "axi_lite_transaction");
    super.new(name);
  endfunction
endclass

2. Driver与Monitor实现‌

// Driver类(驱动AXI-Lite信号)
class axi_lite_driver extends uvm_driver #(axi_lite_transaction);
  virtual axi_lite_if vif;  // 虚拟接口‌:ml-citation{ref="3,4" data="citationList"}
  
  `uvm_component_utils(axi_lite_driver)
  
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction
  
  task run_phase(uvm_phase phase);
    forever begin
      seq_item_port.get_next_item(req);  // 获取事务‌:ml-citation{ref="3,4" data="citationList"}
      drive_transaction(req);
      seq_item_port.item_done();
    end
  endtask
  
  task drive_transaction(axi_lite_transaction tr);
    // 写操作驱动逻辑‌:ml-citation{ref="1,4" data="citationList"}
    if (tr.rw == WRITE) begin
      vif.awaddr  <= tr.addr;
      vif.awvalid <= 1;
      vif.wdata   <= tr.data;
      vif.wvalid  <= 1;
      @(posedge vif.clk iff vif.awready && vif.wready);  // 握手等待‌:ml-citation{ref="2,3" data="citationList"}
      vif.awvalid <= 0;
      vif.wvalid  <= 0;
      @(posedge vif.clk iff vif.bvalid);  // 写响应等待‌:ml-citation{ref="2,3" data="citationList"}
    end 
    // 读操作驱动逻辑‌:ml-citation{ref="1,4" data="citationList"}
    else begin
      vif.araddr  <= tr.addr;
      vif.arvalid <= 1;
      @(posedge vif.clk iff vif.arready);  // 握手等待‌:ml-citation{ref="2,3" data="citationList"}
      vif.arvalid <= 0;
      @(posedge vif.clk iff vif.rvalid);   // 读数据等待‌:ml-citation{ref="2,3" data="citationList"}
      tr.data     = vif.rdata;
    end
  endtask
endclass

// Monitor类(监听总线事务)
class axi_lite_monitor extends uvm_monitor;
  virtual axi_lite_if vif;
  uvm_analysis_port #(axi_lite_transaction) ap;  // 事务分析端口‌:ml-citation{ref="3,4" data="citationList"}
  
  `uvm_component_utils(axi_lite_monitor)
  
  function new(string name, uvm_component parent);
    super.new(name, parent);
    ap = new("ap", this);
  endfunction
  
  task run_phase(uvm_phase phase);
    forever begin
      axi_lite_transaction tr;
      // 捕获写事务‌:ml-citation{ref="2,3" data="citationList"}
      if (vif.awvalid && vif.awready) begin
        tr = axi_lite_transaction::type_id::create("tr");
        tr.addr = vif.awaddr;
        tr.rw   = WRITE;
        @(posedge vif.clk iff vif.wvalid && vif.wready);
        tr.data = vif.wdata;
        ap.write(tr);
      end
      // 捕获读事务‌:ml-citation{ref="2,3" data="citationList"}
      if (vif.arvalid && vif.arready) begin
        tr = axi_lite_transaction::type_id::create("tr");
        tr.addr = vif.araddr;
        tr.rw   = READ;
        @(posedge vif.clk iff vif.rvalid);
        tr.data = vif.rdata;
        ap.write(tr);
      end
      @(posedge vif.clk);
    end
  endtask
endclass

3. 仿真环境与测试用例‌

// 测试环境(集成Driver/Monitor)
class axi_lite_env extends uvm_env;
  axi_lite_driver    driver;
  axi_lite_monitor   monitor;
  virtual axi_lite_if vif;
  
  `uvm_component_utils(axi_lite_env)
  
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    driver  = axi_lite_driver::type_id::create("driver", this);
    monitor = axi_lite_monitor::type_id::create("monitor", this);
    if (!uvm_config_db#(virtual axi_lite_if)::get(this, "", "vif", vif))
      `uvm_fatal("NOVIF", "Virtual interface not set")  // 接口配置检查‌:ml-citation{ref="3,4" data="citationList"}
    driver.vif = vif;
    monitor.vif = vif;
  endfunction
endclass

// 测试用例(生成随机事务)
class axi_lite_test extends uvm_test;
  axi_lite_env env;
  
  `uvm_component_utils(axi_lite_test)
  
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    env = axi_lite_env::type_id::create("env", this);
  endfunction
  
  task run_phase(uvm_phase phase);
    axi_lite_transaction tr;
    phase.raise_objection(this);
    repeat(10) begin  // 生成10个随机事务‌:ml-citation{ref="3,4" data="citationList"}
      tr = axi_lite_transaction::type_id::create("tr");
      assert(tr.randomize());
      env.driver.seq_item_port.put(tr);  // 发送到Driver‌:ml-citation{ref="3,4" data="citationList"}
    end
    phase.drop_objection(this);
  endtask
endclass

4. xrun仿真指令‌

# 编译并仿真(使用Cadence Xcelium)
xrun -sv -64bit -access +rw \
     axi_lite_pkg.sv \      # 事务类/接口定义
     axi_lite_if.sv \       # 接口文件
     axi_lite_driver.sv \   # Driver实现
     axi_lite_monitor.sv \  # Monitor实现
     axi_lite_env.sv \      # 环境集成
     axi_lite_test.sv \     # 测试用例
     top.sv \               # 顶层模块(连接DUT与TB)
     -uvm -uvmhome CDNS-1.2 \
     -wave \                # 生成波形
     -timescale 1ns/1ps     # 时间精度‌:ml-citation{ref="3,4" data="citationList"}

5. 关键实现说明‌

  1. 事务对齐约束‌:通过addr_alignment约束强制地址按4字节对齐,符合AXI-Lite协议要求‌。
  2. 握手协议实现‌:Driver中使用@(posedge vif.clk iff condition)等待VALID/READY握手完成‌。‌
  3. 覆盖率导向‌:通过rw_dist约束控制读写操作比例,提升验证效率‌。‌
  4. 接口绑定‌:使用uvm_config_db传递虚拟接口,实现TB与DUT连接‌。

示例四: AXI-Lite事务类

1. AXI-Lite事务类定义(axi_lite_transaction.sv

import uvm_pkg::*;
`include "uvm_macros.svh"

class axi_lite_transaction extends uvm_sequence_item;
  // 定义字段
  rand logic [31:0] addr;  // 32位地址
  rand logic [31:0] data;  // 32位数据
  rand enum {READ, WRITE} rw;  // 读写类型

  // 地址对齐约束(AXI-Lite要求地址按4字节对齐)
  constraint addr_alignment {
    addr % 4 == 0;
  }

  // UVM自动化注册
  `uvm_object_utils_begin(axi_lite_transaction)
    `uvm_field_int(addr, UVM_ALL_ON)
    `uvm_field_int(data, UVM_ALL_ON)
    `uvm_field_enum(rw, UVM_ALL_ON)
  `uvm_object_utils_end

  // 构造函数
  function new(string name = "axi_lite_transaction");
    super.new(name);
  endfunction

  // 可选的copy函数
  virtual function void do_copy(uvm_object rhs);
    axi_lite_transaction rhs_;
    if (!$$cast(rhs_, rhs)) begin
      uvm_report_error("do_copy", "Copy failed");
      return;
    end
    super.do_copy(rhs);
    addr = rhs_.addr;
    data = rhs_.data;
    rw   = rhs_.rw;
  endfunction
endclass

2. 测试平台示例(axi_lite_tb.sv

module axi_lite_tb;
  import uvm_pkg::*;
  `include "uvm_macros.svh"

  initial begin
    axi_lite_transaction tr;
    tr = axi_lite_transaction::type_id::create("tr");

    // 生成并打印随机事务
    repeat(5) begin
      assert(tr.randomize());
      $$display("[Transaction] Addr=0x%0h, Data=0x%0h, RW=%s", 
               tr.addr, tr.data, tr.rw.name());
    end
    $$finish;
  end
endmodule

3. xrun仿真指令

执行以下命令编译并运行仿真:

xrun -uvm -access +rwc axi_lite_transaction.sv axi_lite_tb.sv
  • 参数说明
    • -uvm: 启用UVM库支持。
    • -access +rwc: 允许对信号的读写权限。
    • 文件列表:包含事务类定义和测试平台文件。

4. 关键设计点说明

  1. UVM集成

    • 事务类继承自uvm_sequence_item,支持UVM的随机化、序列化和调试功能。
    • 使用uvm_field_*宏实现字段的自动化操作(如打印、复制等)。
  2. 地址对齐约束

    • AXI-Lite协议要求地址按4字节对齐,通过约束addr % 4 == 0实现。
  3. 随机化与测试

    • 在测试平台中调用randomize()生成随机事务,覆盖不同地址和数据组合。

5. 示例输出

仿真运行后,控制台可能输出:

[Transaction] Addr=0x00001000, Data=0x12345678, RW=WRITE
[Transaction] Addr=0x00002004, Data=0xdeadbeef, RW=READ
...

通过此示例,可快速验证AXI-Lite事务类的功能,并扩展为完整的验证环境(如添加Driver/Monitor)。


http://www.kler.cn/a/572731.html

相关文章:

  • JavaWeb-CS和BS的异同点
  • 调用链追踪(Trace ID)
  • 关于tresos Studio(EB)的MCAL配置之GPT
  • 计算机毕设-基于springboot的网上商城系统的设计与实现(附源码+lw+ppt+开题报告)
  • VSTO(C#)Excel开发起步
  • unittest框架 核心知识的系统复习及与pytest的对比
  • 厦门大学:《DeepSeek大模型赋能高校教学和科研报告》(120页PPT,建议收藏)
  • Milvus 数据批量导出实战:Python 代码解析
  • 【深度剖析】古德-图灵估计:从密码破译到NLP的统计革命
  • react精简面试题
  • 金融术语:Loan origination理解
  • RockyLinux9.5 虚拟机安装、配置及XShell连接
  • GaussianCity:实时生成城市级数字孪生基底的技术突破
  • 报错Non-terminating decimal expansion; no exact representable decimal result
  • 【YOLO V5】目标检测 WSL2 AutoDL VScode SSH
  • MySQL环境搭建
  • 充分必要条件
  • Spring Boot 3 整合 MinIO 实现分布式文件存储
  • 大模型基石——Transformer介绍
  • 蓝桥杯4T平台(频率测量显示)