最近的工作中需要用UVM平台去仿真软件同事写的C程序,虽然只要用EDA同事已经搭好的UVM平台稍微改改就行,但对于我这种从未接触过UVM甚至都没用过System Verilog的纯FPGA工程师来说还是很有难度的,因为我对这方面一点概念都没有。

基于此,想着边用边学,就在网上找了一些资料学习。看到了下面这篇文章:

从零开始,搭建一个简单的UVM验证平台(一)

看着还是挺简单的,但亲自动手去做一遍,还是费了很大功夫的。虽然这个博客里提供了大部分代码,但并没有写一步步地怎么做。另外,特别注意,这个博客系列文章里的代码有一些小问题,会导致结果出不来,我就遇到了好几个坑。

下面就记录下,我一步步的过程,并附上所以源码和相应的截图。

第1步:把这几个模块代码拷贝下来

dut.v

module dut(
  input             clk           , 
  input             rstn          ,
  input      [7:0]  data_i        ,
  input             data_i_valid  ,
  output reg [7:0]  data_o        ,
  output reg        data_o_valid
);
 
always @(posedge clk)begin
  if(!rstn)begin
    data_o       <= 8'd0;
    data_o_valid <= 1'b0;
  end
  else begin
    data_o       <= data_i;
    data_o_valid <= data_i_valid;
  end
end
 
endmodule 

my_driver.sv

//`ifndef _MY_DRIVER
//`define _MY_DRIVER


`include "uvm_macros.svh"
import uvm_pkg::*;
 
class my_driver extends uvm_driver;
   `uvm_component_utils(my_driver); // 注册
    function new(string name = "my_driver", uvm_component parent = null);
        super.new(name, parent);
        `uvm_info("my_driver", "new is called.", UVM_LOW)
    endfunction
 
    extern virtual task main_phase(uvm_phase phase); 
endclass


task my_driver::main_phase(uvm_phase phase);
   phase.raise_objection(this);
   `uvm_info("my_driver", "main phase is called.", UVM_LOW);
    top_tb.data_i       <= 8'd0;
    top_tb.data_i_valid <= 1'b0;
    while(!top_tb.rstn)
      @(posedge top_tb.clk);
    for(int i = 0; i < 256; i = i+1)begin
      @(posedge top_tb.clk)
      top_tb.data_i <= $urandom_range(0,255);
      top_tb.data_i_valid <= 1'b1;
      `uvm_info("my_driver", "data is drived.", UVM_LOW) 
    end
    @(posedge top_tb.clk);
    top_tb.data_i_valid <= 1'b0;
    phase.drop_objection(this);
endtask


//`endif

top_tb.sv

`timescale 1ns/1ps
`include "uvm_macros.svh" //这是UVM中的一个文件,包含了众多宏定义
 
import uvm_pkg::*;        //只有导入了这个库,编译器在编译my_driver.sv文件时才会认识其中继承的uvm_driver等类名
 
//`include "my_driver.sv"
 
module top_tb;
 
reg clk,rstn;
reg  [7:0] data_i;
reg  data_i_valid;
wire [7:0] data_o;
wire data_o_valid;
 
dut my_dut(
  .clk            (clk   )        ,
  .rstn           (rstn  )        ,
  .data_i         (data_i)        ,
  .data_o         (data_o)        ,
  .data_i_valid   (data_i_valid)  ,
  .data_o_valid   (data_o_valid)
);

//initial begin
//  my_driver drv; // instance
//  drv = new("drv", null);
//  drv.main_phase(null);
//  $finish();
//end

initial begin
    run_test("my_driver");
end 


initial begin
  clk = 0;
  forever begin
    #100 clk = ~clk;
  end
end
 
initial begin
  rstn = 1'b0;
  #1000
  rstn = 1'b1;
end

initial begin
    $fsdbDumpfile("tb.fsdb");
    $fsdbDumpvars;
end
 
endmodule

第2步:产生filelist

find ./ -name "*.*v" > filelist.f

第3步:产生makefile

这个makefile,我是在网上找了一些资料作为参考,写了个简单能用的。

#--------------------------------------------------------------------------------------
all  : clean vcs
#--------------------------------------------------------------------------------------
vcs   :
	vcs   	  -f filelist.f \
			  -ntb_opts uvm \
              -timescale=1ns/1ps \
              -full64 -R  +vc  +v2k  -sverilog \
			  -debug_access \
	          -kdb \
	          -l simv.log &
#--------------------------------------------------------------------------------------
verdi  :
	verdi -f filelist.f -ssf tb.fsdb &
#--------------------------------------------------------------------------------------
clean  :
	 rm  -rf  *~  core  csrc  simv*  vc_hdrs.h  ucli.key  urg* *.log  novas.* *.fsdb*  
	 rm  -rf  64* DVEfiles *.vpd  verdiLog verdi_config_file
#---------------------------------------------------------------------------------------

第4步:编译

《从零开始,搭建一个简单的UVM验证平台》实操-LMLPHP

所有文件如上图所示,在当前路径下执行如下命令进行编译:

make all

或者

make vcs

第5步:查看结果

编译结果如下图所示:

《从零开始,搭建一个简单的UVM验证平台》实操-LMLPHP

也可以打开simv.log查看编译结果,还可以用make verdi查看波形。


附:问题记录

我现在学到了第三篇,也就是下面这篇博客,遇到了几个问题,卡了我好几天才找到原因,也一并记录在此,方便后来人!

从零开始,搭建一个简单的UVM验证平台(三)

第一个问题

《从零开始,搭建一个简单的UVM验证平台》实操-LMLPHP

第二个问题,这个是巨坑啊,编译的时候发现会卡住,一直找不到原因,差点让我UVM从入门到放弃,花了几天的时间各种找资料各种加log才定位到这里。啊。。。超级想骂人!!!

《从零开始,搭建一个简单的UVM验证平台》实操-LMLPHP

05-09 03:29