|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
一、 代码设计1 H" F* J( L( S9 K1 O. P
8 a( i, G- B& s& V8 u. l2 _6 O1、设计中的FIFO、状态机接口需要有异常恢复状态和状态上报机制,格雷码电路防止被综合工具优化掉。9 T# T# ^4 {6 A' S- i
$ M6 d) G, X& o9 \' w7 G! ja)自行设计的格雷码FIFO(一般用于连续数据流跨时钟域)用Synplify综合时,为了防止被优化需要添加综合引导语句:“synthesis_syn_preserve = 1”;
9 S$ F' v$ F. U+ ^/ k2 e9 K, J1 }4 k1 N; r- w
b)各种综合工具均有状态机安全模式,综合时候建议打开。
' V4 U2 o: B6 y
8 {5 S2 O5 Y" h" v6 s2、电路中所有寄存器、状态机、计数器、FIFO在单板上电复位时及使用前必须处于一个已知状态。
. b% I" W5 s* u) C( u6 _( L# z) V* P- ]
a)对电路中的寄存器、状态机、计数器、FIFO必须进行异步复位(不依赖于任何时钟的复位);9 k h4 L! T" ^( J. e
9 H7 U+ Q: Y! y/ {( c8 z
b)电路中的状态机、计数器在应用的时候不能完全依赖于异步复位时的状态,对于重要的状态机或计数器,必须还有周期检测或同步并对它进行复位/置数机制,保证可靠工作。
% y2 Q6 W( ~9 W7 n0 J& x7 ]: e$ R8 c/ V
3、跨时钟域以及异步信号必须同步化处理(使用的QuartusII中的Design Assistant或者专业的nlint、spyglass[1]等工具完成代码检查),这条是用FPGA进行数字电路设计的最核心最基本的思想和方法!( v! c0 F' }; \( ~# G5 u
" a* b! `! q c- u- V
a)尽可能在整个设计中只用一个主时钟,同时只用一个时钟沿,主时钟走全局时钟网络;4 Y4 w9 [7 G2 A% D' V
$ N1 T9 f% t' `b)推荐所有输入输出信号均通过寄存器寄存,寄存器接口当作异步接口考虑;: l G$ N0 v' m6 U
1 ~) s+ |) _7 N2 z
c)当全部电路不能用同步电路思想设计时,即需要用多个时钟来实现,则可以将全部电路分成若干个局部同步电路(尽量以同一个时钟为一个模块),局部同步电路之间的接口当作异步接口考虑;
E3 K/ t, q6 @* w+ S5 r0 G! P$ k6 l8 G0 l
d)电路的实际最高工作频率不应大于理论最高工作频率,要留有一定设计余量,保证芯片可靠工作;
& \- I7 O% }8 E) \1 K% n) y( L+ P U* X# |2 j4 Q3 l3 S
e)电路中所有寄存器、状态机在单板上电复位时应处在一个已知状态;6 j4 L4 I- V4 |# f
/ C+ Q L* ~. q+ R w9 x
f)对于设计中的异步电路,要给出不能转换为同步设计的原因,并对该部分异步电路的工作可靠性(如时钟等信号是否有毛刺,建立保持时间是否满足要求等)做出分析判断,并提供分析报告;; Y$ w# T2 I% `$ n) J
/ R) j' N/ @) r: Cg)关于全局时钟的约束,能上全局的全部上全局,不能上全局的建议通过区域时钟约束、逻辑锁定、增量编译等保证性能;6 b+ A: g5 h0 R4 G! d; i/ `- K% m
3 R: t& ~) n( _; H1 E0 p: bh)依靠QuartusII中的Design Assistant或者专业的nlint/spyglass工具检查跨时钟域代码处理部分。
4 D( {3 M/ M5 O7 o0 L/ D
+ b7 t( H$ o: M& G1 n1 i l4、电路中不能出现门控时钟和行波时钟。
' X7 ^8 e" T7 }, Q2 b1 y7 v, x, l
1 k) ]! c2 O/ oa)门控时钟的使用主要是通过关断时钟来达到降低功耗的目的,但是使用不当容易使得时钟出现毛刺,给设计带来灾难性风险。如果降功耗必要的话,推荐使用厂家自带的时钟控制的IPCORE,例如 ALTCLKCTRL;9 |* r+ {- X3 z% f, ?3 ?- {
) H- ~4 {" d: b; g3 V
b)行波时钟是指寄存器输出的数据又作为下一个寄存器的时钟使用。行波时钟是一个非常危险的设计,由于寄存器有Tco,它会使时钟沿变缓,延时加大,多级级联的时候情况更加恶劣,出问题是必然的!行波时钟设计实际上是一种异步设计,大部分综合布线工具都不会对行波时钟设计进行setup/hold时序分析检查,设计无法保证正确性!
2 B, q4 P' X4 K2 Q/ _1 S
' D$ G- W8 w% n5 B: b2 C1 Z, p设计中完全没有必要使用行波时钟,可以用寄存器输出做同步使能用,与行波时钟设计意图完全一致!
8 P2 t) X6 ]8 G% d t5 ]/ D( Q8 O/ c0 c
5、需要综合的RTL源代码中不允许出现“* / %”这三个运算符。
+ y6 {9 i7 O, R2 l7 M
3 \0 Q1 c) d# Sa)目前大部分综合工具对以上三种运算支持的不好,而且非常浪费LE资源,而且还不能保证正确性和稳定性!可行的替代方案如下:, M {6 @) Z# P* U* ?1 z: M
" a0 q$ s {* m5 } h$ S6 b: a“*”通过例化IPCORE或者“移位运算+加法”来实现;
7 S+ s: D# Q/ x
; }6 U8 i! e3 e, U“/”通过“移位运算+加法”来近似逼近实现;例如:1/30 = 1/32 + 1/512 + 1/8192;
9 t% x5 n" {' L0 z# P$ H9 Q- X# l h5 r' w: i- G, j
“%”通过自己手动计算得到;* e- M+ J- c* Z' m, L
; T% i- F" O2 T1 P, w: f以上运算在非综合的RTL的代码中使用不受此限制。- G$ z, l' p/ r$ g! V
4 t" y! X0 m) b
6、条件语句必须赋值完全,即:if语句后必须有配对else语句,case、casez、casex语句中必须有default语句。1 b9 V# q% w0 B+ j8 Q
* A2 e; l4 n- i" d) Ma)如果if没有配对的else,case/casez/casex中没有对应的default语句的话,之后reg型数据会保持原来的值。这个在时序逻辑中可能没有太大的问题(如果设计者本意就是要保持的话),但在组合逻辑中会生成一个锁存器,锁存器逻辑往往不是设计者的意图而导致灾难性后果!
# N4 j& p; X- D, o7 U5 {# `5 u# O7 B% E; N
为了避免不经意的犯错,建议养成良好的编码习惯:if一定要有配对的else,case/casez/casex中一定要有对应的default语句,即使要保持原来的值也要显示声明(else;或者default;)
4 O5 R3 m' k* m! [$ r+ d* ?; U4 Y' y9 e, A
7、使用器件的专用管脚和专用资源实现电路功能,这些包括全局时钟、复位管脚,全局输出允许管脚等,内部全局时钟网络等。
, z* i8 z* A, B1 L& j& c
% X; p1 a' t+ `2 \: s+ ia)专用管脚和专用资源一定要优先使用,使用得好会事半功倍。如果不用器件提供的专用管脚或资源,有时导致稳定性和可靠性不高甚至是设计失败。
3 Z. x9 {5 ?; F# C% {6 w( C; q4 \9 B$ ^4 z9 ~) F
8、逻辑未使用的但又硬件连线的管脚,逻辑必须显示声明并处理。所有有硬件连线的管脚必须在顶层代码中显示声明(包括暂时没有使用的),不允许放任不管。
6 E4 ^. u% T. R7 ]6 J
/ u. H, }+ D x( s4 r9 N% E( ka)对于有硬件连线的输入信号(包括三态的输入方向),建议输入到CPU接口作为只读寄存器(如果没CPU接口可以将该信号做成一些等效冗余逻辑加到其他逻辑中去),这样既可以消除warning,又可避免布线工具随便布线(把输出信号放到输入管脚)导致外部信号冲突;
& R: b( }) P/ {% @
$ j7 f0 s% d1 k% Z: E5 @" M! Mb)对于有硬件连线的输出信号(包括三态的输出方向),对于暂时没有使用的一定与硬件人员确定其默认值,避免对外信号(如电阻上下拉)的干扰。
; r% H5 n; G4 L
. k7 {# ~# B5 N. ?9、修改接口文档需要同对应项目组人员确认。
$ g" R$ \% }. W: J/ |' F: {# h# R
5 A, f" S M. r8 e8 z- }, y. ha)与硬件相关的方面涉及输入文件有qsf和sdc,内容包括但不限于电平标准、电流强度、管脚位置、输入输出方向、上下拉等等;0 g4 \8 e) K. M+ A5 u8 x
) t ~+ u: d3 a4 C7 L: r- S7 }+ P' |b)与软件相关的方面涉及方案协同实现文档和寄存器接口文档,包括寄存器操作地址、操作顺序等等。
. W2 K l! a# x1 ?7 @$ h* Q1 W! c% f
& r7 m$ O0 y. t( r" H9 V二、 综合布线过程
$ q5 e2 u3 O4 i" v, z: ]# m
& f% y- m$ }7 U. v1、综合布线的版本是否与配置库上的版本完全一致; z: ]; Z& p' y7 o* F0 N- [
: S3 R0 P J& P0 z( P5 |
a)养成良好的版本维护和管理习惯(如复制修改和设置只读属性等),善于使用代码比较工具修改版本(包括源代码、qsf和sdc等输入文件要全部仔细比对)。
* ?; W6 E. J. C8 U' U: N( ?1 \2 u: Z6 E9 T
2、所有约束(包括对外部接口的管脚约束、时序约束、内部时序约束)是否已经添加正确,布线报告满足约束要求,时序无error类告警。
& n( _$ z4 \0 X
/ `* ~) @9 f9 r9 X7 M5 Ba)硬件方面:电平标准、电流强度、翻转速率以及上下拉(差分时还有输入阻抗匹配,高速信号还有预加重、VOD、接收均衡、直流增益等);; o6 u) ^! p+ B; b8 p
0 U8 R/ z; g: k' i- ]5 i- v o# N' qb)输入输出锁IOB/IOE,时序约束正确(Tsu、Th、Tco、Fmax);" m- @% @4 B5 I- n8 ?* `4 @
3 X2 Y4 e0 {+ P: W( o2 F- r% Sc)异步和组合逻辑锁IOB/IOE,加set_minimum_delay和set_maximum_delay约束;
2 J/ m0 u [, o% x5 \4 A1 w6 U5 y# N
d)时钟约束有基时钟、衍生时钟、虚拟时钟和多周期约束等。 I# e. @; a! N! }
4 }' Y$ f, D) g
3、所有编译、布线、时序分析等过程中出现的warning都已经确认。+ a% y6 ?. t. C% s) S; T6 [# P9 v
/ u& r6 o0 e3 j* Z
三、 版本验证过程
8 c1 g: h& i5 ?9 g. p0 U( e9 n, u' C7 M
1、修改模块必须进行UT(单元测试)。
! K4 M$ M% v; s, i2 j$ K& ? s+ E5 d, x3 J$ Q" k/ v; q
a)建议UT的覆盖按照功能覆盖优先,分解测试点,根据测试点来设计测试用例,保证测试点覆盖率为100%;
( |8 d/ H3 F5 _- L% L* \
7 Z+ i/ E8 U3 b5 w$ [9 rb)在功能覆盖率的前提下关注代码覆盖率,建议的代码覆盖率标准为:语句覆盖和分支覆盖为100%,条件覆盖和表达式覆盖率为90%。
+ ~) ~( i0 _; x, y- b& a) p
: V' N: G+ J% `8 S9 p+ R9 t* e 2、有条件的话单板验证必须进行完整的STB(上板系统测试)或全系统业务平台测试。
! c3 b- M- e, ?" G, g7 X2 r* |7 X
! M F( J8 Q- H3 A# d良好代码编写风格可以满足信、达、雅的要求。在满足功能和性能目标的前提下,增强代码的可读性、可移植性。
! A* `) A1 p+ L0 ~FPGA优化方法和准则概括如下:2 H1 p: F2 ^& P1 s' F
, `. [: j7 s4 j4 G一、 面积类
4 G$ Q! E* h$ o6 J0 v( v+ N
. }/ L/ E* Q6 z* \! t7 v& }$ \1、不进行不必要的数据清零。) g1 \8 X0 V5 e1 y: Y
`3 l7 ]8 S4 w m9 R
说明:一般在数据总线赋值额时候,习惯加上例如的:“else dout [15:0] <= 16’d0”,实际上这种清零并不是必要的,因为一般写使能就已经控制了数据的有效性,数据即使保持原值也没有问题,加入上述语句后,综合其会用多余的资源实现这个没有必要的清零分支。, n8 ?. B5 u+ ~) l W. r: N! L
1 ^" e/ W0 g+ p/ p9 z- I
2、多路数据进行相同处理时,先选择后处理优于先处理后选择。
% B3 y' M) t# q. @ _) j
0 l# m: @6 p8 Y3、采用合适的编码方式(one hot bit速度更快,但是资源消耗得也更多)。
+ x& g# R- S) K
& P3 G6 T9 U" I( K. ?4、多拍串行计算打开为一拍并行计算- y" {; W& s* i$ Y3 J1 U# O! z" G. V
: U" |/ T3 A5 h& e& [5、统计寄存器位宽根据需要来确定,不需要一位的32bit大位宽。
5 M5 q5 n( o: ?/ T9 x
# U! C/ x$ d5 S* Z& L6、异步配置信号(CPU)可根据配置模块所在不同时钟域分别进行处理。/ ]7 Z+ u& R! B/ A# U
( j, r) _: {5 H* M' T4 R7、尽可能实现资源共享(计数器、比较器等),节省资源。
" G) s5 n, {- n6 w3 i
: r& J O' _, Z! U6 L8、采用迭代算法节省资源。 J3 F8 c9 h C, _' H; t0 I
: o6 F3 W" N1 Y8 d M* w4 J10、使用reg代替FIFO接口。
0 p% u* V- T5 c5 l0 F% ^$ Z
2 j) W2 m% z% H( ^. a2 ?11、状态机状态不要在比较器中使用。
9 T' A0 v% h$ e$ B* G' T3 k6 R; c5 Z) x3 O4 {1 @0 h
12、3倍插值FIR滤波器优化。4 }) p; k% ^5 _! i, L" z2 i& X
" b" |1 v5 z* e( Z" f" R13、用减法器借位位代替比较器。! N3 a; i0 V$ ^2 {# K5 u* z
) E( s* @2 o% A$ f+ S5 g) m14、利用ROM代替较大的组合逻辑。
$ Z8 D( ]7 ?, j
+ {+ E1 T; ^# R7 s1 j7 ?15、利用多周期约束或通过RAM换LE的方法来节省CIC滤波器LE资源。( q. P- H9 Y O+ g3 i; y* D9 x* ~6 F
S6 C) R: g3 e5 S, u16、Multiplexer重编码节省LUT资源。
0 J- _6 p( d# e% J; G
3 ~+ l8 l& k* q. y, w6 i! e17、合理设置MUX默认条件有利于资源优化。例如:“default:dout <= 1’dx;”* \6 e9 ^# v$ a) w, S1 E
7 A5 U6 u# }2 f4 n" r7 o, w
18、合理设置QuartusII软件中auto packed register选项
3 I" A1 J; _, S0 w/ ], Z$ E" ^
7 ^4 ]# ?" C) N9 s4 q0 Y20、建议使用“减法溢出”来设计Timer。+ e: L& B, w$ C$ q5 ^% @
4 z& D8 b0 R8 |+ x: [& h
21、简化环回设计,节省资源。1 M5 _( w5 U( B$ o* w) [4 u
* K% x, F4 c: h0 N5 g
22、减少时钟域,节省资源。
# u7 d. F% T8 b5 c0 y
8 R& i+ G. b6 U1 \5 q, y23、复数乘法公式展开,利用加法部分代替乘法。
+ m* v: A k2 ~! T. |" L3 G; g! `- o- [6 u
24、禁止使用shift reg自动替换功能,避免小的的移位寄存器浪费M9K。
/ o+ G! d' s8 E Y2 N2 Q9 T% S! W& }/ |
25、基于RAM的交换架构。
; J* X! t. |. u, T
' U! x% F6 i2 M# ~3 _26、用RAM存放统计值来代替统计寄存器。
# x) s4 I. t6 Y/ C8 n& H& z( H6 t+ b: O4 p1 K% V5 g# L
28、多通道分时处理时,功能相同的模块可以考虑复用。
8 s+ i: I1 q1 D4 s! f% o# U6 m
/ ]; A' n3 v. b4 [3 s29、复用没有全速运行的模块,多通道RAM使用复用模块代替。8 S, i/ C9 a" f! t$ S
4 A/ w2 q, ?6 q! v9 A3 J1 b7 @
RAM节省部分# L9 @9 E! V0 u b
! K: \1 R) ]4 J) v1、 使用根据器件RAM块的位宽和深度合理选择。$ Q2 X" j7 j7 g; I. l
! j0 Y+ D5 e2 T& x9 ?6 ?& I* ?
2、 使用分布式RAM替换寄存器资源8 f7 y! c$ n6 K5 t5 Z5 H
& N9 R+ \$ Z& A( @+ a3 X! A3、 2倍插值滤波器优化。9 H5 V" |1 r4 o0 Z4 A1 }- T
4 d- n0 c# P) s; E7 ?# I1 y: M
其他部分
/ p# J: _; c( `$ `% x( s, X7 \( F
' j9 v6 z8 Y" c' \ p- e1、 根据器件内部block RAM特点,选择合理的拼接模式,可以减小RAM块地址译码和数据选择的LE。5 U, }8 {! z! H; g) |) x5 @
: M, p5 Q4 z A" z2 L. t8 P
2、 路由查表优化。+ I( |. E3 a. j1 b
4 m2 ]) I# Z) Y% }- V二、 时序类3 ~4 z8 A/ _# K' A, w* C" f/ m z
/ Y9 `9 e# k( _/ ^& W' w0 x# p1、打平逻辑可以提高时序。- B+ N$ I) g* N7 s9 ?5 V* ^
- z2 w% q: R9 g, Z2、配平寄存器以提高时序。: G8 F! _4 |8 W1 b, _
: g( b, z- M% p* Y& H1 }3、尽可能减少组合逻辑。* P! E, p( X, s- i4 V K
3 \" h6 J; ^8 y# J5 [4、在输出到IOB时安排布线时延要求低的路径,要求高的放在内部逻辑。
* x% n1 u( D) x1 Z9 d
7 f! b7 \8 A/ a$ F5 [ k5、降低高速时钟域布线资源。
& j# V: ]" ?( X4 l
S1 q s! I) c6 s$ y8 y6、加法时,将位宽较宽的放在多周期中,全速率中尽量减少加法位宽。% O1 j; Y/ c. j" A. L4 i
' W' F$ ?! `% u$ q4 O7、加法时,将高位宽拆分成两级进行运算。& m# N. s) R1 o) R
- j$ p" [+ Z$ K4 j- r* C X1 m+ Z8、使用RAM、DSP中流水reg,不增加额外延时。
1 B+ A) a: `) w9 b( C
$ W* }+ s7 a; S! i# S' d9、使用multicycle。# L# g- O- L, F& k7 _
7 L: u, X" H& ^1 t' g! S
10、减少扇出fanout。# j/ h, p, d c; Z7 L3 J
* w8 \7 r$ z w+ u, }6 I5 x+ r11、功能等价法均匀分散组合逻辑。
. I/ c' ~* ^$ d) B! x& J k* i( {
# A( ^/ }3 o. w* V4 x- V! @8 W12、设置QuartusII软件综合选项。" s4 G% g' C, J3 O; w5 v) R; g) Q) e
. n" q8 Q! y0 B0 C; p13、功能没有优先级的if-else将关键路径放在最前。1 {- _' {- _) B. X, t' A
; d: _+ h' v7 X% G14、物理综合优化removal和recovery时序。4 o/ h! u3 b6 ?, m5 A$ |
& @! f' Z2 @- D6 S& x! ]( A9 j! Z
三、 功耗类
6 b9 E5 D' f- H1 O3 F9 Z5 v. t* A2 Q
1、避免小fanout的信号也使用全局clock网络。
6 {( X, u& K9 u) ^$ E+ B8 u" K/ s( t" o! O3 m) L$ y
2、尽可能使用区域clock代替全局clock network。
: {6 T- q8 ]4 N y/ \1 Q: ?/ h9 U( f1 ]7 \ B5 L/ K1 P
3、关闭非持续工作的模块时钟(通过IPCORE、clock_ctrl模块)。
+ Z- ]$ x; O/ b8 c2 k6 z4 w2 Y0 F, c4 a. r( A! N& D! I: q% Z
4、条件允许小选择低功耗管脚和设置电压电流约束。
9 j& H0 u, A0 R9 a9 e2 g) W% p& s+ L& ]4 F% J
5、控制RAM组合形式,减少每次操作的RAM块个数。' f! k$ u9 u" F
+ V: u: f* e- I+ s& |
6、代码中才用关断使能、数据等降低功耗。) J8 A! X, o2 S5 E# [
, z( `2 u$ N7 P+ q H: d% s四、 案例类
7 r( R; D0 J4 F7 S7 U! P& x6 e U. a: {: b7 V& G. E$ @
1、减少调度模块的调度颗粒,提高系统吞吐率。2 O' F3 z5 \: k. c# V6 k2 j
0 J0 @$ s; M& {2 l5 Z; N
2、从方案角度优化降低编码实现复杂度。
" g5 ?) |7 I7 t% j. c5 p/ q7 `3 A; K3 \% F1 z& }0 G
3、保证外部总线错误时,逻辑内部可以检查到。
) C0 r& I' x( V( U; @5 p# [+ D- J# F7 Y9 K8 g4 ?4 P
4、多带宽滤波器实现时,可考虑使用通用混模filter实现多个不同带宽filter,以节省资源。% K" |6 @; E6 W/ h/ o; Y
" n3 i& H/ Y7 Y五、其他- e# G3 K, H1 \
. Z1 E: a- e8 N5 @/ p, O0 V9 _1、可靠性—板级信号传递握手机制为送耦合机制。+ r$ f+ ^3 w9 I# I
|
|