|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
可编程逻辑培训——Verilog 语言基础
. [6 }9 H, W% s# |1 @
* s' X% [) W% H. Z: F9 Y8 |' j' ?先记下来:8 b! F# O$ s, h/ A s9 F
1、不使用初始化语句;
6 k2 b, F* _* R& w, h2、不使用延时语句;. h( z. m# l2 k4 m& w. w/ o( l
3、不使用循环次数不确定的语句,如:forever,while等;
( D- v5 n8 U X; D4 l& F! _: C0 e& @4、尽量采用同步方式设计电路;& V( F6 r9 I& n2 S! M/ q
5、尽量采用行为语句完成设计;. a1 u( J4 c$ v2 h9 [$ `9 s+ J
6、always过程块描述组合逻辑,应在敏感信号表中列出所有的输入信号;
+ O0 s# M$ R. v0 u7、所有的内部寄存器都应该可以被复位;
* W0 m. v; l ^, v1 m8、用户自定义原件(UDP元件)是不能被综合的。
# Q; h) {# u& N# j一:基本
; y, I% I/ d. D. _; }5 lVerilog中的变量有线网类型和寄存器类型。线网型变量综合成wire,而寄存器可能综合成WIRE,锁存器和触发器,还有可能被优化掉。- q0 x0 j( X; T. |
二:verilog语句结构到门级的映射
0 J- l% I1 F- s" g- z1、连续性赋值:assign2 p9 R4 G( Y; M7 Q1 M2 ~8 S
连续性赋值语句逻辑结构上就是将等式右边的驱动左边的结点。因此连续性赋值的目标结点总是综合成由组合逻辑驱动的结点。Assign语句中的延时综合时都将忽视。+ b1 Q6 \+ D; J L- z+ L- p2 {$ y% `2 K
2、过程性赋值:+ G. q1 V* _! }4 r) N
过程性赋值只出现在always语句中。
- A1 g& D5 M( W9 Q+ p ~4 b阻塞赋值和非阻塞赋值就该赋值本身是没有区别的,只是对后面的语句有不同的影响。
$ L+ z+ ?. E5 X* O建议设计组合逻辑电路时用阻塞赋值,设计时序电路时用非阻塞赋值。: b# t/ m) Z, | y5 E
过程性赋值的赋值对象有可能综合成wire, latch,和flip-flop,取决于具体状况。如,时钟控制下的非阻塞赋值综合成flip-flop。
6 s! t9 z J/ [3 e- G过程性赋值语句中的任何延时在综合时都将忽略。1 W$ X* `3 W4 F$ N+ O+ m
建议同一个变量单一地使用阻塞或者非阻塞赋值。' X9 M/ D. w. K% g( Q- A
3、逻辑操作符:
7 r0 o" h9 b- h9 L& Y: U$ [" {逻辑操作符对应于硬件中已有的逻辑门,一些操作符不能被综合:===、!==。
& M6 S% H( v5 ~5 O l" z$ e" G/ C4、算术操作符:' b. S- A4 n/ d W q" |4 w* V* Q
Verilog中将reg视为无符号数,而integer视为有符号数。因此,进行有符号操作时使用integer,使用无符号操作时使用reg。
% s4 g+ `" K7 z/ K' {5、进位:; j5 Z3 y9 ?+ O6 U4 d$ V
通常会将进行运算操作的结果比原操作数扩展一位,用来存放进位或者借位。如:
# e3 p- {. x* q2 V _) p7 y: |Wire [3:0] A,B;
! N8 K5 N/ g/ M$ mWire [4:0] C;; o8 Y; d5 g G! K0 X
Assign C=A+B;. w5 b9 g* T$ ^/ \% l- _
C的最高位用来存放进位。 T. q. @5 d- m8 M! U
6、关系运算符:4 w! L9 k) t/ }! x
关系运算符:<,>,<=,>=
* ]2 h7 Z/ h3 x% q/ |+ h和算术操作符一样,可以进行有符号和无符号运算,取决于数据类型是reg,net还是integer。. j% p- e8 E% J! P# p
7、相等运算符:==,!=
: X" S+ x8 g& Z* [2 k, Z注意:===和!==是不可综合的。2 o3 R$ Z( D; u$ Y6 Q
可以进行有符号或无符号操作,取决于数据类型
% F2 B) N ]0 |! F8、移位运算符:
( w7 [# A5 v* L左移,右移,右边操作数可以是常数或者是变量,二者综合出来的结果不同。) U8 G0 ]5 A* v# k! M
9、部分选择:+ \/ _- x6 I9 M9 I- u9 u3 Z
部分选择索引必须是常量。7 K5 q5 A: m9 X3 b) v- A2 c& Z6 c
10、BIT选择:/ H- A8 H; s$ Z
BIT选择中的索引可以用变量,这样将综合成多路(复用)器。
8 e* R7 x! T8 _4 q% S) P11、敏感表:Always过程中,所有被读取的数据,即等号右边的变量都要应放在敏感表中,不然,综合时不能正确地映射到所用的门。; B% l" I+ q u9 x+ E/ S8 _- D
12、IF:
# J8 n# |4 J. m: |如果变量没有在IF语句的每个分支中进行赋值,将会产生latch。如果IF语句中产生了latch,则IF的条件中最好不要用到算术操作。Case语句类似。Case的条款可以是变量。
~7 h: Z+ s7 q) d" p$ f如果一个变量在同一个IF条件分支中先赎值然后读取,则不会产生latch。如果先读取,后赎值,则会产生latch。1 c7 h. w$ l' c7 }% E. _
13、循环:# T, m+ Z+ }* `2 W1 R
只有for-loop语句是可以综合的。
1 C% V0 J) G! D# E) y14、设计时序电路时,建议变量在always语句中赋值,而在该always语句外使用,使综合时能准确地匹配。建议不要使用局部变量。* }' `$ \0 O' j
15、不能在多个always块中对同一个变量赎值
$ ?! x& C. [( |& [2 j16、函数4 Q. V6 i* G3 b: c8 {, r- m
函数代表一个组合逻辑,所有内部定义的变量都是临时的,这些变量综合后为wire。# H& w2 U$ h7 |" O
17、任务:
8 D6 g2 k) |9 N; o, Y% n& i. N任务可能是组合逻辑或者时序逻辑,取决于何种情况下调用任务。
) W" K$ t2 ^; r18、Z:' F6 w/ y* s* N5 L7 Z- X
Z会综合成一个三态门,必须在条件语句中赋值
9 b6 ]4 i5 G1 R) ], m19、参数化设计:
* N/ R! Y2 F/ l6 n' a优点:参数可重载,不需要多次定义模块
' t1 {- _; S/ w9 L3 Q& B" z* M; U S: @6 [
*基本原则1 i7 X Q9 Y. A( e! z5 S
设计时应该把你的系统划分为计数器,触发器,时序机,组合逻辑等等可综合的单元,对此不同的IC公司和EDA开发商可能根据自己的见解和经验提出不同的要求,并且对verilog程序的细节进行自己的规定,但有一点是对的:即写硬件描述语言不象写C语言那样符合语法就行.单单符合verilog语法的程序可能被拒绝综合,甚至被拒绝模拟;0 n6 o- D3 k+ R0 w
*最外层可以写什么?( L( r4 _/ M; ?# N) s
这里所说的最外层是指module语句后的第一层,在这一层可以写这些可执行语句:( S; d* s6 C9 v2 D( S
assign和nand等定义组合逻辑的语句,
J- K$ a3 h$ f! Xalways语句,
o% I4 I0 g2 n, y& B# V模块引用语句,# s6 {* f# Q. m% p, U. Q J
一些以"$"开头的系统定义语句.4 h4 ~* m0 x4 [9 k* ~, }6 K
特别注意不可以写if语句.if语句只能放在always内部.
& ~0 s( b' [9 ~% s$ w6 v不推荐写wait语句,因为不能综合.
: }/ {$ B: ]. U) P7 i*不可以在多个always语句中对一个信号赋值.+ L- u# P: M8 ~5 e% h
1.强烈建议用同步设计: G: }6 ?" x6 l+ I% c7 G2 ^
2.在设计时总是记住时序问题$ f2 p7 x9 s# z D% e. Z
3.在一个设计开始就要考虑到地电平或高电平复位、同步或异步复位、上升沿或下降沿触发等问题,在所有模块中都要遵守它4 D" w7 I0 W6 }/ r0 T1 b4 H
4.在不同的情况下用if和case,最好少用if的多层嵌套(1层或2层比较合适,当在3层以上时,最好修改写法,因为这样不仅可以reducearea,而且可以获得好的timing)
: g t; O" x2 [; T5.在锁存一个信号或总线时要小心,对于整个design,尽量避免使用latch,因为在DFT时很难test。7 Y& Z8 K3 o, h0 e' j; n4 V
6.确信所有的信号被复位,在DFT时,所有的FlipFlop都是controllable,2 ]2 }, }- b& H
7.永远不要再写入之前读取任何内部存储器(如SRAM)+ @8 {1 U# z; p0 ?% k, B
8.从一个时钟到另一个不同的时钟传输数据时用数据缓冲,他工作像一个双时钟FIFO(是异步的),可以用AsyncSRAM搭建AsyncFIFO。
; O9 {8 y0 t: ]9.在VHDL中二维数组可以使用,它是非常有用的。在VERILOG中他仅仅可以使用在测试模块中,不能被综合
% a& B# Q" e& K( }10.遵守register-inregister-out规则
1 g6 P3 R8 t N, \11.像synopsys的DC的综合工具是非常稳定的,任何bugs都不会从综合工具中产生$ d7 j: }* J3 e4 Q$ W7 X0 l l) [+ w
12.确保FPGA版本与ASIC的版本尽可能的相似,特别是SRAM类型,若版本一致是最理想的,但是在工作中FPGA版本一般用FPGA自带的SRAM,ASIC版本一般用厂商提供的SRAM。8 Z6 L e' a4 U z4 @
13.在嵌入式存储器中使用BIST) G" i9 \1 t0 V/ q/ T3 p
14.虚单元和一些修正电路是必需的
/ w: f3 f- t+ j$ j15.一些简单的测试电路也是需要的,经常在一个芯片中有许多测试模块1 s$ f! q7 a; r7 j1 @
16.除非低功耗不要用门控时钟,强烈建议不要在design中使用gateclock
2 D% W" {/ H! W( K! O4 }; E& e17.不要依靠脚本来保证设计。但是在脚本中的一些好的约束能够起到更好的性能(例如前向加法器)
. b z. p5 h$ m' B/ V, Y! v Y18.如果时间充裕,通过时钟做一个多锁存器来取代用MUX
4 Z# L5 k) s( [19.不要用内部tri-state,ASIC需要总线保持器来处理内部tri-state,如IOcell。' L% h* G7 Y' J# q2 Z6 }: f7 `
20.在toplevel中作padinsertion
% o( q4 j+ d+ a: o3 i21.选择pad时要小心(如上拉能力,施密特触发器,5伏耐压等),选择合适的IOcell
& w, ]3 e/ p5 }* {; f* p22.小心由时钟偏差引起的问题
4 r( d3 D7 c' d) {) ~23.不要试着产生半周期信号
$ p" K7 B4 ^/ J1 U( n, u24.如果有很多函数要修正,请一个一个地作,修正一个函数检查一个函数
# Y" B% X/ t' U7 f& C25.在一个计算等式中排列每个信号的位数是一个好习惯,即使综合工具能做8 @3 F/ T0 n8 `3 z6 z+ {
26.不要使用HDL提供的除法器' d, b) P4 f2 p2 M- h0 z0 Y* Y( I
27.削减不必要的时钟。它会在设计和布局中引起很多麻烦,大多数FPGA有1-4个专门的时钟通道
0 `# n( L$ t9 q! C. c }0 V |
|