2008年10月8日星期三

用modelsim和debussy协同仿真VHDL Verilog的流程(ZZ)

关于整个流程,modelsim用do文件命令行方式,不开启GUI模式。仿真完成后用debussy看波形,速度相当快。不敢独享,共献出来大家分享。
debussy和modelsim协同仿真全过程。
1.编辑modelsim根目录下的modelsim.ini文件,将; Veriuser = veriuser.sl 更换为Veriuser = novas_fli.dll。
2.将D:\Novas\Debussy\share\PLI\modelsim_fli54\WINNT下的novas_fli.dll 拷贝至D:\Modeltech_6.1d\win32中
3.将D:\Novas\Debussy\share\PLI\modelsim_fli54\WINNT下的novas.vhd拷贝至工程所在目录
4.编译novas.vhd文件,并将其作为一个lib加入,在testbentch中增加library novas;use novas.pkg.all;
5.在testbentch中添加fsdbdumpfile("t1.fsdb");
6.编译整个工程,然后仿真

编辑SDT_VSIM.do文件,我的do文件如下。
vlib work
vcom novas.vhd
vcom FIFO256.vhd
vcom PS8TO1.vhd
vcom rxb.vhd
vcom sdt.vhd
vcom SP1TO8.vhd
vcom txb.vhd
vcom sdt_TB.vhd
vsim sdt_TB
run 1000us
quit

然后在dos界面中输入D:\Modeltech_6.1d\win32/vsim -c -do SDT_VSIM.do
可以去debussy中看波形了
备注:
如果是Verilog. 则省去第4步. 就可以用了。

关于硬件设计

就我所见的电源芯片来讲,没有哪个是可以完全按照厂家的Spec来设计的。不要以为芯片厂家给你的都是没问题的东西,电源芯片最常见的又最难定位的就是芯片自身设计缺陷。

例子1:M公司的片子在实验室常温就没问题,拿去做高低温和潮敏实验就挂,这种问题才是硬件工程师常遇到的问题。后来发现是厂家防潮设计不到位。

例子2:M公司的某xxxx片子号称开关频率能到300KHz,上了单板后打死都上不到300KHz的开关频率,导致输出纹波超标。厂家的FAE也无法定位问题,后来是硬件工程师想法解决的,怎么解决的就不说了,机密。

例子3:T公司的某xxxxx芯片上管驱动与Spec标称值不符,导致原设计的MOSFET不可用。灭办法,投诉加改版。你以后可以完全按照Spec来设计,我等着看你死得有多惨。
在下刚接触硬件设计的时候电源按Spec的设计来(Spec不可能Cover所有的设计情况,所以只有按典型值来设计),被老板骂得狗血淋头,盖因按我手 上板子某V电源的输入输出要求,典型设计只会让环路响应不稳定,交越频率大于1/4-1/5开关频率,相位稳定度小于45。

例子5:有了新项目,电源有新需求。联系厂家M,T,A,三家都屁颠屁颠按要求提供自己的电源芯片。Sales说得那个天花乱坠啊,都说自己的好。
Buck电源有单环的,双环的。双环有电流平均值型,on-off型,峰值型,您老人家选哪种,哪家的呢?您该如何抉择呢?硬件工程师同学?选不好老大要打pp的哦~~

例子6:为什么一模一样的设计,A单板完全正常,B单板就纹波大个100mV呢?欧也,一查brd文件,公司低价请的外协PCB工程师把滤波电容放在芯 片侧了,为什么你没查出来呢?你说全板几K个电容,我哪查得过来啊?不好意思,老大还是要打你pp,谁让你是硬件工程师,你必须懂得的。没出问题是应该 的,出了问题就是你的错。

例子7:公司为适应竞争,要降成本了,在满足一切性能要求的情况下,硬件工程师同学,请把你板上的成本给我降个50块。不要小看50块,会把你脑门上的毛都愁掉下来,不信以后你做做降成本试试看。

硬件确实没萨东西,但你没做过,没教过学费,你还真做不下来。

IC设计流程(zz)

1. 首先是使用HDL语言进行电路描述,写出可综合的代码。然后用仿真工具作前仿真,对理想状况下的功能进行验证。这一步可以使用Vhdl或Verilog作为工作语言,EDA工具方面就我所知可以用Synopsys的VSS(for Vhdl)、VCS(for Verilog),Cadence的工具也就是著名的Verilog-XL和NC Verilog。
2.前仿真通过以后,可以把代码拿去综合,把语言描述转化成电路网表,并进行逻辑和时序电路的优化。在这一步通过综合器可以引入门延时,关键要看使用了什么工艺的库,这一步的输出文件可以有多种格式,常用的有EDIF格式。
综合工具Synopsys的Design Compiler,Cadence的Ambit
3。综合后的输出文件,可以拿去做layout,将电路fit到可编程的片子里或者布到硅片上。这要看你是做单元库的还是全定制的。
全定制的话,专门有版图工程师帮你画版图,Cadence的工具是layout editor。单元库的话,下面一步就是自动布局布线,auto place & route,简称apr。cadence的工具是Silicon Ensembler,Avanti的是Apollo。layout出来以后就要进行extract,只知道用Avanti的Star_rcxt,然后做后仿真。如果后仿真不通过的话,只能iteration,就是回过头去改。
4,接下来就是做DRC,ERC,LVS了,如果没有什么问题的话,就tape out GDSII格式的文件,送制版厂做掩膜板,制作完毕上流水线流片,然后就看是不是work了。做DRC,ERC,LVSAvanti的是Hercules,Venus,其它公司的你们补充好了。
btw:后仿真之前的输出文件忘记说了,应该是带有完整的延时信息的设计文件如:*.VHO,*.sdf
RTL->SIM->DC->SIM-->PT-->DC---ASTRO--->PT----DRC,LVS--->TAPE OUT
1。PT后一般也要做动态仿真,原因:异步路径PT是做不了的
2。综合后加一个形式验证,验证综合前后网表与RTL的一致性
3。布版完成后一般都会有ECO,目的手工修改小的错误
SPEC->ARCHITECTURE->RTL->SIM->DC->SIM-->PT-->DC---ASTRO--->PT----DRC,LVS--->TAPE OUT
SPEC:specification,在进行IC设计之前,首先需要对本IC的功能有一个基本的定义。
ARCHITECTURE:IC的系统架构,包括算法的设计,算法到电路的具体映射,
电路的具体实现方法,如总线结构、流水方式等。
在IC前端的设计中,ARCHITECTURE才是精华,其他的大部是EDA 工具的使用,技术含量不高。
dv, design verification,验证 和前端、后端并列。
DFT, design for test. 前后端合作,并与tapeout 后测试合作。
ir-drop. 后端和验证合作。
SI, 后端。
low-power design ,前后端合作.

我的仿真工作流程(Verilog/Modelsim+Debussy) (zz)

转自http://www.tai-yan.com/news/bencandy.php?id=15753

文章详细说明了本人近一年来,自己摸索出来的一套仿真工作流程。接触过Modelsim这类软件的朋友可能都会感觉上手比较困 难,原因有二:一、对仿真机制不了解,对基于source+testbench的工作流程不熟悉(大多数朋友接触FPGA仿真可能以waveform的方 式);二、对软件的安装和使用不熟悉,Modelsim软件破解和平时常用软件相比要麻烦一些,也不像常用软件那样易于上手。即使入门了,也不一定能够熟 练使用,相信很多朋友后仿过程中都碰到过back-annotation error的问题:)与大家一样,我也是这样一步步摸索出来的……

设计语言完全采用verilog, 设计工具采用ModelSim + Debussy。目前我的工作平台是Windows, 使用的版本是ModelSim6.2a + Debussy5.3v9。

为了便于管理,在文件夹的管理上采用分级管理。举一个例子:如果顶层模块是A1;A1划分为B1,B2,B3;B1又划分为C1,C2,B2划分为C3, C4,B3划分为C5,C6。那么一共建立10个文件夹,分别命名为A1, B1, B2, B3, C1, C2, C3, C4, C5, C6。在各文件夹中存放相应的设计源文件.v和testbench文件.v,这样可以避免单个文件夹中文件过多,给管理上带来不便。

ModelSim有三种操作模式:GUI、Command-line和Batch。GUI模式比较麻烦,又要敲键盘,又要点鼠标,对我这样的懒人不合 适:)而且初学者在做后仿的时候,.sdf文件的back-annotation比较难掌握。我推荐的是采用编写.do文件或.bat文件的工作方式。. do文件的编写可以参照ISE自动生成的.fdo(功能仿真)和.tdo(后仿)文件。通过ISE调用ModelSim进行仿真,在工程的文件夹下会生成 *.fdo和*.tdo的文件,用编辑器打开文件查看,是诸如此类的一些命令:
## NOTE: Do not edit this file.
## Auto generated by Project Navigator for Post-PAR Simulation
##
vlib work
## Compile Post-PAR Model
vlog "C:/test/netgen/par/shift_reg_timesim.v"
vlog "testbench.v"
vlog "C:/Xilinx/verilog/src/glbl.v"
vsim -novopt +maxdelays -L simprims_ver -lib work testbench glbl
do {testbench.udo}
view wave
add wave *
add wave .glbl.GSR
view structure
view signals
run 10us
## End
这些命令并不一定都要写上,可以根据自己的需要加以精简,比如一个功能仿真的fsim.do文件如下所示:

vlib work
vlog "PCMSyn.v"
vlog "Timing.v"
vlog "Search.v"
vlog "FSM.v"
vlog "test.v"
vsim -t 1ns -lib work test
view wave
add wave *
view structure
view signals
run 4ms
用ModelSim也可以查看波形图和进行调试,但是Debussy查错比较方便,下面说明如何利用ModelSim和Debussy进行仿真和调试。
在testbench文件中initial begin后需添加两条语句:
$fsdbDumpfile("test.fsdb"); //文件名随便起
$fsdbDumpvars;

点击图标或在cmd下敲vsim启动ModelSim GUI,在Transcript窗口cd到该模块的文件夹下,运行do *.do(*.do为仿真的do文件,比如fsim.do)。ModelSim有个不好的地方,如果仿真波形不对,可能需要查看中间信号以便定位错误,这 时用add wave命令添加中间信号后,需要重新run一次,才能看到这些中间信号的值。而采用Debussy查看ModelSim生成的.fsdb文件的话,添加 信号后立即就可看到值,给调试带来很大的方便。另外,Debussy还有个很有用的功能叫做active annotation,在nWave窗口点击波形图上的不同时间点,nTrace和nScheme的源代码和示意图上的表示出的信号值会随之变化,也大大 方便了查错。关于Debussy的使用方法,请大家参考帮助文档,我只结合自己使用的经验强调2点:
1.在打开.fsdb文件之前,先在nTrace窗口Import Design一下,选择From File,Add所有相关的设计源文件和testbench文件,否则在nWave窗口打开.fsdb文件,用Get Signal添加信号后会显示NF。另外,在Get Signal之前请将ModelSim关掉,否则好像还是会显示NF。
2.再强调一遍,Import Design的时候要将testbench文件也添加进去,否则启动active annotation后,所有信号都会显示NF!这个问题曾郁闷了我很久,所以特别提出来。

可能大家都发现ModelSim的主要作用是产生.fsdb文件,我们并没有用它来进行查错,完全没必要启动GUI。这个问题我思考了很久,最后在网友 hamamdu的帮助下解决了这个问题。用文本编辑器生成一个.bat文件,文件内容和.do文件差不多,不过语句到vsim命令为止,此外vsim命令 也要做一些修改,添加-c参数。下面给出一个.bat的例子:
vlib work
vlog "PCMSyn.v"
vlog "Timing.v"
vlog "Search.v"
vlog "FSM.v"
vlog "test.v"
vsim -c work.test
运行这个.bat文件后,将会出现VSIM 1>提示,这时输入run 4ms,回车,将提示fsdb文件产生好了。
经我试验,开启Optimization后,对Command-line操作模式没有影响,但是最后一条语句不可写成vsim -c test,虽然这样也可产生fsdb文件,但是启动active annotation后Debussy软件会报错:(
写的比较仓促,大家试验中发现什么问题,请及时提出来:)

电子科大tony的工作经验(zz)

转载自:http://zgynuaa.blog.163.com/blog/static/800776212008610102049336/
序
很早之前就想对这几个月工作经历写的东西,一是作为自己的总结,二是自己也很
想将自己这段时间的一些经历和大家分享一下,希望对初学者而言能使得他们能少走一
些弯路。只是公司里的事情很多,最近经常加班,所以一直拖到现在。
能来到这家公司应该是一种缘份--缘起NIOS。当初三月份altera来我们学校建立SO
PC实验室的时候自己还不知道NIOS是什么东西,只是想在altera的FAE讲完NIOS后多问他
几个时序约束的问题,然后拷一份PPT回去。但是想不到因为那一份NIOS的培训资料,我
认识了edacn上的cawan,他给我讲了很多NIOS的东西,之后是丁哥在SOC版帖了位NIOS大
赛的通知,然后我和队友就去报了名,并去川大参加了NIOS的培训,认识了峻龙的FAE-
---也是我现在的boss。在这里要谢谢cawan、丁哥、和我一起参加NIOS竞赛的队友刘科
以及我的BOSS,是他们让我有了这一段的经历。
在公司里的几个月,做的项目其实不多,但是收获还是有一些,我觉得收获最大的是
设计理念的改变,这也是我这段时间最想总结的,我会在后面逐渐阐述。
版权所有,未经作者允许,禁止用于商业性质的转载;如对此文有疑问或想给作者提
建议请给作者发email:wangdian@tom.com

时序是设计出来的
我的boss有在华为及峻龙工作的背景,自然就给我们讲了一些华为及altera做逻辑
的一些东西,而我们的项目规范,也基本上是按华为的那一套去做。在工作这几个月中
,给我感触最深的是华为的那句话:时序是设计出来的,不是仿出来的,更不是�出来
的。
在我们公司,每一个项目都有很严格的评审,只有评审通过了,才能做下一步的工
作。以做逻辑为例,并不是一上来就开始写代码,而是要先写总体设计方案和逻辑详细
设计方案,要等这些方案评审通过,认为可行了,才能进行编码,一般来说这部分工作
所占的时间要远大于编码的时间。
总体方案主要是涉及模块划分,一级模块和二级模块的接口信号和时序(我们要求
把接口信号的时序波形描述出来)以及将来如何测试设计。在这一级方案中,要保证在
今后的设计中时序要收敛到一级模块(最后是在二级模块中)。什么意思呢?我们在做
详细设计的时候,对于一些信号的时序肯定会做一些调整的,但是这种时序的调整最多
只能波及到本一级模块,而不能影响到整个设计。记得以前在学校做设计的时候,由于
不懂得设计时序,经常因为有一处信号的时序不满足,结果不得不将其它模块信号的时
序也改一下,搞得人很郁闷。
在逻辑详细设计方案这一级的时候,我们已经将各级模块的接口时序都设计出来了
,各级模块内部是怎么实现的也基本上确定下来了。
由于做到这一点,在编码的时候自然就很快了,最重要的是这样做后可以让设计会
一直处于可控的状态,不会因为某一处的错误引起整个设计从头进行。

做逻辑的难点在于系统结构设计和仿真验证
刚去公司的时候BOSS就和我讲,做逻辑的难点不在于RTL级代码的设计,而在于系统
结构设计和仿真验证方面。目前国内对可综合的设计强调的比较多,而对系统结构设计
和仿真验证方面似乎还没有什么资料,这或许也从一个侧面反映了国内目前的设计水平
还比较低下吧。
以前在学校的时候,总是觉得将RTL级代码做好就行了,仿真验证只是形式而已,所
以对HDL的行为描述方面的语法不屑一顾,对testbench也一直不愿意去学--因为觉得画
波形图方便;对于系统结构设计更是一点都不懂了。
到了公司接触了些东西才发现完全不是这样。
其实在国外,花在仿真验证上的时间和人力大概是花在RTL级代码上的两倍,现在仿
真验证才是百万门级芯片设计的关键路径。仿真验证的难点主要在于怎么建模才能完全
和准确地去验证设计的正确性(主要是提高代码覆盖),在这过程中,验证速度也是很
重要的。
验证说白了也就是怎么产生足够覆盖率的激励源,然后怎么去检测错误。我个人认
为,在仿真验证中,最基本就是要做到验证的自动化。这也是为什么我们要写testbenc
h的原因。在我现在的一个设计中,每次跑仿真都要一个小时左右(这其实算小设计)。
由于画波形图无法做到验证自动化,如果用通过画波形图来仿真的话,一是画波形会画
死(特别是对于算法复杂的、输入呈统计分布的设计),二是看波形图要看死,三是检
错率几乎为零。
那么怎么做到自动化呢?我个人的水平还很有限,只能简单地谈下BFM(bus funct
ion model,总线功能模型)。
以做一个MAC的core为例(背板是PCI总线),那么我们需要一个MAC_BFM和PCI_BFM
及PCI_BM(PCI behavior model)。MAC_BFM的主要功能是产生以太网帧(激励源),随
机的长度和帧头,内容也是随机的,在发送的同时也将其复制一份到PCI_BM中;PCI_BFM
的功能则是仿PCI总线的行为,比如被测收到了一个正确帧后会向PCI总线发送一个
请求,PCI_BFM则会去响应它,并将数据收进来;PCI_BM的主要功能是将MAC_BFM发送出
来的东西与PCI_BFM接收到的东西做比较,由于它具有了MAC_BFM的发送信息和PCI_BFM的
接收信息,只要设计合理,它总是可以自动地、完全地去测试被测是否工作正常,
从而实现自动检测。
华为在仿真验证方面估计在国内来说是做的比较好的,他们已建立起了比较好的验
证平台,大部分与通信有关的BFM都做好了,听我朋友说,现在他们只需要将被测放
在测试平台中,并配置好参数,就可以自动地检测被测功能的正确与否。
在功能仿真做完后,由于我们做在是FPGA的设计,在设计时已经基本保证RTL级代码
在综合结果和功能仿真结果的一致性,只要综合布局布线后的静态时序报告没有违反时
序约束的警告,就可以下到板子上去调试了。事实上,在华为中兴,他们做FPGA的设计
时也是不做时序仿真的,因为做时序仿真很花时间,且效果也不见得比看静态时序分析
报告好。
当然了,如果是ASIC的设计话,它们的仿真验证的工作量要大一些,在涉及到多时
钟域的设计时,一般还是做后仿的。不过在做后仿之前,也一般会先用形式验证工具和
通过静态时序分序报告去查看有没有违反设计要求的地方,这样做了之后,后仿的工作
量可以小很多。
在HDL语言方面,国内语言很多人都在争论VHDL和verilog哪个好,其实我个人认为
这并没有多大的意义,外面的大公司基本上都是用verilog在做RTL级的代码,所以还是
建议大家尽量学verilog。在仿真方面,由于VHDL在行为级建模方面弱于verilog,用VH
DL做仿真模型的很少,当然也不是说verilog就好,其实verilog在复杂的行为级建模方
面的能力也是有限的,比如目前它还不支持数组。在一些复杂的算法设计中,需要高级
语言做抽象才能描述出行为级模型。在国外,仿真建模很多都是用System C和E语言,用
verilog的都算是很落后的了,国内华为的验证平台好像是用System C写。
在系统结构设计方面,由于我做的设计还不够大,还谈不上什么经验,只是觉得必
须要具备一些计算机系统结构的知识才行。划分的首要依据是功能,之后是选择合适的
总线结构、存储结构和处理器架构,通过系统结构划分要使各部分功能模块清晰,易于
实现。这一部分我想过段时间有一点体会了再和大家分享,就先不误导大家了。

规范很重要
工作过的朋友肯定知道,公司里是很强调规范的,特别是对于大的设计(无论软件
还是硬件),不按照规范走几乎是不可实现的。逻辑设计也是这样:如果不按规范做的
话,过一个月后调试时发现有错,回头再看自己写的代码,估计很多信号功能都忘了,
更不要说检错了;如果一个项目做了一半一个人走了,接班的估计得从头开始设计;如
果需要在原来的版本基础上增加新功能,很可能也得从头来过,很难做到设计的可重用
性。
在逻辑方面,我觉得比较重要的规范有这些:
1.设计必须文档化。要将设计思路,详细实现等写入文档,然后经过严格评审通过
后才能进行下一步的工作。这样做乍看起来很花时间,但是从整个项目过程来看,绝对
要比一上来就写代码要节约时间,且这种做法可以使项目处于可控、可实现的状态。
2.代码规范。
a.设计要参数化。比如一开始的设计时钟周期是30ns,复位周期是5个时钟周期,我
们可以这么写:
parameter CLK_PERIOD = 30;
parameter RST_MUL_TIME = 5;
parameter RST_TIME = RST_MUL_TIME * CLK_PERIOD;
...
rst_n = 1'b0;
# RST_TIME rst_n = 1'b1;
...
# CLK_PERIOD/2 clk <= ~clk;
如果在另一个设计中的时钟是40ns,复位周期不变,我们只需对CLK_PERIOD进行重
新例化就行了,从而使得代码更加易于重用。
b.信号命名要规范化。
1) 信号名一律小写,参数用大写。
2) 对于低电平有效的信号结尾要用_n标记,如rst_n。
3) 端口信号排列要统一,一个信号只占一行,最好按输入输出及从哪个模块来到哪
个模块去的关系排列,这样在后期仿真验证找错时后 方便很多。如:
module a(
//input
clk,
rst_n, //globle signal
wren,
rden,
avalon_din, //related to avalon bus
sdi, //related to serial port input
//output
data_ready,
avalon_dout, //related to avalon bus
...
);
4) 一个模块尽量只用一个时钟,这里的一个模块是指一个module或者是一个en
tity。在多时钟域的设计中涉及到跨时钟域的设计中最好有专门一个模块做时钟域的隔
离。这样做可以让综合器综合出更优的结果。
5) 尽量在底层模块上做逻辑,在高层尽量做例化,顶层模块只能做例化,禁止
出现任何胶连逻辑(glue logic),哪怕仅仅是对某个信号取反。理由同上。
6) 在FPGA的设计上禁止用纯组合逻辑产生latch,带D触发器的latch的是允许的
,比如配置寄存器就是这种类型。
7) 一般来说,进入FPGA的信号必须先同步,以提高系统工作频率(板级)。
8) 所有模块的输出都要寄存器化,以提高工作频率,这对设计做到时序收敛也
是极有好处的。
9) 除非是低功耗设计,不然不要用门控时钟--这会增加设计的不稳定性,在要
用到门控时钟的地方,也要将门控信号用时钟的下降沿 打一拍再输出与时钟相与。
clk_gate_en -------- ----
-----------------|D Q |------------------| \ gate_clk
_out
| | ---------| )--------
-
------o|> | | | /
clk | -------- | ----
------------------------------------
10)禁止用计数器分频后的信号做其它模块的时钟,而要用改成时钟使能的方式
,否则这种时钟满天飞的方式对设计的可靠性极为不利,也大大增加了静态时序分析的
复杂性。如FPGA的输入时钟是25M的,现在系统内部要通过RS232与PC通信,要以rs232_
1xclk的速率发送数据。
不要这样做:
always (posedge rs232_1xclk or negedge rst_n)
begin
...
end
而要这样做:
always (posedge clk_25m or negedge rst_n)
begin
...
else if ( rs232_1xclk == 1'b1 )
...
end
11)状态机要写成3段式的(这是最标准的写法),即
...
always @(posedge clk or negedge rst_n)
...
current_state <= next_state;
...
always @ (current_state ...)
...
case(current_state)
...
s1:
if ...
next_state = s2;
...
...
always @(posedge clk or negedge rst_n)
...
else
a <= 1'b0;
c <= 1'b0;
c <= 1'b0; //赋默认值
case(current_state)
s1:
a <= 1'b0; //由于上面赋了默认值,这里就不用再对b
、c赋值了
s2:
b <= 1'b1;
s3:
c <= 1'b1;
default:
...
...
3.ALTERA参考设计准则
1) Ensure Clock, Preset, and Clear configurations are free of glitch
es.
2) Never use Clocks consisting of more than one level of combinatori
al logic.
3) Carefully calculate setup times and hold times for multi-Clock sy
stems.
4) Synchronize signals between flipflops in multi-Clock systems when
the setup and hold time requirements cannot be met.
5) Ensure that Preset and Clear signals do not contain race conditio
ns.
6) Ensure that no other internal race conditions exist.
7) Register all glitch-sensitive outputs.
8) Synchronize all asynchronous inputs.
9) Never rely on delay chains for pin-to-pin or internal delays.
10)Do not rely on Power-On Reset. Use a master Reset pin to clear al
l flipflops.
11)Remove any stuck states from state machines or synchronous logic.
其它方面的规范一时没有想到,想到了再写,也欢迎大家补充。

如何提高电路工作频率
对于设计者来说,我们当然希望我们设计的电路的工作频率(在这里如无特别说明
,工作频率指FPGA片内的工作频率)尽量高。我们也经常听说用资源换速度,用流水的
方式可以提高工作频率,这确实是一个很重要的方法,今天我想进一步去分析该如何提
高电路的工作频率。
我们先来分析下是什么影响了电路的工作频率。
我们电路的工作频率主要与寄存器到寄存器之间的信号传播时延及clock skew有关
。在FPGA内部如果时钟走长线的话,clock skew很小,基本上可以忽略, 在这里为了简
单起见,我们只考虑信号的传播时延的因素。
信号的传播时延包括寄存器的开关时延、走线时延、经过组合逻辑的时延(这样划
分或许不是很准确,不过对分析问题来说应该是没有可以的),要提高电路的工作频率
,我们就要在这三个时延中做文章,使其尽可能的小。
我们先来看开关时延,这个时延是由器件物理特性决定的,我们没有办法去改变,
所以我们只能通过改变走线方式和减少组合逻辑的方法来提高工作频率。
1.通过改变走线的方式减少时延。
以altera的器件为例,我们在quartus里面的timing closure floorplan可以看到有
很多条条块块,我们可以将条条块块按行和按列分,每一个条块代表1个LAB,每个LAB里
有8个或者是10个LE。它们的走线时延的关系如下:同一个LAB中(最快) < 同列或者同
行 < 不同行且不同列。
我们通过给综合器加适当的约束(不可贪心,一般以加5%裕量较为合适,比如电路
工作在100Mhz,则加约束加到105Mhz就可以了,贪心效果反而不好,且极大增加综合时
间)可以将相关的逻辑在布线时尽量布的靠近一点,从而减少走线的时延。(注:约束
的实现不完全是通过改进布局布线方式去提高工作频率,还有其它的改进措施)
2.通过减少组合逻辑的减少时延。
上面我们讲了可以通过加约束来提高工作频率,但是我们在做设计之初可万万不可
将提高工作频率的美好愿望寄托在加约束上,我们要通过合理的设计去避免出现大的组
合逻辑,从而提高电路的工作频率,这才能增强设计的可移植性,才可以使得我们的设
计在移植到另一同等速度级别的芯片时还能使用。
我们知道,目前大部分FPGA都基于4输入LUT的,如果一个输出对应的判断条件大于
四输入的话就要由多个LUT级联才能完成,这样就引入一级组合逻辑时延,我们要减少组
合逻辑,无非就是要输入条件尽可能的少,,这样就可以级联的LUT更少,从而减少了组
合逻辑引起的时延。
我们平时听说的流水就是一种通过切割大的组合逻辑(在其中插入一级或多级D触发
器,从而使寄存器与寄存器之间的组合逻辑减少)来提高工作频率的方法。比如一个32
位的计数器,该计数器的进位链很长,必然会降低工作频率,我们可以将其分割成4位和
8位的计数,每当4位的计数器计到15后触发一次8位的计数器,这样就实现了计数器的切
割,也提高了工作频率。
在状态机中,一般也要将大的计数器移到状态机外,因为计数器这东西一般是经常
是大于4输入的,如果再和其它条件一起做为状态的跳变判据的话,必然会增加LUT的级
联,从而增大组合逻辑。以一个6输入的计数器为例,我们原希望当计数器计到111100后
状态跳变,现在我们将计数器放到状态机外,当计数器计到111011后产生个enable信号
去触发状态跳变,这样就将组合逻辑减少了。
上面说的都是可以通过流水的方式切割组合逻辑的情况,但是有些情况下我们是很
难去切割组合逻辑的,在这些情况下我们又该怎么做呢?
状态机就是这么一个例子,我们不能通过往状态译码组合逻辑中加入流水。如果我
们的设计中有一个几十个状态的状态机,它的状态译码逻辑将非常之巨大,毫无疑问,
这极有可能是设计中的关键路径。那我们该怎么做呢?还是老思路,减少组合逻辑。我
们可以对状态的输出进行分析,对它们进行重新分类,并根据这个重新定义成一组组小
状态机,通过对输入进行选择(case语句)并去触发相应的小状态机,从而实现了将大的
状态机切割成小的状态机。在ATA6的规范中(硬盘的标准),输入的命令大概有20十种
,每一个命令又对应很多种状态,如果用一个大的状态机(状态套状态)去做那是不可
想象的,我们可以通过case语句去对命令进行译码,并触发相应的状态机,这样做下来
这一个模块的频率就可以跑得比较高了。
总结:提高工作频率的本质就是要减少寄存器到寄存器的时延,最有效的方法就是
避免出现大的组合逻辑,也就是要尽量去满足四输入的条件,减少LUT级联的数量。我们
可以通过加约束、流水、切割状态的方法提高工作频率。

谈VHDL/Verilog的可综合性以及对初学者的一些建议

一、HDL不是硬件设计语言
过去笔者曾碰到过不少VHDL或Verilog HDL的初学者问一些相似的问题,诸如如何实现除法、开根号,如何写循环语句等等。在这个论坛上,也时常能看到一些网友提出这一类的问题。
对于这些问题,首先要明确的是VHDL和Veriglog并非是针对硬件设计而开发的语言,只不过目前被我们用来设计硬件。HDL是Hardware Description Language的缩写,正式中文名称是"硬件描述语言"。也就是说,HDL并不是"硬件设计语言(Hardware Design Language)"。别看只差这一个单词,正是这一个单词才决定了绝大部分电路设计必须遵循RTL的模式来编写代码,而不能随心所欲得写仅仅符合语法的HDL代码。
二、HDL的来历
之所以是"硬件描述语言",要从HDL的来历说起。
VHDL于1980年开始在美国国防部的指导下开发,完成于1983年,并于1987年成为IEEE的标准。当初开发这种语言,是出于美国国防部采购电子 设备的需要。美军的装备采购自私人企业,时常要面对这样一种风险:如果某种武器大量装备部队,而其中某个零件的供应商却在几年后倒闭了,那这种武器的再生 产、维修和保养都会出现大问题。而电子设备、尤其是集成电路的内部结构较为复杂,若出现前面所说的情况要找其他公司生产代用品非常困难。于是美国防部希望 供应商能以某种形式留下其产品的信息,以保证一旦其破产后能由其他厂商迅速生产出代用品。
显然,当初的设计文档显然是不能交出来的,这在美国会涉及商业机密和知识产权问题。于是美国防部就想出了一种折衷的方法――描述硬件的语言,也就是VHDL。通过VHDL,供应商要把自己生产的集成电路芯片的行为描述出来:比如说,加了什么样的信号后过多少时间它能输出什么等等。这样,如果有必要让其他厂商生产代用品,他们只需照着VHDL文档,设计出行为与其相同的芯片即可。这样的代用品相当于是新厂商在不了解原产品结构的情况下独立设计的,所以不太会涉及知识侵权。
Verilog HDL也形成于差不多的年代,是由Gateway Design Automation公司大约在1983年左右开发的。其架构同VHDL相似,但主要被用来进行硬件仿真。或许私人公司更注重实用,Verilog要比VHDL简洁得多。
由此可见,这两种最流行的用于电路设计的语言,没有一种是为了设计硬件而开发的(更何况80年代还没有现在的那些功能强大的EDA软件呢)。因此,当初制订HDL语言标准的时候,并没有考虑这些代码如何用硬件来实现。换句话说,有些代码写起来简单,实现起来却可能非常复杂,或者几乎不可能实现。
三、HDL代码的可综合性
现在回到最初的问题上。为什么诸如除法、循环之类的HDL代码总是会出错?
由上一部分可知,任何符合HDL语法标准的代码都是对硬件行为的一种描述,但不一定是可直接对应成电路的设计信息。行为描述可以基于不同的层次,如系统级,算法级,寄存器传输级(RTL)、门级等等。以目前大部分EDA软件的综合能力来说,只有RTL或更低层次的行为描述才能保证是可综合的。而众多初学者试图做的,却是想让软件去综合算法级或者更加抽象的硬件行为描述。
比如说,要想实现两个变量相除的运算,若在代码中写下C=A/B,你将会发现只有一些模拟软件在前仿真中能正确执行这句代码,但几乎任何软件都不能将其综合成硬件。不要怪软件太笨。试想一下,如果我们自己笔算除法是怎么做的?从高位到低位逐次试除、求余、移位。试除和求余需要减法器,商数和余数的中间结果必须有寄存器存储;而此运算显然不能在一个时钟周期里完成,还需要一个状态机来控制时序。一句简单的C=A/B同所有这些相比显得太抽象,对于只能接受RTL或更低层次描述的EDA软件来说确实太难实现。而如果代码是类似于(Verilog)
always @(posedge clk)
c<=A/B; 这样的,要求除法在一个时钟延上完成,那更是不可能实现的。(注:有些FPGA的配套软件提供乘除法的运算模块,但也只能支持直接调用,不支持把形如C=A/B的语句综合成除法模块。)
又比如,一个很多初学者常见的问题是试图让HDL进行循环运算,形同(Verilog):
for (i=0; iparity = parity xor data[i];
一些功能比较简单的综合软件会完全拒绝综合循环语句;而一些功能较强的软件仅当wordlength是常数的时候能综合;当wordlength为变量 时,任何软件都不能综合上面的语句。这是因为硬件规模必须是有限的、固定的。当综合软件遇到循环语句时,总是将其展开成若干条顺序执行的语句,然后再综合 成电路。若wordlength是常数,则展开的语句数是确定的,具有可综合性;而若它是变量时,展开的语句数不确定,对应的硬件电路数量也不能确定,无 法被综合。或许有人说用计数器就能实现变量循环,但这情形又和上面的除法运算相同。那需要额外的硬件,用来存储中间结果和进行时序控制,象上面那样的循环 语句对此描述得太抽象,软件接受不了。
四、如何判断自己写的代码是可综合的?
用一句简单的话概括:电脑永远没有你聪明。具体来说,通常EDA软件对HDL代码的综合能力总是比人差。对于一段代码,如果你不能想象出一个较直观的硬件 实现方法,那EDA软件肯定也不行。比如说,加法器、多路选择器是大家都很熟悉的电路,所以类似A B-C,(A>B)?C这 样的运算一定可以综合。而除法、开根、对数等等较复杂的运算,必须通过一定的算法实现,没有直观简单的实现方法,则可以判断那些计算式是不能综合的,必须 按它们的算法写出更具体的代码才能实现。此外,硬件无法支持的行为描述,当然也不能被综合(比如想在FPGA上实现DDR内存那样的双延触发逻辑,代码很 容易写,但却不能实现)。
不过,这样的判断标准非常主观模糊,遇到具体情况还得按设计人员自己的经验来判断。如果要一个相对客观的标准,一般来说:在RTL级的描述中,所有逻辑运 算和加减法运算、以及他们的有限次组合,基本上是可综合的,否则就有无法综合的可能性。当然,这样的标准仍然有缺陷,更况且EDA的技术也在不断发展,过 去无法综合的代码或许将来行,某些软件不支持的代码换个软件或许行。比如固定次数的循环,含一个常数参数的乘法运算等等,有些EDA软件支持对它们的综 合,而有些软件不行。
所以,正确的判断仍然要靠实践来积累经验。当你可以较准确判断代码的可综合性的时候,你对HDL的掌握就算完全入门了。
作者:董培良
电机和电子工程系博士生
英国University of Nottingham

关于嵌入式几个发展方向的前途(ZZ)

关于嵌入式几个发展方向的前途这或许是很多人想问的一个问题,学习嵌入式前途如何呢?
嵌入式在软件、硬件、开发平台、人才需求、应用领域、培训领域等都处在快速增长、逐步成熟的阶段,很多高校也逐渐开始嵌入式专业课程,企业对嵌入式人才的需求正在增加,高校师生、企业员工很多都开始转向嵌入式开发。 相比起普通IT开发,嵌入式开发薪资待遇更好。今天看了21ic的一个帖子,也顺便转过来,可以作为一种参考~ 嵌入式以下几方面: (1)嵌入式硬件 (2)BSP bootloader (3)内核 驱动 (4)上层应用
以我在嵌入式系统的从业的情况大体是这样,仅供参考 如果在一个层面上有六年及以上工作经验的话,以六年为准。 (1)嵌入式硬件   ---8000-12000,正常价为10000
(2)BSP bootloader ---10000-20000,正常价为15000
(3)内核驱动    ---10000-15000,正常价为12000
(4)上层应用    ---8000-10000,正常价为8000
另外和行业还有关系,比如,做手机公司还要相对高些。 这些情况一般是在外企公司或国内大公司的情况。小公司很少能开到这个价。 因此说什么公司用什么样的人,是有一定道理的。 还有这四层都是很有前途的,关键要根据自己的特长选择做那一层面,一个学计算机专业的人去搞硬件有点不太好搞,在基础这块就要比电子工程类专业的欠缺。 以上这些仅供参考,但目前国内能真正在嵌入式系统这块做上六年的都很少很少。国内嵌入式系统是从当年的Motorola的68K体系结构的DragonBall开始的,那个时间就是1999年,2000年底-2001年夏才达到了最高时期,以后才是ARM开始接替。