赞
踩
最近的工作中需要用UVM平台去仿真软件同事写的C程序,虽然只要用EDA同事已经搭好的UVM平台稍微改改就行,但对于我这种从未接触过UVM甚至都没用过System Verilog的纯FPGA工程师来说还是很有难度的,因为我对这方面一点概念都没有。
基于此,想着边用边学,就在网上找了一些资料学习。看到了下面这篇文章:
看着还是挺简单的,但亲自动手去做一遍,还是费了很大功夫的。虽然这个博客里提供了大部分代码,但并没有写一步步地怎么做。另外,特别注意,这个博客系列文章里的代码有一些小问题,会导致结果出不来,我就遇到了好几个坑。
下面就记录下,我一步步的过程,并附上所以源码和相应的截图。
- 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
- //`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
- `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
find ./ -name "*.*v" > filelist.f
这个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
- #---------------------------------------------------------------------------------------
-
所有文件如上图所示,在当前路径下执行如下命令进行编译:
- make all
-
- 或者
-
- make vcs
编译结果如下图所示:
也可以打开simv.log查看编译结果,还可以用make verdi查看波形。
我现在学到了第三篇,也就是下面这篇博客,遇到了几个问题,卡了我好几天才找到原因,也一并记录在此,方便后来人!
第一个问题
第二个问题,这个是巨坑啊,编译的时候发现会卡住,一直找不到原因,差点让我UVM从入门到放弃,花了几天的时间各种找资料各种加log才定位到这里。啊。。。超级想骂人!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。