仿真功能概述
仿真FPGA开发中常用的功能,通过给设计注入激励和观察输出结果,验证设计的功能性。Vivado设计套件支持如下仿真工具:Vivado Simulator、Questa、ModelSim、IES、VCS、Rivera-PRO和Active-HDl。
Vivado的仿真流程如下图所示:
仿真可以在设计阶段的不同时间点进行,主要包括如下三个阶段:
- RTL级行为仿真:在综合和实现前便可验证设计,用来检查代码语法和验证代码像设计者想要的功能一样工作,早期的行为级仿真可以尽早发现问题;
- 综合后仿真:使用综合网表仿真,验证综合后设计满足功能需求。该阶段仿真不太常用,可以用时序仿真(timing simulation)来估计时间;功能仿真(functional sumulation)由层次化的网表组成,最底层由Xilinx原语构成;
- 实现后仿真:可以进行功能仿真和时序仿真,且与FPGA硬件上的工作情况最为接近,确保实现后设计满足功能和时序要求。
时序仿真相比功能仿真要耗费大量的时间,但是可以检测到功能仿真无法检测的问题,比如:
- 由于属性设置(综合属性、UNISIM库属性等),或不同仿真器对语法的不同解释,导致综合后或实现后功能发生改变;
- 双口RAM读写冲突;
- 错误的、不合适的时序约束;
- 异步路径操作问题;
- 由于优化技术引起的功能问题
Vivado Simulator支持VHDL(IEEE-STD-1076-1993)、Verilog(IEEE-STD-1364-2001)、SystemVerilog中的可综合子集(IEEE-STD-1800-2009)三种硬件描述语言,此外还支持IEEE P1735加密标准。
使用TestBench和激励文件
TestBench也是由HDL语言代码编写,其实例化了需要仿真的设计,生成设计所需要的激励信号,监测设计输出结果并检查功能的正确性。一个简单的TestBench可以仅仅将激励顺序地加载到设计的输入管脚上;一个复杂的TestBench可能会包含子程序调用、从外部文件读取激励信号、条件化激励和其它更多复杂的结构。
下面是编写TestBench时极度推荐的一些注意事项:
- 在Verilog TestBench中总是使用timescale规定时间,如`timescale 1ns/1ps;
- 在仿真时间的0时刻,将所有的设计输入初始化位为一个确定的值;
- 在综合后和实现后的时序仿真中,会自动触发全局置位/复位脉冲(GSR),这会让所有的寄存器在仿真的前100ns内锁定其值。因此在100ns之后再赋值激励数据;
- 在全局置位、复位脉冲释放之前就确保时钟源已经开始工作。
指定仿真器位置
点击Tools->Settings->Tool Settings->3rd Party Simulators:
Install Paths中定位仿真器的安装路径,Default Compiled Library Paths中指定与仿真器相关的编译库路径。只有第三方仿真器需要在此设置,Vivado Simulator不需要设置。
编译仿真库
使用Vivado Simulator时,不需要编译仿真库。但是使用第三方仿真工具时,必须先编译仿真库,才能在第三方仿真工具中正确运行。仿真库中包含了仿真模型,比如FPGA和IP的行为模型和时序模型。编译之后的库可以在多个设计工程中使用。
在编译过程中,Vivado会创建一个仿真器用来参考编译库文件的初始化文件,该文件包含了一些控制变量,包括规定参考库路径、优化、编译和仿真设置。如果没有正确的初始化文件,就不能运行包含Xilinx原语的仿真。不同仿真器的初始化文件名称如下:
- Questa/ModelSim:modelsim.ini;
- IES:cds.lib;
- VCS:synopsys_sim.setup
如果使用的仿真器版本不变,只需要编译一次库文件即可;如果更换了Vivado或仿真器的版本,就必须重新编译一次库文件。编译库文件有Vivado IDE和Tcl命令两种方法,本文介绍第一种。点击Tools->Compile Simulation Libraries(即使不打开工程也有此命令)打开如下窗口:
- Simulator:选择第三方仿真器;
- Language:编译库到规定的语言,如果为All,则会根据选择的仿真器自动选择语言,如果仿真器支持混合语言仿真,则Verilog库和VHDL库都会编译;
- Library:选择需要编译的仿真库(Unisim或Simprim),默认会编译所有 的库;
- Family:编译库到规定的FPGA系列,默认会生成所有的器件系列;
- Compiled library location:设置保存编译库结果的目录路径。默认情况下会保存在当前工程目录的.cache/compile_simlib目录下;
- Simulator executable path:设置仿真器可执行文件所在的路径;
- Miscellaneous Options:使用Tcl命令设置一些其它选项;
- Compile Xilinx IP:选择是否编译Xilinx IP的仿真库;
- Overwrite current pre-compiled libraries:选择是否重写当前预编译库;
- Compile 32-bit libraries:默认为64bit模式,选中此项,仿真器编译会在32bit模式下进行;
- Verbose:Messages窗口默认有消息显示数量限制,选中此选项后,相关命令会忽视此限制,所有消息都会显示在Messages窗口中;
- Command:展示了上述设置所等效的Tcl命令。
Xilinx仿真库
设计者可以将Xilinx仿真库用于任何支持VHDL-93和Verilog-2001语言标准的仿真器。库中包含延迟与模型信息,可以正确地仿真Xilinx硬件器件。
仿真时,如果数据和时钟同时发生变化,仿真器在判断当前时钟边缘时会采样上一个状态的输入,同时变换时刻的输入会安排在下一个始终边缘才有效。最好的做法当然是不要使数据信号和时钟信号同时变换,以避免出现意料之外的仿真结果。
当设计者在设计中实例化了一个组件后,仿真器必须在库中找到描述该组件功能的内容,以确保正确的仿真。下面列出Xilinx提供的仿真库:
- UNISIM:Xilinx原语的功能仿真,Verilog库名为UNISIMS_VER。包含了器件原语和最低等级构建模块的描述。
- UNIMACRO:Xilinx宏的功能仿真,Verilog库名为UNIMACRO_VER。当使用器件宏时,必须设置此库。
- UNIFAST:快速仿真库,Verilog库名为UNIFAST_VER。推荐在RTL行为级仿真中使用此库,可以节省仿真运行时间。
- SIMPRIMS_VER:Xilinx原语的时序仿真,仅支持Verilog,因此时序仿真仅支持Verilog语言。
- SECUREIP:Xilinx复杂器件组件(如PCIE、高速收发器)的功能仿真和时序仿真库,在Vivado安装目录的data/secureip目录下可以查看完整IP列表。
- XPM:Xilinx原语的功能仿真。
除了SECUREIP外,其它库都位于Vivado安装目录data/Verilog或VHDL/src目录内。设计者必须根据运行的仿真来设定不同的仿真库。下表中给出了与不同仿真阶段相关的仿真库文件:
仿真设置
在仿真设置中规定目标仿真器、仿真集、仿真顶层模块名称等选项。打开Settings切换到Simulation标签中,或在Flow Navigator中的Simulation上右键->Simulation Settings,打开设置窗口:
其中Clean up simulation files表示重新运行仿真时会将现存的整个仿真目录全部移除,其余设置选项很熟悉了,不多作介绍。下面着重介绍Simulator language,理解背后的处理机制,其值可选择VHDL、Verilog或Mixed。
大多数的Xilinx IP只会生成单语言的行为仿真模型;某些第三方仿真工具也仅支持单语言仿真。通常应该将Simulator language设置为仿真工具支持的语言,以确保工具正常运行。如果IP核同时也可以生成该语言的行为模型再好不过,但是如果IP核不支持该设置,Vivado会自动从IP核的DCP文件中生成一个结构化仿真模型用于仿真,确保仿真可以正常运行。
仿真分辨率需要在TestBench中使用timescale设置,某些人认为设置一个粗略的仿真分辨率(如1s)可以提升仿真性能,这是错误的。在 Xilinx仿真模型中,大多数仿真时间是基于一个固定间隔,与仿真分辨率并无联系。设置仿真分辨率主要是为了观察更方便。但是某些Xilinx原语组件(如MMCM)需要1ps的分辨率才能在仿真中正常工作,最常用的分辨率设置是`timescale 1ns/1ps。
仿真集功能
Vivado提供了仿真集(Simulation Sets)功能,该机制可以让用户将不同设计阶段所用到的不同源文件添加到各自的仿真集中。比如一个仿真集可以添加用于RTL行为级仿真的源文件,另一个仿真集添加用于实现后时序仿真的源文件。或者不同的仿真集提供对一个设计的不同测试方法,等等。
在创建或添加仿真源文件时,可以选择将文件加入到哪个仿真集,或者创建新的仿真集:
当设计中存在多个仿真集时,当前运行使用的仿真集会显示为Active状态: