You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于APB驱动run_phase向DUT发送事务逻辑的技术疑问

UVM APB驱动常见问题解答

问题1:是否可以在driver类中手动设置Penable、Psel、Pready的值,还是需要在seq_item类中对这些信号进行随机化?

  • Psel、Penable:必须由driver手动控制,不需要在seq_item中随机化。这两个是APB总线的控制信号,属于事务执行的时序细节,是driver按照APB协议状态机生成的,不属于事务本身的属性。
  • Pready:这是DUT输出的响应信号,driver只需要采样它,不需要主动设置。

seq_item的核心作用是描述一个完整的事务请求,比如读写类型、目标地址、写数据、传输等待周期(可选)等。总线握手的控制信号是driver的职责,要严格遵循APB协议时序驱动,交给seq_item随机化会破坏协议规范性,也混淆了seq(事务发起)和driver(事务执行)的分层职责。特殊场景下(比如模拟异常时序),可以在seq_item中加配置参数让driver生成异常信号,但常规正常传输不需要这么做。

问题2:如何根据idle、setup、access等不同状态来设置这些信号的值?

APB协议状态机是固定的,driver需要根据状态切换精准控制信号,以下是标准状态处理逻辑:

各状态信号规则

  1. Idle(空闲状态)
    • 无传输时保持此状态
    • 信号设置:Psel = 0,Penable = 0,Pwrite、Paddr、Pwdata可保持无效值
  2. Setup(建立状态)
    • 发起新传输的第一个时钟周期进入此状态
    • 信号设置:Psel = 1,Penable = 0,同时设置Paddr(目标地址)、Pwrite(读写类型)、Pwdata(写操作时赋值)
  3. Access(访问状态)
    • Setup状态的下一个时钟周期进入此状态
    • 信号设置:Psel = 1,Penable = 1,保持Paddr、Pwrite、Pwdata不变(写操作)
    • 等待DUT的Pready信号:当Pready == 1时传输完成,读操作在此周期采样Prdata,写操作在此周期完成数据传输
  4. 连续传输
    • 如果需要连续发起多个事务,传输完成后可直接进入下一个事务的Setup状态,无需回到Idle

修正后的driver run_phase示例代码

task run_phase(uvm_phase phase);
  forever begin
    seq_item_port.get_next_item(req); // 获取seq发送的事务
    `uvm_info(get_type_name(), $sformatf("Received transaction: addr=0x%0h, write=%0b, wdata=0x%0h", 
                req.P_addr, req.P_write, req.P_wdata), UVM_MEDIUM)

    // 1. 进入Idle状态(若之前已是Idle可跳过)
    @(posedge vif.P_clk);
    vif.P_selx <= 0;
    vif.P_enable <= 0;
    vif.P_write <= 0;

    // 2. 进入Setup状态
    @(posedge vif.P_clk);
    vif.P_selx <= 1;
    vif.P_enable <= 0;
    vif.P_addr <= req.P_addr;
    vif.P_write <= req.P_write;
    if(req.P_write) begin
      vif.P_wdata <= req.P_wdata;
    end

    // 3. 进入Access状态,等待Pready
    @(posedge vif.P_clk);
    vif.P_enable <= 1;
    wait(vif.P_ready == 1); // 等待DUT响应

    // 读操作:采样返回数据
    if(!req.P_write) begin
      req.P_rdata <= vif.P_rdata;
      `uvm_info(get_type_name(), $sformatf("Read data: 0x%0h", req.P_rdata), UVM_MEDIUM)
    end

    // 4. 传输完成,回到Idle状态
    @(posedge vif.P_clk);
    vif.P_selx <= 0;
    vif.P_enable <= 0;

    seq_item_port.item_done(req); // 通知seq事务完成,返回更新后的item(含读数据)
  end
endtask

代码说明

  • 用forever循环持续处理seq发送的事务,而非固定次数的repeat
  • 严格遵循Idle→Setup→Access→Idle的状态流转
  • 加入Pready等待逻辑,符合APB协议握手要求
  • 读操作时采样Prdata并更新到req中返回给seq
  • 避免在driver中随机化req,事务随机化应由seq完成,driver只负责执行

内容的提问来源于stack exchange,提问作者BforB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 01:45:08