sometimes,自己寫了塊RTL,想快速地輸入激勵看一下結(jié)果耸采;根據(jù)UVM的套路一步步的搭建看來是太費勁了兴泥;本文就給出了一種簡單方法,可以快速簡單的給出激勵虾宇;
1 RTL
本文的DUT如下,file名字test_md.v
其實現(xiàn)的功能很簡單如绸,通過一組BUS讀寫寄存器嘱朽;
module test_md(
input clk ,
input rst_n,
input rd ,
input wr ,
input [1:0] addr ,
input [31:0] wdata,
output reg ack ,
output reg [31:0] rdata
);
reg [31:0] cfg_test0;
reg [31:0] cfg_test1;
reg [31:0] cfg_test2;
reg [31:0] cfg_test3;
always@(posedge clk or negedge rst_n) begin
if(rst_n==1'b0) begin
cfg_test0<=32'b0;
cfg_test1<=32'b0;
cfg_test2<=32'b0;
cfg_test3<=32'b0;
end
else if(wr) begin
if(addr==2'd0) cfg_test0<=wdata;
if(addr==2'd1) cfg_test1<=wdata;
if(addr==2'd2) cfg_test2<=wdata;
if(addr==2'd3) cfg_test3<=wdata;
end
end
always@(posedge clk or negedge rst_n) begin
if(rst_n==1'b0)
cfg_test0<=32'b0;
else if(rd) begin
case(addr)
2'd0: rdata<=cfg_test0;
2'd1: rdata<=cfg_test1;
2'd2: rdata<=cfg_test2;
2'd3: rdata<=cfg_test3;
endcase
end
end
always@(posedge clk or negedge rst_n) begin
if(rst_n==1'b0)
ack<=1'b0;
else
ack<=wr | rd;
end
endmodule
2 TB and CASE
這里TB和CASE用一個文件實現(xiàn),名字為top_tb.sv
代碼如下:
`timescale 1ns/1ps //part 1
`include "test_md.v" //part 2
interface acc_if(input clk); //part 3
bit rd ;
bit wr ;
bit [1:0] addr ;
bit [31:0] wdata;
bit [31:0] rdata;
bit ack ;
endinterface
class acc_drv; //part 4
virtual acc_if vif;
function new(virtual acc_if cc_if);
this.vif=cc_if;
endfunction
extern task init();
extern task write(bit[1:0] addr,bit[31:0] wdata);
extern task read (bit[1:0] addr,output bit[31:0] rdata);
endclass;
task acc_drv::init();
vif.wr =0;
vif.rd =0;
vif.addr =0;
vif.wdata=0;
endtask
task acc_drv::write(bit[1:0] addr, bit[31:0] wdata);
repeat(1)@(vif.clk);
vif.wr =1;
vif.addr =addr;
vif.wdata =wdata;
repeat(1)@(vif.clk);
vif.wr =0;
vif.addr =0;
endtask
task acc_drv::read(bit[1:0] addr, output bit[31:0] rdata);
repeat(1)@(vif.clk);
vif.rd =1;
vif.addr =addr;
repeat(1)@(vif.clk);
vif.rd =0;
vif.addr =0;
rdata =vif.rdata;
endtask
module top_tb; //part 5
bit clk;
bit rst_n;
bit [31:0] rdata;
acc_if u_acc_if(clk);
test_md U_TEST_MD(
.clk (clk ),
.rst_n (rst_n ),
.rd (u_acc_if.rd ),
.wr (u_acc_if.wr ),
.addr (u_acc_if.addr ),
.wdata (u_acc_if.wdata ),
.ack (u_acc_if.ack ),
.rdata (u_acc_if.rdata )
);
initial begin
clk=0;
forever #5 clk=~clk;
end
initial begin
rst_n=0;
#30 rst_n=1'b1;
end
initial begin
acc_drv bus;
bus=new(u_acc_if);
bus.init();
wait(rst_n);
bus.write(2'b0,32'hA);
bus.read(2'b0,rdata);
if(rdata==32'hA) begin
$display("compare ok!!");
end
else begin
$display("compare failed!!");
end
#400 $finish();
end
initial begin
$fsdbDumpfile("top_tb.fsdb");
$fsdbDumpvars;
end
endmodule
分為5個大部分:
- timescale
- include RTL
- interface定義
- class定義怔接,主要定義驅(qū)動class及其task與function:
- 注意要聲明一個virtual interface搪泳,類型和part 3一致;
- new函數(shù)中對virtual interface賦值扼脐;
- module定義岸军,這里將class和interface例化,并完成主要功能
- 聲明clk,rst_n和其他變量瓦侮;
- 例化一個interface實體艰赞;
- 例化DUT,并和interface實體相連肚吏;
- clk和rst的產(chǎn)生方妖;
- 生成class句柄,new時候?qū)嶓winterface賦值給virtual interface
- 使用class中的task驅(qū)動DUT
- 比較結(jié)果罚攀,finish
- dump波形
3 makefile
case := top_tb
file := $(addsuffix .sv,$(case))
comp:
vcs -sverilog -debug_access -kdb $(file) -f "xxx.f" -l comp.log +lint=TFIPC-L
sim:
./simv -l sim.log
run: comp sim
verdi:
verdi -dbdir simv.daidir -ssf top_tb.fsdb
clean:
rm -r *.log *fsdb* *.key csrc verdiLog simv.daidir simv *.rc *.conf
將test_md.v党觅,top_tb.sv和makefile這3個file放在一個路徑雌澄;執(zhí)行下面命令即可完成simulation
> make run
4 結(jié)束語
SV在RTL驗證中功能不是死板的,可以很靈活地完成各種想要驗證的內(nèi)容杯瞻;