当前位置:首页 > EDA > 电子设计自动化
[导读]在SoC/ASIC验证中,UVM(Universal Verification Methodology) 已成为芯片流片前的“最后防线”。很多初学者卡在“组件怎么连”、“sequence怎么跑”。本文将基于SystemVerilog,手把手带你走完从driver到scoreboard的最小闭环验证流程。



在SoC/ASIC验证中,UVM(Universal Verification Methodology) 已成为芯片流片前的“最后防线”。很多初学者卡在“组件怎么连”、“sequence怎么跑”。本文将基于SystemVerilog,手把手带你走完从driver到scoreboard的最小闭环验证流程。


一、UVM验证平台核心架构(先懂“骨架”)


一个标准的UVM平台遵循严格的层次结构,数据流自上而下:


1.  Sequencer:生成高层次的transaction(事务)。

2.  Driver:从Sequencer“拉”取transaction,并驱动到DUT(被测设计) 的接口上(转换成信号)。

3.  Monitor:被动监视接口信号,将信号采集并还原成transaction。

4.  Scoreboard:从Monitor拿到实际transaction,与自己预测的期望值进行比对。


核心原则:Driver是“发号施令者”,Monitor是“情报员”,Scoreboard是“裁判”。


二、实战第一步:定义Transaction(数据包)


Transaction是所有组件传递的“标准信封”。假设我们要验证一个简单的APB总线写操作。

// my_transaction.sv

class my_transaction extends uvm_sequence_item;

   rand bit [31:0] addr;

   rand bit [31:0] data;

   rand bit          write; // 1=写, 0=读


   `uvm_object_utils_begin(my_transaction)

       `uvm_field_int(addr, UVM_ALL_ON)

       `uvm_field_int(data, UVM_ALL_ON)

       `uvm_field_int(write, UVM_ALL_ON)

   `uvm_object_utils_end


   function new(string name = "my_transaction");

       super.new(name);

   endfunction

endclass


关键点:必须继承uvm_sequence_item,并使用uvm_object_utils宏注册,否则UVM工厂机制无法识别。


三、Driver:把“指令”变成“电信号”


Driver负责与DUT接口“硬碰硬”。它需要virtual interface来访问DUT的信号。


1. 接口定义(Interface)


// my_if.sv

interface my_if (input logic clk);

   logic [31:0] paddr;

   logic [31:0] pwdata;

   logic        pwrite;

   logic        psel;

   logic        penable;

   // ... 其他信号

endinterface



2. Driver实现


// my_driver.sv

class my_driver extends uvm_driver #(my_transaction);

   `uvm_component_utils(my_driver)

   

   virtual my_if vif; // 关键:虚拟接口句柄


   task run_phase(uvm_phase phase);

       forever begin

           seq_item_port.get_next_item(req); // 从sequencer取transaction

           drive_one_pkt(req);             // 驱动到接口

           seq_item_port.item_done();

       end

   endtask


   task drive_one_pkt(my_transaction tr);

       @(posedge vif.clk);

       vif.psel   <= 1'b1;

       vif.pwrite <= tr.write;

       vif.paddr  <= tr.addr;

       if (tr.write) vif.pwdata <= tr.data;

       @(posedge vif.clk);

       vif.penable <= 1'b1;

       @(posedge vif.clk);

       vif.psel   <= 1'b0;

       vif.penable <= 1'b0;

   endtask

endclass


避坑指南:seq_item_port.get_next_item()是阻塞调用,Driver会一直等到Sequencer有数据才往下跑。


四、Monitor:从信号中“破案”


Monitor与Driver类似,但它不驱动信号,只采样。它的产出是analysis_port。

// my_monitor.sv

class my_monitor extends uvm_monitor;

   `uvm_component_utils(my_monitor)

   

   virtual my_if vif;

   uvm_analysis_port #(my_transaction) ap; // 广播端口


   function void build_phase(uvm_phase phase);

       super.build_phase(phase);

       ap = new("ap", this);

   endfunction


   task run_phase(uvm_phase phase);

       forever begin

           my_transaction tr = my_transaction::type_id::create("tr");

           @(posedge vif.clk iff vif.psel && vif.penable);

           tr.addr  = vif.paddr;

           tr.data  = vif.pwdata;

           tr.write = vif.pwrite;

           ap.write(tr); // 广播给所有订阅者(如scoreboard)

       end

   endtask

endclass



五、Scoreboard:最终的“法官”


Scoreboard负责预测与比对。它订阅Monitor的数据,同时可能直接访问DUT的寄存器模型或参考模型。

// my_scoreboard.sv

class my_scoreboard extends uvm_scoreboard;

   `uvm_component_utils(my_scoreboard)

   

   uvm_analysis_imp #(my_transaction, my_scoreboard) analysis_export;

   bit [31:0] ref_mem [32'h0000:32'hFFFF]; // 参考模型(内存)


   function void build_phase(uvm_phase phase);

       analysis_export = new("analysis_export", this);

   endfunction


   // 必须实现的write函数

   function void write(my_transaction tr);

       if (tr.write) begin // 写操作

           ref_mem[tr.addr] = tr.data; // 更新参考模型

       end else begin // 读操作

           if (ref_mem[tr.addr] != tr.data) begin // 关键:比对

               `uvm_error("SCB_ERR",

                   $sformatf("Addr=0x%0h, Exp=0x%0h, Got=0x%0h",

                             tr.addr, ref_mem[tr.addr], tr.data))

           end

       end

   endfunction

endclass


核心逻辑:analysis_export收到Monitor发来的transaction后,调用write()函数。在这里进行期望值(ref_mem) 与实际值(tr.data) 的比较。


六、Env与Test:把积木拼起来


1. Environment(胶水层)


class my_env extends uvm_env;

   my_driver    drv;

   my_monitor   mon;

   my_scoreboard scb;

   uvm_agent    agent; // 通常用agent封装drv/mon

   // ... 省略agent定义 ...


   function void build_phase(uvm_phase phase);

       drv = my_driver::type_id::create("drv", this);

       mon = my_monitor::type_id::create("mon", this);

       scb = my_scoreboard::type_id::create("scb", this);

   endfunction


   function void connect_phase(uvm_phase phase);

       mon.ap.connect(scb.analysis_export); // 关键连接!

   endfunction

endclass



2. Test与Sequence


class base_test extends uvm_test;

   my_env env;

   `uvm_component_utils(base_test)

   // ... build_phase创建env ...


   task run_phase(uvm_phase phase);

       my_sequence seq = my_sequence::type_id::create("seq");

       phase.raise_objection(this);

       seq.start(env.agent.sequencer); // 启动sequence

       phase.drop_objection(this);

   endtask

endclass



七、调试与避坑指南


1.  Factory Override失效:确保create()使用的是type_id::create(),且字符串名字匹配。

2.  Driver没反应:检查Test中是否raise_objection(),如果没有,仿真会立刻结束。

3.  Scoreboard收不到数据:99%是connect_phase没连对,确认monitor.ap.connect(scoreboard.analysis_export)。

4.  看波形调试:在波形窗口中,优先看Driver的vif信号,确认激励是否正确发出;再看Scoreboard内部的ref_mem和比对结果。


八、结语


搭建UVM平台的核心是“数据流”思维:Sequence → Sequencer → Driver → DUT → Monitor → Scoreboard。掌握了从Driver的信号驱动到Scoreboard的数据比对,你就打通了UVM验证的“任督二脉”。下一步,可以进阶学习寄存器模型(RAL) 与覆盖率(Coverage)。


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读

在芯片验证领域,UVM(Universal Verification Methodology)已成为行业标准,其核心优势在于通过模块化设计实现验证环境的可复用性。然而,当验证场景涉及复杂随机约束时,约束冲突导致的随机化失...

关键字: SystemVerilog 芯片验证 UVM

在复杂SoC验证中,某些corner case因触发条件苛刻,常被验证团队视为"不可能覆盖"的场景。这些隐藏的缺陷往往在流片后暴露,导致高额修复成本。本文将介绍如何通过UVM回调机制与断言注入技术,构建智能化的覆盖率闭环...

关键字: UVM Corner Case

在SoC(System on Chip)验证中,寄存器级验证是确保芯片功能正确性的核心环节。UVM(Universal Verification Methodology)凭借其标准化的寄存器模型(RAL)和层次化验证架构...

关键字: UVM SoC寄存器
关闭