UVM学习之路(3)— 基于UVM的第一个Hello程序

UVM学习之路(3)— 基于UVM的第一个Hello程序

一、前言

UVM( Universal Verification Methodology),是一个标准化的用于验证设计的方法学。其正式版是在2011年2月由Accellera推出的, 得到了Sysnopsys、 Mentor和Cadence 的支持。 UVM几乎完全继承了OVM, 同时又采纳了Synopsys在VMM中的寄存器解决方案RAL。 同时, UVM还吸收了VMM中的一些优秀的实现方式。 可以说, UVM继承了VMM和OVM的优点, 克服了各自的缺点, 代表了验证方法学的发展方向。

二、编写源码

新建hello.sv文件,编写代码如下所示

`timescale 1ns/1ps

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

class hello_test extends uvm_test;
    `uvm_component_utils(hello_test)

    function new(string name = "hello_test", uvm_component parent = null);
        super.new(name, parent);
        `uvm_info("hello_test", "new is called", UVM_LOW);
    endfunction

    virtual task main_phase(uvm_phase phase);
        phase.raise_objection(this);
        `uvm_info("hello_test", "main_phase is called", UVM_LOW);
        #100;
        `uvm_info("hello_test", "main_phase is finish", UVM_LOW);
        phase.drop_objection(this);
    endtask

endclass


module tb;

    initial begin;
        run_test("hello_test");
    end

endmodule

三、编译运行

使用如下命令进行编译,-ntb_opts uvm-1.2选项表示要引入UVM1.2的包,当然也可以选择使用1.0或1.1版本的,但是要注意这个选项不可缺少

vcs -full64 -sverilog -ntb_opts uvm-1.2 -timescale=1ns/1ps hello.sv 

编译结果如下所示,没有报错
,
然后进行仿真运行

./simv

运行结果如下所示,可以看到,UVM的版本为1.2,我们想要的打印信息都有了,同时也在最后报告了仿真时间
在这里插入图片描述

四、使用VSCode

我们可以使用VSCode来更好地做开发,关于VSCode环境的建立参考:
在Win10上使用SSH远程连接Linux搭建VSCode开发环境
搭建好后我们可以在插件中搜索systemverilog来安装对sv和uvm语法支持的插件
在这里插入图片描述
添加语法高亮后可以看到如下所示
在这里插入图片描述

五、Makefile

然后我们也也可以编写Makefile来帮助编译运行,如下所示

#---------------------------------------------------------------------------
# files options
#---------------------------------------------------------------------------
DFILES  += 
VFILES  += hello.sv


#---------------------------------------------------------------------------
# tool options
#---------------------------------------------------------------------------
TOOL_CMD	= vcs -full64
COMP_OPT	= -sverilog -debug_access+all -lca -kdb -fsdb +define+FSDB -timescale=1ns/1ps 
UVM_OPT		= -ntb_opts uvm-1.1

comp:
	$(TOOL_CMD) $(COMP_OPT) $(UVM_OPT) $(DFILES) $(VFILES)

run:
	./simv +UVM_NO_RELNOTES
	
rung:
	./simv +UVM_NO_RELNOTES -gui=verdi

verdi:
	verdi tb.fsdb

clean:
	rm -rf csrc simv simv.daidir *.fsdb novas.* ucli.key
	rm -rf *.log* *.vpd *.h urgReport verdiLog

运行结果如下所示
在这里插入图片描述

  • 9
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
以下是一个简单的异步FIFO的UVM验证程序示例: 首先定义FIFO的接口: ```systemverilog interface fifo_if(input logic clk); logic [7:0] data_in; logic [7:0] data_out; logic wr_en; logic rd_en; logic full; logic empty; endinterface ``` 接着定义FIFO的实现: ```systemverilog module fifo(input logic clk, rst, input logic [7:0] data_in, input logic wr_en, rd_en, output logic [7:0] data_out, output logic full, empty); logic [7:0] buffer [0:7]; int wr_ptr = 0; int rd_ptr = 0; int count = 0; always_ff @(posedge clk) begin if (rst) begin buffer <= '0; wr_ptr <= 0; rd_ptr <= 0; count <= 0; end else begin if (wr_en && !full) begin buffer[wr_ptr] <= data_in; wr_ptr <= (wr_ptr == 7) ? 0 : wr_ptr + 1; count <= count + 1; end if (rd_en && !empty) begin data_out <= buffer[rd_ptr]; rd_ptr <= (rd_ptr == 7) ? 0 : rd_ptr + 1; count <= count - 1; end end end assign full = (count == 8); assign empty = (count == 0); endmodule ``` 接着定义FIFO的测试: ```systemverilog class tb_fifo extends uvm_test; fifo_if dut; uvm_blocking_put_port #(byte) put_port; uvm_blocking_get_port #(byte) get_port; uvm_analysis_port #(byte) analysis_port; function new(string name, uvm_component parent); super.new(name, parent); endfunction virtual function void build_phase(uvm_phase phase); super.build_phase(phase); dut = new("dut", null); put_port = new("put_port", this); get_port = new("get_port", this); analysis_port = new("analysis_port", this); // Connect the DUT to the testbench dut.clk = clk; put_port.connect(dut); get_port.connect(dut); endfunction virtual task run_phase(uvm_phase phase); // Test FIFO with 10 random data items for (int i = 0; i < 10; i++) begin byte data = $random; put_data(data); get_data(data); end endtask virtual task put_data(byte data); // Put data into FIFO if (put_port.try_put(data)) begin `uvm_info(get_type_name(), $sformatf("Put data: %0h", data), UVM_LOW) end else begin `uvm_error(get_type_name(), "Failed to put data into FIFO") end endtask virtual task get_data(byte expected_data); // Get data from FIFO byte data; if (get_port.try_get(data)) begin `uvm_info(get_type_name(), $sformatf("Got data: %0h", data), UVM_LOW) if (data == expected_data) begin analysis_port.write(data); end else begin `uvm_error(get_type_name(), "Data mismatch") end end else begin `uvm_error(get_type_name(), "Failed to get data from FIFO") end endtask endclass ``` 最后,我们需要定义一个分析器来检查FIFO的输出是否与输入匹配: ```systemverilog class fifo_analyzer extends uvm_analysis_port #(byte); function new(string name, uvm_component parent); super.new(name, parent); endfunction virtual function void write(byte t); // Check if the output matches the input if (t != dut.data_in) begin `uvm_error(get_type_name(), "Output does not match input") end endfunction endclass ``` 现在我们可以运行测试来验证FIFO的正确性: ```systemverilog module test; initial begin uvm_config_db #(virtual fifo_if)::set(null, "*", "dut", dut); uvm_config_db #(uvm_object_wrapper)::set(null, "tb_fifo.*", "default_sequence", fifo_sequence::type_id::get()); uvm_top.print_topology(); run_test(); end endmodule ``` 这个测试程序会运行FIFO序列,然后检查输出是否与输入匹配。如果没有错误,测试就通过了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值