首先得在Linux下配置好VCS和Verdi的环境,这个方面我就不再这里赘述了,你可以在命令行输下which vcs和which verdi看有没有信息,有信息的话就说明已经安装。
要在Linux下用VCS仿真和Verdi看波形,首先需要3个主要的文件,rtl设计文件,也就是Verilog的设计.v文件;testbench文件,也就是给你的设计模块产生激励,用来测试发信号的文件,也是.v文件;还有就是file list文件,就是把你的testbench和rtl文件在文件中列出来,这样编译啥的就不用一个个都打出来,它自己根据列表文件自己去找。我刚开始做的是最简单的Uart实验,所以我的三个文件是:Uart_byte_tx.v, Uart_byte_tx_tb.v, Uart_rtl.f,三个文件我都放在APB_Uart文件夹下面。
Testbench和设计文件我就不多说了,我写的是一个Uart的发送程序,初学者做实验可以参考。testbench代码如下,名字为uart_byte_tx_tb.v
`timescale 1ns / 1ns
module uart_byte_tx_tb( );
reg clk;
reg reset_n;
reg [7:0]data;
reg send_en;
reg [3:0]baud_set;
wire uart_tx;
wire tx_done;
uart_byte_tx uart_byte_tx_inst(
.clk(clk),
.reset_n(reset_n),
.data(data),
.send_en(send_en),
.baud_set(baud_set),
.uart_tx(uart_tx),
.tx_done(tx_done)
);
initial clk=0;
always #10 clk = ~clk;
initial begin
$fsdbDumpfile("/home/APB_Uart/uart_wav.fsdb");
$fsdbDumpvars(0);
end
initial begin
reset_n = 0;
data = 0;
send_en = 0;
baud_set = 0;
#200;
reset_n = 1;
data = 8'h87;
send_en = 1;
baud_set = 4;
@(posedge tx_done);
send_en = 0;
#100000;
data = 8'h48;
send_en = 1;
baud_set = 4;
@(posedge tx_done);
send_en = 0;
#100000;
$stop;
end
endmodule
设计代码名字为uart_byte_tx.v如下:
module uart_byte_tx(
clk,
reset_n,
data,
send_en,
baud_set,
uart_tx,
tx_done
);
input clk;
input reset_n;
input [7:0]data;
input send_en;
input [3:0]baud_set;
output reg tx_done;
output reg uart_tx;
//reg send_en;
reg [4:0]counter;
reg [17:0]counter1;//时钟分频得到不同的频率
reg [17:0]bps_DR;
wire bps_clk;
assign bps_clk = (counter1 == 1);
always@(*)
case(baud_set)
0: bps_DR = 1000000000/9600/20;
1: bps_DR = 1000000000/19200/20;
2: bps_DR = 1000000000/38400/20;
3: bps_DR = 1000000000/57600/20;
4: bps_DR = 1000000000/115200/20;
default: bps_DR = 1000000000/9600/20;
endcase
always@(posedge clk or negedge reset_n)
if(!reset_n)
counter1 <= 0;
else if(send_en) begin
if(counter1 == bps_DR - 1 )
counter1 <= 0;
else
counter1 <= counter1 + 1'b1;
end
else
counter1 <= 0;
//数据位数定时器
always@(posedge clk or negedge reset_n)
if(!reset_n)
counter <= 0;
else if(send_en) begin
if(bps_clk)begin
if(counter == 12 )
counter <= 0;
else
counter <= counter + 1'b1;
end
end
else
counter = 0;
//counter = bsp_cnt
//counter div_cnt
//数据传输
always@(posedge clk or negedge reset_n)
if(!reset_n)begin
tx_done = 0;
uart_tx = 1;
end
else begin
case(counter)
1:uart_tx = 0;
2: uart_tx = data[0];
3: uart_tx = data[1];
4: uart_tx = data[2];
5: uart_tx = data[3];
6: uart_tx = data[4];
7: uart_tx = data[5];
8: uart_tx = data[6];
9: uart_tx = data[7];
10: uart_tx = 1;
11: uart_tx = 1;
default:uart_tx = 1;
endcase
end
always@(posedge clk or negedge reset_n)
if(!reset_n)
tx_done = 0;
else if((bps_clk == 1) && (counter == 10))
tx_done <= 1;
else
tx_done = 0;
endmodule
接着说一下filelist的编写。
1.编写filelist,进入到你的rtl设计文件下,也就是APB_Uart下面,命令 find -name “*.v” > Uart_rtl.f ,然后打开文件 gvim Uart_rtl.f 你会看到你这文件夹下面的.v文件都写入到了filelist中,如图
2.然后就可以用VCS编译文件了,这里简单介绍一下VCS的主要指令:
指令 | 介绍 |
---|---|
-sverilog | 用VCS编译,支持SystemVerilog |
-full64 | 这是你安装的VCS的版本,如果是64位需要此指令,否则会错 |
-R | 表示编译完成之后直接运行可执行文件,如果缺少此指令,编译完成后VCS就会退出,如果你要生成fsdb波形文件的话就需要这个指令,否则生成不了这个文件。 |
-debug_all | 表示调用UCLI和DVE,并为进一步调试DVE建立所需要的文档,继续用VCS看波形用此命令 |
-debug_access | 这个命令是要生成fsdb波形,后面用Verdi看波形就要用到它了 |
–gui | 调用 VCS 的图形界面 |
3.需要调用VCS生成simv指令为
vcs -full64 -f Uart_rtl.f -timescale=1ns/1ns -sverilog -debug_access -kdb -R -l ./output.log
或者:
vcs -full64 -sverilog -debug_all -lca -kdb -timescale=1ns/1ps <verilog_file_name>
上述指令中:-debug_all在新版本中已经过时,用_debug_access代替;-l ./output表示生成log文件的名字是output并保存在当前文件夹;-sverilog选项开启SystemVerilog支持;添加-kdb选项支持输出KDB格式的数据,用于与Verdi在交互模式交换数据,而KDB格式属于"Limited Customer Availability"特性,必须通过-lca选项开启;-f Uart_rtl.f这是从你的filelist下开始编译;vcs -full64一定要加-full64这是版本号,不加很可能也会报错,说是找不到VCS;-timescale=1ns/1ps这个是编译的时间精度,也需要加上,并且和你的Testbench应该要保持一致; -fsdb表示支持对fsdb相应操作,但是新版已经不支持这个指令,而是用-debug_access代替了。
注意:我这个项目最后是要生成fsdb的波形文件,并且是要用指令去查看波形的,所以在testbench中要加入dump波形的指令,否则也是生成不了波形的,主要有2句话:
$fsdbDumpfile(fsdb_name[,limit_size]):指定文件名和波形大小;
$fsdbDumpvars([depth, instance][, “option”]):表示要加载波形的层次;
我写的已经附在代码里面了,具体指令的意思以及其他的指令可以自己去百度,不再赘述。注意一点,我踩过的坑就是,这两句话最好放在单独的initial模块,或者放在一个initial最前面,我开始就把第二句话放在了initial块的最后面,表示我都仿完了他才采集波形,这样最后只有fsdb文件但是里面的波形没有。
言归正传,这句指令执行完成之后,会出现simv文件和fsdb文件,表示你就已将编译成功了,如图:
4.接着就是用verdi看波形了,指令:
verdi -sv -f -Uart_rtl.f -ssf uart_wav.fsdb
这个指令的意思就是同时打开Uart_rtl.f这个list里面的文件和仿真生成的波形fsdb文件。但是你打开之后可能里面还是没有东西,主要是你现在没有进到那个文件夹下面,所以有可能指令打不开,这个时候你可以按照下面的步骤导入你的设计和波形。
5.在verdi中导入设计文件
6.接着在verdi中导入波形:
最后你就能在你下面的窗口看到所有的波形了: