1.多个always语句不能对同一变量赋值。
2.assign语句只能进行阻塞赋值,用来描述组合逻辑。
3.verilog描述方式:结构描述(门级描述和模块调用)、数据流描述(assign,wire型)、行为描述(initial、always,reg型)。
4.数据流描述根据信号(变量)之间的逻辑关系,采用连续赋值语句描述逻辑电路的方式,称为数据流描述。狭义理解:将传统意义上的“逻辑表达式”,运用VerilogHDL中的运算符,改变成连续赋值语句(assign语句)中的表达式。
assign 连线型变量名= 赋值表达式;
wire型变量没有数据保持能力,只有被连续驱动后,才能取得确定值。(而寄存器型变量只要在某时刻得到过一次过程赋值,就能一直保持该值,直到下一次过程赋值。)若一个连线型变量没有得到任何连续驱动,它的取值将是不定态“x”。assign连续赋值语句就是实现对连线型变量进行连续驱动的一种方法。
进一步讲,assign持续赋值语句对wire型变量赋值后,始终监视赋值表达式中的每一个操作数,只要赋值表达式中任一操作数发生变化,立即对wire型变量进行更新操作,以保持对wire型变量的连续驱动。体现了组合逻辑电路的特征——任何输入的变化,立即影响输出。所以,可根据组合电路的逻辑表达式,用assign持续赋值语句进行描述。数据类型缺省为wire型。
而reg型的驱动可以通过过程赋值语句实现,变量被赋值后在接受下一次的过程赋值之前,将保持原值不变。
5.永远不要忘记写default,以避免因为没有考虑完整case的所有分支而引入了不必要的锁存器。若正常功能的所有情况都包含在了case的显示条件判断分支中,则在default语句中,可以给输出变量赋x值。在仿真时,错误的x值可以传播,可以更容易发现因为case分支没有写全造成的错误。而在综合时,综合工具会自动选区最合适的固定值在default情况下赋值给输出信号,以生成最优化的电路。
6.在设计一个模块电路时,应尽量采用参数化的设计,即多用parameter定义一些可配置的电路参数。这样,该模块可以被更灵活的使用。在模块实例化时可重定义模块参数或使用defparam。如:fulladder #(2,3) u_fulladder。
7.多模块设计。建模思想。
8.分别用Quartus和ModelSim进行功能仿真和时序仿真。
9.当begin-end块中定义了局部变量时,必须有一个模块名。
10.FPGA上电寄存器初始值问题。
You can apply the Quartus II integrated synthesis Power-Up Level logic option to a
specific register or to a design entity, module or subdesign. If you do so, every register
in that block receives the value. Registers power up to 0 by default; therefore you can
use this assignment to force all registers to power up to 1 using NOT gate push-back.
如果要规定寄存器上电的电平
需要在Analysis & Synthesis Settings 中去掉Power-Up Don't Care 选项,
如果选择这个选项会让编译器按照逻辑优化对寄存器初值任意取值,或者根本就不关心是什么值。
而它是默认选中的。
当去掉这个选项之后,就可以在你的HDL源文件中,为寄存器变量赋初值了。
如Verilog中:
reg q = 1'b1;
11.时序的精确控制,定时计数器。
12.Verilog具有强大的位操作能力。
13.else,in RTL
inout use in top module(PAD)
dont use inout(tri) in sub module
也就是说,在内部模块最好不要出现inout,如果确实需要,那么用两个port实现,到顶层的时候再用三态实现。理由是:在非顶层模块用双向口的话,该双向口必然有它的上层跟它相连。既然是双向口,则上层至少有一个输入口和一个输出口联到该双向口上,则发生两个内部输出单元连接到一起的情况出现,这样在综合时往往会出错。
14.组合逻辑复杂时,优先always语句,语句中被赋值的必须是reg类型,可以实现较复杂的语句。
15.设计电路时要区分组合电路和时序电路。
16.要用到值的上一次值时,需要寄存器保存该值。
17.对于组合逻辑多输出,在case语句之前先赋给默认值,这样做避免了锁存器的产生,减少了在每一个case分支语句中对于其他输出的赋值,且强调了分支语句中某个输出的改变。
18.进入FPGA的信号先进行同步,保证同步设计时序,提高系统工作频率。
19.Verilog层次事件队列,优先级高到低:1.活跃事件:连续赋值(assign)、阻塞赋值、非阻塞赋值右式计算、$display、原语元件事件;2.非活跃事件:显示0延时的阻塞赋值、带PLI例程的回调过程;3.非阻塞赋值左值更新;4.监控事件:$monitor、$strobe;5.未来事件:未来非活跃事件、未来非阻塞赋值更新事件。
20.状态机跳转判断条件不应有较大的计数器(大于4位),应该移到状态机外部产生使能信号进行判断。
21.顶层尽量只做模块例化,不出现胶连逻辑,包括与非或门和选择器。
22.推荐模块间数据传递要寄存器化。
23.利用时钟使能电路解决设计中可能的多时钟,进而避免了不必要的亚稳态发生,在降低设计复杂度的同时也提高了设计的可靠性。详见http://www.cnblogs.com/qiweiwang/archive/2010/12/18/1910186.html#2690007和http://blog.163.com/xupengee@126/blog/static/141308243201052384539804/。
24.延迟n个时钟利用拼接运算符{}完成辅以assign,详见http://www.cnblogs.com/oomusou/archive/2009/06/15/verilog_dly_n_clk.html。
25.不要同时使用同一时钟的上升沿和下降沿,可以考虑利用PLL将原时钟倍频或者相移180度。
26.使能信号扇出过大,可以逻辑赋值或者打拍。
27.时序应该是先设计好,再实现。调试的时候可以通过SignalTap抓信号比对时序,进行修改(状态机输出信号)。
28.多周期约束能解决的问题:(1) 组合逻辑延时大,不可能在下一个时钟沿达到;(2) 不需要在下一时钟沿稳定; (3) 不同时钟域,但是有确定相位关系。
29.ALTERA的RAM宏模块默认输出时寄存一拍的,可以根据实际需要不寄存输出。
30.利用Modelsim、Matlab和SignalTap进行互相验证,尤其是Modelsim和Matlab的联调(基于读文本txt的方式),详见http://www.cnblogs.com/aikimi7/archive/2013/06/06/3122573.html。
31.ModelSim仿真出现“Unresolved reference to'...'”.,后续端口大小不匹配,原因是模块例化时端口前面没有加一点!!!
32.重要:更改状态机状态参数和其他parameter型参数时,为了使修改后的参数生效,务必重新生成bsf,用以顶层模块连接!!
33.Verilog-2001将`bz和`bx赋值扩展到变量的全部宽度,即wire [63:0] my_data = `bz,64位都为高阻值; 支持对数或者幂运算符“**”;带符号的算法运算;
Verilog介绍:http://zh.wikipedia.org/wiki/Verilog_HDL,Verilog-2001新特性:http://blog.sina.com.cn/s/blog_6e44841b0100mm91.html。
34.FIFO的作用:跨时钟域、数据缓冲、总线宽度转换等。