Verilog经验谈
每天多学一点:Verilog编写技巧(一)
每天多学一点:Verilog编写技巧(一)来源:网路素材好的设计者一般都要对电路要实现的功能有清晰的认识,对数据流很清楚,知道数据如何从一个点移动到另一个点,这就是所谓的“勾划”(walk-through)。
一旦设计蓝图在脑海中变得清晰,此后釆用Verilog编写数据路径和控制逻辑就会变得思路清晰。
脑海中的模拟正如大多数人玩过的象棋游戏,我们都知道提前谋划是何等重要,要在下一次移动棋子之前考虑好此后的几步棋应该怎么走,以确保不会出错,不被对手捕捉到机会。
电路设计过程与下棋非常相似。
当设计状态机、数据路径或者控制逻辑时,我们知道它们的功能。
在进行设计仿真之前,我们需要思考代码在不同输入和边界条件下如何工作。
如果用心去做好这一步工作,并且分析可能出现的问题,验证工作将会变得非常高效。
另外,这一步也给我们建立了自信,使我们确信整个设计非常扎实,可以很好地工作。
否则很可能出现的情况是在验证阶段反复发现问题并进行电路修改,不断进行补救T.作,并且最终也不能确定设计足否还隐含着没有被发现的问题。
哪种风格—数据流或算法描述组合逻辑有两种方式—使用wire(对应数据流描述方式)或者使用reg(对应算法描述方式)。
这两种方式都能实现相同的逻辑功能,综合后得到相同的门电路,具体使用哪一种方式可以根据个人喜好。
数据流—短表达式举例wire [7:0] regl0_nxt;assign regl0_nxt = wren ? data_in : regl0;算法—短表达式举例reg [7:0] regl0_nxt;always @(*) beginreglO_nxt = reglO;if (wren)regl0_nxt = data_in;end当表达式非常简单时,一般更倾向于使用数据流风格来实现,此时代码行数很少。
然而,当表达式很长并且与很多条件有关时,数据流风格阅读起来较为费力。
此时可以使用算法风格,可以采用if-else 语句进行描述,以易于阅读和减少错误发生。
verilog课程期末总结
verilog课程期末总结一、引言Verilog(硬件描述语言)是一种用于描述电子系统的硬件结构和行为的语言,它广泛用于设计和验证数字电路,尤其是在集成电路和FPGA设计中。
在本学期的Verilog课程中,我们学习并实践了Verilog语言的基本概念和设计技巧,通过实验和项目开发,我们对Verilog语言的使用和应用有了更深入的了解。
本文将对这门课程进行总结,包括所学内容、实践经验以及未来的发展方向。
二、课程内容回顾本学期的Verilog课程共包含以下几个部分的内容:1. Verilog的基本语法和数据类型:在这个部分,我们学习了Verilog的基本语法,如模块定义、端口声明、数据类型定义等。
我们了解了如何使用Verilog语言进行模块化设计,利用不同的数据类型来描述数字电路中的信号和寄存器。
2. Verilog建模:这个部分教授了如何使用Verilog语言来建模和设计数字电路。
我们学习了组合逻辑和时序逻辑的建模方法,掌握了常用的门级建模和行为级建模技巧。
3. Verilog仿真:通过仿真可以验证我们设计的电路是否符合功能和时序的要求。
在这个部分,我们学习了如何使用Verilog语言进行仿真,以及如何编写仿真测试平台、编写仿真测试用例等。
通过仿真,我们可以对设计进行调试和验证,同时也方便了我们对电路性能和时序约束的分析。
4. Verilog项目开发:最后一个部分是课程的项目开发,通过一个实际项目的设计和实现,我们将所学的Verilog知识应用到实践中。
这个项目的设计还涉及模块间的通信和数据处理等方面,对我们综合运用所学知识的能力提出了更高的要求。
三、实践经验总结在学习和实践Verilog语言的过程中,我积累了一些宝贵的经验。
以下是我总结的几点实践经验:1. 充分理解和熟练掌握语法规则:Verilog语言的语法规则对于我们正确理解和使用这门语言非常重要。
通过不断的练习和实践,我渐渐熟练掌握了Verilog的语法规则,如模块的定义、端口的声明、数据类型的使用等。
个人总结FPGA设计中Verilog编程的27条经验
个人总结Verilog编程27条经验1.强烈建议用同步设计;2.在设计时总是记住时序问题;3.在一个设计开始就要考虑到地电平或高电平复位、同步或异步复位、上升沿或下降沿触发等问题,在所有模块中都要遵守它;4.在不同的情况下用if和case,最好少用if的多层嵌套(1层或2层比较合适,当在3层以上时,最好修改写法,因为这样不仅可以reduce area,而且可以获得好的timing);5.在锁存一个信号或总线时要小心,对于整个design,尽量避免使用latch,因为在DFT时很难test;6.确信所有的信号被复位,在DFT时,所有的FlipFlop都是controllable;7.永远不要再写入之前读取任何内部存储器(如SRAM);8.从一个时钟到另一个不同的时钟传输数据时用数据缓冲,他工作像一个双时钟FIFO(是异步的),可以用Async SRAM搭建Async FIFO;9.在VHDL中二维数组可以使用,它是非常有用的。
在VERILOG中他仅仅可以使用在测试模块中,不能被综合;10.遵守register-in register-out规则;11.像synopsys的DC的综合工具是非常稳定的,任何bugs都不会从综合工具中产生12.确保FPGA版本与ASIC的版本尽可能的相似,特别是SRAM类型,若版本一致是最理想的,但是在工作中FPGA版本一般用FPGA自带的SRAM,ASIC版本一般用厂商提供的SRAM;13.在嵌入式存储器中使用BIST;14.虚单元和一些修正电路是必需的;15.一些简单的测试电路也是需要的,经常在一个芯片中有许多测试模块;16.除非低功耗不要用门控时钟,强烈建议不要在design中使用gate clock;17.不要依靠脚本来保证设计。
但是在脚本中的一些好的约束能够起到更好的性能(例如前向加法器);18.如果时间充裕,通过时钟做一个多锁存器来取代用MUX;19.不要用内部tri-state, ASIC需要总线保持器来处理内部tri-state,如IOcell;20.在top level中作pad insertion;21.选择pad时要小心(如上拉能力,施密特触发器,5伏耐压等),选择合适的IO cell;22.小心由时钟偏差引起的问题;23.不要试着产生半周期信号;24.如果有很多函数要修正,请一个一个地作,修正一个函数检查一个函数;25.在一个计算等式中排列每个信号的位数是一个好习惯,即使综合工具能做;26.不要使用HDL提供的除法器;27.削减不必要的时钟。
初学者学习Verilog HDL的步骤和经验技巧
初学者学习Verilog HDL的步骤和经验技巧Verilog HDL是一种硬件描述语言(HDL:Hardware DiscripTIon Language),Verilog HDL语言是一种以文本形式来描述数字系统硬件的结构和行为的语言,用它可以表示逻辑电路图、逻辑表达式,还可以表示数字逻辑系统所完成的逻辑功能。
Verilog HDL和VHDL是目前世界上最流行的两种硬件描述语言,都是在20世纪80年代中期开发出来的。
前者由Gateway Design AutomaTIon公司(该公司于1989年被Cadence 公司收购)开发。
两种HDL均为IEEE标准Verilog HDL语言学习用途就是在最广泛的C语言的基础上发展起来的一种件描述语言,它是由GDA(Gateway Design AutomaTIon)公司的PhilMoorby在1983年末首创的,最初只设计了一个仿真与验证工具,之后又陆续开发了相关的故障模拟与时序分析工具。
1985年Moorby推出它的第三个商用仿真器Verilog-XL,获得了巨大的成功,从而使得Verilog HDL迅速得到推广应用。
1989年CADENCE公司收购了GDA公司,使得VerilogHDL成为了该公司的独家专利。
1990年CADENCE公司公开发表了Verilog HDL,并成立LVI组织以促进Verilog HDL成为IEEE标准,即IEEE Standard 1364-1995.Verilog HDL的最大特点就是易学易用,如果有C语言的编程经验,可以在一个较短的时间内很快的学习和掌握,因而可以把Verilog HDL内容安排在与ASIC设计等相关课程内部进行讲授,由于HDL语言本身是专门面向硬件与系统设计的,这样的安排可以使学习者同时获得设计实际电路的经验。
与之相比,VHDL的学习要困难一些。
但Verilog HDL较**的语法,也容易造成初学者犯一些错误,这一点要注意。
verilog学习经验
8. 用test bench等工具针对大的工程进行仿真,quarters用来做小的,比如计数器。
9. 站在一定的高度看:FPGA内部的问题都是小问题,而接口往往较难,比如异步时钟问题,可能与内部不一致。
10. 在写代码的时候就不要写不可综合的语句,这样前仿出来之后,后仿就并不是很费事,只是有资源的约束而已。
1. wire与reg之外的数据类型不要在verilog代码中出现。
2. assign(组合逻辑)与always之外的语句不要在verilog代码中出现。
3. 一个module最好一个always,再加若干assign,这样便于控制。
4. verilog中无函数调用及函数传递,都转化成input、output接口。
写代码之前,先找个规范看看,比如华为的,然后规规矩矩的写,后仿真就会快的多。
11. 不同模块的调用以时序来控制,且确保一个模块是以整体的形式进行工作(即并行)。换言之,用状态信号控制不同模块的启用,配合状态机加以控制。
12. 一定要采用同步处理,即在同一时钟下,所有数据要受信号控制。
17. RAM分内外,内部是指FPGA内,外部的是在板子上连接的器件。如果用外部的RAM,在做板子之前可以用数组的方式模拟外部RAM。
18. 处理输入的几种方式:
需要什么,送入什么,用时序和信号进行控制;
一个时钟送入一个,送入的先寄存下来;
也可以将总线放宽,一次传入更多的数据。
5. 不建议使用for循环,因为看不到其电路是什么样子。
For可以用状态机控制,状态机可以打圈,定义一个计数器,做为循环的索引。
动态次数的循环,用一个寄存器记录处理的次数,再加一个状态信号判结束。
解读verilog代码的一点经验
解读verilog代码的一点经验学习其实也不算久,开头的时候参考别人的代码并不多,大多是自己写的,那时候做时序规律多一些。
参与了中嵌的培训班,一个多月的时光在认识ISE软件的用法以及verilog语法方面下了苦功,也参考了不少书,算是为自己打下了比较好的基础。
由于那时候培训的方向是软件方面的,所以做了无数有关的模块程序,之前的日志里也发表了无数,关键是一个爱好,感觉后看到自己的一个个算法思想得到实现真有成就感。
后来停了一段时光,由于实在没有比较故意思的活干了。
直到前段时光开头用法SP306的开发板,然后会参考它们的代码,受益匪浅吧。
现在组长已经给正活干了,跟的大项目我是基本都有所认识了,然后那个里面做总控的FPGA的代码开头举行总攻了,要把前辈们的代码都消化了,然后更好的为下一代升级版的产品服务。
这个看verilog 程序估量是大家都比较头疼的事,小的模块都没问题,大模块大项目,有时候就比较难以入手了,由于HDL的设计是不同于软件编程的,软件其实无非一个大while或者再有一些中断,大多是挨次执行的,渐渐一步一步往下走总会弄明了。
HDL的并行性很强,要是你根据软件的思路来那绝对行不通,那么该怎么办呢?我就班门弄斧说点自己的一点迅速进阶的小窍门吧。
既然HDL设计是并行的,那么就只能各个击破了。
我的习惯是先抓几个重要端口,比如时钟(CLK)、复位(RESET)等浮现频率比较高的端口,把它先弄清晰,比如时钟是什么频率的?复位是高有效还是低有效? 然后呢,最好是对比原理图来理解程序。
这就需要你有一定功底的硬件常识了,一些常用器件的操作时序什么的一定要做到胸有成竹,起码要知其一二吧,这样在读程序时才会达到事半功倍的效果。
比例说你要先读懂FPGA与AD芯片的程序,那么你先把AD的各个端口(如片选,读写,转换,转换完成中断等端口)在verilog程序中浮现的地方多做一下分析,比如我找CS信号,看看什么时候它拉低有效,那么你可以在Find in file窗口中输入CS,然后ENTER,这样ISE就会在底层的信息窗口中排列出全部用法了CS信号的语句便利你的查找分析,你把每个浮现CS的地方分析到了,那么你就明了verilog在硬件上是如何操作CS信号的。
初学者学习Verilog HDL的步骤和经验技巧
初学者学习Verilog HDL的步骤和经验技巧Verilog HDL是一种硬件描述语言(HDL:Hardware DiscripTIon Language),Verilog HDL语言是一种以文本形式来描述数字系统硬件的结构和行为的语言,用它可以表示逻辑电路图、逻辑表达式,还可以表示数字逻辑系统所完成的逻辑功能。
Verilog HDL和VHDL是目前世界上最流行的两种硬件描述语言,都是在20世纪80年代中期开发出来的。
前者由Gateway Design AutomaTIon公司(该公司于1989年被Cadence 公司收购)开发。
两种HDL均为IEEE标准Verilog HDL语言学习用途就是在最广泛的C语言的基础上发展起来的一种件描述语言,它是由GDA(Gateway Design AutomaTIon)公司的PhilMoorby在1983年末首创的,最初只设计了一个仿真与验证工具,之后又陆续开发了相关的故障模拟与时序分析工具。
1985年Moorby推出它的第三个商用仿真器Verilog-XL,获得了巨大的成功,从而使得Verilog HDL迅速得到推广应用。
1989年CADENCE公司收购了GDA公司,使得VerilogHDL成为了该公司的独家专利。
1990年CADENCE公司公开发表了Verilog HDL,并成立LVI组织以促进Verilog HDL成为IEEE标准,即IEEE Standard 1364-1995.Verilog HDL的最大特点就是易学易用,如果有C语言的编程经验,可以在一个较短的时间内很快的学习和掌握,因而可以把Verilog HDL内容安排在与ASIC设计等相关课程内部进行讲授,由于HDL语言本身是专门面向硬件与系统设计的,这样的安排可以使学习者同时获得设计实际电路的经验。
与之相比,VHDL的学习要困难一些。
但Verilog HDL较**的语法,也容易造成初学者犯一些错误,这一点要注意。
verilog设计经验浅谈
因为Verilog是一种硬件描述语言,所以在写Verilog语言时,首先要有所要写的module在硬件上如何实现的概念,而不是去想编译器如何去解释这个module. 比如在决定是否使用reg定义时,要问问自己物理上是不是真正存在这个register, 如果是,它的clock是什么? D端是什么?Q端是什么?有没有清零和置位?同步还是异步?再比如上面讨论的三态输出问题,首先想到的应该是在register的输出后面加一个三态门,而不是如何才能让编译器知道要“赋值”给一个信号为三态。
同样,Verilog中没有“编译”的概念,而只有综合的概念。
verilog设计经验浅谈1,敏感变量的描述完备性V erilog中,用always块设计组合逻辑电路时,在赋值表达式右端参与赋值的所有信号都必须在always@(敏感电平列表)中列出,always中if语句的判断表达式必须在敏感电平列表中列出。
如果在赋值表达式右端引用了敏感电平列表中没有列出的信号,在综合时将会为没有列出的信号隐含地产生一个透明锁存器。
这是因为该信号的变化不会立刻引起所赋值的变化,而必须等到敏感电平列表中的某一个信号变化时,它的作用才表现出来,即相当于存在一个透明锁存器,把该信号的变化暂存起来,待敏感电平列表中的某一个信号变化时再起作用,纯组合逻辑电路不可能作到这一点。
综合器会发出警告。
Example1:input a,b,c;reg e,d;always @(a or b or c)begine=d&a&b; /*d没有在敏感电平列表中,d变化时e不会立刻变化,直到a,b,c中某一个变化*/d=e |c;endExample2:input a,b,c;reg e,d;always @(a or b or c or d)begine=d&a&b; /*d在敏感电平列表中,d变化时e立刻变化*/d=e |c;end2, 条件的描述完备性如果if语句和case语句的条件描述不完备,也会造成不必要的锁存器。
Verilog 开发经验总结说明书
Verilog 开发经验总结●以硬件为基础的原则Verilog是硬件描述语言,所谓描述就是是在在描绘已经设计好的电路。
尤其是在刚开始学习HDL时,还没有能直接把语言对应到具体电路的能力,更不能上手直接写Verilog代码。
所以最优方案是先设计好硬件电路,再按照电路编写Verilog。
●模块化思想这个思想不仅仅是Verilog的开发了,就算是C语言甚至现在的超高级语言,也一直在强调封装的概念。
Verilog开发遵循的是自顶向下的模块化设计,思路基本是从最终功能不断细分,直到Verilog可以很直接地描述最基础的硬件单元,例如加法器,移位寄存器等等。
模块划分一定要尽量细,功能单一,且一定要留出使能、复位等接口以便于系统搭建。
说明以下,所谓Verilog可直接描述指的是按照规范描述出来的电路,开发工具能够很清晰地理解所要描述的功能,而不会发生误解等现象。
一个只使用编译器能理解的代码开发的电路,错误率会大大降低。
相反,如果功能划分不够清晰,使得一个模块的功能过于庞杂,不仅描述困难,编译器也可能产生很大的误解。
把握编译器的理解方式是有助于做Verilog的开发的,但这就需要一个长远的积累了,我在最后会给出一些例子。
●时序电路与逻辑电路完全分开Verilog中除了数据流模型和门级模型以外,最常用的是always即行为级模型描述电路。
一个always块可以理解为一个电路,或者实物上的一个芯片。
所以不要在一个always里杂糅时序电路和逻辑电路,那样很可能导致编译器综合出一些奇葩的结果。
时序always模块的敏感变量有且最多两个,一个是时钟边沿,一个是复位边沿,没有再多的敏感变量了。
组合逻辑always中敏感变量列表必须包含该模块所有涉及到的变量,或者直接用(*)代替,个人推荐后者。
●时序always块编写规范在时序always中,统一使用非阻塞赋值<=,因为时序always中在赋值号左侧的变量是真实的触发器,非阻塞赋值在触发时是同时赋值的,这很符合触发器在上升沿到来后同时将D输出到Q的实际情况。
个人总结Verilog代码编写的25条经验
个人总结Verilog代码编写的25条经验1、对所有的信号名、变量名和端口名都用小写,这样做是为了和业界的习惯保持一致;对常量名和用户定义的类型用大写;2、使用有意义的信号名、端口名、函数名和参数名;3、信号名长度不要太长;4、对于时钟信号使用clk 作为信号名,如果设计中存在多个时钟,使用clk 作为时钟信号的前缀;5、对来自同一驱动源的信号在不同的子模块中采用相同的名字,这要求在芯片总体设计时就定义好顶层子模块间连线的名字,端口和连接端口的信号尽可能采用相同的名字;6、对于低电平有效的信号,应该以一个下划线跟一个小写字母b 或n 表示。
注意在同一个设计中要使用同一个小写字母表示低电平有效;7、对于复位信号使用rst 作为信号名,如果复位信号是低电平有效,建议使用rst_n;8、当描述多比特总线时,使用一致的定义顺序,对于verilog 建议采用bus_signal[x:0]的表示;9、尽量遵循业界已经习惯的一些约定。
如*_r 表示寄存器输出,*_a 表示异步信号,*_pn 表示多周期路径第n 个周期使用的信号,*_nxt 表示锁存前的信号,*_z 表示三态信号等;10、在源文件、批处理文件的开始应该包含一个文件头、文件头一般包含的内容如下例所示:文件名,作者,模块的实现功能概述和关键特性描述,文件创建和修改的记录,包括修改时间,修改的内容等;11、使用适当的注释来解释所有的always 进程、函数、端口定义、信号含义、变量含义或信号组、变量组的意义等。
注释应该放在它所注释的代码附近,要求简明扼要,只要足够说明设计意图即可,避免过于复杂;12、每一行语句独立成行。
尽管VHDL 和Verilog 都允许一行可以写多个语句,当时每个语句独立成行可以增加可读性和可维护性。
同时保持每行小于或等于72 个字符,这样做都是为了提高代码得可读性;13、建议采用缩进提高续行和嵌套语句得可读性。
缩进一般采用两个空格,如西安交通大学SOC 设计中心2 如果空格太多则在深层嵌套时限制行长。
关于verilog的学习经验简单分享
关于verilog的学习经验简单分享 我学verilog语言进行FPGA设计也就半年时间,很多的东西就是在网上学到的,现在想说说自己对使用verilog进行FPGA设计的一些体会,我水平不高,主要是为新手朋友们介绍自己的一点经验少走点弯路。
1、verilog语言 学习verilog最重要的不是语法,因为10%的语法就能完成90%的工作,verilog语言常用语言就是always@(),if~else,case,assign这几个了,不用去专研繁杂的语法,有些问题等你碰到了查查书就好了。
这里推荐夏雨闻老师的《verilog数字系统设计教程》,一本很适合新手的好书。
2、硬件原则 虽然verilog语言很象c语言,但它和c语言还是有本质的区别的,因为verilog进行的是硬件设计,你写出来的东西是实实在在电路,所以要有数字电路的知识是肯定的。
数字电路就是由时序电路(触发器)和组合逻辑电路(各种逻辑门)构成的,用verilog写的程序在FPGA实现就是触发器和逻辑门,所以最重要的就是你对你写的语言生成的电路心中有数,做到这一点你就不会有写出来的程序不能综合的麻烦,电路的冗余逻辑肯定也是最少的。
还要注意一点就是verilog程序是并行的,不是象c那样是顺序执行的,这是因为fpga硬件可配置,可形成不同的任务单元同时工作;而单片机这种基于通用目的,硬件结构也固定了,它处理任务只能一件一件顺序的进行。
3、同步原则 在进行FPGA设计的时候,同步原则应该是最重要的原则之一了,因为异步电路的不可控性,很可能有毛刺产生,而在芯片内部的任何一点毛刺都会一级一级的传递下去,最终影响系统的稳定性。
同步原则用一句话来总结就是不要试图产生自己的时钟,最好一个设计或者一个模块只使用同一个时钟,这样所有的触发器都在同一个时钟沿跳变,当然最稳定了,系统也能跑到很高的速度。
一个小技巧就是多使用触发器的使能端和取沿电路。
4、养成好的代码习惯 很多的细节,比如缩进、命名、参数化、组合逻辑和时序逻辑分离、注释等等,也就是大家说的代码风格。
Verilog学习心得
Verilog学习心得因为Verilog是一种硬件描述语言,所以在写Verilog语言时,首先要有所要写的module在硬件上如何实现的概念,而不是去想编译器如何去解释这个module. 比如在决定是否使用reg定义时,要问问自己物理上是不是真正存在这个register, 如果是,它的clock是什么? D端是什么?Q端是什么?有没有清零和置位?同步还是异步?再比如上面讨论的三态输出问题,首先想到的应该是在register的输出后面加一个三态门,而不是如何才能让编译器知道要“赋值”给一个信号为三态。
同样,Verilog中没有“编译”的概念,而只有综合的概念。
写硬件描述语言的目的是为了综合,所以说要想写的好就要对综合器有很深的了解,这样写出来的代码才有效率。
曾经接触过motorola苏州设计中心的一位资深工程师,他忠告了一句:就是用verilog描述电路的时候,一定要清楚它实现的电路,很多人只顾学习verilog语言,而不熟悉它实现的电路,这是设计不出好的电路来的.一般写verilog code时,对整个硬件的结构应该是很清楚了,最好有详细的电路图画出,时序问题等都应该考虑清楚了。
可以看着图直接写code。
要知道,最初Verilog是为了实现仿真而发明的.不可综合的Verilog 语句也是很重要的.因为在实际设计电路时,除了要实现一个可综合的module外,你还要知道它的外围电路是怎样的,以及我的这个电路与这些外围电路能否协调工作.这些外围电路就可以用不可综合的语句来实现而不必管它是如何实现的.因为它们可能已经实际存在了,我仅是用它来模拟的.所以,在写verilog的时候应该要先明确我是用它来仿真的还是综合的.要是用来综合的话,就必须要严格地使用可综合的语句,而且不同的写法可能产生的电路会有很大差别,这时就要懂一些verilog综合方法的知识.就像前面说的,脑子里要有一个硬件的概念.特别是当综合报错时,就要想一想我这种写法能不能用硬件来实现,verilog毕竟还不是C,很多写法是不可实现的.要是这个module仅是用来仿真的,就要灵活得多了,这时你大可不必太在意硬件实现.只要满足它的语法,实现你要的功能就行了.有网友说关于#10 clk=~clk的问题,虽然这种语句是不可综合的,但是在做simulation和verification是常常用它在testbench中来产生一个clock信号。
veriloghdl学习心得
竭诚为您提供优质文档/双击可除veriloghdl学习心得篇一:Verilog学习心得Verilog学习心得因为Verilog是一种硬件描述语言,所以在写Verilog语言时,首先要有所要写的module在硬件上如何实现的概念,而不是去想编译器如何去解释这个module.比如在决定是否使用reg定义时,要问问自己物理上是不是真正存在这个register,如果是,它的clock是什么?D端是什么?Q端是什么?有没有清零和置位?同步还是异步?再比如上面讨论的三态输出问题,首先想到的应该是在register的输出后面加一个三态门,而不是如何才能让编译器知道要“赋值”给一个信号为三态。
同样,Verilog 中没有“编译”的概念,而只有综合的概念。
写硬件描述语言的目的是为了综合,所以说要想写的好就要对综合器有很深的了解,这样写出来的代码才有效率。
曾经接触过motorola苏州设计中心的一位资深工程师,他忠告了一句:就是用verilog描述电路的时候,一定要清楚它实现的电路,很多人只顾学习verilog语言,而不熟悉它实现的电路,这是设计不出好的电路来的.一般写verilogcode时,对整个硬件的结构应该是很清楚了,最好有详细的电路图画出,时序问题等都应该考虑清楚了。
可以看着图直接写code。
要知道,最初Verilog是为了实现仿真而发明的.不可综合的Verilog语句也是很重要的.因为在实际设计电路时,除了要实现一个可综合的module外,你还要知道它的外围电路是怎样的,以及我的这个电路与这些外围电路能否协调工作.这些外围电路就可以用不可综合的语句来实现而不必管它是如何实现的.因为它们可能已经实际存在了,我仅是用它来模拟的.所以,在写verilog的时候应该要先明确我是用它来仿真的还是综合的.要是用来综合的话,就必须要严格地使用可综合的语句,而且不同的写法可能产生的电路会有很大差别,这时就要懂一些verilog综合方法的知识.就像前面说的,脑子里要有一个硬件的概念.特别是当综合报错时,就要想一想我这种写法能不能用硬件来实现,verilog毕竟还不是c,很多写法是不可实现的.要是这个module仅是用来仿真的,就要灵活得多了,这时你大可不必太在意硬件实现.只要满足它的语法,实现你要的功能就行了.有网友说关于#10clk=~clk的问题,虽然这种语句是不可综合的,但是在做simulation和verification是常常用它在testbench中来产生一个clock信号。
Verilog经验谈
rst_n = 1'b0;
# RST_TIME rst_n = 1'b1;
...
# CLK_PERIOD/2 clk <= ~clk;
如果在另一个设计中的时钟是40ns,复位周期不变,我们只需对CLK_PERIOD进行重
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.
-
------o|> | | | /
clk | -------- | ----
------------------------------------
10)禁止用计数器分频后的信号做其它模块的时钟,而要用改成时钟使能的方式
,否则这种时钟满天飞的方式对设计的可靠性极为不利,也大大增加了静态时序分析的
复杂性。如FPGA的输入时钟是25M的,现在系统内部要通过RS232与PC通信,要以rs232_
1xclk的速率发送数据。
不要这样做:
果需要在原来的版本基础上增加新功能,很可能也得从头来过,很难做到设计的可重用
性。
在逻辑方面,我觉得比较重要的规范有这些:
1.设计必须文档化。要将设计思路,详细实现等写入文档,然后经过严格评审通过后才能进行下一步的工作。这样做乍看起来很花时间,但是从整个项目过程来看,绝对要比一上来就写代码要节约时间,且这种做法可以使项目处于可控、可实现的状态。
verilog_经验(适合初学者)
综合时不能正确地映射到所用的门。 12、IF: 如果变量没有在 IF 语句的每个分支中进行赋值,将会产生 latch。如果 IF 语句中产生了 latch,则 IF 的条件中最好不要用到算术操作。Case 语句类似。Case 的条款可以是变量。 如果一个变量在同一个 IF 条件分支中先赎值然后读取,则不会产生 latch。如果先读取,后赎值,则会 产生 latch。 13、循环: 只有 for-loop 语句是可以综合的。 14、设计时序电路时,建议变量在 always 语句中赋值,而在该 always 语句外使用,使综合时能准确 地匹配。建议不要使用局部变量。 15、不能在多个 always 块中对同一个变量赎值 16、函数 函数代表一个组合逻辑,所有内部定义的变量都是临时的,这些变量综合后为 wire。 17、任务: 任务可能是组合逻辑或者时序逻辑,取决于何种情况下调用任务。 18、Z: Z 会综合成一个三态门,必须在条件语句中赋值 19、参数化设计: 优点:参数可重载,不需要多次定义模块 四:模块优化 1、资源共享: 当进程涉及到共用 ALU 时,要考虑资源分配问题。可以共享的操作符主要有:关系操作符、加减乘除 操作符。通常乘和加不共用 ALU,乘除通常在其内部共用。 2、共用表达式: 如:C=A+B; D=G+(A+B); 两者虽然有共用的A+B,但是有些综合工具不能识别.可以将第二句改为:D=G+C;这样只需两个 加法器. 3、转移代码: 如循环语句中没有发生变化的语句移出循环. 4、避免 latch: 两种方法:1、在每一个 IF 分支中对变量赋值。2、在每一个 IF 语句中都对变量赋初值。 5:模块: 综合生成的存储器如 ROM 或 RAM 不是一种好方法,只是成堆的寄存器,很费资源。最好用库自带的 存储器模块。 五、验证: 1、敏感表: 在 always 语句中,如果敏感表不含时钟,最好将所有的被读取的信号都放在敏感表中。 2、异步复位: 建议不要在异步时对变量读取,即异步复位时,对信号赋以常数值。 Averilog 的流行,有两方面的原因; B verilog 与 VHDL 相比的优点 C 典型的 verilog 模块 D verilog 语法要点 A) verilog 的流行,有两方面的原因:
Verilog基本知识_下_
Verilog基本知识_下_图1-3TOP_DOWN设计思想HDL的推⼴和发展。
由于Verilog HDL设计⽅法的与⼯艺⽆关性,因⽽⼤⼤提⾼了Verilog模型的可重⽤性。
功能经过验证的、可综合的、实现后电路结构总门数在5000门以上的Verilog HDL模型称之为“软核”(Soft Core)。
⽽把由软核构成的器件称为虚拟器件,在新电路的研制过程中,软核和虚拟器件可以很容易地借助EDA综合⼯具与其它外部逻辑结合为⼀体。
这样,软核和虚拟器件的重⽤性就可⼤⼤缩短设计周期,加快了复杂电路的设计。
⽬前国际上有⼀个叫作虚拟接⼝联盟的组织(Virtual SocketInterface Alliance)来协调这⽅⾯的⼯作。
软核、固核和硬核的概念以及重⽤上⼀节中介绍了软核的概念,下⾯再介绍⼀下固核(Firm Core)和硬核(Hard Core)的概念。
在某⼀种现场可编程门阵列(FPGA)器件上实现的,经验证是正确的总门数在5000门以上电路结构编码⽂件,称之为“固核”。
在某⼀种专⽤集成电路(ASIC)器件上实现的经验证是正确的总门数在5000门以上的电路结构版图掩膜,称之为“硬核”。
显⽽易见,在具体实现⼿段和⼯艺技术尚未确定的逻辑设计阶段,软核具有最⼤的灵活性,它可以很容易地借助EDA综合⼯具与其它外部逻辑结合为⼀体。
当然,由于实现技术的不确定性,有可能要作⼀些改动以适应相应的⼯艺。
相⽐之下固核和硬核与其它外部逻辑结合为⼀体的灵活性要差得多,特别是电路实现⼯艺技术改变时更是如此。
⽽近年来电路实现⼯艺技术的发展是相当迅速的,为了逻辑电路设计成果的积累,和更快更好地设计更⼤规模的电路,发展软核的设计和推⼴软核的重⽤技术是⾮常有必要的。
新⼀代的数字逻辑电路设计师必须掌握这⽅⾯的知识和技术。
Verilog HDL设计流程简介⾃顶向下(Top-Down)设计的基本概念现代集成电路制造⼯艺技术的改进,使得在⼀个芯⽚上集成数⼗万乃⾄数千万个器件成为可能。
VerilogFPGA入门笔记(源于学习经验积累)
FPGA入门笔记(源于学习经验积累)17.verilog特点:区分大小写,所有关键字都要求小写不是强类型语言,不同类型数据之间可以赋值和运算//是单行注释可以跨行注释描述风格有系统级描述、行为级描述、RTL级描述、门级描述,其中RTL级和门级别与具体电路结构有关,行为级描述要遵守可综合原则门级描述使用门级模型或者用户自定义模型UDP来代替具体基本元件,在IDE中针对不同FPGA器件已经有对应的基本元件原语18.verlog语法要点:module endmodule之间由两部分构成:接口描述和逻辑功能描述IO端口种类:input output inout相同位宽的输入输出信号可以一起声明,input[3:0] a,b; 不同位宽的必须分开写内部信号为reg类型,内部信号信号的状态:0 1 x z,3'bx1=3'bxx1 x/z会往左扩展3'b1=3'b001 数字不往左扩展逻辑功能描述中常用assign描述组合逻辑电路,always既可以描述组合逻辑电路又可以描述时序逻辑电路,还可以用元件调用方法描述逻辑功能always之间、assign之间、实例引用之间以及它们之间都是并行执行,always内部是顺序执行常量格式:<+/-><二进制位宽><'><进制><该进制的数值>:默认进制为10进制默认位宽为32位位宽是从二进制宽度角度而言的由位宽决定从低位截取二进制数2'hFF=2'b11,通常由被赋值的reg变量位宽决定parameter常用于定义延迟和变量位宽,可用常量或常量表达式定义变量种类:wire reg memoryIO信号默认为wire类型,除非指定为reg类型wire可以用作任何输入输出端口wire包括input output inoutwire不带寄存功能assign赋值语句中,被赋值的信号都是wire类型assign之所以称为连续赋值,是因为不断检测表达式的变化reg类型可以被赋值后再使用,而不是向wire一样只能输出,类似VHDL中的buffer端口reg类型变量初始值为x (VHDL中初始值为本类型最小值,通常是0)always模块里被赋值的信号都必须定义为reg类型,因为always可以反复执行,而reg表示信号的寄存,可以保留上次执行的值reg类型变量与integer变量不同,即使赋负值,实质上也是按二进制无符号数存储的,integer是有符号数verilog中所有内部信号都是静态变量,因为它们的值都在reg中存储起来了memory型只有一维数组,由reg型变量组成memory初始化只能按地址赋值,不能一次性赋值1*256的memory写法:reg mema[255:0] mema[3]=0;不同位宽的变量之间赋值,处理之前都以被赋值的变量位宽为准扩展或截取A[a:b] 无论a b谁大,a总是实际电路的信号高位,b总是实际电路的信号低位算术运算中如果有X值则结果为Xfor循环中的变量另外定义成integer,因为它不是实际信号,有正负;reg则以无符号数存在== 和!=只比较0、1,遇到z或x时结果都为x (x在if中算做假条件),结果可能是1、0、x===和!==比较更加苛刻,包括x和z的精确比较,结果可能是0、1&&的结果只有1'b1或1'b0两种,A&A的结果位宽则是与A相同的{1,0}为64'h100000000,所以拼接运算中各信号一定要指定位宽移位运算左移将保留4'b1000<<1等于5'b10000,右移则舍弃4'b0011等于4'b0001数字电路里位运算应用普遍,包括按位逻辑运算、移位运算、拼接运算、缩减运算非阻塞式赋值<=与阻塞式赋值=阻塞:在同一个always过程中,后面的赋值语句要等待前一个赋值语句执行完,后面的语句被该赋值语句阻塞非阻塞:在同一个always过程中,非阻塞赋值语句是同时进行的,排在后面的语句不会被该赋值语句阻塞<=:块结束后才能完成赋值块内所有<=语句在always块结束时刻同时赋值<=右边各变量的值是上一次时钟边沿时,这些变量当时的值用于描述可综合的时序电路=:=语句结束之后过程always才可能结束在always过程中,begin end块内按先后顺序立即赋值,在fork join内同时赋值(可能造成冲突)与assign连用描述组合电路begin end中阻塞的含义:begin ...@(A) B=C...; end 如果A事件不发生则永远不能执行下去,被阻塞了由于时钟的延时(往往在ps级),多个always(posedge)之间究竟谁先执行是个未知数使用原则:同一个always过程块内建立时序电路用<=纯组合逻辑电路用=,生成的电路结构最简单,执行速度最快同一个always块内不要混用<=和=不要在多个always块内对同一个变量赋值(多源驱动)if else的三种形式,第三种形式适合描述优先编码器if条件中0/x/z当成假,1当成真,非0的数值也当成真case语句的三种:case(四种状态的比较) casez(忽略z) casex(忽略x和z,只看哪些位的信号有用)case语句中所有表达式值的位宽必须相等,default中不能将n'bx用'bx代替避免生成锁存器的方法:电平触发时if后加else case中加default ?使用casex会将不必要的状态视为无关项,使得综合出来的电路最简单两种特殊的括号:begin 顺序语句... end fork 并行语句... join,其差别在于块内语句的起止时间、执行顺序、相对延时块被命名后,其内部变量可以被调用,因为变量都是静态的(调用信号:对应电路中的一个信号线被引到另一处)initial块只无条件执行一次always块在满足条件时不断执行initial常用来写测试文件,always块常用来写电路描述always既可以描述组合逻辑电路又可以描述时序逻辑电路always如果后面有敏感信号列表则不能用wait语句always既可以描述电平触发又可以描述边沿触发,wait只能描述电平触发assign常用于描述组合逻辑电路测试文件中一般都是现initial 后always生成语句:生成快的本质是使用循环内的一条语句代替多条重复的verilog语句,简化了用户的编程genvar用于声明生成变量,生成变量只能用在生成快之间仿真时,仿真器会将生成块中的代码展平,在确立后的方针代码中,生成变量是不存在的最好是先想象出来循环生成语句被展平后的电路样子,再写相关的描述语句task和function的区别:task可以定义自己的仿真时间单位,function与主模块共用同一个仿真时间单位函数不能启动任务,任务能够启动函数函数至少要有一个输入变量,任务没有输入变量函数返回一个值,任务不返回值一个模块的设计包括3个部分:电路模块的设计测试模块的设计设计文档的编写设计者通过布局布线工具生成具有布线延迟的电路,再进行后仿真,得到时序分析报告从时序分析报告中可以知道电路的实际延迟t,同步电路内每个时钟周期要大于t,从而可确定该运算逻辑的最高频率综合器之所以能够实现加法器、乘法器是因为库中已经存在可配置的参数化器件模型FPGA内总线宽度容易自定义,以便实现高速数据流,三态数据总线相当于数据流的控制阀门数字系统内数据流的控制:开关(或三态数据总线)、数据暂存部件(寄存器)、同步状态机控制(整个系统在一个时钟域内)流水线操作pipe line:K级流水线就是从组合逻辑的输入到输出恰好有K个寄存器组,上一级的输出是下一级的输入流水线操作获得第一个结果的时间要比不用流水线操作的时间长,但以后结果获得时间都只需要一个时钟周期,提高了数据吞吐量流水线操作的保证:Tclk>K*(组合逻辑延迟+触发器的建立保持时间/触发时间),即时间片段要长于最大路径延迟体现了面积换速度的思想,在综合时考虑的是以面积小为主还是以速度为主本质上是一种同步逻辑同步时序逻辑和异步时序逻辑:同步时序逻辑指所有寄存器组由唯一时钟触发always@(posedge clk) 或always@(negedage clk)异步时序逻辑指触发条件不唯一,任意一个条件都会引起触发always@(posedge clk or posedage reset)目前的综合器是以同步时序逻辑综合的,因为同步时序逻辑较异步时序逻辑可靠严格的同步要求时钟信号传递速度远远大于各部分的延迟,实际中clk要单独用线,而不要经过反相器等部件always @(posedge.. ) begin ...<=... end 表示同步时序逻辑(同时刻赋值)不同速率数据接口的处理方法(异步数据的处理方法):帧同步FIFO 双端口RAM同步状态机:包括moore和mealy型两种,及其反馈模型(是一种反馈控制系统,当前状态就是其内部状态变量)状态机的开发步骤:根据实际问题列出输入输出变量和状态数画出状态图并化简写出状态转移真值表得到逻辑表达式用D触发器或JK触发器构建电路(目前用D触发器多)verilog描述时只需要得到简化的状态图就可以描述状态编码方式:独热码格雷码状态机主体程序有单always描述方式和多always描述方式采用case/casez/casex建立模型最好,因为x是无关态,生成的电路最简单default: state='bx与实际情况更一致,效果等同于default: state<=idle只有同步状态机才能被目前的综合for语句会将所有变量的情况展开,占用巨量逻辑资源,替代办法是用计数器和case语句说明所有情况有优先级的if else结构会消耗更多资源,建议用无优先级的case替代模块的复用往往比代码上修改节省的资源多PLL的分频、倍频、移相操作会增加设计精度同步时序电路的延时:#x通常用于仿真测试,实际硬件延时是:长延迟用计数器,小延迟用D触发器,此方法用来取代延迟链同步电路中,稳定的数据采用必须满足采样寄存器的建立和保持时间reg类型在always中不一定综合成时序电路,也可能是组合逻辑电路乒乓操作与作用异步时钟域同步问题延迟包括门延迟和线延迟组合逻辑产生的时钟仅能应用在时钟频率较低、精度要求不高的情况下增减敏感信号得到的结果一样补充部分:verilog HDL起初是作为写testbench而产生的verilog 有1995进入IEEE标准,为IEEE-1364, 于2001年进行了扩展,为IEEE 1364-2001;verilog AMS可用于模拟电路和数字电路的综合,目前正在不断发展和完善中;verilog的标识符区分大小写,关键字使用小写;用\\来进行单行注释,用\* *\来进行跨行注释;标识符由字母、数字、下划线构成,并以字母开头;关键字又叫保留字,只有小写的关键字才是保留字;信号的状态有4种:0 1 x zx和z在描述电路时不区分大小写,在仿真时大小写有不同意义;常量表达式中:x z不区分大小写;进制符号h o d b与H O D B不区分大小写;十六进制中a~f不区分大小写;下划线_用于提高可读性;?在数中可以代替z;x和z的左端补位;字符和字符串都以ASICII码形式存在,也可以当成电路内的信号;字符串必须包含在同一行,不能分成多行书写;如果表达式或者赋值语句中将字符串当成操作数,则字符串中的每个字符都被看成8位的ASCII值序列;可综合的信号类型:wire reg memory 它们用来描述数字电路不可综合的数据类型:integer real 它们只用仿真,位于testbench中wire是连线的抽象模型,不能保存数据,其值由驱动元的值决定;wire不能用在always或initial块中;wire的默认值为高阻z;wire的使用情形: 1.作为模块的输出端口2.用连续赋值语句assign赋值;reg是1位寄存器(触发器)的抽象模型,可以保存数据;reg必须用在always或initial块中;reg的默认值为x;reg的使用情形:1.阻塞赋值<= 2.非阻塞赋值=memory只能是一维的;memory只能对每个单元分别初始化,方法:1.一个一个赋值2. 通过系统任务$readmem赋值reg[3:0] fc;//一个4位寄存器reg fc[3:0] //4个一位寄存器parameter的作用:仿真开始以前对其进行赋值,整个仿真过程中保持其值不变;关系运算符将以逻辑1或逻辑0返回比较的结果;== !=的返回值有0 1 x三种情况,=== !==的返回值只有0 1两种情况;verilog由于是描述电路的,用于位的操作较多,有: 位逻辑操作,移位操作,并置操作,归约操作;位逻辑运算的结果中,位数与原操作数一样多;归约符是在原操作数的所有位上进行操作,并产生1位结果;并置运算可以发生在bit与bit之间bit与矢量之间矢量与矢量之间用于仿真的系统任务:所有系统任务都必须在initial或always内;所有系统任务都必须以$开头;常见系统任务:显示任务($diplay系列和$write系列)监控任务($monitor系列)探测任务($strobe系列)文件打开、输入、关闭任务(&fopen &fclose &fdisplay...)读取文件任务($readmemb $readmemh)仿真结束控制任务($finish $stop)随即信号任务($random)过程块:initial块和always块一个module内可以包含多个initial或always模块;所有initial或always块在0时刻开始并行执行,各initial或always块内部顺序执行;initial过程块主要是面向testbench的,通常不具有可综合性;always过程块在描述电路时既可以描述组合逻辑电路(电平敏感)又可以描述时序逻辑电路(边沿敏感);写testbench时initial通常用于初始化以及顺序波形的描述,always通常用于重复波形的描述;任务task与函数function: 为了描述模块中被多次执行的部分以及为了增强代码的易读性verilog中的高级程序语句如for循环语句只用在写testbench中;begin end和fork join是两种特殊的括号if语句的第三种形式适合描述优先编码器,case语句适合描述数据选择器和状态机;case的条件表达式如果与分支项表达式长度不同,则在比较前将所有表达式都统一为这些表达式的最长长度;casez忽略z,casex忽略z和x;assign语句只在右端表达式发生变化时才重新计算并重新赋值,其余时间都是连续赋值;assign语句可以指定bit、vector或是任意拼接操作的结果;assign语句是连续赋值的,用于驱动网线wire,reg类型不需要连续赋值,reg 类型一旦被赋值就会一直保存;过程赋值语句有两种:阻塞式=和非阻塞式<=,只能在过程块initial和always中使用;@对事件触发的控制与wait语句不能同时使用;FPGA学习心得(二)V erilog的两个误区:使用Reg类型还是Net类型:Reg类型只在过程块中被赋值;而Net类型则在过程块外面被赋值或者驱动. 阻塞赋值和非阻塞赋值:V erilog中竞争发生的条件:两个或多个语句在执行顺序不同时导致不同的结果,则存在竞争.Nonblocking不是一个类型;Blocking赋值是一个单步过程,计算RHS,并更形LHS是不可中断的.七条准则:1.时序逻辑和锁存器,使用非阻塞赋值2.always块中的组合逻辑,使用阻塞赋值3.同一always块,时序组合混合逻辑使用非阻塞赋值4.通常情况下,在同一always块中不要混合使用阻塞与非阻塞赋值5.不要在多个always块中对同一变量进行赋值6.使用$strobe显示非阻塞赋值得信号7.不要用#0的过程赋值V erilog中的分层事件队列:活动事件:阻塞赋值;计算非阻塞赋值的RHS;连续赋值;$display命令;计算输入并改变原语的输出.这些事件可能按照任意次序调度.非活动事件:#0的阻塞赋值非阻塞事件:更新非阻塞赋值的LHS监视事件:$monitor命令;$strobe命令经验:在always块中使用非阻塞赋值来产生时序逻辑和锁存器在always块中使用阻塞赋值来产生组合逻辑在always块中使用非阻塞赋值来产生同一块中的时序和组合逻辑在纯组合逻辑中使用非阻塞赋值可能会导致功能错误阻塞赋值和非阻塞赋值混合使用的方式:将组合逻辑赋值通过时序表达式表示或者将组合逻辑赋值与时序逻辑分开,在独立的语句块中描述不推荐在同一always块中混合使用阻塞和非阻塞赋值几个关于非阻塞赋值的错误理解:错误1:无法使用$display命令显示非阻塞赋值变量正解:非阻塞赋值变量的更新在所有$display命令之后错误2:#0让一个赋值在每个时间步的最后执行正解:#0只会让赋值语句进入非活动事件队列错误3:在同一always块中对同一变量进行多次非阻塞赋值是不允许的正解:在IEEE 1364 verilog标准中定义了上述赋值,最后一个非阻塞赋值起作用模拟开始时候的困难:不同的模拟器,不同的模拟选项导致开始模拟时现象不同建议: 在0时刻通过非阻塞赋值设置reset信号;第一个半周期设置clock为0编写V erilog代码的一些经验:V erilog文件名和模块名相同不要在可综合代码中使用casex语句当在可综合代码中使用casez语句时要小心当写case语句时,对存在不关心的cases时使用casez,使用?代替Z来表示不关心的casesV erilog编写状态机相关:状态机分类:Moore(输出只与当前状态相关)和Mealy(输出与当前状态和输入相关)二进制编码和One-Hot编码状态机的基本块:下一状态度组合逻辑;时钟同步的当前状态逻辑;输出组合逻辑两个always块写状态机,使用三个always块,如果输出需要寄存使用高效的One-Hot状态编码,组合输出经验:每个状态机作为一个独立的V erilog模块对状态进行预定义,状态赋值使用状态名作参数,不要使用`define,多使用parameter两个always语句块的状态机,一个always用来描述状态向量寄存器的时序逻辑.一个用来描述下一状态度组合逻辑.组合输出可以通过连续赋值语句或者在下一状态度组合always块中描述.verilog语法规则1.V erilog分以下四个层次:l 低阶交换模型:电路由开关与储存点所组成l 逻辑间层次描述:用and ,or, buf , not 等l 资料处理模型或暂存器转移层次:用于说明资料如何在暂存器中储存与传送。
NC-Verilog仿真技巧
提高NC-Verilog仿真效率的技巧本文回顾了一些NC-Verilog的命令行选项,并说明这些选项如何影响仿真效率。
同时,我们也展示了一些技巧,以帮助用户的NC-Verilog在最大效率下仿真一个设计和测试平台。
文中的命令行选项语法采用单步启动的方式(ncverilog +<options>),这些选项也适合多步启动模式(ncvlog, ncelab, 或ncsim)。
安装最新发布的软件首先确认你是否安装了最新的Cadence LDV版本。
自动1996年发布第一版NC-Verilog以来,我们的研发队伍一直把仿真器的仿真效率作为重点来研究。
在后来推出的新版本里,不断按各种设计风格优化仿真器,因此使用最新版本是最有利的。
直到2002年2月,最新版本是LDV 3.4(s1)。
使用NC-Verilog内置的profilerNC-Verilog在仿真引擎内开发了一个profiler工具。
该工具每秒中断仿真器100次,并将终端时的结构记录下来,生成一个日志文件。
日志文件里列出了被中断次数最多的模块、代码行和结构类型。
这些信息可以帮助你诊断是哪些代码或模块在仿真时耗费了最多的时间。
通过修改这些模块,就能提升仿真效率。
Profiler功能很容易启动,并对仿真只产生非常小的影响。
% ncverilog +ncprofile <other_options>or% ncsim –profile snapshot_name <other_options>在仿真结束时,profiler会创建一个日志文件(ncprof.out),文件里列出了profile运行的细节。
关于如何利用profiler日志文件,可参考Cadence在线文档(Cadence NC-Verilog Simulator Help, Version 3.4, Chapter 14)。
禁止时序验证来提升效率缺省情况下,如果在设计中考虑了时序,NC-Sim将进行标准延迟格式(SDF)的全时序标注(annotation),并在仿真时检查时序。
基于verilog的FPGA编程经验总结(XILINXISE工具)
基于verilog的FPGA编程经验总结(XILINXISE工具)用了半个多月的ISE,几乎全是自学起来的,碰到了很多很多让人DT好久的小问题,百度也百不到,后来还是都解决了,为了尽量方便以后的刚学ISE的童鞋不再因为一些小问题而纠结,把这几天的经验总结了一下。
好了,废话不多说,上料!1.用ISE仿真的时候.所用变量一定要初始化. ISE默认初始量为"XXXXX", 而Quarters是默认为"00000"的, 其实实际上, 下到FPGA 里后也是默认为0的,只是可以说ISE严谨得令人DT吧.比如说用一个累加器, result = A+B+result ,必须保证在某一刻A, B, result都为定值时, 之后的数据才不会一直为"XXXXX";2.所有的中间线(就是module间用来传递参数的信号)都要用wire 定义一下. 这个ise一般会提醒的;3.任何一个warning都是有用的;4.debug时要多把中间变量设成输出,然后查看仿真波形;5.其实,新版本还是比较好用的.虽然取消了test bench wave 功能. 但是最好学会编测试文件,后期比test bench wave好用, 而且貌似一旦测试信号太多,test bench wave就不显示某些输出了;6. warning: Nod <....> is unconnected. 表明<...>所在的模块没用被执行,一般是参数没进来, 或者进来的参数不对("XXXX"之类)的原因引起的.7.建立rom时候,Error: sinrom can't be resolved. 因为在把程序挪地方的时候,sinrom.ngc文件没有一同拷过来.8.把"XXXXX"信号处理掉的一个方法可以是: 从信号中随意选出一位 if (data[0] == 0) ....; else if (data[0] == 1).... else data = 0; 就可以把"XXXX"信号给清成"0000"了. 可以很好的解决1中仿真的问题.9.如果某一个不是时钟的信号被当作周期信号来用的话,就会出现WARNING:Route:455 - CLK Net:trn_clk_OBUF may have excessive skew. because 0 CLK pins and 1 NON_CLK pins failed to route using a CLK template 不管也行.10. 一开始用FPGA时不要害怕,用ucf文件配好引脚,直接LOAD,先不用管什么区域约束,以后进阶了再学. .。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Verilog经验谈规范很重要工作过的朋友肯定知道,公司里是很强调规范的,特别是对于大的设计(无论软件还是硬件),不按照规范走几乎是不可实现的。
逻辑设计也是这样:如果不按规范做的话,过一个月后调试时发现有错,回头再看自己写的代码,估计很多信号功能都忘了,更不要说检错了;如果一个项目做了一半一个人走了,接班的估计得从头开始设计;如果需要在原来的版本基础上增加新功能,很可能也得从头来过,很难做到设计的可重用性。
在逻辑方面,我觉得比较重要的规范有这些: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(//inputclk,rst_n, //globle signalwren,rden,avalon_din, //related to avalon bussdi, //related to serial port input//outputdata_ready,avalon_dout, //related to avalon bus...);4) 一个模块尽量只用一个时钟,这里的一个模块是指一个module或者是一个en tity。
在多时钟域的设计中涉及到跨时钟域的设计中最好有专门一个模块做时钟域的隔离。
这样做可以让综合器综合出更优的结果。
5) 尽量在底层模块上做逻辑,在高层尽量做例化,顶层模块只能做例化,禁止出现任何胶连逻辑(glue logic),哪怕仅仅是对某个信号取反。
理由同上。
6) 在FPGA的设计上禁止用纯组合逻辑产生latch,带D触发器的latch的是允许的,比如配置寄存器就是这种类型。
7) 一般来说,进入FPGA的信号必须先同步,以提高系统工作频率(板级)。
所有模块的输出都要寄存器化,以提高工作频率,这对设计做到时序收敛也是极有好处的。
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 )...end11)状态机要写成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)...elsea <= 1'b0;c <= 1'b0;c <= 1'b0; //赋默认值case(current_state)s1:a <= 1'b0; //由于上面赋了默认值,这里就不用再对b 、c赋值了(b、c在该状态为0,不会产生锁存器,下同)s2:b <= 1'b1;s3:c <= 1'b1;default:......3.ALTERA参考设计准则1) Ensure Clock, Preset, and Clear configurations are free of glitches.2) Never use Clocks consisting of more than one level of combinatorial 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.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 all flipflops.11)Remove any stuck states from state machines or synchronous logic.其它方面的规范一时没有想到,想到了再写,也欢迎大家补充。
================================================= ===================================时序是设计出来的我的boss有在华为及峻龙工作的背景,自然就给我们讲了一些华为及altera做逻辑的一些东西,而我们的项目规范,也基本上是按华为的那一套去做。
在工作这几个月中,给我感触最深的是华为的那句话:时序是设计出来的,不是仿出来的,更不是湊出来的。
在我们公司,每一个项目都有很严格的评审,只有评审通过了,才能做下一步的工作。
以做逻辑为例,并不是一上来就开始写代码,而是要先写总体设计方案和逻辑详细设计方案,要等这些方案评审通过,认为可行了,才能进行编码,一般来说这部分工作所占的时间要远大于编码的时间。
总体方案主要是涉及模块划分,一级模块和二级模块的接口信号和时序(我们要求把接口信号的时序波形描述出来)以及将来如何测试设计。
在这一级方案中,要保证在今后的设计中时序要收敛到一级模块(最后是在二级模块中)。
什么意思呢?我们在做详细设计的时候,对于一些信号的时序肯定会做一些调整的,但是这种时序的调整最多只能波及到本一级模块,而不能影响到整个设计。
记得以前在学校做设计的时候,由于不懂得设计时序,经常因为有一处信号的时序不满足,结果不得不将其它模块信号的时序也改一下,搞得人很郁闷。
在逻辑详细设计方案这一级的时候,我们已经将各级模块的接口时序都设计出来了,各级模块内部是怎么实现的也基本上确定下来了。
由于做到这一点,在编码的时候自然就很快了,最重要的是这样做后可以让设计会一直处于可控的状态,不会因为某一处的错误引起整个设计从头进行。
如何提高电路工作频率对于设计者来说,我们当然希望我们设计的电路的工作频率(在这里如无特别说明,工作频率指FPGA片内的工作频率)尽量高。
我们也经常听说用资源换速度,用流水的方式可以提高工作频率,这确实是一个很重要的方法,今天我想进一步去分析该如何提高电路的工作频率。
我们先来分析下是什么影响了电路的工作频率。
我们电路的工作频率主要与寄存器到寄存器之间的信号传播时延及clock skew有关。
在FPGA内部如果时钟走长线的话,clock skew很小,基本上可以忽略, 在这里为了简单起见,我们只考虑信号的传播时延的因素。
信号的传播时延包括寄存器的开关时延、走线时延、经过组合逻辑的时延(这样划分或许不是很准确,不过对分析问题来说应该是没有可以的),要提高电路的工作频率,我们就要在这三个时延中做文章,使其尽可能的小。
我们先来看开关时延,这个时延是由器件物理特性决定的,我们没有办法去改变,所以我们只能通过改变走线方式和减少组合逻辑的方法来提高工作频率。
1.通过改变走线的方式减少时延。
以altera的器件为例,我们在quartus里面的timing closure floorplan可以看到有很多条条块块,我们可以将条条块块按行和按列分,每一个条块代表1个LAB,每个LAB里有8个或者是10个LE。
它们的走线时延的关系如下:同一个LAB中(最快)< 同列或者同行< 不同行且不同列。
我们通过给综合器加适当的约束(不可贪心,一般以加5%裕量较为合适,比如电路工作在100Mhz,则加约束加到105Mhz就可以了,贪心效果反而不好,且极大增加综合时间)可以将相关的逻辑在布线时尽量布的靠近一点,从而减少走线的时延。