做fpga样机和做芯片的思路其实是有差异的。为了追求好的性能,节省成本,降低功耗(ppa),芯片设计者往往把事情做到极致,去做验证时把各种覆盖率尽可能做到100%,把每个模块电路结构优化到面积最小,通过power gating和clock gating等技术把功耗降到最低,争取把每次流片(烧钱)的风险降到最低;相比芯片设计流程,fpga样机的开发人员往往不太注重上述要求,虽然有着与做芯片相同的目标和追求,但往往因为fpga的可编程性,即便后续发现问题,也可以通过修改代码再次烧写bit文件的方式来弥补,出错成本相对低了很多。但如果按照做芯片的方式来做fpga样机,肯定会带来更好的结果,甚至可以大幅度的降低fpga开发时间。在这个过程中,就需要把常规的做fpga的方式进行修正,比如经常采用的跟fpga编译工具联合仿真的办法就不太适合做芯片的验证了。本文就探讨如何把vivado与modelsim联合仿真修改为单独采用modelsim进行仿真。
在本公众号上一篇文章(【干货】推荐一款fpga仿真调试鸟枪换炮的工具!)中就曾提到,隔行如隔山,做芯片的人永远无法理解只做fpga样机的人在某些情况下不做仿真就直接上板的做法,非芯片设计出身只做fpga样机的人也不知道这个世界上还存在更为高效的verilog或vhdl语言的仿真工具和仿真方法,也不理解为了把一个芯片做到极致,必须严格要求代码规范的做法。为了能够使用上一篇文章中高效的verdi或者simvision仿真调试工具,脱离vivado等仿真工具单独搭建仿真环境的就成为比较急迫的需求了。
本公众号之前也曾经发布过一篇相关的文章,用modelsim独立仿真带vivado ip核的仿真工程,也是实现采用modelsim单独搭建仿真环境的一种方法,但文中所述方法仍未彻底摆脱vivado的环境,适用的场景也受到限制,某些工程中还会出错。因此,本文从最原始文件搭建仿真环境的思路出发,尝试着研究脱离vivado单独建仿真环境的过程中都会遇到什么问题,采用什么样的方法比较容易解决,笔者试了好几个工程,总结出一套相对完善的解决思路,来分享给大家。
fpga开发最不理解的芯片设计中的操作
1、做芯片的仿真最后都不用图形界面
与刚开始做fpga开发时都在图形界面下操作的仿真方法不同,做大规模芯片设计时的仿真常常不调用图形界面,都是采用命令行的形式做的仿真。
上图就是采用简单的windows下的批处理调用modelsim进行的一个仿真过程,这个简单的批处理,就是脚本。也是本文最终要实现的目标。
set project_path=%cd%
::vsim -do sim.do
vsim -c -do sim.do
脚本,是芯片设计人员必须要掌握的基本技能。在芯片设计的各个阶段,脚本的作用是非常巨大的。代码仿真,可以使用脚本来进行仿真环境的搭建,综合的约束文件,必须采用脚本来提前对综合过程中的各种要求进行说明,后端就更不用说了。因为整个芯片的设计流程,每个流程的所有中间信息都是靠文本来储存的,rtl代码,netlist,后端的颜色文件,流片用的gdsii等等,对文本进行随意的操作处理就是一名ic设计人员的基本技能。
如下图就是一个简单的采用ncverilog进行仿真的脚本。
#!/bin/sh
echo /`include /../testcase166/$1.v/ > testcase.v
sed s///wave.shm///wave$1.shm/g ../testbench/testbench.v > testbench.tmp
cp ../testbench/testbench.v ../testbench/testbench.bak
cp testbench.tmp ../testbench/testbench.v
rm -f testbench.tmp
ncverilog -f ../filelist/filelist.v +access+rwc -l ../log/log/$1.log
mv ../testbench/testbench.bak ../testbench/testbench.v
rm -f testcase
~
而下图则是一个采用tcl语言描述的design complier综合脚本的开头部分。
sh date
remove_design -designs
##########################
#set library #
##########################
set search_path [list /tools/lib/smic25/feview_s/version1/std/synopsys /
/tools/lib/smic25/feview_s/version1/std/symbol/synopsys]
set target_library { smic25_tt.db }
set link_library { smic25_tt.db }
set symbol_library { smic25.sdb }
##########################
#paths variables #
##########################
set main_dir ../..
set rtl_root_path $main_dir/hdl
set netlist_path $main_dir/sim/syn/netlist
set rpt_path $main_dir/sim/syn/log
set db_path $main_dir/sim/syn/db
set sdf_path $main_dir/sim/syn/sdf
##########################
#void warning info #
##########################
suppress_message ver-130
suppress_message ver-129
suppress_message ver-318
suppress_message elab-311
suppress_message ver-936
################################
#read&link&check design#
################################
2、做芯片的仿真最后都不看波形
在做芯片仿真时,无论是采用自己搭建的简单仿真环境还是uvm的仿真环境,最后的形式常常是把所有的testcase都集中到仿真环境中,只需敲一个命令,回车,所有的testcase就能够全部运行下去。而仿真过程的错误,也都被记录到log文件中,无论是运行的对与错,都可以在log文件中看到。如下图就是所有的testcase截图,每个case运行的结果也会保存到另外一个log目录下。
而fpga开发人员,则不会去建立如此完善的仿真环境,往往是简单的搭建一个某种功能模式下的仿真环境仿一下过了,就上板了。
采用modelsim单独仿真
1、整理rtl代码及仿真代码
如果要用modelsim单独仿真,并且需要搭建类似于上面描述的采用脚本形式来仿真的仿真环境,那么第一步就需要从vivado工程中把相应的verilog代码整理出来。
vivado跟quartus在仿真时采用的思路是不一样的,对于quartus而言,你可以很容易就能脱离开quartus单独搭建一个modelsim或者vcs的仿真环境,因为quartus所有的ip核或者原语库之类的内容全部都是以verilog或者vhdl文件存储的,建仿真环境时,只需要到quartus的安装路径下找一个叫eda的目录下找sim_lib的子目录下找相应的.v文件添加到仿真工程里就可以了,常见的库文件主要有三个,220model.v,altera_mf.v和cyclone_atoms.v(或者是别的fpga型号)。见本公众号之前的文章有详细描述:用quartus ii和modelsim做后仿真(时序仿真)。
在vivado中也有类似于quartus中的库文件,在vivado工程目录下,如下图所示。
然后,整体拷贝ip文件夹到自己想搭建的modesim仿真环境目录下:
上图中rtl文件夹就是自己原来的设计文件,tb则是一些仿真用的.v文件。
2、编写脚本sim.do文件
一个比较简单的modelsim脚本文件如下。
vlib work
vlog -f ./rtl.f
vsim -novopt work.tb_crossbar_top
do wave.do
run 10us
上面的脚本的具体含义,大家都可以百度搜索找到。需要说明的是所有工程中的文件的路径是需要写到一个rtl.f的文件夹下的,具体源代码可以参考本公众号之前的文章:如何快速生成verilog代码文件列表?(内附开源c代码),需要注意的是,生成的文件路径地址中的斜杠与modelsim脚本中要求的斜杠刚好相反,可以直接采用文本编辑器替换掉,也可以添加以下子函数到c代码中简单修改一下。
void xiegang(char* s)
{
int i,j,k;
char buf[800]= ;
char buf1[800]= ;
memset(buf,0,800);
memset(buf1,0,800);
strcpy(buf,s);
strcpy(buf1,s);
for(i=0;i {
if(buf[i]=='//')
{
buf1[i]='/';
}
}
strcpy(s,buf1);
}
上面的c代码实现文件列表的程序,其实也是脚本。
3、注意事项
在实现的过程中,发现vivado并没有把所有用到的库文件都写成.v的形式,而是以编译库的形式存在。这样就需要在仿真时把对应的库文件包含进去。上面的脚本需要修改为:
vlib work
vlog -f ./rtl.f
#vsim -novopt work.tb_crossbar_top
vsim -gui work.tb_crossbar_top -voptargs=+acc -l c:/modeltech64_10.5/vivado_17_2/simprims_ver -l c:/modeltech64_10.5/vivado_17_2/unisims_ver
do wave.do
run 10us
c:/modeltech64_10.5/vivado_17_2/simprims_ver
c:/modeltech64_10.5/vivado_17_2/unisims_ver
两个库都是vivado与modelsim联合仿真时modelsim预先编译好的仿真库,这里面很多都是fpga上用到的bufg、pll等内容。但添加完这些库文件后,还是有错误,具体如下:
经过上网查找原因,发现这是xilinx全局复位的模块。该模块在c:/xilinx/vivado/2015.1/data/verilog/src路径其实在上面error提示的一部分。
于是,自己copy一份glbl.v到当前工程,进行编译。
但还是弹出相同的错误提示。
最后,在tb.v中添加该模块的调用才最终解决问题。
在笔者尝试多个工程之后,发现找vivado 对应的库实在是太麻烦了,那么多的编译出来的库,每个库也找不到具体解释含义的说明文档。无奈之下,想到了彻底摆脱vivado的终极解决方案。
出现了找不到某个模块定义的错误之后,就需要尝试着去添加上图中不知道含义的库看能不能解决问题,一个一个的试,一个一个的试,试到怀疑人生。
终极方案
这个终极解决方案就是采用asic的思路来替换掉所有的ip。如果考虑最后要做asic,那么就需要把设计代码中所有的fgpa ip核或者原语之类的内容全部替换掉,比如fifo都要修改成控制逻辑加ram的形式,一些bufg之类的改善时序或驱动的原语也全部删掉。如果只考虑做仿真,则只需要自己手写一个ram的行为逻辑,定义一个数组类型,根据输出的时候是否打拍随意的调整。一些fifo也可以很容易的在网上找到源代码,同步的,异步的,首字置出的fifo都有。替换干净之后,就跟vivado没有任何关系了!甚至也跟modelsim也没有任何关系了,可以随意的更换仿真工具,比如vcs和nc等,彻底的解决问题。
写到此处,想起了一个有趣的事情。据说有一种永远不让代码中出现bug的终极解决方案。猜猜看是什么。
答案是:不要写一行代码!
这个跟摆脱vivado单独建仿真环境的终极解决思路竟然高度一致!彻底摆脱vivado建仿真环境的方法也是,仿真代码中不要用到vivado中的任何一个ip核!!!
4、覆盖率分析
有了脚本的支持,也脱离掉了vivado的束缚,就可以做很多自己想做的事情,把仿真环境做成可回归的形式之后就可以做覆盖率分析。这时的脚本就修改成如下的样子。
vlib work
vlog -f ../filelist/filelist_sim.v
vlog -f ../filelist/filelist_hdl.v -cover bcesxf
vsim -novopt -coverage work.testbench -l c:/modeltech64_10.5/vivado_17_2/simprims_ver -l c:/modeltech64_10.5/vivado_17_2/unisims_ver
run -all
大家可能注意到,上面脚本中把filelist分成了两种,一种是仿真的,不用看覆盖率,另外一种则是可综合代码部分,需要看覆盖率,单独写到了filelist_hdl.v的文件里面。
运行结束后,就可以在图形界面上看到覆盖率分析的结果。
随着测试例的运行,上面设计代码的覆盖率也会逐渐提高,最后可以通过选择达不到覆盖率要求的模块进行详细的分析,查看测试例没有运行到的语句。有了充分的仿真验证后,再上板就顺利的多了。至少99%的逻辑bug都被解决掉了,剩余的就是一些时序方面的问题,这样就可以大大节约fpga调试的时间。
用做芯片的思路去做fpga,不是杀鸡用牛刀,而是一种正确的思路。搭建一个完善的仿真验证环境固然麻烦,但一旦做好之后,事半功倍,效率会大幅度的提升。本文中提到的仿真环境仅仅是一种最简单的只有verilog代码的仿真环境,在验证复杂度和便捷性等方面都差的很远远。公司里面目前采用的办法,往往是大牛们用sv搭建好一个uvm框架后,下面做具体实现的人只需要往对应框里面填数字就可以了。
工欲善其事,必先利其器!做fpga,仿真验证就是器!
erlang编程语言特点详细解析
5G多功能智慧杆,助力新时代海洋智能化管理
PLC编程中程序设计的步骤
迅远RFID超高频电力智能工具柜的产品特点有哪些
引领面板行业未来的黑科技,MiniLED到底是什么?
基于PFGA的脱离Vivado单独建仿真环境工程
简单介绍下全自动智能指纹锁的报警方式
单线总线为水位传感器供电系统检测水位
浅谈汽车连接器端子夹紧力控制的优缺点
ARM44B0x实现信号发射机控制器
东芝发布12.5寸2in1笔记本
全新的超声波液位计LST200可以同时兼容ABB通用的FIM调试软件
全新人工智能驾驶舱用“读心”的增强现实头盔取代现有仪器
如何优雅地安排PCB丝印?
新一代电池供电用极低功耗设计
荣耀V9幻夜黑:不光有极致的快还有深邃的美
AOC推出全新带鱼屏曲面显示器Agon AG273QZ 27英寸TN面板+240Hz刷新率
东莞鑫芯源为你介绍铜编织线主要用在哪些地方?
了解千兆光模块和万兆光模块的标准规范
土壤重金属检测仪的详细介绍