modelsim可以通过编写编写命令的方式进行自动化仿真,方便了仿真过程。下面给出几个实例,介绍用命令进行仿真的流程。
一、基本仿真流程
这个模块描述了一个分频器:
module f_divide #(
parameter DIVI_NUM = 6'd2
)
(
input clk_in,
input rstn,
output reg clk_out
);
reg [5:0] counter;
always @(posedge clk_in or negedge rstn) begin
if(!rstn)
counter <= 'd0;
else
counter <= (counter == DIVI_NUM - 6'd1) ? 6'd0 : counter + 6'd1;
end
always @(posedge clk_in or negedge rstn) begin
if(!rstn)
clk_out <= 1'd0;
else if(counter == DIVI_NUM/2 - 6'd1)
clk_out <= 1'd0;
else if(counter == DIVI_NUM - 6'd1)
clk_out <= 1'd1;
else
clk_out <= clk_out;
end
endmodule
测试代码:
module test_sim();
reg clk;
reg rstn;
initial begin
clk = 1'd0;
rstn = 1'd0;
#10;
rstn = 1'd1;
#1000;
$stop;
end
always #5 clk = ~clk;
wire clk_out;
f_divide #(
.DIVI_NUM (6'd2)
)
f_divide_inst
(
.clk_in (clk ),
.rstn (rstn ),
.clk_out (clk_out)
);
endmodule
将这两段代码分别放在两个.v文件中,存为一个文件夹下,这里命名为test:
在test文件夹中新建一个.f文件,里面存放“f_divide.v”和“test_sim.v”文件的相对路径,如下图:
关于相对路径,可参考这篇文章:verilog 相对路径与绝对路径_verilog跨模块引用 相对和绝对-CSDN博客
test文件夹中再新建一个.do文件,内容如下:
打开modelsim,将文件夹目录转到test文件夹:
命令窗口中输入“do cmd.do”并按回车键,运行.do文件:
将信号拖拽至波形窗口:
点击波形窗口并按ctrl+s键保存:
回到cmd.do文件,重新加入添加波形和运行仿真的语句:
命令窗口中重新输入“do cmd.do”并按回车键,再次运行.do文件,即可看到波形:
二、define文件的包含
在写verilog代码时,经常会将所有的预定义都写进一个文件中,习惯性地命名为“define.v”。下面介绍如何将define.v包含进仿真工程中。
方法1
用`include"xxx",其中xxx为相对路径,例如下面的分频器模块,引用了define.v中定义的分频系数DIVI_NUM:
`include "./include/define.v"
module f_divide
(
input clk_in,
input rstn,
output reg clk_out
);
reg [5:0] counter;
always @(posedge clk_in or negedge rstn) begin
if(!rstn)
counter <= 'd0;
else
counter <= (counter == `DIVI_NUM - 6'd1) ? 6'd0 : counter + 6'd1;
end
always @(posedge clk_in or negedge rstn) begin
if(!rstn)
clk_out <= 1'd0;
else if(counter == `DIVI_NUM/2 - 6'd1)
clk_out <= 1'd0;
else if(counter == `DIVI_NUM - 6'd1)
clk_out <= 1'd1;
else
clk_out <= clk_out;
end
endmodule
其中,define.v文件存在test文件夹下的include文件夹中:
内容如下:
`define DIVI_NUM 6'd2 //6bits and >=6'd2
仿真测试代码:
module test_sim();
reg clk;
reg rstn;
initial begin
clk = 1'd0;
rstn = 1'd0;
#10;
rstn = 1'd1;
#1000;
$stop;
end
always #5 clk = ~clk;
wire clk_out;
f_divide f_divide_inst
(
.clk_in (clk ),
.rstn (rstn ),
.clk_out (clk_out)
);
endmodule
按照上一节的流程进行仿真,仍然可以看到波形:
方法2
如果工程中各个.v文件存放的结构复杂,相对路径不好获取时,可以只写文件名:
但是,在compile.f文件中,要加入“+incdir+xxx”的命令,其中“xxx”是define.v所在文件夹的相对路径。该命令的意思是编译compile.f中的所有.v文件时,遇到“`include”的话,就在xxx文件夹下寻找define.v文件。即:
按照上一节的方法,仍然能仿真成功:
个人比较推荐方法1,因为仿真完成后的代码一般要在其他软件完成综合和布局布线,而这些软件不一定能像方法2那样添加专属的`include路径,即方法2在代码的兼容性上略逊一筹。
三、仿真库的包含
这里所谓的仿真库,其实是一些FPGA厂商对自家芯片的硬核模块进行Verilog代码描述,以方便开发者在第三方仿真软件中进行仿真。有些FPGA厂商给用户的库文件是分离的,即一个文件夹下放多个硬核模块的.v文件,例如安路FPGA的PH1A系列仿真库,如下图所示:
通常,开发者编写了使用硬核模块的代码时,要从这些文件中找到对应的硬核模块所在的文件,并将其路径添加至compile.f中(如第一节所述),才能进行仿真。若使用了多个硬核模块,那添加路径将是十分费事费力的事情。因此这里介绍一种快捷添加库文件的方法,即在compile.f文件中添加下图红框中的语句:
红框中的语句表示将“D:/Anlogic/TD5.6.2/sim_release/ph1”路径对应的文件夹内所有.v文件都添加进工程中进行仿真,仿真时modelsim会根据需要调用这些.v文件。