verilog设计经验
- 格式:docx
- 大小:17.70 KB
- 文档页数:4
每天多学一点: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的135个经典设计实例1、立即数放大器:立即数放大器是一种用于将输入电平放大到更高电平的电路,它可以实现任意输入到输出的映射,并且可以在Verilog中使用。
立即数放大器的Verilog实现如下:module immedamp(in, out);input in;output out;reg [3:0] immed;assign out = immed[3];begincase (in)4'b0000: immed = 4'b1000;4'b0001: immed = 4'b1001;4'b0010: immed = 4'b1010;4'b0011: immed = 4'b1011;4'b0100: immed = 4'b1100;4'b0101: immed = 4'b1101;4'b0110: immed = 4'b1110;4'b0111: immed = 4'b1111;4'b1000: immed = 4'b1000;4'b1001: immed = 4'b1001;4'b1010: immed = 4'b1010;4'b1011: immed = 4'b1011;4'b1100: immed = 4'b1100;4'b1101: immed = 4'b1101;4'b1110: immed = 4'b1110;4'b1111: immed = 4'b1111;endcaseendendmodule2、多路复用器:多路复用器是一种用于将多个输入选择转换为单个输出的电路,它可以实现由多种方式选择的输出,并可以使用Verilog实现。
Verilog(FPGA/CPLD)设计小技巧(来自Xilinx)这是一个在设计中常犯的错误列表这些错误常使得你的设计不可靠或速度较慢为了提高你的设计性能和提高速度的可靠性你必须确定你的设计通过所有的这些检查可靠性**为时钟信号选用全局时钟缓冲器BUFG• 不选用全局时钟缓冲器的时钟将会引入偏差 。
**只用一个时钟沿来寄存数据• 使用时钟的两个沿是不可靠的因为时钟的某沿或者两个沿会漂移; 如果时钟有漂移而且你只使用了时钟的一个沿你就降低了时钟边沿漂移的风险。
• 这个问题可以这样来解决就是允许CLKDLL自动纠正时钟的占空比以达百分之五十的占空比否则强烈建议你只使用一个时钟沿**除了用CLKDLL或DCM产生的时钟外不要在内部产生时钟.• 这包括产生门控时钟和分频时钟• 作为替代可以建立时钟使能或使用CLKDLL或DCM来产生不同的时钟信号。
• 对于一个纯同步设计建议你在任何可能的情况下只使用一个时钟**不要在内部产生异步的控制信号 例如复位信号或者置位信号• 内部产生的异步控制信号会产生毛刺• 作为替代可以产生一个同步的复位/置位信号这个信号的译码要比需要作用的时刻提前一个时钟周期**不要使用没有相位关系的多个时钟• 你也许并不总能避免这个条件在这些情况下确定你已使用了适当的同步电路来跨越时钟域**不要使用没有相位关系的多个时钟• 再次你也许并不总能避免这个条件相反许多设计都需要这样在这 些情况下确定你已适当地约束了跨越时钟域的路径**不要使用内部锁存器• 内部锁存器会混淆时序而且常常会引入另外的时钟信号• 内部锁存器在透明门打开时可以被看成是组合逻辑但在门被锁存时 可以被看成是同步元件这将会混淆时序分析• 内部锁存器常常会引入门控时钟门控时钟会产生毛刺使得设计变得不可靠性能**逻辑级的时延不要超过时序预算的百分之五十• 每个路径逻辑级时延可以在逻辑级时序报告或布局后时序报告中找到详细分析了每个路径之后时序分析器将生成每个路径时延的统计量检查一下总共的逻辑级时延超过了你的时序预算的百分之五十吗?**IOB 寄存器• IOB寄存器提供了最快的时钟到输出和输入到时钟的时延• 首先有一些限制对于输入寄存器在从管脚到寄存器间不能有组合逻 辑存在对于输出寄存器在寄存器和管脚之间也不能有组合逻辑存在对于三态输出在IOB 中的所有的寄存器必须使用同一个时钟信号和复位信号而且IOB三态寄存器必须低电平有效才能放到IOB中三态缓冲器低电平有效所以在寄存器和三态缓冲器之间不需要一个反相器• 你必须使软件能够选用IOB寄存器你可以设置全局实现选项为输入 输出或输入输出选择IOB寄存器缺省值为关(off)。
Systemverilog的一个牛人总结SystemVerilog是一种硬件描述语言,用于设计和验证硬件系统。
它是Verilog的扩展版本,提供了更丰富的特性和功能,使得硬件设计变得更加灵活和高效。
在SystemVerilog的大家庭中,有许多牛人通过深入研究和实践,掌握了该语言的精髓,并在硬件设计和验证领域取得了杰出的成绩。
下面是对SystemVerilog牛人的一些总结:1. 对SystemVerilog语言精通:牛人对SystemVerilog语言的语法和语义有着深入的理解,并能充分利用其强大的特性来设计和验证复杂的硬件系统。
他们熟悉SystemVerilog中各种数据类型、控制结构、模块化设计、接口和并发编程等方面的内容,并能灵活运用这些知识来解决实际问题。
2. 良好的编码风格和规范:牛人在编写SystemVerilog代码时,注重良好的编码风格和规范,使得代码易读、易于维护。
他们遵循一致的命名规则,使用有意义的变量名和模块名,编写清晰的注释,避免使用过于复杂的语法和结构,以及注意代码的可重用性和可扩展性。
3. 高效的调试和验证技巧:SystemVerilog牛人具备高效的调试和验证技巧,能够快速定位和解决设计和验证中的问题。
他们熟悉仿真工具的使用方法,能够利用断点、波形查看器、覆盖率分析等功能来分析和调试代码。
此外,他们还熟悉常见的验证方法和技术,如约束随机测试、功能覆盖率分析和形式化验证等,以确保设计的正确性和完整性。
4. 广泛的项目经验:SystemVerilog牛人在硬件设计和验证领域有着广泛的项目经验,涉及多个行业和应用领域。
他们参与过各种规模和复杂度的项目,从小规模的IP设计到大型的SoC设计和验证。
通过这些项目的实践,他们积累了丰富的经验和技巧,能够在不同的项目中灵活应对各种挑战。
5. 持续学习和研究的态度:SystemVerilog牛人具备持续学习和研究的态度,不断追求自我提升和突破。
一个新手的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设计的时候,同步原则应该是最重要的原则之一了,因为异步电路的不可控性,很可能有毛刺产生,而在芯片内部的任何一点毛刺都会一级一级的传递下去,最终影响系统的稳定性。
同步原则用一句话来总结就是“不要试图产生自己的时钟”,最好一个设计或者一个模块只使用同一个时钟,这样所有的触发器都在同一个时钟沿跳变,当然最稳定了,系统也能跑到很高的速度。
一个小技巧就是多使用触发器的使能端和取沿电路。
Verilog十大基本功1(流水线设计PipelineDesign)需求说明:Verilog设计基础内容:流水线设计来自:时间的诗流水线设计前言:本文从四部分对流水线设计进行分析,具体如下:第一部分什么是流水线第二部分什么时候用流水线设计第三部分使用流水线的优缺点第四部分流水线加法器举例第一什么是流水线流水线设计就是将组合逻辑系统地分割,并在各个部分(分级)之间插入寄存器,并暂存中间数据的方法。
目的是将一个大操作分解成若干的小操作,每一步小操作的时间较小,所以能提高频率,各小操作能并行执行,所以能提高数据吞吐率(提高处理速度)。
第二什么时候用流水线设计使用流水线一般是时序比较紧张,对电路工作频率较高的时候。
典型情况如下:1)功能模块之间的流水线,用乒乓buffer 来交互数据。
代价是增加了 memory 的数量,但是和获得的巨大性能提升相比,可以忽略不计。
2) I/O 瓶颈,比如某个运算需要输入 8 个数据,而 memroy 只能同时提供 2 个数据,如果通过适当划分运算步骤,使用流水线反而会减少面积。
3)片内 sram 的读操作,因为 sram 的读操作本身就是两极流水线,除非下一步操作依赖读结果,否则使用流水线是自然而然的事情。
4)组合逻辑太长,比如(a+b)*c,那么在加法和乘法之间插入寄存器是比较稳妥的做法。
第三使用流水线的优缺点1)优点:流水线缩短了在一个时钟周期内给的那个信号必须通过的通路长度,增加了数据吞吐量,从而可以提高时钟频率,但也导致了数据的延时。
举例如下:例如:一个 2 级组合逻辑,假定每级延迟相同为 Tpd,1.无流水线的总延迟就是2Tpd,可以在一个时钟周期完成,但是时钟周期受限制在 2Tpd;2.流水线:每一级加入寄存器(延迟为T co)后,单级的延迟为Tpd+Tco,每级消耗一个时钟周期,流水线需要 2 个时钟周期来获得第一个计算结果,称为首次延迟,它要2*(Tpd+Tco),但是执行重复操作时,只要一个时钟周期来获得最后的计算结果,称为吞吐延迟( Tpd+Tco)。
综合:不可综合的运算符:= = = ,!= =,/(除法),%(取余数)。
1、不使用初始化语句。
2、不使用带有延时的描述。
3、不使用循环次数不确定的循环语句,如:forever、while等。
4、尽量采用同步方式设计电路。
5、除非是关键路径的设计,一般不调用门级元件来描述设计的方法,建议采用行为语句来完成设计。
6、用always过程块描述组合逻辑,应在信号敏感列表中列出所有的输入信号。
7、所有的内部寄存器都应该能够被复位,在使用FPGA实现设计时,应尽量使用器件的全局复位端作为系统总的复位。
8、在verilog模块中,任务(task)通常被综合成组合逻辑的形式,每个函数(function)在调用时通常也被综合为一个独立的组合电路模块。
9、用户自定义原语(UDP)是不可综合的,它只能用来建立门级元件的仿真模型。
移位运算符:Verilog HDL提供向右(>>)及向左(<<)两种运算符,运算符高位或地位一旦移出即予丢弃,其空缺的位则予以补零。
连续赋值语句(assign)、case语句、if…else语句都是可以综合的initial 语句内若包含有多个语句时,必须以begin end 作聚合;单一的初值赋值,因此并不需以begin end做聚合。
循环(Loops)并不能单独地在程序中存在,而必须在initial和always块中才能使用。
initial过程块中的语句仅执行一次,而always块中的语句是不断重复执行的。
编写顶层模块的注意事项每个端口除了要声明是输入、输出还是双向外,还要声明其数据类型,是连线型(wire)还是寄存器型(reg),如果没有声明则综合器默认为wire型。
1、输入和双向端口不能声明为寄存器型。
2、在测试模块中不需要定义端口。
编写testbentch所归纳的心得module 模块名称;将input 定义为reg;将output定义为wire;引用欲测试的module 别名initial begin设定reg 初始值endalways处理变化值endmodule在always 、initial 过程块内,被赋值的每一个信号都必须定义成寄存器型。
从大学时代第一次接触FPGA至今已有10多年的时间。
至今记得当初第一次在EDA实验平台上完成数字秒表,抢答器,密码锁等实验时,那个兴奋劲。
当时由于没有接触到HDL硬件描述语言,设计都是在MAX+plus II原理图环境下用74系列逻辑器件搭建起来的。
后来读研究生,工作陆陆续续也用过Quartus II,Foundation,ISE,Libero,并且学习了verilogHDL语言,学习的过程中也慢慢体会到verilog的妙用,原来一小段语言就能完成复杂的原理图设计,而且语言的移植性可操作性比原理图设计强很多。
工作过的朋友肯定知道,公司里是很强调规范的,特别是对于大的设计(无论软件还是硬件),不按照规范走几乎是不可实现的。
逻辑设计也是这样:如果不按规范做的话,过一个月后调试时发现有错,回头再看自己写的代码,估计很多信号功能都忘了,更不要说检错了;如果一个项目做了一半一个人走了,接班的估计得从头开始设计;如果需要在原来的版本基础上增加新功能,很可能也得从头来过,很难做到设计的可重用性。
在逻辑方面,我觉得比较重要的规范有这些:1.设计必须文档化。
要将设计思路,详细实现等写入文档,然后经过严格评审通过后才能进行下一步的工作。
这样做乍看起来很花时间,但是从整个项目过程来看,绝对要比一上来就写代码要节约时间,且这种做法可以使项目处于可控、可实现的状态。
2.代码规范。
如果在另一个设计中的时钟是40ns,复位周期不变,我们只需对CLK_PERIOD进行重新例化就行了,从而使得代码更加易于重用。
b.信号命名要规范化。
1)信号名一律小写,参数用大写。
2)对于低电平有效的信号结尾要用_n标记,如rst_n。
3)端口信号排列要统一,一个信号只占一行,最好按输入输出及从哪个模块来到哪个模块去的关系排列,这样在后期仿真验证找错时后方便很多。
4)一个模块尽量只用一个时钟,这里的一个模块是指一个module或者是一个entity。
因为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是硬件描述语言,所谓描述就是是在在描绘已经设计好的电路。
尤其是在刚开始学习HDL时,还没有能直接把语言对应到具体电路的能力,更不能上手直接写Verilog代码。
所以最优方案是先设计好硬件电路,再按照电路编写Verilog。
●模块化思想这个思想不仅仅是Verilog的开发了,就算是C语言甚至现在的超高级语言,也一直在强调封装的概念。
Verilog开发遵循的是自顶向下的模块化设计,思路基本是从最终功能不断细分,直到Verilog可以很直接地描述最基础的硬件单元,例如加法器,移位寄存器等等。
模块划分一定要尽量细,功能单一,且一定要留出使能、复位等接口以便于系统搭建。
说明以下,所谓Verilog可直接描述指的是按照规范描述出来的电路,开发工具能够很清晰地理解所要描述的功能,而不会发生误解等现象。
一个只使用编译器能理解的代码开发的电路,错误率会大大降低。
相反,如果功能划分不够清晰,使得一个模块的功能过于庞杂,不仅描述困难,编译器也可能产生很大的误解。
把握编译器的理解方式是有助于做Verilog的开发的,但这就需要一个长远的积累了,我在最后会给出一些例子。
●时序电路与逻辑电路完全分开Verilog中除了数据流模型和门级模型以外,最常用的是always即行为级模型描述电路。
一个always块可以理解为一个电路,或者实物上的一个芯片。
所以不要在一个always里杂糅时序电路和逻辑电路,那样很可能导致编译器综合出一些奇葩的结果。
时序always模块的敏感变量有且最多两个,一个是时钟边沿,一个是复位边沿,没有再多的敏感变量了。
组合逻辑always中敏感变量列表必须包含该模块所有涉及到的变量,或者直接用(*)代替,个人推荐后者。
●时序always块编写规范在时序always中,统一使用非阻塞赋值<=,因为时序always中在赋值号左侧的变量是真实的触发器,非阻塞赋值在触发时是同时赋值的,这很符合触发器在上升沿到来后同时将D输出到Q的实际情况。
基于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,先不用管什么区域约束,以后进阶了再学. .。
乘法器verilog设计的设计方法【1.乘法器的Verilog设计概述】乘法器是数字电路设计中常见的组件,其作用是将两个二进制数相乘得到结果。
Verilog是一种通用的硬件描述语言,可以用于描述和实现数字电路。
乘法器的Verilog设计就是利用Verilog语言实现乘法器的功能。
【2.乘法器Verilog设计的基本原理】乘法器Verilog设计的基本原理是通过移位和相加操作实现两个二进制数的乘积。
典型的乘法器架构包括全加器、半加器和数据选择器等。
在全加器中,乘数和被乘数分别经过多次移位操作后与乘法器输出相加,从而得到最终结果。
【3.乘法器Verilog设计的实现步骤】乘法器Verilog设计的实现步骤如下:1) 确定乘法器的输入和输出:根据需求确定乘法器的输入信号,如乘数和被乘数,以及输出信号,如乘积。
2) 编写Verilog代码:利用Verilog语言编写乘法器的逻辑功能,包括移位、相加和数据选择等操作。
3) 仿真和验证:对编写好的Verilog代码进行仿真和验证,确保其功能正确。
4) 优化和调试:根据仿真结果对代码进行优化和调试,以提高性能和减少资源占用。
5) 下载和测试:将设计好的乘法器下载到目标硬件,进行实际测试。
【4.乘法器Verilog设计的优化策略】1) 优化代码结构:合理划分模块,减少模块间的耦合度,提高代码的可读性和可维护性。
2) 采用高效的算法:如布斯算法、Wallace树等,提高乘法器的运算速度。
3) 减少资源占用:通过合理分配信号位数、使用紧凑型数据结构等方法,降低硬件成本。
4) 电源和时序优化:针对功耗和时序要求,采用适当的电路设计和优化技术。
【5.乘法器Verilog设计的应用领域】乘法器Verilog设计广泛应用于各类电子设备和系统中,如数字信号处理、图像处理、通信系统等。
在这些领域,乘法器作为基本组件,为实现高速、高效、低功耗的数字信号处理提供了有力支持。
【6.总结与展望】乘法器Verilog设计是数字电路设计的重要内容。
Verilog数字系统设计概述:Verilog HDL 是一种硬件描述语言,用于数字电子系统设计。
Verilog 适合系统级(system),算法级(alogrithem),寄存器传输级(RTL),逻辑级(logic),门级(gate),电路开关级(switch)设计,而SystemVerilog 是Verilog语言的一种拓展和延伸,更适用于可重用的可综合IP和可重用的验证用IP设计,以及特大型(千万门级以上)基于IP的系统级设计和验证。
Verilog的设计流程:自顶向下的设计搜索知识产权核(IP)系统级设计模块A 模块B 模块C模块A1 模块A2 模块A3 模块B1 模块B2 模块C1 模块C2软核:功能经过验证的,可综合的,实现后电路结构总门数超过5000门的V erilogHDl模型(很重要)固核:在FPGA器件上实现的,经验证是正确的,总门数在5000门以上的电路结构编码文件硬核:在某一种专用集成电路工艺(ASIC)的器件上实现的,经验证是正确的,总门数在5000门以上的电路结构版图掩膜。
系统级,算法级,RTL级属于行为级门级和开关级属于结构级描述测试信号的变化和测试过程的模块叫做测试平台(testbench)基本语法:模块结构的组成:一部分描述接口,一部分描述逻辑功能模块的端口:模块的端口表示的是模块的输入和输出名在模块被引用时,通常有两种方法1.flop flop_d(d1,clk,clrb,q,qn);2.flop flop_d(.clock(clk),.q(q),.clear(clrb),.qb(qn),.data(d1));模块内容:I/O说明输入口:input[信号位宽-1:0] 端口名;输出口:output[信号位宽-1:0] 端口名;输入/输出口:inout[信号位宽-1:0] 端口名;内部信号声明Reg [width-1:0]R变量1,R变量2...;Wire [width-1:0]W变量1,W变量2...;功能定义用“assign”语句如assign a=b&c;用实例元件如and #2 ul(q,a,b);用always 块如always@(posedge clk or posedge clr)begin...end数据类型常量:程序运行中其值不能改变的量,包括整型,参数型常量(parameter)变量:。
竭诚为您提供优质文档/双击可除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信号。
VerilogHDL 可综合设计的注意事项一、逻辑设计(1)组合逻辑设计下面是一些用Verilog进行组合逻辑设计时的一些注意事项:①组合逻辑可以得到两种常用的RTL 级描述方式。
第一种是always 模块的触发事件为电平敏感信号列表;第二种就是用assign 关键字描述的数据流赋值语句。
②always 模块的敏感表为电平敏感信号的电路可几乎可以完成对所有组合逻辑电路的建模。
always模块的敏感列表为所有判断条件信号和输入信号,但一定要注意敏感列表的完整性(注意通配符*的使用)。
由于赋值语句有阻塞赋值和非阻塞赋值两类,建议读者使用阻塞赋值语句“=”,原因将在“阻塞赋值和非阻塞赋值”中(现在还没有写)进行说明。
always 模块中的信号必须定义为reg 型,不过最终的实现结果中并没有寄存器。
这是由于在组合逻辑电路描述中,将信号定义为reg 型,只是为了满足语法要求。
③assign 语句的描述,利用条件符“?”可以描述一些相对简单的组合逻辑电路,左边的赋值信号只能被定义为wire 型。
当组合逻辑比较复杂时,需要很多条语句assign 语句或者多重嵌套“?”,使得代码可读性极差,因此此时推荐always组合逻辑建模方式。
④设计时要注意不要出现组合逻辑环路:不要在组合逻辑中引入环路,在组合逻辑中引入环路会导致电路产生振荡、毛刺以及冲突等问题,从而降低设计的稳定性和可靠性,此外,环回逻辑的延时完全依靠组合逻辑门延迟和布线延迟。
一旦这些传播时延有所变化,则环路的整体逻辑将彻底失效。
其次,环路的时序分析是个死循环过程。
目前的EDA 开发工具为了计算环路的时序逻辑都会主动割断时序路径,引入许多不确定的因素。
因此要彻底避免环路。
(2)时序逻辑设计①时序电路的行为决定了其只能通过always 块语句实现,通过关键词“posedge”和“negedge”来捕获时钟信号的上升沿和下降沿。
在always 语句块中可以使用任何可综合的标志符。
verilog十大基本功SOCvista的版主dancia最近对国内的主要EDA论坛做了一项调查,耗时一个多月,经过仔细的总结,发现一个有趣的现象:国内关于HDL提出问题的帖子,有80%都集中在一小部分基本问题上。
同样的一个问题,从5年前开始就有人问起,一直问到今天,很可能还会持续到N年后。
貌似新人们总也避不开这些说难其实也不难的问题,而且实际的调查还发现,就连好多工作多年的工程师们对这些问题也是稀里糊涂,似懂非懂。
为了帮助大家一劳永逸解决这些基本难题,从而迈向自由编程的康庄大道,我们特地开辟了这个版块,要把这些基本功一一传授给大家。
如果觉得我们的帖子还不过瘾,你可以回帖继续提问,务必把所有概念搞清搞懂。
另外所谓十项只是一个概述,请勿过分计较。
谢谢大家的关注和支持。
原帖见:dancia《高手也搞不清楚的十项基本功》/bbs/search.php?searchid=11&orderby=lastpost&ascdesc=desc&searchsubmit=yes以下是大家讨论的一个总结:1、阻塞赋值与非阻塞赋值前言:阻塞与非阻塞赋值是Verilog语言中最基本的部分,也是让大部分Verilog新手最困惑的地方。
关于阻塞与非阻塞的著作文章可谓汗牛充栋,这些文章对阻塞与非阻塞赋值的原理进行了非常详细的讲解,但新手读了之后依然有种似懂非懂的感觉,编码过程中一如既往的犯错。
所以,本文的目的立足于提供一种实用化的解决方案,用最简单的语言和形象的类比让新手能够一目了然的明白正确的编码方式以及相应的电路行为逻辑,关于仿真细节的讲解不是本文重点,需要了解更多细节的朋友可以参考文后列举的参考文献。
本文共分为三部分,第一部分是正确使用阻塞与非阻塞赋值的基本原则。
第二部分是阻塞与非阻塞赋值对应电路的行为逻辑。
第三部分是阻塞与非阻塞赋值的原理简介。
Golden Rule编码原则很多,就阻塞非阻塞赋值而言,新手最需要牢记的是其中三条:1、时序逻辑一定用非阻塞赋值”<=”,一旦看到敏感列表有posedge就用”<=”。
、不使用初始化语句;
2、不使用延时语句;
3、不使用循环次数不确定的语句,如:forever,while等;
4、尽量采用同步方式设计电路;
5、尽量采用行为语句完成设计;
6、always过程块描述组合逻辑,应在敏感信号表中列出所有的输入信号;
7、所有的内部寄存器都应该可以被复位;
8、用户自定义原件(UDP元件)是不能被综合的。
一:基本
Verilog中的变量有线网类型和寄存器类型。
线网型变量综合成wire,而寄存器可能综合成WIRE,锁存器和触发器,还有可能被优化掉。
二:verilog语句结构到门级的映射
1、连续性赋值:assign
连续性赋值语句逻辑结构上就是将等式右边的驱动左边的结点。
因此连续性赋值的目标结点总是综合成由组合逻辑驱动的结点。
Assign语句中的延时综合时都将忽视。
2、过程性赋值:
过程性赋值只出现在always语句中。
阻塞赋值和非阻塞赋值就该赋值本身是没有区别的,只是对后面的语句有不同的影响。
建议设计组合逻辑电路时用阻塞赋值,设计时序电路时用非阻塞赋值。
过程性赋值的赋值对象有可能综合成wire, latch,和flip-flop,取决于具体状况。
如,时钟控制下的非阻塞赋值综合成flip-flop。
过程性赋值语句中的任何延时在综合时都将忽略。
建议同一个变量单一地使用阻塞或者非阻塞赋值。
3、逻辑操作符:
逻辑操作符对应于硬件中已有的逻辑门,一些操作符不能被综合:===、!==。
4、算术操作符:
Verilog中将reg视为无符号数,而integer视为有符号数。
因此,进行有符号操作时使用integer,使用无符号操作时使用reg。
5、进位:
通常会将进行运算操作的结果比原操作数扩展一位,用来存放进位或者借位。
如:
Wire [3:0] A,B;
Wire [4:0] C;
Assign C=A+B;
C的最高位用来存放进位。
6、关系运算符:
关系运算符:<,>,<=,>=
和算术操作符一样,可以进行有符号和无符号运算,取决于数据类型是reg,net还是integer。
7、相等运算符:==,!=
注意:===和!==是不可综合的。
可以进行有符号或无符号操作,取决于数据类型
8、移位运算符:
左移,右移,右边操作数可以是常数或者是变量,二者综合出来的结果不同。
9、部分选择:
部分选择索引必须是常量。
10、BIT选择:
BIT选择中的索引可以用变量,这样将综合成多路(复用)器。
11、敏感表:
Always过程中,所有被读取的数据,即等号右边的变量都要应放在敏感表中,不然,综合时不能正确地映射到所用的门。
12、IF:
如果变量没有在IF语句的每个分支中进行赋值,将会产生latch。
如果IF语句中产生了latch,则IF的条件中最好不要用到算术操作。
Case语句类似。
Case的条款可以是变量。
如果一个变量在同一个IF条件分支中先赎值然后读取,则不会产生latch。
如果先读取,后赎值,则会产生latch。
只有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语句中都对变量赋初值。
综合生成的存储器如ROM或RAM不是一种好方法,只是成堆的寄存器,很费资源。
最好用库自带的存储器模块。
五、:验证
1、敏感表:
在always语句中,如果敏感表不含时钟,最好将所有的被读取的信号都放在敏感表中。
2、异步复位:
建议不要在异步时对变量读取,即异步复位时,对信号赋以常数值。