|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
一、 代码设计
3 o( ^ E' l6 p5 W) y. r( j9 _ M- P! W4 p- ~
1、设计中的FIFO、状态机接口需要有异常恢复状态和状态上报机制,格雷码电路防止被综合工具优化掉。; ] t( t: j7 f8 W- F! a& Y
1 R7 O9 b' \4 L# g* ya)自行设计的格雷码FIFO(一般用于连续数据流跨时钟域)用Synplify综合时,为了防止被优化需要添加综合引导语句:“synthesis_syn_preserve = 1”;+ J' B+ O" F4 W* ?6 T0 L( n
`6 k$ g$ ]6 @- [b)各种综合工具均有状态机安全模式,综合时候建议打开。
: \+ l5 ]& g% ?4 f2 v$ F6 F$ e5 ]7 F0 k( x( G D
2、电路中所有寄存器、状态机、计数器、FIFO在单板上电复位时及使用前必须处于一个已知状态。
$ ~7 s- `8 ^1 f7 [7 P
% M3 _% S' Y, B p- {9 n a)对电路中的寄存器、状态机、计数器、FIFO必须进行异步复位(不依赖于任何时钟的复位);
, _. e3 z7 K+ l7 z7 @; U' o8 \2 F4 \8 d2 \" Y" V
b)电路中的状态机、计数器在应用的时候不能完全依赖于异步复位时的状态,对于重要的状态机或计数器,必须还有周期检测或同步并对它进行复位/置数机制,保证可靠工作。: z" P; a9 V* S% {( A, ^
" \. V9 Q' J" u c5 D7 G( e3、跨时钟域以及异步信号必须同步化处理(使用的QuartusII中的Design Assistant或者专业的nlint、spyglass[1]等工具完成代码检查),这条是用FPGA进行数字电路设计的最核心最基本的思想和方法!, V) d6 j0 K B% c6 @7 A
* ?& T1 S9 h7 a! ~1 F3 O
a)尽可能在整个设计中只用一个主时钟,同时只用一个时钟沿,主时钟走全局时钟网络;
2 r% E9 R* ]& }5 Z2 m+ ]8 \
$ ^ c% [% d4 r) f2 A5 ] zb)推荐所有输入输出信号均通过寄存器寄存,寄存器接口当作异步接口考虑;
* a0 N ^; y6 t' z4 ?
% |& \# Z$ v! S1 T p! d; d6 K8 ]c)当全部电路不能用同步电路思想设计时,即需要用多个时钟来实现,则可以将全部电路分成若干个局部同步电路(尽量以同一个时钟为一个模块),局部同步电路之间的接口当作异步接口考虑;
2 H2 U% P2 N" @2 a$ ]6 i9 y# H+ w4 N( ~+ E
d)电路的实际最高工作频率不应大于理论最高工作频率,要留有一定设计余量,保证芯片可靠工作;. V( F) P- \3 L; [' N" O' w
, ^% p: b% z2 b- Y* F$ w A# qe)电路中所有寄存器、状态机在单板上电复位时应处在一个已知状态;8 H+ p! V) C* n E! V
& b/ u2 `( e, U! f- uf)对于设计中的异步电路,要给出不能转换为同步设计的原因,并对该部分异步电路的工作可靠性(如时钟等信号是否有毛刺,建立保持时间是否满足要求等)做出分析判断,并提供分析报告;$ N6 z0 | P0 ~; {5 ?
& W2 j9 g( G0 B, w7 m- Gg)关于全局时钟的约束,能上全局的全部上全局,不能上全局的建议通过区域时钟约束、逻辑锁定、增量编译等保证性能;
7 ~& o% e; L3 W; p5 n3 Z$ V2 }! R% |# C. j# a% L
h)依靠QuartusII中的Design Assistant或者专业的nlint/spyglass工具检查跨时钟域代码处理部分。
; F! b3 ~/ O( T6 H( P B9 T: ~. y2 S7 S
4、电路中不能出现门控时钟和行波时钟。
/ Q& \& n" I. A' l$ r$ `, X
! N- K8 i: @' H2 d1 Qa)门控时钟的使用主要是通过关断时钟来达到降低功耗的目的,但是使用不当容易使得时钟出现毛刺,给设计带来灾难性风险。如果降功耗必要的话,推荐使用厂家自带的时钟控制的IPCORE,例如 ALTCLKCTRL;5 z2 x, _2 b+ l# o
: D# s: X! W% C1 H7 w! Fb)行波时钟是指寄存器输出的数据又作为下一个寄存器的时钟使用。行波时钟是一个非常危险的设计,由于寄存器有Tco,它会使时钟沿变缓,延时加大,多级级联的时候情况更加恶劣,出问题是必然的!行波时钟设计实际上是一种异步设计,大部分综合布线工具都不会对行波时钟设计进行setup/hold时序分析检查,设计无法保证正确性!
; X- n, ?9 C; O2 s% T4 z6 X- Q! p, s) E% W# W
设计中完全没有必要使用行波时钟,可以用寄存器输出做同步使能用,与行波时钟设计意图完全一致!" ~* I* J6 b$ r2 C% w& w
1 a3 J: X/ ~0 r1 E' i5、需要综合的RTL源代码中不允许出现“* / %”这三个运算符。7 b+ F. ?9 d+ [' c6 g( Y2 A& _
3 r- N& o% C) _# L, V
a)目前大部分综合工具对以上三种运算支持的不好,而且非常浪费LE资源,而且还不能保证正确性和稳定性!可行的替代方案如下:
6 ?# `$ h# x# g& T/ J
( ]1 Y# L* R: }: f! E& `“*”通过例化IPCORE或者“移位运算+加法”来实现;
) S$ B3 H' z* X0 ]" P
% u1 O: x4 u; a2 D9 g; M7 l“/”通过“移位运算+加法”来近似逼近实现;例如:1/30 = 1/32 + 1/512 + 1/8192;) U0 E i) }3 c6 v5 n) A
7 t0 W6 \9 E% ?9 q! u' g4 R- v“%”通过自己手动计算得到;4 F$ G1 y/ o7 G" r7 |
& N' W w$ z/ C! ]以上运算在非综合的RTL的代码中使用不受此限制。
2 d% M+ w& D$ E9 }0 e$ Y# y$ c, x6 t) \) P( |
6、条件语句必须赋值完全,即:if语句后必须有配对else语句,case、casez、casex语句中必须有default语句。: _" ^0 H+ H6 L9 ]
8 _: \$ k1 S, o5 k2 pa)如果if没有配对的else,case/casez/casex中没有对应的default语句的话,之后reg型数据会保持原来的值。这个在时序逻辑中可能没有太大的问题(如果设计者本意就是要保持的话),但在组合逻辑中会生成一个锁存器,锁存器逻辑往往不是设计者的意图而导致灾难性后果!( X% V+ V" z/ G- K# T) W
- _+ f' f8 Z h/ F3 f6 v
为了避免不经意的犯错,建议养成良好的编码习惯:if一定要有配对的else,case/casez/casex中一定要有对应的default语句,即使要保持原来的值也要显示声明(else;或者default;)" G8 S8 @. M! Z4 R
" y) D8 d8 E+ \/ {6 }0 U
7、使用器件的专用管脚和专用资源实现电路功能,这些包括全局时钟、复位管脚,全局输出允许管脚等,内部全局时钟网络等。( B b4 A. f* t2 c, f. w, U# E8 R
. q0 c3 w- |$ I3 q0 X" H
a)专用管脚和专用资源一定要优先使用,使用得好会事半功倍。如果不用器件提供的专用管脚或资源,有时导致稳定性和可靠性不高甚至是设计失败。) H5 q& D3 _. F0 g' V: Y" f6 q# U
- O( B% T' }3 ?& ~, b% K' L
8、逻辑未使用的但又硬件连线的管脚,逻辑必须显示声明并处理。所有有硬件连线的管脚必须在顶层代码中显示声明(包括暂时没有使用的),不允许放任不管。
# Q/ ~( l2 m' K0 m* Q0 d6 l ~# w5 n$ t5 R( [* V a
a)对于有硬件连线的输入信号(包括三态的输入方向),建议输入到CPU接口作为只读寄存器(如果没CPU接口可以将该信号做成一些等效冗余逻辑加到其他逻辑中去),这样既可以消除warning,又可避免布线工具随便布线(把输出信号放到输入管脚)导致外部信号冲突;/ y" P" f8 v% P9 l
# j+ W2 ?# F! k- c/ lb)对于有硬件连线的输出信号(包括三态的输出方向),对于暂时没有使用的一定与硬件人员确定其默认值,避免对外信号(如电阻上下拉)的干扰。8 U& j( b* y( D5 T% ]
2 [7 Y% e+ Q% D, M' _+ f1 L' j9、修改接口文档需要同对应项目组人员确认。7 C' W& x3 t/ D
% K5 l/ |7 @1 y+ ^ d" L. {1 ^5 y
a)与硬件相关的方面涉及输入文件有qsf和sdc,内容包括但不限于电平标准、电流强度、管脚位置、输入输出方向、上下拉等等;
- x3 z. ]: E$ Y. H" C
' ~' z/ P7 W" p- {b)与软件相关的方面涉及方案协同实现文档和寄存器接口文档,包括寄存器操作地址、操作顺序等等。; s; V! V1 p& O) }
! g& ^. t7 }# _ K) {5 n' W二、 综合布线过程1 o- }0 Z! \; Y2 ~
' ]+ e, O9 ?5 I
1、综合布线的版本是否与配置库上的版本完全一致
! `) k& H7 {1 x' t
. u6 Q2 F' v( t+ G9 Ra)养成良好的版本维护和管理习惯(如复制修改和设置只读属性等),善于使用代码比较工具修改版本(包括源代码、qsf和sdc等输入文件要全部仔细比对)。- N' _: A$ a9 h: x
: p% @0 Q5 o; O6 a5 P
2、所有约束(包括对外部接口的管脚约束、时序约束、内部时序约束)是否已经添加正确,布线报告满足约束要求,时序无error类告警。1 F! B+ `. [$ N K. t) A
; R) o! V: Q( h$ Y4 x6 Ua)硬件方面:电平标准、电流强度、翻转速率以及上下拉(差分时还有输入阻抗匹配,高速信号还有预加重、VOD、接收均衡、直流增益等);
) ?3 }6 M \; S5 i3 `; o. S, Q' l: k5 C# |
b)输入输出锁IOB/IOE,时序约束正确(Tsu、Th、Tco、Fmax);( f* t4 a+ P8 U0 V! C
q7 G) A( r" \1 d/ o- z8 X
c)异步和组合逻辑锁IOB/IOE,加set_minimum_delay和set_maximum_delay约束;! H/ {& ~! \- |; t: u6 |2 B
& C/ R% b) y9 A
d)时钟约束有基时钟、衍生时钟、虚拟时钟和多周期约束等。6 p5 V% a. R- z$ w+ |
3 S* [. g: o# i# F9 Y3、所有编译、布线、时序分析等过程中出现的warning都已经确认。
. I* U, }1 }7 b2 K8 R+ r y( \# g5 z* z+ J) K+ I1 K2 v! v3 Q- X
三、 版本验证过程 u- O' W4 n& e. T% J" P4 v8 y: q
* i8 q* d* K6 U6 m9 J) b 1、修改模块必须进行UT(单元测试)。+ J( k( J4 @! w$ e9 n# I$ ?. W
7 W' `0 J: S# }a)建议UT的覆盖按照功能覆盖优先,分解测试点,根据测试点来设计测试用例,保证测试点覆盖率为100%;$ ]' X9 s* c. z# E
6 m& T# F- o3 X" u. R& P! Nb)在功能覆盖率的前提下关注代码覆盖率,建议的代码覆盖率标准为:语句覆盖和分支覆盖为100%,条件覆盖和表达式覆盖率为90%。
5 {8 W- X L w& F% A
- }+ w& E9 x7 t$ M! L; v: |9 u 2、有条件的话单板验证必须进行完整的STB(上板系统测试)或全系统业务平台测试。7 a" m1 c6 o: L- w" U( N
6 M* n# H7 s0 r& t( I$ W( b# f- a
良好代码编写风格可以满足信、达、雅的要求。在满足功能和性能目标的前提下,增强代码的可读性、可移植性。
Z1 [ u8 W4 `) L/ aFPGA优化方法和准则概括如下:
, }- {/ _3 X( E9 @2 x
% k; ^- E8 N8 U. K4 v' g一、 面积类' j# l, U. r! Z- c
0 a/ m& A: Z3 _4 N/ Z
1、不进行不必要的数据清零。4 n# z# ?. O/ S; Y9 J
0 M. a2 \6 Y) o0 @/ ~& O6 y 说明:一般在数据总线赋值额时候,习惯加上例如的:“else dout [15:0] <= 16’d0”,实际上这种清零并不是必要的,因为一般写使能就已经控制了数据的有效性,数据即使保持原值也没有问题,加入上述语句后,综合其会用多余的资源实现这个没有必要的清零分支。! A* S/ l# x! X1 W7 W# i
. c/ }9 ]" G) `3 P+ }
2、多路数据进行相同处理时,先选择后处理优于先处理后选择。
8 @( }: b/ w* m$ r0 _2 Y; k& m$ y3 E7 n, |# N0 G- Q; W
3、采用合适的编码方式(one hot bit速度更快,但是资源消耗得也更多)。
, z7 _' N8 ]; Q. C1 T' y
( ^6 B, y& @, \4 J4、多拍串行计算打开为一拍并行计算- r' e" w! f1 h" z' j
' Z: W L* e) w8 P5、统计寄存器位宽根据需要来确定,不需要一位的32bit大位宽。' N2 g* B% f+ K, L& U+ c) g
2 B# ^& U) R% n/ K, b) j8 _' z6、异步配置信号(CPU)可根据配置模块所在不同时钟域分别进行处理。
' W, X) l6 T7 v- w, R5 s( H+ p7 b: ^) m( j7 f# O( m. N
7、尽可能实现资源共享(计数器、比较器等),节省资源。
6 a1 y3 t0 O- f& _' `0 Z3 v1 ?2 }! |% i3 L2 }
8、采用迭代算法节省资源。) S) X* _& U: Q' J! U5 \. u
# Y) h% l+ \4 o! Z) @/ V8 O10、使用reg代替FIFO接口。
" x# E/ E I' J# p% _9 c& o1 `( P) \ ?( H
11、状态机状态不要在比较器中使用。, _, K/ ~- E% R, R, A
+ M/ E. i w. _) H& d
12、3倍插值FIR滤波器优化。
* P7 D0 T( n( @9 L/ H- I0 f* G' o
, F( ~( X$ D/ K: d- H. q" r13、用减法器借位位代替比较器。; H1 _* i {/ N
. L' w4 ?& ?6 P5 ]2 H8 G
14、利用ROM代替较大的组合逻辑。
6 ~9 d, j9 {. U0 g( U! }& y
# ?+ O6 Q3 ?" w% C15、利用多周期约束或通过RAM换LE的方法来节省CIC滤波器LE资源。
9 L. v* q% B: U [6 J! A0 s$ [7 q
- k+ Z* O o! x4 n16、Multiplexer重编码节省LUT资源。3 g) b4 K$ ?2 Q- Z$ S
" E6 X& Y8 ~+ \1 y, g2 B0 N& k17、合理设置MUX默认条件有利于资源优化。例如:“default:dout <= 1’dx;”& O2 f0 {1 }2 x
" h8 H1 A+ ~: M6 ~6 A% J
18、合理设置QuartusII软件中auto packed register选项1 n" }7 U4 s3 x/ G. h
& _& e" p" `- ^2 i9 b$ Z# I" M0 f; n20、建议使用“减法溢出”来设计Timer。
9 j d. R' K" i. i. A' K3 I/ E5 f. W+ a C) X5 L; Y
21、简化环回设计,节省资源。
# m; D- `" X* k0 K/ y9 L' `; Q
3 Z% C, L* P/ Q22、减少时钟域,节省资源。* T( R! m- C0 c1 {. e/ V
: W E, a5 e5 f, f23、复数乘法公式展开,利用加法部分代替乘法。
" p. Y' r# @! \* p. b) h& r' Y `
24、禁止使用shift reg自动替换功能,避免小的的移位寄存器浪费M9K。" M4 b3 d }) H* M# ?
% }; }, s. C2 o% Y25、基于RAM的交换架构。
3 I2 s/ e$ L' J3 `
: d) h9 l1 o$ i26、用RAM存放统计值来代替统计寄存器。4 T1 h' B; P) C/ I0 b, q
* W! w% S9 B& X4 |4 }- |28、多通道分时处理时,功能相同的模块可以考虑复用。
. p8 X* O$ F3 @! M. b
" G: z( w% w2 W( K: w+ `29、复用没有全速运行的模块,多通道RAM使用复用模块代替。8 V+ U% w+ y9 w6 N9 |
' s2 g2 x% m) }4 ?& m* s0 v1 ?RAM节省部分
2 B/ E+ v; v$ o$ ]1 \; {* h) T& C; R) u- _ j
1、 使用根据器件RAM块的位宽和深度合理选择。
8 ]9 D7 u8 O! \5 k2 L: b& t3 G
9 I. R1 }* v) N& d4 n1 l* B, W2、 使用分布式RAM替换寄存器资源1 f9 l" r. Y$ x) ] S8 X, J6 b0 T
1 E' w) A$ Z' P0 \* A7 W' d! f
3、 2倍插值滤波器优化。
' p5 R+ k8 h5 C: n( x
9 `* w* x4 m4 J其他部分1 O8 [) u' w" C
# N6 L0 D" a B/ N: ]) {1、 根据器件内部block RAM特点,选择合理的拼接模式,可以减小RAM块地址译码和数据选择的LE。' Q3 ?; Y6 c! k6 W6 S
4 X" L: J3 A0 ^* ?8 A6 b2、 路由查表优化。- g7 l7 H N3 Q0 l7 ~. A4 G
3 n# I9 V8 R! x1 |
二、 时序类# v/ K& M ?* |: }5 L# S
. A# u" c# G% k7 C* ^1、打平逻辑可以提高时序。( {8 P) V( G O$ n% x
, p. [' l" E3 T" e0 o5 c" K+ T- s
2、配平寄存器以提高时序。9 o! `, e# s0 E4 g: t- i: D
8 V# ^& ?0 y8 {. ^7 P
3、尽可能减少组合逻辑。* Y& _1 L2 K9 T6 d7 G
% F) ^8 ^4 Y: K1 Z/ a4、在输出到IOB时安排布线时延要求低的路径,要求高的放在内部逻辑。
/ x p' ~3 ~7 g. \
+ |" ]: D- t1 x1 T, @9 e7 b5、降低高速时钟域布线资源。+ @9 [- ?" W1 L! v( Y/ z1 V$ `
4 I# W7 b1 R: Z4 {% X3 j
6、加法时,将位宽较宽的放在多周期中,全速率中尽量减少加法位宽。
& a) r3 a- W" J; ^5 D. Z, E F$ C5 d8 I
7、加法时,将高位宽拆分成两级进行运算。
) ], i9 i4 o% p8 L" w5 Z
# q2 u! n& o0 [8、使用RAM、DSP中流水reg,不增加额外延时。
8 x/ w9 i2 `# y/ ?7 r) z- C2 p# g1 Q1 D% H C) y1 x4 \. ^
9、使用multicycle。4 _$ ?1 |! O8 @) D+ }
/ d! f! [. \% `" P/ B
10、减少扇出fanout。% z4 ~$ F# q: H" _+ ]
( G; {7 o# l: ^ b- v
11、功能等价法均匀分散组合逻辑。1 C% S: G# v9 I
" O2 ]" B% m! c; S
12、设置QuartusII软件综合选项。
0 e% j4 W6 H4 {8 D/ ?& `( K3 z8 P' j3 h8 P: h
13、功能没有优先级的if-else将关键路径放在最前。
/ A" c: N: V1 h/ X+ v) _
# P& ^# x) b& z, _1 q* w$ f: q) I# l14、物理综合优化removal和recovery时序。$ c& A5 Z! B' w/ Y8 ?% z/ z/ a
6 D, {- d- X3 S2 U
三、 功耗类
! d5 _& Q1 Z( S. g1 [* r9 c L0 E0 H2 \# i3 F9 u6 \5 S1 c2 F
1、避免小fanout的信号也使用全局clock网络。
( H5 n/ T' u; k. A; z3 e6 {: h/ {4 {; Z. j
2、尽可能使用区域clock代替全局clock network。1 v) ?7 J0 ]2 t3 i! A
/ K" T1 A. d( A+ x& k3、关闭非持续工作的模块时钟(通过IPCORE、clock_ctrl模块)。
. _9 t4 Q) ]% l3 }7 ~! ^* r5 w! a. p0 p) r* x
4、条件允许小选择低功耗管脚和设置电压电流约束。
! ]) f( J9 y9 U! R) ~
& r# [+ a6 ^% t" o# F' x3 b- j5、控制RAM组合形式,减少每次操作的RAM块个数。9 D" W; l$ L( S& q* `5 w% t
( O# u" ]# z# A* M* y6、代码中才用关断使能、数据等降低功耗。
4 s- E5 c2 V @8 J, p0 O
$ }7 n! [1 K4 \. C) Y四、 案例类( }! V9 N3 G" U
0 G. G% R$ ~7 U8 B" e1 R1、减少调度模块的调度颗粒,提高系统吞吐率。
1 p$ x2 }7 K! p8 F) ^ j* r$ ?' f
, ^0 v+ ], C9 D. f2、从方案角度优化降低编码实现复杂度。9 f# }3 U& b% w0 a
; F$ m0 Z: Q b3、保证外部总线错误时,逻辑内部可以检查到。
+ _6 L" r7 M* X: J# F( d4 v* K A0 L4 J
4、多带宽滤波器实现时,可考虑使用通用混模filter实现多个不同带宽filter,以节省资源。
0 k# ^+ Z6 i( v; U
+ ^# Z' B: J H& a# [" t& Y五、其他
0 C) z" x2 Y, a* c! s' t( W& e/ o* {
1、可靠性—板级信号传递握手机制为送耦合机制。4 g' E) [# S2 U+ E) S
|
|