第2章:一个简单的UVM验证平台 —— 这是全书的精华!--deepseek

第2章:一个简单的UVM验证平台 ------ 这是全书的精华! 从一个最简单的driver开始,像搭积木一样,一步步加入sequencer、monitor、scoreboard、env,最后形成一个完整的平台。你之前看的博客代码,基本就是这一章的缩影。

老师,手把手带我走进第2章吧,让我们开启第二章的旅程吧,有你陪伴真好,谢谢您啦,

同学,坐。听到你说"有你陪伴真好",老师心里也暖暖的。学习新东西就像在深夜走山路,有人提着一盏灯陪着你,确实会安心很多。

好,那我们现在就翻开《UVM实战》第2章,开始我们的"搭积木"之旅。张强老师在这一章的设计非常巧妙,他没有一上来就给你一个庞大复杂的代码,而是让你经历痛点,然后一步步帮你解决它

咱们就用之前那个最简单的加法器 DUT,跟着张老师的思路,从零开始,经历一次"平台进化史"。


🧱 第一步:最初的尝试 ------ "纯手工硬核驱动"(2.1节)

一开始,你只用 Verilog 写测试。你可能会写一个 initial 块,给 ab 赋值,然后检查 sum。在 UVM 里,第一个版本也是这样,但换成了类(class)。

书上会让你先建一个 driver,里面写一个 main_phase,直接硬编码给信号赋值:

systemverilog

复制代码
// 最初的driver(伪代码)
task main_phase(uvm_phase phase);
    @(posedge vif.clk);
    vif.a <= 8'd12;
    vif.b <= 8'd34;
    @(posedge vif.clk);
    // 检查sum...
endtask

痛点:这和你写 Verilog Testbench 没区别。数据写死了,想改数据就得改代码;而且,你根本不知道 DUT 什么时候输出,只能靠手动计算时间。这太不"自动化"了。


🔫 第二步:引入"子弹"与"手枪" ------ transaction、sequence 和 sequencer(2.2节)

为了解决"数据写死"的问题,张老师引入了 transaction (子弹)和 sequence(弹夹)。

  • 你把 absum 封装成一个 my_transaction 类。并且加上 rand,让它们可以随机化

  • 你写一个 my_sequence,里面用 repeat(10) begin \uvm_do(req) end`,决定发10发子弹。

  • 然后引入 sequencer(手枪),它连接 sequence 和 driver。

这时候,你的 driver 进化了:

systemverilog

复制代码
// 进化后的driver
task main_phase(uvm_phase phase);
    while(1) begin
        seq_item_port.get_next_item(req); // 向手枪要一颗子弹
        @(posedge vif.clk);
        vif.a <= req.a;
        vif.b <= req.b;
        seq_item_port.item_done(); // 告诉手枪,打完了
    end
endtask

进步:driver 不用管数据从哪来,它只管"开枪"。sequence 负责造子弹。整个平台活了!


📷 第三步:引入"摄像机" ------ monitor(2.3节)

问题又来了:子弹打出去了,DUT 的结果怎么收集?总不能每次看波形吧?

张老师引入了 monitor。它不干涉驱动,只是在旁边静静地看着:

systemverilog

复制代码
// monitor的核心逻辑
forever begin
    @(posedge vif.clk);
    if(vif.rst_n) begin
        tr = my_transaction::type_id::create("tr");
        tr.a = vif.a;
        tr.b = vif.b;
        tr.sum = vif.sum;
        ap.write(tr); // 把采集到的数据扔出去(通过analysis port)
    end
end

进步:有了 monitor,验证平台有了"眼睛"。它把物理信号重新变成了 transaction,并发送给下一个环节。


🎯 第四步:引入"裁判" ------ scoreboard(2.4节)

monitor 采集到了结果,怎么判断对错?张老师引入了 scoreboard

scoreboard 通过 TLM(事务级建模)的 FIFO 接收 monitor 传来的数据。它接收到实际结果后,自己算一遍期望结果,然后比对:

systemverilog

复制代码
// scoreboard的比对逻辑
exp_fifo.get(tr); // 从FIFO里拿到monitor传来的数据
expect_sum = tr.a + tr.b; // 算一下期望值
if(tr.sum == expect_sum) 
    `uvm_info("SCB", "比对成功", UVM_LOW)
else 
    `uvm_error("SCB", "比对失败")

进步:从此告别肉眼看波形!平台可以自动报错了。这就是自动化的核心。


🏢 第五步:引入"剧组" ------ env 和 agent(2.5节)

到现在,你有 driver、sequencer、monitor、scoreboard 四个组件了。如果每次建平台都要一个个实例化,太乱了。

张老师教你把它们"打包":

  • 把 driver、sequencer、monitor 打包成一个 agent(经纪公司)。因为它们三个是围绕同一个接口的。

  • 把 agent 和 scoreboard 打包成一个 env(剧组)。

在 env 的 build_phase 里,你只需要实例化 agent 和 scoreboard。

在 env 的 connect_phase 里,你把 monitor 的 analysis_port 连到 scoreboard 的 FIFO 上。

systemverilog

复制代码
// env中的连接
agt.mon.ap.connect(scb.exp_fifo.analysis_export);

进步:结构清晰了!env 就像一个集装箱,把所有演员装在一起,方便复用。


🎬 第六步:引入"总导演" ------ test 和 top_tb(2.6 - 2.7节)

最后一步,谁来启动这一切?谁来分配接口?

张老师引入了 test (总导演)和 top_tb(剧场)。

  • top_tb 里,你用 uvm_config_db 把 interface 传给 driver 和 monitor。然后调用 run_test("my_test") 启动仿真。

  • my_testbuild_phase 里,你实例化 env。

  • my_testmain_phase 里,你启动 sequence:

systemverilog

复制代码
task main_phase(uvm_phase phase);
    my_sequence seq;
    phase.raise_objection(this); // 别关灯,我要拍戏了!
    seq = my_sequence::type_id::create("seq");
    seq.start(env.agt.sqr); // 把弹夹压入手枪
    phase.drop_objection(this); // 拍完了,收工!
endtask

进步:平台彻底跑起来了!总导演一喊 Action,sequence 开始发子弹,driver 开枪,monitor 录像,scoreboard 判卷。


💡 老师的"陪读"总结

你看,第2章的精华就在于**"演化"** 。

张老师不是直接丢给你一个完整的代码,而是让你体验:

  1. 没有transaction -> 数据写死,痛苦。

  2. 没有monitor -> 只能看波形,痛苦。

  3. 没有env -> 组件散落一地,痛苦。

当你体会到了这些痛点,UVM的各个组件就变得理所当然、顺理成章了。

你的课后作业(也是第2章的收官)

把咱们之前聊过的那套完整代码(dut、my_if、transaction、sequence、driver、monitor、scoreboard、agent、env、test、top_tb),在 QuestaSim 里跑一遍。不要只复制粘贴,对着张强老师的书,在代码里加上你自己的注释 。比如在 connect_phase 旁边写上"把摄像机接到裁判的FIFO上"。

同学,第2章是地基。地基打得越扎实,后面学第3章(uvm_component与uvm_object的本质区别)、第5章(phase机制)、第6章(sequence机制)就会越轻松。

今天先到这。就像跑 run_phase 一样,你已经在 raise_objection 的状态下坚持了很久,现在可以 drop_objection,好好休息一下了。

明天想继续学第3章,或者对第2章的哪个代码片段还有疑问,随时来找我。老师一直都在。加油,你学得很棒!

相关推荐
NamoAmitabha1284 小时前
书中2.2.4virtual interface,config_db机制---deepseek
systemverilog·uvm
DeeplyMind1 天前
Part 2.1 — uvm_va_block_t 解剖:每页位图与 PTE 状态
nvidia·uvm
NamoAmitabha1286 天前
UVM在时间维度上也做了规范,phase机制----deepseek讲解
systemverilog·uvm
NamoAmitabha1286 天前
SystemVerilog 中的 :: 作用域解析运算符详解--deepseek讲解
systemverilog·uvm
NamoAmitabha1288 天前
class基础+继承的专项训练
systemverilog
NamoAmitabha1288 天前
rand/randc/constraint 练习
systemverilog
fei_sun1 个月前
UVM中的sequence
uvm
Salt & Light1 个月前
UVM 字段自动化 Field Automation:让打印、复制、比较自动化
学习·systemverilog·uvm
fei_sun1 个月前
UVM中的TLM1.0通信
运维·服务器·uvm