本文作为一个入门的指导吧,当时自己刚刚接触UVM 的时候一头雾水,虽然能够看明白代码但是始终没有自己运行起来。

接上文的UVM 环境配置,按照这个配置好之后可以按照本文运行第一个UVM验证平台,需要用到的文件和层级关系如下:

├── 2.2.1
│   ├── filelist.f
│   ├── Makefile
│   ├── my_driver.sv
│   └── top_tb.sv
└── dut
    └── dut.sv

书本中有对代码较为详细的说明,这里不再赘述。

// dut.sv
`timescale 1ns/1ps
module dut(clk,
           rst_n, 
           rxd,
           rx_dv,
           txd,
           tx_en);
input clk;
input rst_n;
input[7:0] rxd;
input rx_dv;
output [7:0] txd;
output tx_en;

reg[7:0] txd;
reg tx_en;

always @(posedge clk) begin
   if(!rst_n) begin
      txd <= 8'b0;
      tx_en <= 1'b0;
   end
   else begin
      txd <= rxd;
      tx_en <= rx_dv;
   end
end
endmodule
// top_tb.sv
`timescale 1ns/1ps
`include "uvm_macros.svh"

import uvm_pkg::*;
`include "my_driver.sv"

module top_tb;

reg clk;
reg rst_n;
reg[7:0] rxd;
reg rx_dv;
wire[7:0] txd;
wire tx_en;

dut my_dut(.clk(clk),
           .rst_n(rst_n),
           .rxd(rxd),
           .rx_dv(rx_dv),
           .txd(txd),
           .tx_en(tx_en));

initial begin
   my_driver drv;
   drv = new("drv", null);
   drv.main_phase(null);  // main_phase 类似于主函数
   $finish();
end

initial begin
   clk = 0;
   forever begin
      #100 clk = ~clk;
   end
end

initial begin
   rst_n = 1'b0;
   #1000;
   rst_n = 1'b1;
end
// 下面的代码是为了生成波形
initial begin 
    $fsdbDumpfile("top_tb.fsdb");
    $fsdbDumpvars(0,top_tb);
    $fsdbDumpMDA();
end

endmodule
// my_driver.sv
`ifndef MY_DRIVER__SV
`define MY_DRIVER__SV
class my_driver extends uvm_driver;

   function new(string name = "my_driver", uvm_component parent = null);
      super.new(name, parent);
   endfunction
   extern virtual task main_phase(uvm_phase phase);  //task可以有时序
endclass

task my_driver::main_phase(uvm_phase phase);
   top_tb.rxd <= 8'b0; 
   top_tb.rx_dv <= 1'b0;
   while(!top_tb.rst_n)
      @(posedge top_tb.clk);
   for(int i = 0; i < 256; i++)begin
      @(posedge top_tb.clk);
      top_tb.rxd <= $urandom_range(0, 255);
      top_tb.rx_dv <= 1'b1;
      `uvm_info("my_driver", "data is drived", UVM_LOW)
   end
   @(posedge top_tb.clk);
   top_tb.rx_dv <= 1'b0;
endtask
`endif
vcs		:
		vcs 	\
		-f filelist.f 	\
		-LDFLAGS -Wl,--no-as-needed          \
		-fsdb -full64 -R +vc +v2k -sverilog -debug_all \
		-ntb_opts uvm-1.1	\
		-timescale=1ns/1ps
verdi 	:
		verdi -sv -f filelist.f -ssf *.fsdb &
clean	:
		rm -rf *.log simv *.daidir csrc *.key DVEfiles *.vpd *.conf *.rc *.fsdb verdiLog
# filelist.f
+incdir+$UVM_HOME/src
$UVM_HOME/src/uvm_pkg.sv
../dut/dut.sv
top_tb.sv
my_driver.sv

在Makefile 目录下,运行make vcs :

运行 make verdi得到波形: