因为用ModelSim 进行仿真是建立在仿真库的基础上的(此处进行的是功能仿真,因而不用编译特定厂商的库),所以首先要建立库并把库映射到实际的物理路径。通常用户编译的文件都放在work库中,所以必须先建立work 库。有两种方法建立并映射库,第一种方法是通过图形界面,在菜单Design→Create a New Library 弹出对话框,如图1 所示。在Library Name 中输入work,如果建立其它库,可以输入其它名字。Library Map to 是映射的物理路径。第二种方法是用命令行的形式,建立库用ModelSim>vlib<库名>,映射库用ModelSim> vmap , 如建立并映射库work,就可以在ModelSim 主窗口命令提示符下输入
vlib work
vmap work work
(2)编译源代码
该步骤主要检查源文件的语法错误。实现方法有两种,一是通过菜单Design→Compile,出现选择源文件对话框,选择要编译的源文件,编译即可;二是通过命令行方式,这一步对于VHDL 和Verilog 所使用的命令是不一样的,对于VHDL 代码用vcom-work.vhd.vhd , 对于Verilog 代码用vlog-work.v.v,文件按出现的先后顺序编译,且支持增量编译。编译后的文件会放在缺省当前work 库中。
(3)启动仿真器
该步骤主要是把所有仿真的文件加载到当前的仿真环境中。实现的方法两种,一是通过菜单Design→Load Design,出现加载对话框,选择要仿真的程序即可;二是通过命令行的形式vsim-lib , 这条命令对于VHDL 和Verilog 都一样。
(4)执行仿真
该步骤是正式执行仿真了,在仿真前最重要的一个步骤就是加载激励,如要对下面的加法器进行仿真,加法器实体说明如下:
entityAdd is
port(D1: in std_logic_vector(7 downto 0);--输入
D2: in std_logic_vector(7 downto 0);--输入
D0: out std_logic_vector(7 downto 0);--输出
CE: in std_logic;-使能,低有效
Clk: in std_logic);--时钟
endAdd; 测试激励的加载
激励的加载有四种方法:
(1)命令行方式
这种方法是通过在命令行下直接输入命令给信号加载激励,然后进行仿真。如要对上面的加法器进行仿真,则输入如下命令:
Vsim –t ps work.add
//加载work 库中的实体add,时间分辨率为ps
Add wave –hex D1
Add wave –hex D2
Add wave –hex D0
Add wave ce
Add wave clk
//把信号加载到波形窗口,hex 表示以16进制显示
Force ce 0 //对ce 加激励为0
Force clk 0 0,1 25 –r 50 //对clk 加载激励
Force D1 16#2 //对D1 加载16 进制数2
Force D2 16#1 //对D2 加载16 进制数1
Run 100 //运行100 个时间单位
如果要仿真其它数据,在命令行中改变激励
就可以了,仿真的结果如图2 所示。
(2)宏文件法
这种方法相当于DOS 的批处理。它把所有的命令保存为以do 为后缀名的文件中,称为宏文件。执行仿真时只要选择菜单Marco → ExecuteMarco,然后选择相应的宏文件执行即可,或者在命令行中输入do<宏文件名>。执行仿真的结果如图2 所示。
(3)测试文件法
上述两种方法只适合验证数据量小的程序,对程序进行简单验证,如果要验证的数据量较大,
上述两种方法就比较麻烦,现在被广泛采用的是测试文件法。这种方法其实是要设计者自己编写测试文件,把要验证的程序当成测试程序的一个模块,在测试文件中对要验证的程序加载激励。以下就是针对上面加发器的测试文件:
library ieee;
use ieee.std_logic_1164.all
use ieee.std_logic_signed.all
entity tb is
end tb
architecture a_tb of tb is
component Add
port(D1 : in std_logic_vector(7 downto 0);
D2 : in std_logic_vector(7 downto 0);
D0 : out std_logic_vector(7 downto 0);
CE : in std_logic;
Clk: in std_logic);
end component;
signal D1 : std_logic_vector(7 downto 0) :=(other => ‘1’);
signal D2 : std_logic_vector(7 downto 0) :=(other => ‘1’);
signal D0 : std_logic_vector(7 downto 0) :=(other => ‘0’);
signal CE : std_logic := ’0’;
signal Clk : std_logic
begin
dut : Add
port map(D1 => D1,
D2 => D2,
D0 => D0,
CE => CE,
Clk => Clk);
Clk <= not Clk after 25 ns;
process
begin
wait until Clk = ‘1’ and Clk’event;
D1 <= D1+1;
D2 <= D2+2;
end process;
end a_tb;
用这个测试文件产生的仿真波形如图3 所示:
这种方法可以仿真大量的数据,对程序进行比较全面的仿真。
(4)textio 法
方法(3)产生的激励数据一般很有规律,也容易分析,但同时也可能造成某些情况无法检测到。所以做仿真时若希望验证一些没有规律的数据,则可以用 textio 方法实现。实际上它的输入激励是存储在dat 文件中的,在测试文件中读入这些数据,如果用VHDL 编写程序,需要textio 库和VHDL93 标准的支持,限于篇幅这里就不详细介绍,详情请参见有关文献。
用ModelSim 进行时序仿真
时序仿真是FPGA 设计的重要步骤之一,它通常是在做完布局布线后进行,仿真中包含布局布线产生的延时信息。时序仿真的方法和步骤和功能仿真基本相同,但有两点需要注意:一是一般布局布线后生成的网表并不包含timing 数据,会用一个SDF(Standard Delay Format)文件来存储timing数据,它通常是由布局布线工具产生,在做时序仿真时要用到。上面启动仿真器加载时不仅要加载布局布线后生成的源文件,还要加载SDF 文件。二是在用ModelSim SE 版本时,由于不包含特定厂商的库文件,而在做时序仿真时恰恰与特定的器件相关,要用到这些库,为了提高仿真速度,通常需要提前编译这些库,而且不同厂商编译库的方法不尽相同,本文以编译Xilnx 公司的库为例,介绍编译库的方法。
这种方法是通过在Xilinx 的网站上下载的xilinx_lib_4.tcl 脚本进行的,选择菜单中的执行宏或者在命令行中输入source xilinx_lib_4.tcl,会弹出图4 所示的对话框,在选择所要编译的语言后,Xilinx Software Version、编译的库、Xilinx 路径和Modelsim 路径后就可以进行库的编译了。其中较重要的是simprim(做时序仿真时用)和Xilinxcorelib(在进行Xilinx core 的电路仿真时用),这些库还有对应的Verilog 版本。在进行库编译之前,最好把ModelSim 安装目录下的modelsim.ini 文件的只读属性去掉,这样可以把编译后的库信息加到该文件中,具体信息如下:
simprim = C:/Modeltech_5.5b/simprim
simprims_ver = C:/Modeltech_5.5b/simprims_ver
xilinxcorelib = C:/ Modeltech_5.5b/xilinxcorelib
xilinxcorelib_ver = C:/
Modeltech_5.5b/xilinxcorelib_ver